You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

459 lines
14 KiB

  1. /**
  2. * @file rgb_ring.c
  3. * @author astro
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "rgb_ring.h"
  19. #include <stdint.h>
  20. #include <stdbool.h>
  21. #include <string.h>
  22. #include "quantum.h"
  23. #include "rgblight.h"
  24. #include "timer.h"
  25. #include "action.h"
  26. #include "drivers/led/issi/is31fl3731.h"
  27. #include "i2c_master.h"
  28. #ifndef RGBLIGHT_ENABLE
  29. #error "MUST enable rgblight"
  30. #endif
  31. // rgb ring leds setting
  32. const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = {
  33. /* Refer to IS31 manual for these locations
  34. * driver
  35. * | R location
  36. * | | G location
  37. * | | | B location
  38. * | | | | */
  39. {0, C1_1, C3_2, C4_2},
  40. {0, C1_2, C2_2, C4_3},
  41. {0, C1_3, C2_3, C3_3},
  42. {0, C1_4, C2_4, C3_4},
  43. {0, C1_5, C2_5, C3_5},
  44. {0, C1_6, C2_6, C3_6},
  45. {0, C1_7, C2_7, C3_7},
  46. {0, C1_8, C2_8, C3_8},
  47. {0, C9_1, C8_1, C7_1},
  48. {0, C9_2, C8_2, C7_2},
  49. {0, C9_3, C8_3, C7_3},
  50. {0, C9_4, C8_4, C7_4},
  51. {0, C9_5, C8_5, C7_5},
  52. {0, C9_6, C8_6, C7_6},
  53. {0, C9_7, C8_7, C6_6},
  54. {0, C9_8, C7_7, C6_7},
  55. {0, C1_9, C3_10, C4_10},
  56. {0, C1_10, C2_10, C4_11},
  57. {0, C1_11, C2_11, C3_11},
  58. {0, C1_12, C2_12, C3_12},
  59. };
  60. #define RING_OUTER_BEGIN 0
  61. #define RING_OUTER_END 15
  62. #define RING_OUTER_SIZE (RING_OUTER_END + 1 - RING_OUTER_BEGIN)
  63. #define RING_INNER_BEGIN 16
  64. #define RING_INNER_END 19
  65. #define RING_INNER_SIZE (RING_INNER_END + 1 - RING_INNER_BEGIN)
  66. #define SPEED_MAX 100
  67. #define SPEED_STEP 10
  68. typedef enum {
  69. RING_STATE_INIT,
  70. RING_STATE_QMK,
  71. RING_STATE_CUSTOM,
  72. } RING_STATE;
  73. typedef enum {
  74. RING_EFFECT_1,
  75. RING_EFFECT_2,
  76. RING_EFFECT_3,
  77. RING_EFFECT_4,
  78. RING_EFFECT_5,
  79. RING_EFFECT_6,
  80. RING_EFFECT_MAX
  81. } RING_EFFECT;
  82. typedef struct {
  83. uint8_t state;
  84. uint8_t effect;
  85. uint8_t speed;
  86. uint8_t outer_index;
  87. uint8_t inner_index;
  88. uint8_t effect_count;
  89. uint8_t led_begin;
  90. uint8_t led_end;
  91. bool led_forward;
  92. bool led_clear;
  93. } rgb_ring_t;
  94. static rgb_ring_t rgb_ring = {
  95. .state = RING_STATE_INIT,
  96. .effect = RING_EFFECT_1,
  97. .speed = 10,
  98. .outer_index = 0,
  99. .inner_index = 0,
  100. .effect_count = 0,
  101. .led_begin = RING_OUTER_BEGIN,
  102. .led_end = RING_OUTER_END,
  103. .led_forward = true,
  104. .led_clear = false,
  105. };
  106. static void rgb_ring_reset(void)
  107. {
  108. rgb_ring.effect_count = 0;
  109. rgb_ring.led_begin = RING_OUTER_BEGIN;
  110. rgb_ring.led_end = RING_OUTER_END;
  111. rgb_ring.led_forward = true;
  112. rgb_ring.led_clear = false;
  113. }
  114. extern animation_status_t animation_status;
  115. extern rgblight_config_t rgblight_config;
  116. #define EFFECT_TEST_INTERVAL 50
  117. #define EFFECT_TEST_COUNT 5
  118. #define EFFECT_TEST_HUE_STEP 85
  119. #define EFFECT_TEST_VAL_STEP 17
  120. static void testing_mode(void)
  121. {
  122. if (timer_elapsed(animation_status.last_timer) > EFFECT_TEST_INTERVAL) {
  123. HSV h = {rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
  124. RGB c = hsv_to_rgb(h);
  125. //is31fl3731_set_color_all(c.r, c.g, c.b);
  126. is31fl3731_set_color_all(0, 0, 0);
  127. is31fl3731_set_color(rgb_ring.outer_index+RING_OUTER_BEGIN, c.r, c.g, c.b);
  128. h.v = EFFECT_TEST_VAL_STEP*rgb_ring.outer_index;
  129. c = hsv_to_rgb(h);
  130. for (uint8_t i = RING_INNER_BEGIN; i <= RING_INNER_END; i++) {
  131. is31fl3731_set_color(i, c.r, c.g, c.b);
  132. }
  133. rgb_ring.outer_index = (rgb_ring.outer_index + 1) % RING_OUTER_SIZE;
  134. //rgb_ring.inner_index = (rgb_ring.inner_index + 1) % RING_INNER_SIZE;
  135. if (rgb_ring.outer_index == RING_OUTER_BEGIN) {
  136. rgblight_config.hue += EFFECT_TEST_HUE_STEP;
  137. rgb_ring.effect_count++;
  138. }
  139. animation_status.last_timer = timer_read();
  140. }
  141. if (rgb_ring.effect_count > EFFECT_TEST_COUNT) {
  142. rgb_ring_reset();
  143. rgb_ring.state = RING_STATE_QMK;
  144. rgblight_set();
  145. }
  146. }
  147. static bool need_update(uint32_t max_interval)
  148. {
  149. uint32_t interval = timer_elapsed(animation_status.last_timer);
  150. return (interval*rgb_ring.speed) > max_interval;
  151. }
  152. static void update_effect(uint32_t max_count)
  153. {
  154. if (rgb_ring.effect_count > max_count) {
  155. rgb_ring_reset();
  156. rgb_ring.effect = (rgb_ring.effect + 1) % RING_EFFECT_MAX;
  157. }
  158. }
  159. #define EFFECT_1_INTERVAL 1000
  160. #define EFFECT_1_COUNT 64
  161. #define EFFECT_1_HUE_STEP 15
  162. static void ring_effect_no_1(void)
  163. {
  164. if (need_update(EFFECT_1_INTERVAL)) {
  165. HSV h = {rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
  166. for (uint8_t i = RING_OUTER_BEGIN; i <= RING_OUTER_END; i++) {
  167. RGB c = hsv_to_rgb(h);
  168. is31fl3731_set_color(i, c.r, c.g, c.b);
  169. }
  170. rgblight_config.hue += EFFECT_1_HUE_STEP;
  171. rgb_ring.effect_count++;
  172. animation_status.last_timer = timer_read();
  173. }
  174. update_effect(EFFECT_1_COUNT);
  175. }
  176. #define EFFECT_2_INTERVAL 1000
  177. #define EFFECT_2_COUNT 64
  178. #define EFFECT_2_HUE_STEP 15
  179. static void ring_effect_no_2(void)
  180. {
  181. if (need_update(EFFECT_2_INTERVAL)) {
  182. is31fl3731_set_color_all(0, 0, 0);
  183. HSV h = {rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
  184. RGB c = hsv_to_rgb(h);
  185. is31fl3731_set_color(rgb_ring.led_begin, c.r, c.g, c.b);
  186. is31fl3731_set_color(rgb_ring.led_end, c.r, c.g, c.b);
  187. rgb_ring.led_begin = (rgb_ring.led_begin + 1) % RING_OUTER_SIZE;
  188. rgb_ring.led_end = (rgb_ring.led_end + RING_OUTER_SIZE - 1) % RING_OUTER_SIZE;
  189. rgblight_config.hue += EFFECT_2_HUE_STEP;
  190. rgb_ring.effect_count++;
  191. animation_status.last_timer = timer_read();
  192. }
  193. update_effect(EFFECT_2_COUNT);
  194. }
  195. #define EFFECT_3_INTERVAL 1000
  196. #define EFFECT_3_COUNT 64
  197. #define EFFECT_3_HUE_STEP 15
  198. static void ring_effect_no_3(void)
  199. {
  200. if (rgb_ring.effect_count == 0) {
  201. is31fl3731_set_color_all(0, 0, 0);
  202. }
  203. if (need_update(EFFECT_3_INTERVAL)) {
  204. HSV h = {rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
  205. if (rgb_ring.led_clear) {
  206. is31fl3731_set_color(rgb_ring.led_begin, 0, 0, 0);
  207. is31fl3731_set_color(rgb_ring.led_end, 0, 0, 0);
  208. } else {
  209. RGB c = hsv_to_rgb(h);
  210. is31fl3731_set_color(rgb_ring.led_begin, c.r, c.g, c.b);
  211. is31fl3731_set_color(rgb_ring.led_end, c.r, c.g, c.b);
  212. }
  213. rgb_ring.led_begin = (rgb_ring.led_begin + 1) % RING_OUTER_SIZE;
  214. if (rgb_ring.led_begin == rgb_ring.led_end) {
  215. if (rgb_ring.led_forward) {
  216. rgb_ring.led_begin = RING_OUTER_BEGIN;
  217. rgb_ring.led_end = RING_OUTER_END+1;
  218. } else {
  219. rgb_ring.led_begin = RING_OUTER_BEGIN + RING_OUTER_SIZE/2;
  220. rgb_ring.led_end = RING_OUTER_END+1 - RING_OUTER_SIZE/2;
  221. }
  222. if (!rgb_ring.led_clear) {
  223. rgb_ring.led_forward = !rgb_ring.led_forward;
  224. }
  225. rgb_ring.led_clear = !rgb_ring.led_clear;
  226. }
  227. rgb_ring.led_end = (rgb_ring.led_end + RING_OUTER_SIZE - 1) % RING_OUTER_SIZE;
  228. rgblight_config.hue += EFFECT_3_HUE_STEP;
  229. rgb_ring.effect_count++;
  230. animation_status.last_timer = timer_read();
  231. }
  232. update_effect(EFFECT_3_COUNT);
  233. }
  234. #define EFFECT_4_INTERVAL 1000
  235. #define EFFECT_4_COUNT 64
  236. #define EFFECT_4_STEP 3
  237. static void ring_effect_no_4(void)
  238. {
  239. if (need_update(EFFECT_4_INTERVAL)) {
  240. is31fl3731_set_color_all(0, 0, 0);
  241. HSV h = {rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
  242. RGB c = hsv_to_rgb(h);
  243. is31fl3731_set_color(rgb_ring.led_begin, c.r, c.g, c.b);
  244. is31fl3731_set_color(rgb_ring.led_end, c.r, c.g, c.b);
  245. rgb_ring.led_begin = (rgb_ring.led_begin + EFFECT_4_STEP) % RING_OUTER_SIZE;
  246. rgb_ring.led_end = (rgb_ring.led_end + RING_OUTER_SIZE - EFFECT_4_STEP) % RING_OUTER_SIZE;
  247. rgblight_config.hue += EFFECT_1_HUE_STEP;
  248. rgb_ring.effect_count++;
  249. animation_status.last_timer = timer_read();
  250. }
  251. update_effect(EFFECT_4_COUNT);
  252. }
  253. #define EFFECT_5_INTERVAL 1000
  254. #define EFFECT_5_COUNT 64
  255. #define EFFECT_5_HUE_STEP 16
  256. static void ring_effect_no_5(void)
  257. {
  258. if (need_update(EFFECT_5_INTERVAL)) {
  259. is31fl3731_set_color_all(0, 0, 0);
  260. for (uint8_t i = RING_INNER_BEGIN; i <= RING_INNER_END; i++) {
  261. HSV h = {rgblight_config.hue, rgblight_config.sat, rgblight_config.val};
  262. RGB c = hsv_to_rgb(h);
  263. is31fl3731_set_color(i, c.r, c.g, c.b);
  264. }
  265. for (uint8_t i = RING_OUTER_BEGIN; i <= RING_OUTER_END; i++) {
  266. HSV h = {rgblight_config.hue+EFFECT_5_HUE_STEP, rgblight_config.sat, rgblight_config.val};
  267. RGB c = hsv_to_rgb(h);
  268. is31fl3731_set_color(i, c.r, c.g, c.b);
  269. }
  270. rgblight_config.hue += EFFECT_5_HUE_STEP;
  271. rgb_ring.effect_count++;
  272. animation_status.last_timer = timer_read();
  273. }
  274. update_effect(EFFECT_5_COUNT);
  275. }
  276. #define EFFECT_6_INTERVAL 1000
  277. #define EFFECT_6_COUNT 64
  278. #define EFFECT_I_HUE_STEP 10
  279. #define EFFECT_O_HUE_STEP 10
  280. static void ring_effect_no_6(void)
  281. {
  282. if (need_update(EFFECT_6_INTERVAL)) {
  283. is31fl3731_set_color_all(0, 0, 0);
  284. for (uint8_t i = RING_INNER_BEGIN; i <= RING_INNER_END; i++) {
  285. HSV h = {rgblight_config.hue+i*EFFECT_I_HUE_STEP, rgblight_config.sat, rgblight_config.val};
  286. RGB c = hsv_to_rgb(h);
  287. is31fl3731_set_color(i, c.r, c.g, c.b);
  288. }
  289. for (uint8_t i = RING_OUTER_BEGIN; i <= RING_OUTER_END; i++) {
  290. HSV h = {rgblight_config.hue+i*EFFECT_O_HUE_STEP, rgblight_config.sat, rgblight_config.val};
  291. RGB c = hsv_to_rgb(h);
  292. is31fl3731_set_color(i, c.r, c.g, c.b);
  293. }
  294. rgblight_config.hue += EFFECT_I_HUE_STEP;
  295. rgb_ring.effect_count++;
  296. animation_status.last_timer = timer_read();
  297. }
  298. update_effect(EFFECT_6_COUNT);
  299. }
  300. typedef void(*effect_fun)(void);
  301. static effect_fun effect_funcs[RING_EFFECT_MAX] = {
  302. ring_effect_no_1,
  303. ring_effect_no_2,
  304. ring_effect_no_3,
  305. ring_effect_no_4,
  306. ring_effect_no_5,
  307. ring_effect_no_6,
  308. };
  309. static void custom_effects(void)
  310. {
  311. effect_funcs[rgb_ring.effect]();
  312. }
  313. void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
  314. {
  315. if (rgb_ring.state != RING_STATE_QMK) {
  316. return;
  317. }
  318. for (uint8_t i = 0; i < num_leds; i++) {
  319. is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b);
  320. }
  321. }
  322. const rgblight_driver_t rgblight_driver = {
  323. .setleds = setleds_custom,
  324. };
  325. void rgb_ring_init(void)
  326. {
  327. is31fl3731_init_drivers();
  328. }
  329. void rgb_ring_task(void)
  330. {
  331. switch (rgb_ring.state) {
  332. case RING_STATE_INIT: // testing mode
  333. testing_mode();
  334. break;
  335. case RING_STATE_QMK: // qmk effects
  336. //rgblight_task();
  337. break;
  338. case RING_STATE_CUSTOM: // custom effects
  339. custom_effects();
  340. break;
  341. default:
  342. break;
  343. };
  344. is31fl3731_flush();
  345. }
  346. bool process_record_kb(uint16_t keycode, keyrecord_t *record)
  347. {
  348. if (record->event.pressed) {
  349. switch(keycode) {
  350. case RGB_MODE_FORWARD:
  351. if (rgb_ring.state == RING_STATE_INIT) {
  352. // in testing mode, do nothing
  353. return false;
  354. } else if (rgb_ring.state == RING_STATE_CUSTOM) {
  355. // switch to qmk mode
  356. rgblight_config.mode = 1;
  357. rgb_ring.state = RING_STATE_QMK;
  358. rgblight_mode(rgblight_config.mode);
  359. return false;
  360. } else {
  361. // in qmk mode, switch to custom mode?
  362. if (rgblight_config.mode >= RGBLIGHT_MODES) {
  363. rgb_ring.state = RING_STATE_CUSTOM;
  364. return false;
  365. }
  366. }
  367. break;
  368. case RGB_MODE_REVERSE:
  369. if (rgb_ring.state == RING_STATE_INIT) {
  370. // in testing mode, do nothing
  371. return false;
  372. } else if (rgb_ring.state == RING_STATE_CUSTOM) {
  373. // switch to qmk mode
  374. rgblight_config.mode = RGBLIGHT_MODES;
  375. rgb_ring.state = RING_STATE_QMK;
  376. rgblight_mode(rgblight_config.mode);
  377. return false;
  378. } else {
  379. // in qmk mode, switch to custom mode?
  380. if (rgblight_config.mode <= 1) {
  381. rgb_ring.state = RING_STATE_CUSTOM;
  382. return false;
  383. }
  384. }
  385. break;
  386. case KC_F24:
  387. if (rgb_ring.state == RING_STATE_QMK) {
  388. rgb_ring.state = RING_STATE_CUSTOM;
  389. rgb_ring_reset();
  390. return false;
  391. } else if (rgb_ring.state == RING_STATE_CUSTOM) {
  392. rgb_ring.state = RING_STATE_QMK;
  393. return false;
  394. }
  395. break;
  396. default:
  397. break;
  398. }
  399. }
  400. return process_record_user(keycode, record);
  401. }