Files
mon_PocketVoltex/Firmware/Keyboard/LEDPatterns.c
T

171 lines
4.9 KiB
C

#include "LEDPatterns.h"
#include <avr/pgmspace.h>
static enum LEDMode animMode = NONE;
static uint8_t frameCounter = 0;
// various things for the different modes
static int8_t flash;
static int8_t flashDirection;
typedef struct {
uint8_t value[3];
uint8_t direction;
} RGBFader;
static RGBFader followers[LED_COUNT];
typedef struct {
const uint8_t rgb[3];
uint8_t leds[2];
uint8_t levels[2];
} KnobLights;
static KnobLights knobs[2] = {
// Aqua, top left LEDs
{{0,1,1}, {0,1}, {BRIGHTNESS_LEVELS-1, 0}},
// Pink, top right LEDs
{{1,0,1}, {6,7}, {0, BRIGHTNESS_LEVELS-1}}
};
// Called every 1ms
void led_frame(void) {
if(++frameCounter < LED_MS_PER_FRAME) {
return;
}
frameCounter = 0;
switch(animMode) {
case INIT_FLASH:
if(flashDirection) {
flash+=3;
if(flash >= BRIGHTNESS_LEVELS - 1) {
flash = BRIGHTNESS_LEVELS - 1;
flashDirection = 0;
}
} else {
flash-=3;
if(flash <= 0) {
led_anim_follower();
flash = 0;
}
}
uint8_t bright = pgm_read_byte(&ledLogCurve[flash]);
led_set_all(bright, bright/2, 0);
break;
case FOLLOWER:
for(uint8_t led = 0; led < LED_COUNT; led++) {
uint8_t followDir;
RGBFader* follow;
follow = followers + led;
followDir = follow->direction;
for(uint8_t i = 0; i < 3; i++) {
if(followDir & 1) {
if(follow->value[i]++ >= BRIGHTNESS_LEVELS - 1) {
follow->value[i] = BRIGHTNESS_LEVELS - 1;
follow->direction <<= 1;
if(follow->direction == 0b1000) {
follow->direction = 0b001;
}
}
} else {
if(follow->value[i] > 0) {
follow->value[i]--;
}
}
followDir >>= 1;
}
led_set(led, follow->value[0], follow->value[1], follow->value[2]);
}
break;
case BREATHE:
default:
break;
}
led_set_all(0,0,0);
for(uint8_t i = 0; i < 2; i++) {
for(uint8_t led = 0; led < 2; led++) {
uint8_t r = knobs[i].levels[led] * knobs[i].rgb[0];
uint8_t g = knobs[i].levels[led] * knobs[i].rgb[1];
uint8_t b = knobs[i].levels[led] * knobs[i].rgb[2];
led_set_max(ledCircleMap[knobs[i].leds[led]], r, g, b);
}
}
}
void led_knob_indiv(KnobLights* knob, int8_t value) {
/* This is annoying and repetitive but don't think there's a nicer way */
if(value > 0) {
knob->levels[0] += value;
if(value > knob->levels[1]) {
// Not properly doing rollover since the knob doesn't spin that fast
knob->levels[1] = 0;
} else {
knob->levels[1] -= value;
}
if(knob->levels[0] > BRIGHTNESS_LEVELS) {
knob->levels[0] = 0;
knob->levels[1] = BRIGHTNESS_LEVELS - 1;
knob->leds[1] = knob->leds[0];
if(knob->leds[0] > 0) {
knob->leds[0]--;
} else {
knob->leds[0] = LED_COUNT - 1;
}
}
} else if(value < 0) {
if(-value > knob->levels[0]) {
knob->levels[0] = 0;
} else {
knob->levels[0] += value;
}
knob->levels[1] -= value;
if(knob->levels[1] > BRIGHTNESS_LEVELS) {
knob->levels[0] = BRIGHTNESS_LEVELS - 1;
knob->levels[1] = 0;
knob->leds[0] = knob->leds[1];
knob->leds[1]++;
knob->leds[1] %= LED_COUNT;
}
}
}
void led_knobs_update(int8_t left, int8_t right) {
led_knob_indiv(&knobs[0], left*2);
led_knob_indiv(&knobs[1], right*2);
}
void led_anim_flash(void) {
animMode = INIT_FLASH;
// starting at 2 stops us getting a frame of red
flash = 2;
flashDirection = 1;
}
void led_anim_follower(void) {
// Generated by FollowerGen.py
static uint8_t PROGMEM followStart[][4] = {
{63, 0, 0, 0b010},
{40, 0, 23, 0b001},
{39, 24, 0, 0b010},
{16, 0, 47, 0b001},
{15, 48, 0, 0b010},
{0, 7, 56, 0b100},
{0, 55, 8, 0b100},
{0, 31, 32, 0b100},
};
animMode = FOLLOWER;
for(uint8_t i = 0; i < LED_COUNT; i++) {
for(uint8_t j = 0; j < 3; j++) {
followers[i].value[j] = pgm_read_byte(&followStart[i][j]);
}
followers[i].direction = pgm_read_byte(&followStart[i][3]);
}
}