summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2024-10-06 19:01:07 +1100
committerGitHub <noreply@github.com>2024-10-06 21:01:07 +1300
commit208ebf54a905ce6e4e563a6811eca8c8dc8b17e1 (patch)
tree7bb6a8bdb5a641263c39236d0b655825ac37307b
parent43e82ed5c72b7386ca91d1bd363ee092f77c1b9a (diff)
WS2812 API rework (#24364)
* Begin WS2812 API rework * Move RGBW conversion, clean up color.h, fix RGBW for AVR bitbang * Formatting & update PS2AVRGB I2C driver (untested) * Tested ARM bitbang RGB+RGBW * Tested ARM SPI RGB - RGBW not working * Tested ARM PWM RGB+RGBW * Tested RP2040 PIO driver RGB+RGBW * Update RGBLight * Formatting * Fix BM60HSRGB rev2 * Fix oddforge/vea * Fix 1k and XD002 RGBLite * Fix model_m/mschwingen * Fix handwired/promethium * Rename `WS2812_LED_TOTAL` for BM60HSRGB * Fix work_louder boards * Fix dawn60 * Fix rgbkb/pan * Fix neson_design/700e and n6 * Fix ergodox_ez/shine * ergodox_ez/shine: invert indices for left half * Fix matrix/abelx * Fix matrix/m20add * Remove custom rgblight driver for matrix/noah - should be done with lighting layers * Fix LED indexes for RGBLight split * Rename `convert_rgb_to_rgbw()` to `ws2812_rgb_to_rgbw()` * Update WS2812 API docs * `ergodox_ez/shine`: simplify LED index calculation * LED/RGB Matrix: Add weak function for LED index resolution * Bandaid fix for RGB Matrix splits not using WS2812 * `steelseries/prime_plus`: redo custom RGBLight driver * Update keyboards/steelseries/prime_plus/rgblight_custom.c Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com> --------- Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>
-rw-r--r--builddefs/common_features.mk2
-rw-r--r--docs/drivers/ws2812.md45
-rw-r--r--drivers/ws2812.c15
-rw-r--r--drivers/ws2812.h45
-rw-r--r--keyboards/1k/config.h2
-rw-r--r--keyboards/1k/keymaps/default/rgblite.h4
-rw-r--r--keyboards/ergodox_ez/post_config.h2
-rw-r--r--keyboards/ergodox_ez/shine/rgblight_custom.c82
-rw-r--r--keyboards/handwired/promethium/config.h1
-rw-r--r--keyboards/handwired/promethium/rgbsps.c8
-rw-r--r--keyboards/ibm/model_m/mschwingen/config.h1
-rw-r--r--keyboards/ibm/model_m/mschwingen/mschwingen.c65
-rw-r--r--keyboards/input_club/ergodox_infinity/ergodox_infinity.c4
-rwxr-xr-xkeyboards/keychron/q11/ansi_encoder/ansi_encoder.c4
-rwxr-xr-xkeyboards/keychron/q11/iso_encoder/iso_encoder.c4
-rw-r--r--keyboards/kprepublic/bm60hsrgb/rev2/config.h6
-rw-r--r--keyboards/kprepublic/bm60hsrgb/rev2/rev2.c26
-rw-r--r--keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h6
-rw-r--r--keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c26
-rw-r--r--keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h6
-rw-r--r--keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c26
-rw-r--r--keyboards/matrix/abelx/abelx.c45
-rw-r--r--keyboards/matrix/abelx/config.h1
-rw-r--r--keyboards/matrix/m20add/m20add.c7
-rw-r--r--keyboards/matrix/m20add/rgb_ring.c19
-rw-r--r--keyboards/matrix/m20add/rgb_ring.h1
-rw-r--r--keyboards/matrix/noah/keyboard.json2
-rw-r--r--keyboards/matrix/noah/noah.c57
-rw-r--r--keyboards/neson_design/700e/700e.c61
-rw-r--r--keyboards/neson_design/700e/config.h1
-rw-r--r--keyboards/neson_design/n6/config.h1
-rw-r--r--keyboards/neson_design/n6/n6.c61
-rw-r--r--keyboards/oddforge/vea/ws2812_custom.c21
-rw-r--r--keyboards/orthograph/orthograph.c3
-rw-r--r--keyboards/rgbkb/pan/config.h1
-rw-r--r--keyboards/rgbkb/pan/pan.c28
-rw-r--r--keyboards/steelseries/prime_plus/rgblight_custom.c60
-rw-r--r--keyboards/wilba_tech/wt_rgb_backlight.c18
-rw-r--r--keyboards/work_louder/rgb_functions.c10
-rw-r--r--keyboards/xelus/dawn60/rev1/config.h2
-rw-r--r--keyboards/xelus/dawn60/rev1_qmk/config.h4
-rw-r--r--keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c14
-rw-r--r--keyboards/xiudi/xd002/keymaps/rgb_lite/config.h3
-rw-r--r--keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h6
-rw-r--r--platforms/avr/drivers/ws2812_bitbang.c52
-rw-r--r--platforms/avr/drivers/ws2812_i2c.c22
-rw-r--r--platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c27
-rw-r--r--platforms/chibios/drivers/ws2812_bitbang.c42
-rw-r--r--platforms/chibios/drivers/ws2812_pwm.c28
-rw-r--r--platforms/chibios/drivers/ws2812_spi.c25
-rw-r--r--quantum/color.c11
-rw-r--r--quantum/color.h24
-rw-r--r--quantum/led_matrix/led_matrix.c11
-rw-r--r--quantum/led_matrix/led_matrix.h2
-rw-r--r--quantum/rgb_matrix/rgb_matrix.c11
-rw-r--r--quantum/rgb_matrix/rgb_matrix.h2
-rw-r--r--quantum/rgb_matrix/rgb_matrix_drivers.c58
-rw-r--r--quantum/rgblight/rgblight.c152
-rw-r--r--quantum/rgblight/rgblight.h1
-rw-r--r--quantum/rgblight/rgblight_drivers.c20
-rw-r--r--quantum/rgblight/rgblight_drivers.h5
61 files changed, 638 insertions, 661 deletions
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 2b12930887..a2c88d7e99 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -932,7 +932,7 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes)
932 932
933 OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]')) 933 OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]'))
934 934
935 SRC += ws2812_$(strip $(WS2812_DRIVER)).c 935 SRC += ws2812.c ws2812_$(strip $(WS2812_DRIVER)).c
936 936
937 ifeq ($(strip $(PLATFORM)), CHIBIOS) 937 ifeq ($(strip $(PLATFORM)), CHIBIOS)
938 ifeq ($(strip $(WS2812_DRIVER)), pwm) 938 ifeq ($(strip $(WS2812_DRIVER)), pwm)
diff --git a/docs/drivers/ws2812.md b/docs/drivers/ws2812.md
index 64343d3c6a..036ea40d1d 100644
--- a/docs/drivers/ws2812.md
+++ b/docs/drivers/ws2812.md
@@ -241,13 +241,44 @@ Using a complementary timer output (`TIMx_CHyN`) is possible only for advanced-c
241 241
242## API {#api} 242## API {#api}
243 243
244### `void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds)` {#api-ws2812-setleds} 244### `void ws2812_init(void)` {#api-ws2812-init}
245 245
246Send RGB data to the WS2812 LED chain. 246Initialize the LED driver. This function should be called first.
247 247
248#### Arguments {#api-ws2812-setleds-arguments} 248---
249 249
250 - `rgb_led_t *ledarray` 250### `void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color}
251 A pointer to the LED array. 251
252 - `uint16_t number_of_leds` 252Set the color of a single LED. This function does not immediately update the LEDs; call `ws2812_flush()` after you are finished.
253 The length of the LED array. 253
254#### Arguments {#api-ws2812-set-color-arguments}
255
256 - `int index`
257 The LED index in the WS2812 chain.
258 - `uint8_t red`
259 The red value to set.
260 - `uint8_t green`
261 The green value to set.
262 - `uint8_t blue`
263 The blue value to set.
264
265---
266
267### `void ws812_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color-all}
268
269Set the color of all LEDs.
270
271#### Arguments {#api-ws2812-set-color-all-arguments}
272
273 - `uint8_t red`
274 The red value to set.
275 - `uint8_t green`
276 The green value to set.
277 - `uint8_t blue`
278 The blue value to set.
279
280---
281
282### `void ws2812_flush(void)` {#api-ws2812-flush}
283
284Flush the PWM values to the LED chain.
diff --git a/drivers/ws2812.c b/drivers/ws2812.c
new file mode 100644
index 0000000000..bf234c6f7d
--- /dev/null
+++ b/drivers/ws2812.c
@@ -0,0 +1,15 @@
1// Copyright 2024 QMK
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "ws2812.h"
5
6#if defined(WS2812_RGBW)
7void ws2812_rgb_to_rgbw(ws2812_led_t *led) {
8 // Determine lowest value in all three colors, put that into
9 // the white channel and then shift all colors by that amount
10 led->w = MIN(led->r, MIN(led->g, led->b));
11 led->r -= led->w;
12 led->g -= led->w;
13 led->b -= led->w;
14}
15#endif
diff --git a/drivers/ws2812.h b/drivers/ws2812.h
index 993cce8ce4..8013e5bd2d 100644
--- a/drivers/ws2812.h
+++ b/drivers/ws2812.h
@@ -15,7 +15,7 @@
15 15
16#pragma once 16#pragma once
17 17
18#include "quantum/color.h" 18#include "util.h"
19 19
20/* 20/*
21 * The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these 21 * The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these
@@ -62,17 +62,36 @@
62# define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT 62# define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT
63#endif 63#endif
64 64
65#define WS2812_BYTE_ORDER_RGB 0
66#define WS2812_BYTE_ORDER_GRB 1
67#define WS2812_BYTE_ORDER_BGR 2
68
69#ifndef WS2812_BYTE_ORDER
70# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
71#endif
72
73typedef struct PACKED ws2812_led_t {
74#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
75 uint8_t g;
76 uint8_t r;
77 uint8_t b;
78#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
79 uint8_t r;
80 uint8_t g;
81 uint8_t b;
82#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
83 uint8_t b;
84 uint8_t g;
85 uint8_t r;
86#endif
87#ifdef WS2812_RGBW
88 uint8_t w;
89#endif
90} ws2812_led_t;
91
65void ws2812_init(void); 92void ws2812_init(void);
93void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
94void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
95void ws2812_flush(void);
66 96
67/* User Interface 97void ws2812_rgb_to_rgbw(ws2812_led_t *led);
68 *
69 * Input:
70 * ledarray: An array of GRB data describing the LED colors
71 * number_of_leds: The number of LEDs to write
72 *
73 * The functions will perform the following actions:
74 * - Set the data-out pin as output
75 * - Send out the LED data
76 * - Wait 50us to reset the LEDs
77 */
78void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds);
diff --git a/keyboards/1k/config.h b/keyboards/1k/config.h
index 0d0cd3712a..fcd7fe6f94 100644
--- a/keyboards/1k/config.h
+++ b/keyboards/1k/config.h
@@ -32,3 +32,5 @@
32#define USB_INTR_ENABLE_BIT PCIE 32#define USB_INTR_ENABLE_BIT PCIE
33#define USB_INTR_PENDING_BIT PCIF 33#define USB_INTR_PENDING_BIT PCIF
34#define USB_INTR_VECTOR SIG_PIN_CHANGE 34#define USB_INTR_VECTOR SIG_PIN_CHANGE
35
36#define WS2812_LED_COUNT 1
diff --git a/keyboards/1k/keymaps/default/rgblite.h b/keyboards/1k/keymaps/default/rgblite.h
index 2e0b898699..b30ec26b04 100644
--- a/keyboards/1k/keymaps/default/rgblite.h
+++ b/keyboards/1k/keymaps/default/rgblite.h
@@ -11,8 +11,8 @@ static inline void rgblite_init(void) {
11} 11}
12 12
13static inline void rgblite_setrgb(RGB rgb) { 13static inline void rgblite_setrgb(RGB rgb) {
14 rgb_led_t leds[RGBLIGHT_LED_COUNT] = {{.r = rgb.r, .g = rgb.g, .b = rgb.b}}; 14 ws2812_set_color_all(rgb.r, rgb.g, rgb.b);
15 ws2812_setleds(leds, RGBLIGHT_LED_COUNT); 15 ws2812_flush();
16} 16}
17 17
18static void rgblite_increase_hue(void) { 18static void rgblite_increase_hue(void) {
diff --git a/keyboards/ergodox_ez/post_config.h b/keyboards/ergodox_ez/post_config.h
index eb22439ae4..e94fda0f06 100644
--- a/keyboards/ergodox_ez/post_config.h
+++ b/keyboards/ergodox_ez/post_config.h
@@ -33,8 +33,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
33 33
34#ifdef ERGODOX_LED_30 34#ifdef ERGODOX_LED_30
35// If using 30 LEDs, then define that many 35// If using 30 LEDs, then define that many
36# define WS2812_LED_COUNT 30
36# define RGBLIGHT_LED_COUNT 30 // Number of LEDs 37# define RGBLIGHT_LED_COUNT 30 // Number of LEDs
37#else 38#else
38// If not, then only define 15 39// If not, then only define 15
40# define WS2812_LED_COUNT 15
39# define RGBLIGHT_LED_COUNT 15 // Number of LEDs 41# define RGBLIGHT_LED_COUNT 15 // Number of LEDs
40#endif 42#endif
diff --git a/keyboards/ergodox_ez/shine/rgblight_custom.c b/keyboards/ergodox_ez/shine/rgblight_custom.c
index 29060e76fc..8e806b1fd1 100644
--- a/keyboards/ergodox_ez/shine/rgblight_custom.c
+++ b/keyboards/ergodox_ez/shine/rgblight_custom.c
@@ -21,47 +21,55 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
21#include "ergodox_ez.h" 21#include "ergodox_ez.h"
22#include "ws2812.h" 22#include "ws2812.h"
23 23
24void setleds_custom(rgb_led_t *led, uint16_t led_num) { 24#define WS2812_I2C_ADDRESS_LEFT 0x84
25 uint16_t length = 0; 25
26 int i = 0; 26#if defined(ERGODOX_LED_30)
27 int j = 0; 27# define WS2812_LED_COUNT_LEFT (RGBLIGHT_LED_COUNT / 2)
28# ifdef WS2812_RGBW 28ws2812_led_t ws2812_leds_left[WS2812_LED_COUNT_LEFT];
29 int bytes_per_led = 4; 29#else
30# else 30# define WS2812_LED_COUNT_LEFT RGBLIGHT_LED_COUNT
31 int bytes_per_led = 3; 31ws2812_led_t ws2812_leds_left[WS2812_LED_COUNT_LEFT];
32# endif 32#endif
33# if defined(ERGODOX_LED_30) 33
34 // prevent right-half code from trying to bitbang all 30 34void set_color_left(int index, uint8_t red, uint8_t green, uint8_t blue) {
35 // so with 30 LEDs, we count from 29 to 15 here, and the 35 ws2812_leds_left[index].r = red;
36 // other half does 0 to 14. 36 ws2812_leds_left[index].g = green;
37 uint8_t half_led_num = RGBLIGHT_LED_COUNT / 2; 37 ws2812_leds_left[index].b = blue;
38 length = half_led_num * bytes_per_led; 38#if defined(WS2812_RGBW)
39 uint8_t data[length]; 39 ws2812_rgb_to_rgbw(&ws2812_leds_left[index]);
40 for (i = half_led_num + half_led_num - 1; i >= half_led_num; --i) 40#endif
41# elif defined(ERGODOX_LED_15_MIRROR) 41}
42 length = led_num * bytes_per_led; 42
43 uint8_t data[length]; 43void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
44 for (i = 0; i < led_num; ++i) 44#if defined(ERGODOX_LED_30)
45# else // ERGDOX_LED_15 non-mirrored 45 if (index < WS2812_LED_COUNT_LEFT) {
46 length = led_num * bytes_per_led; 46 ws2812_set_color(index, red, green, blue);
47 uint8_t data[length]; 47 } else {
48 for (i = led_num - 1; i >= 0; --i) 48 set_color_left(RGBLIGHT_LED_COUNT - index - 1, red, green, blue);
49# endif 49 }
50 { 50#elif defined(ERGODOX_LED_15_MIRROR)
51 uint8_t *data_byte = (uint8_t *)(led + i); 51 ws2812_set_color(index, red, green, blue);
52 data[j++] = data_byte[0]; 52 set_color_left(index, red, green, blue);
53 data[j++] = data_byte[1]; 53#else
54 data[j++] = data_byte[2]; 54 ws2812_set_color(index, red, green, blue);
55#ifdef WS2812_RGBW 55 set_color_left(WS2812_LED_COUNT_LEFT - index - 1, red, green, blue);
56 data[j++] = data_byte[3];
57#endif 56#endif
57}
58
59void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
60 for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
61 set_color_custom(i, red, green, blue);
58 } 62 }
59 i2c_transmit(0x84, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT); 63}
60 64
61 ws2812_setleds(led, led_num); 65void flush_custom(void) {
66 i2c_transmit(WS2812_I2C_ADDRESS_LEFT, (uint8_t *)ws2812_leds_left, sizeof(ws2812_leds_left), ERGODOX_EZ_I2C_TIMEOUT);
67 ws2812_flush();
62} 68}
63 69
64const rgblight_driver_t rgblight_driver = { 70const rgblight_driver_t rgblight_driver = {
65 .init = ws2812_init, 71 .init = ws2812_init,
66 .setleds = setleds_custom, 72 .set_color = set_color_custom,
73 .set_color_all = set_color_all_custom,
74 .flush = flush_custom,
67}; 75};
diff --git a/keyboards/handwired/promethium/config.h b/keyboards/handwired/promethium/config.h
index 342411a6b2..806726b5eb 100644
--- a/keyboards/handwired/promethium/config.h
+++ b/keyboards/handwired/promethium/config.h
@@ -155,6 +155,7 @@ enum led_sequence {
155}; 155};
156 156
157# define RGBSPS_NUM LED_TOTAL 157# define RGBSPS_NUM LED_TOTAL
158# define WS2812_LED_COUNT RGBSPS_NUM
158#endif 159#endif
159 160
160/* PS/2 mouse */ 161/* PS/2 mouse */
diff --git a/keyboards/handwired/promethium/rgbsps.c b/keyboards/handwired/promethium/rgbsps.c
index 7dc26f4a5e..07ece69166 100644
--- a/keyboards/handwired/promethium/rgbsps.c
+++ b/keyboards/handwired/promethium/rgbsps.c
@@ -2,8 +2,6 @@
2#include "ws2812.h" 2#include "ws2812.h"
3#include "rgbsps.h" 3#include "rgbsps.h"
4 4
5rgb_led_t led[RGBSPS_NUM];
6
7void keyboard_pre_init_kb(void) { 5void keyboard_pre_init_kb(void) {
8 ws2812_init(); 6 ws2812_init();
9 7
@@ -11,9 +9,7 @@ void keyboard_pre_init_kb(void) {
11} 9}
12 10
13void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b) { 11void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
14 led[index].r = r; 12 ws2812_set_color(index, r, g, b);
15 led[index].g = g;
16 led[index].b = b;
17} 13}
18 14
19void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b) { 15void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b) {
@@ -27,7 +23,7 @@ void rgbsps_turnoff(void) {
27} 23}
28 24
29void rgbsps_send(void) { 25void rgbsps_send(void) {
30 ws2812_setleds(led, RGBSPS_NUM); 26 ws2812_flush();
31} 27}
32 28
33void rgbsps_sethsv(uint8_t index, uint16_t hue, uint8_t sat, uint8_t val) { 29void rgbsps_sethsv(uint8_t index, uint16_t hue, uint8_t sat, uint8_t val) {
diff --git a/keyboards/ibm/model_m/mschwingen/config.h b/keyboards/ibm/model_m/mschwingen/config.h
index b34d29649a..19fb3fcd6f 100644
--- a/keyboards/ibm/model_m/mschwingen/config.h
+++ b/keyboards/ibm/model_m/mschwingen/config.h
@@ -65,6 +65,7 @@
65# define MODELM_LED_SCROLLOCK MODELM_LED3 65# define MODELM_LED_SCROLLOCK MODELM_LED3
66# define MODELM_LED_NUMLOCK MODELM_LED1 66# define MODELM_LED_NUMLOCK MODELM_LED1
67#elif defined(KEYBOARD_ibm_model_m_mschwingen_led_ws2812) 67#elif defined(KEYBOARD_ibm_model_m_mschwingen_led_ws2812)
68# define WS2812_LED_COUNT 3
68#else 69#else
69# error one of MODELM_LEDS_FFC, MODELM_LEDS_WIRED or MODELM_LEDS_WS2812 must be set! 70# error one of MODELM_LEDS_FFC, MODELM_LEDS_WIRED or MODELM_LEDS_WS2812 must be set!
70#endif 71#endif
diff --git a/keyboards/ibm/model_m/mschwingen/mschwingen.c b/keyboards/ibm/model_m/mschwingen/mschwingen.c
index 7c0f1b2565..cb4854d8d1 100644
--- a/keyboards/ibm/model_m/mschwingen/mschwingen.c
+++ b/keyboards/ibm/model_m/mschwingen/mschwingen.c
@@ -39,27 +39,10 @@ static uint8_t isRecording = 0;
39# if RGBLIGHT_LED_COUNT < 3 39# if RGBLIGHT_LED_COUNT < 3
40# error we need at least 3 RGB LEDs! 40# error we need at least 3 RGB LEDs!
41# endif 41# endif
42static rgb_led_t led[RGBLIGHT_LED_COUNT] = {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}};
43 42
44# define BRIGHT 32 43# define BRIGHT 32
45# define DIM 6 44# define DIM 6
46 45
47static const rgb_led_t black = {.r = 0, .g = 0, .b = 0};
48
49static const __attribute__((unused)) rgb_led_t green = {.r = 0, .g = BRIGHT, .b = 0};
50static const __attribute__((unused)) rgb_led_t lgreen = {.r = 0, .g = DIM, .b = 0};
51
52static const __attribute__((unused)) rgb_led_t red = {.r = BRIGHT, .g = 0, .b = 0};
53static const __attribute__((unused)) rgb_led_t lred = {.r = DIM, .g = 0, .b = 0};
54
55static const __attribute__((unused)) rgb_led_t blue = {.r = 0, .g = 0, .b = BRIGHT};
56static const __attribute__((unused)) rgb_led_t lblue = {.r = 0, .g = 0, .b = DIM};
57
58static const __attribute__((unused)) rgb_led_t turq = {.r = 0, .g = BRIGHT, .b = BRIGHT};
59static const __attribute__((unused)) rgb_led_t lturq = {.r = 0, .g = DIM, .b = DIM};
60
61static const __attribute__((unused)) rgb_led_t white = {.r = BRIGHT, .g = BRIGHT, .b = BRIGHT};
62
63static led_t led_state; 46static led_t led_state;
64static uint8_t layer; 47static uint8_t layer;
65static uint8_t default_layer; 48static uint8_t default_layer;
@@ -81,17 +64,15 @@ void sleep_led_enable(void) {
81 suspend_active = true; 64 suspend_active = true;
82 gpio_write_pin_low(MODELM_STATUS_LED); 65 gpio_write_pin_low(MODELM_STATUS_LED);
83#ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812 66#ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
84 led[0] = black; 67 ws2812_set_color_all(0, 0, 0);
85 led[1] = black; 68 ws2812_flush();
86 led[2] = black;
87 ws2812_setleds(led, RGBLIGHT_LED_COUNT);
88#endif 69#endif
89} 70}
90 71
91void keyboard_pre_init_kb(void) { 72void keyboard_pre_init_kb(void) {
92#ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812 73#ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
93 ws2812_init(); 74 ws2812_init();
94 ws2812_setleds(led, RGBLIGHT_LED_COUNT); 75 ws2812_flush();
95#else 76#else
96 /* Set status LEDs pins to output and Low (on) */ 77 /* Set status LEDs pins to output and Low (on) */
97 gpio_set_pin_output(MODELM_LED_CAPSLOCK); 78 gpio_set_pin_output(MODELM_LED_CAPSLOCK);
@@ -121,35 +102,59 @@ void keyboard_pre_init_kb(void) {
121#ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812 102#ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812
122static void led_update_rgb(void) { 103static void led_update_rgb(void) {
123 if (isRecording && blink_state) { 104 if (isRecording && blink_state) {
124 led[0] = white; 105 ws2812_set_color(0, BRIGHT, BRIGHT, BRIGHT);
125 } else { 106 } else {
126 switch (default_layer) { 107 switch (default_layer) {
127 case 0: 108 case 0:
128 led[0] = led_state.num_lock ? blue : lblue; 109 if (led_state.num_lock) {
110 ws2812_set_color(0, 0, 0, BRIGHT);
111 } else {
112 ws2812_set_color(0, 0, 0, DIM);
113 }
129 break; 114 break;
130 case 1: 115 case 1:
131 led[0] = led_state.num_lock ? green : black; 116 if (led_state.num_lock) {
117 ws2812_set_color(0, 0, BRIGHT, 0);
118 } else {
119 ws2812_set_color(0, 0, 0, 0);
120 }
132 break; 121 break;
133 } 122 }
134 } 123 }
135 124
136 led[1] = led_state.caps_lock ? green : black; 125 if (led_state.caps_lock) {
126 ws2812_set_color(1, 0, BRIGHT, 0);
127 } else {
128 ws2812_set_color(1, 0, 0, 0);
129 }
137 130
138 switch (layer) { 131 switch (layer) {
139 case 0: 132 case 0:
140 case 1: 133 case 1:
141 default: 134 default:
142 led[2] = led_state.scroll_lock ? green : black; 135 if (led_state.scroll_lock) {
136 ws2812_set_color(2, 0, BRIGHT, 0);
137 } else {
138 ws2812_set_color(2, 0, 0, 0);
139 }
143 break; 140 break;
144 case 2: 141 case 2:
145 led[2] = led_state.scroll_lock ? red : lred; 142 if (led_state.scroll_lock) {
143 ws2812_set_color(2, BRIGHT, 0, 0);
144 } else {
145 ws2812_set_color(2, DIM, 0, 0);
146 }
146 break; 147 break;
147 case 3: 148 case 3:
148 led[2] = led_state.scroll_lock ? turq : lturq; 149 if (led_state.scroll_lock) {
150 ws2812_set_color(2, 0, BRIGHT, BRIGHT);
151 } else {
152 ws2812_set_color(2, 0, DIM, DIM);
153 }
149 break; 154 break;
150 } 155 }
151 if (!suspend_active) { 156 if (!suspend_active) {
152 ws2812_setleds(led, RGBLIGHT_LED_COUNT); 157 ws2812_flush();
153 } 158 }
154} 159}
155 160
diff --git a/keyboards/input_club/ergodox_infinity/ergodox_infinity.c b/keyboards/input_club/ergodox_infinity/ergodox_infinity.c
index 2e8d0b9763..03988a440a 100644
--- a/keyboards/input_club/ergodox_infinity/ergodox_infinity.c
+++ b/keyboards/input_club/ergodox_infinity/ergodox_infinity.c
@@ -209,6 +209,10 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
209// 71 70 69 209// 71 70 69
210 { 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 }, 210 { 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 },
211}; 211};
212
213int led_matrix_led_index(int index) {
214 return index;
215}
212#endif 216#endif
213 217
214#ifdef ST7565_ENABLE 218#ifdef ST7565_ENABLE
diff --git a/keyboards/keychron/q11/ansi_encoder/ansi_encoder.c b/keyboards/keychron/q11/ansi_encoder/ansi_encoder.c
index 49e428bc00..5794056bfa 100755
--- a/keyboards/keychron/q11/ansi_encoder/ansi_encoder.c
+++ b/keyboards/keychron/q11/ansi_encoder/ansi_encoder.c
@@ -125,4 +125,8 @@ const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = {
125 {0, CB7_CA1, CB9_CA1, CB8_CA1}, // Down 125 {0, CB7_CA1, CB9_CA1, CB8_CA1}, // Down
126 {0, CB7_CA7, CB9_CA7, CB8_CA7}, // Right 126 {0, CB7_CA7, CB9_CA7, CB8_CA7}, // Right
127}; 127};
128
129int rgb_matrix_led_index(int index) {
130 return index;
131}
128#endif 132#endif
diff --git a/keyboards/keychron/q11/iso_encoder/iso_encoder.c b/keyboards/keychron/q11/iso_encoder/iso_encoder.c
index 8725598b1c..e750addcfa 100755
--- a/keyboards/keychron/q11/iso_encoder/iso_encoder.c
+++ b/keyboards/keychron/q11/iso_encoder/iso_encoder.c
@@ -126,4 +126,8 @@ const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = {
126 {0, CB7_CA1, CB9_CA1, CB8_CA1}, // Down 126 {0, CB7_CA1, CB9_CA1, CB8_CA1}, // Down
127 {0, CB7_CA7, CB9_CA7, CB8_CA7}, // Right 127 {0, CB7_CA7, CB9_CA7, CB8_CA7}, // Right
128}; 128};
129
130int rgb_matrix_led_index(int index) {
131 return index;
132}
129#endif 133#endif
diff --git a/keyboards/kprepublic/bm60hsrgb/rev2/config.h b/keyboards/kprepublic/bm60hsrgb/rev2/config.h
index 1d2b071fc1..a8010af152 100644
--- a/keyboards/kprepublic/bm60hsrgb/rev2/config.h
+++ b/keyboards/kprepublic/bm60hsrgb/rev2/config.h
@@ -25,9 +25,9 @@
25// Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them; 25// Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
26// don't use those LEDs in RGB Matrix in that case. 26// don't use those LEDs in RGB Matrix in that case.
27#ifdef RGBLIGHT_ENABLE 27#ifdef RGBLIGHT_ENABLE
28# define WS2812_LED_TOTAL 0 28# define WS2812_LED_COUNT 0
29#else 29#else
30# define WS2812_LED_TOTAL 6 30# define WS2812_LED_COUNT 6
31#endif 31#endif
32 32
33#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL) 33#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT)
diff --git a/keyboards/kprepublic/bm60hsrgb/rev2/rev2.c b/keyboards/kprepublic/bm60hsrgb/rev2/rev2.c
index 5bd23a12b8..e7ff5a9ddc 100644
--- a/keyboards/kprepublic/bm60hsrgb/rev2/rev2.c
+++ b/keyboards/kprepublic/bm60hsrgb/rev2/rev2.c
@@ -110,7 +110,7 @@ led_config_t g_led_config = {
110 { 18, 48 }, { 30, 48 }, { 45, 48 }, { 60, 48 }, { 75, 48 }, { 90, 48 }, { 105, 48 }, { 120, 48 }, { 135, 48 }, { 150, 48 }, { 165, 48 }, { 191, 48 }, { 210, 48 }, 110 { 18, 48 }, { 30, 48 }, { 45, 48 }, { 60, 48 }, { 75, 48 }, { 90, 48 }, { 105, 48 }, { 120, 48 }, { 135, 48 }, { 150, 48 }, { 165, 48 }, { 191, 48 }, { 210, 48 },
111 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right 111 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
112 { 3, 64 }, { 22, 64 }, { 33, 64 }, { 101, 64 }, { 135, 64 }, { 153, 64 }, { 195, 64 }, { 210, 64 }, { 225, 64 } 112 { 3, 64 }, { 22, 64 }, { 33, 64 }, { 101, 64 }, { 135, 64 }, { 153, 64 }, { 195, 64 }, { 210, 64 }, { 225, 64 }
113# if WS2812_LED_TOTAL > 0 113# if WS2812_LED_COUNT > 0
114 ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40} 114 ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
115# endif 115# endif
116}, { 116}, {
@@ -124,7 +124,7 @@ led_config_t g_led_config = {
124 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 124 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4,
125 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right 125 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
126 1, 1, 1, 4, 1, 1, 1, 1, 1 126 1, 1, 1, 4, 1, 1, 1, 1, 1
127# if WS2812_LED_TOTAL > 0 127# if WS2812_LED_COUNT > 0
128 ,2, 2, 2, 2, 2, 2 128 ,2, 2, 2, 2, 2, 2
129# endif 129# endif
130 } 130 }
@@ -147,10 +147,6 @@ bool rgb_matrix_indicators_kb(void) {
147// Custom RGB Matrix driver that combines IS31FL3733 and WS2812 147// Custom RGB Matrix driver that combines IS31FL3733 and WS2812
148// ========================================================================== 148// ==========================================================================
149 149
150# if WS2812_LED_TOTAL > 0
151rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
152# endif
153
154static void rgb_matrix_driver_init(void) { 150static void rgb_matrix_driver_init(void) {
155 i2c_init(); 151 i2c_init();
156 is31fl3733_init(0); 152 is31fl3733_init(0);
@@ -164,31 +160,25 @@ static void rgb_matrix_driver_init(void) {
164 160
165static void rgb_matrix_driver_flush(void) { 161static void rgb_matrix_driver_flush(void) {
166 is31fl3733_update_pwm_buffers(0); 162 is31fl3733_update_pwm_buffers(0);
167# if WS2812_LED_TOTAL > 0 163# if WS2812_LED_COUNT > 0
168 ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); 164 ws2812_flush();
169# endif 165# endif
170} 166}
171 167
172static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { 168static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
173 if (index < IS31FL3733_LED_COUNT) { 169 if (index < IS31FL3733_LED_COUNT) {
174 is31fl3733_set_color(index, red, green, blue); 170 is31fl3733_set_color(index, red, green, blue);
171# if WS2812_LED_COUNT > 0
175 } else { 172 } else {
176# if WS2812_LED_TOTAL > 0 173 ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue);
177 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red;
178 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green;
179 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue;
180# endif 174# endif
181 } 175 }
182} 176}
183 177
184static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { 178static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
185 is31fl3733_set_color_all(red, green, blue); 179 is31fl3733_set_color_all(red, green, blue);
186# if WS2812_LED_TOTAL > 0 180# if WS2812_LED_COUNT > 0
187 for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { 181 ws2812_set_color_all(red, green, blue);
188 rgb_matrix_ws2812_array[i].r = red;
189 rgb_matrix_ws2812_array[i].g = green;
190 rgb_matrix_ws2812_array[i].b = blue;
191 }
192# endif 182# endif
193} 183}
194 184
diff --git a/keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h b/keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h
index ea594e53cf..710e240aa4 100644
--- a/keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h
+++ b/keyboards/kprepublic/bm60hsrgb_iso/rev2/config.h
@@ -23,9 +23,9 @@
23// Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them; 23// Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
24// don't use those LEDs in RGB Matrix in that case. 24// don't use those LEDs in RGB Matrix in that case.
25#ifdef RGBLIGHT_ENABLE 25#ifdef RGBLIGHT_ENABLE
26# define WS2812_LED_TOTAL 0 26# define WS2812_LED_COUNT 0
27#else 27#else
28# define WS2812_LED_TOTAL 6 28# define WS2812_LED_COUNT 6
29#endif 29#endif
30 30
31#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL) 31#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT)
diff --git a/keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c b/keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c
index 794dea5176..0d52d1bacb 100644
--- a/keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c
+++ b/keyboards/kprepublic/bm60hsrgb_iso/rev2/rev2.c
@@ -112,7 +112,7 @@ led_config_t g_led_config = { {
112 { 3, 48 }, { 22, 48 }, { 33, 48 }, { 48, 48 }, { 63, 48 }, { 78, 48 }, { 93, 48 }, { 108, 48 }, { 123, 48 }, { 138, 48 }, { 153, 48 }, { 168, 48 }, { 194, 48 }, { 213, 48 }, 112 { 3, 48 }, { 22, 48 }, { 33, 48 }, { 48, 48 }, { 63, 48 }, { 78, 48 }, { 93, 48 }, { 108, 48 }, { 123, 48 }, { 138, 48 }, { 153, 48 }, { 168, 48 }, { 194, 48 }, { 213, 48 },
113 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right 113 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
114 { 3, 64 }, { 22, 64 }, { 33, 64 }, { 101, 64 }, { 135, 64 }, { 153, 64 }, { 195, 64 }, { 210, 64 }, { 225, 64 } 114 { 3, 64 }, { 22, 64 }, { 33, 64 }, { 101, 64 }, { 135, 64 }, { 153, 64 }, { 195, 64 }, { 210, 64 }, { 225, 64 }
115# if WS2812_LED_TOTAL > 0 115# if WS2812_LED_COUNT > 0
116 ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40} 116 ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
117# endif 117# endif
118}, { 118}, {
@@ -126,7 +126,7 @@ led_config_t g_led_config = { {
126 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 126 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4,
127 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right 127 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
128 1, 1, 1, 4, 1, 1, 1, 1, 1 128 1, 1, 1, 4, 1, 1, 1, 1, 1
129# if WS2812_LED_TOTAL > 0 129# if WS2812_LED_COUNT > 0
130 ,2, 2, 2, 2, 2, 2 130 ,2, 2, 2, 2, 2, 2
131# endif 131# endif
132} }; 132} };
@@ -147,10 +147,6 @@ bool rgb_matrix_indicators_kb(void) {
147// Custom RGB Matrix driver that combines IS31FL3733 and WS2812 147// Custom RGB Matrix driver that combines IS31FL3733 and WS2812
148// ========================================================================== 148// ==========================================================================
149 149
150# if WS2812_LED_TOTAL > 0
151rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
152# endif
153
154static void rgb_matrix_driver_init(void) { 150static void rgb_matrix_driver_init(void) {
155 i2c_init(); 151 i2c_init();
156 is31fl3733_init(0); 152 is31fl3733_init(0);
@@ -164,31 +160,25 @@ static void rgb_matrix_driver_init(void) {
164 160
165static void rgb_matrix_driver_flush(void) { 161static void rgb_matrix_driver_flush(void) {
166 is31fl3733_update_pwm_buffers(0); 162 is31fl3733_update_pwm_buffers(0);
167# if WS2812_LED_TOTAL > 0 163# if WS2812_LED_COUNT > 0
168 ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); 164 ws2812_flush();
169# endif 165# endif
170} 166}
171 167
172static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { 168static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
173 if (index < IS31FL3733_LED_COUNT) { 169 if (index < IS31FL3733_LED_COUNT) {
174 is31fl3733_set_color(index, red, green, blue); 170 is31fl3733_set_color(index, red, green, blue);
171# if WS2812_LED_COUNT > 0
175 } else { 172 } else {
176# if WS2812_LED_TOTAL > 0 173 ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue);
177 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red;
178 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green;
179 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue;
180# endif 174# endif
181 } 175 }
182} 176}
183 177
184static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { 178static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
185 is31fl3733_set_color_all(red, green, blue); 179 is31fl3733_set_color_all(red, green, blue);
186# if WS2812_LED_TOTAL > 0 180# if WS2812_LED_COUNT > 0
187 for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { 181 ws2812_set_color_all(red, green, blue);
188 rgb_matrix_ws2812_array[i].r = red;
189 rgb_matrix_ws2812_array[i].g = green;
190 rgb_matrix_ws2812_array[i].b = blue;
191 }
192# endif 182# endif
193} 183}
194 184
diff --git a/keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h b/keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h
index b5ff897b18..843c5b2625 100644
--- a/keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h
+++ b/keyboards/kprepublic/bm60hsrgb_poker/rev2/config.h
@@ -21,9 +21,9 @@
21// Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them; 21// Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
22// don't use those LEDs in RGB Matrix in that case. 22// don't use those LEDs in RGB Matrix in that case.
23#ifdef RGBLIGHT_ENABLE 23#ifdef RGBLIGHT_ENABLE
24# define WS2812_LED_TOTAL 0 24# define WS2812_LED_COUNT 0
25#else 25#else
26# define WS2812_LED_TOTAL 6 26# define WS2812_LED_COUNT 6
27#endif 27#endif
28 28
29#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL) 29#define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT)
diff --git a/keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c b/keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c
index 3586dc8e80..5766942b34 100644
--- a/keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c
+++ b/keyboards/kprepublic/bm60hsrgb_poker/rev2/rev2.c
@@ -107,7 +107,7 @@ led_config_t g_led_config = {
107 { 18, 48 }, { 30, 48 }, { 45, 48 }, { 60, 48 }, { 75, 48 }, { 90, 48 }, { 105, 48 }, { 120, 48 }, { 135, 48 }, { 150, 48 }, { 165, 48 }, { 191, 48 }, 107 { 18, 48 }, { 30, 48 }, { 45, 48 }, { 60, 48 }, { 75, 48 }, { 90, 48 }, { 105, 48 }, { 120, 48 }, { 135, 48 }, { 150, 48 }, { 165, 48 }, { 191, 48 },
108 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right 108 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
109 { 3, 64 }, { 22, 64 }, { 33, 64 }, { 101, 64 }, { 135, 64 }, { 153, 64 }, { 210, 64 }, { 225, 64 } 109 { 3, 64 }, { 22, 64 }, { 33, 64 }, { 101, 64 }, { 135, 64 }, { 153, 64 }, { 210, 64 }, { 225, 64 }
110# if WS2812_LED_TOTAL > 0 110# if WS2812_LED_COUNT > 0
111 ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40} 111 ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40}
112# endif 112# endif
113}, { 113}, {
@@ -121,7 +121,7 @@ led_config_t g_led_config = {
121 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 121 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
122 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right 122 // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
123 1, 1, 1, 4, 1, 1, 1, 1 123 1, 1, 1, 4, 1, 1, 1, 1
124# if WS2812_LED_TOTAL > 0 124# if WS2812_LED_COUNT > 0
125 ,2, 2, 2, 2, 2, 2 125 ,2, 2, 2, 2, 2, 2
126# endif 126# endif
127 } 127 }
@@ -143,10 +143,6 @@ bool rgb_matrix_indicators_kb(void) {
143// Custom RGB Matrix driver that combines IS31FL3733 and WS2812 143// Custom RGB Matrix driver that combines IS31FL3733 and WS2812
144// ========================================================================== 144// ==========================================================================
145 145
146# if WS2812_LED_TOTAL > 0
147rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
148# endif
149
150static void rgb_matrix_driver_init(void) { 146static void rgb_matrix_driver_init(void) {
151 i2c_init(); 147 i2c_init();
152 is31fl3733_init(0); 148 is31fl3733_init(0);
@@ -160,31 +156,25 @@ static void rgb_matrix_driver_init(void) {
160 156
161static void rgb_matrix_driver_flush(void) { 157static void rgb_matrix_driver_flush(void) {
162 is31fl3733_update_pwm_buffers(0); 158 is31fl3733_update_pwm_buffers(0);
163# if WS2812_LED_TOTAL > 0 159# if WS2812_LED_COUNT > 0
164 ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); 160 ws2812_flush();
165# endif 161# endif
166} 162}
167 163
168static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { 164static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
169 if (index < IS31FL3733_LED_COUNT) { 165 if (index < IS31FL3733_LED_COUNT) {
170 is31fl3733_set_color(index, red, green, blue); 166 is31fl3733_set_color(index, red, green, blue);
167# if WS2812_LED_COUNT > 0
171 } else { 168 } else {
172# if WS2812_LED_TOTAL > 0 169 ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue);
173 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red;
174 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green;
175 rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue;
176# endif 170# endif
177 } 171 }
178} 172}
179 173
180static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { 174static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
181 is31fl3733_set_color_all(red, green, blue); 175 is31fl3733_set_color_all(red, green, blue);
182# if WS2812_LED_TOTAL > 0 176# if WS2812_LED_COUNT > 0
183 for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { 177 ws2812_set_color_all(red, green, blue);
184 rgb_matrix_ws2812_array[i].r = red;
185 rgb_matrix_ws2812_array[i].g = green;
186 rgb_matrix_ws2812_array[i].b = blue;
187 }
188# endif 178# endif
189} 179}
190 180
diff --git a/keyboards/matrix/abelx/abelx.c b/keyboards/matrix/abelx/abelx.c
index ee7ffde134..9058bf6e2f 100644
--- a/keyboards/matrix/abelx/abelx.c
+++ b/keyboards/matrix/abelx/abelx.c
@@ -41,20 +41,6 @@ uint8_t read_pin(uint16_t pin)
41 return (data & (1<<GET_PIN(pin))) ? 1 : 0; 41 return (data & (1<<GET_PIN(pin))) ? 1 : 0;
42} 42}
43 43
44void matrix_init_kb(void) {
45#ifdef RGBLIGHT_ENABLE
46 aw9523b_init(AW9523B_ADDR);
47#endif
48 matrix_init_user();
49}
50
51
52void housekeeping_task_kb(void) {
53#ifdef RGBLIGHT_ENABLE
54 aw9523b_update_pwm_buffers(AW9523B_ADDR);
55#endif
56}
57
58#ifdef RGBLIGHT_ENABLE 44#ifdef RGBLIGHT_ENABLE
59#include "rgblight.h" 45#include "rgblight.h"
60#include "ws2812.h" 46#include "ws2812.h"
@@ -67,20 +53,35 @@ const aw9523b_led g_aw9523b_leds[AW9523B_RGB_NUM] = {
67 {AW9523B_P07_PWM, AW9523B_P06_PWM, AW9523B_P05_PWM}, 53 {AW9523B_P07_PWM, AW9523B_P06_PWM, AW9523B_P05_PWM},
68}; 54};
69 55
70void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) 56void init_custom(void) {
71{ 57 aw9523b_init(AW9523B_ADDR);
72 uint8_t num = num_leds < AW9523B_RGB_NUM ? num_leds : AW9523B_RGB_NUM; 58 ws2812_init();
59}
73 60
74 ws2812_setleds(start_led, num); 61void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
62 if (index < AW9523B_RGB_NUM) {
63 aw9523b_set_color(index, red, green, blue);
64 } else {
65 ws2812_set_color(index - AW9523B_RGB_NUM, red, green, blue);
66 }
67}
75 68
76 for (int i = 0; i < num; i++) { 69void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
77 aw9523b_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); 70 for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
71 set_color_custom(i, red, green, blue);
78 } 72 }
79} 73}
80 74
75void flush_custom(void) {
76 aw9523b_update_pwm_buffers(AW9523B_ADDR);
77 ws2812_flush();
78}
79
81const rgblight_driver_t rgblight_driver = { 80const rgblight_driver_t rgblight_driver = {
82 .init = ws2812_init, 81 .init = init_custom,
83 .setleds = setleds_custom, 82 .set_color = set_color_custom,
83 .set_color_all = set_color_all_custom,
84 .flush = flush_custom,
84}; 85};
85 86
86#endif 87#endif
diff --git a/keyboards/matrix/abelx/config.h b/keyboards/matrix/abelx/config.h
index 63b8202146..bd552d11a2 100644
--- a/keyboards/matrix/abelx/config.h
+++ b/keyboards/matrix/abelx/config.h
@@ -89,5 +89,6 @@
89#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2 89#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
90 90
91#define AW9523B_RGB_NUM 4 91#define AW9523B_RGB_NUM 4
92#define WS2812_LED_COUNT 5
92 93
93#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE 94#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE
diff --git a/keyboards/matrix/m20add/m20add.c b/keyboards/matrix/m20add/m20add.c
index 267c8e5134..2d5209e3a0 100644
--- a/keyboards/matrix/m20add/m20add.c
+++ b/keyboards/matrix/m20add/m20add.c
@@ -27,13 +27,6 @@ uint8_t read_pin(uint16_t pin)
27 return (data & (1<<GET_PIN(pin))) ? 1 : 0; 27 return (data & (1<<GET_PIN(pin))) ? 1 : 0;
28} 28}
29 29
30void matrix_init_kb(void) {
31#ifdef RGBLIGHT_ENABLE
32 rgb_ring_init();
33#endif
34 matrix_init_user();
35}
36
37void housekeeping_task_kb(void) { 30void housekeeping_task_kb(void) {
38#ifdef RGBLIGHT_ENABLE 31#ifdef RGBLIGHT_ENABLE
39 rgb_ring_task(); 32 rgb_ring_task();
diff --git a/keyboards/matrix/m20add/rgb_ring.c b/keyboards/matrix/m20add/rgb_ring.c
index d629a5d2ec..9b0e54a6b9 100644
--- a/keyboards/matrix/m20add/rgb_ring.c
+++ b/keyboards/matrix/m20add/rgb_ring.c
@@ -361,27 +361,22 @@ static void custom_effects(void)
361 effect_funcs[rgb_ring.effect](); 361 effect_funcs[rgb_ring.effect]();
362} 362}
363 363
364void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) 364void flush_custom(void) {
365{
366 if (rgb_ring.state != RING_STATE_QMK) { 365 if (rgb_ring.state != RING_STATE_QMK) {
367 return; 366 return;
368 } 367 }
369 368
370 for (uint8_t i = 0; i < num_leds; i++) { 369 is31fl3731_flush();
371 is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b);
372 }
373} 370}
374 371
375const rgblight_driver_t rgblight_driver = { 372const rgblight_driver_t rgblight_driver = {
376 .setleds = setleds_custom, 373 .init = is31fl3731_init_drivers,
374 .set_color = is31fl3731_set_color,
375 .set_color_all = is31fl3731_set_color_all,
376 .flush = flush_custom,
377}; 377};
378 378
379 379
380void rgb_ring_init(void)
381{
382 is31fl3731_init_drivers();
383}
384
385void rgb_ring_task(void) 380void rgb_ring_task(void)
386{ 381{
387 switch (rgb_ring.state) { 382 switch (rgb_ring.state) {
@@ -397,8 +392,6 @@ void rgb_ring_task(void)
397 default: 392 default:
398 break; 393 break;
399 }; 394 };
400
401 is31fl3731_flush();
402} 395}
403 396
404bool process_record_kb(uint16_t keycode, keyrecord_t *record) 397bool process_record_kb(uint16_t keycode, keyrecord_t *record)
diff --git a/keyboards/matrix/m20add/rgb_ring.h b/keyboards/matrix/m20add/rgb_ring.h
index 1e96b68367..25937e6500 100644
--- a/keyboards/matrix/m20add/rgb_ring.h
+++ b/keyboards/matrix/m20add/rgb_ring.h
@@ -19,5 +19,4 @@
19 19
20#pragma once 20#pragma once
21 21
22void rgb_ring_init(void);
23void rgb_ring_task(void); 22void rgb_ring_task(void);
diff --git a/keyboards/matrix/noah/keyboard.json b/keyboards/matrix/noah/keyboard.json
index 3ba9be21eb..53c8dc2458 100644
--- a/keyboards/matrix/noah/keyboard.json
+++ b/keyboards/matrix/noah/keyboard.json
@@ -10,7 +10,7 @@
10 "no_startup_check": true 10 "no_startup_check": true
11 }, 11 },
12 "rgblight": { 12 "rgblight": {
13 "driver": "custom", 13 "driver": "ws2812",
14 "led_count": 7, 14 "led_count": 7,
15 "animations": { 15 "animations": {
16 "breathing": true, 16 "breathing": true,
diff --git a/keyboards/matrix/noah/noah.c b/keyboards/matrix/noah/noah.c
index 99f4e063d1..22d159328a 100644
--- a/keyboards/matrix/noah/noah.c
+++ b/keyboards/matrix/noah/noah.c
@@ -9,57 +9,6 @@ void bootloader_jump(void) {
9 NVIC_SystemReset(); 9 NVIC_SystemReset();
10} 10}
11 11
12#ifdef RGBLIGHT_ENABLE
13#include <string.h>
14#include "rgblight.h"
15#include "ws2812.h"
16extern rgblight_config_t rgblight_config;
17
18// led 0 for caps lock, led 1 for scroll lock, led 3 for num lock
19// led 4 for layer 1, led 5 for layer 2, led 6 for layer 3, led 7 for layer 4
20#if RGBLIGHT_LED_COUNT < 7
21#error "MUST set the RGBLIGHT_LED_COUNT bigger than 7"
22#endif
23rgb_led_t noah_leds[RGBLIGHT_LED_COUNT];
24static bool noah_led_mode = false;
25void setleds_custom(rgb_led_t *ledarray, uint16_t num_leds) {
26 memset(&noah_leds[0], 0, sizeof(noah_leds));
27 if (!rgblight_config.enable) {
28 for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) {
29 ledarray[i].r = 0;
30 ledarray[i].g = 0;
31 ledarray[i].b = 0;
32 }
33 }
34 if (noah_led_mode) {
35 led_t led_state = host_keyboard_led_state();
36 if (led_state.caps_lock) {
37 noah_leds[0] = ledarray[0];
38 }
39 if (led_state.scroll_lock) {
40 noah_leds[1] = ledarray[1];
41 }
42 if (led_state.num_lock) {
43 noah_leds[2] = ledarray[2];
44 }
45 for (int32_t i = 0; i < 4; i++) {
46 if(layer_state_is(i+1)) {
47 noah_leds[i + 3] = ledarray[i + 3];
48 }
49 }
50 } else {
51 memcpy(&noah_leds[0], &ledarray[0], sizeof(noah_leds));
52 }
53
54 ws2812_setleds(noah_leds, RGBLIGHT_LED_COUNT);
55}
56
57const rgblight_driver_t rgblight_driver = {
58 .init = ws2812_init,
59 .setleds = setleds_custom,
60};
61#endif
62
63#ifdef RGB_MATRIX_ENABLE 12#ifdef RGB_MATRIX_ENABLE
64const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { 13const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
65/* Refer to IS31 manual for these locations 14/* Refer to IS31 manual for these locations
@@ -150,11 +99,6 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
150bool process_record_kb(uint16_t keycode, keyrecord_t *record) { 99bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
151 if (record->event.pressed) { 100 if (record->event.pressed) {
152 switch(keycode) { 101 switch(keycode) {
153 #ifdef RGBLIGHT_ENABLE
154 case KC_F24: // switch the led mode on or off
155 noah_led_mode = !noah_led_mode;
156 return false;
157
158 #ifdef RGB_MATRIX_ENABLE 102 #ifdef RGB_MATRIX_ENABLE
159 case KC_F13: // toggle rgb matrix 103 case KC_F13: // toggle rgb matrix
160 rgb_matrix_toggle(); 104 rgb_matrix_toggle();
@@ -163,7 +107,6 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
163 rgb_matrix_step(); 107 rgb_matrix_step();
164 return false; 108 return false;
165 #endif 109 #endif
166 #endif
167 default: 110 default:
168 break; 111 break;
169 } 112 }
diff --git a/keyboards/neson_design/700e/700e.c b/keyboards/neson_design/700e/700e.c
index c6ba94c834..cee22cf78d 100644
--- a/keyboards/neson_design/700e/700e.c
+++ b/keyboards/neson_design/700e/700e.c
@@ -18,9 +18,11 @@
18 */ 18 */
19 19
20#include "quantum.h" 20#include "quantum.h"
21#include "i2c_master.h" 21
22#include "drivers/led/issi/is31fl3731.h" 22#ifdef RGBLIGHT_ENABLE
23#include "ws2812.h" 23# include "i2c_master.h"
24# include "drivers/led/issi/is31fl3731.h"
25# include "ws2812.h"
24 26
25enum { 27enum {
26 SELF_TESTING, 28 SELF_TESTING,
@@ -67,7 +69,6 @@ enum {
67#endif 69#endif
68#define ST_RIGHT_END (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1) 70#define ST_RIGHT_END (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1)
69 71
70#ifdef RGBLIGHT_ENABLE
71 72
72typedef struct { 73typedef struct {
73 uint8_t state; 74 uint8_t state;
@@ -295,7 +296,6 @@ void matrix_init_kb(void)
295 gpio_set_pin_output(LED_CAPS_LOCK_PIN); 296 gpio_set_pin_output(LED_CAPS_LOCK_PIN);
296 gpio_write_pin_low(LED_CAPS_LOCK_PIN); 297 gpio_write_pin_low(LED_CAPS_LOCK_PIN);
297 298
298 is31fl3731_init_drivers();
299 299
300 update_ticks(); 300 update_ticks();
301 matrix_init_user(); 301 matrix_init_user();
@@ -313,17 +313,10 @@ void housekeeping_task_kb(void)
313 } else if (rgb_state.state == CAPS_ALERT) { 313 } else if (rgb_state.state == CAPS_ALERT) {
314 if (rgb_state.alert) { 314 if (rgb_state.alert) {
315 is31fl3731_set_color_all(ALERM_LED_R, ALERM_LED_G, ALERM_LED_B); 315 is31fl3731_set_color_all(ALERM_LED_R, ALERM_LED_G, ALERM_LED_B);
316 rgb_led_t leds[4]; 316 ws2812_set_color_all(ALERM_LED_G, ALERM_LED_R, ALERM_LED_B);
317 for (int i = 0; i < 4; i++) {
318 leds[i].r = ALERM_LED_G;
319 leds[i].g = ALERM_LED_R;
320 leds[i].b = ALERM_LED_B;
321 }
322 ws2812_setleds(leds, 4);
323 } else { 317 } else {
324 is31fl3731_set_color_all(0, 0, 0); 318 is31fl3731_set_color_all(0, 0, 0);
325 rgb_led_t leds[4] = {0}; 319 ws2812_set_color_all(0, 0, 0);
326 ws2812_setleds(leds, 4);
327 } 320 }
328 321
329 if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) { 322 if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) {
@@ -333,28 +326,40 @@ void housekeeping_task_kb(void)
333 } 326 }
334 327
335 is31fl3731_flush(); 328 is31fl3731_flush();
329 ws2812_flush();
336} 330}
337 331
338void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) 332void init_custom(void) {
339{ 333 is31fl3731_init_drivers();
340 if (rgb_state.state != NORMAL) return; 334 ws2812_init();
335}
341 336
342 for (uint8_t i = 0; i < IS31FL3731_LED_COUNT; i++) { 337void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
343 is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); 338 if (index < IS31FL3731_LED_COUNT) {
339 is31fl3731_set_color(index, red, green, blue);
340 } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) {
341 ws2812_set_color(index - IS31FL3731_LED_COUNT, green, red, blue);
344 } 342 }
345 rgb_led_t leds[4]; 343}
346 for (int i = 0; i < 4; i++) { 344
347 leds[i].r = start_led[IS31FL3731_LED_COUNT+i].g; 345void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
348 leds[i].g = start_led[IS31FL3731_LED_COUNT+i].r; 346 for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
349 leds[i].b = start_led[IS31FL3731_LED_COUNT+i].b; 347 set_color_custom(i, red, green, blue);
350 } 348 }
351 //ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 4); 349}
352 ws2812_setleds(leds, 4); 350
351void flush_custom(void) {
352 if (rgb_state.state != NORMAL) return;
353
354 is31fl3731_flush();
355 ws2812_flush();
353} 356}
354 357
355const rgblight_driver_t rgblight_driver = { 358const rgblight_driver_t rgblight_driver = {
356 .init = ws2812_init, 359 .init = init_custom,
357 .setleds = setleds_custom, 360 .set_color = set_color_custom,
361 .set_color_all = set_color_all_custom,
362 .flush = flush_custom,
358}; 363};
359 364
360bool led_update_kb(led_t led_state) 365bool led_update_kb(led_t led_state)
diff --git a/keyboards/neson_design/700e/config.h b/keyboards/neson_design/700e/config.h
index d92c9deb5d..2c2d02cad1 100644
--- a/keyboards/neson_design/700e/config.h
+++ b/keyboards/neson_design/700e/config.h
@@ -21,5 +21,6 @@
21#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND 21#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
22#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC 22#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
23#define IS31FL3731_LED_COUNT 64 23#define IS31FL3731_LED_COUNT 64
24#define WS2812_LED_COUNT 4
24 25
25#define USB_SUSPEND_WAKEUP_DELAY 1000 26#define USB_SUSPEND_WAKEUP_DELAY 1000
diff --git a/keyboards/neson_design/n6/config.h b/keyboards/neson_design/n6/config.h
index 92aa189fae..dd67c11851 100644
--- a/keyboards/neson_design/n6/config.h
+++ b/keyboards/neson_design/n6/config.h
@@ -21,3 +21,4 @@
21#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND 21#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
22#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC 22#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC
23#define IS31FL3731_LED_COUNT 64 23#define IS31FL3731_LED_COUNT 64
24#define WS2812_LED_COUNT 1
diff --git a/keyboards/neson_design/n6/n6.c b/keyboards/neson_design/n6/n6.c
index ef5035dcde..03bb88c40b 100644
--- a/keyboards/neson_design/n6/n6.c
+++ b/keyboards/neson_design/n6/n6.c
@@ -18,9 +18,11 @@
18 */ 18 */
19 19
20#include "quantum.h" 20#include "quantum.h"
21#include "i2c_master.h" 21
22#include "drivers/led/issi/is31fl3731.h" 22#ifdef RGBLIGHT_ENABLE
23#include "ws2812.h" 23# include "i2c_master.h"
24# include "drivers/led/issi/is31fl3731.h"
25# include "ws2812.h"
24 26
25enum { 27enum {
26 SELF_TESTING, 28 SELF_TESTING,
@@ -67,7 +69,6 @@ enum {
67#endif 69#endif
68#define ST_RIGHT_END (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1) 70#define ST_RIGHT_END (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1)
69 71
70#ifdef RGBLIGHT_ENABLE
71extern rgblight_config_t rgblight_config; 72extern rgblight_config_t rgblight_config;
72 73
73typedef struct { 74typedef struct {
@@ -299,8 +300,6 @@ void matrix_init_kb(void)
299 gpio_set_pin_output(LED_CAPS_LOCK_PIN); 300 gpio_set_pin_output(LED_CAPS_LOCK_PIN);
300 gpio_write_pin_low(LED_CAPS_LOCK_PIN); 301 gpio_write_pin_low(LED_CAPS_LOCK_PIN);
301 302
302 is31fl3731_init_drivers();
303
304 update_ticks(); 303 update_ticks();
305 matrix_init_user(); 304 matrix_init_user();
306} 305}
@@ -310,22 +309,12 @@ void housekeeping_task_kb(void)
310 if (rgb_state.state == SELF_TESTING) { 309 if (rgb_state.state == SELF_TESTING) {
311 self_testing(); 310 self_testing();
312 } else if (rgb_state.state == CAPS_ALERT) { 311 } else if (rgb_state.state == CAPS_ALERT) {
313 //gold 0xFF, 0xD9, 0x00
314 rgb_led_t led = {
315 .r = 0xFF,
316 //.g = 0xD9,
317 .g = 0xA5,
318 .b = 0x00,
319 };
320 if (rgb_state.alert) { 312 if (rgb_state.alert) {
321 is31fl3731_set_color_all(led.r, led.g, led.b); 313 is31fl3731_set_color_all(0xFF, 0xA5, 0x00);
322 ws2812_setleds(&led, 1); 314 ws2812_set_color_all(0xFF, 0xA5, 0x00);
323 } else { 315 } else {
324 led.r = 0;
325 led.g = 0;
326 led.b = 0;
327 is31fl3731_set_color_all(0, 0, 0); 316 is31fl3731_set_color_all(0, 0, 0);
328 ws2812_setleds(&led, 1); 317 ws2812_set_color_all(0, 0, 0);
329 } 318 }
330 319
331 if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) { 320 if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) {
@@ -337,19 +326,37 @@ void housekeeping_task_kb(void)
337 is31fl3731_flush(); 326 is31fl3731_flush();
338} 327}
339 328
340void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) 329void init_custom(void) {
341{ 330 is31fl3731_init_drivers();
342 if (rgb_state.state != NORMAL) return; 331 ws2812_init();
332}
343 333
344 for (uint8_t i = 0; i < IS31FL3731_LED_COUNT; i++) { 334void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
345 is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); 335 if (index < IS31FL3731_LED_COUNT) {
336 is31fl3731_set_color(index, red, green, blue);
337 } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) {
338 ws2812_set_color(index - IS31FL3731_LED_COUNT, red, green, blue);
346 } 339 }
347 ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 1); 340}
341
342void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
343 for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
344 set_color_custom(i, red, green, blue);
345 }
346}
347
348void flush_custom(void) {
349 if (rgb_state.state != NORMAL) return;
350
351 is31fl3731_flush();
352 ws2812_flush();
348} 353}
349 354
350const rgblight_driver_t rgblight_driver = { 355const rgblight_driver_t rgblight_driver = {
351 .init = ws2812_init, 356 .init = init_custom,
352 .setleds = setleds_custom, 357 .set_color = set_color_custom,
358 .set_color_all = set_color_all_custom,
359 .flush = flush_custom,
353}; 360};
354 361
355bool led_update_kb(led_t led_state) 362bool led_update_kb(led_t led_state)
diff --git a/keyboards/oddforge/vea/ws2812_custom.c b/keyboards/oddforge/vea/ws2812_custom.c
index 317f98130b..568f0e176d 100644
--- a/keyboards/oddforge/vea/ws2812_custom.c
+++ b/keyboards/oddforge/vea/ws2812_custom.c
@@ -17,12 +17,25 @@
17# define WS2812_I2C_TIMEOUT 100 17# define WS2812_I2C_TIMEOUT 100
18#endif 18#endif
19 19
20ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
21
20void ws2812_init(void) { 22void ws2812_init(void) {
21 i2c_init(); 23 i2c_init();
22} 24}
23 25
24// Setleds for standard RGB 26void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
25void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) { 27 ws2812_leds[index].r = red;
26 i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ledarray, sizeof(rgb_led_t) * (leds >> 1), WS2812_I2C_TIMEOUT); 28 ws2812_leds[index].g = green;
27 i2c_transmit(WS2812_I2C_ADDRESS_RIGHT, (uint8_t *)ledarray+(sizeof(rgb_led_t) * (leds >> 1)), sizeof(rgb_led_t) * (leds - (leds >> 1)), WS2812_I2C_TIMEOUT); 29 ws2812_leds[index].b = blue;
30}
31
32void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
33 for (int i = 0; i < WS2812_LED_COUNT; i++) {
34 ws2812_set_color(i, red, green, blue);
35 }
36}
37
38void ws2812_flush(void) {
39 i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, sizeof(ws2812_led_t) * (WS2812_LED_COUNT >> 1), WS2812_I2C_TIMEOUT);
40 i2c_transmit(WS2812_I2C_ADDRESS_RIGHT, (uint8_t *)ws2812_leds + (sizeof(ws2812_led_t) * (WS2812_LED_COUNT >> 1)), sizeof(ws2812_led_t) * (WS2812_LED_COUNT - (WS2812_LED_COUNT >> 1)), WS2812_I2C_TIMEOUT);
28} 41}
diff --git a/keyboards/orthograph/orthograph.c b/keyboards/orthograph/orthograph.c
index 9d824574d1..0649115aa3 100644
--- a/keyboards/orthograph/orthograph.c
+++ b/keyboards/orthograph/orthograph.c
@@ -125,4 +125,7 @@ const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT] = {
125{0, SW7_CS7, SW8_CS7, SW9_CS7} 125{0, SW7_CS7, SW8_CS7, SW9_CS7}
126}; 126};
127 127
128int rgb_matrix_led_index(int index) {
129 return index;
130}
128#endif 131#endif
diff --git a/keyboards/rgbkb/pan/config.h b/keyboards/rgbkb/pan/config.h
index abb9620a5d..be719c1437 100644
--- a/keyboards/rgbkb/pan/config.h
+++ b/keyboards/rgbkb/pan/config.h
@@ -17,3 +17,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
17#pragma once 17#pragma once
18 18
19#define RGB_MATRIX_LED_COUNT 64 19#define RGB_MATRIX_LED_COUNT 64
20#define WS2812_LED_COUNT 64
diff --git a/keyboards/rgbkb/pan/pan.c b/keyboards/rgbkb/pan/pan.c
index 401831e0e2..20cc4dd248 100644
--- a/keyboards/rgbkb/pan/pan.c
+++ b/keyboards/rgbkb/pan/pan.c
@@ -21,43 +21,23 @@
21# if defined(KEYBOARD_rgbkb_pan_rev1) 21# if defined(KEYBOARD_rgbkb_pan_rev1)
22# include "ws2812.h" 22# include "ws2812.h"
23 23
24// LED color buffer
25rgb_led_t rgb_matrix_ws2812_array[RGB_MATRIX_LED_COUNT];
26
27static void flush(void) {
28 ws2812_setleds(rgb_matrix_ws2812_array, RGB_MATRIX_LED_COUNT);
29}
30
31// Set an led in the buffer to a color 24// Set an led in the buffer to a color
32static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) { 25static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
33# if defined(RGB_ENCODERS) || defined(STAGGERED_RGB_ENCODERS) 26# if defined(RGB_ENCODERS) || defined(STAGGERED_RGB_ENCODERS)
34 if (i == 0 || i == 1) { // if encoder LEDs, change LEDs 27 if (i == 0 || i == 1) { // if encoder LEDs, change LEDs
35 rgb_matrix_ws2812_array[i].r = g; 28 ws2812_set_color(i, g, b, r);
36 rgb_matrix_ws2812_array[i].g = b;
37 rgb_matrix_ws2812_array[i].b = r;
38 } else 29 } else
39# endif 30# endif
40 { 31 {
41 rgb_matrix_ws2812_array[i].r = r; 32 ws2812_set_color(i, r, g, b);
42 rgb_matrix_ws2812_array[i].g = g;
43 rgb_matrix_ws2812_array[i].b = b;
44 }
45# ifdef WS2812_RGBW
46 convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]);
47# endif
48}
49
50static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
51 for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) {
52 setled(i, r, g, b);
53 } 33 }
54} 34}
55 35
56const rgb_matrix_driver_t rgb_matrix_driver = { 36const rgb_matrix_driver_t rgb_matrix_driver = {
57 .init = ws2812_init, 37 .init = ws2812_init,
58 .flush = flush, 38 .flush = ws2812_flush,
59 .set_color = setled, 39 .set_color = setled,
60 .set_color_all = setled_all, 40 .set_color_all = ws2812_set_color_all,
61}; 41};
62# endif 42# endif
63 43
diff --git a/keyboards/steelseries/prime_plus/rgblight_custom.c b/keyboards/steelseries/prime_plus/rgblight_custom.c
index cdb9e10078..d2be789203 100644
--- a/keyboards/steelseries/prime_plus/rgblight_custom.c
+++ b/keyboards/steelseries/prime_plus/rgblight_custom.c
@@ -1,45 +1,65 @@
1// Copyright 2024 Dasky (@daskygit) 1// Copyright 2024 Dasky (@daskygit)
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "quantum.h" 4#include <hal.h>
5#include "chibios_config.h"
6#include "gpio.h"
7#include "color.h"
8#include "rgblight_drivers.h"
5 9
6static PWMConfig pwmCFG = { 10static PWMConfig pwmCFG = {
7 .frequency = 0xFFFF, 11 .frequency = 0xFFFF,
8 .period = 256, 12 .period = 256,
9}; 13};
10 14
11void prime_setleds(rgb_led_t *start_led, uint16_t num_leds) { 15rgb_led_t prime_leds[RGBLIGHT_LED_COUNT];
12 if (start_led[0].r == 0) { 16
17void init_custom(void) {
18 palSetPadMode(PAL_PORT(RGB_RED_PIN), PAL_PAD(RGB_RED_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
19 palSetPadMode(PAL_PORT(RGB_GREEN_PIN), PAL_PAD(RGB_GREEN_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
20 palSetPadMode(PAL_PORT(RGB_BLUE_PIN), PAL_PAD(RGB_BLUE_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
21 pwmCFG.channels[RGB_RED_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
22 pwmCFG.channels[RGB_GREEN_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
23 pwmCFG.channels[RGB_BLUE_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
24 pwmStart(&RGB_PWM_DRIVER, &pwmCFG);
25}
26
27void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) {
28 prime_leds[index].r = red;
29 prime_leds[index].g = green;
30 prime_leds[index].b = blue;
31}
32
33void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) {
34 for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) {
35 set_color_custom(i, red, green, blue);
36 }
37}
38
39void flush_custom(void) {
40 if (prime_leds[0].r == 0) {
13 pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1); 41 pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1);
14 } else { 42 } else {
15 uint32_t duty = ((uint32_t)0xFFFF * start_led[0].r) / 0xFF; 43 uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].r) / 0xFF;
16 pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); 44 pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
17 } 45 }
18 if (start_led[0].g == 0) { 46 if (prime_leds[0].g == 0) {
19 pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1); 47 pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1);
20 } else { 48 } else {
21 uint32_t duty = ((uint32_t)0xFFFF * start_led[0].g) / 0xFF; 49 uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].g) / 0xFF;
22 pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); 50 pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
23 } 51 }
24 if (start_led[0].b == 0) { 52 if (prime_leds[0].b == 0) {
25 pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1); 53 pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1);
26 } else { 54 } else {
27 uint32_t duty = ((uint32_t)0xFFFF * start_led[0].b) / 0xFF; 55 uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].b) / 0xFF;
28 pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); 56 pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
29 } 57 }
30} 58}
31 59
32void prime_initleds(void) {
33 palSetPadMode(PAL_PORT(RGB_RED_PIN), PAL_PAD(RGB_RED_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
34 palSetPadMode(PAL_PORT(RGB_GREEN_PIN), PAL_PAD(RGB_GREEN_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
35 palSetPadMode(PAL_PORT(RGB_BLUE_PIN), PAL_PAD(RGB_BLUE_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
36 pwmCFG.channels[RGB_RED_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
37 pwmCFG.channels[RGB_GREEN_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
38 pwmCFG.channels[RGB_BLUE_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
39 pwmStart(&RGB_PWM_DRIVER, &pwmCFG);
40}
41
42const rgblight_driver_t rgblight_driver = { 60const rgblight_driver_t rgblight_driver = {
43 .init = prime_initleds, 61 .init = init_custom,
44 .setleds = prime_setleds, 62 .set_color = set_color_custom,
63 .set_color_all = set_color_all_custom,
64 .flush = flush_custom,
45}; 65};
diff --git a/keyboards/wilba_tech/wt_rgb_backlight.c b/keyboards/wilba_tech/wt_rgb_backlight.c
index 936286c2ee..645ee2b32a 100644
--- a/keyboards/wilba_tech/wt_rgb_backlight.c
+++ b/keyboards/wilba_tech/wt_rgb_backlight.c
@@ -60,7 +60,6 @@
60 60
61#if defined(RGB_BACKLIGHT_DAWN60) 61#if defined(RGB_BACKLIGHT_DAWN60)
62#include "ws2812.h" 62#include "ws2812.h"
63rgb_led_t g_ws2812_leds[WS2812_LED_TOTAL];
64#endif 63#endif
65 64
66#include "progmem.h" 65#include "progmem.h"
@@ -1011,6 +1010,9 @@ void backlight_update_pwm_buffers(void)
1011 driver = 0; 1010 driver = 0;
1012 } 1011 }
1013#else 1012#else
1013#if defined(RGB_BACKLIGHT_DAWN60)
1014 ws2812_flush();
1015#endif
1014 is31fl3731_update_pwm_buffers( 0 ); 1016 is31fl3731_update_pwm_buffers( 0 );
1015 is31fl3731_update_pwm_buffers( 1 ); 1017 is31fl3731_update_pwm_buffers( 1 );
1016 is31fl3731_update_led_control_registers( 0 ); 1018 is31fl3731_update_led_control_registers( 0 );
@@ -1037,10 +1039,7 @@ void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
1037 if( index < IS31FL3731_LED_COUNT ) { 1039 if( index < IS31FL3731_LED_COUNT ) {
1038 is31fl3731_set_color( index, red, green, blue ); 1040 is31fl3731_set_color( index, red, green, blue );
1039 } else { 1041 } else {
1040 g_ws2812_leds[index - IS31FL3731_LED_COUNT].r = red; 1042 ws2812_set_color( index - IS31FL3731_LED_COUNT, red, green, blue );
1041 g_ws2812_leds[index - IS31FL3731_LED_COUNT].g = green;
1042 g_ws2812_leds[index - IS31FL3731_LED_COUNT].b = blue;
1043 ws2812_setleds(g_ws2812_leds, WS2812_LED_TOTAL);
1044 } 1043 }
1045#else 1044#else
1046 is31fl3731_set_color( index, red, green, blue ); 1045 is31fl3731_set_color( index, red, green, blue );
@@ -1075,12 +1074,7 @@ void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
1075 } 1074 }
1076#elif defined(RGB_BACKLIGHT_DAWN60) 1075#elif defined(RGB_BACKLIGHT_DAWN60)
1077 is31fl3731_set_color_all( red, green, blue ); 1076 is31fl3731_set_color_all( red, green, blue );
1078 for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { 1077 ws2812_set_color_all( red, green, blue );
1079 g_ws2812_leds[i].r = red;
1080 g_ws2812_leds[i].g = green;
1081 g_ws2812_leds[i].b = blue;
1082 }
1083 ws2812_setleds(g_ws2812_leds, WS2812_LED_TOTAL);
1084#else 1078#else
1085 is31fl3731_set_color_all( red, green, blue ); 1079 is31fl3731_set_color_all( red, green, blue );
1086#endif 1080#endif
@@ -1325,7 +1319,7 @@ void backlight_effect_alphas_mods(void)
1325 } 1319 }
1326 } 1320 }
1327#if defined(RGB_BACKLIGHT_DAWN60) 1321#if defined(RGB_BACKLIGHT_DAWN60)
1328 for (int i = 0; i < WS2812_LED_TOTAL; i++) { 1322 for (int i = 0; i < WS2812_LED_COUNT; i++) {
1329 if ((RGB_UNDERGLOW_ALPHA_TOP_START <= i && i <= RGB_UNDERGLOW_ALPHA_TOP_END) || 1323 if ((RGB_UNDERGLOW_ALPHA_TOP_START <= i && i <= RGB_UNDERGLOW_ALPHA_TOP_END) ||
1330 (RGB_UNDERGLOW_ALPHA_BOT_START <= i && i <= RGB_UNDERGLOW_ALPHA_BOT_END)) { 1324 (RGB_UNDERGLOW_ALPHA_BOT_START <= i && i <= RGB_UNDERGLOW_ALPHA_BOT_END)) {
1331 backlight_set_color(i + IS31FL3731_LED_COUNT, rgb1.r, rgb1.g, rgb1.b); 1325 backlight_set_color(i + IS31FL3731_LED_COUNT, rgb1.r, rgb1.g, rgb1.b);
diff --git a/keyboards/work_louder/rgb_functions.c b/keyboards/work_louder/rgb_functions.c
index bc31aab7c1..fb99c0b008 100644
--- a/keyboards/work_louder/rgb_functions.c
+++ b/keyboards/work_louder/rgb_functions.c
@@ -26,13 +26,17 @@
26#define WS2812_DI_PIN RGBLIGHT_DI_PIN 26#define WS2812_DI_PIN RGBLIGHT_DI_PIN
27 27
28#define ws2812_init ws2812_rgb_init 28#define ws2812_init ws2812_rgb_init
29#define ws2812_setleds ws2812_rgb_setleds 29#define ws2812_set_color ws2812_rgb_set_color
30#define ws2812_set_color_all ws2812_rgb_set_color_all
31#define ws2812_flush ws2812_rgb_flush
30 32
31#include "ws2812_bitbang.c" 33#include "ws2812_bitbang.c"
32 34
33const rgblight_driver_t rgblight_driver = { 35const rgblight_driver_t rgblight_driver = {
34 .init = ws2812_init, 36 .init = ws2812_init,
35 .setleds = ws2812_setleds, 37 .set_color = ws2812_set_color,
38 .set_color_all = ws2812_set_color_all,
39 .flush = ws2812_flush,
36}; 40};
37#endif 41#endif
38 42
diff --git a/keyboards/xelus/dawn60/rev1/config.h b/keyboards/xelus/dawn60/rev1/config.h
index e64b0895fa..7ff2294ddd 100644
--- a/keyboards/xelus/dawn60/rev1/config.h
+++ b/keyboards/xelus/dawn60/rev1/config.h
@@ -42,7 +42,7 @@
42#define RGB_BACKLIGHT_DAWN60 42#define RGB_BACKLIGHT_DAWN60
43 43
44//RGB Underglow defines 44//RGB Underglow defines
45#define WS2812_LED_TOTAL 20 45#define WS2812_LED_COUNT 20
46 46
47#define RGB_UNDERGLOW_ALPHA_TOP_START 0 47#define RGB_UNDERGLOW_ALPHA_TOP_START 0
48#define RGB_UNDERGLOW_ALPHA_TOP_END 6 48#define RGB_UNDERGLOW_ALPHA_TOP_END 6
diff --git a/keyboards/xelus/dawn60/rev1_qmk/config.h b/keyboards/xelus/dawn60/rev1_qmk/config.h
index b54fcaee2a..12f0dad8df 100644
--- a/keyboards/xelus/dawn60/rev1_qmk/config.h
+++ b/keyboards/xelus/dawn60/rev1_qmk/config.h
@@ -16,14 +16,14 @@
16#pragma once 16#pragma once
17 17
18//RGB Underglow defines 18//RGB Underglow defines
19#define WS2812_LED_TOTAL 20 19#define WS2812_LED_COUNT 20
20 20
21//RGB Matrix defines 21//RGB Matrix defines
22#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND 22#define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND
23#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_SDA 23#define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_SDA
24#define IS31FL3731_LED_COUNT 64 24#define IS31FL3731_LED_COUNT 64
25 25
26#define RGB_MATRIX_LED_COUNT (IS31FL3731_LED_COUNT + WS2812_LED_TOTAL) 26#define RGB_MATRIX_LED_COUNT (IS31FL3731_LED_COUNT + WS2812_LED_COUNT)
27 27
28// enable/disable LEDs based on layout 28// enable/disable LEDs based on layout
29// switch between split backspace (1) or normal backspace(0) 29// switch between split backspace (1) or normal backspace(0)
diff --git a/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c b/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c
index a153a7cf83..746c68950b 100644
--- a/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c
+++ b/keyboards/xelus/dawn60/rev1_qmk/rev1_qmk.c
@@ -23,8 +23,6 @@
23#include "ws2812.h" 23#include "ws2812.h"
24 24
25#ifdef RGB_MATRIX_ENABLE 25#ifdef RGB_MATRIX_ENABLE
26rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL];
27
28const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { 26const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
29/* Refer to IS31 manual for these locations 27/* Refer to IS31 manual for these locations
30 * driver 28 * driver
@@ -161,26 +159,20 @@ static void init(void) {
161static void flush(void) { 159static void flush(void) {
162 is31fl3731_update_pwm_buffers(0); 160 is31fl3731_update_pwm_buffers(0);
163 is31fl3731_update_pwm_buffers(1); 161 is31fl3731_update_pwm_buffers(1);
164 ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); 162 ws2812_flush();
165} 163}
166 164
167static void set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { 165static void set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
168 if (index < IS31FL3731_LED_COUNT) { 166 if (index < IS31FL3731_LED_COUNT) {
169 is31fl3731_set_color(index, red, green, blue); 167 is31fl3731_set_color(index, red, green, blue);
170 } else { 168 } else {
171 rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].r = red; 169 ws2812_set_color(index - IS31FL3731_LED_COUNT, red, green, blue);
172 rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].g = green;
173 rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].b = blue;
174 } 170 }
175} 171}
176 172
177static void set_color_all(uint8_t red, uint8_t green, uint8_t blue) { 173static void set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
178 is31fl3731_set_color_all( red, green, blue ); 174 is31fl3731_set_color_all( red, green, blue );
179 for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { 175 ws2812_set_color_all( red, green, blue );
180 rgb_matrix_ws2812_array[i].r = red;
181 rgb_matrix_ws2812_array[i].g = green;
182 rgb_matrix_ws2812_array[i].b = blue;
183 }
184} 176}
185 177
186 178
diff --git a/keyboards/xiudi/xd002/keymaps/rgb_lite/config.h b/keyboards/xiudi/xd002/keymaps/rgb_lite/config.h
new file mode 100644
index 0000000000..bb9f2fc153
--- /dev/null
+++ b/keyboards/xiudi/xd002/keymaps/rgb_lite/config.h
@@ -0,0 +1,3 @@
1#pragma once
2
3#define WS2812_LED_COUNT 2
diff --git a/keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h b/keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h
index 0bb0582415..3ee8c44b87 100644
--- a/keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h
+++ b/keyboards/xiudi/xd002/keymaps/rgb_lite/rgblite.h
@@ -7,9 +7,9 @@ static inline void rgblite_init(void) {
7 ws2812_init(); 7 ws2812_init();
8} 8}
9 9
10static inline void rgblite_setrgb(uint8_t _r, uint8_t _g, uint8_t _b) { 10static inline void rgblite_setrgb(uint8_t r, uint8_t g, uint8_t b) {
11 rgb_led_t leds[RGBLIGHT_LED_COUNT] = {{.r = _r, .g = _g, .b = _b}, {.r = _r, .g = _g, .b = _b}}; 11 ws2812_set_color_all(r, g, b);
12 ws2812_setleds(leds, RGBLIGHT_LED_COUNT); 12 ws2812_flush();
13} 13}
14 14
15static void rgblite_increase_hue(void) { 15static void rgblite_increase_hue(void) {
diff --git a/platforms/avr/drivers/ws2812_bitbang.c b/platforms/avr/drivers/ws2812_bitbang.c
index be127e501c..183690c967 100644
--- a/platforms/avr/drivers/ws2812_bitbang.c
+++ b/platforms/avr/drivers/ws2812_bitbang.c
@@ -29,28 +29,6 @@
29#define pinmask(pin) (_BV((pin)&0xF)) 29#define pinmask(pin) (_BV((pin)&0xF))
30 30
31/* 31/*
32 * Forward declare internal functions
33 *
34 * The functions take a byte-array and send to the data output as WS2812 bitstream.
35 * The length is the number of bytes to send - three per LED.
36 */
37
38static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi);
39
40void ws2812_init(void) {
41 DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN);
42}
43
44void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) {
45 uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN);
46 uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN);
47
48 ws2812_sendarray_mask((uint8_t *)ledarray, number_of_leds * sizeof(rgb_led_t), masklo, maskhi);
49
50 _delay_us(WS2812_TRST_US);
51}
52
53/*
54 This routine writes an array of bytes with RGB values to the Dataout pin 32 This routine writes an array of bytes with RGB values to the Dataout pin
55 using the fast 800kHz clockless WS2811/2812 protocol. 33 using the fast 800kHz clockless WS2811/2812 protocol.
56*/ 34*/
@@ -172,3 +150,33 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t
172 150
173 SREG = sreg_prev; 151 SREG = sreg_prev;
174} 152}
153
154ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
155
156void ws2812_init(void) {
157 DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN);
158}
159
160void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
161 ws2812_leds[index].r = red;
162 ws2812_leds[index].g = green;
163 ws2812_leds[index].b = blue;
164#if defined(WS2812_RGBW)
165 ws2812_rgb_to_rgbw(&ws2812_leds[index]);
166#endif
167}
168
169void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
170 for (int i = 0; i < WS2812_LED_COUNT; i++) {
171 ws2812_set_color(i, red, green, blue);
172 }
173}
174
175void ws2812_flush(void) {
176 uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN);
177 uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN);
178
179 ws2812_sendarray_mask((uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), masklo, maskhi);
180
181 _delay_us(WS2812_TRST_US);
182}
diff --git a/platforms/avr/drivers/ws2812_i2c.c b/platforms/avr/drivers/ws2812_i2c.c
index 86a5ac8394..e6b922f4bf 100644
--- a/platforms/avr/drivers/ws2812_i2c.c
+++ b/platforms/avr/drivers/ws2812_i2c.c
@@ -1,3 +1,6 @@
1// Copyright 2024 QMK
2// SPDX-License-Identifier: GPL-2.0-or-later
3
1#include "ws2812.h" 4#include "ws2812.h"
2#include "i2c_master.h" 5#include "i2c_master.h"
3 6
@@ -13,11 +16,24 @@
13# define WS2812_I2C_TIMEOUT 100 16# define WS2812_I2C_TIMEOUT 100
14#endif 17#endif
15 18
19ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
20
16void ws2812_init(void) { 21void ws2812_init(void) {
17 i2c_init(); 22 i2c_init();
18} 23}
19 24
20// Setleds for standard RGB 25void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
21void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) { 26 ws2812_leds[index].r = red;
22 i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ledarray, sizeof(rgb_led_t) * leds, WS2812_I2C_TIMEOUT); 27 ws2812_leds[index].g = green;
28 ws2812_leds[index].b = blue;
29}
30
31void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
32 for (int i = 0; i < WS2812_LED_COUNT; i++) {
33 ws2812_set_color(i, red, green, blue);
34 }
35}
36
37void ws2812_flush(void) {
38 i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), WS2812_I2C_TIMEOUT);
23} 39}
diff --git a/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c b/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
index 41a5311719..6cf035e1f2 100644
--- a/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
+++ b/platforms/chibios/drivers/vendor/RP/RP2040/ws2812_vendor.c
@@ -266,19 +266,36 @@ static inline void sync_ws2812_transfer(void) {
266 busy_wait_until(LAST_TRANSFER); 266 busy_wait_until(LAST_TRANSFER);
267} 267}
268 268
269void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) { 269ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
270
271void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
272 ws2812_leds[index].r = red;
273 ws2812_leds[index].g = green;
274 ws2812_leds[index].b = blue;
275#if defined(WS2812_RGBW)
276 ws2812_rgb_to_rgbw(&ws2812_leds[index]);
277#endif
278}
279
280void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
281 for (int i = 0; i < WS2812_LED_COUNT; i++) {
282 ws2812_set_color(i, red, green, blue);
283 }
284}
285
286void ws2812_flush(void) {
270 sync_ws2812_transfer(); 287 sync_ws2812_transfer();
271 288
272 for (int i = 0; i < leds; i++) { 289 for (int i = 0; i < WS2812_LED_COUNT; i++) {
273#if defined(WS2812_RGBW) 290#if defined(WS2812_RGBW)
274 WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w); 291 WS2812_BUFFER[i] = rgbw8888_to_u32(ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, ws2812_leds[i].w);
275#else 292#else
276 WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, 0); 293 WS2812_BUFFER[i] = rgbw8888_to_u32(ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, 0);
277#endif 294#endif
278 } 295 }
279 296
280 dmaChannelSetSourceX(dma_channel, (uint32_t)WS2812_BUFFER); 297 dmaChannelSetSourceX(dma_channel, (uint32_t)WS2812_BUFFER);
281 dmaChannelSetCounterX(dma_channel, leds); 298 dmaChannelSetCounterX(dma_channel, WS2812_LED_COUNT);
282 dmaChannelSetModeX(dma_channel, RP_DMA_MODE_WS2812); 299 dmaChannelSetModeX(dma_channel, RP_DMA_MODE_WS2812);
283 dmaChannelEnableX(dma_channel); 300 dmaChannelEnableX(dma_channel);
284} 301}
diff --git a/platforms/chibios/drivers/ws2812_bitbang.c b/platforms/chibios/drivers/ws2812_bitbang.c
index 96378ec0ac..fce1963d0a 100644
--- a/platforms/chibios/drivers/ws2812_bitbang.c
+++ b/platforms/chibios/drivers/ws2812_bitbang.c
@@ -76,33 +76,49 @@ void sendByte(uint8_t byte) {
76 } 76 }
77} 77}
78 78
79ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
80
79void ws2812_init(void) { 81void ws2812_init(void) {
80 palSetLineMode(WS2812_DI_PIN, WS2812_OUTPUT_MODE); 82 palSetLineMode(WS2812_DI_PIN, WS2812_OUTPUT_MODE);
81} 83}
82 84
83// Setleds for standard RGB 85void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
84void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) { 86 ws2812_leds[index].r = red;
87 ws2812_leds[index].g = green;
88 ws2812_leds[index].b = blue;
89#if defined(WS2812_RGBW)
90 ws2812_rgb_to_rgbw(&ws2812_leds[index]);
91#endif
92}
93
94void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
95 for (int i = 0; i < WS2812_LED_COUNT; i++) {
96 ws2812_set_color(i, red, green, blue);
97 }
98}
99
100void ws2812_flush(void) {
85 // this code is very time dependent, so we need to disable interrupts 101 // this code is very time dependent, so we need to disable interrupts
86 chSysLock(); 102 chSysLock();
87 103
88 for (uint8_t i = 0; i < leds; i++) { 104 for (int i = 0; i < WS2812_LED_COUNT; i++) {
89 // WS2812 protocol dictates grb order 105 // WS2812 protocol dictates grb order
90#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) 106#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
91 sendByte(ledarray[i].g); 107 sendByte(ws2812_leds[i].g);
92 sendByte(ledarray[i].r); 108 sendByte(ws2812_leds[i].r);
93 sendByte(ledarray[i].b); 109 sendByte(ws2812_leds[i].b);
94#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) 110#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
95 sendByte(ledarray[i].r); 111 sendByte(ws2812_leds[i].r);
96 sendByte(ledarray[i].g); 112 sendByte(ws2812_leds[i].g);
97 sendByte(ledarray[i].b); 113 sendByte(ws2812_leds[i].b);
98#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) 114#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
99 sendByte(ledarray[i].b); 115 sendByte(ws2812_leds[i].b);
100 sendByte(ledarray[i].g); 116 sendByte(ws2812_leds[i].g);
101 sendByte(ledarray[i].r); 117 sendByte(ws2812_leds[i].r);
102#endif 118#endif
103 119
104#ifdef WS2812_RGBW 120#ifdef WS2812_RGBW
105 sendByte(ledarray[i].w); 121 sendByte(ws2812_leds[i].w);
106#endif 122#endif
107 } 123 }
108 124
diff --git a/platforms/chibios/drivers/ws2812_pwm.c b/platforms/chibios/drivers/ws2812_pwm.c
index 1e9d2ebb41..dc0e309163 100644
--- a/platforms/chibios/drivers/ws2812_pwm.c
+++ b/platforms/chibios/drivers/ws2812_pwm.c
@@ -387,13 +387,29 @@ void ws2812_write_led_rgbw(uint16_t led_number, uint8_t r, uint8_t g, uint8_t b,
387 } 387 }
388} 388}
389 389
390// Setleds for standard RGB 390ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
391void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) { 391
392 for (uint16_t i = 0; i < leds; i++) { 392void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
393#ifdef WS2812_RGBW 393 ws2812_leds[index].r = red;
394 ws2812_write_led_rgbw(i, ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w); 394 ws2812_leds[index].g = green;
395 ws2812_leds[index].b = blue;
396#if defined(WS2812_RGBW)
397 ws2812_rgb_to_rgbw(&ws2812_leds[index]);
398#endif
399}
400
401void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
402 for (int i = 0; i < WS2812_LED_COUNT; i++) {
403 ws2812_set_color(i, red, green, blue);
404 }
405}
406
407void ws2812_flush(void) {
408 for (int i = 0; i < WS2812_LED_COUNT; i++) {
409#if defined(WS2812_RGBW)
410 ws2812_write_led_rgbw(i, ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, ws2812_leds[i].w);
395#else 411#else
396 ws2812_write_led(i, ledarray[i].r, ledarray[i].g, ledarray[i].b); 412 ws2812_write_led(i, ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b);
397#endif 413#endif
398 } 414 }
399} 415}
diff --git a/platforms/chibios/drivers/ws2812_spi.c b/platforms/chibios/drivers/ws2812_spi.c
index 9896f9e69d..a1357edec5 100644
--- a/platforms/chibios/drivers/ws2812_spi.c
+++ b/platforms/chibios/drivers/ws2812_spi.c
@@ -106,7 +106,7 @@ static uint8_t get_protocol_eq(uint8_t data, int pos) {
106 return eq; 106 return eq;
107} 107}
108 108
109static void set_led_color_rgb(rgb_led_t color, int pos) { 109static void set_led_color_rgb(ws2812_led_t color, int pos) {
110 uint8_t* tx_start = &txbuf[PREAMBLE_SIZE]; 110 uint8_t* tx_start = &txbuf[PREAMBLE_SIZE];
111 111
112#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) 112#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
@@ -137,6 +137,8 @@ static void set_led_color_rgb(rgb_led_t color, int pos) {
137#endif 137#endif
138} 138}
139 139
140ws2812_led_t ws2812_leds[WS2812_LED_COUNT];
141
140void ws2812_init(void) { 142void ws2812_init(void) {
141 palSetLineMode(WS2812_DI_PIN, WS2812_MOSI_OUTPUT_MODE); 143 palSetLineMode(WS2812_DI_PIN, WS2812_MOSI_OUTPUT_MODE);
142 144
@@ -187,9 +189,24 @@ void ws2812_init(void) {
187#endif 189#endif
188} 190}
189 191
190void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) { 192void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
191 for (uint8_t i = 0; i < leds; i++) { 193 ws2812_leds[index].r = red;
192 set_led_color_rgb(ledarray[i], i); 194 ws2812_leds[index].g = green;
195 ws2812_leds[index].b = blue;
196#if defined(WS2812_RGBW)
197 ws2812_rgb_to_rgbw(&ws2812_leds[index]);
198#endif
199}
200
201void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
202 for (int i = 0; i < WS2812_LED_COUNT; i++) {
203 ws2812_set_color(i, red, green, blue);
204 }
205}
206
207void ws2812_flush(void) {
208 for (int i = 0; i < WS2812_LED_COUNT; i++) {
209 set_led_color_rgb(ws2812_leds[i], i);
193 } 210 }
194 211
195 // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues. 212 // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues.
diff --git a/quantum/color.c b/quantum/color.c
index 96d548a33c..5f264cb76f 100644
--- a/quantum/color.c
+++ b/quantum/color.c
@@ -108,14 +108,3 @@ RGB hsv_to_rgb(HSV hsv) {
108RGB hsv_to_rgb_nocie(HSV hsv) { 108RGB hsv_to_rgb_nocie(HSV hsv) {
109 return hsv_to_rgb_impl(hsv, false); 109 return hsv_to_rgb_impl(hsv, false);
110} 110}
111
112#ifdef WS2812_RGBW
113void convert_rgb_to_rgbw(rgb_led_t *led) {
114 // Determine lowest value in all three colors, put that into
115 // the white channel and then shift all colors by that amount
116 led->w = MIN(led->r, MIN(led->g, led->b));
117 led->r -= led->w;
118 led->g -= led->w;
119 led->b -= led->w;
120}
121#endif
diff --git a/quantum/color.h b/quantum/color.h
index b6a9dd0641..81a2c1e7ba 100644
--- a/quantum/color.h
+++ b/quantum/color.h
@@ -74,31 +74,10 @@
74 74
75// clang-format on 75// clang-format on
76 76
77#define WS2812_BYTE_ORDER_RGB 0
78#define WS2812_BYTE_ORDER_GRB 1
79#define WS2812_BYTE_ORDER_BGR 2
80
81#ifndef WS2812_BYTE_ORDER
82# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB
83#endif
84
85typedef struct PACKED rgb_led_t { 77typedef struct PACKED rgb_led_t {
86#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB)
87 uint8_t g;
88 uint8_t r;
89 uint8_t b;
90#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB)
91 uint8_t r; 78 uint8_t r;
92 uint8_t g; 79 uint8_t g;
93 uint8_t b; 80 uint8_t b;
94#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR)
95 uint8_t b;
96 uint8_t g;
97 uint8_t r;
98#endif
99#ifdef WS2812_RGBW
100 uint8_t w;
101#endif
102} rgb_led_t; 81} rgb_led_t;
103 82
104typedef rgb_led_t RGB; 83typedef rgb_led_t RGB;
@@ -111,6 +90,3 @@ typedef struct PACKED HSV {
111 90
112RGB hsv_to_rgb(HSV hsv); 91RGB hsv_to_rgb(HSV hsv);
113RGB hsv_to_rgb_nocie(HSV hsv); 92RGB hsv_to_rgb_nocie(HSV hsv);
114#ifdef WS2812_RGBW
115void convert_rgb_to_rgbw(rgb_led_t *led);
116#endif
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c
index a5f0296f8d..58263c62e3 100644
--- a/quantum/led_matrix/led_matrix.c
+++ b/quantum/led_matrix/led_matrix.c
@@ -139,11 +139,20 @@ void led_matrix_update_pwm_buffers(void) {
139 led_matrix_driver.flush(); 139 led_matrix_driver.flush();
140} 140}
141 141
142__attribute__((weak)) int led_matrix_led_index(int index) {
143#if defined(LED_MATRIX_SPLIT)
144 if (!is_keyboard_left() && index >= k_led_matrix_split[0]) {
145 return index - k_led_matrix_split[0];
146 }
147#endif
148 return index;
149}
150
142void led_matrix_set_value(int index, uint8_t value) { 151void led_matrix_set_value(int index, uint8_t value) {
143#ifdef USE_CIE1931_CURVE 152#ifdef USE_CIE1931_CURVE
144 value = pgm_read_byte(&CIE1931_CURVE[value]); 153 value = pgm_read_byte(&CIE1931_CURVE[value]);
145#endif 154#endif
146 led_matrix_driver.set_value(index, value); 155 led_matrix_driver.set_value(led_matrix_led_index(index), value);
147} 156}
148 157
149void led_matrix_set_value_all(uint8_t value) { 158void led_matrix_set_value_all(uint8_t value) {
diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h
index 9a13c3e52b..a3468a2003 100644
--- a/quantum/led_matrix/led_matrix.h
+++ b/quantum/led_matrix/led_matrix.h
@@ -121,6 +121,8 @@ void eeconfig_debug_led_matrix(void);
121uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); 121uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
122uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); 122uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
123 123
124int led_matrix_led_index(int index);
125
124void led_matrix_set_value(int index, uint8_t value); 126void led_matrix_set_value(int index, uint8_t value);
125void led_matrix_set_value_all(uint8_t value); 127void led_matrix_set_value_all(uint8_t value);
126 128
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c
index 0ea421d1c5..47bba278e4 100644
--- a/quantum/rgb_matrix/rgb_matrix.c
+++ b/quantum/rgb_matrix/rgb_matrix.c
@@ -143,8 +143,17 @@ void rgb_matrix_update_pwm_buffers(void) {
143 rgb_matrix_driver.flush(); 143 rgb_matrix_driver.flush();
144} 144}
145 145
146__attribute__((weak)) int rgb_matrix_led_index(int index) {
147#if defined(RGB_MATRIX_SPLIT)
148 if (!is_keyboard_left() && index >= k_rgb_matrix_split[0]) {
149 return index - k_rgb_matrix_split[0];
150 }
151#endif
152 return index;
153}
154
146void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { 155void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
147 rgb_matrix_driver.set_color(index, red, green, blue); 156 rgb_matrix_driver.set_color(rgb_matrix_led_index(index), red, green, blue);
148} 157}
149 158
150void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { 159void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h
index ceb3185d1a..a1115a721e 100644
--- a/quantum/rgb_matrix/rgb_matrix.h
+++ b/quantum/rgb_matrix/rgb_matrix.h
@@ -145,6 +145,8 @@ void eeconfig_update_rgb_matrix(void);
145uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); 145uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i);
146uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); 146uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i);
147 147
148int rgb_matrix_led_index(int index);
149
148void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); 150void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
149void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue); 151void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
150 152
diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c
index bf5209a9d3..3b45e82cb9 100644
--- a/quantum/rgb_matrix/rgb_matrix_drivers.c
+++ b/quantum/rgb_matrix/rgb_matrix_drivers.c
@@ -146,61 +146,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
146# pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration." 146# pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration."
147# endif 147# endif
148 148
149// LED color buffer
150rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_COUNT];
151bool ws2812_dirty = false;
152
153static void init(void) {
154 ws2812_init();
155 ws2812_dirty = false;
156}
157
158static void flush(void) {
159 if (ws2812_dirty) {
160 ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_COUNT);
161 ws2812_dirty = false;
162 }
163}
164
165// Set an led in the buffer to a color
166static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) {
167# if defined(RGB_MATRIX_SPLIT)
168 const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT;
169 if (!is_keyboard_left()) {
170 if (i >= k_rgb_matrix_split[0]) {
171 i -= k_rgb_matrix_split[0];
172 } else {
173 return;
174 }
175 } else if (i >= k_rgb_matrix_split[0]) {
176 return;
177 }
178# endif
179
180 if (rgb_matrix_ws2812_array[i].r == r && rgb_matrix_ws2812_array[i].g == g && rgb_matrix_ws2812_array[i].b == b) {
181 return;
182 }
183
184 ws2812_dirty = true;
185 rgb_matrix_ws2812_array[i].r = r;
186 rgb_matrix_ws2812_array[i].g = g;
187 rgb_matrix_ws2812_array[i].b = b;
188# ifdef WS2812_RGBW
189 convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]);
190# endif
191}
192
193static void setled_all(uint8_t r, uint8_t g, uint8_t b) {
194 for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) {
195 setled(i, r, g, b);
196 }
197}
198
199const rgb_matrix_driver_t rgb_matrix_driver = { 149const rgb_matrix_driver_t rgb_matrix_driver = {
200 .init = init, 150 .init = ws2812_init,
201 .flush = flush, 151 .flush = ws2812_flush,
202 .set_color = setled, 152 .set_color = ws2812_set_color,
203 .set_color_all = setled_all, 153 .set_color_all = ws2812_set_color_all,
204}; 154};
205 155
206#endif 156#endif
diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c
index b0f2dfdc1d..e16fb99c3b 100644
--- a/quantum/rgblight/rgblight.c
+++ b/quantum/rgblight/rgblight.c
@@ -115,11 +115,6 @@ static bool pre_suspend_enabled;
115animation_status_t animation_status = {}; 115animation_status_t animation_status = {};
116#endif 116#endif
117 117
118#ifndef LED_ARRAY
119rgb_led_t led[RGBLIGHT_LED_COUNT];
120# define LED_ARRAY led
121#endif
122
123#ifdef RGBLIGHT_LAYERS 118#ifdef RGBLIGHT_LAYERS
124rgblight_segment_t const *const *rgblight_layers = NULL; 119rgblight_segment_t const *const *rgblight_layers = NULL;
125 120
@@ -145,23 +140,26 @@ __attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) {
145 return hsv_to_rgb(hsv); 140 return hsv_to_rgb(hsv);
146} 141}
147 142
148void setrgb(uint8_t r, uint8_t g, uint8_t b, rgb_led_t *led1) { 143uint8_t rgblight_led_index(uint8_t index) {
149 led1->r = r; 144#if defined(RGBLIGHT_LED_MAP)
150 led1->g = g; 145 return pgm_read_byte(&led_map[index]) - rgblight_ranges.clipping_start_pos;
151 led1->b = b; 146#else
152#ifdef WS2812_RGBW 147 return index - rgblight_ranges.clipping_start_pos;
153 led1->w = 0;
154#endif 148#endif
155} 149}
156 150
157void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) { 151void setrgb(uint8_t r, uint8_t g, uint8_t b, int index) {
152 rgblight_driver.set_color(rgblight_led_index(index), r, g, b);
153}
154
155void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, int index) {
158 HSV hsv = {hue, sat, val}; 156 HSV hsv = {hue, sat, val};
159 RGB rgb = rgblight_hsv_to_rgb(hsv); 157 RGB rgb = rgblight_hsv_to_rgb(hsv);
160 setrgb(rgb.r, rgb.g, rgb.b, led1); 158 setrgb(rgb.r, rgb.g, rgb.b, index);
161} 159}
162 160
163void sethsv(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) { 161void sethsv(uint8_t hue, uint8_t sat, uint8_t val, int index) {
164 sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, led1); 162 sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, index);
165} 163}
166 164
167void rgblight_check_config(void) { 165void rgblight_check_config(void) {
@@ -515,9 +513,8 @@ void rgblight_decrease_speed_noeeprom(void) {
515 513
516void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) { 514void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
517 if (rgblight_config.enable) { 515 if (rgblight_config.enable) {
518 rgb_led_t tmp_led; 516 RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
519 sethsv(hue, sat, val, &tmp_led); 517 rgblight_setrgb(rgb.r, rgb.g, rgb.b);
520 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
521 } 518 }
522} 519}
523 520
@@ -531,13 +528,12 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
531 rgblight_status.base_mode = mode_base_table[rgblight_config.mode]; 528 rgblight_status.base_mode = mode_base_table[rgblight_config.mode];
532 if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) { 529 if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
533 // same static color 530 // same static color
534 rgb_led_t tmp_led;
535#ifdef RGBLIGHT_LAYERS_RETAIN_VAL 531#ifdef RGBLIGHT_LAYERS_RETAIN_VAL
536 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val 532 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
537 rgblight_config.val = val; 533 rgblight_config.val = val;
538#endif 534#endif
539 sethsv(hue, sat, val, &tmp_led); 535 RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
540 rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); 536 rgblight_setrgb(rgb.r, rgb.g, rgb.b);
541 } else { 537 } else {
542 // all LEDs in same color 538 // all LEDs in same color
543 if (1 == 0) { // dummy 539 if (1 == 0) { // dummy
@@ -575,7 +571,7 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
575 _hue = hue - _hue; 571 _hue = hue - _hue;
576 } 572 }
577 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range); 573 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
578 sethsv(_hue, sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]); 574 sethsv(_hue, sat, val, i + rgblight_ranges.effect_start_pos);
579 } 575 }
580# ifdef RGBLIGHT_LAYERS_RETAIN_VAL 576# ifdef RGBLIGHT_LAYERS_RETAIN_VAL
581 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val 577 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
@@ -649,12 +645,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
649 } 645 }
650 646
651 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { 647 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
652 led[i].r = r; 648 rgblight_driver.set_color(rgblight_led_index(i), r, g, b);
653 led[i].g = g;
654 led[i].b = b;
655#ifdef WS2812_RGBW
656 led[i].w = 0;
657#endif
658 } 649 }
659 rgblight_set(); 650 rgblight_set();
660} 651}
@@ -664,12 +655,7 @@ void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
664 return; 655 return;
665 } 656 }
666 657
667 led[index].r = r; 658 rgblight_driver.set_color(rgblight_led_index(index), r, g, b);
668 led[index].g = g;
669 led[index].b = b;
670#ifdef WS2812_RGBW
671 led[index].w = 0;
672#endif
673 rgblight_set(); 659 rgblight_set();
674} 660}
675 661
@@ -678,9 +664,8 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
678 return; 664 return;
679 } 665 }
680 666
681 rgb_led_t tmp_led; 667 RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
682 sethsv(hue, sat, val, &tmp_led); 668 rgblight_setrgb_at(rgb.r, rgb.g, rgb.b, index);
683 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
684} 669}
685 670
686#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) 671#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE)
@@ -701,12 +686,7 @@ void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8
701 } 686 }
702 687
703 for (uint8_t i = start; i < end; i++) { 688 for (uint8_t i = start; i < end; i++) {
704 led[i].r = r; 689 rgblight_driver.set_color(rgblight_led_index(i), r, g, b);
705 led[i].g = g;
706 led[i].b = b;
707#ifdef WS2812_RGBW
708 led[i].w = 0;
709#endif
710 } 690 }
711 rgblight_set(); 691 rgblight_set();
712} 692}
@@ -716,9 +696,8 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start,
716 return; 696 return;
717 } 697 }
718 698
719 rgb_led_t tmp_led; 699 RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val});
720 sethsv(hue, sat, val, &tmp_led); 700 rgblight_setrgb_range(rgb.r, rgb.g, rgb.b, start, end);
721 rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
722} 701}
723 702
724#ifndef RGBLIGHT_SPLIT 703#ifndef RGBLIGHT_SPLIT
@@ -785,12 +764,12 @@ static void rgblight_layers_write(void) {
785 break; // No more segments 764 break; // No more segments
786 } 765 }
787 // Write segment.count LEDs 766 // Write segment.count LEDs
788 rgb_led_t *const limit = &led[MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT)]; 767 int limit = MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT);
789 for (rgb_led_t *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) { 768 for (int i = segment.index; i < limit; i++) {
790# ifdef RGBLIGHT_LAYERS_RETAIN_VAL 769# ifdef RGBLIGHT_LAYERS_RETAIN_VAL
791 sethsv(segment.hue, segment.sat, current_val, led_ptr); 770 sethsv(segment.hue, segment.sat, current_val, i);
792# else 771# else
793 sethsv(segment.hue, segment.sat, segment.val, led_ptr); 772 sethsv(segment.hue, segment.sat, segment.val, i);
794# endif 773# endif
795 } 774 }
796 segment_ptr++; 775 segment_ptr++;
@@ -897,17 +876,9 @@ void rgblight_wakeup(void) {
897#endif 876#endif
898 877
899void rgblight_set(void) { 878void rgblight_set(void) {
900 rgb_led_t *start_led;
901 uint8_t num_leds = rgblight_ranges.clipping_num_leds;
902
903 if (!rgblight_config.enable) { 879 if (!rgblight_config.enable) {
904 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { 880 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
905 led[i].r = 0; 881 rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0);
906 led[i].g = 0;
907 led[i].b = 0;
908#ifdef WS2812_RGBW
909 led[i].w = 0;
910#endif
911 } 882 }
912 } 883 }
913 884
@@ -923,22 +894,7 @@ void rgblight_set(void) {
923 } 894 }
924#endif 895#endif
925 896
926#ifdef RGBLIGHT_LED_MAP 897 rgblight_driver.flush();
927 rgb_led_t led0[RGBLIGHT_LED_COUNT];
928 for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) {
929 led0[i] = led[pgm_read_byte(&led_map[i])];
930 }
931 start_led = led0 + rgblight_ranges.clipping_start_pos;
932#else
933 start_led = led + rgblight_ranges.clipping_start_pos;
934#endif
935
936#ifdef WS2812_RGBW
937 for (uint8_t i = 0; i < num_leds; i++) {
938 convert_rgb_to_rgbw(&start_led[i]);
939 }
940#endif
941 rgblight_driver.setleds(start_led, num_leds);
942} 898}
943 899
944#ifdef RGBLIGHT_SPLIT 900#ifdef RGBLIGHT_SPLIT
@@ -1222,7 +1178,7 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
1222 1178
1223 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { 1179 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1224 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue); 1180 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue);
1225 sethsv(hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]); 1181 sethsv(hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
1226 } 1182 }
1227 rgblight_set(); 1183 rgblight_set();
1228 1184
@@ -1259,13 +1215,8 @@ void rgblight_effect_snake(animation_status_t *anim) {
1259# endif 1215# endif
1260 1216
1261 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { 1217 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1262 rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos; 1218 rgblight_driver.set_color(rgblight_led_index(i + rgblight_ranges.effect_start_pos), 0, 0, 0);
1263 ledp->r = 0; 1219
1264 ledp->g = 0;
1265 ledp->b = 0;
1266# ifdef WS2812_RGBW
1267 ledp->w = 0;
1268# endif
1269 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { 1220 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
1270 k = pos + j * increment; 1221 k = pos + j * increment;
1271 if (k > RGBLIGHT_LED_COUNT) { 1222 if (k > RGBLIGHT_LED_COUNT) {
@@ -1275,7 +1226,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
1275 k = k + rgblight_ranges.effect_num_leds; 1226 k = k + rgblight_ranges.effect_num_leds;
1276 } 1227 }
1277 if (i == k) { 1228 if (i == k) {
1278 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp); 1229 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), i + rgblight_ranges.effect_start_pos);
1279 } 1230 }
1280 } 1231 }
1281 } 1232 }
@@ -1320,26 +1271,16 @@ void rgblight_effect_knight(animation_status_t *anim) {
1320# endif 1271# endif
1321 // Set all the LEDs to 0 1272 // Set all the LEDs to 0
1322 for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { 1273 for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
1323 led[i].r = 0; 1274 rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0);
1324 led[i].g = 0;
1325 led[i].b = 0;
1326# ifdef WS2812_RGBW
1327 led[i].w = 0;
1328# endif
1329 } 1275 }
1330 // Determine which LEDs should be lit up 1276 // Determine which LEDs should be lit up
1331 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { 1277 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
1332 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos; 1278 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos;
1333 1279
1334 if (i >= low_bound && i <= high_bound) { 1280 if (i >= low_bound && i <= high_bound) {
1335 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[cur]); 1281 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, cur);
1336 } else { 1282 } else {
1337 led[cur].r = 0; 1283 rgblight_driver.set_color(rgblight_led_index(cur), 0, 0, 0);
1338 led[cur].g = 0;
1339 led[cur].b = 0;
1340# ifdef WS2812_RGBW
1341 led[cur].w = 0;
1342# endif
1343 } 1284 }
1344 } 1285 }
1345 rgblight_set(); 1286 rgblight_set();
@@ -1384,7 +1325,7 @@ void rgblight_effect_christmas(animation_status_t *anim) {
1384 1325
1385 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { 1326 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1386 uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue; 1327 uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue;
1387 sethsv(local_hue, rgblight_config.sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]); 1328 sethsv(local_hue, rgblight_config.sat, val, i + rgblight_ranges.effect_start_pos);
1388 } 1329 }
1389 rgblight_set(); 1330 rgblight_set();
1390 1331
@@ -1407,9 +1348,8 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
1407 uint8_t b; 1348 uint8_t b;
1408 1349
1409 if (maxval == 0) { 1350 if (maxval == 0) {
1410 rgb_led_t tmp_led; 1351 RGB rgb = hsv_to_rgb((HSV){0, 255, RGBLIGHT_LIMIT_VAL});
1411 sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led); 1352 maxval = rgb.r;
1412 maxval = tmp_led.r;
1413 } 1353 }
1414 g = r = b = 0; 1354 g = r = b = 0;
1415 switch (anim->pos) { 1355 switch (anim->pos) {
@@ -1431,13 +1371,12 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
1431#ifdef RGBLIGHT_EFFECT_ALTERNATING 1371#ifdef RGBLIGHT_EFFECT_ALTERNATING
1432void rgblight_effect_alternating(animation_status_t *anim) { 1372void rgblight_effect_alternating(animation_status_t *anim) {
1433 for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) { 1373 for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1434 rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos;
1435 if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) { 1374 if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) {
1436 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); 1375 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
1437 } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) { 1376 } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) {
1438 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); 1377 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos);
1439 } else { 1378 } else {
1440 sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp); 1379 sethsv(rgblight_config.hue, rgblight_config.sat, 0, i + rgblight_ranges.effect_start_pos);
1441 } 1380 }
1442 } 1381 }
1443 rgblight_set(); 1382 rgblight_set();
@@ -1504,8 +1443,7 @@ void rgblight_effect_twinkle(animation_status_t *anim) {
1504 // This LED is off, and was NOT selected to start brightening 1443 // This LED is off, and was NOT selected to start brightening
1505 } 1444 }
1506 1445
1507 rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos; 1446 sethsv(c->h, c->s, c->v, i + rgblight_ranges.effect_start_pos);
1508 sethsv(c->h, c->s, c->v, ledp);
1509 } 1447 }
1510 1448
1511 rgblight_set(); 1449 rgblight_set();
diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h
index 0ed67ff6e3..7c23805129 100644
--- a/quantum/rgblight/rgblight.h
+++ b/quantum/rgblight/rgblight.h
@@ -169,7 +169,6 @@ enum RGBLIGHT_EFFECT_MODE {
169#include "rgblight_drivers.h" 169#include "rgblight_drivers.h"
170#include "progmem.h" 170#include "progmem.h"
171#include "eeconfig.h" 171#include "eeconfig.h"
172#include "ws2812.h"
173#include "color.h" 172#include "color.h"
174 173
175#ifdef RGBLIGHT_LAYERS 174#ifdef RGBLIGHT_LAYERS
diff --git a/quantum/rgblight/rgblight_drivers.c b/quantum/rgblight/rgblight_drivers.c
index 76e9031aec..ef986ee13c 100644
--- a/quantum/rgblight/rgblight_drivers.c
+++ b/quantum/rgblight/rgblight_drivers.c
@@ -7,24 +7,20 @@
7# include "ws2812.h" 7# include "ws2812.h"
8 8
9const rgblight_driver_t rgblight_driver = { 9const rgblight_driver_t rgblight_driver = {
10 .init = ws2812_init, 10 .init = ws2812_init,
11 .setleds = ws2812_setleds, 11 .set_color = ws2812_set_color,
12 .set_color_all = ws2812_set_color_all,
13 .flush = ws2812_flush,
12}; 14};
13 15
14#elif defined(RGBLIGHT_APA102) 16#elif defined(RGBLIGHT_APA102)
15# include "apa102.h" 17# include "apa102.h"
16 18
17// Temporary shim
18static void apa102_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) {
19 for (uint16_t i = 0; i < number_of_leds; i++) {
20 apa102_set_color(i, ledarray[i].r, ledarray[i].g, ledarray[i].b);
21 }
22 apa102_flush();
23}
24
25const rgblight_driver_t rgblight_driver = { 19const rgblight_driver_t rgblight_driver = {
26 .init = apa102_init, 20 .init = apa102_init,
27 .setleds = apa102_setleds, 21 .set_color = apa102_set_color,
22 .set_color_all = apa102_set_color_all,
23 .flush = apa102_flush,
28}; 24};
29 25
30#endif 26#endif
diff --git a/quantum/rgblight/rgblight_drivers.h b/quantum/rgblight/rgblight_drivers.h
index af28b918e1..16fb4cebd6 100644
--- a/quantum/rgblight/rgblight_drivers.h
+++ b/quantum/rgblight/rgblight_drivers.h
@@ -4,11 +4,12 @@
4#pragma once 4#pragma once
5 5
6#include <stdint.h> 6#include <stdint.h>
7#include "color.h"
8 7
9typedef struct { 8typedef struct {
10 void (*init)(void); 9 void (*init)(void);
11 void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds); 10 void (*set_color)(int index, uint8_t red, uint8_t green, uint8_t blue);
11 void (*set_color_all)(uint8_t red, uint8_t green, uint8_t blue);
12 void (*flush)(void);
12} rgblight_driver_t; 13} rgblight_driver_t;
13 14
14extern const rgblight_driver_t rgblight_driver; 15extern const rgblight_driver_t rgblight_driver;