- 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 long auto_off = 0;
-
-
- pic_init();
- unused_init();
- buttons_init();
- rgb_init();
- timer_init();
- dbgpin_init();
-
- reset_steps();
- if (buttons_on())
- rgb_on();
-
- dbgpin_high();
- while (1) {
- unsigned char buttons = buttons_read();
-
- if ((buttons & IN_ROCKERB) && auto_off == 0)
- auto_off = AUTO_OFF_COUNT;
-
- if (((buttons & IN_ROCKERB) && auto_off && --auto_off == 0) ||
- (!(buttons & (IN_ROCKERA | IN_ROCKERB)))) {
- /* Sleep when auto-off time has expired or if rocker switch is
- * turned off.
- */
- rgb_off();
- dbgpin_low();
- auto_off = 0;
- buttons_sleep();
- dbgpin_high();
- reset_steps();
- rgb_on();
- red.value = 0;
- grn.value = 0;
- blu.value = 0;
- wht.value = 0;
- } else {
- /* 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) {
- fade_steps--;
- /* Continue the in-progress fade */
- 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) {
- int newr, newg, newb, neww, tmp;
-
- /* Next led color. All off is not a valid option.
- * RGB values are stored and processed as 15-bit non-negative
- * integers. Since the RGB pwm values are 8 bits in width,
- * leds_set() uses >> 7 to convert each color's value.
- */
- 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 = (buttons & IN_ROCKERA) ? 1 : 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);
- }
- dbgpin_low();
- timer_owait(); /* wait 32 ms since last return from last call() */
- dbgpin_high();
- }
+ /* 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);
+
+ /* Random # of steps to reach the new color */
+ fade_steps = min_fade_steps[speed & 3] +
+ (rand() & range_fade_steps[speed & 3]);
+
+ /* Compute increment per fade step, 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);
+
+ /* Start the fade timer */
+ tmr_stop(TMR_INCOLOR);
+ tmr_startPeriodic(TMR_FADE, 1); /* 32.768 msec */
+}
+
+void turnOn()
+{
+ dbgpin_high();
+ on = 1;
+ red.value = 0;
+ grn.value = 0;
+ blu.value = 0;
+ wht.value = 0;
+ leds_set(red, grn, blu, wht);
+ rgb_on();
+ start_fade();
+ btn_pben();
+}
+
+void turnOff()
+{
+ /* Event on to off, either by switch or auto-off timer */
+ tmr_stop(TMR_INCOLOR);
+ tmr_stop(TMR_FADE);
+ rgb_off();
+ dbgpin_low();
+ on = 0;
+}
+
+void pb_task()
+{
+ /* Is this task running nearly continuously? */
+ if (on) {
+ if (btn_pb() == BTN_PB_UP) {
+ speed = (speed + 1) & 3;
+ start_fade();