aboutsummaryrefslogtreecommitdiff
path: root/quantum/rgblight.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/rgblight.c')
-rw-r--r--quantum/rgblight.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 33326fa86..8d01bcf0e 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -15,6 +15,7 @@
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>
@@ -561,7 +562,7 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
561 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); 562 rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
562} 563}
563 564
564#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) 565#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)
565 566
566static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) { 567static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
567 return 568 return
@@ -905,6 +906,12 @@ void rgblight_task(void) {
905 effect_func = (effect_func_t)rgblight_effect_alternating; 906 effect_func = (effect_func_t)rgblight_effect_alternating;
906 } 907 }
907# endif 908# endif
909# ifdef RGBLIGHT_EFFECT_TWINKLE
910 else if (rgblight_status.base_mode == RGBLIGHT_MODE_TWINKLE) {
911 interval_time = get_interval_time(&RGBLED_TWINKLE_INTERVALS[delta % 3], 5, 50);
912 effect_func = (effect_func_t)rgblight_effect_twinkle;
913 }
914# endif
908 if (animation_status.restart) { 915 if (animation_status.restart) {
909 animation_status.restart = false; 916 animation_status.restart = false;
910 animation_status.last_timer = timer_read() - interval_time - 1; 917 animation_status.last_timer = timer_read() - interval_time - 1;
@@ -1189,3 +1196,59 @@ void rgblight_effect_alternating(animation_status_t *anim) {
1189 anim->pos = (anim->pos + 1) % 2; 1196 anim->pos = (anim->pos + 1) % 2;
1190} 1197}
1191#endif 1198#endif
1199
1200#ifdef RGBLIGHT_EFFECT_TWINKLE
1201__attribute__((weak)) const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {50, 25, 10};
1202
1203typedef struct PACKED {
1204 HSV hsv;
1205 uint8_t life;
1206 bool up;
1207} TwinkleState;
1208
1209static TwinkleState led_twinkle_state[RGBLED_NUM];
1210
1211void rgblight_effect_twinkle(animation_status_t *anim) {
1212
1213 bool random_color = anim->delta / 3;
1214 bool restart = anim->pos == 0;
1215 anim->pos = 1;
1216
1217 for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) {
1218 TwinkleState *t = &(led_twinkle_state[i]);
1219 HSV *c = &(t->hsv);
1220 if (restart) {
1221 // Restart
1222 t->life = 0;
1223 t->hsv.v = 0;
1224 } else if (t->life) {
1225 // This LED is already on, either brightening or dimming
1226 t->life--;
1227 uint8_t on = t->up ? RGBLIGHT_EFFECT_TWINKLE_LIFE - t->life : t->life;
1228 c->v = (uint16_t) rgblight_config.val * on / RGBLIGHT_EFFECT_TWINKLE_LIFE;
1229 if (t->life == 0 && t->up) {
1230 t->up = false;
1231 t->life = RGBLIGHT_EFFECT_TWINKLE_LIFE;
1232 }
1233 if (!random_color) {
1234 c->h = rgblight_config.hue;
1235 c->s = rgblight_config.sat;
1236 }
1237 } else if (rand() < RAND_MAX * RGBLIGHT_EFFECT_TWINKLE_PROBABILITY) {
1238 // This LED is off, but was randomly selected to start brightening
1239 c->h = random_color ? rand() % 0xFF : rgblight_config.hue;
1240 c->s = random_color ? (rand() % (rgblight_config.sat / 2)) + (rgblight_config.sat / 2) : rgblight_config.sat;
1241 c->v = 0;
1242 t->life = RGBLIGHT_EFFECT_TWINKLE_LIFE;
1243 t->up = true;
1244 } else {
1245 // This LED is off, and was NOT selected to start brightening
1246 }
1247
1248 LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos;
1249 sethsv(c->h, c->s, c->v, ledp);
1250 }
1251
1252 rgblight_set();
1253}
1254#endif