* - ( 9) RB3 - CCP1 PWM for red LED
* - (10) RB4 - rocker switch position B (right)
* - (11) RB5 - rocker switch position A (left)
- * - (12) RB6 - unused
- * - (13) RB7 - unused
+ * - (12) RB6 - unused (future crystal)
+ * - (13) RB7 - unused (future crystal)
* - (14) Vdd
* - (15) RA6 - unused
* - (16) RA7 - CCP2 PWM for grn LED
*
*/
-#define RUNAT32MHZ /* else 16 MHz */
-
#include <htc.h>
#include <stdlib.h>
#include "picinit.h"
+#include "unused.h"
#include "buttons.h"
#include "rgb.h"
-#include "unused.h"
+#include "timer.h"
+#include "adc_random.h"
-#define STEP_SIZE 32 /* ms */
+#define AUTO_OFF_COUNT 549316UL /* 5 hrs in 32.768 ms units */
#define reset_steps() do { incolor_steps = 1; fade_steps = 0; } \
while (0)
#define rand_u8() (rand() & 0xff)
#define leds_set(r,g,b,w) rgb_set((r).value >> 7, \
(g).value >> 7, \
(b).value >> 7, \
- (w).value >> 7)
+ 0)
+
+#define dbgpin_init() \
+do { \
+ /* Set RA2 as output low */ \
+ PORTA &= ~0x04; \
+ TRISA &= ~0x04; \
+} while (0)
+
+#define dbgpin_high() PORTA |= 0x04;
+#define dbgpin_low() PORTA &= ~0x04;
typedef struct {
int value;
int increment;
- char remainder;
+ signed char remainder;
} led_t;
#define INIT_LED { 0, 0, 0 }
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();
+ srand((adc_random() << 8) + adc_random());
reset_steps();
if (buttons_on())
rgb_on();
+ dbgpin_high();
while (1) {
unsigned char buttons = buttons_read();
- if ((buttons & (IN_ROCKERA | IN_ROCKERB))) {
+ 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)) {
+ if (!(speed & 4) && (buttons & IN_PUSHBTN))
speed |= 4;
- } else if ((speed & 4) && !(buttons & IN_PUSHBTN)) {
+ else if ((speed & 4) && !(buttons & IN_PUSHBTN)) {
speed = (speed + 1) & ~4;
reset_steps();
}
/* Next incolor and fade steps */
incolor_steps = rand_incolor_steps(speed);
- fade_steps = (buttons & IN_ROCKERA) ? 1 : rand_fade_steps(speed);
+ fade_steps = rand_fade_steps(speed);
/* Compute increment and remainder for each led */
red.increment = (newr - red.value) / fade_steps;
wht.increment = (neww - wht.value) / fade_steps;
wht.remainder = neww - (wht.value + wht.increment * fade_steps);
}
- __delay_ms(STEP_SIZE); /* step should be start to start... */
- } else {
- rgb_off();
- buttons_sleep();
- reset_steps();
- rgb_on();
- red.value = 0;
- grn.value = 0;
- blu.value = 0;
- wht.value = 0;
+ dbgpin_low();
+ timer_owait(); /* wait 32 ms since last return from last call() */
+ dbgpin_high();
}
}
return 0;