X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=main.c;h=37fda9036ac1083a474eca0d02a1cd18a47932c8;hb=8c7b4fef50432ef0775b00b3fe7737a1b924b1af;hp=b93a564a03945e98a5678b345a980744e8524db2;hpb=3b8d0e786f15ed9c2a0f2460aa1473ae9f6a0b4d;p=rgblamp.git diff --git a/main.c b/main.c index b93a564..37fda90 100644 --- a/main.c +++ b/main.c @@ -38,6 +38,7 @@ #include #include "picinit.h" #include "unused.h" +#include "lfsr.h" #include "btn.h" #include "rgb.h" #include "tmr.h" @@ -45,14 +46,16 @@ #include "task.h" #include "adc_random.h" +//#define AUTO_OFF_COUNT 150 /* 5 mins on*/ +//#define AUTO_ON_COUNT 300 /* 10 mins off */ //#define AUTO_OFF_COUNT 450 /* 15 mins on*/ //#define AUTO_ON_COUNT 1350 /* 45 mins off */ -#define AUTO_OFF_COUNT 600 /* 20 mins on*/ -#define AUTO_ON_COUNT 1200 /* 40 mins off */ +//#define AUTO_OFF_COUNT 600 /* 20 mins on*/ +//#define AUTO_ON_COUNT 1200 /* 40 mins off */ //#define AUTO_OFF_COUNT 450 /* 2 hours on*/ //#define AUTO_ON_COUNT 1350 /* 22 hours off */ -//#define AUTO_OFF_COUNT 9000U /* 5 hrs in 2 sec units */ -//#define AUTO_ON_COUNT 34200U /* 19 hrs in 2 sec units */ +#define AUTO_OFF_COUNT 9000U /* 5 hrs in 2 sec units */ +#define AUTO_ON_COUNT 34200U /* 19 hrs in 2 sec units */ #define dbgpin_init() do { \ /* Set RA2 as output low */ \ RA2 = 0; \ @@ -66,7 +69,7 @@ enum { /* Operating modes */ MODE_SOLID = 0, /* Cycle through colors[][] before next mode */ //MODE_CANDLE, - MODE_FADE, /* Auto cycle through colors */ + MODE_CYCLE, /* Auto cycle through colors */ MODE_PARTY, /* Random yet fast incolor and fade */ MODE_COUNT, @@ -87,10 +90,12 @@ enum { BRIGHT_MIN = 1, /* ... by min and max. */ BRIGHT_INIT = 42, /* later, get from eeprom */ STD_FADE = 16, /* Fade time in 32.768 ms units */ - STD_INCOLOR = 29491, /* Time in color when MODE_FADE, in 32.768 ms units */ + STD_INCOLOR = 29491, /* Time in color when MODE_CYCLE, in 32.768 ms units */ PARTY_MIN = 8, /* Min party fade and incolor units */ - PARTY_RANGE = 8, /* Party fade/incolor range mask for rand() */ + PARTY_RANGE = 8, /* Party fade/incolor range mask for lfsr_get() */ /* ... see start_fade() */ + CFG_ADDR = 0, /* EEPROM address of start of configuration */ + CFG_DELAY = 92, /* 3 seconds in 32.768 msec units */ }; typedef struct { @@ -116,63 +121,83 @@ const unsigned char colors[COLOR_COUNT][LED_COUNT] = { unsigned char mode = MODE_SOLID; unsigned char color = COLOR_WHITE; +signed char bright = BRIGHT_INIT; +bit bright_up; led_t red; led_t grn; led_t blu; led_t wht; bit on; int fade_steps; -signed char bright = BRIGHT_INIT; -bit bright_up; signed char pbHeldCount; -/* Return the constrained brightness level for use in computing RGB values */ -unsigned char bright_get() +void cfg_write() { - if (bright > BRIGHT_MAX) - return BRIGHT_MAX; - else if (bright < BRIGHT_MIN) - return BRIGHT_MIN; - else - return bright; + unsigned char addr = CFG_ADDR; + + eeprom_write(addr++, mode); + eeprom_write(addr++, color); + eeprom_write(addr++, bright); } -/* RGB values will not illuminate the LED */ -unsigned char led_get(unsigned value) +void cfg_read() { - value = (value * bright_get()) >> 8; -#ifdef CEIL256 - if (value && value < 0x26) - return 0x26; -#else - if (value && value < 4) - return 4; -#endif - return value; + unsigned char addr = CFG_ADDR; + unsigned char tmp; + + tmp = eeprom_read(addr++); + if (tmp < MODE_COUNT) + mode = tmp; + + tmp = eeprom_read(addr++); + if (tmp < COLOR_COUNT) + color = tmp; + + tmp = eeprom_read(addr++); + if ((signed char)tmp >= BRIGHT_BOTTOM && (signed char)tmp <= BRIGHT_TOP) + bright = tmp; +} + +/* Combine LED color value and brightness level to generate an RGB value. + * bright will be BRIGHT_MIN...BRIGHT_MAX + * + * @param value 0...1023 (6 bit color, left shifted 4 bits, for 10 bits) + * @param b brightness value BRIGHT_MIN...BRIGHT_MAX + * @return An RGB drive value, 0...255 + */ +unsigned char led_get(int value, signed char b) +{ + return (unsigned long)value * b / 4 / BRIGHT_MAX; } -/* Set the LEDs using both color and brightness values. */ +/* Set the LEDs using color values and current brightness. */ void leds_set() { - rgb_set(led_get((red).value), - led_get((grn).value), led_get((blu).value), - led_get((wht).value)); + signed char b; + + if (bright > BRIGHT_MAX) + b = BRIGHT_MAX; + else if (bright < BRIGHT_MIN) + b = BRIGHT_MIN; + else + b = bright; + rgb_set(led_get((red).value, b), led_get((grn).value, b), + led_get((blu).value, b), led_get((wht).value, b)); } void start_fade() { - /* 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. + /* RGB PWM values are 8 bits. Color values are 12 bits. See led_get() + * for the conversion of color values and brightness to RGB values. */ int newr, newg, newb, neww; /* Select the destination color and fade-to time depending upon mode. */ fade_steps = STD_FADE; if (mode == MODE_PARTY) { - color = rand() % COLOR_COUNT; - fade_steps = PARTY_MIN + (rand() % PARTY_RANGE); - } else if (mode == MODE_FADE) { + color = lfsr_get() % COLOR_COUNT; + fade_steps = PARTY_MIN + (lfsr_get() % PARTY_RANGE); + } else if (mode == MODE_CYCLE) { if (++color == COLOR_COUNT) color = 0; } @@ -210,6 +235,7 @@ void turnOn() void turnOff() { /* Event on to off, either by switch or auto-off timer */ + tmr_stop(TMR_CFG); tmr_stop(TMR_INCOLOR); tmr_stop(TMR_FADE); rgb_off(); @@ -222,6 +248,8 @@ void turnOff() void pb_clicked() { if (on) { + unsigned char omode = mode; + if (mode == MODE_SOLID) { if (++color == COLOR_COUNT) { color = 0; @@ -232,12 +260,16 @@ void pb_clicked() mode = 0; color = 0; } + if (mode != omode || mode == MODE_SOLID) + tmr_start(TMR_CFG, CFG_DELAY); start_fade(); } } void pb_held() { + signed char obright = bright; + /* The button has been held. Change the color magnitude. */ if (bright_up) { if (bright == BRIGHT_TOP) @@ -250,6 +282,8 @@ void pb_held() else bright--; } + if (bright != obright) + tmr_start(TMR_CFG, CFG_DELAY); leds_set(); } @@ -318,10 +352,10 @@ void fade_task() blu.value += blu.remainder; wht.value += wht.remainder; tmr_stop(TMR_FADE); - if (mode == MODE_FADE) + if (mode == MODE_CYCLE) tmr_start(TMR_INCOLOR, STD_INCOLOR); else if (mode == MODE_PARTY) - tmr_start(TMR_INCOLOR, PARTY_MIN + (rand() % PARTY_RANGE)); + tmr_start(TMR_INCOLOR, PARTY_MIN + (lfsr_get() % PARTY_RANGE)); } leds_set(); } @@ -339,19 +373,11 @@ void auto_offon_task() } } -void config_read() -{ - /* Read configuration fields from eeprom, notably current mode and - * brightness level. - */ - /* FIXME: implement this */ -} - void user_boot() { dbgpin_high(); - srand((adc_random() << 8) + adc_random()); - config_read(); + lfsr_init((adc_random() << 8) + adc_random()); + cfg_read(); rs_task(); } @@ -379,6 +405,9 @@ void user_tasks(unsigned char block) case TASK_TMR32: /* auto on/off event */ auto_offon_task(); break; + case TASK_CFG: /* Save config to EEPROM event */ + cfg_write(); + break; } } }