From 6a050a5588787a7279218c93db50f4b47c50e151 Mon Sep 17 00:00:00 2001 From: William Toohey Date: Sun, 21 May 2017 01:05:12 +1000 Subject: [PATCH] Better LED patterns --- Firmware/PocketVoltex/Descriptors.c | 3 + Firmware/PocketVoltex/Descriptors.h | 3 - Firmware/PocketVoltex/LED.c | 2 +- Firmware/PocketVoltex/LEDPatterns.c | 162 +++++++++++++++------------ Firmware/PocketVoltex/LEDPatterns.h | 13 +-- Firmware/PocketVoltex/PocketVoltex.c | 11 +- 6 files changed, 105 insertions(+), 89 deletions(-) diff --git a/Firmware/PocketVoltex/Descriptors.c b/Firmware/PocketVoltex/Descriptors.c index 42146ca..067a30f 100644 --- a/Firmware/PocketVoltex/Descriptors.c +++ b/Firmware/PocketVoltex/Descriptors.c @@ -1,5 +1,8 @@ #include "Descriptors.h" +#include "Config.h" +#include "LED.h" + #define WEBUSB_ID 0x01 #define MS_OS_ID 0x02 diff --git a/Firmware/PocketVoltex/Descriptors.h b/Firmware/PocketVoltex/Descriptors.h index 0202f26..abc45b4 100644 --- a/Firmware/PocketVoltex/Descriptors.h +++ b/Firmware/PocketVoltex/Descriptors.h @@ -5,9 +5,6 @@ #include #include - - #include "Config.h" - #include "LED.h" /* Type Defines: */ /** Type define for the device configuration descriptor structure. This must be defined in the diff --git a/Firmware/PocketVoltex/LED.c b/Firmware/PocketVoltex/LED.c index cb638d0..2e54c51 100644 --- a/Firmware/PocketVoltex/LED.c +++ b/Firmware/PocketVoltex/LED.c @@ -120,7 +120,7 @@ void led_fade_all(uint8_t r, uint8_t g, uint8_t b, uint8_t strength) { new = 0; scales[i] = new; } - led_set_all(scales[0], scales[1], scales[2]); + led_set_all(scales[R], scales[G], scales[B]); } void led_set_all(uint8_t r, uint8_t g, uint8_t b) { diff --git a/Firmware/PocketVoltex/LEDPatterns.c b/Firmware/PocketVoltex/LEDPatterns.c index 0f30ad2..2724e77 100644 --- a/Firmware/PocketVoltex/LEDPatterns.c +++ b/Firmware/PocketVoltex/LEDPatterns.c @@ -1,28 +1,21 @@ #include "LEDPatterns.h" #include -static enum LEDMode animMode = NONE; +static uint8_t flash = 0;; static uint8_t frameCounter = 0; +static RGB_t initFlashColour = {BRIGHTNESS_MAX, BRIGHTNESS_MAX, BRIGHTNESS_MAX}; + typedef struct { uint8_t value[3]; uint8_t direction; } RGBFader; -// stuff for the different modes -// because only 1 mode is active at a time, config is stored in EEPROM, and -// modes are initialised, we can save a little RAM and store these as a union -typedef union { - struct { - uint8_t level; - int8_t dir; - RGB_t colour; - } flash; - +typedef struct { struct { uint8_t level; uint8_t dir; - RGB_t colour; + RGB_t *colour; } breathe; RGB_t singleColour; @@ -32,8 +25,6 @@ typedef union { static Patterns_t pattern; -// These can always be active and are thus not unionised. Capitalism wins again. - typedef struct { uint8_t leds[2]; uint8_t levels[2]; @@ -52,7 +43,17 @@ static KnobLights knobs[2] = { void led_knob_light_indiv(KnobLights* knob, RGB_t* colour, const uint8_t* map); void led_update_breather(uint8_t speed); +void led_update_follower(void); +void led_init_flash(void); +void led_init_breathe(void); +void led_init_follower(void); +void led_pattern_init(void) { + led_init_flash(); + led_init_follower(); +} + +// Called every 1ms uint8_t led_on_frame(void) { if(++frameCounter >= LED_MS_PER_FRAME) { frameCounter = 0; @@ -62,42 +63,24 @@ uint8_t led_on_frame(void) { } } -// Called every 1ms -void led_animate(void) { - switch(animMode) { - case INIT_FLASH: - led_update_breather(FLASH_SPEED); - if(pattern.flash.level == 0) { - led_anim_follower(); - break; - } +void led_pattern_animate(void) { + if(flash) { + led_update_breather(FLASH_SPEED); + if(pattern.breathe.level < 5) { + led_init_breathe(); + flash = 0; + return; + } + } + switch(sdvxConfig.lightPattern) { + case NONE: + led_set_all(0,0,0); + break; + case SINGLE_COLOUR: + led_set_all_rgb(&sdvxConfig.breatheColour); break; case FOLLOWER: - for(uint8_t led = 0; led < LED_COUNT; led++) { - uint8_t followDir; - RGBFader* follow; - - follow = pattern.followers + led; - followDir = follow->direction; - for(uint8_t i = 0; i < 3; i++) { - if(followDir & 1) { - if(follow->value[i] >= BRIGHTNESS_LEVELS - FOLLOW_SPEED) { - follow->direction <<= 1; - if(follow->direction == 0b1000) { - follow->direction = 0b001; - } - } else { - follow->value[i] += FOLLOW_SPEED; - } - } else { - if(follow->value[i] >= FOLLOW_SPEED) { - follow->value[i] -= FOLLOW_SPEED; - } - } - followDir >>= 1; - } - led_set(led, follow->value[0], follow->value[1], follow->value[2]); - } + led_update_follower(); break; case BREATHE: led_update_breather(BREATHE_SPEED); @@ -107,7 +90,14 @@ void led_animate(void) { } } -void led_knob_lights(void) { +void led_pattern_next(void) { + sdvxConfig.lightPattern++; + if(sdvxConfig.lightPattern > BREATHE) + // since we don't want the init flash + sdvxConfig.lightPattern = NONE; +} + +void led_overlay_knobs(void) { led_knob_light_indiv(&knobs[0], &sdvxConfig.knobColours[0], ledLeftCircleMap); led_knob_light_indiv(&knobs[1], &sdvxConfig.knobColours[1], ledRightCircleMap); } @@ -186,42 +176,69 @@ void led_knobs_update(int8_t left, int8_t right) { } void led_update_breather(uint8_t speed) { - if(pattern.flash.dir) { - if(pattern.flash.level >= BRIGHTNESS_LEVELS - speed) { - pattern.flash.level = BRIGHTNESS_MAX; - pattern.flash.dir = 0; + if(pattern.breathe.dir) { + if(pattern.breathe.level >= BRIGHTNESS_LEVELS - speed) { + pattern.breathe.level = BRIGHTNESS_MAX; + pattern.breathe.dir = 0; } else { - pattern.flash.level += speed; + pattern.breathe.level += speed; } } else { - if(pattern.flash.level <= speed) { - pattern.flash.level = 0; - pattern.flash.dir = 1; + if(pattern.breathe.level <= speed) { + pattern.breathe.level = 0; + pattern.breathe.dir = 1; } else { - pattern.flash.level -= speed; + pattern.breathe.level -= speed; } } - uint8_t bright = pattern.flash.level; - //uint8_t bright = pgm_read_byte(&ledLogCurve[pattern.flash.level]); - led_fade_all_rgb(&pattern.flash.colour, bright); + uint8_t bright = pattern.breathe.level; + //uint8_t bright = pgm_read_byte(&ledLogCurve[pattern.breathe.level]); + led_fade_all_rgb(pattern.breathe.colour, bright); } -void led_anim_flash(void) { - animMode = INIT_FLASH; - pattern.flash.level = 0; - pattern.flash.dir = 1; - pattern.flash.colour = (RGB_t){BRIGHTNESS_MAX, BRIGHTNESS_MAX, BRIGHTNESS_MAX}; +void led_update_follower(void) { + uint8_t followDir; + RGBFader* follow; + + for(uint8_t led = 0; led < LED_COUNT; led++) { + follow = pattern.followers + led; + followDir = follow->direction; + for(uint8_t i = 0; i < 3; i++) { + if(followDir & 1) { + if(follow->value[i] >= BRIGHTNESS_LEVELS - FOLLOW_SPEED) { + follow->direction <<= 1; + if(follow->direction == 0b1000) { + follow->direction = 0b001; + } + } else { + follow->value[i] += FOLLOW_SPEED; + } + } else { + if(follow->value[i] >= FOLLOW_SPEED) { + follow->value[i] -= FOLLOW_SPEED; + } + } + followDir >>= 1; + } + led_set(led, follow->value[0], follow->value[1], follow->value[2]); + } } -void led_anim_breathe(void) { - animMode = BREATHE; - pattern.flash.level = 0; - pattern.flash.dir = 1; - pattern.flash.colour = sdvxConfig.breatheColour; +void led_init_flash(void) { + pattern.breathe.level = 0; + pattern.breathe.dir = 1; + pattern.breathe.colour = &initFlashColour; + flash = 1; } -void led_anim_follower(void) { +void led_init_breathe(void) { + pattern.breathe.level = 0; + pattern.breathe.dir = 1; + pattern.breathe.colour = &sdvxConfig.breatheColour; +} + +void led_init_follower(void) { // Generated by FollowerGen.py static const PROGMEM uint8_t followStart[][4] = { {255, 0, 0, 0b010}, @@ -233,7 +250,6 @@ void led_anim_follower(void) { {0, 223, 32, 0b100}, {0, 127, 128, 0b100}, }; - animMode = FOLLOWER; for(uint8_t i = 0; i < LED_COUNT; i++) { for(uint8_t j = 0; j < 3; j++) { diff --git a/Firmware/PocketVoltex/LEDPatterns.h b/Firmware/PocketVoltex/LEDPatterns.h index 7420728..e46ae25 100644 --- a/Firmware/PocketVoltex/LEDPatterns.h +++ b/Firmware/PocketVoltex/LEDPatterns.h @@ -3,8 +3,8 @@ // circular dependency with Config.h requires this to be here enum LEDMode { - NONE = 0, - INIT_FLASH = 1, + INIT_FLASH = 0, + NONE = 1, SINGLE_COLOUR = 2, FOLLOWER = 3, BREATHE = 4, @@ -28,11 +28,10 @@ enum LEDMode { #define LED_KNOB_SENSITIVITY 5 uint8_t led_on_frame(void); -void led_animate(void); -void led_anim_flash(void); -void led_anim_breathe(void); -void led_anim_follower(void); -void led_knob_lights(void); +void led_pattern_init(void); +void led_pattern_animate(void); +void led_pattern_next(void); +void led_overlay_knobs(void); void led_knobs_update(int8_t left, int8_t right); #endif \ No newline at end of file diff --git a/Firmware/PocketVoltex/PocketVoltex.c b/Firmware/PocketVoltex/PocketVoltex.c index ff409b5..b7ffed8 100644 --- a/Firmware/PocketVoltex/PocketVoltex.c +++ b/Firmware/PocketVoltex/PocketVoltex.c @@ -143,9 +143,6 @@ int main(void) SetupHardware(); GlobalInterruptEnable(); - - // Blink to show we're not in bootloader - led_anim_flash(); for (;;) { @@ -179,7 +176,7 @@ int main(void) if(updateLEDs && sdvxConfig.lightsOn) { updateLEDs = 0; if(!sdvxConfig.hidLights || hidTimeout >= HID_LED_TIMEOUT) { - led_animate(); + led_pattern_animate(); if(sdvxConfig.keyLights) { // Keep normal lights but override when we get flashes on BT or FX // BT LEDs @@ -198,7 +195,10 @@ int main(void) } // knob lights go above all if(sdvxConfig.knobLights) - led_knob_lights(); + led_overlay_knobs(); + led_commit(); + } else if(!sdvxConfig.lightsOn) { + led_set_all(0,0,0); led_commit(); } } @@ -231,6 +231,7 @@ void SetupHardware() /* Hardware Initialization */ encoder_init(); led_init(); + led_pattern_init(); USB_Init(); }