aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfauxpark <fauxpark@gmail.com>2020-12-26 19:32:05 +1100
committerZach White <skullydazed@drpepper.org>2021-01-04 16:27:16 -0800
commitc38fe492426676cf101eeb024f7f33d8e98c445f (patch)
treec716022c1a1242613c281ddf7bad56d332260f9f
parentd1e10a067b6e0a976979daec25f3c61486f6b64f (diff)
downloadqmk_firmware-c38fe492426676cf101eeb024f7f33d8e98c445f.tar.gz
qmk_firmware-c38fe492426676cf101eeb024f7f33d8e98c445f.zip
Update MXSS custom rgblight and fix compilation error
-rw-r--r--keyboards/mxss/rgblight.c382
-rw-r--r--keyboards/mxss/rgblight.h358
2 files changed, 289 insertions, 451 deletions
diff --git a/keyboards/mxss/rgblight.c b/keyboards/mxss/rgblight.c
index 2e9352c55..d2d79815c 100644
--- a/keyboards/mxss/rgblight.c
+++ b/keyboards/mxss/rgblight.c
@@ -15,13 +15,16 @@
15 */ 15 */
16#include <math.h> 16#include <math.h>
17#include <string.h> 17#include <string.h>
18#include <stdlib.h>
18#ifdef __AVR__ 19#ifdef __AVR__
19# include <avr/eeprom.h> 20# include <avr/eeprom.h>
20# include <avr/interrupt.h> 21# include <avr/interrupt.h>
21#endif 22#endif
23#ifdef EEPROM_ENABLE
24# include "eeprom.h"
25#endif
22#ifdef STM32_EEPROM_ENABLE 26#ifdef STM32_EEPROM_ENABLE
23# include <hal.h> 27# include <hal.h>
24# include "eeprom.h"
25# include "eeprom_stm32.h" 28# include "eeprom_stm32.h"
26#endif 29#endif
27#include "wait.h" 30#include "wait.h"
@@ -38,17 +41,23 @@
38// MxSS custom 41// MxSS custom
39#include "mxss_frontled.h" 42#include "mxss_frontled.h"
40 43
44#ifndef MIN
45# define MIN(a, b) (((a) < (b)) ? (a) : (b))
46#endif
47
41#ifdef RGBLIGHT_SPLIT 48#ifdef RGBLIGHT_SPLIT
42/* for split keyboard */ 49/* for split keyboard */
43# define RGBLIGHT_SPLIT_SET_CHANGE_MODE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_MODE 50# define RGBLIGHT_SPLIT_SET_CHANGE_MODE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_MODE
44# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_HSVS 51# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_HSVS
45# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE | RGBLIGHT_STATUS_CHANGE_HSVS) 52# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE | RGBLIGHT_STATUS_CHANGE_HSVS)
53# define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_LAYERS
46# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER 54# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER
47# define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK 55# define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK
48#else 56#else
49# define RGBLIGHT_SPLIT_SET_CHANGE_MODE 57# define RGBLIGHT_SPLIT_SET_CHANGE_MODE
50# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS 58# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS
51# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS 59# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS
60# define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS
52# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE 61# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE
53# define RGBLIGHT_SPLIT_ANIMATION_TICK 62# define RGBLIGHT_SPLIT_ANIMATION_TICK
54#endif 63#endif
@@ -97,11 +106,11 @@ LED_TYPE led[RGBLED_NUM];
97# define LED_ARRAY led 106# define LED_ARRAY led
98#endif 107#endif
99 108
100static uint8_t clipping_start_pos = 0; 109#ifdef RGBLIGHT_LAYERS
101static uint8_t clipping_num_leds = RGBLED_NUM; 110rgblight_segment_t const *const *rgblight_layers = NULL;
102static uint8_t effect_start_pos = 0; 111#endif
103static uint8_t effect_end_pos = RGBLED_NUM; 112
104static uint8_t effect_num_leds = RGBLED_NUM; 113rgblight_ranges_t rgblight_ranges = {0, RGBLED_NUM, 0, RGBLED_NUM, RGBLED_NUM};
105 114
106// MxSS custom 115// MxSS custom
107extern uint8_t fled_mode; 116extern uint8_t fled_mode;
@@ -116,18 +125,20 @@ void copyrgb(LED_TYPE *src, LED_TYPE *dst) {
116} 125}
117 126
118void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) { 127void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
119 clipping_start_pos = start_pos; 128 rgblight_ranges.clipping_start_pos = start_pos;
120 clipping_num_leds = num_leds; 129 rgblight_ranges.clipping_num_leds = num_leds;
121} 130}
122 131
123void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) { 132void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) {
124 if (start_pos >= RGBLED_NUM) return; 133 if (start_pos >= RGBLED_NUM) return;
125 if (start_pos + num_leds > RGBLED_NUM) return; 134 if (start_pos + num_leds > RGBLED_NUM) return;
126 effect_start_pos = start_pos; 135 rgblight_ranges.effect_start_pos = start_pos;
127 effect_end_pos = start_pos + num_leds; 136 rgblight_ranges.effect_end_pos = start_pos + num_leds;
128 effect_num_leds = num_leds; 137 rgblight_ranges.effect_num_leds = num_leds;
129} 138}
130 139
140__attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); }
141
131void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { 142void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
132 HSV hsv = {hue, sat, val}; 143 HSV hsv = {hue, sat, val};
133 // MxSS custom 144 // MxSS custom
@@ -138,7 +149,8 @@ void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
138 } else if (led1 == &led[RGBLIGHT_FLED2]) { 149 } else if (led1 == &led[RGBLIGHT_FLED2]) {
139 fled_hs[1].hue = hue; 150 fled_hs[1].hue = hue;
140 fled_hs[1].sat = sat; 151 fled_hs[1].sat = sat;
141 } RGB rgb = hsv_to_rgb(hsv); 152 }
153 RGB rgb = rgblight_hsv_to_rgb(hsv);
142 setrgb(rgb.r, rgb.g, rgb.b, led1); 154 setrgb(rgb.r, rgb.g, rgb.b, led1);
143} 155}
144 156
@@ -168,7 +180,7 @@ void rgblight_check_config(void) {
168} 180}
169 181
170uint32_t eeconfig_read_rgblight(void) { 182uint32_t eeconfig_read_rgblight(void) {
171#if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) 183#ifdef EEPROM_ENABLE
172 return eeprom_read_dword(EECONFIG_RGBLIGHT); 184 return eeprom_read_dword(EECONFIG_RGBLIGHT);
173#else 185#else
174 return 0; 186 return 0;
@@ -176,15 +188,13 @@ uint32_t eeconfig_read_rgblight(void) {
176} 188}
177 189
178void eeconfig_update_rgblight(uint32_t val) { 190void eeconfig_update_rgblight(uint32_t val) {
179#if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) 191#ifdef EEPROM_ENABLE
180 rgblight_check_config(); 192 rgblight_check_config();
181 eeprom_update_dword(EECONFIG_RGBLIGHT, val); 193 eeprom_update_dword(EECONFIG_RGBLIGHT, val);
182#endif 194#endif
183} 195}
184 196
185void eeconfig_update_rgblight_current(void) { 197void eeconfig_update_rgblight_current(void) { eeconfig_update_rgblight(rgblight_config.raw); }
186 eeconfig_update_rgblight(rgblight_config.raw);
187}
188 198
189void eeconfig_update_rgblight_default(void) { 199void eeconfig_update_rgblight_default(void) {
190 rgblight_config.enable = 1; 200 rgblight_config.enable = 1;
@@ -233,9 +243,7 @@ void rgblight_init(void) {
233 243
234 eeconfig_debug_rgblight(); // display current eeprom values 244 eeconfig_debug_rgblight(); // display current eeprom values
235 245
236#ifdef RGBLIGHT_USE_TIMER
237 rgblight_timer_init(); // setup the timer 246 rgblight_timer_init(); // setup the timer
238#endif
239 247
240 if (rgblight_config.enable) { 248 if (rgblight_config.enable) {
241 rgblight_mode_noeeprom(rgblight_config.mode); 249 rgblight_mode_noeeprom(rgblight_config.mode);
@@ -252,9 +260,7 @@ void rgblight_update_dword(uint32_t dword) {
252 if (rgblight_config.enable) 260 if (rgblight_config.enable)
253 rgblight_mode_noeeprom(rgblight_config.mode); 261 rgblight_mode_noeeprom(rgblight_config.mode);
254 else { 262 else {
255#ifdef RGBLIGHT_USE_TIMER
256 rgblight_timer_disable(); 263 rgblight_timer_disable();
257#endif
258 rgblight_set(); 264 rgblight_set();
259 } 265 }
260} 266}
@@ -322,13 +328,9 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
322 dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); 328 dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
323 } 329 }
324 if (is_static_effect(rgblight_config.mode)) { 330 if (is_static_effect(rgblight_config.mode)) {
325#ifdef RGBLIGHT_USE_TIMER
326 rgblight_timer_disable(); 331 rgblight_timer_disable();
327#endif
328 } else { 332 } else {
329#ifdef RGBLIGHT_USE_TIMER
330 rgblight_timer_enable(); 333 rgblight_timer_enable();
331#endif
332 } 334 }
333#ifdef RGBLIGHT_USE_TIMER 335#ifdef RGBLIGHT_USE_TIMER
334 animation_status.restart = true; 336 animation_status.restart = true;
@@ -376,9 +378,7 @@ void rgblight_disable(void) {
376 rgblight_config.enable = 0; 378 rgblight_config.enable = 0;
377 eeconfig_update_rgblight(rgblight_config.raw); 379 eeconfig_update_rgblight(rgblight_config.raw);
378 dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 380 dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
379#ifdef RGBLIGHT_USE_TIMER
380 rgblight_timer_disable(); 381 rgblight_timer_disable();
381#endif
382 RGBLIGHT_SPLIT_SET_CHANGE_MODE; 382 RGBLIGHT_SPLIT_SET_CHANGE_MODE;
383 wait_ms(50); 383 wait_ms(50);
384 rgblight_set(); 384 rgblight_set();
@@ -387,14 +387,14 @@ void rgblight_disable(void) {
387void rgblight_disable_noeeprom(void) { 387void rgblight_disable_noeeprom(void) {
388 rgblight_config.enable = 0; 388 rgblight_config.enable = 0;
389 dprintf("rgblight disable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); 389 dprintf("rgblight disable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
390#ifdef RGBLIGHT_USE_TIMER
391 rgblight_timer_disable(); 390 rgblight_timer_disable();
392#endif
393 RGBLIGHT_SPLIT_SET_CHANGE_MODE; 391 RGBLIGHT_SPLIT_SET_CHANGE_MODE;
394 wait_ms(50); 392 wait_ms(50);
395 rgblight_set(); 393 rgblight_set();
396} 394}
397 395
396bool rgblight_is_enabled(void) { return rgblight_config.enable; }
397
398void rgblight_increase_hue_helper(bool write_to_eeprom) { 398void rgblight_increase_hue_helper(bool write_to_eeprom) {
399 uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP; 399 uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP;
400 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom); 400 rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
@@ -431,17 +431,25 @@ void rgblight_decrease_val_helper(bool write_to_eeprom) {
431} 431}
432void rgblight_decrease_val_noeeprom(void) { rgblight_decrease_val_helper(false); } 432void rgblight_decrease_val_noeeprom(void) { rgblight_decrease_val_helper(false); }
433void rgblight_decrease_val(void) { rgblight_decrease_val_helper(true); } 433void rgblight_decrease_val(void) { rgblight_decrease_val_helper(true); }
434void rgblight_increase_speed(void) { 434
435void rgblight_increase_speed_helper(bool write_to_eeprom) {
435 if (rgblight_config.speed < 3) rgblight_config.speed++; 436 if (rgblight_config.speed < 3) rgblight_config.speed++;
436 // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED? 437 // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?
437 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this 438 if (write_to_eeprom) {
439 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this
440 }
438} 441}
439 442void rgblight_increase_speed(void) { rgblight_increase_speed_helper(true); }
440void rgblight_decrease_speed(void) { 443void rgblight_increase_speed_noeeprom(void) { rgblight_increase_speed_helper(false); }
444void rgblight_decrease_speed_helper(bool write_to_eeprom) {
441 if (rgblight_config.speed > 0) rgblight_config.speed--; 445 if (rgblight_config.speed > 0) rgblight_config.speed--;
442 // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?? 446 // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED??
443 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this 447 if (write_to_eeprom) {
448 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this
449 }
444} 450}
451void rgblight_decrease_speed(void) { rgblight_decrease_speed_helper(true); }
452void rgblight_decrease_speed_noeeprom(void) { rgblight_decrease_speed_helper(false); }
445 453
446void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) { 454void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
447 if (rgblight_config.enable) { 455 if (rgblight_config.enable) {
@@ -502,15 +510,15 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w
502# else 510# else
503 uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2]; 511 uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2];
504# endif 512# endif
505 for (uint8_t i = 0; i < effect_num_leds; i++) { 513 for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) {
506 uint8_t _hue = ((uint16_t)i * (uint16_t)range) / effect_num_leds; 514 uint8_t _hue = ((uint16_t)i * (uint16_t)range) / rgblight_ranges.effect_num_leds;
507 if (direction) { 515 if (direction) {
508 _hue = hue + _hue; 516 _hue = hue + _hue;
509 } else { 517 } else {
510 _hue = hue - _hue; 518 _hue = hue - _hue;
511 } 519 }
512 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range); 520 dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
513 sethsv(_hue, sat, val, (LED_TYPE *)&led[i + effect_start_pos]); 521 sethsv(_hue, sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]);
514 } 522 }
515 rgblight_set(); 523 rgblight_set();
516 } 524 }
@@ -542,7 +550,7 @@ uint8_t rgblight_get_speed(void) { return rgblight_config.speed; }
542void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { 550void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
543 rgblight_config.speed = speed; 551 rgblight_config.speed = speed;
544 if (write_to_eeprom) { 552 if (write_to_eeprom) {
545 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this 553 eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this
546 dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed); 554 dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed);
547 } else { 555 } else {
548 dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed); 556 dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed);
@@ -559,12 +567,14 @@ uint8_t rgblight_get_sat(void) { return rgblight_config.sat; }
559 567
560uint8_t rgblight_get_val(void) { return rgblight_config.val; } 568uint8_t rgblight_get_val(void) { return rgblight_config.val; }
561 569
570HSV rgblight_get_hsv(void) { return (HSV){rgblight_config.hue, rgblight_config.sat, rgblight_config.val}; }
571
562void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { 572void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
563 if (!rgblight_config.enable) { 573 if (!rgblight_config.enable) {
564 return; 574 return;
565 } 575 }
566 576
567 for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) { 577 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
568 led[i].r = r; 578 led[i].r = r;
569 led[i].g = g; 579 led[i].g = g;
570 led[i].b = b; 580 led[i].b = b;
@@ -599,7 +609,7 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
599 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); 609 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
600} 610}
601 611
602#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) 612#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)
603 613
604static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) { 614static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
605 return 615 return
@@ -648,13 +658,97 @@ void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_se
648void 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); } 658void 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); }
649#endif // ifndef RGBLIGHT_SPLIT 659#endif // ifndef RGBLIGHT_SPLIT
650 660
661#ifdef RGBLIGHT_LAYERS
662void rgblight_set_layer_state(uint8_t layer, bool enabled) {
663 rgblight_layer_mask_t mask = 1 << layer;
664 if (enabled) {
665 rgblight_status.enabled_layer_mask |= mask;
666 } else {
667 rgblight_status.enabled_layer_mask &= ~mask;
668 }
669 RGBLIGHT_SPLIT_SET_CHANGE_LAYERS;
670 // Static modes don't have a ticker running to update the LEDs
671 if (rgblight_status.timer_enabled == false) {
672 rgblight_mode_noeeprom(rgblight_config.mode);
673 }
674
675# ifdef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF
676 // If not enabled, then nothing else will actually set the LEDs...
677 if (!rgblight_config.enable) {
678 rgblight_set();
679 }
680# endif
681}
682
683bool rgblight_get_layer_state(uint8_t layer) {
684 rgblight_layer_mask_t mask = 1 << layer;
685 return (rgblight_status.enabled_layer_mask & mask) != 0;
686}
687
688// Write any enabled LED layers into the buffer
689static void rgblight_layers_write(void) {
690 uint8_t i = 0;
691 // For each layer
692 for (const rgblight_segment_t *const *layer_ptr = rgblight_layers; i < RGBLIGHT_MAX_LAYERS; layer_ptr++, i++) {
693 if (!rgblight_get_layer_state(i)) {
694 continue; // Layer is disabled
695 }
696 const rgblight_segment_t *segment_ptr = pgm_read_ptr(layer_ptr);
697 if (segment_ptr == NULL) {
698 break; // No more layers
699 }
700 // For each segment
701 while (1) {
702 rgblight_segment_t segment;
703 memcpy_P(&segment, segment_ptr, sizeof(rgblight_segment_t));
704 if (segment.index == RGBLIGHT_END_SEGMENT_INDEX) {
705 break; // No more segments
706 }
707 // Write segment.count LEDs
708 LED_TYPE *const limit = &led[MIN(segment.index + segment.count, RGBLED_NUM)];
709 for (LED_TYPE *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) {
710 sethsv(segment.hue, segment.sat, segment.val, led_ptr);
711 }
712 segment_ptr++;
713 }
714 }
715}
716
717# ifdef RGBLIGHT_LAYER_BLINK
718rgblight_layer_mask_t _blinked_layer_mask = 0;
719uint16_t _blink_duration = 0;
720static uint16_t _blink_timer;
721
722void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) {
723 rgblight_set_layer_state(layer, true);
724 _blinked_layer_mask |= 1 << layer;
725 _blink_timer = timer_read();
726 _blink_duration = duration_ms;
727}
728
729void rgblight_unblink_layers(void) {
730 if (_blinked_layer_mask != 0 && timer_elapsed(_blink_timer) > _blink_duration) {
731 for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) {
732 if ((_blinked_layer_mask & 1 << layer) != 0) {
733 rgblight_set_layer_state(layer, false);
734 }
735 }
736 _blinked_layer_mask = 0;
737 }
738}
739# endif
740
741#endif
742
743__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); }
744
651#ifndef RGBLIGHT_CUSTOM_DRIVER 745#ifndef RGBLIGHT_CUSTOM_DRIVER
652void rgblight_set(void) { 746void rgblight_set(void) {
653 LED_TYPE *start_led; 747 LED_TYPE *start_led;
654 uint16_t num_leds = clipping_num_leds; 748 uint8_t num_leds = rgblight_ranges.clipping_num_leds;
655 749
656 if (!rgblight_config.enable) { 750 if (!rgblight_config.enable) {
657 for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) { 751 for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
658 if (i == RGBLIGHT_FLED1 && i == RGBLIGHT_FLED2) 752 if (i == RGBLIGHT_FLED1 && i == RGBLIGHT_FLED2)
659 continue; 753 continue;
660 754
@@ -667,54 +761,63 @@ void rgblight_set(void) {
667 } 761 }
668 } 762 }
669 763
764# ifdef RGBLIGHT_LAYERS
765 if (rgblight_layers != NULL
766# ifndef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF
767 && rgblight_config.enable
768# endif
769 ) {
770 rgblight_layers_write();
771 }
772# endif
773
670# ifdef RGBLIGHT_LED_MAP 774# ifdef RGBLIGHT_LED_MAP
671 LED_TYPE led0[RGBLED_NUM]; 775 LED_TYPE led0[RGBLED_NUM];
672 for (uint8_t i = 0; i < RGBLED_NUM; i++) { 776 for (uint8_t i = 0; i < RGBLED_NUM; i++) {
673 led0[i] = led[pgm_read_byte(&led_map[i])]; 777 led0[i] = led[pgm_read_byte(&led_map[i])];
674 } 778 }
675 start_led = led0 + clipping_start_pos; 779 start_led = led0 + rgblight_ranges.clipping_start_pos;
676# else 780# else
677 start_led = led + clipping_start_pos; 781 start_led = led + rgblight_ranges.clipping_start_pos;
678# endif 782# endif
679 783
680#ifdef RGBW 784# ifdef RGBW
681 for (uint8_t i = 0; i < num_leds; i++) { 785 for (uint8_t i = 0; i < num_leds; i++) {
682 convert_rgb_to_rgbw(&start_led[i]); 786 convert_rgb_to_rgbw(&start_led[i]);
683 } 787 }
684#endif 788# endif
685 // MxSS custom 789 // MxSS custom
686 switch (fled_mode) { 790 switch (fled_mode) {
687 case FLED_OFF: 791 case FLED_OFF:
688 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
689 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
690 break;
691
692 case FLED_INDI:
693 copyrgb(&fleds[0], &led[RGBLIGHT_FLED1]);
694 copyrgb(&fleds[1], &led[RGBLIGHT_FLED2]);
695 break;
696
697 case FLED_RGB:
698 if (fled_hs[0].hue == 0 && fled_hs[0].hue == 0 &&
699 (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE ||
700 rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT))
701 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]); 792 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
702 else 793 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
703 sethsv(fled_hs[0].hue, fled_hs[0].sat, fled_val, &led[RGBLIGHT_FLED1]); 794 break;
795
796 case FLED_INDI:
797 copyrgb(&fleds[0], &led[RGBLIGHT_FLED1]);
798 copyrgb(&fleds[1], &led[RGBLIGHT_FLED2]);
799 break;
704 800
705 if (fled_hs[1].hue == 0 && fled_hs[1].hue == 0 && 801 case FLED_RGB:
802 if (fled_hs[0].hue == 0 && fled_hs[0].hue == 0 &&
706 (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE || 803 (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE ||
707 rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT)) 804 rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT))
708 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]); 805 setrgb(0, 0, 0, &led[RGBLIGHT_FLED1]);
709 else 806 else
710 sethsv(fled_hs[1].hue, fled_hs[1].sat, fled_val, &led[RGBLIGHT_FLED2]); 807 sethsv(fled_hs[0].hue, fled_hs[0].sat, fled_val, &led[RGBLIGHT_FLED1]);
711 break;
712 808
713 default: 809 if (fled_hs[1].hue == 0 && fled_hs[1].hue == 0 &&
714 break; 810 (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE ||
715 } 811 rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT))
812 setrgb(0, 0, 0, &led[RGBLIGHT_FLED2]);
813 else
814 sethsv(fled_hs[1].hue, fled_hs[1].sat, fled_val, &led[RGBLIGHT_FLED2]);
815 break;
816 default:
817 break;
818 }
716 819
717 ws2812_setleds(start_led, num_leds); 820 rgblight_call_driver(start_led, num_leds);
718} 821}
719#endif 822#endif
720 823
@@ -731,6 +834,11 @@ void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo) {
731 834
732/* for split keyboard slave side */ 835/* for split keyboard slave side */
733void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) { 836void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) {
837# ifdef RGBLIGHT_LAYERS
838 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_LAYERS) {
839 rgblight_status.enabled_layer_mask = syncinfo->status.enabled_layer_mask;
840 }
841# endif
734 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) { 842 if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) {
735 if (syncinfo->config.enable) { 843 if (syncinfo->config.enable) {
736 rgblight_config.enable = 1; // == rgblight_enable_noeeprom(); 844 rgblight_config.enable = 1; // == rgblight_enable_noeeprom();
@@ -893,6 +1001,12 @@ void rgblight_task(void) {
893 effect_func = (effect_func_t)rgblight_effect_alternating; 1001 effect_func = (effect_func_t)rgblight_effect_alternating;
894 } 1002 }
895# endif 1003# endif
1004# ifdef RGBLIGHT_EFFECT_TWINKLE
1005 else if (rgblight_status.base_mode == RGBLIGHT_MODE_TWINKLE) {
1006 interval_time = get_interval_time(&RGBLED_TWINKLE_INTERVALS[delta % 3], 5, 50);
1007 effect_func = (effect_func_t)rgblight_effect_twinkle;
1008 }
1009# endif
896 if (animation_status.restart) { 1010 if (animation_status.restart) {
897 animation_status.restart = false; 1011 animation_status.restart = false;
898 animation_status.last_timer = timer_read() - interval_time - 1; 1012 animation_status.last_timer = timer_read() - interval_time - 1;
@@ -922,6 +1036,10 @@ void rgblight_task(void) {
922# endif 1036# endif
923 } 1037 }
924 } 1038 }
1039
1040# ifdef RGBLIGHT_LAYER_BLINK
1041 rgblight_unblink_layers();
1042# endif
925} 1043}
926 1044
927#endif /* RGBLIGHT_USE_TIMER */ 1045#endif /* RGBLIGHT_USE_TIMER */
@@ -972,9 +1090,9 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
972 uint8_t hue; 1090 uint8_t hue;
973 uint8_t i; 1091 uint8_t i;
974 1092
975 for (i = 0; i < effect_num_leds; i++) { 1093 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
976 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / effect_num_leds * i + anim->current_hue); 1094 hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue);
977 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]); 1095 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]);
978 } 1096 }
979 rgblight_set(); 1097 rgblight_set();
980 1098
@@ -1002,7 +1120,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
1002# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) 1120# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1003 if (anim->pos == 0) { // restart signal 1121 if (anim->pos == 0) { // restart signal
1004 if (increment == 1) { 1122 if (increment == 1) {
1005 pos = effect_num_leds - 1; 1123 pos = rgblight_ranges.effect_num_leds - 1;
1006 } else { 1124 } else {
1007 pos = 0; 1125 pos = 0;
1008 } 1126 }
@@ -1014,8 +1132,8 @@ void rgblight_effect_snake(animation_status_t *anim) {
1014 fled_hs[0].hue = fled_hs[1].hue = 0; 1132 fled_hs[0].hue = fled_hs[1].hue = 0;
1015 fled_hs[0].sat = fled_hs[1].sat = 0; 1133 fled_hs[0].sat = fled_hs[1].sat = 0;
1016 1134
1017 for (i = 0; i < effect_num_leds; i++) { 1135 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1018 LED_TYPE *ledp = led + i + effect_start_pos; 1136 LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos;
1019 ledp->r = 0; 1137 ledp->r = 0;
1020 ledp->g = 0; 1138 ledp->g = 0;
1021 ledp->b = 0; 1139 ledp->b = 0;
@@ -1028,7 +1146,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
1028 k = k % RGBLED_NUM; 1146 k = k % RGBLED_NUM;
1029 } 1147 }
1030 if (k < 0) { 1148 if (k < 0) {
1031 k = k + effect_num_leds; 1149 k = k + rgblight_ranges.effect_num_leds;
1032 } 1150 }
1033 if (i == k) { 1151 if (i == k) {
1034 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp); 1152 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp);
@@ -1038,7 +1156,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
1038 rgblight_set(); 1156 rgblight_set();
1039 if (increment == 1) { 1157 if (increment == 1) {
1040 if (pos - 1 < 0) { 1158 if (pos - 1 < 0) {
1041 pos = effect_num_leds - 1; 1159 pos = rgblight_ranges.effect_num_leds - 1;
1042# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) 1160# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1043 anim->pos = 0; 1161 anim->pos = 0;
1044# endif 1162# endif
@@ -1049,7 +1167,7 @@ void rgblight_effect_snake(animation_status_t *anim) {
1049# endif 1167# endif
1050 } 1168 }
1051 } else { 1169 } else {
1052 pos = (pos + 1) % effect_num_leds; 1170 pos = (pos + 1) % rgblight_ranges.effect_num_leds;
1053# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) 1171# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
1054 anim->pos = pos; 1172 anim->pos = pos;
1055# endif 1173# endif
@@ -1075,7 +1193,7 @@ void rgblight_effect_knight(animation_status_t *anim) {
1075 } 1193 }
1076# endif 1194# endif
1077 // Set all the LEDs to 0 1195 // Set all the LEDs to 0
1078 for (i = effect_start_pos; i < effect_end_pos; i++) { 1196 for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) {
1079 led[i].r = 0; 1197 led[i].r = 0;
1080 led[i].g = 0; 1198 led[i].g = 0;
1081 led[i].b = 0; 1199 led[i].b = 0;
@@ -1085,7 +1203,7 @@ void rgblight_effect_knight(animation_status_t *anim) {
1085 } 1203 }
1086 // Determine which LEDs should be lit up 1204 // Determine which LEDs should be lit up
1087 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { 1205 for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
1088 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % effect_num_leds + effect_start_pos; 1206 cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos;
1089 1207
1090 if (i >= low_bound && i <= high_bound) { 1208 if (i >= low_bound && i <= high_bound) {
1091 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]); 1209 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
@@ -1124,16 +1242,39 @@ void rgblight_effect_knight(animation_status_t *anim) {
1124#endif 1242#endif
1125 1243
1126#ifdef RGBLIGHT_EFFECT_CHRISTMAS 1244#ifdef RGBLIGHT_EFFECT_CHRISTMAS
1127void rgblight_effect_christmas(animation_status_t *anim) { 1245# define CUBED(x) ((x) * (x) * (x))
1128 uint8_t hue;
1129 uint8_t i;
1130 1246
1131 anim->current_offset = (anim->current_offset + 1) % 2; 1247/**
1132 for (i = 0; i < effect_num_leds; i++) { 1248 * Christmas lights effect, with a smooth animation between red & green.
1133 hue = 0 + ((i / RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85; 1249 */
1134 sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + effect_start_pos]); 1250void rgblight_effect_christmas(animation_status_t *anim) {
1251 static int8_t increment = 1;
1252 const uint8_t max_pos = 32;
1253 const uint8_t hue_green = 85;
1254
1255 uint32_t xa;
1256 uint8_t hue, val;
1257 uint8_t i;
1258
1259 // The effect works by animating anim->pos from 0 to 32 and back to 0.
1260 // The pos is used in a cubic bezier formula to ease-in-out between red and green, leaving the interpolated colors visible as short as possible.
1261 xa = CUBED((uint32_t)anim->pos);
1262 hue = ((uint32_t)hue_green) * xa / (xa + CUBED((uint32_t)(max_pos - anim->pos)));
1263 // Additionally, these interpolated colors get shown with a slightly darker value, to make them less prominent than the main colors.
1264 val = 255 - (3 * (hue < hue_green / 2 ? hue : hue_green - hue) / 2);
1265
1266 for (i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1267 uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue;
1268 sethsv(local_hue, rgblight_config.sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]);
1135 } 1269 }
1136 rgblight_set(); 1270 rgblight_set();
1271
1272 if (anim->pos == 0) {
1273 increment = 1;
1274 } else if (anim->pos == max_pos) {
1275 increment = -1;
1276 }
1277 anim->pos += increment;
1137} 1278}
1138#endif 1279#endif
1139 1280
@@ -1183,11 +1324,11 @@ void rgblight_effect_rgbtest(animation_status_t *anim) {
1183 1324
1184#ifdef RGBLIGHT_EFFECT_ALTERNATING 1325#ifdef RGBLIGHT_EFFECT_ALTERNATING
1185void rgblight_effect_alternating(animation_status_t *anim) { 1326void rgblight_effect_alternating(animation_status_t *anim) {
1186 for (int i = 0; i < effect_num_leds; i++) { 1327 for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1187 LED_TYPE *ledp = led + i + effect_start_pos; 1328 LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos;
1188 if (i < effect_num_leds / 2 && anim->pos) { 1329 if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) {
1189 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); 1330 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
1190 } else if (i >= effect_num_leds / 2 && !anim->pos) { 1331 } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) {
1191 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); 1332 sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp);
1192 } else { 1333 } else {
1193 sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp); 1334 sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp);
@@ -1197,3 +1338,58 @@ void rgblight_effect_alternating(animation_status_t *anim) {
1197 anim->pos = (anim->pos + 1) % 2; 1338 anim->pos = (anim->pos + 1) % 2;
1198} 1339}
1199#endif 1340#endif
1341
1342#ifdef RGBLIGHT_EFFECT_TWINKLE
1343__attribute__((weak)) const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {50, 25, 10};
1344
1345typedef struct PACKED {
1346 HSV hsv;
1347 uint8_t life;
1348 bool up;
1349} TwinkleState;
1350
1351static TwinkleState led_twinkle_state[RGBLED_NUM];
1352
1353void rgblight_effect_twinkle(animation_status_t *anim) {
1354 bool random_color = anim->delta / 3;
1355 bool restart = anim->pos == 0;
1356 anim->pos = 1;
1357
1358 for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1359 TwinkleState *t = &(led_twinkle_state[i]);
1360 HSV * c = &(t->hsv);
1361 if (restart) {
1362 // Restart
1363 t->life = 0;
1364 t->hsv.v = 0;
1365 } else if (t->life) {
1366 // This LED is already on, either brightening or dimming
1367 t->life--;
1368 uint8_t on = t->up ? RGBLIGHT_EFFECT_TWINKLE_LIFE - t->life : t->life;
1369 c->v = (uint16_t)rgblight_config.val * on / RGBLIGHT_EFFECT_TWINKLE_LIFE;
1370 if (t->life == 0 && t->up) {
1371 t->up = false;
1372 t->life = RGBLIGHT_EFFECT_TWINKLE_LIFE;
1373 }
1374 if (!random_color) {
1375 c->h = rgblight_config.hue;
1376 c->s = rgblight_config.sat;
1377 }
1378 } else if (rand() < RAND_MAX * RGBLIGHT_EFFECT_TWINKLE_PROBABILITY) {
1379 // This LED is off, but was randomly selected to start brightening
1380 c->h = random_color ? rand() % 0xFF : rgblight_config.hue;
1381 c->s = random_color ? (rand() % (rgblight_config.sat / 2)) + (rgblight_config.sat / 2) : rgblight_config.sat;
1382 c->v = 0;
1383 t->life = RGBLIGHT_EFFECT_TWINKLE_LIFE;
1384 t->up = true;
1385 } else {
1386 // This LED is off, and was NOT selected to start brightening
1387 }
1388
1389 LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos;
1390 sethsv(c->h, c->s, c->v, ledp);
1391 }
1392
1393 rgblight_set();
1394}
1395#endif
diff --git a/keyboards/mxss/rgblight.h b/keyboards/mxss/rgblight.h
deleted file mode 100644
index 21eff627d..000000000
--- a/keyboards/mxss/rgblight.h
+++ /dev/null
@@ -1,358 +0,0 @@
1/* Copyright 2017 Yang Liu
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#ifndef RGBLIGHT_H
17#define RGBLIGHT_H
18
19/***** rgblight_mode(mode)/rgblight_mode_noeeprom(mode) ****
20
21 old mode number (before 0.6.117) to new mode name table
22
23|-----------------|-----------------------------------|
24| old mode number | new mode name |
25|-----------------|-----------------------------------|
26| 1 | RGBLIGHT_MODE_STATIC_LIGHT |
27| 2 | RGBLIGHT_MODE_BREATHING |
28| 3 | RGBLIGHT_MODE_BREATHING + 1 |
29| 4 | RGBLIGHT_MODE_BREATHING + 2 |
30| 5 | RGBLIGHT_MODE_BREATHING + 3 |
31| 6 | RGBLIGHT_MODE_RAINBOW_MOOD |
32| 7 | RGBLIGHT_MODE_RAINBOW_MOOD + 1 |
33| 8 | RGBLIGHT_MODE_RAINBOW_MOOD + 2 |
34| 9 | RGBLIGHT_MODE_RAINBOW_SWIRL |
35| 10 | RGBLIGHT_MODE_RAINBOW_SWIRL + 1 |
36| 11 | RGBLIGHT_MODE_RAINBOW_SWIRL + 2 |
37| 12 | RGBLIGHT_MODE_RAINBOW_SWIRL + 3 |
38| 13 | RGBLIGHT_MODE_RAINBOW_SWIRL + 4 |
39| 14 | RGBLIGHT_MODE_RAINBOW_SWIRL + 5 |
40| 15 | RGBLIGHT_MODE_SNAKE |
41| 16 | RGBLIGHT_MODE_SNAKE + 1 |
42| 17 | RGBLIGHT_MODE_SNAKE + 2 |
43| 18 | RGBLIGHT_MODE_SNAKE + 3 |
44| 19 | RGBLIGHT_MODE_SNAKE + 4 |
45| 20 | RGBLIGHT_MODE_SNAKE + 5 |
46| 21 | RGBLIGHT_MODE_KNIGHT |
47| 22 | RGBLIGHT_MODE_KNIGHT + 1 |
48| 23 | RGBLIGHT_MODE_KNIGHT + 2 |
49| 24 | RGBLIGHT_MODE_CHRISTMAS |
50| 25 | RGBLIGHT_MODE_STATIC_GRADIENT |
51| 26 | RGBLIGHT_MODE_STATIC_GRADIENT + 1 |
52| 27 | RGBLIGHT_MODE_STATIC_GRADIENT + 2 |
53| 28 | RGBLIGHT_MODE_STATIC_GRADIENT + 3 |
54| 29 | RGBLIGHT_MODE_STATIC_GRADIENT + 4 |
55| 30 | RGBLIGHT_MODE_STATIC_GRADIENT + 5 |
56| 31 | RGBLIGHT_MODE_STATIC_GRADIENT + 6 |
57| 32 | RGBLIGHT_MODE_STATIC_GRADIENT + 7 |
58| 33 | RGBLIGHT_MODE_STATIC_GRADIENT + 8 |
59| 34 | RGBLIGHT_MODE_STATIC_GRADIENT + 9 |
60| 35 | RGBLIGHT_MODE_RGB_TEST |
61| 36 | RGBLIGHT_MODE_ALTERNATING |
62|-----------------|-----------------------------------|
63 *****/
64
65#ifdef RGBLIGHT_ANIMATIONS
66// for backward compatibility
67# define RGBLIGHT_EFFECT_BREATHING
68# define RGBLIGHT_EFFECT_RAINBOW_MOOD
69# define RGBLIGHT_EFFECT_RAINBOW_SWIRL
70# define RGBLIGHT_EFFECT_SNAKE
71# define RGBLIGHT_EFFECT_KNIGHT
72# define RGBLIGHT_EFFECT_CHRISTMAS
73# define RGBLIGHT_EFFECT_STATIC_GRADIENT
74# define RGBLIGHT_EFFECT_RGB_TEST
75# define RGBLIGHT_EFFECT_ALTERNATING
76#endif
77
78#ifdef RGBLIGHT_STATIC_PATTERNS
79# define RGBLIGHT_EFFECT_STATIC_GRADIENT
80#endif
81
82// clang-format off
83
84// check dynamic animation effects chose ?
85#if defined(RGBLIGHT_EFFECT_BREATHING) \
86 || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) \
87 || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) \
88 || defined(RGBLIGHT_EFFECT_SNAKE) \
89 || defined(RGBLIGHT_EFFECT_KNIGHT) \
90 || defined(RGBLIGHT_EFFECT_CHRISTMAS) \
91 || defined(RGBLIGHT_EFFECT_RGB_TEST) \
92 || defined(RGBLIGHT_EFFECT_ALTERNATING)
93# define RGBLIGHT_USE_TIMER
94#endif
95
96// clang-format on
97
98#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym,
99#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym,
100#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym,
101#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym,
102#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym,
103#define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##sym,
104enum RGBLIGHT_EFFECT_MODE {
105 RGBLIGHT_MODE_zero = 0,
106#include "rgblight_modes.h"
107 RGBLIGHT_MODE_last
108};
109
110#ifndef RGBLIGHT_H_DUMMY_DEFINE
111
112# define RGBLIGHT_MODES (RGBLIGHT_MODE_last - 1)
113
114// sample: #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85
115
116# ifndef RGBLIGHT_EFFECT_BREATHE_MAX
117# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255
118# endif
119
120# ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH
121# define RGBLIGHT_EFFECT_SNAKE_LENGTH 4
122# endif
123
124# ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH
125# define RGBLIGHT_EFFECT_KNIGHT_LENGTH 3
126# endif
127
128# ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET
129# define RGBLIGHT_EFFECT_KNIGHT_OFFSET 0
130# endif
131
132# ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM
133# define RGBLIGHT_EFFECT_KNIGHT_LED_NUM (effect_num_leds)
134# endif
135
136# ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL
137# define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 1000
138# endif
139
140# ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP
141# define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2
142# endif
143
144# ifndef RGBLIGHT_HUE_STEP
145# define RGBLIGHT_HUE_STEP 8
146# endif
147# ifndef RGBLIGHT_SAT_STEP
148# define RGBLIGHT_SAT_STEP 17
149# endif
150# ifndef RGBLIGHT_VAL_STEP
151# define RGBLIGHT_VAL_STEP 17
152# endif
153# ifndef RGBLIGHT_LIMIT_VAL
154# define RGBLIGHT_LIMIT_VAL 255
155# endif
156
157# define RGBLED_TIMER_TOP F_CPU / (256 * 64)
158// #define RGBLED_TIMER_TOP 0xFF10
159
160# include <stdint.h>
161# include <stdbool.h>
162# include "eeconfig.h"
163# ifndef RGBLIGHT_CUSTOM_DRIVER
164# include "ws2812.h"
165# endif
166# include "color.h"
167# include "rgblight_list.h"
168
169# if defined(__AVR__)
170# include <avr/pgmspace.h>
171# endif
172
173extern LED_TYPE led[RGBLED_NUM];
174
175extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM;
176extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM;
177extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM;
178extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM;
179extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM;
180extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM;
181extern bool is_rgblight_initialized;
182
183// Should stay in sycn with rgb matrix config as we reuse eeprom storage for both (for now)
184typedef union {
185 uint32_t raw;
186 struct {
187 bool enable : 1;
188 uint8_t mode : 7;
189 uint8_t hue : 8;
190 uint8_t sat : 8;
191 uint8_t val : 8;
192 uint8_t speed : 8; // EECONFIG needs to be increased to support this
193 };
194} rgblight_config_t;
195
196typedef struct _rgblight_status_t {
197 uint8_t base_mode;
198 bool timer_enabled;
199# ifdef RGBLIGHT_SPLIT
200 uint8_t change_flags;
201# endif
202} rgblight_status_t;
203
204/* === Utility Functions ===*/
205void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1);
206void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); // without RGBLIGHT_LIMIT_VAL check
207void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1);
208
209/* === Low level Functions === */
210void rgblight_set(void);
211void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
212
213/* === Effects and Animations Functions === */
214/* effect range setting */
215void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds);
216
217/* direct operation */
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(uint8_t r, uint8_t g, uint8_t b);
223
224# ifndef RGBLIGHT_SPLIT
225void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
226void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
227void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val);
228void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val);
229# endif
230
231/* effect mode change */
232void rgblight_mode(uint8_t mode);
233void rgblight_mode_noeeprom(uint8_t mode);
234void rgblight_increase(void);
235void rgblight_decrease(void);
236void rgblight_step(void);
237void rgblight_step_noeeprom(void);
238void rgblight_step_reverse(void);
239void rgblight_step_reverse_noeeprom(void);
240
241/* effects mode disable/enable */
242void rgblight_toggle(void);
243void rgblight_toggle_noeeprom(void);
244void rgblight_enable(void);
245void rgblight_enable_noeeprom(void);
246void rgblight_disable(void);
247void rgblight_disable_noeeprom(void);
248
249/* hue, sat, val change */
250void rgblight_increase_hue(void);
251void rgblight_increase_hue_noeeprom(void);
252void rgblight_decrease_hue(void);
253void rgblight_decrease_hue_noeeprom(void);
254void rgblight_increase_sat(void);
255void rgblight_increase_sat_noeeprom(void);
256void rgblight_decrease_sat(void);
257void rgblight_decrease_sat_noeeprom(void);
258void rgblight_increase_val(void);
259void rgblight_increase_val_noeeprom(void);
260void rgblight_decrease_val(void);
261void rgblight_decrease_val_noeeprom(void);
262void rgblight_increase_speed(void);
263void rgblight_decrease_speed(void);
264void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val);
265void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val);
266
267/* effect speed */
268uint8_t rgblight_get_speed(void);
269void rgblight_set_speed(uint8_t speed);
270void rgblight_set_speed_noeeprom(uint8_t speed);
271
272/* query */
273uint8_t rgblight_get_mode(void);
274uint8_t rgblight_get_hue(void);
275uint8_t rgblight_get_sat(void);
276uint8_t rgblight_get_val(void);
277
278/* === qmk_firmware (core)internal Functions === */
279void rgblight_init(void);
280uint32_t rgblight_read_dword(void);
281void rgblight_update_dword(uint32_t dword);
282uint32_t eeconfig_read_rgblight(void);
283void eeconfig_update_rgblight(uint32_t val);
284void eeconfig_update_rgblight_current(void);
285void eeconfig_update_rgblight_default(void);
286void eeconfig_debug_rgblight(void);
287
288void rgb_matrix_increase(void);
289void rgb_matrix_decrease(void);
290
291void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom);
292void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom);
293
294# define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF)
295void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b);
296
297# ifdef RGBLIGHT_USE_TIMER
298void rgblight_task(void);
299void rgblight_timer_init(void);
300void rgblight_timer_enable(void);
301void rgblight_timer_disable(void);
302void rgblight_timer_toggle(void);
303# else
304# define rgblight_task()
305# define rgblight_timer_init()
306# define rgblight_timer_enable()
307# define rgblight_timer_disable()
308# define rgblight_timer_toggle()
309# endif
310
311# ifdef RGBLIGHT_SPLIT
312# define RGBLIGHT_STATUS_CHANGE_MODE (1 << 0)
313# define RGBLIGHT_STATUS_CHANGE_HSVS (1 << 1)
314# define RGBLIGHT_STATUS_CHANGE_TIMER (1 << 2)
315# define RGBLIGHT_STATUS_ANIMATION_TICK (1 << 3)
316
317typedef struct _rgblight_syncinfo_t {
318 rgblight_config_t config;
319 rgblight_status_t status;
320} rgblight_syncinfo_t;
321
322/* for split keyboard master side */
323uint8_t rgblight_get_change_flags(void);
324void rgblight_clear_change_flags(void);
325void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo);
326/* for split keyboard slave side */
327void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom);
328# endif
329
330# ifdef RGBLIGHT_USE_TIMER
331
332typedef struct _animation_status_t {
333 uint16_t last_timer;
334 uint8_t delta; /* mode - base_mode */
335 bool restart;
336 union {
337 uint16_t pos16;
338 uint8_t pos;
339 int8_t current_hue;
340 uint16_t current_offset;
341 };
342} animation_status_t;
343
344extern animation_status_t animation_status;
345
346void rgblight_effect_breathing(animation_status_t *anim);
347void rgblight_effect_rainbow_mood(animation_status_t *anim);
348void rgblight_effect_rainbow_swirl(animation_status_t *anim);
349void rgblight_effect_snake(animation_status_t *anim);
350void rgblight_effect_knight(animation_status_t *anim);
351void rgblight_effect_christmas(animation_status_t *anim);
352void rgblight_effect_rgbtest(animation_status_t *anim);
353void rgblight_effect_alternating(animation_status_t *anim);
354
355# endif
356
357#endif // #ifndef RGBLIGHT_H_DUMMY_DEFINE
358#endif // RGBLIGHT_H