2 #include <util/delay.h>
3 #include <avr/interrupt.h>
7 static volatile uint16_t jiffies;
9 // #define CHRISTMAS_TREE 1
11 #define rgb_return(r, g, b) do { send_rgb((r), (g), (b)); return 1; } while(0)
15 /* RNG from ADC noise */
16 static unsigned char rand_pool[8], rand_pool_off, prev_bit, rand_pool_out;
18 static void init_rng()
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
23 ADCSRA |= _BV(ADIE) | _BV(ADSC);
28 static unsigned char rand() {
31 rv = rand_pool[rand_pool_out];
33 if (rand_pool_out >= sizeof(rand_pool))
42 if ((rand_pool_off & 1) == 0) { // first bit of the pair
46 unsigned char bit = ADCW & 1;
47 if (bit == prev_bit) { // whitening fail: try again
53 rand_pool[rand_pool_off >> 4]
54 ^= 1 << ((rand_pool_off >> 1) & 7);
58 if (rand_pool_off >= 16*sizeof(rand_pool))
63 static unsigned int slow_dim[] = {
67 static void fill_color(unsigned char r, unsigned char g, unsigned char b)
71 for (i = 0; i < STRIP_SIZE; i++)
79 static void do_buttons()
81 static uint8_t prev_buttons = _BV(PB0) | _BV(PB3) | _BV(PB4);
82 static uint16_t prev_len = 0;
84 uint8_t buttons = PINB & (_BV(PB0) | _BV(PB3) | _BV(PB4));
86 if (prev_buttons == buttons) {
92 if (prev_len < 3 || (buttons != (_BV(PB0) | _BV(PB3) | _BV(PB4)))) {
93 prev_buttons = buttons;
98 if ((prev_buttons & _BV(PB0)) == 0) {
101 } else if ((prev_buttons & _BV(PB3)) == 0) {
104 } else if ((prev_buttons & _BV(PB4)) == 0) {
108 prev_buttons = buttons;
119 _delay_ms(3000/8); // wait for a bit and then increase the CPU clock
123 PORTB |= _BV(PB0) | _BV(PB3) | _BV(PB4); // pull-ups for buttons
131 static unsigned char c = 28;
141 while (i < STRIP_SIZE) {
153 if ((jiffies & 0x1ff) == 0) {
159 for (i = 0; i < STRIP_SIZE; i++) {
160 unsigned char x = c; // + i / 2;
164 send_rgb(8*(10-x), x, 0);
166 send_rgb(0, 20-x, x-10);
168 send_rgb(8*(x-20), 0, 30-x);
174 fill_color(32, 4, 8);
177 fill_color(255, 92, 92);
180 fill_color(255, 255, 255);
183 { unsigned char light;
185 light = slow_dim[sizeof(slow_dim)/sizeof(slow_dim[0]) - state];
186 fill_color(4*light, light, 2*light);