Support fading, but not tested yet

This commit is contained in:
whowe 2024-02-14 15:01:30 +08:00
parent 3d6661d6e7
commit 5b2ad791e9
4 changed files with 80 additions and 32 deletions

View File

@ -54,7 +54,7 @@ typedef struct {
uint8_t len;
uint8_t cmd;
} hdr;
led_data_t data;
led_data_t led;
};
};
uint8_t len;
@ -122,29 +122,30 @@ static void led_cmd(cdc_t *cdc)
cdc->len = 0;
ctx.last_io_time = time_us_64();
uint32_t color = rgb32(cdc->led.r, cdc->led.g, cdc->led.b, false);
switch (cdc->hdr.cmd) {
case 0x31:
printf("8b\n");
uint32_t color = rgb32(cdc->data.r, cdc->data.g, cdc->data.b, false);
rgb_set_button_color(cdc->data.index, color);
rgb_set_button(cdc->led.index, color, 0);
break;
case 0x32:
printf("8bM\n");
for (int i = 0; i < cdc->data.len; i++) {
rgb_set_button_color(i + cdc->data.start, rgb32(cdc->data.mr, cdc->data.mg, cdc->data.mb, false));
for (int i = 0; i < cdc->led.len; i++) {
rgb_set_button(i + cdc->led.start, color, 0);
}
break;
case 0x33:
printf("8bMF\n");
for (int i = 0; i < cdc->data.len; i++) {
rgb_set_button_color(i + cdc->data.start, rgb32(cdc->data.mr, cdc->data.mg, cdc->data.mb, false));
for (int i = 0; i < cdc->led.len; i++) {
rgb_set_button(i + cdc->led.start, color, cdc->led.speed);
}
break;
case 0x39:
printf("Fet\n");
rgb_set_cab_color(0, rgb32(cdc->data.body, cdc->data.body, cdc->data.body, false));
rgb_set_cab_color(1, rgb32(cdc->data.ext, cdc->data.ext, cdc->data.ext, false));
rgb_set_cab_color(2, rgb32(cdc->data.side, cdc->data.side, cdc->data.side, false));
rgb_set_cab(0, gray32(cdc->led.body, false));
rgb_set_cab(1, gray32(cdc->led.ext, false));
rgb_set_cab(2, gray32(cdc->led.side, false));
break;
case 0x3C:
printf("Upd\n");

View File

@ -47,7 +47,7 @@ static void run_lights()
if (buttons & (1 << i)) {
color = mai_cfg->color.key_on;
}
rgb_set_button_color(i, color);
rgb_set_button(i, color, 0);
}
}

View File

@ -22,7 +22,12 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static uint32_t rgb_buf[20];
static struct {
uint32_t color;
uint32_t target; // target color
uint16_t duration;
uint16_t elapsed;
} rgb_ctrl[20];
static const uint8_t button_led_map[] = RGB_BUTTON_MAP;
#define _MAP_LED(x) _MAKE_MAPPER(x)
@ -53,6 +58,11 @@ uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix)
#endif
}
uint32_t gray32(uint32_t c, bool gamma_fix)
{
return rgb32(c, c, c, gamma_fix);
}
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v)
{
uint32_t region, remainder, p, q, t;
@ -84,6 +94,14 @@ uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v)
}
}
static uint32_t lerp(uint32_t a, uint32_t b, uint8_t t)
{
uint32_t c1 = ((a & 0xff0000) * (255 - t) + (b & 0xff0000) * t) & 0xff000000;
uint32_t c2 = ((a & 0xff00) * (255 - t) + (b & 0xff00) * t) & 0xff0000;
uint32_t c3 = ((a & 0xff) * (255 - t) + (b & 0xff) * t) & 0xff00;
return c1 | c2 | c3;
}
static void drive_led()
{
static uint64_t last = 0;
@ -93,23 +111,37 @@ static void drive_led()
}
last = now;
for (int i = 0; i < ARRAY_SIZE(rgb_buf); i++) {
for (int i = 0; i < ARRAY_SIZE(rgb_ctrl); i++) {
int num = (i < 8) ? mai_cfg->rgb.per_button : mai_cfg->rgb.per_aux;
for (int j = 0; j < num; j++) {
pio_sm_put_blocking(pio0, 0, rgb_buf[i] << 8u);
pio_sm_put_blocking(pio0, 0, rgb_ctrl[i].color << 8u);
}
}
}
void rgb_set_colors(const uint32_t *colors, unsigned index, size_t num)
static void fade_ctrl()
{
if (index >= ARRAY_SIZE(rgb_buf)) {
return;
static uint64_t last = 0;
uint64_t now = time_us_64();
uint64_t delta = now - last;
for (int i = 0; i < ARRAY_SIZE(rgb_ctrl); i++) {
if (rgb_ctrl[i].duration == 0) {
continue;
}
rgb_ctrl[i].elapsed += delta;
if (rgb_ctrl[i].elapsed >= rgb_ctrl[i].duration) {
rgb_ctrl[i].color = rgb_ctrl[i].target;
rgb_ctrl[i].duration = 0;
continue;
}
uint8_t progress = rgb_ctrl[i].elapsed * 255 / rgb_ctrl[i].duration;
rgb_ctrl->color = lerp(rgb_ctrl->color, rgb_ctrl->target, progress);
}
if (index + num > ARRAY_SIZE(rgb_buf)) {
num = ARRAY_SIZE(rgb_buf) - index;
}
memcpy(&rgb_buf[index], colors, num * sizeof(*colors));
last = now;
}
static inline uint32_t apply_level(uint32_t color)
@ -125,20 +157,36 @@ static inline uint32_t apply_level(uint32_t color)
return r << 16 | g << 8 | b;
}
void rgb_set_button_color(unsigned index, uint32_t color)
static void set_color(unsigned index, uint32_t color, uint8_t speed)
{
if (index >= 8) {
if (index >= ARRAY_SIZE(rgb_ctrl)) {
return;
}
rgb_buf[button_led_map[index]] = apply_level(color);
if (speed > 0) {
rgb_ctrl[index].target = apply_level(color);
rgb_ctrl[index].duration = 32767 / speed;
rgb_ctrl[index].elapsed = 0;
} else {
rgb_ctrl[index].color = apply_level(color);
rgb_ctrl[index].duration = 0;
}
}
void rgb_set_cab_color(unsigned index, uint32_t color)
void rgb_set_button(unsigned index, uint32_t color, uint8_t speed)
{
if (index >= 0) {
if (index >= ARRAY_SIZE(button_led_map)) {
return;
}
rgb_buf[8 + index] = apply_level(color);
set_color(button_led_map[index], color, speed);
}
void rgb_set_cab(unsigned index, uint32_t color)
{
if (index >= 3) {
return;
}
set_color(8 + index, color, 0);
}
void rgb_init()
@ -151,5 +199,6 @@ void rgb_init()
void rgb_update()
{
fade_ctrl();
drive_led();
}

View File

@ -16,12 +16,10 @@ void rgb_init();
void rgb_update();
uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix);
uint32_t gray32(uint32_t c, bool gamma_fix);
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v);
void rgb_set_button_color(unsigned index, uint32_t color);
void rgb_set_cab_color(unsigned index, uint32_t color);
/* num of the rgb leds, num*3 bytes in the array */
void rgb_set_brg(unsigned index, const uint8_t *brg_array, size_t num);
void rgb_set_button(unsigned index, uint32_t color, uint8_t speed);
void rgb_set_cab(unsigned index, uint32_t color);
#endif