X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=main.c;h=b9a8cbcd62de300fa6beb7b91a21f73eab3d710f;hb=abb51a86d7e6cc789f84c35694c0bff042e46a48;hp=7fa14f2fab32eb238dd7f46eefd16f91731e43d6;hpb=e9763e77e5192ca658d54f346d1a046ec227be2c;p=rgblamp.git diff --git a/main.c b/main.c index 7fa14f2..b9a8cbc 100644 --- a/main.c +++ b/main.c @@ -4,156 +4,133 @@ * Created on August 16, 2010, 12:09 PM */ - -#include -//#include - #define RUNAT32MHZ /* else 16 MHz */ -#define LEDBIT 0x01 /* Port RB0 */ -#define RED_CHAN 1 -#define GRN_CHAN 2 -#define BLU_CHAN 4 -#define WHT_CHAN 8 -#define ALL_CHAN 15 -#if defined(RUNAT32MHZ) -__CONFIG(WDTE_OFF & FOSC_INTOSC); -__CONFIG(LVP_OFF & PLLEN_ON); +#include +#include +#include "picinit.h" +#include "buttons.h" +#include "rgb.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(f) (min_incolor_steps[f & 1] + \ + (rand() % range_incolor_steps[f & 1])) +#define rand_fade_steps(f) (min_fade_steps[f & 1] + \ + (rand() % range_fade_steps[f & 1])) +#define leds_set(r,g,b,w) rgb_set((r).value >> 7, \ + (g).value >> 7, \ + (b).value >> 7, 0) +// (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 fast variable, 0=slow, 1=fast. */ +#if 0 +const static unsigned min_incolor_steps[2] = { 320, 32 }; +const static unsigned range_incolor_steps[2] = { 32768, 128 }; +const static int min_fade_steps[2] = { 64, 32 }; +const static int range_fade_steps[2] = { 416, 128 }; #else -__CONFIG(WDTE_OFF); -__CONFIG(LVP_OFF); +const static unsigned min_incolor_steps[2] = { 64, 32 }; +const static unsigned range_incolor_steps[2] = { 1, 1 }; +const static int min_fade_steps[2] = { 64, 32 }; +const static int range_fade_steps[2] = { 1, 1 }; #endif -void pic_init() -{ -#if defined(RUNAT32MHZ) - OSCCON = 0b11110000; -#else /* 16 MHz */ - OSCCON = 0b01111010; -#endif - - /* OSCSTAT.HFIOFL is set when oscillator is locked (accurate within 2%) */ - while (!HFIOFL); -} - -void pwm_init() -{ - /* Initialize PWM - * CCP1 on RB3, CCP2 on RA7, CCP3 on RA3, CCP4 on RA4 - * - Fosc = 32MHz - * - Prescale = 16 - * - PRx value = 0xff - * = f(pwm) = 1.95 kHz - */ - - /* Disable output on PWM Rxn pins */ - TRISA |= 0b10011000; - TRISB |= 0b00001000; - - /* Configure ECCP1 */ - CCP1CON = 0b00001100; - CCPR1L = 0; /* Initial PWM value; only using 8 LSBs */ - - /* Configure ECCP2 */ - APFCON0 |= 0b00001000; /* Use alternate output pin RA7 */ - CCP2CON = 0b00001100; - CCPR2L = 0; /* Initial PWM value; only using 8 LSBs */ - - /* Configure CCP3 */ - CCP3CON = 0b00001100; - CCPR3L = 0; /* Initial PWM value; only using 8 LSBs */ - - /* Configure CCP4 */ - CCP4CON = 0b00001100; - CCPR4L = 0; /* Initial PWM value; only using 8 LSBs */ - - /* Configure Timer2 */ - CCPTMRS = 0; /* All CCPx use Timer 2 */ - TMR2IF = 0; - PR2 = 0xff; - T2CON = 0b00000111; - - /* Enable PWM outputs after Timer 2 overflows */ - while (!TMR2IF); - TRISA &= ~0b10011000; - TRISB &= ~0b00001000; -} - -void led_init() -{ - PORTB &= ~LEDBIT; /* Led is RB0 */ - TRISB &= ~LEDBIT; -} - -void led_set(unsigned char led) -{ - if (led) - PORTB |= LEDBIT; - else - PORTB &= ~LEDBIT; -} - -void pwm_set(unsigned char channels, unsigned char step) -{ - if (channels & RED_CHAN) - CCPR1L = step; - if (channels & GRN_CHAN) - CCPR2L = step; - if (channels & BLU_CHAN) - CCPR3L = step; - if (channels & WHT_CHAN) - CCPR4L = step; -} - -void delay() -{ - for (unsigned counter = 0; counter < 10000; counter++); -} - -void ramp_up(unsigned char channels) -{ - unsigned char step = 0; - - do { - pwm_set(channels, step++); - delay(); - } while (step != 0); -} - -void ramp_down(unsigned char channels) -{ - unsigned char step = 255; - - do { - pwm_set(channels, step--); - delay(); - } while (step != 255); -} - -void ramp_up_down(unsigned char channels) -{ - ramp_up(channels); - ramp_down(channels); -} - int main(void) { - unsigned char fwd = 1; - unsigned char step = 0; + led_t red = INIT_LED; + led_t grn = INIT_LED; + led_t blu = INIT_LED; + led_t wht = INIT_LED; + unsigned char fast = 0; + unsigned incolor_steps; + int fade_steps; pic_init(); - led_init(); - pwm_init(); + buttons_init(); + rgb_init(); + reset_steps(); + + if (buttons_on()) + rgb_on(); + while (1) { - ramp_up(RED_CHAN); - ramp_up(GRN_CHAN); - ramp_down(RED_CHAN); - ramp_up(BLU_CHAN); - ramp_down(GRN_CHAN); - ramp_up(RED_CHAN); - ramp_up(GRN_CHAN + BLU_CHAN); - ramp_down(ALL_CHAN); - ramp_up_down(WHT_CHAN); + unsigned char buttons = buttons_read(); + + if ((buttons & (IN_ROCKERA | IN_ROCKERB))) { + /* Crappy way to detect rising edges to change state of fast var */ + if (!(fast & 2) && (buttons & IN_PUSHBTN)) { + fast |= 2; + } else if ((fast & 2) && !(buttons & IN_PUSHBTN)) { + fast &= ~2; + fast = 1 - fast; + reset_steps(); + } + + 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; + + /* 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(fast); + fade_steps = (buttons & IN_ROCKERA) ? 1 : rand_fade_steps(fast); + + /* 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(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; + } } return 0; }