X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=main.c;h=4f36d146b1133f58aa7e32e07ddd4c05f9fc5831;hb=ad6305c1dcd38ee6e1365481ee8920b3d2e07dfc;hp=abf109814c0e2d93a2fb47f12806bd34f8c2976e;hpb=5c74e1a22c444b8769e0ce82975414f1c72b7b0e;p=rgblamp.git diff --git a/main.c b/main.c index abf1098..4f36d14 100644 --- a/main.c +++ b/main.c @@ -1,100 +1,171 @@ /* * File: main.c * - * Created on August 16, 2010, 12:09 PM + * PWM test program + * + * PIC resources in use, 18-pin DIP, by pin: + * - ( 1) RA2 - unused + * - ( 2) RA3 - CCP3 PWM for blu LED + * - ( 3) RA4 - CCP4 PWM for wht LED. ICSP pin 6, PGM/LVP. + * - ( 4) RA5 - ICSP pin 1, MCLR#/Vpp + * - ( 5) Vss + * - ( 6) RB0 - pushbutton + * - ( 7) RB1 - unused + * - ( 8) RB2 - unused + * - ( 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 + * - (14) Vdd + * - (15) RA6 - unused + * - (16) RA7 - CCP2 PWM for grn LED + * - (17) RA0 - unused + * - (18) RA1 - unused + * */ -#define RUNAT32MHZ /* else 16 MHz */ - #include #include #include "picinit.h" #include "buttons.h" #include "rgb.h" +#include "unused.h" + +#define STEP_SIZE 32 /* ms */ +#define reset_steps() do { incolor_steps = 1; fade_steps = 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] + \ + (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, \ + (w).value >> 7) + +typedef struct { + int value; + int increment; + char remainder; +} led_t; +#define INIT_LED { 0, 0, 0 } + +/* The index of all step arrays is the speed variable */ +#if 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 -#define random_rgb() (rand() >> 7) /* 0...255 */ -#define random_time() (rand() >> 5) /* 0...1024 */ -#define min_incolor_time() 512 -#define min_fade_time() 512 +#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) { - unsigned char red = 0, grn = 0, blu = 0; //, wht = 0; - char fadestep_red, fadestep_grn, fadestep_blu; //, fadestep_wht; - unsigned char incolor_time = 0; - unsigned char fade_time = 0; - unsigned char fast = 0; + led_t red = INIT_LED; + led_t grn = INIT_LED; + led_t blu = INIT_LED; + led_t wht = INIT_LED; + unsigned char speed = 0; + unsigned incolor_steps; + int fade_steps; pic_init(); + unused_init(); buttons_init(); rgb_init(); + dbgpin_init(); - if (buttons_on()) { + reset_steps(); + if (buttons_on()) rgb_on(); - red = random_rgb(); - grn = random_rgb(); - blu = random_rgb(); - //wht = random_rgb(); - rgb_set(red, grn, blu, 0); //wht); - } + dbgpin_high(); while (1) { unsigned char buttons = buttons_read(); if ((buttons & (IN_ROCKERA | IN_ROCKERB))) { - if (buttons & IN_PUSHBTN) { - if (!fast) { - incolor_time = 0; - fade_time = 0; - fast = 1; - } else - fast = 0; + /* Crappy way to detect rising edges to change state of speed var */ + if (!(speed & 4) && (buttons & IN_PUSHBTN)) { + speed |= 4; + } else if ((speed & 4) && !(buttons & IN_PUSHBTN)) { + speed = (speed + 1) & ~4; + reset_steps(); } - if (fade_time) { - red += fadestep_red; - grn += fadestep_grn; - blu += fadestep_blu; - //wht += fadestep_wht; - rgb_set(red, grn, blu, 0); // wht); - fade_time--; - } else if (incolor_time) - incolor_time--; - else /* fade_time == 0 && incolor_time == 0 */ { - unsigned char newr, newg, newb, neww; - - /* Determine next color state */ - newr = random_rgb(); - newg = random_rgb(); - newb = random_rgb(); - //neww = random_rgb(); - - /* Calculate new incolor_time and fade_time */ - if (buttons & IN_ROCKERA) { - incolor_time = 1 + random_time(); - fade_time = 1; - } else /* (buttons & IN_ROCKERB) */ { - incolor_time = min_incolor_time() + random_time() / 2; - fade_time = min_fade_time() + random_time() / 2; + if (fade_steps) { + fade_steps--; + /* Continue the in-progress fade */ + red.value += red.increment; + grn.value += grn.increment; + blu.value += blu.increment; + wht.value += wht.increment; + if (fade_steps == 0) { + red.value += red.remainder; + grn.value += grn.remainder; + blu.value += blu.remainder; + wht.value += wht.remainder; } + leds_set(red, grn, blu, wht); + } else if (--incolor_steps == 0) { + int newr, newg, newb, neww, tmp; - if (fast) { - incolor_time = 1 + incolor_time / 8; - fade_time = 1 + fade_time / 8; - } + /* Next led color. All off is not a valid option. + * RGB values are stored and processed as 15-bit non-negative + * integers. Since the RGB pwm values are 8 bits in width, + * leds_set() uses >> 7 to convert each color's value. + */ + do { + newr = rand(); + newg = rand(); + newb = rand(); + neww = rand(); + } while (newr == 0 && newg == 0 && newb == 0 && neww == 0); + + /* Next incolor and fade steps */ + incolor_steps = rand_incolor_steps(speed); + fade_steps = (buttons & IN_ROCKERA) ? 1 : rand_fade_steps(speed); - fadestep_red = ((int)newr - red) / fade_time; - fadestep_grn = ((int)newg - red) / fade_time; - fadestep_blu = ((int)newb - red) / fade_time; - //fadestep_wht = ((int)neww - red) / fade_time; + /* Compute increment and remainder for each led */ + red.increment = (newr - red.value) / fade_steps; + red.remainder = newr - (red.value + red.increment * fade_steps); + grn.increment = (newg - grn.value) / fade_steps; + grn.remainder = newg - (grn.value + grn.increment * fade_steps); + blu.increment = (newb - blu.value) / fade_steps; + blu.remainder = newb - (blu.value + blu.increment * fade_steps); + wht.increment = (neww - wht.value) / fade_steps; + wht.remainder = neww - (wht.value + wht.increment * fade_steps); } - __delay_ms(10); + dbgpin_low(); + __delay_ms(STEP_SIZE); /* step should be start to start... */ + dbgpin_high(); } else { rgb_off(); + dbgpin_low(); buttons_sleep(); - incolor_time = 0; - fade_time = 0; + dbgpin_high(); + reset_steps(); rgb_on(); + red.value = 0; + grn.value = 0; + blu.value = 0; + wht.value = 0; } } return 0;