mirror of
https://github.com/mon/PocketVoltex.git
synced 2026-09-22 22:57:58 +03:00
Better LED patterns
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "LED.h"
|
||||
|
||||
#define WEBUSB_ID 0x01
|
||||
#define MS_OS_ID 0x02
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user