/* pwm.c */ /* {{{ * * Copyright (C) 2004 Nicolas Schodet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contact : * Web: http://perso.efrei.fr/~schodet/ * Email: * }}} */ #include "pwm.h" #include /* +AutoDec */ /* -AutoDec */ inline void pwm_init (void) { /* No timer/counter interrupt. */ //TIMSK = 0; //ETIMSK = 0; /* Phase correct PWM, TOP = 0xff, OC1B & OC1C with positive logic. f_IO without prescaler. Fpwm = f_IO / (2 * prescaler * TOP) = 28912 Hz. */ TCCR1A = _BV (COM1B1) | _BV (COM1C1) | _BV (WGM10); TCCR1B = _BV (CS10); /* Enable pwm and direction outputs in DDRB. */ DDRB |= _BV (7) | _BV (6) | _BV (3) | _BV (2); } static inline int16_t pwm_preproc (int16_t v) { v = (v >> 2) + ((v >> 1) & 1); /*if (v > 0) v += 0x0f; else if (v < 0) v -= 0x0f;*/ if (v > 255) return 255; else if (v < -255) return -255; else return v; } inline void pwm_set_left (int16_t v) { v = pwm_preproc (v); if (v < 0) { PORTB &= ~_BV (2); OCR1B = -v; } else { PORTB |= _BV (2); OCR1B = v; } } inline void pwm_set_right (int16_t v) { v = pwm_preproc (v); if (v < 0) { PORTB |= _BV (3); OCR1C = -v; } else { PORTB &= ~_BV (3); OCR1C = v; } }