]> www.fi.muni.cz Git - bike-lights.git/blob - firmware/pwm.c
firmware: move PWM_MAX to lights.h
[bike-lights.git] / firmware / pwm.c
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <util/delay.h>
4
5 #include "lights.h"
6
7 void init_pwm()
8 {
9         /* Async clock */
10         PLLCSR = _BV(PLLE);
11
12         /* Synchronize to the phase lock */
13         _delay_ms(1);
14         while ((PLLCSR & _BV(PLOCK)) == 0)
15                 ;
16         PLLCSR |= _BV(PCKE);
17
18         // PWM channel D is inverted, ...
19         TCCR1C = _BV(COM1D1) | _BV(COM1D0) | _BV(PWM1D);
20         // PWM channels A and B are not
21         TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
22         TCCR1D = 0;
23         TCCR1B = _BV(CS10);                     // no clock prescaling
24
25         TC1H = PWM_MAX >> 8;
26         OCR1C = PWM_MAX & 0xFF;                         // TOP value
27
28         TC1H = PWM_MAX >> 8;            // PWM3 is inverted
29         OCR1D = PWM_MAX & 0xFF;
30
31         TC1H = 0x00;
32         OCR1B = OCR1A = 0;              // initial stride is 0
33
34         DDRB  &= ~(_BV( PB1 ) | _BV( PB3 ) | _BV( PB5 )); // tristate it
35         PORTB &= ~(_BV( PB1 ) | _BV( PB3 ) | _BV( PB5 )); // set to zero
36 }
37
38 void susp_pwm()
39 {
40         DDRB &= ~(_BV( PB1 ) | _BV( PB3 ) | _BV( PB5 ));
41         TCCR1D = TCCR1C = TCCR1B = TCCR1A = 0;
42         TIMSK = 0;
43         TIFR = 0;
44 }
45
46 void pwm_off(unsigned char n)
47 {
48         switch (n) {
49         case 0: DDRB &= ~_BV(PB1); break;
50         case 1: DDRB &= ~_BV(PB3); break;
51         case 2: DDRB &= ~_BV(PB5); break;
52         }
53 }
54
55 void pwm_set(unsigned char n, uint16_t stride)
56 {
57         unsigned char hi, lo;
58
59         if (stride > PWM_MAX)
60                 stride = PWM_MAX;
61
62         if (n == 2)
63                 stride = PWM_MAX - stride;
64
65         hi = stride >> 8;
66         lo = stride & 0xFF;
67
68         switch (n) {
69         case 0:
70                 TC1H = hi;
71                 OCR1A = lo;
72                 DDRB |= _BV(PB1);
73                 break;
74         case 1:
75                 TC1H = hi;
76                 OCR1B = lo;
77                 DDRB |= _BV(PB3);
78                 break;
79         case 2:
80                 TC1H = hi;
81                 OCR1D = lo;
82                 DDRB |= _BV(PB5);
83                 break;
84         }
85 }
86
87 #if 0
88 static void inline pwm_handler()
89 {
90         OCR1A = pwmval[0];
91         OCR1B = pwmval[1];
92         OCR1D = pwmval[2];
93         TIMSK &= ~_BV(TOIE1);
94 }
95
96 ISR(TIMER1_OVF_vect)
97 {
98         pwm_handler();
99 }
100 #endif
101