rgblight.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102
  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. #ifdef __AVR__
  19. #include <avr/eeprom.h>
  20. #include <avr/interrupt.h>
  21. #endif
  22. #ifdef STM32_EEPROM_ENABLE
  23. #include "hal.h"
  24. #include "eeprom.h"
  25. #include "eeprom_stm32.h"
  26. #endif
  27. #include "wait.h"
  28. #include "progmem.h"
  29. #include "timer.h"
  30. #include "rgblight.h"
  31. #include "color.h"
  32. #include "debug.h"
  33. #include "led_tables.h"
  34. #include "lib/lib8tion/lib8tion.h"
  35. #ifdef VELOCIKEY_ENABLE
  36. #include "velocikey.h"
  37. #endif
  38. #ifdef RGBLIGHT_SPLIT
  39. /* for split keyboard */
  40. #define RGBLIGHT_SPLIT_SET_CHANGE_MODE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_MODE
  41. #define RGBLIGHT_SPLIT_SET_CHANGE_HSVS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_HSVS
  42. #define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE|RGBLIGHT_STATUS_CHANGE_HSVS)
  43. #define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER
  44. #define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK
  45. #else
  46. #define RGBLIGHT_SPLIT_SET_CHANGE_MODE
  47. #define RGBLIGHT_SPLIT_SET_CHANGE_HSVS
  48. #define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS
  49. #define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE
  50. #define RGBLIGHT_SPLIT_ANIMATION_TICK
  51. #endif
  52. #define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
  53. #define _RGBM_SINGLE_DYNAMIC(sym)
  54. #define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
  55. #define _RGBM_MULTI_DYNAMIC(sym)
  56. #define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_ ## sym,
  57. #define _RGBM_TMP_DYNAMIC(sym, msym)
  58. static uint8_t static_effect_table [] = {
  59. #include "rgblight_modes.h"
  60. };
  61. #define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
  62. #define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
  63. #define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
  64. #define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
  65. #define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_ ## msym,
  66. #define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_ ## msym,
  67. static uint8_t mode_base_table [] = {
  68. 0, // RGBLIGHT_MODE_zero
  69. #include "rgblight_modes.h"
  70. };
  71. static inline int is_static_effect(uint8_t mode) {
  72. return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL;
  73. }
  74. #ifdef RGBLIGHT_LED_MAP
  75. const uint8_t led_map[] PROGMEM = RGBLIGHT_LED_MAP;
  76. #endif
  77. #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
  78. __attribute__ ((weak))
  79. const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
  80. #endif
  81. rgblight_config_t rgblight_config;
  82. rgblight_status_t rgblight_status = { .timer_enabled = false };
  83. bool is_rgblight_initialized = false;
  84. #ifdef RGBLIGHT_USE_TIMER
  85. animation_status_t animation_status = {};
  86. #endif
  87. #ifndef LED_ARRAY
  88. LED_TYPE led[RGBLED_NUM];
  89. #define LED_ARRAY led
  90. #endif
  91. static uint8_t clipping_start_pos = 0;
  92. static uint8_t clipping_num_leds = RGBLED_NUM;
  93. void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
  94. clipping_start_pos = start_pos;
  95. clipping_num_leds = num_leds;
  96. }
  97. void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
  98. HSV hsv = { hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val };
  99. RGB rgb = hsv_to_rgb(hsv);
  100. setrgb(rgb.r, rgb.g, rgb.b, led1);
  101. }
  102. void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) {
  103. (*led1).r = r;
  104. (*led1).g = g;
  105. (*led1).b = b;
  106. }
  107. void rgblight_check_config(void) {
  108. /* Add some out of bound checks for RGB light config */
  109. if (rgblight_config.mode < RGBLIGHT_MODE_STATIC_LIGHT) {
  110. rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
  111. }
  112. else if (rgblight_config.mode > RGBLIGHT_MODES) {
  113. rgblight_config.mode = RGBLIGHT_MODES;
  114. }
  115. if (rgblight_config.val > RGBLIGHT_LIMIT_VAL) {
  116. rgblight_config.val = RGBLIGHT_LIMIT_VAL;
  117. }
  118. }
  119. uint32_t eeconfig_read_rgblight(void) {
  120. #if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE)
  121. return eeprom_read_dword(EECONFIG_RGBLIGHT);
  122. #else
  123. return 0;
  124. #endif
  125. }
  126. void eeconfig_update_rgblight(uint32_t val) {
  127. #if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE)
  128. rgblight_check_config();
  129. eeprom_update_dword(EECONFIG_RGBLIGHT, val);
  130. #endif
  131. }
  132. void eeconfig_update_rgblight_default(void) {
  133. //dprintf("eeconfig_update_rgblight_default\n");
  134. rgblight_config.enable = 1;
  135. rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
  136. rgblight_config.hue = 0;
  137. rgblight_config.sat = UINT8_MAX;
  138. rgblight_config.val = RGBLIGHT_LIMIT_VAL;
  139. rgblight_config.speed = 0;
  140. RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
  141. eeconfig_update_rgblight(rgblight_config.raw);
  142. }
  143. void eeconfig_debug_rgblight(void) {
  144. dprintf("rgblight_config eprom\n");
  145. dprintf("rgblight_config.enable = %d\n", rgblight_config.enable);
  146. dprintf("rghlight_config.mode = %d\n", rgblight_config.mode);
  147. dprintf("rgblight_config.hue = %d\n", rgblight_config.hue);
  148. dprintf("rgblight_config.sat = %d\n", rgblight_config.sat);
  149. dprintf("rgblight_config.val = %d\n", rgblight_config.val);
  150. dprintf("rgblight_config.speed = %d\n", rgblight_config.speed);
  151. }
  152. void rgblight_init(void) {
  153. /* if already initialized, don't do it again.
  154. If you must do it again, extern this and set to false, first.
  155. This is a dirty, dirty hack until proper hooks can be added for keyboard startup. */
  156. if (is_rgblight_initialized) { return; }
  157. debug_enable = 1; // Debug ON!
  158. dprintf("rgblight_init called.\n");
  159. dprintf("rgblight_init start!\n");
  160. if (!eeconfig_is_enabled()) {
  161. dprintf("rgblight_init eeconfig is not enabled.\n");
  162. eeconfig_init();
  163. eeconfig_update_rgblight_default();
  164. }
  165. rgblight_config.raw = eeconfig_read_rgblight();
  166. RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
  167. if (!rgblight_config.mode) {
  168. dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n");
  169. eeconfig_update_rgblight_default();
  170. rgblight_config.raw = eeconfig_read_rgblight();
  171. }
  172. rgblight_check_config();
  173. eeconfig_debug_rgblight(); // display current eeprom values
  174. #ifdef RGBLIGHT_USE_TIMER
  175. rgblight_timer_init(); // setup the timer
  176. #endif
  177. if (rgblight_config.enable) {
  178. rgblight_mode_noeeprom(rgblight_config.mode);
  179. }
  180. is_rgblight_initialized = true;
  181. }
  182. uint32_t rgblight_read_dword(void) {
  183. return rgblight_config.raw;
  184. }
  185. void rgblight_update_dword(uint32_t dword) {
  186. RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS;
  187. rgblight_config.raw = dword;
  188. if (rgblight_config.enable)
  189. rgblight_mode_noeeprom(rgblight_config.mode);
  190. else {
  191. #ifdef RGBLIGHT_USE_TIMER
  192. rgblight_timer_disable();
  193. #endif
  194. rgblight_set();
  195. }
  196. }
  197. void rgblight_increase(void) {
  198. uint8_t mode = 0;
  199. if (rgblight_config.mode < RGBLIGHT_MODES) {
  200. mode = rgblight_config.mode + 1;
  201. }
  202. rgblight_mode(mode);
  203. }
  204. void rgblight_decrease(void) {
  205. uint8_t mode = 0;
  206. // Mode will never be < 1. If it ever is, eeprom needs to be initialized.
  207. if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) {
  208. mode = rgblight_config.mode - 1;
  209. }
  210. rgblight_mode(mode);
  211. }
  212. void rgblight_step_helper(bool write_to_eeprom) {
  213. uint8_t mode = 0;
  214. mode = rgblight_config.mode + 1;
  215. if (mode > RGBLIGHT_MODES) {
  216. mode = 1;
  217. }
  218. rgblight_mode_eeprom_helper(mode, write_to_eeprom);
  219. }
  220. void rgblight_step_noeeprom(void) {
  221. rgblight_step_helper(false);
  222. }
  223. void rgblight_step(void) {
  224. rgblight_step_helper(true);
  225. }
  226. void rgblight_step_reverse_helper(bool write_to_eeprom) {
  227. uint8_t mode = 0;
  228. mode = rgblight_config.mode - 1;
  229. if (mode < 1) {
  230. mode = RGBLIGHT_MODES;
  231. }
  232. rgblight_mode_eeprom_helper(mode, write_to_eeprom);
  233. }
  234. void rgblight_step_reverse_noeeprom(void) {
  235. rgblight_step_reverse_helper(false);
  236. }
  237. void rgblight_step_reverse(void) {
  238. rgblight_step_reverse_helper(true);
  239. }
  240. uint8_t rgblight_get_mode(void) {
  241. if (!rgblight_config.enable) {
  242. return false;
  243. }
  244. return rgblight_config.mode;
  245. }
  246. void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
  247. if (!rgblight_config.enable) {
  248. return;
  249. }
  250. if (mode < RGBLIGHT_MODE_STATIC_LIGHT) {
  251. rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
  252. } else if (mode > RGBLIGHT_MODES) {
  253. rgblight_config.mode = RGBLIGHT_MODES;
  254. } else {
  255. rgblight_config.mode = mode;
  256. }
  257. RGBLIGHT_SPLIT_SET_CHANGE_MODE;
  258. if (write_to_eeprom) {
  259. eeconfig_update_rgblight(rgblight_config.raw);
  260. xprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode);
  261. } else {
  262. xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
  263. }
  264. if( is_static_effect(rgblight_config.mode) ) {
  265. #ifdef RGBLIGHT_USE_TIMER
  266. rgblight_timer_disable();
  267. #endif
  268. } else {
  269. #ifdef RGBLIGHT_USE_TIMER
  270. rgblight_timer_enable();
  271. #endif
  272. }
  273. #ifdef RGBLIGHT_USE_TIMER
  274. animation_status.restart = true;
  275. #endif
  276. rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
  277. }
  278. void rgblight_mode(uint8_t mode) {
  279. rgblight_mode_eeprom_helper(mode, true);
  280. }
  281. void rgblight_mode_noeeprom(uint8_t mode) {
  282. rgblight_mode_eeprom_helper(mode, false);
  283. }
  284. void rgblight_toggle(void) {
  285. xprintf("rgblight toggle [EEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable);
  286. if (rgblight_config.enable) {
  287. rgblight_disable();
  288. }
  289. else {
  290. rgblight_enable();
  291. }
  292. }
  293. void rgblight_toggle_noeeprom(void) {
  294. xprintf("rgblight toggle [NOEEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable);
  295. if (rgblight_config.enable) {
  296. rgblight_disable_noeeprom();
  297. }
  298. else {
  299. rgblight_enable_noeeprom();
  300. }
  301. }
  302. void rgblight_enable(void) {
  303. rgblight_config.enable = 1;
  304. // No need to update EEPROM here. rgblight_mode() will do that, actually
  305. //eeconfig_update_rgblight(rgblight_config.raw);
  306. xprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
  307. rgblight_mode(rgblight_config.mode);
  308. }
  309. void rgblight_enable_noeeprom(void) {
  310. rgblight_config.enable = 1;
  311. xprintf("rgblight enable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
  312. rgblight_mode_noeeprom(rgblight_config.mode);
  313. }
  314. void rgblight_disable(void) {
  315. rgblight_config.enable = 0;
  316. eeconfig_update_rgblight(rgblight_config.raw);
  317. xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
  318. #ifdef RGBLIGHT_USE_TIMER
  319. rgblight_timer_disable();
  320. #endif
  321. RGBLIGHT_SPLIT_SET_CHANGE_MODE;
  322. wait_ms(50);
  323. rgblight_set();
  324. }
  325. void rgblight_disable_noeeprom(void) {
  326. rgblight_config.enable = 0;
  327. xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
  328. #ifdef RGBLIGHT_USE_TIMER
  329. rgblight_timer_disable();
  330. #endif
  331. RGBLIGHT_SPLIT_SET_CHANGE_MODE;
  332. wait_ms(50);
  333. rgblight_set();
  334. }
  335. void rgblight_increase_hue_helper(bool write_to_eeprom) {
  336. uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP;
  337. rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
  338. }
  339. void rgblight_increase_hue_noeeprom(void) {
  340. rgblight_increase_hue_helper(false);
  341. }
  342. void rgblight_increase_hue(void) {
  343. rgblight_increase_hue_helper(true);
  344. }
  345. void rgblight_decrease_hue_helper(bool write_to_eeprom) {
  346. uint8_t hue = rgblight_config.hue - RGBLIGHT_HUE_STEP;
  347. rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom);
  348. }
  349. void rgblight_decrease_hue_noeeprom(void) {
  350. rgblight_decrease_hue_helper(false);
  351. }
  352. void rgblight_decrease_hue(void) {
  353. rgblight_decrease_hue_helper(true);
  354. }
  355. void rgblight_increase_sat_helper(bool write_to_eeprom) {
  356. uint8_t sat = qadd8(rgblight_config.sat, RGBLIGHT_SAT_STEP);
  357. rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);
  358. }
  359. void rgblight_increase_sat_noeeprom(void) {
  360. rgblight_increase_sat_helper(false);
  361. }
  362. void rgblight_increase_sat(void) {
  363. rgblight_increase_sat_helper(true);
  364. }
  365. void rgblight_decrease_sat_helper(bool write_to_eeprom) {
  366. uint8_t sat = qsub8(rgblight_config.sat, RGBLIGHT_SAT_STEP);
  367. rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom);
  368. }
  369. void rgblight_decrease_sat_noeeprom(void) {
  370. rgblight_decrease_sat_helper(false);
  371. }
  372. void rgblight_decrease_sat(void) {
  373. rgblight_decrease_sat_helper(true);
  374. }
  375. void rgblight_increase_val_helper(bool write_to_eeprom) {
  376. uint8_t val = qadd8(rgblight_config.val, RGBLIGHT_VAL_STEP);
  377. rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);
  378. }
  379. void rgblight_increase_val_noeeprom(void) {
  380. rgblight_increase_val_helper(false);
  381. }
  382. void rgblight_increase_val(void) {
  383. rgblight_increase_val_helper(true);
  384. }
  385. void rgblight_decrease_val_helper(bool write_to_eeprom) {
  386. uint8_t val = qsub8(rgblight_config.val, RGBLIGHT_VAL_STEP);
  387. rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom);
  388. }
  389. void rgblight_decrease_val_noeeprom(void) {
  390. rgblight_decrease_val_helper(false);
  391. }
  392. void rgblight_decrease_val(void) {
  393. rgblight_decrease_val_helper(true);
  394. }
  395. void rgblight_increase_speed(void) {
  396. if (rgblight_config.speed < 3)
  397. rgblight_config.speed++;
  398. //RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?
  399. eeconfig_update_rgblight(rgblight_config.raw);//EECONFIG needs to be increased to support this
  400. }
  401. void rgblight_decrease_speed(void) {
  402. if (rgblight_config.speed > 0)
  403. rgblight_config.speed--;
  404. //RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED??
  405. eeconfig_update_rgblight(rgblight_config.raw);//EECONFIG needs to be increased to support this
  406. }
  407. void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) {
  408. if (rgblight_config.enable) {
  409. LED_TYPE tmp_led;
  410. sethsv(hue, sat, val, &tmp_led);
  411. // dprintf("rgblight set hue [MEMORY]: %u,%u,%u\n", inmem_config.hue, inmem_config.sat, inmem_config.val);
  412. rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
  413. }
  414. }
  415. void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
  416. if (rgblight_config.enable) {
  417. rgblight_status.base_mode = mode_base_table[rgblight_config.mode];
  418. if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
  419. // same static color
  420. LED_TYPE tmp_led;
  421. sethsv(hue, sat, val, &tmp_led);
  422. rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
  423. } else {
  424. // all LEDs in same color
  425. if ( 1 == 0 ) { //dummy
  426. }
  427. #ifdef RGBLIGHT_EFFECT_BREATHING
  428. else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING ) {
  429. // breathing mode, ignore the change of val, use in memory value instead
  430. val = rgblight_config.val;
  431. }
  432. #endif
  433. #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
  434. else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) {
  435. // rainbow mood, ignore the change of hue
  436. hue = rgblight_config.hue;
  437. }
  438. #endif
  439. #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
  440. else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) {
  441. // rainbow swirl, ignore the change of hue
  442. hue = rgblight_config.hue;
  443. }
  444. #endif
  445. #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
  446. else if (rgblight_status.base_mode == RGBLIGHT_MODE_STATIC_GRADIENT) {
  447. // static gradient
  448. uint8_t delta = rgblight_config.mode - rgblight_status.base_mode;
  449. bool direction = (delta % 2) == 0;
  450. #ifdef __AVR__
  451. // probably due to how pgm_read_word is defined for ARM, but the ARM compiler really hates this line
  452. uint8_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[delta / 2]);
  453. #else
  454. uint8_t range = RGBLED_GRADIENT_RANGES[delta / 2];
  455. #endif
  456. for (uint8_t i = 0; i < RGBLED_NUM; i++) {
  457. uint8_t _hue = ((uint16_t)i * (uint16_t)range) / RGBLED_NUM;
  458. if (direction) {
  459. _hue = hue + _hue;
  460. } else {
  461. _hue = hue - _hue;
  462. }
  463. dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range);
  464. sethsv(_hue, sat, val, (LED_TYPE *)&led[i]);
  465. }
  466. rgblight_set();
  467. }
  468. #endif
  469. }
  470. #ifdef RGBLIGHT_SPLIT
  471. if( rgblight_config.hue != hue ||
  472. rgblight_config.sat != sat ||
  473. rgblight_config.val != val ) {
  474. RGBLIGHT_SPLIT_SET_CHANGE_HSVS;
  475. }
  476. #endif
  477. rgblight_config.hue = hue;
  478. rgblight_config.sat = sat;
  479. rgblight_config.val = val;
  480. if (write_to_eeprom) {
  481. eeconfig_update_rgblight(rgblight_config.raw);
  482. xprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
  483. } else {
  484. xprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
  485. }
  486. }
  487. }
  488. void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val) {
  489. rgblight_sethsv_eeprom_helper(hue, sat, val, true);
  490. }
  491. void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val) {
  492. rgblight_sethsv_eeprom_helper(hue, sat, val, false);
  493. }
  494. uint8_t rgblight_get_hue(void) {
  495. return rgblight_config.hue;
  496. }
  497. uint8_t rgblight_get_sat(void) {
  498. return rgblight_config.sat;
  499. }
  500. uint8_t rgblight_get_val(void) {
  501. return rgblight_config.val;
  502. }
  503. void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) {
  504. if (!rgblight_config.enable) { return; }
  505. for (uint8_t i = 0; i < RGBLED_NUM; i++) {
  506. led[i].r = r;
  507. led[i].g = g;
  508. led[i].b = b;
  509. }
  510. rgblight_set();
  511. }
  512. void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) {
  513. if (!rgblight_config.enable || index >= RGBLED_NUM) { return; }
  514. led[index].r = r;
  515. led[index].g = g;
  516. led[index].b = b;
  517. rgblight_set();
  518. }
  519. void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) {
  520. if (!rgblight_config.enable) { return; }
  521. LED_TYPE tmp_led;
  522. sethsv(hue, sat, val, &tmp_led);
  523. rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index);
  524. }
  525. #if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) \
  526. || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT)
  527. static uint8_t get_interval_time(const uint8_t* default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
  528. return
  529. #ifdef VELOCIKEY_ENABLE
  530. velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) :
  531. #endif
  532. pgm_read_byte(default_interval_address);
  533. }
  534. #endif
  535. void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end) {
  536. if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLED_NUM) { return; }
  537. for (uint8_t i = start; i < end; i++) {
  538. led[i].r = r;
  539. led[i].g = g;
  540. led[i].b = b;
  541. }
  542. rgblight_set();
  543. wait_ms(1);
  544. }
  545. void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end) {
  546. if (!rgblight_config.enable) { return; }
  547. LED_TYPE tmp_led;
  548. sethsv(hue, sat, val, &tmp_led);
  549. rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end);
  550. }
  551. void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) {
  552. rgblight_setrgb_range(r, g, b, 0 , (uint8_t) RGBLED_NUM/2);
  553. }
  554. void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b) {
  555. rgblight_setrgb_range(r, g, b, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM);
  556. }
  557. void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) {
  558. rgblight_sethsv_range(hue, sat, val, 0, (uint8_t) RGBLED_NUM/2);
  559. }
  560. void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) {
  561. rgblight_sethsv_range(hue, sat, val, (uint8_t) RGBLED_NUM/2, (uint8_t) RGBLED_NUM);
  562. }
  563. #ifndef RGBLIGHT_CUSTOM_DRIVER
  564. void rgblight_set(void) {
  565. LED_TYPE *start_led = led + clipping_start_pos;
  566. uint16_t num_leds = clipping_num_leds;
  567. if (rgblight_config.enable) {
  568. #ifdef RGBLIGHT_LED_MAP
  569. LED_TYPE led0[RGBLED_NUM];
  570. for(uint8_t i = 0; i < RGBLED_NUM; i++) {
  571. led0[i] = led[pgm_read_byte(&led_map[i])];
  572. }
  573. start_led = led0 + clipping_start_pos;
  574. #endif
  575. #ifdef RGBW
  576. ws2812_setleds_rgbw(start_led, num_leds);
  577. #else
  578. ws2812_setleds(start_led, num_leds);
  579. #endif
  580. } else {
  581. for (uint8_t i = 0; i < RGBLED_NUM; i++) {
  582. led[i].r = 0;
  583. led[i].g = 0;
  584. led[i].b = 0;
  585. }
  586. #ifdef RGBW
  587. ws2812_setleds_rgbw(start_led, num_leds);
  588. #else
  589. ws2812_setleds(start_led, num_leds);
  590. #endif
  591. }
  592. }
  593. #endif
  594. #ifdef RGBLIGHT_SPLIT
  595. /* for split keyboard master side */
  596. uint8_t rgblight_get_change_flags(void) {
  597. return rgblight_status.change_flags;
  598. }
  599. void rgblight_clear_change_flags(void) {
  600. rgblight_status.change_flags = 0;
  601. }
  602. void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo) {
  603. syncinfo->config = rgblight_config;
  604. syncinfo->status = rgblight_status;
  605. }
  606. /* for split keyboard slave side */
  607. void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) {
  608. if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) {
  609. if (syncinfo->config.enable) {
  610. rgblight_config.enable = 1; // == rgblight_enable_noeeprom();
  611. rgblight_mode_eeprom_helper(syncinfo->config.mode, write_to_eeprom);
  612. } else {
  613. rgblight_disable_noeeprom();
  614. }
  615. }
  616. if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_HSVS) {
  617. rgblight_sethsv_eeprom_helper(syncinfo->config.hue, syncinfo->config.sat, syncinfo->config.val, write_to_eeprom);
  618. // rgblight_config.speed = config->speed; // NEED???
  619. }
  620. #ifdef RGBLIGHT_USE_TIMER
  621. if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_TIMER) {
  622. if (syncinfo->status.timer_enabled) {
  623. rgblight_timer_enable();
  624. } else {
  625. rgblight_timer_disable();
  626. }
  627. }
  628. #ifndef RGBLIGHT_SPLIT_NO_ANIMATION_SYNC
  629. if (syncinfo->status.change_flags & RGBLIGHT_STATUS_ANIMATION_TICK) {
  630. animation_status.restart = true;
  631. }
  632. #endif /* RGBLIGHT_SPLIT_NO_ANIMATION_SYNC */
  633. #endif /* RGBLIGHT_USE_TIMER */
  634. }
  635. #endif /* RGBLIGHT_SPLIT */
  636. #ifdef RGBLIGHT_USE_TIMER
  637. typedef void (*effect_func_t)(animation_status_t *anim);
  638. // Animation timer -- use system timer (AVR Timer0)
  639. void rgblight_timer_init(void) {
  640. // OLD!!!! Animation timer -- AVR Timer3
  641. // static uint8_t rgblight_timer_is_init = 0;
  642. // if (rgblight_timer_is_init) {
  643. // return;
  644. // }
  645. // rgblight_timer_is_init = 1;
  646. // /* Timer 3 setup */
  647. // TCCR3B = _BV(WGM32) // CTC mode OCR3A as TOP
  648. // | _BV(CS30); // Clock selelct: clk/1
  649. // /* Set TOP value */
  650. // uint8_t sreg = SREG;
  651. // cli();
  652. // OCR3AH = (RGBLED_TIMER_TOP >> 8) & 0xff;
  653. // OCR3AL = RGBLED_TIMER_TOP & 0xff;
  654. // SREG = sreg;
  655. rgblight_status.timer_enabled = false;
  656. RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE;
  657. }
  658. void rgblight_timer_enable(void) {
  659. if( !is_static_effect(rgblight_config.mode) ) {
  660. rgblight_status.timer_enabled = true;
  661. }
  662. animation_status.last_timer = timer_read();
  663. RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE;
  664. dprintf("rgblight timer enabled.\n");
  665. }
  666. void rgblight_timer_disable(void) {
  667. rgblight_status.timer_enabled = false;
  668. RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE;
  669. dprintf("rgblight timer disable.\n");
  670. }
  671. void rgblight_timer_toggle(void) {
  672. dprintf("rgblight timer toggle.\n");
  673. if(rgblight_status.timer_enabled) {
  674. rgblight_timer_disable();
  675. } else {
  676. rgblight_timer_enable();
  677. }
  678. }
  679. void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
  680. rgblight_enable();
  681. rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
  682. rgblight_setrgb(r, g, b);
  683. }
  684. static void rgblight_effect_dummy(animation_status_t *anim) {
  685. // do nothing
  686. /********
  687. dprintf("rgblight_task() what happened?\n");
  688. dprintf("is_static_effect %d\n", is_static_effect(rgblight_config.mode));
  689. dprintf("mode = %d, base_mode = %d, timer_enabled %d, ",
  690. rgblight_config.mode, rgblight_status.base_mode,
  691. rgblight_status.timer_enabled);
  692. dprintf("last_timer = %d\n",anim->last_timer);
  693. **/
  694. }
  695. void rgblight_task(void) {
  696. if (rgblight_status.timer_enabled) {
  697. effect_func_t effect_func = rgblight_effect_dummy;
  698. uint16_t interval_time = 2000; // dummy interval
  699. uint8_t delta = rgblight_config.mode - rgblight_status.base_mode;
  700. animation_status.delta = delta;
  701. // static light mode, do nothing here
  702. if ( 1 == 0 ) { //dummy
  703. }
  704. #ifdef RGBLIGHT_EFFECT_BREATHING
  705. else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) {
  706. // breathing mode
  707. interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[delta], 1, 100);
  708. effect_func = rgblight_effect_breathing;
  709. }
  710. #endif
  711. #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
  712. else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) {
  713. // rainbow mood mode
  714. interval_time = get_interval_time(&RGBLED_RAINBOW_MOOD_INTERVALS[delta], 5, 100);
  715. effect_func = rgblight_effect_rainbow_mood;
  716. }
  717. #endif
  718. #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
  719. else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) {
  720. // rainbow swirl mode
  721. interval_time = get_interval_time(&RGBLED_RAINBOW_SWIRL_INTERVALS[delta / 2], 1, 100);
  722. effect_func = rgblight_effect_rainbow_swirl;
  723. }
  724. #endif
  725. #ifdef RGBLIGHT_EFFECT_SNAKE
  726. else if (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE) {
  727. // snake mode
  728. interval_time = get_interval_time(&RGBLED_SNAKE_INTERVALS[delta / 2], 1, 200);
  729. effect_func = rgblight_effect_snake;
  730. }
  731. #endif
  732. #ifdef RGBLIGHT_EFFECT_KNIGHT
  733. else if (rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT) {
  734. // knight mode
  735. interval_time = get_interval_time(&RGBLED_KNIGHT_INTERVALS[delta], 5, 100);
  736. effect_func = rgblight_effect_knight;
  737. }
  738. #endif
  739. #ifdef RGBLIGHT_EFFECT_CHRISTMAS
  740. else if (rgblight_status.base_mode == RGBLIGHT_MODE_CHRISTMAS) {
  741. // christmas mode
  742. interval_time = RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL;
  743. effect_func = (effect_func_t)rgblight_effect_christmas;
  744. }
  745. #endif
  746. #ifdef RGBLIGHT_EFFECT_RGB_TEST
  747. else if (rgblight_status.base_mode == RGBLIGHT_MODE_RGB_TEST) {
  748. // RGB test mode
  749. interval_time = pgm_read_word(&RGBLED_RGBTEST_INTERVALS[0]);
  750. effect_func = (effect_func_t)rgblight_effect_rgbtest;
  751. }
  752. #endif
  753. #ifdef RGBLIGHT_EFFECT_ALTERNATING
  754. else if (rgblight_status.base_mode == RGBLIGHT_MODE_ALTERNATING){
  755. interval_time = 500;
  756. effect_func = (effect_func_t)rgblight_effect_alternating;
  757. }
  758. #endif
  759. if (animation_status.restart) {
  760. animation_status.restart = false;
  761. animation_status.last_timer = timer_read() - interval_time - 1;
  762. animation_status.pos16 = 0; // restart signal to local each effect
  763. }
  764. if (timer_elapsed(animation_status.last_timer) >= interval_time) {
  765. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  766. static uint16_t report_last_timer = 0;
  767. static bool tick_flag = false;
  768. uint16_t oldpos16;
  769. if (tick_flag) {
  770. tick_flag = false;
  771. //dprintf("rgblight animation tick\n");
  772. if (timer_elapsed(report_last_timer) >= 30000) {
  773. report_last_timer = timer_read();
  774. dprintf("rgblight animation tick report to slave\n");
  775. RGBLIGHT_SPLIT_ANIMATION_TICK;
  776. }
  777. }
  778. oldpos16 = animation_status.pos16;
  779. //dprintf("call effect function\n");
  780. #endif
  781. animation_status.last_timer += interval_time;
  782. effect_func(&animation_status);
  783. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  784. //dprintf("pos16, oldpos16 = %d %d\n",
  785. // animation_status.pos16,oldpos16);
  786. if (animation_status.pos16 == 0 && oldpos16 != 0) {
  787. //dprintf("flag on\n");
  788. tick_flag = true;
  789. }
  790. #endif
  791. }
  792. }
  793. }
  794. #endif /* RGBLIGHT_USE_TIMER */
  795. // Effects
  796. #ifdef RGBLIGHT_EFFECT_BREATHING
  797. __attribute__ ((weak))
  798. const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
  799. void rgblight_effect_breathing(animation_status_t *anim) {
  800. float val;
  801. // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
  802. val = (exp(sin((anim->pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E));
  803. rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
  804. anim->pos = (anim->pos + 1);
  805. }
  806. #endif
  807. #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
  808. __attribute__ ((weak))
  809. const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
  810. void rgblight_effect_rainbow_mood(animation_status_t *anim) {
  811. rgblight_sethsv_noeeprom_old(anim->current_hue, rgblight_config.sat, rgblight_config.val);
  812. anim->current_hue++;
  813. }
  814. #endif
  815. #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
  816. #ifndef RGBLIGHT_RAINBOW_SWIRL_RANGE
  817. #define RGBLIGHT_RAINBOW_SWIRL_RANGE 255
  818. #endif
  819. __attribute__ ((weak))
  820. const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
  821. void rgblight_effect_rainbow_swirl(animation_status_t *anim) {
  822. uint8_t hue;
  823. uint8_t i;
  824. for (i = 0; i < RGBLED_NUM; i++) {
  825. hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / RGBLED_NUM * i + anim->current_hue);
  826. sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  827. }
  828. rgblight_set();
  829. if (anim->delta % 2) {
  830. anim->current_hue++;
  831. } else {
  832. anim->current_hue--;
  833. }
  834. }
  835. #endif
  836. #ifdef RGBLIGHT_EFFECT_SNAKE
  837. __attribute__ ((weak))
  838. const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
  839. void rgblight_effect_snake(animation_status_t *anim) {
  840. static uint8_t pos = 0;
  841. uint8_t i, j;
  842. int8_t k;
  843. int8_t increment = 1;
  844. if (anim->delta % 2) {
  845. increment = -1;
  846. }
  847. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  848. if (anim->pos == 0) { // restart signal
  849. if (increment == 1) {
  850. pos = RGBLED_NUM - 1;
  851. } else {
  852. pos = 0;
  853. }
  854. anim->pos = 1;
  855. }
  856. #endif
  857. for (i = 0; i < RGBLED_NUM; i++) {
  858. led[i].r = 0;
  859. led[i].g = 0;
  860. led[i].b = 0;
  861. for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) {
  862. k = pos + j * increment;
  863. if (k < 0) {
  864. k = k + RGBLED_NUM;
  865. }
  866. if (i == k) {
  867. sethsv(rgblight_config.hue, rgblight_config.sat,
  868. (uint8_t)(rgblight_config.val*(RGBLIGHT_EFFECT_SNAKE_LENGTH-j)/RGBLIGHT_EFFECT_SNAKE_LENGTH),
  869. (LED_TYPE *)&led[i]);
  870. }
  871. }
  872. }
  873. rgblight_set();
  874. if (increment == 1) {
  875. if (pos - 1 < 0) {
  876. pos = RGBLED_NUM - 1;
  877. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  878. anim->pos = 0;
  879. #endif
  880. } else {
  881. pos -= 1;
  882. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  883. anim->pos = 1;
  884. #endif
  885. }
  886. } else {
  887. pos = (pos + 1) % RGBLED_NUM;
  888. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  889. anim->pos = pos;
  890. #endif
  891. }
  892. }
  893. #endif
  894. #ifdef RGBLIGHT_EFFECT_KNIGHT
  895. __attribute__ ((weak))
  896. const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
  897. void rgblight_effect_knight(animation_status_t *anim) {
  898. static int8_t low_bound = 0;
  899. static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
  900. static int8_t increment = 1;
  901. uint8_t i, cur;
  902. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  903. if (anim->pos == 0) { // restart signal
  904. anim->pos = 1;
  905. low_bound = 0;
  906. high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1;
  907. increment = 1;
  908. }
  909. #endif
  910. // Set all the LEDs to 0
  911. for (i = 0; i < RGBLED_NUM; i++) {
  912. led[i].r = 0;
  913. led[i].g = 0;
  914. led[i].b = 0;
  915. }
  916. // Determine which LEDs should be lit up
  917. for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) {
  918. cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % RGBLED_NUM;
  919. if (i >= low_bound && i <= high_bound) {
  920. sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]);
  921. } else {
  922. led[cur].r = 0;
  923. led[cur].g = 0;
  924. led[cur].b = 0;
  925. }
  926. }
  927. rgblight_set();
  928. // Move from low_bound to high_bound changing the direction we increment each
  929. // time a boundary is hit.
  930. low_bound += increment;
  931. high_bound += increment;
  932. if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) {
  933. increment = -increment;
  934. #if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC)
  935. if (increment == 1) {
  936. anim->pos = 0;
  937. }
  938. #endif
  939. }
  940. }
  941. #endif
  942. #ifdef RGBLIGHT_EFFECT_CHRISTMAS
  943. void rgblight_effect_christmas(animation_status_t *anim) {
  944. uint8_t hue;
  945. uint8_t i;
  946. anim->current_offset = (anim->current_offset + 1) % 2;
  947. for (i = 0; i < RGBLED_NUM; i++) {
  948. hue = 0 + ((i/RGBLIGHT_EFFECT_CHRISTMAS_STEP + anim->current_offset) % 2) * 85;
  949. sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  950. }
  951. rgblight_set();
  952. }
  953. #endif
  954. #ifdef RGBLIGHT_EFFECT_RGB_TEST
  955. __attribute__ ((weak))
  956. const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
  957. void rgblight_effect_rgbtest(animation_status_t *anim) {
  958. static uint8_t maxval = 0;
  959. uint8_t g; uint8_t r; uint8_t b;
  960. if( maxval == 0 ) {
  961. LED_TYPE tmp_led;
  962. sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led);
  963. maxval = tmp_led.r;
  964. }
  965. g = r = b = 0;
  966. switch( anim->pos ) {
  967. case 0: r = maxval; break;
  968. case 1: g = maxval; break;
  969. case 2: b = maxval; break;
  970. }
  971. rgblight_setrgb(r, g, b);
  972. anim->pos = (anim->pos + 1) % 3;
  973. }
  974. #endif
  975. #ifdef RGBLIGHT_EFFECT_ALTERNATING
  976. void rgblight_effect_alternating(animation_status_t *anim) {
  977. for(int i = 0; i<RGBLED_NUM; i++){
  978. if(i<RGBLED_NUM/2 && anim->pos){
  979. sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  980. }else if (i>=RGBLED_NUM/2 && !anim->pos){
  981. sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i]);
  982. }else{
  983. sethsv(rgblight_config.hue, rgblight_config.sat, 0, (LED_TYPE *)&led[i]);
  984. }
  985. }
  986. rgblight_set();
  987. anim->pos = (anim->pos + 1) % 2;
  988. }
  989. #endif