From 83d13b44c22f33463ad00cb93466008657e030d6 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Fri, 9 Jul 2021 22:11:50 -0400 Subject: [PATCH] vialrgb: support direct LED control --- .../rgb_matrix_effects.inc | 1 + .../vialrgb_direct_anim.h | 18 ++++++ quantum/vialrgb.c | 58 +++++++++++++++++++ quantum/vialrgb.h | 3 + quantum/vialrgb_effects.inc | 4 +- 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 quantum/rgb_matrix_animations/vialrgb_direct_anim.h diff --git a/quantum/rgb_matrix_animations/rgb_matrix_effects.inc b/quantum/rgb_matrix_animations/rgb_matrix_effects.inc index 053d441506..0e9b525de6 100644 --- a/quantum/rgb_matrix_animations/rgb_matrix_effects.inc +++ b/quantum/rgb_matrix_animations/rgb_matrix_effects.inc @@ -35,3 +35,4 @@ #include "rgb_matrix_animations/solid_reactive_nexus.h" #include "rgb_matrix_animations/splash_anim.h" #include "rgb_matrix_animations/solid_splash_anim.h" +#include "rgb_matrix_animations/vialrgb_direct_anim.h" diff --git a/quantum/rgb_matrix_animations/vialrgb_direct_anim.h b/quantum/rgb_matrix_animations/vialrgb_direct_anim.h new file mode 100644 index 0000000000..42fc9c7d83 --- /dev/null +++ b/quantum/rgb_matrix_animations/vialrgb_direct_anim.h @@ -0,0 +1,18 @@ +#if defined(VIALRGB_ENABLE) && !defined(VIALRGB_NO_DIRECT) +#define RGB_MATRIX_EFFECT_VIALRGB_DIRECT +RGB_MATRIX_EFFECT(VIALRGB_DIRECT) +# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS + +extern HSV g_direct_mode_colors[DRIVER_LED_TOTAL]; + +bool VIALRGB_DIRECT(effect_params_t* params) { + RGB_MATRIX_USE_LIMITS(led_min, led_max); + + for (uint8_t i = led_min; i < led_max; i++) { + RGB rgb = rgb_matrix_hsv_to_rgb(g_direct_mode_colors[i]); + rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); + } + return led_max < DRIVER_LED_TOTAL; +} +# endif +#endif diff --git a/quantum/vialrgb.c b/quantum/vialrgb.c index e8789fc310..0efa56b283 100644 --- a/quantum/vialrgb.c +++ b/quantum/vialrgb.c @@ -17,6 +17,8 @@ typedef struct { #define SUPPORTED_MODES_LENGTH (sizeof(supported_modes)/sizeof(*supported_modes)) +HSV g_direct_mode_colors[DRIVER_LED_TOTAL]; + static void get_supported(uint8_t *args, uint8_t length) { /* retrieve supported effects (VialRGB IDs) with ID > gt */ uint16_t gt; @@ -69,6 +71,41 @@ static void set_mode(uint16_t mode) { } } +static void get_matrix_pos_for_led(uint16_t led, uint8_t *output) { + /* reset initially so if we cannot locate the led, it's considered not part of kb matrix */ + output[0] = output[1] = 0xFF; + /* this is kinda O(n^2) but what can you do */ + for (size_t row = 0; row < MATRIX_ROWS; ++row) + for (size_t col = 0; col < MATRIX_COLS; ++col) + if (g_led_config.matrix_co[row][col] == led) { + output[0] = row; + output[1] = col; + return; + } +} + +static void fast_set_leds(uint8_t *args, size_t length) { + /* Set multiple leds HSV, first 2 bytes are index of the first led, then number of leds, followed by HSV for the leds */ + /* we have 32-2-2-1=27 total bytes available, so can set up to 9 leds per packet */ + if (length < 3) return; + + uint16_t first_index = args[0] | (args[1] << 8); + uint8_t num_leds = args[2]; + length -= 3; + args += 3; + + if (num_leds * 3 > length) return; + + for (size_t i = 0; i < num_leds; ++i) { + if (i + first_index >= DRIVER_LED_TOTAL) + break; + g_direct_mode_colors[i + first_index].h = args[i * 3 + 0]; + g_direct_mode_colors[i + first_index].s = args[i * 3 + 1]; + uint8_t val = args[i * 3 + 2]; + g_direct_mode_colors[i + first_index].v = (val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) ? RGB_MATRIX_MAXIMUM_BRIGHTNESS : val; + } +} + void vialrgb_get_value(uint8_t *data, uint8_t length) { if (length != VIAL_RAW_EPSIZE) return; @@ -95,6 +132,23 @@ void vialrgb_get_value(uint8_t *data, uint8_t length) { get_supported(args, length - 2); break; } + case vialrgb_get_number_leds: { + args[0] = DRIVER_LED_TOTAL & 0xFF; + args[1] = DRIVER_LED_TOTAL >> 8; + break; + } + case vialrgb_get_led_info: { + uint16_t led = (args[0] & 0xFF) | (args[1] >> 8); + if (led >= DRIVER_LED_TOTAL) return; + // x, y + args[0] = g_led_config.point[led].x; + args[1] = g_led_config.point[led].y; + // flags + args[2] = g_led_config.flags[led]; + // position in keyboard matrix (if it's keyboard LED, otherwise 0xFF) + get_matrix_pos_for_led(led, &args[3]); + break; + } } } @@ -112,6 +166,10 @@ void vialrgb_set_value(uint8_t *data, uint8_t length) { rgb_matrix_sethsv_noeeprom(args[3], args[4], args[5]); break; } + case vialrgb_direct_fastset: { + fast_set_leds(args, length); + break; + } } } diff --git a/quantum/vialrgb.h b/quantum/vialrgb.h index 170d110c34..486a8aa2f7 100644 --- a/quantum/vialrgb.h +++ b/quantum/vialrgb.h @@ -8,12 +8,15 @@ even though they likely wouldn't be enabled together with vialrgb */ enum { vialrgb_set_mode = 0x41, + vialrgb_direct_fastset = 0x42, }; enum { vialrgb_get_info = 0x40, vialrgb_get_mode = 0x41, vialrgb_get_supported = 0x42, + vialrgb_get_number_leds = 0x43, + vialrgb_get_led_info = 0x44, }; void vialrgb_get_value(uint8_t *data, uint8_t length); diff --git a/quantum/vialrgb_effects.inc b/quantum/vialrgb_effects.inc index efe8f66de3..1d21ce3813 100644 --- a/quantum/vialrgb_effects.inc +++ b/quantum/vialrgb_effects.inc @@ -49,7 +49,9 @@ enum { static const PROGMEM vialrgb_supported_mode_t supported_modes[] = { { VIALRGB_EFFECT_OFF, 0 }, - // { VIALRGB_EFFECT_DIRECT, 0 }, TODO +#ifdef RGB_MATRIX_EFFECT_VIALRGB_DIRECT + { VIALRGB_EFFECT_DIRECT, RGB_MATRIX_VIALRGB_DIRECT }, +#endif #ifdef RGB_MATRIX_EFFECT_SOLID_COLOR { VIALRGB_EFFECT_SOLID_COLOR, RGB_MATRIX_SOLID_COLOR }, #endif