]> www.fi.muni.cz Git - tinyboard.git/blob - projects/led-blinker/main.c
Three-channel LED blinker
[tinyboard.git] / projects / led-blinker / main.c
1 #include <avr/io.h>
2 #include <util/delay.h>
3 #include <avr/sleep.h>
4 #include <avr/power.h>
5
6 /*
7  * Overview:
8  * three LEDs:
9  * PB1/OC1A     yellow
10  * PB2          yellow
11  * PB4/OC1B     red
12  */
13
14 static void init()
15 {
16         DDRB |= _BV(PB1) | _BV(PB2) | _BV(PB4);
17
18         // PWM setup, use T/C 1
19         TCCR1 = _BV(CS10)       // clock at CLK/1
20                 | _BV(PWM1A)    // OCR1A in PWM mode
21                 | _BV(COM1A1);  // clear on compare match
22         GTCCR = _BV(PWM1B)      // OCR1B in PWM mode
23                 | _BV(COM1B1); // clear on compare match)
24
25         OCR1C = 255;
26         OCR1A = 0;
27         OCR1B = 0;
28 }
29
30
31 static unsigned char levels[] = {
32         0, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 255
33 };
34 #define N_LEVELS (sizeof(levels)/sizeof(levels[0]))
35
36 static void led_set(unsigned char led, unsigned char val)
37 {
38         switch (led) {
39         case 0:
40                 OCR1A = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1];
41                 break;
42         case 1:
43                 if (val) {
44                         PORTB |= _BV(PB2);
45                 } else {
46                         PORTB &= ~_BV(PB2);
47                 }
48                 break;
49         case 2:
50                 OCR1B = val < N_LEVELS ? levels[val] : levels[N_LEVELS-1];
51                 break;
52         }
53 }
54
55 static unsigned char rand[] = {
56 193, 33, 133, 97, 139, 225, 40, 105, 110, 238, 57, 250, 26, 221, 166, 247, 138, 23, 107, 122, 154, 33, 201, 66, 154, 78, 137, 198, 86, 232, 38, 182, 16, 198, 73, 231, 58, 114, 58, 105,
57 };
58 #define N_RAND (sizeof(rand)/sizeof(rand[0]))
59
60 static void led0()
61 {
62         static unsigned char r, l, exp;
63
64 again:
65         if (l == exp) {
66                 r++;
67                 if (r > N_RAND-7)
68                         r = 0;
69                 exp = rand[r] >> 4;
70                 if (exp >= N_LEVELS-4)
71                         goto again;
72         }
73
74         if (l < exp) {
75                 l++;
76         } else if (l > exp) {
77                 l--;
78         }
79
80         led_set(0, l);
81 }
82
83 static void led1()
84 {
85         static unsigned char r;
86         unsigned char exp;
87
88         led_set(1, 1);
89 #if 0
90 again:
91         r++;
92         if (r > N_RAND)
93                 r = 0;
94         exp = rand[r];
95
96         led_set(1, ((exp >> 3) & 1) ^ ((exp >> 5) & 1));
97 #endif
98 }
99
100 static void led2()
101 {
102         static unsigned char r, l, exp;
103
104 again:
105         if (l == exp) {
106                 r++;
107                 if (r > N_RAND)
108                         r = 0;
109                 exp = rand[r] & 0xF;
110                 if (exp >= N_LEVELS)
111                         goto again;
112         }
113
114         if (l < exp) {
115                 l++;
116         } else if (l > exp) {
117                 l--;
118         }
119
120         led_set(2, l);
121 }
122
123 int main(void)
124 {
125         init();
126
127         while (1) {
128                 led0();
129                 led1();
130                 led2();
131                 _delay_ms(40);
132         }
133
134 }