]> www.fi.muni.cz Git - bike-lights.git/blob - lights.c
pattern flashing
[bike-lights.git] / lights.c
1 #include <avr/io.h>
2 #include <avr/eeprom.h>
3 #include <util/delay.h>
4 #include <avr/sleep.h>
5 #include <avr/interrupt.h>
6
7 uint16_t pwmee EEMEM;
8 volatile uint16_t adcval;
9
10 volatile struct
11 {
12   uint8_t pwm_int: 1;
13   uint8_t adc_int: 1;
14   uint8_t tmr_int: 1;
15 }
16 intflags;
17
18
19 unsigned char debug EEMEM = 1;
20
21 ISR(ADC_vect)
22 {
23         adcval = ADCW;
24         ADCSRA &= ~_BV(ADIE);         /* disable ADC interrupt */
25         intflags.adc_int = 1;
26 }
27
28 ISR(TIMER1_OVF_vect)
29 {
30         TIMSK &= ~_BV(TOIE1);
31         intflags.pwm_int = 1;
32 }
33
34 ISR(TIMER0_COMPA_vect)
35 {
36         intflags.tmr_int = 1;
37 }
38
39 struct {
40         unsigned char intensity :2;
41         unsigned char length :6;
42 } pattern[] = { {1, 2}, {0, 4}, { 1, 2 }, {0, 15}, {0, 0} };
43         
44 static void inline init_pwm()
45 {
46         TCCR1C = _BV(COM1D0) | _BV(COM1D1) | _BV(PWM1D);
47         TCCR1A = _BV(COM1A0) | _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(PWM1A) | _BV(PWM1B);
48         TCCR1B = 0x80| _BV(CS13) | _BV(CS11);
49         TC1H  = 0x03;
50         OCR1C = 0xFF;
51         OCR1D = OCR1B = OCR1A = 0x40;
52         TCNT1 = 0;
53         DDRB |= _BV( PB5 ) | _BV( PB1 ) | _BV( PB3 );
54         PORTB &= ~(_BV( PB5 ) | _BV( PB1 ) | _BV( PB3 ));
55         TIMSK |= _BV(TOIE1);
56 }
57
58 static void inline init_adc()
59 {
60         ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADPS1) | _BV(ADPS0);
61         ADMUX = _BV(REFS1) | _BV(MUX0);
62         // ADCSRB = _BV(REFS2); 
63         DIDR0 = _BV(ADC1D) | _BV(AREFD);
64 }
65
66 static void inline init_tmr()
67 {
68         TCCR0A = _BV(WGM00);
69         TCCR0B = _BV(CS02); // | _BV(CS00);
70         OCR0A = 0x80;
71         TIMSK |= _BV(OCIE0A);
72         DDRA |= _BV( PA0 );
73 }
74
75 int main(void)
76 {
77         char seen = 0;
78         char pcount, ppos;
79
80         init_pwm();
81         init_adc();
82         init_tmr();
83
84         ppos = 0;
85         pcount = pattern[ppos].length;
86         if (pattern[ppos].intensity) {
87                 PORTA |=  _BV( PA0 );
88         }
89
90         while (1) {
91                 unsigned char pwmhi, pwmlo;
92
93                 if (intflags.adc_int) {
94                         intflags.adc_int = 0;
95
96                         if (adcval > 0x3C0)
97                                 adcval = 0x3C0;
98                         if (adcval < 1)
99                                 adcval = 1;
100                         pwmhi = adcval >> 8;
101                         pwmlo = adcval & 0xFF;
102
103                         TC1H = pwmhi;
104                         OCR1D = pwmlo;
105
106                         TC1H = pwmhi;
107                         OCR1B = pwmlo;
108
109                         TC1H = pwmhi;
110                         OCR1A = pwmlo;
111
112                         TIMSK |= _BV(TOIE1);
113                 }
114
115                 if (intflags.pwm_int) {
116                         intflags.pwm_int = 0;
117                         ADCSRA |= _BV(ADIE) | _BV(ADSC);
118                 }
119
120                 if (intflags.tmr_int) {
121                         intflags.tmr_int = 0;
122                         if (--pcount == 0) {
123                                 ppos++;
124                                 pcount = pattern[ppos].length;
125                                 if (!pcount) {
126                                         ppos = 0;
127                                         pcount = pattern[ppos].length;
128                                 }
129                                 if (pattern[ppos].intensity) {
130                                         PORTA |= _BV(PA0);
131                                 } else {
132                                         PORTA &= ~_BV(PA0);
133                                 }
134                         }
135                 }
136
137                 sei();
138                 sleep_mode();
139                 cli();
140
141 #if 0
142                 if (!seen) {
143                         seen = 1;
144                         eeprom_write_byte(&debug, 2);
145                 }
146 #endif
147         }
148
149     DDRA |= _BV( PA0 );
150     while( 1 ) { 
151         PORTA |=  _BV( PA0 );
152         _delay_ms(2000);
153         PORTA &=~ _BV( PA0 );
154         _delay_ms(2000);
155     }
156 }