rgblight.c 36 KB

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