* - ( 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
#include <htc.h>
#include <stdlib.h>
#include "picinit.h"
+#include "unused.h"
#include "buttons.h"
#include "rgb.h"
-#include "unused.h"
+#include "tmr.h"
+#include "adc_random.h"
-#define STEP_SIZE 32 /* ms */
+#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 reset_steps() do { incolor_steps = 1; fade_steps = 0; } \
- while (0)
+ while (0)
#define rand_u8() (rand() & 0xff)
#define rand_u16() ((rand() << 8) + rand_u8())
#define rand_incolor_steps(s) (min_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, \
- (w).value >> 7)
+ (g).value >> 7, \
+ (b).value >> 7, \
+ 0)
+#define dbgpin_init() do { \
+ /* Set RA2 as output low */ \
+ RA2 = 0; \
+ TRISA2 = 0; \
+ } while (0)
+#define dbgpin_high() (RA2 = 1)
+#define dbgpin_low() (RA2 = 0)
+#define dbgpin_toggle() (RA2 = (LATA2 == 0) ? 1 : 0)
typedef struct {
int value;
int increment;
- char remainder;
+ signed char remainder;
} led_t;
#define INIT_LED { 0, 0, 0 }
const static int range_fade_steps[4] = { 1, 1, 1, 1 };
#endif
-#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;
-
int main(void)
{
led_t red = 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();
+ tmr_init();
dbgpin_init();
+ srand((adc_random() << 8) + adc_random());
reset_steps();
if (buttons_on())
rgb_on();
dbgpin_high();
+ tmr_startPeriodic(TMR_FADE, 1); /* 32.768 msec */
while (1) {
unsigned char buttons = buttons_read();
- if ((buttons & (IN_ROCKERA | IN_ROCKERB))) {
+ if ((buttons & IN_ROCKERB) && auto_off == 0)
+ tmr_startPeriodic(TMR_AUTO_OFFON, AUTO_OFF_COUNT);
+
+ if ((buttons & IN_ROCKERB) && tmr_fired(TMR_AUTO_OFFON) ||
+ (!(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();
}
}
leds_set(red, grn, blu, wht);
} else if (--incolor_steps == 0) {
- int newr, newg, newb, neww, tmp;
+ int newr, newg, newb, neww;
/* Next led color. All off is not a valid option.
* RGB values are stored and processed as 15-bit non-negative
/* 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.remainder = neww - (wht.value + wht.increment * fade_steps);
}
dbgpin_low();
- __delay_ms(STEP_SIZE); /* step should be start to start... */
- dbgpin_high();
- } else {
- rgb_off();
- dbgpin_low();
- buttons_sleep();
+ while (!tmr_fired(TMR_FADE));
dbgpin_high();
- reset_steps();
- rgb_on();
- red.value = 0;
- grn.value = 0;
- blu.value = 0;
- wht.value = 0;
}
}
return 0;