GIE = 1; /* enable global interrupts */
}
+void btn_pben()
+{
+ ndi();
+ IOCBP0 = 1; IOCBN0 = 1; IOCBF0 = 0;
+ nei();
+}
+
+/* Disable the pushbutton from user code */
+void btn_pbdis()
+{
+ ndi();
+ IOCBP0 = 0; IOCBN0 = 0; IOCBF0 = 0;
+ nei();
+}
+
+/* Enable the rocker switch from user code */
+void btn_rsen()
+{
+ ndi();
+ IOCBP4 = 1; IOCBN4 = 1; IOCBF4 = 0;
+ IOCBP5 = 1; IOCBN5 = 1; IOCBF5 = 0;
+ nei();
+}
+
+/* Disable the rocker switch from user code */
+void btn_rsdis()
+{
+ ndi();
+ IOCBP4 = 0; IOCBN4 = 0; IOCBF4 = 0;
+ IOCBP5 = 0; IOCBN5 = 0; IOCBF5 = 0;
+ nei();
+}
+
void btn_isr()
{
if (IOCIF) {
#define btn_pb() (RB0)
/* Read the current state of the rocker switch */
-#define btn_rs() ((RB4 + ((unsigned char)RB5 << 1)) % 3)
+#define btn_rs() (RB4 + ((unsigned char)RB5 << 1))
/* Enable the pushbutton from user code */
-#define btn_pben() do { \
- ndi(); \
- IOCBP0 = 1; IOCBN0 = 1; IOCBF0 = 0; \
- nei(); \
- } while (0)
+void btn_pben();
/* Disable the pushbutton from user code */
-#define btn_pbdis() do { \
- ndi(); \
- IOCBP0 = 0; IOCBN0 = 0; IOCBF0 = 0; \
- nei(); \
- } while (0)
+void btn_pbdis();
/* Enable the rocker switch from user code */
-#define btn_rsen() do { \
- ndi(); \
- IOCBP4 = 1; IOCBN4 = 1; IOCBF4 = 0; \
- IOCBP5 = 1; IOCBN5 = 1; IOCBF5 = 0; \
- nei(); \
- } while (0)
+void btn_rsen();
/* Disable the rocker switch from user code */
-#define btn_rsdis() do { \
- ndi(); \
- IOCBP4 = 0; IOCBN4 = 0; IOCBF4 = 0; \
- IOCBP5 = 0; IOCBN5 = 0; IOCBF5 = 0; \
- nei(); \
- } while (0)
+void btn_rsdis();
/* Initialize the button module */
void btn_init();
bit _isr_gie; /* Used to store the state of GIE for nested ndi()/nei() */
unsigned char _isr_di; /* Count of nested ndi() */
+void ndi()
+{
+ if (_isr_di++ == 0) {
+ _isr_gie = GIE;
+ di();
+ }
+}
+
+/* Nested enable interrupts inline function. Should be OK even in ISR. */
+void nei()
+{
+ if (--_isr_di == 0 && _isr_gie)
+ ei();
+}
+
void interrupt isr()
{
tmr_isr();
extern unsigned char _isr_di;
/* Nested disable interrupts inline function. Should be OK even in ISR. */
-#define ndi() \
- do { \
- if (_isr_di++ == 0) { \
- _isr_gie = GIE; \
- di(); \
- } \
- } while (0)
+void ndi();
/* Nested enable interrupts inline function. Should be OK even in ISR. */
-#define nei() \
- do { \
- if (--_isr_di == 0 && _isr_gie) \
- ei(); \
- } while (0)
+void nei();
void interrupt isr();
#define AUTO_OFF_COUNT 549316UL /* 5 hrs in 32.768 ms units */
#define AUTO_ON_COUNT 2087402UL /* 19 hrs in 32.768 ms units */
-#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 */
+/* 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 };
+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;
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 rgb_init();
/* Turn on the rgb. Outputs are zero, or last values set by rgb_set(). */
-#define rgb_on() do { TMR2ON = 1; } while (0)
+#define rgb_on() (TMR2ON = 1)
/* Turn off the rgb, first setting outputs to zero. */
void rgb_off();
nei();
if (ids) {
for (unsigned char i = 0; t == -1 && i < TASK_COUNT; i++) {
- if (bit_get(ids, _task_bitno))
+ if (bit_get(ids, _task_bitno)) {
t = _task_bitno;
+ ndi();
+ bit_clr(_task_ids, t);
+ nei();
+ }
if (++_task_bitno == TASK_COUNT)
_task_bitno = 0;
}
}
-#if 0 /* Not until we have a crystal and can wake from sleep via tmr module */
+#if 0
+ /* Something like this when we have a crystal. But watch for the race of
+ * going to sleep when a task is posted by an ISR.
+ */
else
SLEEP();
#endif
} while (t == -1 && block == 1);
- if (t >= 0) {
- ndi();
- bit_clr(_task_ids, t);
- nei();
- }
return t;
}
extern task_id_t _task_bitno;
/* Post task t. No need for ndi() since bit_set is a single instruction. */
-#define task_post(t) do { bit_set(_task_ids, t); } while (0)
+#define task_post(t) (bit_set(_task_ids, t))
/* Initialize the task subsystem */
-#define task_init() do { _task_ids = 0; _task_bitno = 0; } while (0)
+#define task_init() (_task_ids = 0)
/* Returns non-zero if one or more tasks are posted. Does not block. */
bit task_check();