aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/feature_rgblight.md134
-rw-r--r--quantum/rgblight.c117
-rw-r--r--quantum/rgblight.h123
3 files changed, 234 insertions, 140 deletions
diff --git a/docs/feature_rgblight.md b/docs/feature_rgblight.md
index 1e0ce9147..be4ddfa72 100644
--- a/docs/feature_rgblight.md
+++ b/docs/feature_rgblight.md
@@ -129,7 +129,7 @@ The following options are used to tweak the various animations:
129|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM` |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel | 129|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM` |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel |
130|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation | 130|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation |
131|`RGBLIGHT_EFFECT_KNIGHT_OFFSET` |`0` |The number of LEDs to start the "Knight" animation from the start of the strip by | 131|`RGBLIGHT_EFFECT_KNIGHT_OFFSET` |`0` |The number of LEDs to start the "Knight" animation from the start of the strip by |
132|`RGBLIGHT_RAINBOW_SWIRL_RANGE` |`360` |Range adjustment for the rainbow swirl effect to get different swirls | 132|`RGBLIGHT_RAINBOW_SWIRL_RANGE` |`255` |Range adjustment for the rainbow swirl effect to get different swirls |
133|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation | 133|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation |
134 134
135### Example Usage to Reduce Memory Footprint 135### Example Usage to Reduce Memory Footprint
@@ -176,44 +176,100 @@ const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
176 176
177If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight.h) for the full list, but the most commonly used functions include: 177If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight.h) for the full list, but the most commonly used functions include:
178 178
179|Function |Description | 179### Utility Functions
180|--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------| 180|Function |Description |
181|`rgblight_enable()` |Turn LEDs on, based on their previous state | 181|--------------------------------------------|-------------------------------------------------------------------|
182|`rgblight_enable_noeeprom()` |Turn LEDs on, based on their previous state (not written to EEPROM) | 182|`sethsv(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value |
183|`rgblight_disable()` |Turn LEDs off | 183|`sethsv_raw(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value without RGBLIGHT_LIMIT_VAL check |
184|`rgblight_disable_noeeprom()` |Turn LEDs off (not written to EEPROM) | 184|`setrgb(r, g, b, ledbuf)` |Set ledbuf to the given RGB value where `r`/`g`/`b` |
185|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled | 185
186|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) | 186### Low level Functions
187|`rgblight_setrgb(r, g, b)` |Set all LEDs to the given RGB value where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | 187|Function |Description |
188|`rgblight_setrgb_at(r, g, b, led)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `led` is between 0 and `RGBLED_NUM` (not written to EEPROM) | 188|--------------------------------------------|-------------------------------------------|
189|`rgblight_set()` |Flash out led buffers to LEDs |
190|`rgblight_set_clipping_range(pos, num)` |Set clipping Range. see [Clipping Range](#clipping-range) |
191
192Example:
193```c
194sethsv(HSV_WHITE, (LED_TYPE *)&led[0]); // led 0
195sethsv(HSV_RED, (LED_TYPE *)&led[1]); // led 1
196sethsv(HSV_GREEN, (LED_TYPE *)&led[2]); // led 2
197rgblight_set(); // Utility functions do not call rgblight_set() automatically, so they need to be called explicitly.
198```
199
200### Effects and Animations Functions
201#### effect range setting
202|Function |Description |
203|--------------------------------------------|------------------|
204|`rgblight_set_effect_range(pos, num)` |Set Effects Range |
205
206#### direct operation
207|Function |Description |
208|--------------------------------------------|-------------|
209|`rgblight_setrgb_at(r, g, b, index)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `index` is between 0 and `RGBLED_NUM` (not written to EEPROM) |
210|`rgblight_sethsv_at(h, s, v, index)` |Set a single LED to the given HSV value, where `h`/`s`/`v` are between 0 and 255, and `index` is between 0 and `RGBLED_NUM` (not written to EEPROM) |
189|`rgblight_setrgb_range(r, g, b, start, end)`|Set a continuous range of LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)| 211|`rgblight_setrgb_range(r, g, b, start, end)`|Set a continuous range of LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)|
190|`rgblight_setrgb_master(r, g, b)` |Set the LEDs on the master side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | 212|`rgblight_sethsv_range(h, s, v, start, end)`|Set a continuous range of LEDs to the given HSV value, where `h`/`s`/`v` are between 0 and 255, and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)|
191|`rgblight_setrgb_slave(r, g, b)` |Set the LEDs on the slave side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | 213|`rgblight_setrgb(r, g, b)` |Set effect range LEDs to the given RGB value where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) |
192|`rgblight_sethsv(h, s, v)` |Set all LEDs to the given HSV value where `h` is between 0 and 360 and `s`/`v` are between 0 and 255 | 214|`rgblight_setrgb_master(r, g, b)` |Set the LEDs on the master side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) |
193|`rgblight_sethsv_noeeprom(h, s, v)` |Set all LEDs to the given HSV value where `h` is between 0 and 360 and `s`/`v` are between 0 and 255 (not written to EEPROM) | 215|`rgblight_setrgb_slave(r, g, b)` |Set the LEDs on the slave side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) |
194|`rgblight_sethsv_at(h, s, v, led)` |Set a single LED to the given HSV value, where `h` is between 0 and 360, `s`/`v` are between 0 and 255, and `led` is between 0 and `RGBLED_NUM` (not written to EEPROM)| 216|`rgblight_sethsv_master(h, s, v)` |Set the LEDs on the master side to the given HSV value, where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
195|`rgblight_sethsv_range(h, s, v, start, end)`|Set a continuous range of LEDs to the given HSV value, where `h` is between 0 and 360, `s`/`v` are between 0 and 255, and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)| 217|`rgblight_sethsv_slave(h, s, v)` |Set the LEDs on the slave side to the given HSV value, where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
196|`rgblight_sethsv_master(h, s, v)` |Set the LEDs on the master side to the given HSV value, where `h` is between 0 and 360, `s`/`v` are between 0 and 255 (not written to EEPROM) | 218
197|`rgblight_sethsv_slave(h, s, v)` |Set the LEDs on the slave side to the given HSV value, where `h` is between 0 and 360, `s`/`v` are between 0 and 255 (not written to EEPROM) | 219Example:
198|`rgblight_toggle()` |Toggle all LEDs between on and off | 220```c
199|`rgblight_toggle_noeeprom()` |Toggle all LEDs between on and off (not written to EEPROM) | 221rgblight_sethsv(HSV_WHITE, 0); // led 0
200|`rgblight_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations | 222rgblight_sethsv(HSV_RED, 1); // led 1
201|`rgblight_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) | 223rgblight_sethsv(HSV_GREEN, 2); // led 2
202|`rgblight_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations | 224// The above functions automatically calls rgblight_set(), so there is no need to call it explicitly.
203|`rgblight_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) | 225// Note that it is inefficient to call repeatedly.
204|`rgblight_increase_hue()` |Increase the hue for all LEDs. This wraps around at maximum hue | 226```
205|`rgblight_increase_hue_noeeprom()` |Increase the hue for all LEDs. This wraps around at maximum hue (not written to EEPROM) | 227
206|`rgblight_decrease_hue()` |Decrease the hue for all LEDs. This wraps around at minimum hue | 228#### effect mode change
207|`rgblight_decrease_hue_noeeprom()` |Decrease the hue for all LEDs. This wraps around at minimum hue (not written to EEPROM) | 229|Function |Description |
208|`rgblight_increase_sat()` |Increase the saturation for all LEDs. This wraps around at maximum saturation | 230|--------------------------------------------|-------------|
209|`rgblight_increase_sat_noeeprom()` |Increase the saturation for all LEDs. This wraps around at maximum saturation (not written to EEPROM) | 231|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled |
210|`rgblight_decrease_sat()` |Decrease the saturation for all LEDs. This wraps around at minimum saturation | 232|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) |
211|`rgblight_decrease_sat_noeeprom()` |Decrease the saturation for all LEDs. This wraps around at minimum saturation (not written to EEPROM) | 233|`rgblight_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations |
212|`rgblight_increase_val()` |Increase the value for all LEDs. This wraps around at maximum value | 234|`rgblight_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) |
213|`rgblight_increase_val_noeeprom()` |Increase the value for all LEDs. This wraps around at maximum value (not written to EEPROM) | 235|`rgblight_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations |
214|`rgblight_decrease_val()` |Decrease the value for all LEDs. This wraps around at minimum value | 236|`rgblight_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) |
215|`rgblight_decrease_val_noeeprom()` |Decrease the value for all LEDs. This wraps around at minimum value (not written to EEPROM) | 237
216|`rgblight_set_clipping_range(pos, num)` |Set clipping Range | 238#### effects mode disable/enable
239|Function |Description |
240|--------------------------------------------|-------------|
241|`rgblight_toggle()` |Toggle effect range LEDs between on and off |
242|`rgblight_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) |
243|`rgblight_enable()` |Turn effect range LEDs on, based on their previous state |
244|`rgblight_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) |
245|`rgblight_disable()` |Turn effect range LEDs off |
246|`rgblight_disable_noeeprom()` |Turn effect range LEDs off (not written to EEPROM) |
247
248#### hue, sat, val change
249|Function |Description |
250|--------------------------------------------|-------------|
251|`rgblight_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue |
252|`rgblight_increase_hue_noeeprom()` |Increase the hue for effect range LEDs. This wraps around at maximum hue (not written to EEPROM) |
253|`rgblight_decrease_hue()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue |
254|`rgblight_decrease_hue_noeeprom()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue (not written to EEPROM) |
255|`rgblight_increase_sat()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation |
256|`rgblight_increase_sat_noeeprom()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation (not written to EEPROM) |
257|`rgblight_decrease_sat()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation |
258|`rgblight_decrease_sat_noeeprom()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation (not written to EEPROM) |
259|`rgblight_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value |
260|`rgblight_increase_val_noeeprom()` |Increase the value for effect range LEDs. This wraps around at maximum value (not written to EEPROM) |
261|`rgblight_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value |
262|`rgblight_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) |
263|`rgblight_sethsv(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 |
264|`rgblight_sethsv_noeeprom(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) |
265
266#### query
267|Function |Description |
268|-----------------------|-----------------|
269|`rgblight_get_mode()` |Get current mode |
270|`rgblight_get_hue()` |Get current hue |
271|`rgblight_get_sat()` |Get current sat |
272|`rgblight_get_val()` |Get current val |
217 273
218## Colors 274## Colors
219 275
@@ -324,4 +380,6 @@ In addition to setting the Clipping Range, you can use `RGBLIGHT_LED_MAP` togeth
324``` 380```
325<img src="https://user-images.githubusercontent.com/2170248/55743747-119e4c00-5a6e-11e9-91e5-013203ffae8a.JPG" alt="clip mapped" width="70%"/> 381<img src="https://user-images.githubusercontent.com/2170248/55743747-119e4c00-5a6e-11e9-91e5-013203ffae8a.JPG" alt="clip mapped" width="70%"/>
326 382
383## Hardware Modification
384
327If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins. 385If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins.
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 77772e292..75e4ef0d8 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -101,19 +101,35 @@ LED_TYPE led[RGBLED_NUM];
101 101
102static uint8_t clipping_start_pos = 0; 102static uint8_t clipping_start_pos = 0;
103static uint8_t clipping_num_leds = RGBLED_NUM; 103static uint8_t clipping_num_leds = RGBLED_NUM;
104static uint8_t effect_start_pos = 0;
105static uint8_t effect_end_pos = RGBLED_NUM;
106static uint8_t effect_num_leds = RGBLED_NUM;
104 107
105void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) { 108void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
106 clipping_start_pos = start_pos; 109 clipping_start_pos = start_pos;
107 clipping_num_leds = num_leds; 110 clipping_num_leds = num_leds;
108} 111}
109 112
113void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) {
114 if (start_pos >= RGBLED_NUM) return;
115 if (start_pos + num_leds > RGBLED_NUM) return;
116 effect_start_pos = start_pos;
117 effect_end_pos = start_pos + num_leds;
118 effect_num_leds = num_leds;
119}
110 120
111void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { 121void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
112 HSV hsv = { hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val }; 122 HSV hsv = { hue, sat, val };
113 RGB rgb = hsv_to_rgb(hsv); 123 RGB rgb = hsv_to_rgb(hsv);
114 setrgb(rgb.r, rgb.g, rgb.b, led1); 124 setrgb(rgb.r, rgb.g, rgb.b, led1);
115} 125}
116 126
127void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
128 sethsv_raw( hue, sat,
129 val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val,
130 led1);
131}
132
117void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) { 133void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
118 (*led1).r = r; 134 (*led1).r = r;
119 (*led1).g = g; 135 (*led1).g = g;
@@ -501,15 +517,15 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
501#else 517#else
502 uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2]; 518 uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2];
503#endif 519#endif
504 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 520 for (uint8_t i = 0; i < effect_num_leds; i++) {
505 uint8_t _hue = ((uint16_t)i * (uint16_t)range) / RGBLED_NUM; 521 uint8_t _hue = ((uint16_t)i * (uint16_t)range) / effect_num_leds;
506 if (direction) { 522 if (direction) {
507 _hue = hue + _hue; 523 _hue = hue + _hue;
508 } else { 524 } else {
509 _hue = hue - _hue; 525 _hue = hue - _hue;
510 } 526 }
511 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range); 527 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
512 sethsv(_hue, sat, val, (LED_TYPE *)&led[i]); 528 sethsv(_hue, sat, val, (LED_TYPE *)&led[i + effect_start_pos]);
513 } 529 }
514 rgblight_set(); 530 rgblight_set();
515 } 531 }
@@ -557,7 +573,7 @@ uint8_t rgblight_get_val(void) {
557void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { 573void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
558 if (!rgblight_config.enable) { return; } 574 if (!rgblight_config.enable) { return; }
559 575
560 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 576 for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
561 led[i].r = r; 577 led[i].r = r;
562 led[i].g = g; 578 led[i].g = g;
563 led[i].b = b; 579 led[i].b = b;
@@ -615,6 +631,7 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start,
615 rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end); 631 rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
616} 632}
617 633
634#ifndef RGBLIGHT_SPLIT
618void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) { 635void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) {
619 rgblight_setrgb_range(r, g, b, 0 , (uint8_t) RGBLED_NUM/2); 636 rgblight_setrgb_range(r, g, b, 0 , (uint8_t) RGBLED_NUM/2);
620} 637}
@@ -630,36 +647,34 @@ void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) {
630void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) { 647void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) {
631 rgblight_sethsv_range(hue, sat, val, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM); 648 rgblight_sethsv_range(hue, sat, val, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM);
632} 649}
650#endif // ifndef RGBLIGHT_SPLIT
633 651
634#ifndef RGBLIGHT_CUSTOM_DRIVER 652#ifndef RGBLIGHT_CUSTOM_DRIVER
635void rgblight_set(void) { 653void rgblight_set(void) {
636 LED_TYPE *start_led = led + clipping_start_pos; 654 LED_TYPE *start_led;
637 uint16_t num_leds = clipping_num_leds; 655 uint16_t num_leds = clipping_num_leds;
638 if (rgblight_config.enable) { 656
639 #ifdef RGBLIGHT_LED_MAP 657 if (!rgblight_config.enable) {
640 LED_TYPE led0[RGBLED_NUM]; 658 for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
641 for(uint8_t i = 0; i < RGBLED_NUM; i++) {
642 led0[i] = led[pgm_read_byte(&led_map[i])];
643 }
644 start_led = led0 + clipping_start_pos;
645 #endif
646 #ifdef RGBW
647 ws2812_setleds_rgbw(start_led, num_leds);
648 #else
649 ws2812_setleds(start_led, num_leds);
650 #endif
651 } else {
652 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
653 led[i].r = 0; 659 led[i].r = 0;
654 led[i].g = 0; 660 led[i].g = 0;
655 led[i].b = 0; 661 led[i].b = 0;
656 } 662 }
657 #ifdef RGBW
658 ws2812_setleds_rgbw(start_led, num_leds);
659 #else
660 ws2812_setleds(start_led, num_leds);
661 #endif
662 } 663 }
664#ifdef RGBLIGHT_LED_MAP
665 LED_TYPE led0[RGBLED_NUM];
666 for(uint8_t i = 0; i < RGBLED_NUM; i++) {
667 led0[i] = led[pgm_read_byte(&led_map[i])];
668 }
669 start_led = led0 + clipping_start_pos;
670#else
671 start_led = led + clipping_start_pos;
672#endif
673#ifdef RGBW
674 ws2812_setleds_rgbw(start_led, num_leds);
675#else
676 ws2812_setleds(start_led, num_leds);
677#endif
663} 678}
664#endif 679#endif
665 680
@@ -926,9 +941,9 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
926 uint8_t hue; 941 uint8_t hue;
927 uint8_t i; 942 uint8_t i;
928 943
929 for (i = 0; i < RGBLED_NUM; i++) { 944 for (i = 0; i < effect_num_leds; i++) {
930 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / RGBLED_NUM * i + anim->current_hue); 945 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / effect_num_leds * i + anim->current_hue);
931 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); 946 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]);
932 } 947 }
933 rgblight_set(); 948 rgblight_set();
934 949
@@ -957,7 +972,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
957#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) 972#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
958 if (anim->pos == 0) { // restart signal 973 if (anim->pos == 0) { // restart signal
959 if (increment == 1) { 974 if (increment == 1) {
960 pos = RGBLED_NUM - 1; 975 pos = effect_num_leds - 1;
961 } else { 976 } else {
962 pos = 0; 977 pos = 0;
963 } 978 }
@@ -965,26 +980,27 @@ void rgblight_effect_snake(animation_status_t *anim) {
965 } 980 }
966#endif 981#endif
967 982
968 for (i = 0; i < RGBLED_NUM; i++) { 983 for (i = 0; i < effect_num_leds; i++) {
969 led[i].r = 0; 984 LED_TYPE *ledp = led + i + effect_start_pos;
970 led[i].g = 0; 985 ledp->r = 0;
971 led[i].b = 0; 986 ledp->g = 0;
987 ledp->b = 0;
972 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { 988 for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
973 k = pos + j * increment; 989 k = pos + j * increment;
974 if (k < 0) { 990 if (k < 0) {
975 k = k + RGBLED_NUM; 991 k = k + effect_num_leds;
976 } 992 }
977 if (i == k) { 993 if (i == k) {
978 sethsv(rgblight_config.hue, rgblight_config.sat, 994 sethsv(rgblight_config.hue, rgblight_config.sat,
979 (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH), 995 (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH),
980 (LED_TYPE *)&led[i]); 996 ledp);
981 } 997 }
982 } 998 }
983 } 999 }
984 rgblight_set(); 1000 rgblight_set();
985 if (increment == 1) { 1001 if (increment == 1) {
986 if (pos - 1 < 0) { 1002 if (pos - 1 < 0) {
987 pos = RGBLED_NUM - 1; 1003 pos = effect_num_leds - 1;
988#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) 1004#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
989 anim->pos = 0; 1005 anim->pos = 0;
990#endif 1006#endif
@@ -995,7 +1011,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
995#endif 1011#endif
996 } 1012 }
997 } else { 1013 } else {
998 pos = (pos + 1) % RGBLED_NUM; 1014 pos = (pos + 1) % effect_num_leds;
999#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) 1015#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1000 anim->pos = pos; 1016 anim->pos = pos;
1001#endif 1017#endif
@@ -1023,14 +1039,14 @@ void rgblight_effect_knight(animation_status_t *anim) {
1023 } 1039 }
1024#endif 1040#endif
1025 // Set all the LEDs to 0 1041 // Set all the LEDs to 0
1026 for (i = 0; i < RGBLED_NUM; i++) { 1042 for (i = effect_start_pos; i < effect_end_pos; i++) {
1027 led[i].r = 0; 1043 led[i].r = 0;
1028 led[i].g = 0; 1044 led[i].g = 0;
1029 led[i].b = 0; 1045 led[i].b = 0;
1030 } 1046 }
1031 // Determine which LEDs should be lit up 1047 // Determine which LEDs should be lit up
1032 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { 1048 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
1033 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM; 1049 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % effect_num_leds + effect_start_pos;
1034 1050
1035 if (i >= low_bound && i <= high_bound) { 1051 if (i >= low_bound && i <= high_bound) {
1036 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]); 1052 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
@@ -1064,9 +1080,9 @@ void rgblight_effect_christmas(animation_status_t *anim) {
1064 uint8_t i; 1080 uint8_t i;
1065 1081
1066 anim->current_offset = (anim->current_offset + 1) % 2; 1082 anim->current_offset = (anim->current_offset + 1) % 2;
1067 for (i = 0; i < RGBLED_NUM; i++) { 1083 for (i = 0; i < effect_num_leds; i++) {
1068 hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85; 1084 hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85;
1069 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); 1085 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]);
1070 } 1086 }
1071 rgblight_set(); 1087 rgblight_set();
1072} 1088}
@@ -1099,13 +1115,14 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
1099#ifdef RGBLIGHT_EFFECT_ALTERNATING 1115#ifdef RGBLIGHT_EFFECT_ALTERNATING
1100void rgblight_effect_alternating(animation_status_t *anim) { 1116void rgblight_effect_alternating(animation_status_t *anim) {
1101 1117
1102 for(int i = 0; i<RGBLED_NUM; i++){ 1118 for (int i = 0; i < effect_num_leds; i++) {
1103 if(i<RGBLED_NUM/2 && anim->pos){ 1119 LED_TYPE *ledp = led + i + effect_start_pos;
1104 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); 1120 if (i<effect_num_leds/2 && anim->pos) {
1105 }else if (i>=RGBLED_NUM/2 && !anim->pos){ 1121 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
1106 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]); 1122 } else if (i>=effect_num_leds/2 && !anim->pos) {
1107 }else{ 1123 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
1108 sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]); 1124 } else {
1125 sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp);
1109 } 1126 }
1110 } 1127 }
1111 rgblight_set(); 1128 rgblight_set();
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 35d7942ca..064522a2b 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -99,7 +99,7 @@ enum RGBLIGHT_EFFECT_MODE {
99#endif 99#endif
100 100
101#ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM 101#ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM
102#define RGBLIGHT_EFFECT_KNIGHT_LED_NUM RGBLED_NUM 102#define RGBLIGHT_EFFECT_KNIGHT_LED_NUM (effect_num_leds)
103#endif 103#endif
104 104
105#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 105#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
@@ -170,61 +170,79 @@ typedef struct _rgblight_status_t {
170#endif 170#endif
171} rgblight_status_t; 171} rgblight_status_t;
172 172
173#ifdef RGBLIGHT_SPLIT 173/* === Utility Functions ===*/
174 #define RGBLIGHT_STATUS_CHANGE_MODE (1<<0) 174void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
175 #define RGBLIGHT_STATUS_CHANGE_HSVS (1<<1) 175void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); // without RGBLIGHT_LIMIT_VAL check
176 #define RGBLIGHT_STATUS_CHANGE_TIMER (1<<2) 176void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
177 #define RGBLIGHT_STATUS_ANIMATION_TICK (1<<3)
178 177
179 typedef struct _rgblight_syncinfo_t { 178/* === Low level Functions === */
180 rgblight_config_t config; 179void rgblight_set(void);
181 rgblight_status_t status; 180void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
182 } rgblight_syncinfo_t;
183 181
184 /* for split keyboard master side */ 182/* === Effects and Animations Functions === */
185 uint8_t rgblight_get_change_flags(void); 183/* effect range setting */
186 void rgblight_clear_change_flags(void); 184void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds);
187 void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo); 185
188 /* for split keyboard slave side */ 186/* direct operation */
189 void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom); 187void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index);
188void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index);
189void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end);
190void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end);
191void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
192
193#ifndef RGBLIGHT_SPLIT
194void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
195void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
196void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val);
197void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val);
190#endif 198#endif
191 199
192void rgblight_init(void); 200/* effect mode change */
201void rgblight_mode(uint8_t mode);
202void rgblight_mode_noeeprom(uint8_t mode);
193void rgblight_increase(void); 203void rgblight_increase(void);
194void rgblight_decrease(void); 204void rgblight_decrease(void);
205void rgblight_step(void);
206void rgblight_step_noeeprom(void);
207void rgblight_step_reverse(void);
208void rgblight_step_reverse_noeeprom(void);
209
210/* effects mode disable/enable */
195void rgblight_toggle(void); 211void rgblight_toggle(void);
212void rgblight_toggle_noeeprom(void);
196void rgblight_enable(void); 213void rgblight_enable(void);
214void rgblight_enable_noeeprom(void);
197void rgblight_disable(void); 215void rgblight_disable(void);
198void rgblight_step(void); 216void rgblight_disable_noeeprom(void);
199void rgblight_step_reverse(void); 217
200uint8_t rgblight_get_mode(void); 218/* hue, sat, val change */
201void rgblight_mode(uint8_t mode);
202void rgblight_set(void);
203uint32_t rgblight_read_dword(void);
204void rgblight_update_dword(uint32_t dword);
205void rgblight_increase_hue(void); 219void rgblight_increase_hue(void);
220void rgblight_increase_hue_noeeprom(void);
206void rgblight_decrease_hue(void); 221void rgblight_decrease_hue(void);
222void rgblight_decrease_hue_noeeprom(void);
207void rgblight_increase_sat(void); 223void rgblight_increase_sat(void);
224void rgblight_increase_sat_noeeprom(void);
208void rgblight_decrease_sat(void); 225void rgblight_decrease_sat(void);
226void rgblight_decrease_sat_noeeprom(void);
209void rgblight_increase_val(void); 227void rgblight_increase_val(void);
228void rgblight_increase_val_noeeprom(void);
210void rgblight_decrease_val(void); 229void rgblight_decrease_val(void);
230void rgblight_decrease_val_noeeprom(void);
211void rgblight_increase_speed(void); 231void rgblight_increase_speed(void);
212void rgblight_decrease_speed(void); 232void rgblight_decrease_speed(void);
213void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val); 233void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val);
234void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val);
235
236/* query */
237uint8_t rgblight_get_mode(void);
214uint8_t rgblight_get_hue(void); 238uint8_t rgblight_get_hue(void);
215uint8_t rgblight_get_sat(void); 239uint8_t rgblight_get_sat(void);
216uint8_t rgblight_get_val(void); 240uint8_t rgblight_get_val(void);
217void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
218void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index);
219void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index);
220void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end);
221void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end);
222void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
223void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
224void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val);
225void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val);
226void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
227 241
242/* === qmk_firmware (core)internal Functions === */
243void rgblight_init(void);
244uint32_t rgblight_read_dword(void);
245void rgblight_update_dword(uint32_t dword);
228uint32_t eeconfig_read_rgblight(void); 246uint32_t eeconfig_read_rgblight(void);
229void eeconfig_update_rgblight(uint32_t val); 247void eeconfig_update_rgblight(uint32_t val);
230void eeconfig_update_rgblight_default(void); 248void eeconfig_update_rgblight_default(void);
@@ -233,27 +251,9 @@ void eeconfig_debug_rgblight(void);
233void rgb_matrix_increase(void); 251void rgb_matrix_increase(void);
234void rgb_matrix_decrease(void); 252void rgb_matrix_decrease(void);
235 253
236void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
237void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
238
239void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val);
240void rgblight_mode_noeeprom(uint8_t mode);
241void rgblight_toggle_noeeprom(void);
242void rgblight_enable_noeeprom(void);
243void rgblight_disable_noeeprom(void);
244void rgblight_step_noeeprom(void);
245void rgblight_step_reverse_noeeprom(void);
246void rgblight_increase_hue_noeeprom(void);
247void rgblight_decrease_hue_noeeprom(void);
248void rgblight_increase_sat_noeeprom(void);
249void rgblight_decrease_sat_noeeprom(void);
250void rgblight_increase_val_noeeprom(void);
251void rgblight_decrease_val_noeeprom(void);
252
253void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom); 254void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
254void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom); 255void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom);
255 256
256
257#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF) 257#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
258void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b); 258void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
259 259
@@ -264,6 +264,25 @@ void rgblight_timer_enable(void);
264void rgblight_timer_disable(void); 264void rgblight_timer_disable(void);
265void rgblight_timer_toggle(void); 265void rgblight_timer_toggle(void);
266 266
267#ifdef RGBLIGHT_SPLIT
268 #define RGBLIGHT_STATUS_CHANGE_MODE (1<<0)
269 #define RGBLIGHT_STATUS_CHANGE_HSVS (1<<1)
270 #define RGBLIGHT_STATUS_CHANGE_TIMER (1<<2)
271 #define RGBLIGHT_STATUS_ANIMATION_TICK (1<<3)
272
273 typedef struct _rgblight_syncinfo_t {
274 rgblight_config_t config;
275 rgblight_status_t status;
276 } rgblight_syncinfo_t;
277
278 /* for split keyboard master side */
279 uint8_t rgblight_get_change_flags(void);
280 void rgblight_clear_change_flags(void);
281 void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo);
282 /* for split keyboard slave side */
283 void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom);
284#endif
285
267#ifdef RGBLIGHT_USE_TIMER 286#ifdef RGBLIGHT_USE_TIMER
268 287
269typedef struct _animation_status_t { 288typedef struct _animation_status_t {