- led_t red = INIT_LED;
- led_t grn = INIT_LED;
- led_t blu = INIT_LED;
- led_t wht = INIT_LED;
- unsigned char speed = 0;
- unsigned incolor_steps;
- int fade_steps;
- unsigned char buttons, last_buttons;
-
- pic_init();
- unused_init();
- buttons_init();
- rgb_init();
- tmr_init();
- dbgpin_init();
-
- srand((adc_random() << 8) + adc_random());
- reset_steps();
- if (buttons_on())
- rgb_on();
-
- dbgpin_high();
- last_buttons = 0;
- buttons = buttons_read();
- while (1) {
- /* Wait for an event. Timer firing or button state change.
- * When we have a crystal, we can sleep instead. Also, soon we
- * can transition button state changes to the ISR.
- */
- dbgpin_low();
- while (!tmr_events() && last_buttons == buttons) {
- last_buttons = buttons;
- buttons = buttons_read();
- }
- dbgpin_high();
-
- if (((buttons & IN_ROCKERB) && !tmr_on(TMR_AUTO_OFFON)) ||
- !(last_buttons & (IN_ROCKERB | IN_ROCKERA))) {
- /* Event: off to on */
- tmr_startPeriodic(TMR_AUTO_OFFON, AUTO_OFF_COUNT);
- tmr_startPeriodic(TMR_FADE, 1); /* 32.768 msec */
-
- } else if (((buttons & IN_ROCKERB) && tmr_fired(TMR_AUTO_OFFON)) ||
- (!(buttons & (IN_ROCKERA | IN_ROCKERB)))) {
- /* Event on to off, either by switch or auto-off timer */
- rgb_off();
- dbgpin_low();
- tmr_stop(TMR_AUTO_OFFON);
- tmr_stop(TMR_FADE);
- buttons_sleep();
- dbgpin_high();
- rgb_on();
- red.value = 0;
- grn.value = 0;
- blu.value = 0;
- wht.value = 0;
- reset_steps();
- tmr_startPeriodic(TMR_FADE, 1); /* 32.768 msec */
-
- } else if (tmr_fired(TMR_FADE)) {
- /* Other actions, driven by the fade timer for now */
-
- /* Crappy way to detect rising edges to change state of speed var */
- if (!(speed & 4) && (buttons & IN_PUSHBTN))
- speed |= 4;
- else if ((speed & 4) && !(buttons & IN_PUSHBTN)) {
- speed = (speed + 1) & ~4;
- reset_steps();
- }
-
- if (fade_steps) {
- /* Continue the in-progress fade */
- fade_steps--;
- red.value += red.increment;
- grn.value += grn.increment;
- blu.value += blu.increment;
- wht.value += wht.increment;
- if (fade_steps == 0) {
- red.value += red.remainder;
- grn.value += grn.remainder;
- blu.value += blu.remainder;
- wht.value += wht.remainder;
- }
- leds_set(red, grn, blu, wht);
-
- } else if (--incolor_steps == 0) {
- /* RGB PWM values are 8 bits, but computations are done in 15
- * (leaving room for a sign bit), so leds_set() uses >>7 to convert
- * to PWM values.
- */
- int newr, newg, newb, neww;
-
- /* New RGB values; all zero is not a valid option */
- do {
- newr = rand();
- newg = rand();
- newb = rand();
- neww = rand();
- } while (newr == 0 && newg == 0 && newb == 0 && neww == 0);
-
- /* Next incolor and fade steps */
- incolor_steps = rand_incolor_steps(speed);
- fade_steps = rand_fade_steps(speed);
-
- /* Compute increment and remainder for each led */
- red.increment = (newr - red.value) / fade_steps;
- red.remainder = newr - (red.value + red.increment * fade_steps);
- grn.increment = (newg - grn.value) / fade_steps;
- grn.remainder = newg - (grn.value + grn.increment * fade_steps);
- blu.increment = (newb - blu.value) / fade_steps;
- blu.remainder = newb - (blu.value + blu.increment * fade_steps);
- wht.increment = (neww - wht.value) / fade_steps;
- wht.remainder = neww - (wht.value + wht.increment * fade_steps);
- }
- }