diff options
Diffstat (limited to 'quantum/rgblight')
| -rw-r--r-- | quantum/rgblight/rgblight.c | 1390 | ||||
| -rw-r--r-- | quantum/rgblight/rgblight.h | 434 | ||||
| -rw-r--r-- | quantum/rgblight/rgblight_breathe_table.h | 117 | ||||
| -rw-r--r-- | quantum/rgblight/rgblight_list.h | 136 | ||||
| -rw-r--r-- | quantum/rgblight/rgblight_modes.h | 75 | ||||
| -rw-r--r-- | quantum/rgblight/rgblight_post_config.h | 5 |
6 files changed, 2157 insertions, 0 deletions
diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c new file mode 100644 index 000000000..148dae78f --- /dev/null +++ b/quantum/rgblight/rgblight.c | |||
| @@ -0,0 +1,1390 @@ | |||
| 1 | /* Copyright 2016-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 | #include <math.h> | ||
| 17 | #include <string.h> | ||
| 18 | #include <stdlib.h> | ||
| 19 | #include "wait.h" | ||
| 20 | #include "progmem.h" | ||
| 21 | #include "sync_timer.h" | ||
| 22 | #include "rgblight.h" | ||
| 23 | #include "color.h" | ||
| 24 | #include "debug.h" | ||
| 25 | #include "led_tables.h" | ||
| 26 | #include <lib/lib8tion/lib8tion.h> | ||
| 27 | #ifdef EEPROM_ENABLE | ||
| 28 | # include "eeprom.h" | ||
| 29 | #endif | ||
| 30 | #ifdef VELOCIKEY_ENABLE | ||
| 31 | # include "velocikey.h" | ||
| 32 | #endif | ||
| 33 | |||
| 34 | #ifndef MIN | ||
| 35 | # define MIN(a, b) (((a) < (b)) ? (a) : (b)) | ||
| 36 | #endif | ||
| 37 | #ifndef MAX | ||
| 38 | # define MAX(a, b) (((a) > (b)) ? (a) : (b)) | ||
| 39 | #endif | ||
| 40 | |||
| 41 | #ifdef RGBLIGHT_SPLIT | ||
| 42 | /* for split keyboard */ | ||
| 43 | # 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 | ||
| 45 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE | RGBLIGHT_STATUS_CHANGE_HSVS) | ||
| 46 | # define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_LAYERS | ||
| 47 | # define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER | ||
| 48 | # define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK | ||
| 49 | #else | ||
| 50 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODE | ||
| 51 | # define RGBLIGHT_SPLIT_SET_CHANGE_HSVS | ||
| 52 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS | ||
| 53 | # define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS | ||
| 54 | # define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE | ||
| 55 | # define RGBLIGHT_SPLIT_ANIMATION_TICK | ||
| 56 | #endif | ||
| 57 | |||
| 58 | #define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym, | ||
| 59 | #define _RGBM_SINGLE_DYNAMIC(sym) | ||
| 60 | #define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym, | ||
| 61 | #define _RGBM_MULTI_DYNAMIC(sym) | ||
| 62 | #define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym, | ||
| 63 | #define _RGBM_TMP_DYNAMIC(sym, msym) | ||
| 64 | static uint8_t static_effect_table[] = { | ||
| 65 | #include "rgblight_modes.h" | ||
| 66 | }; | ||
| 67 | |||
| 68 | #define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym, | ||
| 69 | #define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym, | ||
| 70 | #define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym, | ||
| 71 | #define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym, | ||
| 72 | #define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##msym, | ||
| 73 | #define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##msym, | ||
| 74 | static uint8_t mode_base_table[] = { | ||
| 75 | 0, // RGBLIGHT_MODE_zero | ||
| 76 | #include "rgblight_modes.h" | ||
| 77 | }; | ||
| 78 | |||
| 79 | #if !defined(RGBLIGHT_DEFAULT_MODE) | ||
| 80 | # define RGBLIGHT_DEFAULT_MODE RGBLIGHT_MODE_STATIC_LIGHT | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #if !defined(RGBLIGHT_DEFAULT_HUE) | ||
| 84 | # define RGBLIGHT_DEFAULT_HUE 0 | ||
| 85 | #endif | ||
| 86 | |||
| 87 | #if !defined(RGBLIGHT_DEFAULT_SAT) | ||
| 88 | # define RGBLIGHT_DEFAULT_SAT UINT8_MAX | ||
| 89 | #endif | ||
| 90 | |||
| 91 | #if !defined(RGBLIGHT_DEFAULT_VAL) | ||
| 92 | # define RGBLIGHT_DEFAULT_VAL RGBLIGHT_LIMIT_VAL | ||
| 93 | #endif | ||
| 94 | |||
| 95 | #if !defined(RGBLIGHT_DEFAULT_SPD) | ||
| 96 | # define RGBLIGHT_DEFAULT_SPD 0 | ||
| 97 | #endif | ||
| 98 | |||
| 99 | static inline int is_static_effect(uint8_t mode) { return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL; } | ||
| 100 | |||
| 101 | #ifdef RGBLIGHT_LED_MAP | ||
| 102 | const uint8_t led_map[] PROGMEM = RGBLIGHT_LED_MAP; | ||
| 103 | #endif | ||
| 104 | |||
| 105 | #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT | ||
| 106 | __attribute__((weak)) const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64}; | ||
| 107 | #endif | ||
| 108 | |||
| 109 | rgblight_config_t rgblight_config; | ||
| 110 | rgblight_status_t rgblight_status = {.timer_enabled = false}; | ||
| 111 | bool is_rgblight_initialized = false; | ||
| 112 | |||
| 113 | #ifdef RGBLIGHT_SLEEP | ||
| 114 | static bool is_suspended; | ||
| 115 | static bool pre_suspend_enabled; | ||
| 116 | #endif | ||
| 117 | |||
| 118 | #ifdef RGBLIGHT_USE_TIMER | ||
| 119 | animation_status_t animation_status = {}; | ||
| 120 | #endif | ||
| 121 | |||
| 122 | #ifndef LED_ARRAY | ||
| 123 | LED_TYPE led[RGBLED_NUM]; | ||
| 124 | # define LED_ARRAY led | ||
| 125 | #endif | ||
| 126 | |||
| 127 | #ifdef RGBLIGHT_LAYERS | ||
| 128 | rgblight_segment_t const *const *rgblight_layers = NULL; | ||
| 129 | #endif | ||
| 130 | |||
| 131 | rgblight_ranges_t rgblight_ranges = {0, RGBLED_NUM, 0, RGBLED_NUM, RGBLED_NUM}; | ||
| 132 | |||
| 133 | void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) { | ||
| 134 | rgblight_ranges.clipping_start_pos = start_pos; | ||
| 135 | rgblight_ranges.clipping_num_leds = num_leds; | ||
| 136 | } | ||
| 137 | |||
| 138 | void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) { | ||
| 139 | if (start_pos >= RGBLED_NUM) return; | ||
| 140 | if (start_pos + num_leds > RGBLED_NUM) return; | ||
| 141 | rgblight_ranges.effect_start_pos = start_pos; | ||
| 142 | rgblight_ranges.effect_end_pos = start_pos + num_leds; | ||
| 143 | rgblight_ranges.effect_num_leds = num_leds; | ||
| 144 | } | ||
| 145 | |||
| 146 | __attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) { return hsv_to_rgb(hsv); } | ||
| 147 | |||
| 148 | void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { | ||
| 149 | HSV hsv = {hue, sat, val}; | ||
| 150 | RGB rgb = rgblight_hsv_to_rgb(hsv); | ||
| 151 | setrgb(rgb.r, rgb.g, rgb.b, led1); | ||
| 152 | } | ||
| 153 | |||
| 154 | 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); } | ||
| 155 | |||
| 156 | void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) { | ||
| 157 | led1->r = r; | ||
| 158 | led1->g = g; | ||
| 159 | led1->b = b; | ||
| 160 | #ifdef RGBW | ||
| 161 | led1->w = 0; | ||
| 162 | #endif | ||
| 163 | } | ||
| 164 | |||
| 165 | void rgblight_check_config(void) { | ||
| 166 | /* Add some out of bound checks for RGB light config */ | ||
| 167 | |||
| 168 | if (rgblight_config.mode < RGBLIGHT_MODE_STATIC_LIGHT) { | ||
| 169 | rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT; | ||
| 170 | } else if (rgblight_config.mode > RGBLIGHT_MODES) { | ||
| 171 | rgblight_config.mode = RGBLIGHT_MODES; | ||
| 172 | } | ||
| 173 | |||
| 174 | if (rgblight_config.val > RGBLIGHT_LIMIT_VAL) { | ||
| 175 | rgblight_config.val = RGBLIGHT_LIMIT_VAL; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | uint32_t eeconfig_read_rgblight(void) { | ||
| 180 | #ifdef EEPROM_ENABLE | ||
| 181 | return eeprom_read_dword(EECONFIG_RGBLIGHT); | ||
| 182 | #else | ||
| 183 | return 0; | ||
| 184 | #endif | ||
| 185 | } | ||
| 186 | |||
| 187 | void eeconfig_update_rgblight(uint32_t val) { | ||
| 188 | #ifdef EEPROM_ENABLE | ||
| 189 | rgblight_check_config(); | ||
| 190 | eeprom_update_dword(EECONFIG_RGBLIGHT, val); | ||
| 191 | #endif | ||
| 192 | } | ||
| 193 | |||
| 194 | void eeconfig_update_rgblight_current(void) { eeconfig_update_rgblight(rgblight_config.raw); } | ||
| 195 | |||
| 196 | void eeconfig_update_rgblight_default(void) { | ||
| 197 | rgblight_config.enable = 1; | ||
| 198 | rgblight_config.mode = RGBLIGHT_DEFAULT_MODE; | ||
| 199 | rgblight_config.hue = RGBLIGHT_DEFAULT_HUE; | ||
| 200 | rgblight_config.sat = RGBLIGHT_DEFAULT_SAT; | ||
| 201 | rgblight_config.val = RGBLIGHT_DEFAULT_VAL; | ||
| 202 | rgblight_config.speed = RGBLIGHT_DEFAULT_SPD; | ||
| 203 | RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; | ||
| 204 | eeconfig_update_rgblight(rgblight_config.raw); | ||
| 205 | } | ||
| 206 | |||
| 207 | void eeconfig_debug_rgblight(void) { | ||
| 208 | dprintf("rgblight_config EEPROM:\n"); | ||
| 209 | dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); | ||
| 210 | dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); | ||
| 211 | dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); | ||
| 212 | dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); | ||
| 213 | dprintf("rgblight_config.val = %d\n", rgblight_config.val); | ||
| 214 | dprintf("rgblight_config.speed = %d\n", rgblight_config.speed); | ||
| 215 | } | ||
| 216 | |||
| 217 | void rgblight_init(void) { | ||
| 218 | /* if already initialized, don't do it again. | ||
| 219 | If you must do it again, extern this and set to false, first. | ||
| 220 | This is a dirty, dirty hack until proper hooks can be added for keyboard startup. */ | ||
| 221 | if (is_rgblight_initialized) { | ||
| 222 | return; | ||
| 223 | } | ||
| 224 | |||
| 225 | dprintf("rgblight_init called.\n"); | ||
| 226 | dprintf("rgblight_init start!\n"); | ||
| 227 | if (!eeconfig_is_enabled()) { | ||
| 228 | dprintf("rgblight_init eeconfig is not enabled.\n"); | ||
| 229 | eeconfig_init(); | ||
| 230 | eeconfig_update_rgblight_default(); | ||
| 231 | } | ||
| 232 | rgblight_config.raw = eeconfig_read_rgblight(); | ||
| 233 | RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; | ||
| 234 | if (!rgblight_config.mode) { | ||
| 235 | dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); | ||
| 236 | eeconfig_update_rgblight_default(); | ||
| 237 | rgblight_config.raw = eeconfig_read_rgblight(); | ||
| 238 | } | ||
| 239 | rgblight_check_config(); | ||
| 240 | |||
| 241 | eeconfig_debug_rgblight(); // display current eeprom values | ||
| 242 | |||
| 243 | rgblight_timer_init(); // setup the timer | ||
| 244 | |||
| 245 | if (rgblight_config.enable) { | ||
| 246 | rgblight_mode_noeeprom(rgblight_config.mode); | ||
| 247 | } | ||
| 248 | |||
| 249 | is_rgblight_initialized = true; | ||
| 250 | } | ||
| 251 | |||
| 252 | void rgblight_reload_from_eeprom(void) { | ||
| 253 | /* Reset back to what we have in eeprom */ | ||
| 254 | rgblight_config.raw = eeconfig_read_rgblight(); | ||
| 255 | RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; | ||
| 256 | rgblight_check_config(); | ||
| 257 | eeconfig_debug_rgblight(); // display current eeprom values | ||
| 258 | if (rgblight_config.enable) { | ||
| 259 | rgblight_mode_noeeprom(rgblight_config.mode); | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | uint32_t rgblight_read_dword(void) { return rgblight_config.raw; } | ||
| 264 | |||
| 265 | void rgblight_update_dword(uint32_t dword) { | ||
| 266 | RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; | ||
| 267 | rgblight_config.raw = dword; | ||
| 268 | if (rgblight_config.enable) | ||
| 269 | rgblight_mode_noeeprom(rgblight_config.mode); | ||
| 270 | else { | ||
| 271 | rgblight_timer_disable(); | ||
| 272 | rgblight_set(); | ||
| 273 | } | ||
| 274 | } | ||
| 275 | |||
| 276 | void rgblight_increase(void) { | ||
| 277 | uint8_t mode = 0; | ||
| 278 | if (rgblight_config.mode < RGBLIGHT_MODES) { | ||
| 279 | mode = rgblight_config.mode + 1; | ||
| 280 | } | ||
| 281 | rgblight_mode(mode); | ||
| 282 | } | ||
| 283 | void rgblight_decrease(void) { | ||
| 284 | uint8_t mode = 0; | ||
| 285 | // Mode will never be < 1. If it ever is, eeprom needs to be initialized. | ||
| 286 | if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) { | ||
| 287 | mode = rgblight_config.mode - 1; | ||
| 288 | } | ||
| 289 | rgblight_mode(mode); | ||
| 290 | } | ||
| 291 | void rgblight_step_helper(bool write_to_eeprom) { | ||
| 292 | uint8_t mode = 0; | ||
| 293 | mode = rgblight_config.mode + 1; | ||
| 294 | if (mode > RGBLIGHT_MODES) { | ||
| 295 | mode = 1; | ||
| 296 | } | ||
| 297 | rgblight_mode_eeprom_helper(mode, write_to_eeprom); | ||
| 298 | } | ||
| 299 | void rgblight_step_noeeprom(void) { rgblight_step_helper(false); } | ||
| 300 | void rgblight_step(void) { rgblight_step_helper(true); } | ||
| 301 | void rgblight_step_reverse_helper(bool write_to_eeprom) { | ||
| 302 | uint8_t mode = 0; | ||
| 303 | mode = rgblight_config.mode - 1; | ||
| 304 | if (mode < 1) { | ||
| 305 | mode = RGBLIGHT_MODES; | ||
| 306 | } | ||
| 307 | rgblight_mode_eeprom_helper(mode, write_to_eeprom); | ||
| 308 | } | ||
| 309 | void rgblight_step_reverse_noeeprom(void) { rgblight_step_reverse_helper(false); } | ||
| 310 | void rgblight_step_reverse(void) { rgblight_step_reverse_helper(true); } | ||
| 311 | |||
| 312 | uint8_t rgblight_get_mode(void) { | ||
| 313 | if (!rgblight_config.enable) { | ||
| 314 | return false; | ||
| 315 | } | ||
| 316 | |||
| 317 | return rgblight_config.mode; | ||
| 318 | } | ||
| 319 | |||
| 320 | void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { | ||
| 321 | if (!rgblight_config.enable) { | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | if (mode < RGBLIGHT_MODE_STATIC_LIGHT) { | ||
| 325 | rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT; | ||
| 326 | } else if (mode > RGBLIGHT_MODES) { | ||
| 327 | rgblight_config.mode = RGBLIGHT_MODES; | ||
| 328 | } else { | ||
| 329 | rgblight_config.mode = mode; | ||
| 330 | } | ||
| 331 | RGBLIGHT_SPLIT_SET_CHANGE_MODE; | ||
| 332 | if (write_to_eeprom) { | ||
| 333 | eeconfig_update_rgblight(rgblight_config.raw); | ||
| 334 | dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode); | ||
| 335 | } else { | ||
| 336 | dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); | ||
| 337 | } | ||
| 338 | if (is_static_effect(rgblight_config.mode)) { | ||
| 339 | rgblight_timer_disable(); | ||
| 340 | } else { | ||
| 341 | rgblight_timer_enable(); | ||
| 342 | } | ||
| 343 | #ifdef RGBLIGHT_USE_TIMER | ||
| 344 | animation_status.restart = true; | ||
| 345 | #endif | ||
| 346 | rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); | ||
| 347 | } | ||
| 348 | |||
| 349 | void rgblight_mode(uint8_t mode) { rgblight_mode_eeprom_helper(mode, true); } | ||
| 350 | |||
| 351 | void rgblight_mode_noeeprom(uint8_t mode) { rgblight_mode_eeprom_helper(mode, false); } | ||
| 352 | |||
| 353 | void rgblight_toggle(void) { | ||
| 354 | dprintf("rgblight toggle [EEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable); | ||
| 355 | if (rgblight_config.enable) { | ||
| 356 | rgblight_disable(); | ||
| 357 | } else { | ||
| 358 | rgblight_enable(); | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | void rgblight_toggle_noeeprom(void) { | ||
| 363 | dprintf("rgblight toggle [NOEEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable); | ||
| 364 | if (rgblight_config.enable) { | ||
| 365 | rgblight_disable_noeeprom(); | ||
| 366 | } else { | ||
| 367 | rgblight_enable_noeeprom(); | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | void rgblight_enable(void) { | ||
| 372 | rgblight_config.enable = 1; | ||
| 373 | // No need to update EEPROM here. rgblight_mode() will do that, actually | ||
| 374 | // eeconfig_update_rgblight(rgblight_config.raw); | ||
| 375 | dprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); | ||
| 376 | rgblight_mode(rgblight_config.mode); | ||
| 377 | } | ||
| 378 | |||
| 379 | void rgblight_enable_noeeprom(void) { | ||
| 380 | rgblight_config.enable = 1; | ||
| 381 | dprintf("rgblight enable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); | ||
| 382 | rgblight_mode_noeeprom(rgblight_config.mode); | ||
| 383 | } | ||
| 384 | |||
| 385 | void rgblight_disable(void) { | ||
| 386 | rgblight_config.enable = 0; | ||
| 387 | eeconfig_update_rgblight(rgblight_config.raw); | ||
| 388 | dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); | ||
| 389 | rgblight_timer_disable(); | ||
| 390 | RGBLIGHT_SPLIT_SET_CHANGE_MODE; | ||
| 391 | wait_ms(50); | ||
| 392 | rgblight_set(); | ||
| 393 | } | ||
| 394 | |||
| 395 | void rgblight_disable_noeeprom(void) { | ||
| 396 | rgblight_config.enable = 0; | ||
| 397 | dprintf("rgblight disable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); | ||
| 398 | rgblight_timer_disable(); | ||
| 399 | RGBLIGHT_SPLIT_SET_CHANGE_MODE; | ||
| 400 | wait_ms(50); | ||
| 401 | rgblight_set(); | ||
| 402 | } | ||
| 403 | |||
| 404 | bool rgblight_is_enabled(void) { return rgblight_config.enable; } | ||
| 405 | |||
| 406 | void rgblight_increase_hue_helper(bool write_to_eeprom) { | ||
| 407 | uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP; | ||
| 408 | rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom); | ||
| 409 | } | ||
| 410 | void rgblight_increase_hue_noeeprom(void) { rgblight_increase_hue_helper(false); } | ||
| 411 | void rgblight_increase_hue(void) { rgblight_increase_hue_helper(true); } | ||
| 412 | void rgblight_decrease_hue_helper(bool write_to_eeprom) { | ||
| 413 | uint8_t hue = rgblight_config.hue - RGBLIGHT_HUE_STEP; | ||
| 414 | rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom); | ||
| 415 | } | ||
| 416 | void rgblight_decrease_hue_noeeprom(void) { rgblight_decrease_hue_helper(false); } | ||
| 417 | void rgblight_decrease_hue(void) { rgblight_decrease_hue_helper(true); } | ||
| 418 | void rgblight_increase_sat_helper(bool write_to_eeprom) { | ||
| 419 | uint8_t sat = qadd8(rgblight_config.sat, RGBLIGHT_SAT_STEP); | ||
| 420 | rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom); | ||
| 421 | } | ||
| 422 | void rgblight_increase_sat_noeeprom(void) { rgblight_increase_sat_helper(false); } | ||
| 423 | void rgblight_increase_sat(void) { rgblight_increase_sat_helper(true); } | ||
| 424 | void rgblight_decrease_sat_helper(bool write_to_eeprom) { | ||
| 425 | uint8_t sat = qsub8(rgblight_config.sat, RGBLIGHT_SAT_STEP); | ||
| 426 | rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom); | ||
| 427 | } | ||
| 428 | void rgblight_decrease_sat_noeeprom(void) { rgblight_decrease_sat_helper(false); } | ||
| 429 | void rgblight_decrease_sat(void) { rgblight_decrease_sat_helper(true); } | ||
| 430 | void rgblight_increase_val_helper(bool write_to_eeprom) { | ||
| 431 | uint8_t val = qadd8(rgblight_config.val, RGBLIGHT_VAL_STEP); | ||
| 432 | rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom); | ||
| 433 | } | ||
| 434 | void rgblight_increase_val_noeeprom(void) { rgblight_increase_val_helper(false); } | ||
| 435 | void rgblight_increase_val(void) { rgblight_increase_val_helper(true); } | ||
| 436 | void rgblight_decrease_val_helper(bool write_to_eeprom) { | ||
| 437 | uint8_t val = qsub8(rgblight_config.val, RGBLIGHT_VAL_STEP); | ||
| 438 | rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom); | ||
| 439 | } | ||
| 440 | void rgblight_decrease_val_noeeprom(void) { rgblight_decrease_val_helper(false); } | ||
| 441 | void rgblight_decrease_val(void) { rgblight_decrease_val_helper(true); } | ||
| 442 | |||
| 443 | void rgblight_increase_speed_helper(bool write_to_eeprom) { | ||
| 444 | if (rgblight_config.speed < 3) rgblight_config.speed++; | ||
| 445 | // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED? | ||
| 446 | if (write_to_eeprom) { | ||
| 447 | eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this | ||
| 448 | } | ||
| 449 | } | ||
| 450 | void rgblight_increase_speed(void) { rgblight_increase_speed_helper(true); } | ||
| 451 | void rgblight_increase_speed_noeeprom(void) { rgblight_increase_speed_helper(false); } | ||
| 452 | |||
| 453 | void rgblight_decrease_speed_helper(bool write_to_eeprom) { | ||
| 454 | if (rgblight_config.speed > 0) rgblight_config.speed--; | ||
| 455 | // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?? | ||
| 456 | if (write_to_eeprom) { | ||
| 457 | eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this | ||
| 458 | } | ||
| 459 | } | ||
| 460 | void rgblight_decrease_speed(void) { rgblight_decrease_speed_helper(true); } | ||
| 461 | void rgblight_decrease_speed_noeeprom(void) { rgblight_decrease_speed_helper(false); } | ||
| 462 | |||
| 463 | void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) { | ||
| 464 | if (rgblight_config.enable) { | ||
| 465 | LED_TYPE tmp_led; | ||
| 466 | sethsv(hue, sat, val, &tmp_led); | ||
| 467 | rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); | ||
| 468 | } | ||
| 469 | } | ||
| 470 | |||
| 471 | void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) { | ||
| 472 | if (rgblight_config.enable) { | ||
| 473 | rgblight_status.base_mode = mode_base_table[rgblight_config.mode]; | ||
| 474 | if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) { | ||
| 475 | // same static color | ||
| 476 | LED_TYPE tmp_led; | ||
| 477 | sethsv(hue, sat, val, &tmp_led); | ||
| 478 | rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); | ||
| 479 | } else { | ||
| 480 | // all LEDs in same color | ||
| 481 | if (1 == 0) { // dummy | ||
| 482 | } | ||
| 483 | #ifdef RGBLIGHT_EFFECT_BREATHING | ||
| 484 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) { | ||
| 485 | // breathing mode, ignore the change of val, use in memory value instead | ||
| 486 | val = rgblight_config.val; | ||
| 487 | } | ||
| 488 | #endif | ||
| 489 | #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD | ||
| 490 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) { | ||
| 491 | // rainbow mood, ignore the change of hue | ||
| 492 | hue = rgblight_config.hue; | ||
| 493 | } | ||
| 494 | #endif | ||
| 495 | #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL | ||
| 496 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) { | ||
| 497 | // rainbow swirl, ignore the change of hue | ||
| 498 | hue = rgblight_config.hue; | ||
| 499 | } | ||
| 500 | #endif | ||
| 501 | #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT | ||
| 502 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_STATIC_GRADIENT) { | ||
| 503 | // static gradient | ||
| 504 | uint8_t delta = rgblight_config.mode - rgblight_status.base_mode; | ||
| 505 | bool direction = (delta % 2) == 0; | ||
| 506 | # ifdef __AVR__ | ||
| 507 | // probably due to how pgm_read_word is defined for ARM, but the ARM compiler really hates this line | ||
| 508 | uint8_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[delta / 2]); | ||
| 509 | # else | ||
| 510 | uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2]; | ||
| 511 | # endif | ||
| 512 | for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||
| 513 | uint8_t _hue = ((uint16_t)i * (uint16_t)range) / rgblight_ranges.effect_num_leds; | ||
| 514 | if (direction) { | ||
| 515 | _hue = hue + _hue; | ||
| 516 | } else { | ||
| 517 | _hue = hue - _hue; | ||
| 518 | } | ||
| 519 | dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range); | ||
| 520 | sethsv(_hue, sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); | ||
| 521 | } | ||
| 522 | rgblight_set(); | ||
| 523 | } | ||
| 524 | #endif | ||
| 525 | } | ||
| 526 | #ifdef RGBLIGHT_SPLIT | ||
| 527 | if (rgblight_config.hue != hue || rgblight_config.sat != sat || rgblight_config.val != val) { | ||
| 528 | RGBLIGHT_SPLIT_SET_CHANGE_HSVS; | ||
| 529 | } | ||
| 530 | #endif | ||
| 531 | rgblight_config.hue = hue; | ||
| 532 | rgblight_config.sat = sat; | ||
| 533 | rgblight_config.val = val; | ||
| 534 | if (write_to_eeprom) { | ||
| 535 | eeconfig_update_rgblight(rgblight_config.raw); | ||
| 536 | dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); | ||
| 537 | } else { | ||
| 538 | dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); | ||
| 539 | } | ||
| 540 | } | ||
| 541 | } | ||
| 542 | |||
| 543 | void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_eeprom_helper(hue, sat, val, true); } | ||
| 544 | |||
| 545 | void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_eeprom_helper(hue, sat, val, false); } | ||
| 546 | |||
| 547 | uint8_t rgblight_get_speed(void) { return rgblight_config.speed; } | ||
| 548 | |||
| 549 | void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { | ||
| 550 | rgblight_config.speed = speed; | ||
| 551 | if (write_to_eeprom) { | ||
| 552 | eeconfig_update_rgblight(rgblight_config.raw); // EECONFIG needs to be increased to support this | ||
| 553 | dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed); | ||
| 554 | } else { | ||
| 555 | dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed); | ||
| 556 | } | ||
| 557 | } | ||
| 558 | |||
| 559 | void rgblight_set_speed(uint8_t speed) { rgblight_set_speed_eeprom_helper(speed, true); } | ||
| 560 | |||
| 561 | void rgblight_set_speed_noeeprom(uint8_t speed) { rgblight_set_speed_eeprom_helper(speed, false); } | ||
| 562 | |||
| 563 | uint8_t rgblight_get_hue(void) { return rgblight_config.hue; } | ||
| 564 | |||
| 565 | uint8_t rgblight_get_sat(void) { return rgblight_config.sat; } | ||
| 566 | |||
| 567 | uint8_t rgblight_get_val(void) { return rgblight_config.val; } | ||
| 568 | |||
| 569 | HSV rgblight_get_hsv(void) { return (HSV){rgblight_config.hue, rgblight_config.sat, rgblight_config.val}; } | ||
| 570 | |||
| 571 | void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { | ||
| 572 | if (!rgblight_config.enable) { | ||
| 573 | return; | ||
| 574 | } | ||
| 575 | |||
| 576 | for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { | ||
| 577 | led[i].r = r; | ||
| 578 | led[i].g = g; | ||
| 579 | led[i].b = b; | ||
| 580 | #ifdef RGBW | ||
| 581 | led[i].w = 0; | ||
| 582 | #endif | ||
| 583 | } | ||
| 584 | rgblight_set(); | ||
| 585 | } | ||
| 586 | |||
| 587 | void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) { | ||
| 588 | if (!rgblight_config.enable || index >= RGBLED_NUM) { | ||
| 589 | return; | ||
| 590 | } | ||
| 591 | |||
| 592 | led[index].r = r; | ||
| 593 | led[index].g = g; | ||
| 594 | led[index].b = b; | ||
| 595 | #ifdef RGBW | ||
| 596 | led[index].w = 0; | ||
| 597 | #endif | ||
| 598 | rgblight_set(); | ||
| 599 | } | ||
| 600 | |||
| 601 | void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) { | ||
| 602 | if (!rgblight_config.enable) { | ||
| 603 | return; | ||
| 604 | } | ||
| 605 | |||
| 606 | LED_TYPE tmp_led; | ||
| 607 | sethsv(hue, sat, val, &tmp_led); | ||
| 608 | rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); | ||
| 609 | } | ||
| 610 | |||
| 611 | #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) | ||
| 612 | |||
| 613 | static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) { | ||
| 614 | return | ||
| 615 | # ifdef VELOCIKEY_ENABLE | ||
| 616 | velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) : | ||
| 617 | # endif | ||
| 618 | pgm_read_byte(default_interval_address); | ||
| 619 | } | ||
| 620 | |||
| 621 | #endif | ||
| 622 | |||
| 623 | void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end) { | ||
| 624 | if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLED_NUM) { | ||
| 625 | return; | ||
| 626 | } | ||
| 627 | |||
| 628 | for (uint8_t i = start; i < end; i++) { | ||
| 629 | led[i].r = r; | ||
| 630 | led[i].g = g; | ||
| 631 | led[i].b = b; | ||
| 632 | #ifdef RGBW | ||
| 633 | led[i].w = 0; | ||
| 634 | #endif | ||
| 635 | } | ||
| 636 | rgblight_set(); | ||
| 637 | wait_ms(1); | ||
| 638 | } | ||
| 639 | |||
| 640 | void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end) { | ||
| 641 | if (!rgblight_config.enable) { | ||
| 642 | return; | ||
| 643 | } | ||
| 644 | |||
| 645 | LED_TYPE tmp_led; | ||
| 646 | sethsv(hue, sat, val, &tmp_led); | ||
| 647 | rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end); | ||
| 648 | } | ||
| 649 | |||
| 650 | #ifndef RGBLIGHT_SPLIT | ||
| 651 | 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); } | ||
| 652 | |||
| 653 | void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b) { rgblight_setrgb_range(r, g, b, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM); } | ||
| 654 | |||
| 655 | void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_range(hue, sat, val, 0, (uint8_t)RGBLED_NUM / 2); } | ||
| 656 | |||
| 657 | 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); } | ||
| 658 | #endif // ifndef RGBLIGHT_SPLIT | ||
| 659 | |||
| 660 | #ifdef RGBLIGHT_LAYERS | ||
| 661 | void rgblight_set_layer_state(uint8_t layer, bool enabled) { | ||
| 662 | rgblight_layer_mask_t mask = (rgblight_layer_mask_t)1 << layer; | ||
| 663 | if (enabled) { | ||
| 664 | rgblight_status.enabled_layer_mask |= mask; | ||
| 665 | } else { | ||
| 666 | rgblight_status.enabled_layer_mask &= ~mask; | ||
| 667 | } | ||
| 668 | RGBLIGHT_SPLIT_SET_CHANGE_LAYERS; | ||
| 669 | // Static modes don't have a ticker running to update the LEDs | ||
| 670 | if (rgblight_status.timer_enabled == false) { | ||
| 671 | rgblight_mode_noeeprom(rgblight_config.mode); | ||
| 672 | } | ||
| 673 | |||
| 674 | # ifdef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF | ||
| 675 | // If not enabled, then nothing else will actually set the LEDs... | ||
| 676 | if (!rgblight_config.enable) { | ||
| 677 | rgblight_set(); | ||
| 678 | } | ||
| 679 | # endif | ||
| 680 | } | ||
| 681 | |||
| 682 | bool rgblight_get_layer_state(uint8_t layer) { | ||
| 683 | rgblight_layer_mask_t mask = (rgblight_layer_mask_t)1 << layer; | ||
| 684 | return (rgblight_status.enabled_layer_mask & mask) != 0; | ||
| 685 | } | ||
| 686 | |||
| 687 | // Write any enabled LED layers into the buffer | ||
| 688 | static void rgblight_layers_write(void) { | ||
| 689 | # ifdef RGBLIGHT_LAYERS_RETAIN_VAL | ||
| 690 | uint8_t current_val = rgblight_get_val(); | ||
| 691 | # endif | ||
| 692 | uint8_t i = 0; | ||
| 693 | // For each layer | ||
| 694 | for (const rgblight_segment_t *const *layer_ptr = rgblight_layers; i < RGBLIGHT_MAX_LAYERS; layer_ptr++, i++) { | ||
| 695 | if (!rgblight_get_layer_state(i)) { | ||
| 696 | continue; // Layer is disabled | ||
| 697 | } | ||
| 698 | const rgblight_segment_t *segment_ptr = pgm_read_ptr(layer_ptr); | ||
| 699 | if (segment_ptr == NULL) { | ||
| 700 | break; // No more layers | ||
| 701 | } | ||
| 702 | // For each segment | ||
| 703 | while (1) { | ||
| 704 | rgblight_segment_t segment; | ||
| 705 | memcpy_P(&segment, segment_ptr, sizeof(rgblight_segment_t)); | ||
| 706 | if (segment.index == RGBLIGHT_END_SEGMENT_INDEX) { | ||
| 707 | break; // No more segments | ||
| 708 | } | ||
| 709 | // Write segment.count LEDs | ||
| 710 | LED_TYPE *const limit = &led[MIN(segment.index + segment.count, RGBLED_NUM)]; | ||
| 711 | for (LED_TYPE *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) { | ||
| 712 | # ifdef RGBLIGHT_LAYERS_RETAIN_VAL | ||
| 713 | sethsv(segment.hue, segment.sat, current_val, led_ptr); | ||
| 714 | # else | ||
| 715 | sethsv(segment.hue, segment.sat, segment.val, led_ptr); | ||
| 716 | # endif | ||
| 717 | } | ||
| 718 | segment_ptr++; | ||
| 719 | } | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 723 | # ifdef RGBLIGHT_LAYER_BLINK | ||
| 724 | rgblight_layer_mask_t _blinking_layer_mask = 0; | ||
| 725 | static uint16_t _repeat_timer; | ||
| 726 | static uint8_t _times_remaining; | ||
| 727 | static uint16_t _dur; | ||
| 728 | |||
| 729 | void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) { rgblight_blink_layer_repeat(layer, duration_ms, 1); } | ||
| 730 | |||
| 731 | void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times) { | ||
| 732 | _times_remaining = times * 2; | ||
| 733 | _dur = duration_ms; | ||
| 734 | |||
| 735 | rgblight_set_layer_state(layer, true); | ||
| 736 | _times_remaining--; | ||
| 737 | _blinking_layer_mask |= (rgblight_layer_mask_t)1 << layer; | ||
| 738 | _repeat_timer = sync_timer_read() + duration_ms; | ||
| 739 | } | ||
| 740 | |||
| 741 | void rgblight_blink_layer_repeat_helper(void) { | ||
| 742 | if (_blinking_layer_mask != 0 && timer_expired(sync_timer_read(), _repeat_timer)) { | ||
| 743 | for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) { | ||
| 744 | if ((_blinking_layer_mask & (rgblight_layer_mask_t)1 << layer) != 0 && _times_remaining > 0) { | ||
| 745 | if (_times_remaining % 2 == 1) { | ||
| 746 | rgblight_set_layer_state(layer, false); | ||
| 747 | } else { | ||
| 748 | rgblight_set_layer_state(layer, true); | ||
| 749 | } | ||
| 750 | _times_remaining--; | ||
| 751 | _repeat_timer = sync_timer_read() + _dur; | ||
| 752 | } | ||
| 753 | } | ||
| 754 | if (_times_remaining <= 0) { | ||
| 755 | _blinking_layer_mask = 0; | ||
| 756 | } | ||
| 757 | } | ||
| 758 | } | ||
| 759 | # endif | ||
| 760 | |||
| 761 | #endif | ||
| 762 | |||
| 763 | #ifdef RGBLIGHT_SLEEP | ||
| 764 | |||
| 765 | void rgblight_suspend(void) { | ||
| 766 | rgblight_timer_disable(); | ||
| 767 | if (!is_suspended) { | ||
| 768 | is_suspended = true; | ||
| 769 | pre_suspend_enabled = rgblight_config.enable; | ||
| 770 | |||
| 771 | # ifdef RGBLIGHT_LAYER_BLINK | ||
| 772 | // make sure any layer blinks don't come back after suspend | ||
| 773 | rgblight_status.enabled_layer_mask &= ~_blinking_layer_mask; | ||
| 774 | _blinking_layer_mask = 0; | ||
| 775 | # endif | ||
| 776 | |||
| 777 | rgblight_disable_noeeprom(); | ||
| 778 | } | ||
| 779 | } | ||
| 780 | |||
| 781 | void rgblight_wakeup(void) { | ||
| 782 | is_suspended = false; | ||
| 783 | |||
| 784 | if (pre_suspend_enabled) { | ||
| 785 | rgblight_enable_noeeprom(); | ||
| 786 | } | ||
| 787 | # ifdef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF | ||
| 788 | // Need this or else the LEDs won't be set | ||
| 789 | else if (rgblight_status.enabled_layer_mask != 0) { | ||
| 790 | rgblight_set(); | ||
| 791 | } | ||
| 792 | # endif | ||
| 793 | |||
| 794 | rgblight_timer_enable(); | ||
| 795 | } | ||
| 796 | |||
| 797 | #endif | ||
| 798 | |||
| 799 | __attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); } | ||
| 800 | |||
| 801 | #ifndef RGBLIGHT_CUSTOM_DRIVER | ||
| 802 | |||
| 803 | void rgblight_set(void) { | ||
| 804 | LED_TYPE *start_led; | ||
| 805 | uint8_t num_leds = rgblight_ranges.clipping_num_leds; | ||
| 806 | |||
| 807 | if (!rgblight_config.enable) { | ||
| 808 | for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { | ||
| 809 | led[i].r = 0; | ||
| 810 | led[i].g = 0; | ||
| 811 | led[i].b = 0; | ||
| 812 | # ifdef RGBW | ||
| 813 | led[i].w = 0; | ||
| 814 | # endif | ||
| 815 | } | ||
| 816 | } | ||
| 817 | |||
| 818 | # ifdef RGBLIGHT_LAYERS | ||
| 819 | if (rgblight_layers != NULL | ||
| 820 | # if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF) | ||
| 821 | && rgblight_config.enable | ||
| 822 | # elif defined(RGBLIGHT_SLEEP) | ||
| 823 | && !is_suspended | ||
| 824 | # endif | ||
| 825 | ) { | ||
| 826 | rgblight_layers_write(); | ||
| 827 | } | ||
| 828 | # endif | ||
| 829 | |||
| 830 | # ifdef RGBLIGHT_LED_MAP | ||
| 831 | LED_TYPE led0[RGBLED_NUM]; | ||
| 832 | for (uint8_t i = 0; i < RGBLED_NUM; i++) { | ||
| 833 | led0[i] = led[pgm_read_byte(&led_map[i])]; | ||
| 834 | } | ||
| 835 | start_led = led0 + rgblight_ranges.clipping_start_pos; | ||
| 836 | # else | ||
| 837 | start_led = led + rgblight_ranges.clipping_start_pos; | ||
| 838 | # endif | ||
| 839 | |||
| 840 | # ifdef RGBW | ||
| 841 | for (uint8_t i = 0; i < num_leds; i++) { | ||
| 842 | convert_rgb_to_rgbw(&start_led[i]); | ||
| 843 | } | ||
| 844 | # endif | ||
| 845 | rgblight_call_driver(start_led, num_leds); | ||
| 846 | } | ||
| 847 | #endif | ||
| 848 | |||
| 849 | #ifdef RGBLIGHT_SPLIT | ||
| 850 | /* for split keyboard master side */ | ||
| 851 | uint8_t rgblight_get_change_flags(void) { return rgblight_status.change_flags; } | ||
| 852 | |||
| 853 | void rgblight_clear_change_flags(void) { rgblight_status.change_flags = 0; } | ||
| 854 | |||
| 855 | void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo) { | ||
| 856 | syncinfo->config = rgblight_config; | ||
| 857 | syncinfo->status = rgblight_status; | ||
| 858 | } | ||
| 859 | |||
| 860 | /* for split keyboard slave side */ | ||
| 861 | void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) { | ||
| 862 | # ifdef RGBLIGHT_LAYERS | ||
| 863 | if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_LAYERS) { | ||
| 864 | rgblight_status.enabled_layer_mask = syncinfo->status.enabled_layer_mask; | ||
| 865 | } | ||
| 866 | # endif | ||
| 867 | if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) { | ||
| 868 | if (syncinfo->config.enable) { | ||
| 869 | rgblight_config.enable = 1; // == rgblight_enable_noeeprom(); | ||
| 870 | rgblight_mode_eeprom_helper(syncinfo->config.mode, write_to_eeprom); | ||
| 871 | } else { | ||
| 872 | rgblight_disable_noeeprom(); | ||
| 873 | } | ||
| 874 | } | ||
| 875 | if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_HSVS) { | ||
| 876 | rgblight_sethsv_eeprom_helper(syncinfo->config.hue, syncinfo->config.sat, syncinfo->config.val, write_to_eeprom); | ||
| 877 | // rgblight_config.speed = config->speed; // NEED??? | ||
| 878 | } | ||
| 879 | # ifdef RGBLIGHT_USE_TIMER | ||
| 880 | if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_TIMER) { | ||
| 881 | if (syncinfo->status.timer_enabled) { | ||
| 882 | rgblight_timer_enable(); | ||
| 883 | } else { | ||
| 884 | rgblight_timer_disable(); | ||
| 885 | } | ||
| 886 | } | ||
| 887 | # ifndef RGBLIGHT_SPLIT_NO_ANIMATION_SYNC | ||
| 888 | if (syncinfo->status.change_flags & RGBLIGHT_STATUS_ANIMATION_TICK) { | ||
| 889 | animation_status.restart = true; | ||
| 890 | } | ||
| 891 | # endif /* RGBLIGHT_SPLIT_NO_ANIMATION_SYNC */ | ||
| 892 | # endif /* RGBLIGHT_USE_TIMER */ | ||
| 893 | } | ||
| 894 | #endif /* RGBLIGHT_SPLIT */ | ||
| 895 | |||
| 896 | #ifdef RGBLIGHT_USE_TIMER | ||
| 897 | |||
| 898 | typedef void (*effect_func_t)(animation_status_t *anim); | ||
| 899 | |||
| 900 | // Animation timer -- use system timer (AVR Timer0) | ||
| 901 | void rgblight_timer_init(void) { | ||
| 902 | rgblight_status.timer_enabled = false; | ||
| 903 | RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE; | ||
| 904 | } | ||
| 905 | void rgblight_timer_enable(void) { | ||
| 906 | if (!is_static_effect(rgblight_config.mode)) { | ||
| 907 | rgblight_status.timer_enabled = true; | ||
| 908 | } | ||
| 909 | animation_status.last_timer = sync_timer_read(); | ||
| 910 | RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE; | ||
| 911 | dprintf("rgblight timer enabled.\n"); | ||
| 912 | } | ||
| 913 | void rgblight_timer_disable(void) { | ||
| 914 | rgblight_status.timer_enabled = false; | ||
| 915 | RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE; | ||
| 916 | dprintf("rgblight timer disable.\n"); | ||
| 917 | } | ||
| 918 | void rgblight_timer_toggle(void) { | ||
| 919 | dprintf("rgblight timer toggle.\n"); | ||
| 920 | if (rgblight_status.timer_enabled) { | ||
| 921 | rgblight_timer_disable(); | ||
| 922 | } else { | ||
| 923 | rgblight_timer_enable(); | ||
| 924 | } | ||
| 925 | } | ||
| 926 | |||
| 927 | void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) { | ||
| 928 | rgblight_enable(); | ||
| 929 | rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); | ||
| 930 | rgblight_setrgb(r, g, b); | ||
| 931 | } | ||
| 932 | |||
| 933 | static void rgblight_effect_dummy(animation_status_t *anim) { | ||
| 934 | // do nothing | ||
| 935 | /******** | ||
| 936 | dprintf("rgblight_task() what happened?\n"); | ||
| 937 | dprintf("is_static_effect %d\n", is_static_effect(rgblight_config.mode)); | ||
| 938 | dprintf("mode = %d, base_mode = %d, timer_enabled %d, ", | ||
| 939 | rgblight_config.mode, rgblight_status.base_mode, | ||
| 940 | rgblight_status.timer_enabled); | ||
| 941 | dprintf("last_timer = %d\n",anim->last_timer); | ||
| 942 | **/ | ||
| 943 | } | ||
| 944 | |||
| 945 | void rgblight_task(void) { | ||
| 946 | if (rgblight_status.timer_enabled) { | ||
| 947 | effect_func_t effect_func = rgblight_effect_dummy; | ||
| 948 | uint16_t interval_time = 2000; // dummy interval | ||
| 949 | uint8_t delta = rgblight_config.mode - rgblight_status.base_mode; | ||
| 950 | animation_status.delta = delta; | ||
| 951 | |||
| 952 | // static light mode, do nothing here | ||
| 953 | if (1 == 0) { // dummy | ||
| 954 | } | ||
| 955 | # ifdef RGBLIGHT_EFFECT_BREATHING | ||
| 956 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) { | ||
| 957 | // breathing mode | ||
| 958 | interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[delta], 1, 100); | ||
| 959 | effect_func = rgblight_effect_breathing; | ||
| 960 | } | ||
| 961 | # endif | ||
| 962 | # ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD | ||
| 963 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) { | ||
| 964 | // rainbow mood mode | ||
| 965 | interval_time = get_interval_time(&RGBLED_RAINBOW_MOOD_INTERVALS[delta], 5, 100); | ||
| 966 | effect_func = rgblight_effect_rainbow_mood; | ||
| 967 | } | ||
| 968 | # endif | ||
| 969 | # ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL | ||
| 970 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) { | ||
| 971 | // rainbow swirl mode | ||
| 972 | interval_time = get_interval_time(&RGBLED_RAINBOW_SWIRL_INTERVALS[delta / 2], 1, 100); | ||
| 973 | effect_func = rgblight_effect_rainbow_swirl; | ||
| 974 | } | ||
| 975 | # endif | ||
| 976 | # ifdef RGBLIGHT_EFFECT_SNAKE | ||
| 977 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE) { | ||
| 978 | // snake mode | ||
| 979 | interval_time = get_interval_time(&RGBLED_SNAKE_INTERVALS[delta / 2], 1, 200); | ||
| 980 | effect_func = rgblight_effect_snake; | ||
| 981 | } | ||
| 982 | # endif | ||
| 983 | # ifdef RGBLIGHT_EFFECT_KNIGHT | ||
| 984 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT) { | ||
| 985 | // knight mode | ||
| 986 | interval_time = get_interval_time(&RGBLED_KNIGHT_INTERVALS[delta], 5, 100); | ||
| 987 | effect_func = rgblight_effect_knight; | ||
| 988 | } | ||
| 989 | # endif | ||
| 990 | # ifdef RGBLIGHT_EFFECT_CHRISTMAS | ||
| 991 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_CHRISTMAS) { | ||
| 992 | // christmas mode | ||
| 993 | interval_time = RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL; | ||
| 994 | effect_func = (effect_func_t)rgblight_effect_christmas; | ||
| 995 | } | ||
| 996 | # endif | ||
| 997 | # ifdef RGBLIGHT_EFFECT_RGB_TEST | ||
| 998 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_RGB_TEST) { | ||
| 999 | // RGB test mode | ||
| 1000 | interval_time = pgm_read_word(&RGBLED_RGBTEST_INTERVALS[0]); | ||
| 1001 | effect_func = (effect_func_t)rgblight_effect_rgbtest; | ||
| 1002 | } | ||
| 1003 | # endif | ||
| 1004 | # ifdef RGBLIGHT_EFFECT_ALTERNATING | ||
| 1005 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_ALTERNATING) { | ||
| 1006 | interval_time = 500; | ||
| 1007 | effect_func = (effect_func_t)rgblight_effect_alternating; | ||
| 1008 | } | ||
| 1009 | # endif | ||
| 1010 | # ifdef RGBLIGHT_EFFECT_TWINKLE | ||
| 1011 | else if (rgblight_status.base_mode == RGBLIGHT_MODE_TWINKLE) { | ||
| 1012 | interval_time = get_interval_time(&RGBLED_TWINKLE_INTERVALS[delta % 3], 5, 30); | ||
| 1013 | effect_func = (effect_func_t)rgblight_effect_twinkle; | ||
| 1014 | } | ||
| 1015 | # endif | ||
| 1016 | if (animation_status.restart) { | ||
| 1017 | animation_status.restart = false; | ||
| 1018 | animation_status.last_timer = sync_timer_read(); | ||
| 1019 | animation_status.pos16 = 0; // restart signal to local each effect | ||
| 1020 | } | ||
| 1021 | uint16_t now = sync_timer_read(); | ||
| 1022 | if (timer_expired(now, animation_status.last_timer)) { | ||
| 1023 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1024 | static uint16_t report_last_timer = 0; | ||
| 1025 | static bool tick_flag = false; | ||
| 1026 | uint16_t oldpos16; | ||
| 1027 | if (tick_flag) { | ||
| 1028 | tick_flag = false; | ||
| 1029 | if (timer_expired(now, report_last_timer)) { | ||
| 1030 | report_last_timer += 30000; | ||
| 1031 | dprintf("rgblight animation tick report to slave\n"); | ||
| 1032 | RGBLIGHT_SPLIT_ANIMATION_TICK; | ||
| 1033 | } | ||
| 1034 | } | ||
| 1035 | oldpos16 = animation_status.pos16; | ||
| 1036 | # endif | ||
| 1037 | animation_status.last_timer += interval_time; | ||
| 1038 | effect_func(&animation_status); | ||
| 1039 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1040 | if (animation_status.pos16 == 0 && oldpos16 != 0) { | ||
| 1041 | tick_flag = true; | ||
| 1042 | } | ||
| 1043 | # endif | ||
| 1044 | } | ||
| 1045 | } | ||
| 1046 | |||
| 1047 | # ifdef RGBLIGHT_LAYER_BLINK | ||
| 1048 | rgblight_blink_layer_repeat_helper(); | ||
| 1049 | # endif | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | #endif /* RGBLIGHT_USE_TIMER */ | ||
| 1053 | |||
| 1054 | #if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_TWINKLE) | ||
| 1055 | |||
| 1056 | # ifndef RGBLIGHT_EFFECT_BREATHE_CENTER | ||
| 1057 | # ifndef RGBLIGHT_BREATHE_TABLE_SIZE | ||
| 1058 | # define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256 or 128 or 64 | ||
| 1059 | # endif | ||
| 1060 | # include <rgblight_breathe_table.h> | ||
| 1061 | # endif | ||
| 1062 | |||
| 1063 | static uint8_t breathe_calc(uint8_t pos) { | ||
| 1064 | // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ | ||
| 1065 | # ifdef RGBLIGHT_EFFECT_BREATHE_TABLE | ||
| 1066 | return pgm_read_byte(&rgblight_effect_breathe_table[pos / table_scale]); | ||
| 1067 | # else | ||
| 1068 | return (exp(sin((pos / 255.0) * M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER / M_E) * (RGBLIGHT_EFFECT_BREATHE_MAX / (M_E - 1 / M_E)); | ||
| 1069 | # endif | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | #endif | ||
| 1073 | |||
| 1074 | // Effects | ||
| 1075 | #ifdef RGBLIGHT_EFFECT_BREATHING | ||
| 1076 | |||
| 1077 | __attribute__((weak)) const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; | ||
| 1078 | |||
| 1079 | void rgblight_effect_breathing(animation_status_t *anim) { | ||
| 1080 | uint8_t val = breathe_calc(anim->pos); | ||
| 1081 | rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val); | ||
| 1082 | anim->pos = (anim->pos + 1); | ||
| 1083 | } | ||
| 1084 | #endif | ||
| 1085 | |||
| 1086 | #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD | ||
| 1087 | __attribute__((weak)) const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; | ||
| 1088 | |||
| 1089 | void rgblight_effect_rainbow_mood(animation_status_t *anim) { | ||
| 1090 | rgblight_sethsv_noeeprom_old(anim->current_hue, rgblight_config.sat, rgblight_config.val); | ||
| 1091 | anim->current_hue++; | ||
| 1092 | } | ||
| 1093 | #endif | ||
| 1094 | |||
| 1095 | #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL | ||
| 1096 | # ifndef RGBLIGHT_RAINBOW_SWIRL_RANGE | ||
| 1097 | # define RGBLIGHT_RAINBOW_SWIRL_RANGE 255 | ||
| 1098 | # endif | ||
| 1099 | |||
| 1100 | __attribute__((weak)) const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; | ||
| 1101 | |||
| 1102 | void rgblight_effect_rainbow_swirl(animation_status_t *anim) { | ||
| 1103 | uint8_t hue; | ||
| 1104 | uint8_t i; | ||
| 1105 | |||
| 1106 | for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||
| 1107 | hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue); | ||
| 1108 | sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); | ||
| 1109 | } | ||
| 1110 | rgblight_set(); | ||
| 1111 | |||
| 1112 | if (anim->delta % 2) { | ||
| 1113 | anim->current_hue++; | ||
| 1114 | } else { | ||
| 1115 | anim->current_hue--; | ||
| 1116 | } | ||
| 1117 | } | ||
| 1118 | #endif | ||
| 1119 | |||
| 1120 | #ifdef RGBLIGHT_EFFECT_SNAKE | ||
| 1121 | __attribute__((weak)) const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; | ||
| 1122 | |||
| 1123 | void rgblight_effect_snake(animation_status_t *anim) { | ||
| 1124 | static uint8_t pos = 0; | ||
| 1125 | uint8_t i, j; | ||
| 1126 | int8_t k; | ||
| 1127 | int8_t increment = 1; | ||
| 1128 | |||
| 1129 | if (anim->delta % 2) { | ||
| 1130 | increment = -1; | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1134 | if (anim->pos == 0) { // restart signal | ||
| 1135 | if (increment == 1) { | ||
| 1136 | pos = rgblight_ranges.effect_num_leds - 1; | ||
| 1137 | } else { | ||
| 1138 | pos = 0; | ||
| 1139 | } | ||
| 1140 | anim->pos = 1; | ||
| 1141 | } | ||
| 1142 | # endif | ||
| 1143 | |||
| 1144 | for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||
| 1145 | LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos; | ||
| 1146 | ledp->r = 0; | ||
| 1147 | ledp->g = 0; | ||
| 1148 | ledp->b = 0; | ||
| 1149 | # ifdef RGBW | ||
| 1150 | ledp->w = 0; | ||
| 1151 | # endif | ||
| 1152 | for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { | ||
| 1153 | k = pos + j * increment; | ||
| 1154 | if (k > RGBLED_NUM) { | ||
| 1155 | k = k % RGBLED_NUM; | ||
| 1156 | } | ||
| 1157 | if (k < 0) { | ||
| 1158 | k = k + rgblight_ranges.effect_num_leds; | ||
| 1159 | } | ||
| 1160 | if (i == k) { | ||
| 1161 | sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp); | ||
| 1162 | } | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | rgblight_set(); | ||
| 1166 | if (increment == 1) { | ||
| 1167 | if (pos - 1 < 0) { | ||
| 1168 | pos = rgblight_ranges.effect_num_leds - 1; | ||
| 1169 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1170 | anim->pos = 0; | ||
| 1171 | # endif | ||
| 1172 | } else { | ||
| 1173 | pos -= 1; | ||
| 1174 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1175 | anim->pos = 1; | ||
| 1176 | # endif | ||
| 1177 | } | ||
| 1178 | } else { | ||
| 1179 | pos = (pos + 1) % rgblight_ranges.effect_num_leds; | ||
| 1180 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1181 | anim->pos = pos; | ||
| 1182 | # endif | ||
| 1183 | } | ||
| 1184 | } | ||
| 1185 | #endif | ||
| 1186 | |||
| 1187 | #ifdef RGBLIGHT_EFFECT_KNIGHT | ||
| 1188 | __attribute__((weak)) const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31}; | ||
| 1189 | |||
| 1190 | void rgblight_effect_knight(animation_status_t *anim) { | ||
| 1191 | static int8_t low_bound = 0; | ||
| 1192 | static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; | ||
| 1193 | static int8_t increment = 1; | ||
| 1194 | uint8_t i, cur; | ||
| 1195 | |||
| 1196 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1197 | if (anim->pos == 0) { // restart signal | ||
| 1198 | anim->pos = 1; | ||
| 1199 | low_bound = 0; | ||
| 1200 | high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; | ||
| 1201 | increment = 1; | ||
| 1202 | } | ||
| 1203 | # endif | ||
| 1204 | // Set all the LEDs to 0 | ||
| 1205 | for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { | ||
| 1206 | led[i].r = 0; | ||
| 1207 | led[i].g = 0; | ||
| 1208 | led[i].b = 0; | ||
| 1209 | # ifdef RGBW | ||
| 1210 | led[i].w = 0; | ||
| 1211 | # endif | ||
| 1212 | } | ||
| 1213 | // Determine which LEDs should be lit up | ||
| 1214 | for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { | ||
| 1215 | cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos; | ||
| 1216 | |||
| 1217 | if (i >= low_bound && i <= high_bound) { | ||
| 1218 | sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]); | ||
| 1219 | } else { | ||
| 1220 | led[cur].r = 0; | ||
| 1221 | led[cur].g = 0; | ||
| 1222 | led[cur].b = 0; | ||
| 1223 | # ifdef RGBW | ||
| 1224 | led[cur].w = 0; | ||
| 1225 | # endif | ||
| 1226 | } | ||
| 1227 | } | ||
| 1228 | rgblight_set(); | ||
| 1229 | |||
| 1230 | // Move from low_bound to high_bound changing the direction we increment each | ||
| 1231 | // time a boundary is hit. | ||
| 1232 | low_bound += increment; | ||
| 1233 | high_bound += increment; | ||
| 1234 | |||
| 1235 | if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) { | ||
| 1236 | increment = -increment; | ||
| 1237 | # if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) | ||
| 1238 | if (increment == 1) { | ||
| 1239 | anim->pos = 0; | ||
| 1240 | } | ||
| 1241 | # endif | ||
| 1242 | } | ||
| 1243 | } | ||
| 1244 | #endif | ||
| 1245 | |||
| 1246 | #ifdef RGBLIGHT_EFFECT_CHRISTMAS | ||
| 1247 | # define CUBED(x) ((x) * (x) * (x)) | ||
| 1248 | |||
| 1249 | /** | ||
| 1250 | * Christmas lights effect, with a smooth animation between red & green. | ||
| 1251 | */ | ||
| 1252 | void rgblight_effect_christmas(animation_status_t *anim) { | ||
| 1253 | static int8_t increment = 1; | ||
| 1254 | const uint8_t max_pos = 32; | ||
| 1255 | const uint8_t hue_green = 85; | ||
| 1256 | |||
| 1257 | uint32_t xa; | ||
| 1258 | uint8_t hue, val; | ||
| 1259 | uint8_t i; | ||
| 1260 | |||
| 1261 | // The effect works by animating anim->pos from 0 to 32 and back to 0. | ||
| 1262 | // 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. | ||
| 1263 | xa = CUBED((uint32_t)anim->pos); | ||
| 1264 | hue = ((uint32_t)hue_green) * xa / (xa + CUBED((uint32_t)(max_pos - anim->pos))); | ||
| 1265 | // Additionally, these interpolated colors get shown with a slightly darker value, to make them less prominent than the main colors. | ||
| 1266 | val = 255 - (3 * (hue < hue_green / 2 ? hue : hue_green - hue) / 2); | ||
| 1267 | |||
| 1268 | for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||
| 1269 | uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue; | ||
| 1270 | sethsv(local_hue, rgblight_config.sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); | ||
| 1271 | } | ||
| 1272 | rgblight_set(); | ||
| 1273 | |||
| 1274 | if (anim->pos == 0) { | ||
| 1275 | increment = 1; | ||
| 1276 | } else if (anim->pos == max_pos) { | ||
| 1277 | increment = -1; | ||
| 1278 | } | ||
| 1279 | anim->pos += increment; | ||
| 1280 | } | ||
| 1281 | #endif | ||
| 1282 | |||
| 1283 | #ifdef RGBLIGHT_EFFECT_RGB_TEST | ||
| 1284 | __attribute__((weak)) const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024}; | ||
| 1285 | |||
| 1286 | void rgblight_effect_rgbtest(animation_status_t *anim) { | ||
| 1287 | static uint8_t maxval = 0; | ||
| 1288 | uint8_t g; | ||
| 1289 | uint8_t r; | ||
| 1290 | uint8_t b; | ||
| 1291 | |||
| 1292 | if (maxval == 0) { | ||
| 1293 | LED_TYPE tmp_led; | ||
| 1294 | sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led); | ||
| 1295 | maxval = tmp_led.r; | ||
| 1296 | } | ||
| 1297 | g = r = b = 0; | ||
| 1298 | switch (anim->pos) { | ||
| 1299 | case 0: | ||
| 1300 | r = maxval; | ||
| 1301 | break; | ||
| 1302 | case 1: | ||
| 1303 | g = maxval; | ||
| 1304 | break; | ||
| 1305 | case 2: | ||
| 1306 | b = maxval; | ||
| 1307 | break; | ||
| 1308 | } | ||
| 1309 | rgblight_setrgb(r, g, b); | ||
| 1310 | anim->pos = (anim->pos + 1) % 3; | ||
| 1311 | } | ||
| 1312 | #endif | ||
| 1313 | |||
| 1314 | #ifdef RGBLIGHT_EFFECT_ALTERNATING | ||
| 1315 | void rgblight_effect_alternating(animation_status_t *anim) { | ||
| 1316 | for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||
| 1317 | LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos; | ||
| 1318 | if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) { | ||
| 1319 | sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); | ||
| 1320 | } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) { | ||
| 1321 | sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); | ||
| 1322 | } else { | ||
| 1323 | sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp); | ||
| 1324 | } | ||
| 1325 | } | ||
| 1326 | rgblight_set(); | ||
| 1327 | anim->pos = (anim->pos + 1) % 2; | ||
| 1328 | } | ||
| 1329 | #endif | ||
| 1330 | |||
| 1331 | #ifdef RGBLIGHT_EFFECT_TWINKLE | ||
| 1332 | __attribute__((weak)) const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {30, 15, 5}; | ||
| 1333 | |||
| 1334 | typedef struct PACKED { | ||
| 1335 | HSV hsv; | ||
| 1336 | uint8_t life; | ||
| 1337 | uint8_t max_life; | ||
| 1338 | } TwinkleState; | ||
| 1339 | |||
| 1340 | static TwinkleState led_twinkle_state[RGBLED_NUM]; | ||
| 1341 | |||
| 1342 | void rgblight_effect_twinkle(animation_status_t *anim) { | ||
| 1343 | const bool random_color = anim->delta / 3; | ||
| 1344 | const bool restart = anim->pos == 0; | ||
| 1345 | anim->pos = 1; | ||
| 1346 | |||
| 1347 | const uint8_t bottom = breathe_calc(0); | ||
| 1348 | const uint8_t top = breathe_calc(127); | ||
| 1349 | |||
| 1350 | uint8_t frac(uint8_t n, uint8_t d) { return (uint16_t)255 * n / d; } | ||
| 1351 | uint8_t scale(uint16_t v, uint8_t scale) { return (v * scale) >> 8; } | ||
| 1352 | |||
| 1353 | for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||
| 1354 | TwinkleState *t = &(led_twinkle_state[i]); | ||
| 1355 | HSV * c = &(t->hsv); | ||
| 1356 | |||
| 1357 | if (!random_color) { | ||
| 1358 | c->h = rgblight_config.hue; | ||
| 1359 | c->s = rgblight_config.sat; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | if (restart) { | ||
| 1363 | // Restart | ||
| 1364 | t->life = 0; | ||
| 1365 | c->v = 0; | ||
| 1366 | } else if (t->life) { | ||
| 1367 | // This LED is already on, either brightening or dimming | ||
| 1368 | t->life--; | ||
| 1369 | uint8_t unscaled = frac(breathe_calc(frac(t->life, t->max_life)) - bottom, top - bottom); | ||
| 1370 | c->v = scale(rgblight_config.val, unscaled); | ||
| 1371 | } else if (rand() < scale((uint16_t)RAND_MAX * RGBLIGHT_EFFECT_TWINKLE_PROBABILITY, 127 + rgblight_config.val / 2)) { | ||
| 1372 | // This LED is off, but was randomly selected to start brightening | ||
| 1373 | if (random_color) { | ||
| 1374 | c->h = rand() % 0xFF; | ||
| 1375 | c->s = (rand() % (rgblight_config.sat / 2)) + (rgblight_config.sat / 2); | ||
| 1376 | } | ||
| 1377 | c->v = 0; | ||
| 1378 | t->max_life = MAX(20, MIN(RGBLIGHT_EFFECT_TWINKLE_LIFE, rgblight_config.val)); | ||
| 1379 | t->life = t->max_life; | ||
| 1380 | } else { | ||
| 1381 | // This LED is off, and was NOT selected to start brightening | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos; | ||
| 1385 | sethsv(c->h, c->s, c->v, ledp); | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | rgblight_set(); | ||
| 1389 | } | ||
| 1390 | #endif | ||
diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h new file mode 100644 index 000000000..5b90b8f49 --- /dev/null +++ b/quantum/rgblight/rgblight.h | |||
| @@ -0,0 +1,434 @@ | |||
| 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 | |||
| 17 | #pragma once | ||
| 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 | | 37 | RGBLIGHT_MODE_TWINKLE | | ||
| 63 | | 38 | RGBLIGHT_MODE_TWINKLE + 1 | | ||
| 64 | | 39 | RGBLIGHT_MODE_TWINKLE + 2 | | ||
| 65 | | 40 | RGBLIGHT_MODE_TWINKLE + 3 | | ||
| 66 | | 41 | RGBLIGHT_MODE_TWINKLE + 4 | | ||
| 67 | | 42 | RGBLIGHT_MODE_TWINKLE + 5 | | ||
| 68 | |-----------------|-----------------------------------| | ||
| 69 | *****/ | ||
| 70 | |||
| 71 | #ifdef RGBLIGHT_ANIMATIONS | ||
| 72 | // for backward compatibility | ||
| 73 | # define RGBLIGHT_EFFECT_BREATHING | ||
| 74 | # define RGBLIGHT_EFFECT_RAINBOW_MOOD | ||
| 75 | # define RGBLIGHT_EFFECT_RAINBOW_SWIRL | ||
| 76 | # define RGBLIGHT_EFFECT_SNAKE | ||
| 77 | # define RGBLIGHT_EFFECT_KNIGHT | ||
| 78 | # define RGBLIGHT_EFFECT_CHRISTMAS | ||
| 79 | # define RGBLIGHT_EFFECT_STATIC_GRADIENT | ||
| 80 | # define RGBLIGHT_EFFECT_RGB_TEST | ||
| 81 | # define RGBLIGHT_EFFECT_ALTERNATING | ||
| 82 | #endif | ||
| 83 | |||
| 84 | #ifdef RGBLIGHT_STATIC_PATTERNS | ||
| 85 | # define RGBLIGHT_EFFECT_STATIC_GRADIENT | ||
| 86 | #endif | ||
| 87 | |||
| 88 | // clang-format off | ||
| 89 | |||
| 90 | // check dynamic animation effects chose ? | ||
| 91 | #if defined(RGBLIGHT_EFFECT_BREATHING) \ | ||
| 92 | || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) \ | ||
| 93 | || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) \ | ||
| 94 | || defined(RGBLIGHT_EFFECT_SNAKE) \ | ||
| 95 | || defined(RGBLIGHT_EFFECT_KNIGHT) \ | ||
| 96 | || defined(RGBLIGHT_EFFECT_CHRISTMAS) \ | ||
| 97 | || defined(RGBLIGHT_EFFECT_RGB_TEST) \ | ||
| 98 | || defined(RGBLIGHT_EFFECT_ALTERNATING) \ | ||
| 99 | || defined(RGBLIGHT_EFFECT_TWINKLE) | ||
| 100 | # define RGBLIGHT_USE_TIMER | ||
| 101 | #endif | ||
| 102 | |||
| 103 | // clang-format on | ||
| 104 | |||
| 105 | #define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym, | ||
| 106 | #define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym, | ||
| 107 | #define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym, | ||
| 108 | #define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym, | ||
| 109 | #define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym, | ||
| 110 | #define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##sym, | ||
| 111 | enum RGBLIGHT_EFFECT_MODE { | ||
| 112 | RGBLIGHT_MODE_zero = 0, | ||
| 113 | #include "rgblight_modes.h" | ||
| 114 | RGBLIGHT_MODE_last | ||
| 115 | }; | ||
| 116 | |||
| 117 | #define RGBLIGHT_MODES (RGBLIGHT_MODE_last - 1) | ||
| 118 | |||
| 119 | // sample: #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 | ||
| 120 | |||
| 121 | #ifndef RGBLIGHT_EFFECT_BREATHE_MAX | ||
| 122 | # define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255 | ||
| 123 | #endif | ||
| 124 | |||
| 125 | #ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH | ||
| 126 | # define RGBLIGHT_EFFECT_SNAKE_LENGTH 4 | ||
| 127 | #endif | ||
| 128 | |||
| 129 | #ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH | ||
| 130 | # define RGBLIGHT_EFFECT_KNIGHT_LENGTH 3 | ||
| 131 | #endif | ||
| 132 | |||
| 133 | #ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET | ||
| 134 | # define RGBLIGHT_EFFECT_KNIGHT_OFFSET 0 | ||
| 135 | #endif | ||
| 136 | |||
| 137 | #ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM | ||
| 138 | # define RGBLIGHT_EFFECT_KNIGHT_LED_NUM (rgblight_ranges.effect_num_leds) | ||
| 139 | #endif | ||
| 140 | |||
| 141 | #ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL | ||
| 142 | # define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 40 | ||
| 143 | #endif | ||
| 144 | |||
| 145 | #ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP | ||
| 146 | # define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2 | ||
| 147 | #endif | ||
| 148 | |||
| 149 | #ifndef RGBLIGHT_EFFECT_TWINKLE_LIFE | ||
| 150 | # define RGBLIGHT_EFFECT_TWINKLE_LIFE 200 | ||
| 151 | #endif | ||
| 152 | |||
| 153 | #ifndef RGBLIGHT_EFFECT_TWINKLE_PROBABILITY | ||
| 154 | # define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1 / 127 | ||
| 155 | #endif | ||
| 156 | |||
| 157 | #ifndef RGBLIGHT_HUE_STEP | ||
| 158 | # define RGBLIGHT_HUE_STEP 8 | ||
| 159 | #endif | ||
| 160 | #ifndef RGBLIGHT_SAT_STEP | ||
| 161 | # define RGBLIGHT_SAT_STEP 17 | ||
| 162 | #endif | ||
| 163 | #ifndef RGBLIGHT_VAL_STEP | ||
| 164 | # define RGBLIGHT_VAL_STEP 17 | ||
| 165 | #endif | ||
| 166 | #ifndef RGBLIGHT_LIMIT_VAL | ||
| 167 | # define RGBLIGHT_LIMIT_VAL 255 | ||
| 168 | #endif | ||
| 169 | |||
| 170 | #include <stdint.h> | ||
| 171 | #include <stdbool.h> | ||
| 172 | #include "progmem.h" | ||
| 173 | #include "eeconfig.h" | ||
| 174 | #include "ws2812.h" | ||
| 175 | #include "color.h" | ||
| 176 | #include "rgblight_list.h" | ||
| 177 | |||
| 178 | #ifdef RGBLIGHT_LAYERS | ||
| 179 | typedef struct { | ||
| 180 | uint8_t index; // The first LED to light | ||
| 181 | uint8_t count; // The number of LEDs to light | ||
| 182 | uint8_t hue; | ||
| 183 | uint8_t sat; | ||
| 184 | uint8_t val; | ||
| 185 | } rgblight_segment_t; | ||
| 186 | |||
| 187 | # define RGBLIGHT_END_SEGMENT_INDEX (255) | ||
| 188 | # define RGBLIGHT_END_SEGMENTS \ | ||
| 189 | { RGBLIGHT_END_SEGMENT_INDEX, 0, 0, 0 } | ||
| 190 | # ifndef RGBLIGHT_MAX_LAYERS | ||
| 191 | # define RGBLIGHT_MAX_LAYERS 8 | ||
| 192 | # endif | ||
| 193 | # if RGBLIGHT_MAX_LAYERS <= 0 | ||
| 194 | # error invalid RGBLIGHT_MAX_LAYERS value (must be >= 1) | ||
| 195 | # elif RGBLIGHT_MAX_LAYERS <= 8 | ||
| 196 | typedef uint8_t rgblight_layer_mask_t; | ||
| 197 | # elif RGBLIGHT_MAX_LAYERS <= 16 | ||
| 198 | typedef uint16_t rgblight_layer_mask_t; | ||
| 199 | # elif RGBLIGHT_MAX_LAYERS <= 32 | ||
| 200 | typedef uint32_t rgblight_layer_mask_t; | ||
| 201 | # else | ||
| 202 | # error invalid RGBLIGHT_MAX_LAYERS value (must be <= 32) | ||
| 203 | # endif | ||
| 204 | # define RGBLIGHT_LAYER_SEGMENTS(...) \ | ||
| 205 | { __VA_ARGS__, RGBLIGHT_END_SEGMENTS } | ||
| 206 | # define RGBLIGHT_LAYERS_LIST(...) \ | ||
| 207 | { __VA_ARGS__, NULL } | ||
| 208 | |||
| 209 | // Get/set enabled rgblight layers | ||
| 210 | void rgblight_set_layer_state(uint8_t layer, bool enabled); | ||
| 211 | bool rgblight_get_layer_state(uint8_t layer); | ||
| 212 | |||
| 213 | // Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers | ||
| 214 | extern const rgblight_segment_t *const *rgblight_layers; | ||
| 215 | |||
| 216 | # ifdef RGBLIGHT_LAYER_BLINK | ||
| 217 | # define RGBLIGHT_USE_TIMER | ||
| 218 | void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms); | ||
| 219 | void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times); | ||
| 220 | # endif | ||
| 221 | |||
| 222 | #endif | ||
| 223 | |||
| 224 | extern LED_TYPE led[RGBLED_NUM]; | ||
| 225 | |||
| 226 | extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; | ||
| 227 | extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM; | ||
| 228 | extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM; | ||
| 229 | extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM; | ||
| 230 | extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM; | ||
| 231 | extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM; | ||
| 232 | extern const uint8_t RGBLED_TWINKLE_INTERVALS[3] PROGMEM; | ||
| 233 | extern bool is_rgblight_initialized; | ||
| 234 | |||
| 235 | // Should stay in sycn with rgb matrix config as we reuse eeprom storage for both (for now) | ||
| 236 | typedef union { | ||
| 237 | uint32_t raw; | ||
| 238 | struct { | ||
| 239 | bool enable : 1; | ||
| 240 | uint8_t mode : 7; | ||
| 241 | uint8_t hue : 8; | ||
| 242 | uint8_t sat : 8; | ||
| 243 | uint8_t val : 8; | ||
| 244 | uint8_t speed : 8; // EECONFIG needs to be increased to support this | ||
| 245 | }; | ||
| 246 | } rgblight_config_t; | ||
| 247 | |||
| 248 | typedef struct _rgblight_status_t { | ||
| 249 | uint8_t base_mode; | ||
| 250 | bool timer_enabled; | ||
| 251 | #ifdef RGBLIGHT_SPLIT | ||
| 252 | uint8_t change_flags; | ||
| 253 | #endif | ||
| 254 | #ifdef RGBLIGHT_LAYERS | ||
| 255 | rgblight_layer_mask_t enabled_layer_mask; | ||
| 256 | #endif | ||
| 257 | } rgblight_status_t; | ||
| 258 | |||
| 259 | /* | ||
| 260 | * Structure for RGB Light clipping ranges | ||
| 261 | */ | ||
| 262 | typedef struct _rgblight_ranges_t { | ||
| 263 | uint8_t clipping_start_pos; | ||
| 264 | uint8_t clipping_num_leds; | ||
| 265 | uint8_t effect_start_pos; | ||
| 266 | uint8_t effect_end_pos; | ||
| 267 | uint8_t effect_num_leds; | ||
| 268 | } rgblight_ranges_t; | ||
| 269 | |||
| 270 | extern rgblight_ranges_t rgblight_ranges; | ||
| 271 | |||
| 272 | /* === Utility Functions ===*/ | ||
| 273 | void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); | ||
| 274 | void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); // without RGBLIGHT_LIMIT_VAL check | ||
| 275 | void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1); | ||
| 276 | |||
| 277 | /* === Low level Functions === */ | ||
| 278 | void rgblight_set(void); | ||
| 279 | void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds); | ||
| 280 | |||
| 281 | /* === Effects and Animations Functions === */ | ||
| 282 | /* effect range setting */ | ||
| 283 | void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds); | ||
| 284 | |||
| 285 | /* direct operation */ | ||
| 286 | void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index); | ||
| 287 | void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index); | ||
| 288 | void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end); | ||
| 289 | void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end); | ||
| 290 | void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b); | ||
| 291 | |||
| 292 | #ifndef RGBLIGHT_SPLIT | ||
| 293 | void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b); | ||
| 294 | void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b); | ||
| 295 | void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val); | ||
| 296 | void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val); | ||
| 297 | #endif | ||
| 298 | |||
| 299 | /* effect mode change */ | ||
| 300 | void rgblight_mode(uint8_t mode); | ||
| 301 | void rgblight_mode_noeeprom(uint8_t mode); | ||
| 302 | void rgblight_increase(void); | ||
| 303 | void rgblight_decrease(void); | ||
| 304 | void rgblight_step(void); | ||
| 305 | void rgblight_step_noeeprom(void); | ||
| 306 | void rgblight_step_reverse(void); | ||
| 307 | void rgblight_step_reverse_noeeprom(void); | ||
| 308 | |||
| 309 | /* effects mode disable/enable */ | ||
| 310 | void rgblight_toggle(void); | ||
| 311 | void rgblight_toggle_noeeprom(void); | ||
| 312 | void rgblight_enable(void); | ||
| 313 | void rgblight_enable_noeeprom(void); | ||
| 314 | void rgblight_disable(void); | ||
| 315 | void rgblight_disable_noeeprom(void); | ||
| 316 | |||
| 317 | /* hue, sat, val change */ | ||
| 318 | void rgblight_increase_hue(void); | ||
| 319 | void rgblight_increase_hue_noeeprom(void); | ||
| 320 | void rgblight_decrease_hue(void); | ||
| 321 | void rgblight_decrease_hue_noeeprom(void); | ||
| 322 | void rgblight_increase_sat(void); | ||
| 323 | void rgblight_increase_sat_noeeprom(void); | ||
| 324 | void rgblight_decrease_sat(void); | ||
| 325 | void rgblight_decrease_sat_noeeprom(void); | ||
| 326 | void rgblight_increase_val(void); | ||
| 327 | void rgblight_increase_val_noeeprom(void); | ||
| 328 | void rgblight_decrease_val(void); | ||
| 329 | void rgblight_decrease_val_noeeprom(void); | ||
| 330 | void rgblight_increase_speed(void); | ||
| 331 | void rgblight_increase_speed_noeeprom(void); | ||
| 332 | void rgblight_decrease_speed(void); | ||
| 333 | void rgblight_decrease_speed_noeeprom(void); | ||
| 334 | void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val); | ||
| 335 | void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val); | ||
| 336 | |||
| 337 | /* effect speed */ | ||
| 338 | uint8_t rgblight_get_speed(void); | ||
| 339 | void rgblight_set_speed(uint8_t speed); | ||
| 340 | void rgblight_set_speed_noeeprom(uint8_t speed); | ||
| 341 | |||
| 342 | /* reset */ | ||
| 343 | void rgblight_reload_from_eeprom(void); | ||
| 344 | |||
| 345 | /* query */ | ||
| 346 | uint8_t rgblight_get_mode(void); | ||
| 347 | uint8_t rgblight_get_hue(void); | ||
| 348 | uint8_t rgblight_get_sat(void); | ||
| 349 | uint8_t rgblight_get_val(void); | ||
| 350 | bool rgblight_is_enabled(void); | ||
| 351 | HSV rgblight_get_hsv(void); | ||
| 352 | |||
| 353 | /* === qmk_firmware (core)internal Functions === */ | ||
| 354 | void rgblight_init(void); | ||
| 355 | void rgblight_suspend(void); | ||
| 356 | void rgblight_wakeup(void); | ||
| 357 | uint32_t rgblight_read_dword(void); | ||
| 358 | void rgblight_update_dword(uint32_t dword); | ||
| 359 | uint32_t eeconfig_read_rgblight(void); | ||
| 360 | void eeconfig_update_rgblight(uint32_t val); | ||
| 361 | void eeconfig_update_rgblight_current(void); | ||
| 362 | void eeconfig_update_rgblight_default(void); | ||
| 363 | void eeconfig_debug_rgblight(void); | ||
| 364 | |||
| 365 | void rgb_matrix_increase(void); | ||
| 366 | void rgb_matrix_decrease(void); | ||
| 367 | |||
| 368 | void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom); | ||
| 369 | void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom); | ||
| 370 | |||
| 371 | #define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF) | ||
| 372 | void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b); | ||
| 373 | |||
| 374 | #ifdef RGBLIGHT_USE_TIMER | ||
| 375 | void rgblight_task(void); | ||
| 376 | void rgblight_timer_init(void); | ||
| 377 | void rgblight_timer_enable(void); | ||
| 378 | void rgblight_timer_disable(void); | ||
| 379 | void rgblight_timer_toggle(void); | ||
| 380 | #else | ||
| 381 | # define rgblight_task() | ||
| 382 | # define rgblight_timer_init() | ||
| 383 | # define rgblight_timer_enable() | ||
| 384 | # define rgblight_timer_disable() | ||
| 385 | # define rgblight_timer_toggle() | ||
| 386 | #endif | ||
| 387 | |||
| 388 | #ifdef RGBLIGHT_SPLIT | ||
| 389 | # define RGBLIGHT_STATUS_CHANGE_MODE (1 << 0) | ||
| 390 | # define RGBLIGHT_STATUS_CHANGE_HSVS (1 << 1) | ||
| 391 | # define RGBLIGHT_STATUS_CHANGE_TIMER (1 << 2) | ||
| 392 | # define RGBLIGHT_STATUS_ANIMATION_TICK (1 << 3) | ||
| 393 | # define RGBLIGHT_STATUS_CHANGE_LAYERS (1 << 4) | ||
| 394 | |||
| 395 | typedef struct _rgblight_syncinfo_t { | ||
| 396 | rgblight_config_t config; | ||
| 397 | rgblight_status_t status; | ||
| 398 | } rgblight_syncinfo_t; | ||
| 399 | |||
| 400 | /* for split keyboard master side */ | ||
| 401 | uint8_t rgblight_get_change_flags(void); | ||
| 402 | void rgblight_clear_change_flags(void); | ||
| 403 | void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo); | ||
| 404 | /* for split keyboard slave side */ | ||
| 405 | void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom); | ||
| 406 | #endif | ||
| 407 | |||
| 408 | #ifdef RGBLIGHT_USE_TIMER | ||
| 409 | |||
| 410 | typedef struct _animation_status_t { | ||
| 411 | uint16_t last_timer; | ||
| 412 | uint8_t delta; /* mode - base_mode */ | ||
| 413 | bool restart; | ||
| 414 | union { | ||
| 415 | uint16_t pos16; | ||
| 416 | uint8_t pos; | ||
| 417 | int8_t current_hue; | ||
| 418 | uint16_t current_offset; | ||
| 419 | }; | ||
| 420 | } animation_status_t; | ||
| 421 | |||
| 422 | extern animation_status_t animation_status; | ||
| 423 | |||
| 424 | void rgblight_effect_breathing(animation_status_t *anim); | ||
| 425 | void rgblight_effect_rainbow_mood(animation_status_t *anim); | ||
| 426 | void rgblight_effect_rainbow_swirl(animation_status_t *anim); | ||
| 427 | void rgblight_effect_snake(animation_status_t *anim); | ||
| 428 | void rgblight_effect_knight(animation_status_t *anim); | ||
| 429 | void rgblight_effect_christmas(animation_status_t *anim); | ||
| 430 | void rgblight_effect_rgbtest(animation_status_t *anim); | ||
| 431 | void rgblight_effect_alternating(animation_status_t *anim); | ||
| 432 | void rgblight_effect_twinkle(animation_status_t *anim); | ||
| 433 | |||
| 434 | #endif | ||
diff --git a/quantum/rgblight/rgblight_breathe_table.h b/quantum/rgblight/rgblight_breathe_table.h new file mode 100644 index 000000000..30245318b --- /dev/null +++ b/quantum/rgblight/rgblight_breathe_table.h | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #define RGBLIGHT_EFFECT_BREATHE_TABLE | ||
| 4 | |||
| 5 | // clang-format off | ||
| 6 | |||
| 7 | // Breathing center: 1.85 | ||
| 8 | // Breathing max: 255 | ||
| 9 | |||
| 10 | const uint8_t PROGMEM rgblight_effect_breathe_table[] = { | ||
| 11 | #if RGBLIGHT_BREATHE_TABLE_SIZE == 256 | ||
| 12 | 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2A, 0x2C, | ||
| 13 | 0x2D, 0x2F, 0x30, 0x32, 0x33, 0x35, 0x36, 0x38, | ||
| 14 | 0x3A, 0x3B, 0x3D, 0x3E, 0x40, 0x42, 0x43, 0x45, | ||
| 15 | 0x47, 0x49, 0x4A, 0x4C, 0x4E, 0x50, 0x51, 0x53, | ||
| 16 | 0x55, 0x57, 0x59, 0x5A, 0x5C, 0x5E, 0x60, 0x62, | ||
| 17 | 0x64, 0x66, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x71, | ||
| 18 | 0x73, 0x75, 0x77, 0x79, 0x7B, 0x7D, 0x7F, 0x81, | ||
| 19 | 0x83, 0x85, 0x87, 0x89, 0x8A, 0x8C, 0x8E, 0x90, | ||
| 20 | 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0x9F, | ||
| 21 | 0xA1, 0xA3, 0xA5, 0xA7, 0xA8, 0xAA, 0xAC, 0xAE, | ||
| 22 | 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xB9, 0xBB, | ||
| 23 | 0xBC, 0xBE, 0xBF, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, | ||
| 24 | 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xD0, | ||
| 25 | 0xD1, 0xD2, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, | ||
| 26 | 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDB, | ||
| 27 | 0xDB, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDD, 0xDD, | ||
| 28 | 0xDD, 0xDD, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB, | ||
| 29 | 0xDB, 0xDB, 0xDA, 0xDA, 0xD9, 0xD9, 0xD8, 0xD7, | ||
| 30 | 0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD2, 0xD1, | ||
| 31 | 0xD0, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC7, | ||
| 32 | 0xC6, 0xC5, 0xC3, 0xC2, 0xC1, 0xBF, 0xBE, 0xBC, | ||
| 33 | 0xBB, 0xB9, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF, | ||
| 34 | 0xAE, 0xAC, 0xAA, 0xA8, 0xA7, 0xA5, 0xA3, 0xA1, | ||
| 35 | 0x9F, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92, | ||
| 36 | 0x90, 0x8E, 0x8C, 0x8A, 0x89, 0x87, 0x85, 0x83, | ||
| 37 | 0x81, 0x7F, 0x7D, 0x7B, 0x79, 0x77, 0x75, 0x73, | ||
| 38 | 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x68, 0x66, 0x64, | ||
| 39 | 0x62, 0x60, 0x5E, 0x5C, 0x5A, 0x59, 0x57, 0x55, | ||
| 40 | 0x53, 0x51, 0x50, 0x4E, 0x4C, 0x4A, 0x49, 0x47, | ||
| 41 | 0x45, 0x43, 0x42, 0x40, 0x3E, 0x3D, 0x3B, 0x3A, | ||
| 42 | 0x38, 0x36, 0x35, 0x33, 0x32, 0x30, 0x2F, 0x2D, | ||
| 43 | 0x2C, 0x2A, 0x29, 0x28, 0x26, 0x25, 0x23, 0x22 | ||
| 44 | #endif | ||
| 45 | |||
| 46 | #if RGBLIGHT_BREATHE_TABLE_SIZE == 128 | ||
| 47 | 0x22, 0x25, 0x28, 0x2A, | ||
| 48 | 0x2D, 0x30, 0x33, 0x36, | ||
| 49 | 0x3A, 0x3D, 0x40, 0x43, | ||
| 50 | 0x47, 0x4A, 0x4E, 0x51, | ||
| 51 | 0x55, 0x59, 0x5C, 0x60, | ||
| 52 | 0x64, 0x68, 0x6B, 0x6F, | ||
| 53 | 0x73, 0x77, 0x7B, 0x7F, | ||
| 54 | 0x83, 0x87, 0x8A, 0x8E, | ||
| 55 | 0x92, 0x96, 0x9A, 0x9E, | ||
| 56 | 0xA1, 0xA5, 0xA8, 0xAC, | ||
| 57 | 0xAF, 0xB3, 0xB6, 0xB9, | ||
| 58 | 0xBC, 0xBF, 0xC2, 0xC5, | ||
| 59 | 0xC7, 0xCA, 0xCC, 0xCE, | ||
| 60 | 0xD1, 0xD2, 0xD4, 0xD6, | ||
| 61 | 0xD7, 0xD9, 0xDA, 0xDB, | ||
| 62 | 0xDB, 0xDC, 0xDC, 0xDD, | ||
| 63 | 0xDD, 0xDC, 0xDC, 0xDC, | ||
| 64 | 0xDB, 0xDA, 0xD9, 0xD8, | ||
| 65 | 0xD7, 0xD5, 0xD3, 0xD2, | ||
| 66 | 0xD0, 0xCD, 0xCB, 0xC9, | ||
| 67 | 0xC6, 0xC3, 0xC1, 0xBE, | ||
| 68 | 0xBB, 0xB8, 0xB4, 0xB1, | ||
| 69 | 0xAE, 0xAA, 0xA7, 0xA3, | ||
| 70 | 0x9F, 0x9C, 0x98, 0x94, | ||
| 71 | 0x90, 0x8C, 0x89, 0x85, | ||
| 72 | 0x81, 0x7D, 0x79, 0x75, | ||
| 73 | 0x71, 0x6D, 0x69, 0x66, | ||
| 74 | 0x62, 0x5E, 0x5A, 0x57, | ||
| 75 | 0x53, 0x50, 0x4C, 0x49, | ||
| 76 | 0x45, 0x42, 0x3E, 0x3B, | ||
| 77 | 0x38, 0x35, 0x32, 0x2F, | ||
| 78 | 0x2C, 0x29, 0x26, 0x23 | ||
| 79 | #endif | ||
| 80 | |||
| 81 | #if RGBLIGHT_BREATHE_TABLE_SIZE == 64 | ||
| 82 | 0x22, 0x28, | ||
| 83 | 0x2D, 0x33, | ||
| 84 | 0x3A, 0x40, | ||
| 85 | 0x47, 0x4E, | ||
| 86 | 0x55, 0x5C, | ||
| 87 | 0x64, 0x6B, | ||
| 88 | 0x73, 0x7B, | ||
| 89 | 0x83, 0x8A, | ||
| 90 | 0x92, 0x9A, | ||
| 91 | 0xA1, 0xA8, | ||
| 92 | 0xAF, 0xB6, | ||
| 93 | 0xBC, 0xC2, | ||
| 94 | 0xC7, 0xCC, | ||
| 95 | 0xD1, 0xD4, | ||
| 96 | 0xD7, 0xDA, | ||
| 97 | 0xDB, 0xDC, | ||
| 98 | 0xDD, 0xDC, | ||
| 99 | 0xDB, 0xD9, | ||
| 100 | 0xD7, 0xD3, | ||
| 101 | 0xD0, 0xCB, | ||
| 102 | 0xC6, 0xC1, | ||
| 103 | 0xBB, 0xB4, | ||
| 104 | 0xAE, 0xA7, | ||
| 105 | 0x9F, 0x98, | ||
| 106 | 0x90, 0x89, | ||
| 107 | 0x81, 0x79, | ||
| 108 | 0x71, 0x69, | ||
| 109 | 0x62, 0x5A, | ||
| 110 | 0x53, 0x4C, | ||
| 111 | 0x45, 0x3E, | ||
| 112 | 0x38, 0x32, | ||
| 113 | 0x2C, 0x26 | ||
| 114 | #endif | ||
| 115 | }; | ||
| 116 | |||
| 117 | static const int table_scale = 256 / sizeof(rgblight_effect_breathe_table); | ||
diff --git a/quantum/rgblight/rgblight_list.h b/quantum/rgblight/rgblight_list.h new file mode 100644 index 000000000..0fd68b75f --- /dev/null +++ b/quantum/rgblight/rgblight_list.h | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | /* Copyright 2018 Jack Humbert | ||
| 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 | #pragma once | ||
| 17 | |||
| 18 | #include "color.h" | ||
| 19 | |||
| 20 | /* | ||
| 21 | ######################################################################################## | ||
| 22 | ## ## | ||
| 23 | ## ## | ||
| 24 | ## ## | ||
| 25 | ## The functions below have been deprecated and may be removed in a future release. ## | ||
| 26 | ## ## | ||
| 27 | ## Please use the values in color.h with the RGB functions. ## | ||
| 28 | ## ## | ||
| 29 | ## ## | ||
| 30 | ## ## | ||
| 31 | ######################################################################################## | ||
| 32 | */ | ||
| 33 | |||
| 34 | /* SET RGB List */ | ||
| 35 | #define rgblight_setrgb_white() rgblight_setrgb(RGB_WHITE) | ||
| 36 | #define rgblight_setrgb_red() rgblight_setrgb(RGB_RED) | ||
| 37 | #define rgblight_setrgb_coral() rgblight_setrgb(RGB_CORAL) | ||
| 38 | #define rgblight_setrgb_orange() rgblight_setrgb(RGB_ORANGE) | ||
| 39 | #define rgblight_setrgb_goldenrod() rgblight_setrgb(RGB_GOLDENROD) | ||
| 40 | #define rgblight_setrgb_gold() rgblight_setrgb(RGB_GOLD) | ||
| 41 | #define rgblight_setrgb_yellow() rgblight_setrgb(RGB_YELLOW) | ||
| 42 | #define rgblight_setrgb_chartreuse() rgblight_setrgb(RGB_CHARTREUSE) | ||
| 43 | #define rgblight_setrgb_green() rgblight_setrgb(RGB_GREEN) | ||
| 44 | #define rgblight_setrgb_springgreen() rgblight_setrgb(RGB_SPRINGGREEN) | ||
| 45 | #define rgblight_setrgb_turquoise() rgblight_setrgb(RGB_TURQUOISE) | ||
| 46 | #define rgblight_setrgb_teal() rgblight_setrgb(RGB_TEAL) | ||
| 47 | #define rgblight_setrgb_cyan() rgblight_setrgb(RGB_CYAN) | ||
| 48 | #define rgblight_setrgb_azure() rgblight_setrgb(RGB_AZURE) | ||
| 49 | #define rgblight_setrgb_blue() rgblight_setrgb(RGB_BLUE) | ||
| 50 | #define rgblight_setrgb_purple() rgblight_setrgb(RGB_PURPLE) | ||
| 51 | #define rgblight_setrgb_magenta() rgblight_setrgb(RGB_MAGENTA) | ||
| 52 | #define rgblight_setrgb_pink() rgblight_setrgb(RGB_PINK) | ||
| 53 | |||
| 54 | /* SET RGB List */ | ||
| 55 | #define rgblight_setrgb_white_at(at) rgblight_setrgb_at(RGB_WHITE, at) | ||
| 56 | #define rgblight_setrgb_red_at(at) rgblight_setrgb_at(RGB_RED, at) | ||
| 57 | #define rgblight_setrgb_coral_at(at) rgblight_setrgb_at(RGB_CORAL, at) | ||
| 58 | #define rgblight_setrgb_orange_at(at) rgblight_setrgb_at(RGB_ORANGE at) | ||
| 59 | #define rgblight_setrgb_goldenrod_at(at) rgblight_setrgb_at(RGB_GOLDENROD, at) | ||
| 60 | #define rgblight_setrgb_gold_at(at) rgblight_setrgb_at(RGB_GOLD, at) | ||
| 61 | #define rgblight_setrgb_yellow_at(at) rgblight_setrgb_at(RGB_YELLOW, at) | ||
| 62 | #define rgblight_setrgb_chartreuse_at(at) rgblight_setrgb_at(RGB_CHARTREUSE, at) | ||
| 63 | #define rgblight_setrgb_green_at(at) rgblight_setrgb_at(RGB_GREEN, at) | ||
| 64 | #define rgblight_setrgb_springgreen_at(at) rgblight_setrgb_at(RGB_SPRINGGREEN, at) | ||
| 65 | #define rgblight_setrgb_turquoise_at(at) rgblight_setrgb_at(RGB_TURQUOISE, at) | ||
| 66 | #define rgblight_setrgb_teal_at(at) rgblight_setrgb_at(RGB_TEAL, at) | ||
| 67 | #define rgblight_setrgb_cyan_at(at) rgblight_setrgb_at(RGB_CYAN, at) | ||
| 68 | #define rgblight_setrgb_azure_at(at) rgblight_setrgb_at(RGB_AZURE, at) | ||
| 69 | #define rgblight_setrgb_blue_at(at) rgblight_setrgb_at(RGB_BLUE, at) | ||
| 70 | #define rgblight_setrgb_purple_at(at) rgblight_setrgb_at(RGB_PURPLE, at) | ||
| 71 | #define rgblight_setrgb_magenta_at(at) rgblight_setrgb_at(RGB_MAGENTA, at) | ||
| 72 | #define rgblight_setrgb_pink_at(at) rgblight_setrgb_at(RGB_PINK, at) | ||
| 73 | |||
| 74 | /* SET HSV List */ | ||
| 75 | #define rgblight_sethsv_white() rgblight_sethsv(HSV_WHITE) | ||
| 76 | #define rgblight_sethsv_red() rgblight_sethsv(HSV_RED) | ||
| 77 | #define rgblight_sethsv_coral() rgblight_sethsv(HSV_CORAL) | ||
| 78 | #define rgblight_sethsv_orange() rgblight_sethsv(HSV_ORANGE) | ||
| 79 | #define rgblight_sethsv_goldenrod() rgblight_sethsv(HSV_GOLDENROD) | ||
| 80 | #define rgblight_sethsv_gold() rgblight_sethsv(HSV_GOLD) | ||
| 81 | #define rgblight_sethsv_yellow() rgblight_sethsv(HSV_YELLOW) | ||
| 82 | #define rgblight_sethsv_chartreuse() rgblight_sethsv(HSV_CHARTREUSE) | ||
| 83 | #define rgblight_sethsv_green() rgblight_sethsv(HSV_GREEN) | ||
| 84 | #define rgblight_sethsv_springgreen() rgblight_sethsv(HSV_SPRINGGREEN) | ||
| 85 | #define rgblight_sethsv_turquoise() rgblight_sethsv(HSV_TURQUOISE) | ||
| 86 | #define rgblight_sethsv_teal() rgblight_sethsv(HSV_TEAL) | ||
| 87 | #define rgblight_sethsv_cyan() rgblight_sethsv(HSV_CYAN) | ||
| 88 | #define rgblight_sethsv_azure() rgblight_sethsv(HSV_AZURE) | ||
| 89 | #define rgblight_sethsv_blue() rgblight_sethsv(HSV_BLUE) | ||
| 90 | #define rgblight_sethsv_purple() rgblight_sethsv(HSV_PURPLE) | ||
| 91 | #define rgblight_sethsv_magenta() rgblight_sethsv(HSV_MAGENTA) | ||
| 92 | #define rgblight_sethsv_pink() rgblight_sethsv(HSV_PINK) | ||
| 93 | |||
| 94 | /* SET HSV List */ | ||
| 95 | /* If you're doing layer indication, this is best, as it won't */ | ||
| 96 | /* write to the eeprom, since it's limited (very high value). */ | ||
| 97 | /* If you want to use modes with this (since you can), then you */ | ||
| 98 | /* want to use rgblight_mode_noeeprom(x) instead. */ | ||
| 99 | #define rgblight_sethsv_noeeprom_white() rgblight_sethsv_noeeprom(HSV_WHITE) | ||
| 100 | #define rgblight_sethsv_noeeprom_red() rgblight_sethsv_noeeprom(HSV_RED) | ||
| 101 | #define rgblight_sethsv_noeeprom_coral() rgblight_sethsv_noeeprom(HSV_CORAL) | ||
| 102 | #define rgblight_sethsv_noeeprom_orange() rgblight_sethsv_noeeprom(HSV_ORANGE) | ||
| 103 | #define rgblight_sethsv_noeeprom_goldenrod() rgblight_sethsv_noeeprom(HSV_GOLDENROD) | ||
| 104 | #define rgblight_sethsv_noeeprom_gold() rgblight_sethsv_noeeprom(HSV_GOLD) | ||
| 105 | #define rgblight_sethsv_noeeprom_yellow() rgblight_sethsv_noeeprom(HSV_YELLOW) | ||
| 106 | #define rgblight_sethsv_noeeprom_chartreuse() rgblight_sethsv_noeeprom(HSV_CHARTREUSE) | ||
| 107 | #define rgblight_sethsv_noeeprom_green() rgblight_sethsv_noeeprom(HSV_GREEN) | ||
| 108 | #define rgblight_sethsv_noeeprom_springgreen() rgblight_sethsv_noeeprom(HSV_SPRINGGREEN) | ||
| 109 | #define rgblight_sethsv_noeeprom_turquoise() rgblight_sethsv_noeeprom(HSV_TURQUOISE) | ||
| 110 | #define rgblight_sethsv_noeeprom_teal() rgblight_sethsv_noeeprom(HSV_TEAL) | ||
| 111 | #define rgblight_sethsv_noeeprom_cyan() rgblight_sethsv_noeeprom(HSV_CYAN) | ||
| 112 | #define rgblight_sethsv_noeeprom_azure() rgblight_sethsv_noeeprom(HSV_AZURE) | ||
| 113 | #define rgblight_sethsv_noeeprom_blue() rgblight_sethsv_noeeprom(HSV_BLUE) | ||
| 114 | #define rgblight_sethsv_noeeprom_purple() rgblight_sethsv_noeeprom(HSV_PURPLE) | ||
| 115 | #define rgblight_sethsv_noeeprom_magenta() rgblight_sethsv_noeeprom(HSV_MAGENTA) | ||
| 116 | #define rgblight_sethsv_noeeprom_pink() rgblight_sethsv_noeeprom(HSV_PINK) | ||
| 117 | |||
| 118 | /* SET HSV List */ | ||
| 119 | #define rgblight_sethsv_white_at(at) rgblight_sethsv_at(HSV_WHITE, at) | ||
| 120 | #define rgblight_sethsv_red_at(at) rgblight_sethsv_at(HSV_RED, at) | ||
| 121 | #define rgblight_sethsv_coral_at(at) rgblight_sethsv_at(HSV_CORAL, at) | ||
| 122 | #define rgblight_sethsv_orange_at(at) rgblight_sethsv_at(HSV_ORANGE, at) | ||
| 123 | #define rgblight_sethsv_goldenrod_at(at) rgblight_sethsv_at(HSV_GOLDENROD, at) | ||
| 124 | #define rgblight_sethsv_gold_at(at) rgblight_sethsv_at(HSV_GOLD, at) | ||
| 125 | #define rgblight_sethsv_yellow_at(at) rgblight_sethsv_at(HSV_YELLOW, at) | ||
| 126 | #define rgblight_sethsv_chartreuse_at(at) rgblight_sethsv_at(HSV_CHARTREUSE, at) | ||
| 127 | #define rgblight_sethsv_green_at(at) rgblight_sethsv_at(HSV_GREEN, at) | ||
| 128 | #define rgblight_sethsv_springgreen_at(at) rgblight_sethsv_at(HSV_SPRINGGREEN, at) | ||
| 129 | #define rgblight_sethsv_turquoise_at(at) rgblight_sethsv_at(HSV_TURQUOISE, at) | ||
| 130 | #define rgblight_sethsv_teal_at(at) rgblight_sethsv_at(HSV_TEAL, at) | ||
| 131 | #define rgblight_sethsv_cyan_at(at) rgblight_sethsv_at(HSV_CYAN, at) | ||
| 132 | #define rgblight_sethsv_azure_at(at) rgblight_sethsv_at(HSV_AZURE, at) | ||
| 133 | #define rgblight_sethsv_blue_at(at) rgblight_sethsv_at(HSV_BLUE, at) | ||
| 134 | #define rgblight_sethsv_purple_at(at) rgblight_sethsv_at(HSV_PURPLE, at) | ||
| 135 | #define rgblight_sethsv_magenta_at(at) rgblight_sethsv_at(HSV_MAGENTA, at) | ||
| 136 | #define rgblight_sethsv_pink_at(at) rgblight_sethsv_at(HSV_PINK, at) | ||
diff --git a/quantum/rgblight/rgblight_modes.h b/quantum/rgblight/rgblight_modes.h new file mode 100644 index 000000000..7abdb87bc --- /dev/null +++ b/quantum/rgblight/rgblight_modes.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | #ifdef _RGBM_SINGLE_STATIC | ||
| 2 | _RGBM_SINGLE_STATIC(STATIC_LIGHT) | ||
| 3 | # ifdef RGBLIGHT_EFFECT_BREATHING | ||
| 4 | _RGBM_MULTI_DYNAMIC(BREATHING) | ||
| 5 | _RGBM_TMP_DYNAMIC(breathing_3, BREATHING) | ||
| 6 | _RGBM_TMP_DYNAMIC(breathing_4, BREATHING) | ||
| 7 | _RGBM_TMP_DYNAMIC(BREATHING_end, BREATHING) | ||
| 8 | # endif | ||
| 9 | # ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD | ||
| 10 | _RGBM_MULTI_DYNAMIC(RAINBOW_MOOD) | ||
| 11 | _RGBM_TMP_DYNAMIC(rainbow_mood_7, RAINBOW_MOOD) | ||
| 12 | _RGBM_TMP_DYNAMIC(RAINBOW_MOOD_end, RAINBOW_MOOD) | ||
| 13 | # endif | ||
| 14 | # ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL | ||
| 15 | _RGBM_MULTI_DYNAMIC(RAINBOW_SWIRL) | ||
| 16 | _RGBM_TMP_DYNAMIC(rainbow_swirl_10, RAINBOW_SWIRL) | ||
| 17 | _RGBM_TMP_DYNAMIC(rainbow_swirl_11, RAINBOW_SWIRL) | ||
| 18 | _RGBM_TMP_DYNAMIC(rainbow_swirl_12, RAINBOW_SWIRL) | ||
| 19 | _RGBM_TMP_DYNAMIC(rainbow_swirl_13, RAINBOW_SWIRL) | ||
| 20 | _RGBM_TMP_DYNAMIC(RAINBOW_SWIRL_end, RAINBOW_SWIRL) | ||
| 21 | # endif | ||
| 22 | # ifdef RGBLIGHT_EFFECT_SNAKE | ||
| 23 | _RGBM_MULTI_DYNAMIC(SNAKE) | ||
| 24 | _RGBM_TMP_DYNAMIC(snake_16, SNAKE) | ||
| 25 | _RGBM_TMP_DYNAMIC(snake_17, SNAKE) | ||
| 26 | _RGBM_TMP_DYNAMIC(snake_18, SNAKE) | ||
| 27 | _RGBM_TMP_DYNAMIC(snake_19, SNAKE) | ||
| 28 | _RGBM_TMP_DYNAMIC(SNAKE_end, SNAKE) | ||
| 29 | # endif | ||
| 30 | # ifdef RGBLIGHT_EFFECT_KNIGHT | ||
| 31 | _RGBM_MULTI_DYNAMIC(KNIGHT) | ||
| 32 | _RGBM_TMP_DYNAMIC(knight_22, KNIGHT) | ||
| 33 | _RGBM_TMP_DYNAMIC(KNIGHT_end, KNIGHT) | ||
| 34 | # endif | ||
| 35 | # ifdef RGBLIGHT_EFFECT_CHRISTMAS | ||
| 36 | _RGBM_SINGLE_DYNAMIC(CHRISTMAS) | ||
| 37 | # endif | ||
| 38 | # ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT | ||
| 39 | _RGBM_MULTI_STATIC(STATIC_GRADIENT) | ||
| 40 | _RGBM_TMP_STATIC(static_gradient_26, STATIC_GRADIENT) | ||
| 41 | _RGBM_TMP_STATIC(static_gradient_27, STATIC_GRADIENT) | ||
| 42 | _RGBM_TMP_STATIC(static_gradient_28, STATIC_GRADIENT) | ||
| 43 | _RGBM_TMP_STATIC(static_gradient_29, STATIC_GRADIENT) | ||
| 44 | _RGBM_TMP_STATIC(static_gradient_30, STATIC_GRADIENT) | ||
| 45 | _RGBM_TMP_STATIC(static_gradient_31, STATIC_GRADIENT) | ||
| 46 | _RGBM_TMP_STATIC(static_gradient_32, STATIC_GRADIENT) | ||
| 47 | _RGBM_TMP_STATIC(static_gradient_33, STATIC_GRADIENT) | ||
| 48 | _RGBM_TMP_STATIC(STATIC_GRADIENT_end, STATIC_GRADIENT) | ||
| 49 | # endif | ||
| 50 | # ifdef RGBLIGHT_EFFECT_RGB_TEST | ||
| 51 | _RGBM_SINGLE_DYNAMIC(RGB_TEST) | ||
| 52 | # endif | ||
| 53 | # ifdef RGBLIGHT_EFFECT_ALTERNATING | ||
| 54 | _RGBM_SINGLE_DYNAMIC(ALTERNATING) | ||
| 55 | # endif | ||
| 56 | # ifdef RGBLIGHT_EFFECT_TWINKLE | ||
| 57 | _RGBM_MULTI_DYNAMIC(TWINKLE) | ||
| 58 | _RGBM_TMP_DYNAMIC(twinkle_38, TWINKLE) | ||
| 59 | _RGBM_TMP_DYNAMIC(twinkle_39, TWINKLE) | ||
| 60 | _RGBM_TMP_DYNAMIC(twinkle_40, TWINKLE) | ||
| 61 | _RGBM_TMP_DYNAMIC(twinkle_41, TWINKLE) | ||
| 62 | _RGBM_TMP_DYNAMIC(TWINKLE_end, TWINKLE) | ||
| 63 | # endif | ||
| 64 | //// Add a new mode here. | ||
| 65 | // #ifdef RGBLIGHT_EFFECT_<name> | ||
| 66 | // _RGBM_<SINGLE|MULTI>_<STATIC|DYNAMIC>( <name> ) | ||
| 67 | // #endif | ||
| 68 | #endif | ||
| 69 | |||
| 70 | #undef _RGBM_SINGLE_STATIC | ||
| 71 | #undef _RGBM_SINGLE_DYNAMIC | ||
| 72 | #undef _RGBM_MULTI_STATIC | ||
| 73 | #undef _RGBM_MULTI_DYNAMIC | ||
| 74 | #undef _RGBM_TMP_STATIC | ||
| 75 | #undef _RGBM_TMP_DYNAMIC | ||
diff --git a/quantum/rgblight/rgblight_post_config.h b/quantum/rgblight/rgblight_post_config.h new file mode 100644 index 000000000..3c14cb610 --- /dev/null +++ b/quantum/rgblight/rgblight_post_config.h | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #if defined(RGBLED_SPLIT) && !defined(RGBLIGHT_SPLIT) | ||
| 2 | // When RGBLED_SPLIT is defined, | ||
| 3 | // it is considered that RGBLIGHT_SPLIT is defined implicitly. | ||
| 4 | # define RGBLIGHT_SPLIT | ||
| 5 | #endif | ||
