summaryrefslogtreecommitdiff
path: root/quantum
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 /quantum
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>
Diffstat (limited to 'quantum')
-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
11 files changed, 84 insertions, 213 deletions
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;