Skip to content

Commit

Permalink
Better LED patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
mon committed May 20, 2017
1 parent f4e98c1 commit 6a050a5
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 89 deletions.
3 changes: 3 additions & 0 deletions Firmware/PocketVoltex/Descriptors.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "Descriptors.h"

#include "Config.h"
#include "LED.h"

#define WEBUSB_ID 0x01
#define MS_OS_ID 0x02

Expand Down
3 changes: 0 additions & 3 deletions Firmware/PocketVoltex/Descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
#include <avr/pgmspace.h>

#include <LUFA/Drivers/USB/USB.h>

#include "Config.h"
#include "LED.h"

/* Type Defines: */
/** Type define for the device configuration descriptor structure. This must be defined in the
Expand Down
2 changes: 1 addition & 1 deletion Firmware/PocketVoltex/LED.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
162 changes: 89 additions & 73 deletions Firmware/PocketVoltex/LEDPatterns.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
#include "LEDPatterns.h"
#include <avr/pgmspace.h>

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;
Expand All @@ -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];
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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_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_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_init_flash(void) {
pattern.breathe.level = 0;
pattern.breathe.dir = 1;
pattern.breathe.colour = &initFlashColour;
flash = 1;
}

void led_anim_breathe(void) {
animMode = BREATHE;
pattern.flash.level = 0;
pattern.flash.dir = 1;
pattern.flash.colour = sdvxConfig.breatheColour;
void led_init_breathe(void) {
pattern.breathe.level = 0;
pattern.breathe.dir = 1;
pattern.breathe.colour = &sdvxConfig.breatheColour;
}

void led_anim_follower(void) {
void led_init_follower(void) {
// Generated by FollowerGen.py
static const PROGMEM uint8_t followStart[][4] = {
{255, 0, 0, 0b010},
Expand All @@ -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++) {
Expand Down
13 changes: 6 additions & 7 deletions Firmware/PocketVoltex/LEDPatterns.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
11 changes: 6 additions & 5 deletions Firmware/PocketVoltex/PocketVoltex.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,6 @@ int main(void)
SetupHardware();

GlobalInterruptEnable();

// Blink to show we're not in bootloader
led_anim_flash();

for (;;)
{
Expand Down Expand Up @@ -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
Expand All @@ -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();
}
}
Expand Down Expand Up @@ -231,6 +231,7 @@ void SetupHardware()
/* Hardware Initialization */
encoder_init();
led_init();
led_pattern_init();

USB_Init();
}
Expand Down

0 comments on commit 6a050a5

Please sign in to comment.