diff --git a/docs/feature_rgblight.md b/docs/feature_rgblight.md
index 1e0ce91473..be4ddfa729 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:
|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM` |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel |
|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation |
|`RGBLIGHT_EFFECT_KNIGHT_OFFSET` |`0` |The number of LEDs to start the "Knight" animation from the start of the strip by |
-|`RGBLIGHT_RAINBOW_SWIRL_RANGE` |`360` |Range adjustment for the rainbow swirl effect to get different swirls |
+|`RGBLIGHT_RAINBOW_SWIRL_RANGE` |`255` |Range adjustment for the rainbow swirl effect to get different swirls |
|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation |
### Example Usage to Reduce Memory Footprint
@@ -176,44 +176,100 @@ const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
If 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:
-|Function |Description |
-|--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
-|`rgblight_enable()` |Turn LEDs on, based on their previous state |
-|`rgblight_enable_noeeprom()` |Turn LEDs on, based on their previous state (not written to EEPROM) |
-|`rgblight_disable()` |Turn LEDs off |
-|`rgblight_disable_noeeprom()` |Turn LEDs off (not written to EEPROM) |
-|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled |
-|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) |
-|`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) |
-|`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) |
+### Utility Functions
+|Function |Description |
+|--------------------------------------------|-------------------------------------------------------------------|
+|`sethsv(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value |
+|`sethsv_raw(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value without RGBLIGHT_LIMIT_VAL check |
+|`setrgb(r, g, b, ledbuf)` |Set ledbuf to the given RGB value where `r`/`g`/`b` |
+
+### Low level Functions
+|Function |Description |
+|--------------------------------------------|-------------------------------------------|
+|`rgblight_set()` |Flash out led buffers to LEDs |
+|`rgblight_set_clipping_range(pos, num)` |Set clipping Range. see [Clipping Range](#clipping-range) |
+
+Example:
+```c
+sethsv(HSV_WHITE, (LED_TYPE *)&led[0]); // led 0
+sethsv(HSV_RED, (LED_TYPE *)&led[1]); // led 1
+sethsv(HSV_GREEN, (LED_TYPE *)&led[2]); // led 2
+rgblight_set(); // Utility functions do not call rgblight_set() automatically, so they need to be called explicitly.
+```
+
+### Effects and Animations Functions
+#### effect range setting
+|Function |Description |
+|--------------------------------------------|------------------|
+|`rgblight_set_effect_range(pos, num)` |Set Effects Range |
+
+#### direct operation
+|Function |Description |
+|--------------------------------------------|-------------|
+|`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) |
+|`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) |
|`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)|
-|`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) |
-|`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) |
-|`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 |
-|`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) |
-|`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)|
-|`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)|
-|`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) |
-|`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) |
-|`rgblight_toggle()` |Toggle all LEDs between on and off |
-|`rgblight_toggle_noeeprom()` |Toggle all LEDs between on and off (not written to EEPROM) |
-|`rgblight_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations |
-|`rgblight_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) |
-|`rgblight_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations |
-|`rgblight_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) |
-|`rgblight_increase_hue()` |Increase the hue for all LEDs. This wraps around at maximum hue |
-|`rgblight_increase_hue_noeeprom()` |Increase the hue for all LEDs. This wraps around at maximum hue (not written to EEPROM) |
-|`rgblight_decrease_hue()` |Decrease the hue for all LEDs. This wraps around at minimum hue |
-|`rgblight_decrease_hue_noeeprom()` |Decrease the hue for all LEDs. This wraps around at minimum hue (not written to EEPROM) |
-|`rgblight_increase_sat()` |Increase the saturation for all LEDs. This wraps around at maximum saturation |
-|`rgblight_increase_sat_noeeprom()` |Increase the saturation for all LEDs. This wraps around at maximum saturation (not written to EEPROM) |
-|`rgblight_decrease_sat()` |Decrease the saturation for all LEDs. This wraps around at minimum saturation |
-|`rgblight_decrease_sat_noeeprom()` |Decrease the saturation for all LEDs. This wraps around at minimum saturation (not written to EEPROM) |
-|`rgblight_increase_val()` |Increase the value for all LEDs. This wraps around at maximum value |
-|`rgblight_increase_val_noeeprom()` |Increase the value for all LEDs. This wraps around at maximum value (not written to EEPROM) |
-|`rgblight_decrease_val()` |Decrease the value for all LEDs. This wraps around at minimum value |
-|`rgblight_decrease_val_noeeprom()` |Decrease the value for all LEDs. This wraps around at minimum value (not written to EEPROM) |
-|`rgblight_set_clipping_range(pos, num)` |Set clipping Range |
+|`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)|
+|`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) |
+|`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) |
+|`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) |
+|`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) |
+|`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) |
+
+Example:
+```c
+rgblight_sethsv(HSV_WHITE, 0); // led 0
+rgblight_sethsv(HSV_RED, 1); // led 1
+rgblight_sethsv(HSV_GREEN, 2); // led 2
+// The above functions automatically calls rgblight_set(), so there is no need to call it explicitly.
+// Note that it is inefficient to call repeatedly.
+```
+
+#### effect mode change
+|Function |Description |
+|--------------------------------------------|-------------|
+|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled |
+|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) |
+|`rgblight_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations |
+|`rgblight_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) |
+|`rgblight_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations |
+|`rgblight_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) |
+
+#### effects mode disable/enable
+|Function |Description |
+|--------------------------------------------|-------------|
+|`rgblight_toggle()` |Toggle effect range LEDs between on and off |
+|`rgblight_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) |
+|`rgblight_enable()` |Turn effect range LEDs on, based on their previous state |
+|`rgblight_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) |
+|`rgblight_disable()` |Turn effect range LEDs off |
+|`rgblight_disable_noeeprom()` |Turn effect range LEDs off (not written to EEPROM) |
+
+#### hue, sat, val change
+|Function |Description |
+|--------------------------------------------|-------------|
+|`rgblight_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue |
+|`rgblight_increase_hue_noeeprom()` |Increase the hue for effect range LEDs. This wraps around at maximum hue (not written to EEPROM) |
+|`rgblight_decrease_hue()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue |
+|`rgblight_decrease_hue_noeeprom()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue (not written to EEPROM) |
+|`rgblight_increase_sat()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation |
+|`rgblight_increase_sat_noeeprom()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation (not written to EEPROM) |
+|`rgblight_decrease_sat()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation |
+|`rgblight_decrease_sat_noeeprom()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation (not written to EEPROM) |
+|`rgblight_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value |
+|`rgblight_increase_val_noeeprom()` |Increase the value for effect range LEDs. This wraps around at maximum value (not written to EEPROM) |
+|`rgblight_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value |
+|`rgblight_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) |
+|`rgblight_sethsv(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 |
+|`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) |
+
+#### query
+|Function |Description |
+|-----------------------|-----------------|
+|`rgblight_get_mode()` |Get current mode |
+|`rgblight_get_hue()` |Get current hue |
+|`rgblight_get_sat()` |Get current sat |
+|`rgblight_get_val()` |Get current val |
## Colors
@@ -324,4 +380,6 @@ In addition to setting the Clipping Range, you can use `RGBLIGHT_LED_MAP` togeth
```
+## Hardware Modification
+
If 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 77772e2925..75e4ef0d86 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -101,19 +101,35 @@ LED_TYPE led[RGBLED_NUM];
static uint8_t clipping_start_pos = 0;
static uint8_t clipping_num_leds = RGBLED_NUM;
+static uint8_t effect_start_pos = 0;
+static uint8_t effect_end_pos = RGBLED_NUM;
+static uint8_t effect_num_leds = RGBLED_NUM;
void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
clipping_start_pos = start_pos;
clipping_num_leds = num_leds;
}
+void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) {
+ if (start_pos >= RGBLED_NUM) return;
+ if (start_pos + num_leds > RGBLED_NUM) return;
+ effect_start_pos = start_pos;
+ effect_end_pos = start_pos + num_leds;
+ effect_num_leds = num_leds;
+}
-void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
- HSV hsv = { hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val };
+void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
+ HSV hsv = { hue, sat, val };
RGB rgb = hsv_to_rgb(hsv);
setrgb(rgb.r, rgb.g, rgb.b, led1);
}
+void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
+ sethsv_raw( hue, sat,
+ val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val,
+ led1);
+}
+
void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
(*led1).r = r;
(*led1).g = g;
@@ -501,15 +517,15 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
#else
uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2];
#endif
- for (uint8_t i = 0; i < RGBLED_NUM; i++) {
- uint8_t _hue = ((uint16_t)i * (uint16_t)range) / RGBLED_NUM;
+ for (uint8_t i = 0; i < effect_num_leds; i++) {
+ uint8_t _hue = ((uint16_t)i * (uint16_t)range) / effect_num_leds;
if (direction) {
_hue = hue + _hue;
} else {
_hue = hue - _hue;
}
dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
- sethsv(_hue, sat, val, (LED_TYPE *)&led[i]);
+ sethsv(_hue, sat, val, (LED_TYPE *)&led[i + effect_start_pos]);
}
rgblight_set();
}
@@ -557,7 +573,7 @@ uint8_t rgblight_get_val(void) {
void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
if (!rgblight_config.enable) { return; }
- for (uint8_t i = 0; i < RGBLED_NUM; i++) {
+ for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
led[i].r = r;
led[i].g = g;
led[i].b = b;
@@ -615,6 +631,7 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start,
rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
}
+#ifndef RGBLIGHT_SPLIT
void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) {
rgblight_setrgb_range(r, g, b, 0 , (uint8_t) RGBLED_NUM/2);
}
@@ -630,36 +647,34 @@ void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) {
void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) {
rgblight_sethsv_range(hue, sat, val, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM);
}
+#endif // ifndef RGBLIGHT_SPLIT
#ifndef RGBLIGHT_CUSTOM_DRIVER
void rgblight_set(void) {
- LED_TYPE *start_led = led + clipping_start_pos;
+ LED_TYPE *start_led;
uint16_t num_leds = clipping_num_leds;
- if (rgblight_config.enable) {
- #ifdef RGBLIGHT_LED_MAP
- LED_TYPE led0[RGBLED_NUM];
- for(uint8_t i = 0; i < RGBLED_NUM; i++) {
- led0[i] = led[pgm_read_byte(&led_map[i])];
- }
- start_led = led0 + clipping_start_pos;
- #endif
- #ifdef RGBW
- ws2812_setleds_rgbw(start_led, num_leds);
- #else
- ws2812_setleds(start_led, num_leds);
- #endif
- } else {
- for (uint8_t i = 0; i < RGBLED_NUM; i++) {
+
+ if (!rgblight_config.enable) {
+ for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
led[i].r = 0;
led[i].g = 0;
led[i].b = 0;
}
- #ifdef RGBW
- ws2812_setleds_rgbw(start_led, num_leds);
- #else
- ws2812_setleds(start_led, num_leds);
- #endif
}
+#ifdef RGBLIGHT_LED_MAP
+ LED_TYPE led0[RGBLED_NUM];
+ for(uint8_t i = 0; i < RGBLED_NUM; i++) {
+ led0[i] = led[pgm_read_byte(&led_map[i])];
+ }
+ start_led = led0 + clipping_start_pos;
+#else
+ start_led = led + clipping_start_pos;
+#endif
+#ifdef RGBW
+ ws2812_setleds_rgbw(start_led, num_leds);
+#else
+ ws2812_setleds(start_led, num_leds);
+#endif
}
#endif
@@ -926,9 +941,9 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
uint8_t hue;
uint8_t i;
- for (i = 0; i < RGBLED_NUM; i++) {
- hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / RGBLED_NUM * i + anim->current_hue);
- sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
+ for (i = 0; i < effect_num_leds; i++) {
+ hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / effect_num_leds * i + anim->current_hue);
+ sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]);
}
rgblight_set();
@@ -957,7 +972,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
if (anim->pos == 0) { // restart signal
if (increment == 1) {
- pos = RGBLED_NUM - 1;
+ pos = effect_num_leds - 1;
} else {
pos = 0;
}
@@ -965,26 +980,27 @@ void rgblight_effect_snake(animation_status_t *anim) {
}
#endif
- for (i = 0; i < RGBLED_NUM; i++) {
- led[i].r = 0;
- led[i].g = 0;
- led[i].b = 0;
+ for (i = 0; i < effect_num_leds; i++) {
+ LED_TYPE *ledp = led + i + effect_start_pos;
+ ledp->r = 0;
+ ledp->g = 0;
+ ledp->b = 0;
for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
k = pos + j * increment;
if (k < 0) {
- k = k + RGBLED_NUM;
+ k = k + effect_num_leds;
}
if (i == k) {
sethsv(rgblight_config.hue, rgblight_config.sat,
(uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH),
- (LED_TYPE *)&led[i]);
+ ledp);
}
}
}
rgblight_set();
if (increment == 1) {
if (pos - 1 < 0) {
- pos = RGBLED_NUM - 1;
+ pos = effect_num_leds - 1;
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
anim->pos = 0;
#endif
@@ -995,7 +1011,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
#endif
}
} else {
- pos = (pos + 1) % RGBLED_NUM;
+ pos = (pos + 1) % effect_num_leds;
#if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
anim->pos = pos;
#endif
@@ -1023,14 +1039,14 @@ void rgblight_effect_knight(animation_status_t *anim) {
}
#endif
// Set all the LEDs to 0
- for (i = 0; i < RGBLED_NUM; i++) {
+ for (i = effect_start_pos; i < effect_end_pos; i++) {
led[i].r = 0;
led[i].g = 0;
led[i].b = 0;
}
// Determine which LEDs should be lit up
for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
- cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;
+ cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % effect_num_leds + effect_start_pos;
if (i >= low_bound && i <= high_bound) {
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) {
uint8_t i;
anim->current_offset = (anim->current_offset + 1) % 2;
- for (i = 0; i < RGBLED_NUM; i++) {
+ for (i = 0; i < effect_num_leds; i++) {
hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85;
- sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
+ sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]);
}
rgblight_set();
}
@@ -1099,13 +1115,14 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
#ifdef RGBLIGHT_EFFECT_ALTERNATING
void rgblight_effect_alternating(animation_status_t *anim) {
- for(int i = 0; ipos){
- sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
- }else if (i>=RGBLED_NUM/2 && !anim->pos){
- sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
- }else{
- sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]);
+ for (int i = 0; i < effect_num_leds; i++) {
+ LED_TYPE *ledp = led + i + effect_start_pos;
+ if (ipos) {
+ sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
+ } else if (i>=effect_num_leds/2 && !anim->pos) {
+ sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
+ } else {
+ sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp);
}
}
rgblight_set();
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index 35d7942ca6..064522a2b0 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -99,7 +99,7 @@ enum RGBLIGHT_EFFECT_MODE {
#endif
#ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM
-#define RGBLIGHT_EFFECT_KNIGHT_LED_NUM RGBLED_NUM
+#define RGBLIGHT_EFFECT_KNIGHT_LED_NUM (effect_num_leds)
#endif
#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
@@ -170,61 +170,79 @@ typedef struct _rgblight_status_t {
#endif
} rgblight_status_t;
-#ifdef RGBLIGHT_SPLIT
- #define RGBLIGHT_STATUS_CHANGE_MODE (1<<0)
- #define RGBLIGHT_STATUS_CHANGE_HSVS (1<<1)
- #define RGBLIGHT_STATUS_CHANGE_TIMER (1<<2)
- #define RGBLIGHT_STATUS_ANIMATION_TICK (1<<3)
+/* === Utility Functions ===*/
+void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
+void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); // without RGBLIGHT_LIMIT_VAL check
+void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
- typedef struct _rgblight_syncinfo_t {
- rgblight_config_t config;
- rgblight_status_t status;
- } rgblight_syncinfo_t;
+/* === Low level Functions === */
+void rgblight_set(void);
+void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
- /* for split keyboard master side */
- uint8_t rgblight_get_change_flags(void);
- void rgblight_clear_change_flags(void);
- void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo);
- /* for split keyboard slave side */
- void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom);
+/* === Effects and Animations Functions === */
+/* effect range setting */
+void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds);
+
+/* direct operation */
+void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index);
+void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index);
+void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end);
+void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end);
+void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
+
+#ifndef RGBLIGHT_SPLIT
+void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
+void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
+void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val);
+void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val);
#endif
-void rgblight_init(void);
+/* effect mode change */
+void rgblight_mode(uint8_t mode);
+void rgblight_mode_noeeprom(uint8_t mode);
void rgblight_increase(void);
void rgblight_decrease(void);
+void rgblight_step(void);
+void rgblight_step_noeeprom(void);
+void rgblight_step_reverse(void);
+void rgblight_step_reverse_noeeprom(void);
+
+/* effects mode disable/enable */
void rgblight_toggle(void);
+void rgblight_toggle_noeeprom(void);
void rgblight_enable(void);
+void rgblight_enable_noeeprom(void);
void rgblight_disable(void);
-void rgblight_step(void);
-void rgblight_step_reverse(void);
-uint8_t rgblight_get_mode(void);
-void rgblight_mode(uint8_t mode);
-void rgblight_set(void);
-uint32_t rgblight_read_dword(void);
-void rgblight_update_dword(uint32_t dword);
+void rgblight_disable_noeeprom(void);
+
+/* hue, sat, val change */
void rgblight_increase_hue(void);
+void rgblight_increase_hue_noeeprom(void);
void rgblight_decrease_hue(void);
+void rgblight_decrease_hue_noeeprom(void);
void rgblight_increase_sat(void);
+void rgblight_increase_sat_noeeprom(void);
void rgblight_decrease_sat(void);
+void rgblight_decrease_sat_noeeprom(void);
void rgblight_increase_val(void);
+void rgblight_increase_val_noeeprom(void);
void rgblight_decrease_val(void);
+void rgblight_decrease_val_noeeprom(void);
void rgblight_increase_speed(void);
void rgblight_decrease_speed(void);
void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val);
+void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val);
+
+/* query */
+uint8_t rgblight_get_mode(void);
uint8_t rgblight_get_hue(void);
uint8_t rgblight_get_sat(void);
uint8_t rgblight_get_val(void);
-void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b);
-void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index);
-void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index);
-void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end);
-void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end);
-void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
-void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
-void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val);
-void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val);
-void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
+/* === qmk_firmware (core)internal Functions === */
+void rgblight_init(void);
+uint32_t rgblight_read_dword(void);
+void rgblight_update_dword(uint32_t dword);
uint32_t eeconfig_read_rgblight(void);
void eeconfig_update_rgblight(uint32_t val);
void eeconfig_update_rgblight_default(void);
@@ -233,27 +251,9 @@ void eeconfig_debug_rgblight(void);
void rgb_matrix_increase(void);
void rgb_matrix_decrease(void);
-void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
-void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
-
-void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val);
-void rgblight_mode_noeeprom(uint8_t mode);
-void rgblight_toggle_noeeprom(void);
-void rgblight_enable_noeeprom(void);
-void rgblight_disable_noeeprom(void);
-void rgblight_step_noeeprom(void);
-void rgblight_step_reverse_noeeprom(void);
-void rgblight_increase_hue_noeeprom(void);
-void rgblight_decrease_hue_noeeprom(void);
-void rgblight_increase_sat_noeeprom(void);
-void rgblight_decrease_sat_noeeprom(void);
-void rgblight_increase_val_noeeprom(void);
-void rgblight_decrease_val_noeeprom(void);
-
void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom);
-
#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
@@ -264,6 +264,25 @@ void rgblight_timer_enable(void);
void rgblight_timer_disable(void);
void rgblight_timer_toggle(void);
+#ifdef RGBLIGHT_SPLIT
+ #define RGBLIGHT_STATUS_CHANGE_MODE (1<<0)
+ #define RGBLIGHT_STATUS_CHANGE_HSVS (1<<1)
+ #define RGBLIGHT_STATUS_CHANGE_TIMER (1<<2)
+ #define RGBLIGHT_STATUS_ANIMATION_TICK (1<<3)
+
+ typedef struct _rgblight_syncinfo_t {
+ rgblight_config_t config;
+ rgblight_status_t status;
+ } rgblight_syncinfo_t;
+
+ /* for split keyboard master side */
+ uint8_t rgblight_get_change_flags(void);
+ void rgblight_clear_change_flags(void);
+ void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo);
+ /* for split keyboard slave side */
+ void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom);
+#endif
+
#ifdef RGBLIGHT_USE_TIMER
typedef struct _animation_status_t {