]> www.fi.muni.cz Git - tinyboard.git/blob - projects/rgb-led-light/main.c
a89481c2a906835409bdf9b687f556d75cc182cc
[tinyboard.git] / projects / rgb-led-light / main.c
1 #include <avr/io.h>
2 #include <util/delay.h>
3 #include <avr/interrupt.h>
4
5 #include "rgbstring.h"
6
7 static volatile uint16_t  jiffies;
8
9 // #define CHRISTMAS_TREE 1
10
11 #define rgb_return(r, g, b)     do { send_rgb((r), (g), (b)); return 1; } while(0)
12
13 #define VERT_SIZE 47
14
15 /* RNG from ADC noise */
16 static unsigned char rand_pool[8], rand_pool_off, prev_bit, rand_pool_out;
17
18 static void init_rng()
19 {
20         ADCSRA |= _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1); // enable, clk/64
21         ADMUX = _BV(REFS1) | _BV(MUX0) | _BV(MUX3); // 1.1V, PB5:PB5, gain 20
22         DIDR0 = _BV(ADC0D);
23         ADCSRA |= _BV(ADIE) | _BV(ADSC);
24         rand_pool_off = 0;
25         prev_bit = 0;
26 }
27
28 static unsigned char rand() {
29         unsigned char rv = 0;
30
31         rv = rand_pool[rand_pool_out];
32         rand_pool_out++;
33         if (rand_pool_out >= sizeof(rand_pool))
34                 rand_pool_out = 0;
35
36         return rv;
37 }
38
39 ISR(ADC_vect) {
40         ADCSRA |= _BV(ADSC);
41         jiffies++;
42         if ((rand_pool_off & 1) == 0) { // first bit of the pair
43                 prev_bit = ADCW & 1;
44                 rand_pool_off++;
45         } else {
46                 unsigned char bit = ADCW & 1;
47                 if (bit == prev_bit) { // whitening fail: try again
48                         rand_pool_off--;
49                         return;
50                 }
51
52                 if (bit) {
53                         rand_pool[rand_pool_off >> 4]
54                                 ^= 1 << ((rand_pool_off >> 1) & 7);
55                 }
56
57                 rand_pool_off++;
58                 if (rand_pool_off >= 16*sizeof(rand_pool))
59                         rand_pool_off = 0;
60         }
61 }
62
63 static unsigned int slow_dim[] = {
64         255, 27, 7, 2,
65 };
66
67 static void fill_color(unsigned char r, unsigned char g, unsigned char b)
68 {
69         unsigned char i;
70
71         for (i = 0; i < STRIP_SIZE; i++)
72                 send_rgb(r, g, b);
73
74         end_frame();
75 }
76
77 unsigned int state;
78
79 static void do_buttons()
80 {
81         static uint8_t prev_buttons = _BV(PB0) | _BV(PB3) | _BV(PB4);
82         static uint16_t prev_len = 0;
83
84         uint8_t buttons = PINB & (_BV(PB0) | _BV(PB3) | _BV(PB4));
85
86         if (prev_buttons == buttons) {
87                 prev_len++;
88                 return;
89         }
90
91         // was change
92         if (prev_len < 3 || (buttons != (_BV(PB0) | _BV(PB3) | _BV(PB4)))) {
93                 prev_buttons = buttons;
94                 prev_len = 0;
95                 return;
96         }
97
98         if ((prev_buttons & _BV(PB0)) == 0) {
99                 if (state)
100                         state--;
101         } else if ((prev_buttons & _BV(PB3)) == 0) {
102                 if (state < 5)
103                         state++;
104         } else if ((prev_buttons & _BV(PB4)) == 0) {
105                 state = 1;
106         }
107
108         prev_buttons = buttons;
109         prev_len = 0;
110 }
111
112 int main(void)
113 {
114
115         init_log();
116         init_rng();
117         init_serial();
118
119         _delay_ms(3000/8); // wait for a bit and then increase the CPU clock
120         CLKPR = _BV(CLKPCE);
121         CLKPR = 0;
122
123         PORTB |= _BV(PB0) | _BV(PB3) | _BV(PB4); // pull-ups for buttons
124
125         state = 0;
126
127         sei();
128
129         while (1) {
130                 unsigned char i;
131                 static unsigned char c = 28;
132
133                 do_buttons();
134
135                 switch (state) {
136                 case 0:
137                         zero_frame();
138                         break;
139                 case 1:
140                         i = 0;
141                         while (i < STRIP_SIZE) {
142                                 send_rgb(4, 0, 0);
143                                 send_rgb(4, 1, 0);
144                                 send_rgb(0, 2, 0);
145                                 send_rgb(0, 1, 1);
146                                 send_rgb(0, 0, 2);
147                                 send_rgb(4, 0, 2);
148                                 i += 6;
149                         }
150                         end_frame();
151                         break;
152                 case 2:
153                         if ((jiffies & 0x1ff) == 0) {
154                                 c++;
155                                 if (c >= 30)
156                                         c = 0;
157                         }
158
159                         for (i = 0; i < STRIP_SIZE; i++) {
160                                 unsigned char x = c; // + i / 2;
161                                 if (x >= 30)
162                                         x %= 30;
163                                 if (x < 10) {
164                                         send_rgb(8*(10-x), x, 0);
165                                 } else if (x < 20) {
166                                         send_rgb(0, 20-x, x-10);
167                                 } else {
168                                         send_rgb(8*(x-20), 0, 30-x);
169                                 }
170                         }
171                         end_frame();
172                         break;
173                 case 3:
174                         fill_color(32, 4, 8);
175                         break;
176                 case 4:
177                         fill_color(255, 92, 92);
178                         break;
179                 case 5:
180                         fill_color(255, 255, 255);
181                         break;
182                 default:
183                         { unsigned char light;
184
185                         light = slow_dim[sizeof(slow_dim)/sizeof(slow_dim[0]) - state];
186                         fill_color(4*light, light, 2*light);
187                         }
188                         break;
189                 }
190         }
191 }
192