#include #include #include #include "lights.h" void init_pwm() { /* Async clock */ PLLCSR = _BV(PLLE); /* Synchronize to the phase lock */ _delay_ms(1); while ((PLLCSR & _BV(PLOCK)) == 0) ; PLLCSR |= _BV(PCKE); TCCR1C = _BV(COM1D0) | _BV(COM1D1) | _BV(PWM1D); TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B); TCCR1B = _BV(7) // PWM1X: PWM inversion mode | _BV(CS10) // no clock prescaling ; TC1H = 0x01; OCR1C = 0xFF; // TOP value TC1H = 0x00; OCR1D = OCR1B = OCR1A = 0; // initial stride is 0 DDRB &= ~(_BV( PB1 ) | _BV( PB3 ) | _BV( PB5 )); // tristate it PORTB &= ~(_BV( PB1 ) | _BV( PB3 ) | _BV( PB5 )); // set to zero } void pwm_on(unsigned char n) { switch (n) { case 0: DDRB |= _BV(PB1); break; case 1: DDRB |= _BV(PB3); break; case 2: DDRB |= _BV(PB5); break; } } void pwm_off(unsigned char n) { switch (n) { case 0: DDRB &= ~_BV(PB1); break; case 1: DDRB &= ~_BV(PB3); break; case 2: DDRB &= ~_BV(PB5); break; } } void pwm_set(unsigned char n, unsigned char stride) { TC1H = 0x00; switch (n) { case 0: OCR1A = stride; break; case 1: OCR1B = stride; break; case 2: OCR1D = stride; break; } } #if 0 static void inline pwm_handler() { OCR1A = pwmval[0]; OCR1B = pwmval[1]; OCR1D = pwmval[2]; TIMSK &= ~_BV(TOIE1); } ISR(TIMER1_OVF_vect) { pwm_handler(); } #endif