#include "btn.h"
#include "rgb.h"
#include "tmr.h"
-#include "adc_random.h"
#include "task.h"
+#include "adc_random.h"
-#if 0
#define AUTO_OFF_COUNT 549316UL /* 5 hrs in 32.768 ms units */
#define AUTO_ON_COUNT 2087402UL /* 19 hrs in 32.768 ms units */
-#else
-#define AUTO_OFF_COUNT 1831 /* 1 minute in 32.768 ms units */
-#define AUTO_ON_COUNT 3662 /* 2 minutes in 32.768 ms units */
-#endif
-#define rand_u8() (rand() & 0xff)
-#define rand_u16() ((rand() << 8) + rand_u8())
-#define rand_incolor_steps(s) (min_incolor_steps[s & 3] + \
- (rand() % range_incolor_steps[s & 3]))
-#define rand_fade_steps(s) (min_fade_steps[s & 3] + \
- (rand() % range_fade_steps[s & 3]))
-#define leds_set(r,g,b,w) rgb_set((r).value >> 7, \
- (g).value >> 7, \
- (b).value >> 7, \
- 0)
+#define leds_set(r,g,b,w) rgb_set((r).value >> 7, (g).value >> 7, \
+ (b).value >> 7, 0)
#define dbgpin_init() do { \
/* Set RA2 as output low */ \
RA2 = 0; \
signed char remainder;
} led_t;
-/* The index of all step arrays is the speed variable */
-#if 1
+/* The index of all step arrays is the speed variable. min values must be
+ * at least one. range values are bit-ANDed with rand() to generate a range, so
+ * ensure they are one less than a power of 2 and at least 1.
+ */
const static unsigned min_incolor_steps[4] = { 320, 32, 32, 1 };
-const static unsigned range_incolor_steps[4] = { 32768, 128, 32, 8 };
-const static int min_fade_steps[4] = { 64, 32, 32, 1 };
-const static int range_fade_steps[4] = { 416, 128, 32, 8 };
-#else /* for debugging */
-const static unsigned min_incolor_steps[4] = { 64, 32, 16, 8 };
-const static unsigned range_incolor_steps[4] = { 1, 1, 1, 1 };
-const static int min_fade_steps[4] = { 64, 32, 16, 8 };
-const static int range_fade_steps[4] = { 1, 1, 1, 1 };
-#endif
+const static unsigned range_incolor_steps[4] = { 32767, 127, 31, 7 };
+const static int min_fade_steps[4] = { 64, 32, 32, 8 };
+const static int range_fade_steps[4] = { 511, 127, 31, 7 };
led_t red;
led_t grn;
} while (newr == 0 && newg == 0 && newb == 0 && neww == 0);
/* Random # of steps to reach the new color */
- fade_steps = rand_fade_steps(speed);
+ 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;
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 */
}
{
dbgpin_high();
on = 1;
- rgb_on();
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()
void pb_task()
{
- if (btn_pb() == BTN_PB_UP) {
- speed = (speed + 1) & ~4;
- fade_steps = 0;
+ /* Is this task running nearly continuously? */
+ if (on) {
+ if (btn_pb() == BTN_PB_UP) {
+ speed = (speed + 1) & 3;
+ start_fade();
+ }
+ btn_pben();
}
- btn_pben();
}
void rs_task()
blu.value += blu.remainder;
wht.value += wht.remainder;
tmr_stop(TMR_FADE);
- tmr_start(TMR_INCOLOR, rand_incolor_steps(speed));
+ tmr_start(TMR_INCOLOR, min_incolor_steps[speed & 3] +
+ (rand() & range_incolor_steps[speed & 3]));
}
leds_set(red, grn, blu, wht);
}
-void auto_onoff_task()
+void auto_offon_task()
{
if (on) {
turnOff();
if (btn_rs() == BTN_RS_RIGHT)
- tmr_start(TMR_AUTO_OFFON, AUTO_OFF_COUNT);
+ tmr_start(TMR_AUTO_OFFON, AUTO_ON_COUNT);
} else /* off */ {
turnOn();
if (btn_rs() == BTN_RS_RIGHT)
- tmr_start(TMR_AUTO_OFFON, AUTO_ON_COUNT);
+ tmr_start(TMR_AUTO_OFFON, AUTO_OFF_COUNT);
}
}
{
dbgpin_high();
srand((adc_random() << 8) + adc_random());
- pb_task();
rs_task();
}
{
task_id_t tid;
- while ((tid = task_get(block))) {
+ while ((tid = task_get(block)) >= 0) {
switch (tid) {
case TASK_BTN_PB: /* pushbutton state change */
pb_task();
start_fade();
break;
case TASK_AUTO_OFFON: /* auto on/off timer has fired */
- auto_onoff_task();
+ auto_offon_task();
break;
}
}
int main(void)
{
+ /* Platform initialization */
pic_init();
unused_init();
btn_init();
/* Process tasks forever */
user_tasks(1);
+
+ /* Prevent return from main, which causes a device reset */
+ while (1);
}