2 #include <util/delay.h>
3 #include <avr/interrupt.h>
7 static unsigned char 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))
41 if ((rand_pool_off & 1) == 0) { // first bit of the pair
45 unsigned char bit = ADCW & 1;
46 if (bit == prev_bit) { // whitening fail: try again
52 rand_pool[rand_pool_off >> 4]
53 ^= 1 << ((rand_pool_off >> 1) & 7);
57 if (rand_pool_off >= 16*sizeof(rand_pool))
62 /* up and down running stars at the beginning/end of the strip */
63 static unsigned char updown_star, updown_star0, updown_down, updown_bright;
65 static void updown_star_init()
71 static void updown_star_frame()
73 if (updown_star0 == 0) {
74 updown_star0 = STRIP_SIZE-VERT_SIZE-8;
76 } else if (updown_star0 == STRIP_SIZE + 8) {
77 updown_star0 = VERT_SIZE+7;
79 } else if (updown_star0 <= VERT_SIZE + 8) {
81 } else if (updown_star0 >= STRIP_SIZE-VERT_SIZE-8) {
85 if (updown_down && updown_star0 < 8) {
87 updown_bright = 1 << updown_star0;
88 } else if (updown_down) {
89 updown_star = updown_star0 - 8;
91 } else if (updown_star0 < STRIP_SIZE-VERT_SIZE) {
92 updown_star = STRIP_SIZE-VERT_SIZE;
93 updown_bright = 1 << (STRIP_SIZE-VERT_SIZE-updown_star0);
95 updown_star = updown_star0;
100 static unsigned char updown_star_pixel(unsigned char pos)
102 if (pos >= VERT_SIZE && pos < STRIP_SIZE-VERT_SIZE)
105 if (pos == updown_star) {
106 send_rgb(updown_bright, updown_bright, updown_bright);
122 /* down running stars at the beginning/end of the strip */
123 static unsigned char down_star, down_star0, down_bright;
125 static void down_star_init()
127 down_star0 = STRIP_SIZE;
130 static void down_star_frame()
132 if (down_star0 == 0) {
133 down_star0 = STRIP_SIZE;
138 if (down_star0 < 8) {
140 down_bright = 1 << down_star0;
142 down_star = down_star0;
147 static unsigned char down_star_pixel(unsigned char pos)
149 if (pos == down_star) {
150 send_rgb(down_bright, down_bright, down_bright);
162 static unsigned char midstar_pos0, midstar_pos, midstar_bright, midstar_color;
164 static void midstar_init()
166 midstar_pos0 = STRIP_SIZE/2;
170 static unsigned int slow_dim[] = {
171 255, 182, 130, 92, 66, 47, 33, 24, 17, 12, 8, 6, 4, 3, 2, 1,
174 static void midstar_frame()
176 unsigned char phase = (jiffies) & 0x1F;
178 midstar_bright = phase & 0x10 ? slow_dim[phase & 0x0F]
179 : slow_dim[15-(phase & 0x0F)];
182 unsigned char c = rand();
183 #ifdef CHRISTMAS_TREE
184 midstar_pos0 = 2 + (c % (STRIP_SIZE - 4));
186 midstar_pos0 -= 2 + VERT_SIZE;
187 midstar_pos0 += 16 + (c & 0x1F);
188 midstar_pos0 &= 0x3F;
189 midstar_pos0 += 2 + VERT_SIZE;
191 midstar_color += 1 + (c & 0xC0 ? 0 : 1);
194 midstar_pos = midstar_pos0 - 2;
197 static unsigned char midstar_pixel(unsigned char pos)
201 if (pos != midstar_pos)
204 if (pos > midstar_pos0) {
205 dim = pos - midstar_pos0;
209 dim = midstar_pos0 - pos;
213 dim = midstar_bright >> 2*dim;
215 switch (midstar_color & 0x7) {
216 case 0: send_rgb(dim, 0, 0); break; // red
217 case 1: send_rgb(dim, dim, dim); break; // white
218 case 2: send_rgb(0, dim, 0); break; // green
219 case 3: send_rgb(dim, 0, dim); break; // violet
220 case 4: send_rgb(dim, dim >> 2, 0); break; // yellow/orange
221 case 5: send_rgb(0, dim, dim >> 2); break; // cyan
222 case 6: send_rgb(0, 0, dim); break; // blue
223 case 7: send_rgb(dim, dim, 0); break; // yellow
232 static void background(unsigned char pos)
234 #ifdef CHRISTMAS_TREE
235 switch ((pos >> 3) & 3) {
236 //case 0: if (pos & 1) send_rgb(7, 0, 7); else send_rgb(0, 7, 5);
237 //case 0: if (pos & 1) send_rgb(0, 0, 7); else send_rgb(7, 7, 7);
238 case 0: if (pos & 1) send_rgb(0, 0, 7); else send_rgb(0, 7, 0);
240 case 1: if (pos & 1) send_rgb(7, 0, 7); else send_rgb(7, 0, 0);
242 case 2: if (pos & 1) send_rgb(7, 5, 0); else send_rgb(7, 7, 7);
244 case 3: if (pos & 1) send_rgb(7, 0, 0); else send_rgb(0, 7, 0);
258 _delay_ms(3000/8); // wait for a bit and then increase the CPU clock
264 #ifdef CHRISTMAS_TREE
276 #ifdef CHRISTMAS_TREE
283 for (i = 0; i < STRIP_SIZE; i++) {
284 #ifdef CHRISTMAS_TREE
285 if (down_star_pixel(i)) continue;
287 if (updown_star_pixel(i)) continue;
289 if (midstar_pixel(i)) continue;