Commit | Line | Data |
---|---|---|
14b7602a JH |
1 | /* Copyright 2017 Jason Williams |
2 | * Copyright 2017 Jack Humbert | |
fdd0f915 | 3 | * Copyright 2018 Yiancar |
14b7602a JH |
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 | ||
19 | ||
20 | #include "rgb_matrix.h" | |
14b7602a JH |
21 | #include "progmem.h" |
22 | #include "config.h" | |
23 | #include "eeprom.h" | |
b382076a | 24 | #include <string.h> |
14b7602a JH |
25 | #include <math.h> |
26 | ||
c98247e3 X |
27 | #include "lib/lib8tion/lib8tion.h" |
28 | ||
29 | #include "rgb_matrix_animations/solid_color_anim.h" | |
30 | #include "rgb_matrix_animations/alpha_mods_anim.h" | |
31 | #include "rgb_matrix_animations/dual_beacon_anim.h" | |
32 | #include "rgb_matrix_animations/gradient_up_down_anim.h" | |
33 | #include "rgb_matrix_animations/raindrops_anim.h" | |
34 | #include "rgb_matrix_animations/cycle_all_anim.h" | |
35 | #include "rgb_matrix_animations/cycle_left_right_anim.h" | |
36 | #include "rgb_matrix_animations/cycle_up_down_anim.h" | |
37 | #include "rgb_matrix_animations/rainbow_beacon_anim.h" | |
38 | #include "rgb_matrix_animations/rainbow_pinwheels_anim.h" | |
39 | #include "rgb_matrix_animations/rainbow_moving_chevron_anim.h" | |
40 | #include "rgb_matrix_animations/jellybean_raindrops_anim.h" | |
41 | #include "rgb_matrix_animations/digital_rain_anim.h" | |
42 | #include "rgb_matrix_animations/solid_reactive_simple_anim.h" | |
43 | #include "rgb_matrix_animations/solid_reactive_anim.h" | |
bb52119a A |
44 | #include "rgb_matrix_animations/solid_reactive_wide.h" |
45 | #include "rgb_matrix_animations/solid_reactive_cross.h" | |
46 | #include "rgb_matrix_animations/solid_reactive_nexus.h" | |
c98247e3 X |
47 | #include "rgb_matrix_animations/splash_anim.h" |
48 | #include "rgb_matrix_animations/solid_splash_anim.h" | |
49 | #include "rgb_matrix_animations/breathing_anim.h" | |
14b7602a | 50 | |
1d784f0f DP |
51 | #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) |
52 | #define RGB_MATRIX_CUSTOM_EFFECT_IMPLS | |
53 | #define RGB_MATRIX_EFFECT(name, ...) | |
54 | #ifdef RGB_MATRIX_CUSTOM_KB | |
55 | #include "rgb_matrix_kb.inc" | |
56 | #endif | |
57 | #ifdef RGB_MATRIX_CUSTOM_USER | |
58 | #include "rgb_matrix_user.inc" | |
59 | #endif | |
60 | #undef RGB_MATRIX_EFFECT | |
61 | #undef RGB_MATRIX_CUSTOM_EFFECT_IMPLS | |
62 | #endif | |
63 | ||
c98247e3 X |
64 | #ifndef RGB_DISABLE_AFTER_TIMEOUT |
65 | #define RGB_DISABLE_AFTER_TIMEOUT 0 | |
fdd0f915 | 66 | #endif |
67 | ||
c98247e3 X |
68 | #ifndef RGB_DISABLE_WHEN_USB_SUSPENDED |
69 | #define RGB_DISABLE_WHEN_USB_SUSPENDED false | |
fdd0f915 | 70 | #endif |
71 | ||
c98247e3 X |
72 | #ifndef EECONFIG_RGB_MATRIX |
73 | #define EECONFIG_RGB_MATRIX EECONFIG_RGBLIGHT | |
14b7602a JH |
74 | #endif |
75 | ||
c98247e3 X |
76 | #if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX |
77 | #undef RGB_MATRIX_MAXIMUM_BRIGHTNESS | |
78 | #define RGB_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX | |
14b7602a JH |
79 | #endif |
80 | ||
c98247e3 X |
81 | #if !defined(RGB_MATRIX_HUE_STEP) |
82 | #define RGB_MATRIX_HUE_STEP 8 | |
14b7602a JH |
83 | #endif |
84 | ||
c98247e3 X |
85 | #if !defined(RGB_MATRIX_SAT_STEP) |
86 | #define RGB_MATRIX_SAT_STEP 16 | |
a7df9027 | 87 | #endif |
88 | ||
c98247e3 X |
89 | #if !defined(RGB_MATRIX_VAL_STEP) |
90 | #define RGB_MATRIX_VAL_STEP 16 | |
da6c5817 DS |
91 | #endif |
92 | ||
c98247e3 X |
93 | #if !defined(RGB_MATRIX_SPD_STEP) |
94 | #define RGB_MATRIX_SPD_STEP 16 | |
504bf117 FD |
95 | #endif |
96 | ||
1d784f0f DP |
97 | #if !defined(RGB_MATRIX_STARTUP_MODE) |
98 | #ifndef DISABLE_RGB_MATRIX_CYCLE_ALL | |
99 | #define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT | |
100 | #else | |
101 | // fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace | |
102 | #define RGB_MATRIX_STARTUP_MODE RGB_MATRIX_SOLID_COLOR | |
103 | #endif | |
104 | #endif | |
105 | ||
14b7602a JH |
106 | bool g_suspend_state = false; |
107 | ||
c98247e3 | 108 | rgb_config_t rgb_matrix_config; |
14b7602a | 109 | |
c98247e3 X |
110 | rgb_counters_t g_rgb_counters; |
111 | static uint32_t rgb_counters_buffer; | |
14b7602a | 112 | |
c98247e3 X |
113 | #ifdef RGB_MATRIX_KEYREACTIVE_ENABLED |
114 | last_hit_t g_last_hit_tracker; | |
115 | static last_hit_t last_hit_buffer; | |
116 | #endif // RGB_MATRIX_KEYREACTIVE_ENABLED | |
14b7602a JH |
117 | |
118 | uint32_t eeconfig_read_rgb_matrix(void) { | |
119 | return eeprom_read_dword(EECONFIG_RGB_MATRIX); | |
120 | } | |
c98247e3 | 121 | |
14b7602a JH |
122 | void eeconfig_update_rgb_matrix(uint32_t val) { |
123 | eeprom_update_dword(EECONFIG_RGB_MATRIX, val); | |
124 | } | |
c98247e3 | 125 | |
14b7602a JH |
126 | void eeconfig_update_rgb_matrix_default(void) { |
127 | dprintf("eeconfig_update_rgb_matrix_default\n"); | |
128 | rgb_matrix_config.enable = 1; | |
1d784f0f | 129 | rgb_matrix_config.mode = RGB_MATRIX_STARTUP_MODE; |
14b7602a | 130 | rgb_matrix_config.hue = 0; |
c98247e3 | 131 | rgb_matrix_config.sat = UINT8_MAX; |
a7df9027 | 132 | rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS; |
c98247e3 | 133 | rgb_matrix_config.speed = UINT8_MAX / 2; |
14b7602a JH |
134 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); |
135 | } | |
c98247e3 | 136 | |
14b7602a JH |
137 | void eeconfig_debug_rgb_matrix(void) { |
138 | dprintf("rgb_matrix_config eprom\n"); | |
139 | dprintf("rgb_matrix_config.enable = %d\n", rgb_matrix_config.enable); | |
140 | dprintf("rgb_matrix_config.mode = %d\n", rgb_matrix_config.mode); | |
141 | dprintf("rgb_matrix_config.hue = %d\n", rgb_matrix_config.hue); | |
142 | dprintf("rgb_matrix_config.sat = %d\n", rgb_matrix_config.sat); | |
143 | dprintf("rgb_matrix_config.val = %d\n", rgb_matrix_config.val); | |
afacd423 | 144 | dprintf("rgb_matrix_config.speed = %d\n", rgb_matrix_config.speed); |
14b7602a JH |
145 | } |
146 | ||
c98247e3 X |
147 | uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { |
148 | // TODO: This is kinda expensive, fix this soonish | |
149 | uint8_t led_count = 0; | |
150 | for (uint8_t i = 0; i < DRIVER_LED_TOTAL && led_count < LED_HITS_TO_REMEMBER; i++) { | |
151 | matrix_co_t matrix_co = g_rgb_leds[i].matrix_co; | |
152 | if (row == matrix_co.row && column == matrix_co.col) { | |
153 | led_i[led_count] = i; | |
154 | led_count++; | |
14b7602a | 155 | } |
c98247e3 X |
156 | } |
157 | return led_count; | |
14b7602a JH |
158 | } |
159 | ||
14b7602a | 160 | void rgb_matrix_update_pwm_buffers(void) { |
c98247e3 | 161 | rgb_matrix_driver.flush(); |
14b7602a JH |
162 | } |
163 | ||
164 | void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { | |
763b26cd DP |
165 | #ifdef RGB_MATRIX_EXTRA_TOG |
166 | const bool is_key = g_rgb_leds[index].matrix_co.raw != 0xff; | |
167 | if ( | |
168 | (rgb_matrix_config.enable == RGB_ZONE_KEYS && !is_key) || | |
169 | (rgb_matrix_config.enable == RGB_ZONE_UNDER && is_key) | |
170 | ) { | |
171 | rgb_matrix_driver.set_color(index, 0, 0, 0); | |
172 | return; | |
173 | } | |
174 | #endif | |
175 | ||
c98247e3 | 176 | rgb_matrix_driver.set_color(index, red, green, blue); |
14b7602a JH |
177 | } |
178 | ||
179 | void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { | |
763b26cd DP |
180 | #ifdef RGB_MATRIX_EXTRA_TOG |
181 | for (int i = 0; i < DRIVER_LED_TOTAL; i++) { | |
182 | rgb_matrix_set_color(i, red, green, blue); | |
183 | } | |
184 | #else | |
c98247e3 | 185 | rgb_matrix_driver.set_color_all(red, green, blue); |
763b26cd | 186 | #endif |
14b7602a JH |
187 | } |
188 | ||
14b7602a | 189 | bool process_rgb_matrix(uint16_t keycode, keyrecord_t *record) { |
c98247e3 X |
190 | #ifdef RGB_MATRIX_KEYREACTIVE_ENABLED |
191 | uint8_t led[LED_HITS_TO_REMEMBER]; | |
192 | uint8_t led_count = 0; | |
193 | ||
194 | #if defined(RGB_MATRIX_KEYRELEASES) | |
195 | if (!record->event.pressed) { | |
196 | led_count = rgb_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led); | |
197 | g_rgb_counters.any_key_hit = 0; | |
198 | } | |
199 | #elif defined(RGB_MATRIX_KEYPRESSES) | |
200 | if (record->event.pressed) { | |
201 | led_count = rgb_matrix_map_row_column_to_led(record->event.key.row, record->event.key.col, led); | |
202 | g_rgb_counters.any_key_hit = 0; | |
203 | } | |
204 | #endif // defined(RGB_MATRIX_KEYRELEASES) | |
205 | ||
206 | if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) { | |
207 | memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count); | |
208 | memcpy(&last_hit_buffer.y[0], &last_hit_buffer.y[led_count], LED_HITS_TO_REMEMBER - led_count); | |
209 | memcpy(&last_hit_buffer.tick[0], &last_hit_buffer.tick[led_count], (LED_HITS_TO_REMEMBER - led_count) * 2); // 16 bit | |
210 | memcpy(&last_hit_buffer.index[0], &last_hit_buffer.index[led_count], LED_HITS_TO_REMEMBER - led_count); | |
211 | last_hit_buffer.count--; | |
212 | } | |
14b7602a | 213 | |
c98247e3 X |
214 | for(uint8_t i = 0; i < led_count; i++) { |
215 | uint8_t index = last_hit_buffer.count; | |
216 | last_hit_buffer.x[index] = g_rgb_leds[led[i]].point.x; | |
217 | last_hit_buffer.y[index] = g_rgb_leds[led[i]].point.y; | |
218 | last_hit_buffer.index[index] = led[i]; | |
219 | last_hit_buffer.tick[index] = 0; | |
220 | last_hit_buffer.count++; | |
221 | } | |
222 | #endif // RGB_MATRIX_KEYREACTIVE_ENABLED | |
223 | return true; | |
14b7602a JH |
224 | } |
225 | ||
226 | void rgb_matrix_test(void) { | |
c98247e3 X |
227 | // Mask out bits 4 and 5 |
228 | // Increase the factor to make the test animation slower (and reduce to make it faster) | |
229 | uint8_t factor = 10; | |
230 | switch ( (g_rgb_counters.tick & (0b11 << factor)) >> factor ) | |
231 | { | |
232 | case 0: { | |
233 | rgb_matrix_set_color_all( 20, 0, 0 ); | |
234 | break; | |
14b7602a | 235 | } |
c98247e3 X |
236 | case 1: { |
237 | rgb_matrix_set_color_all( 0, 20, 0 ); | |
238 | break; | |
14b7602a | 239 | } |
c98247e3 X |
240 | case 2: { |
241 | rgb_matrix_set_color_all( 0, 0, 20 ); | |
242 | break; | |
14b7602a | 243 | } |
c98247e3 X |
244 | case 3: { |
245 | rgb_matrix_set_color_all( 20, 20, 20 ); | |
246 | break; | |
14b7602a | 247 | } |
c98247e3 | 248 | } |
14b7602a JH |
249 | } |
250 | ||
c98247e3 X |
251 | static bool rgb_matrix_none(effect_params_t* params) { |
252 | if (!params->init) { | |
253 | return false; | |
254 | } | |
14b7602a | 255 | |
c98247e3 X |
256 | RGB_MATRIX_USE_LIMITS(led_min, led_max); |
257 | for (uint8_t i = led_min; i < led_max; i++) { | |
258 | rgb_matrix_set_color(i, 0, 0, 0); | |
259 | } | |
260 | return led_max < DRIVER_LED_TOTAL; | |
14b7602a JH |
261 | } |
262 | ||
c98247e3 X |
263 | static uint8_t rgb_last_enable = UINT8_MAX; |
264 | static uint8_t rgb_last_effect = UINT8_MAX; | |
265 | static effect_params_t rgb_effect_params = { 0, 0 }; | |
266 | static rgb_task_states rgb_task_state = SYNCING; | |
14b7602a | 267 | |
c98247e3 X |
268 | static void rgb_task_timers(void) { |
269 | // Update double buffer timers | |
270 | uint16_t deltaTime = timer_elapsed32(rgb_counters_buffer); | |
271 | rgb_counters_buffer = timer_read32(); | |
272 | if (g_rgb_counters.any_key_hit < UINT32_MAX) { | |
273 | if (UINT32_MAX - deltaTime < g_rgb_counters.any_key_hit) { | |
274 | g_rgb_counters.any_key_hit = UINT32_MAX; | |
275 | } else { | |
276 | g_rgb_counters.any_key_hit += deltaTime; | |
14b7602a | 277 | } |
c98247e3 | 278 | } |
14b7602a | 279 | |
c98247e3 X |
280 | // Update double buffer last hit timers |
281 | #ifdef RGB_MATRIX_KEYREACTIVE_ENABLED | |
282 | uint8_t count = last_hit_buffer.count; | |
283 | for (uint8_t i = 0; i < count; ++i) { | |
284 | if (UINT16_MAX - deltaTime < last_hit_buffer.tick[i]) { | |
285 | last_hit_buffer.count--; | |
286 | continue; | |
14b7602a | 287 | } |
c98247e3 X |
288 | last_hit_buffer.tick[i] += deltaTime; |
289 | } | |
290 | #endif // RGB_MATRIX_KEYREACTIVE_ENABLED | |
291 | } | |
292 | ||
293 | static void rgb_task_sync(void) { | |
294 | // next task | |
295 | if (timer_elapsed32(g_rgb_counters.tick) >= RGB_MATRIX_LED_FLUSH_LIMIT) | |
296 | rgb_task_state = STARTING; | |
297 | } | |
298 | ||
299 | static void rgb_task_start(void) { | |
300 | // reset iter | |
301 | rgb_effect_params.iter = 0; | |
302 | ||
303 | // update double buffers | |
304 | g_rgb_counters.tick = rgb_counters_buffer; | |
305 | #ifdef RGB_MATRIX_KEYREACTIVE_ENABLED | |
306 | g_last_hit_tracker = last_hit_buffer; | |
307 | #endif // RGB_MATRIX_KEYREACTIVE_ENABLED | |
308 | ||
309 | // next task | |
310 | rgb_task_state = RENDERING; | |
311 | } | |
312 | ||
313 | static void rgb_task_render(uint8_t effect) { | |
314 | bool rendering = false; | |
315 | rgb_effect_params.init = (effect != rgb_last_effect) || (rgb_matrix_config.enable != rgb_last_enable); | |
316 | ||
317 | // each effect can opt to do calculations | |
318 | // and/or request PWM buffer updates. | |
319 | switch (effect) { | |
320 | case RGB_MATRIX_NONE: | |
321 | rendering = rgb_matrix_none(&rgb_effect_params); | |
322 | break; | |
323 | ||
324 | case RGB_MATRIX_SOLID_COLOR: | |
325 | rendering = rgb_matrix_solid_color(&rgb_effect_params); // Max 1ms Avg 0ms | |
326 | break; | |
327 | #ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS | |
328 | case RGB_MATRIX_ALPHAS_MODS: | |
329 | rendering = rgb_matrix_alphas_mods(&rgb_effect_params); // Max 2ms Avg 1ms | |
330 | break; | |
331 | #endif // DISABLE_RGB_MATRIX_ALPHAS_MODS | |
332 | #ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN | |
333 | case RGB_MATRIX_GRADIENT_UP_DOWN: | |
334 | rendering = rgb_matrix_gradient_up_down(&rgb_effect_params); // Max 4ms Avg 3ms | |
335 | break; | |
336 | #endif // DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN | |
337 | #ifndef DISABLE_RGB_MATRIX_BREATHING | |
338 | case RGB_MATRIX_BREATHING: | |
339 | rendering = rgb_matrix_breathing(&rgb_effect_params); // Max 1ms Avg 0ms | |
340 | break; | |
341 | #endif // DISABLE_RGB_MATRIX_BREATHING | |
342 | #ifndef DISABLE_RGB_MATRIX_CYCLE_ALL | |
343 | case RGB_MATRIX_CYCLE_ALL: | |
344 | rendering = rgb_matrix_cycle_all(&rgb_effect_params); // Max 4ms Avg 3ms | |
345 | break; | |
346 | #endif // DISABLE_RGB_MATRIX_CYCLE_ALL | |
347 | #ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT | |
348 | case RGB_MATRIX_CYCLE_LEFT_RIGHT: | |
349 | rendering = rgb_matrix_cycle_left_right(&rgb_effect_params); // Max 4ms Avg 3ms | |
350 | break; | |
351 | #endif // DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT | |
352 | #ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN | |
353 | case RGB_MATRIX_CYCLE_UP_DOWN: | |
354 | rendering = rgb_matrix_cycle_up_down(&rgb_effect_params); // Max 4ms Avg 3ms | |
355 | break; | |
356 | #endif // DISABLE_RGB_MATRIX_CYCLE_UP_DOWN | |
357 | #ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON | |
358 | case RGB_MATRIX_RAINBOW_MOVING_CHEVRON: | |
359 | rendering = rgb_matrix_rainbow_moving_chevron(&rgb_effect_params); // Max 4ms Avg 3ms | |
360 | break; | |
361 | #endif // DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON | |
362 | #ifndef DISABLE_RGB_MATRIX_DUAL_BEACON | |
363 | case RGB_MATRIX_DUAL_BEACON: | |
364 | rendering = rgb_matrix_dual_beacon(&rgb_effect_params); // Max 4ms Avg 3ms | |
365 | break; | |
366 | #endif // DISABLE_RGB_MATRIX_DUAL_BEACON | |
367 | #ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON | |
368 | case RGB_MATRIX_RAINBOW_BEACON: | |
369 | rendering = rgb_matrix_rainbow_beacon(&rgb_effect_params); // Max 4ms Avg 3ms | |
370 | break; | |
371 | #endif // DISABLE_RGB_MATRIX_RAINBOW_BEACON | |
372 | #ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS | |
373 | case RGB_MATRIX_RAINBOW_PINWHEELS: | |
374 | rendering = rgb_matrix_rainbow_pinwheels(&rgb_effect_params); // Max 4ms Avg 3ms | |
375 | break; | |
376 | #endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS | |
377 | #ifndef DISABLE_RGB_MATRIX_RAINDROPS | |
378 | case RGB_MATRIX_RAINDROPS: | |
379 | rendering = rgb_matrix_raindrops(&rgb_effect_params); // Max 1ms Avg 0ms | |
380 | break; | |
381 | #endif // DISABLE_RGB_MATRIX_RAINDROPS | |
382 | #ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS | |
383 | case RGB_MATRIX_JELLYBEAN_RAINDROPS: | |
384 | rendering = rgb_matrix_jellybean_raindrops(&rgb_effect_params); // Max 1ms Avg 0ms | |
385 | break; | |
386 | #endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS | |
387 | #ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN | |
388 | case RGB_MATRIX_DIGITAL_RAIN: | |
389 | rendering = rgb_matrix_digital_rain(&rgb_effect_params); // Max 9ms Avg 8ms | this is expensive, fix it | |
390 | break; | |
391 | #endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN | |
392 | #ifdef RGB_MATRIX_KEYREACTIVE_ENABLED | |
393 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE | |
394 | case RGB_MATRIX_SOLID_REACTIVE_SIMPLE: | |
395 | rendering = rgb_matrix_solid_reactive_simple(&rgb_effect_params);// Max 4ms Avg 3ms | |
396 | break; | |
397 | #endif | |
398 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE | |
399 | case RGB_MATRIX_SOLID_REACTIVE: | |
400 | rendering = rgb_matrix_solid_reactive(&rgb_effect_params); // Max 4ms Avg 3ms | |
401 | break; | |
402 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE | |
bb52119a A |
403 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE |
404 | case RGB_MATRIX_SOLID_REACTIVE_WIDE: | |
405 | rendering = rgb_matrix_solid_reactive_wide(&rgb_effect_params); // Max ?? ms Avg ?? ms | |
406 | break; | |
407 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE | |
408 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE | |
409 | case RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE: | |
410 | rendering = rgb_matrix_solid_reactive_multiwide(&rgb_effect_params); // Max ?? ms Avg ?? ms | |
411 | break; | |
412 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE | |
413 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS | |
414 | case RGB_MATRIX_SOLID_REACTIVE_CROSS: | |
415 | rendering = rgb_matrix_solid_reactive_cross(&rgb_effect_params); // Max ?? ms Avg ?? ms | |
416 | break; | |
417 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS | |
418 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS | |
419 | case RGB_MATRIX_SOLID_REACTIVE_MULTICROSS: | |
420 | rendering = rgb_matrix_solid_reactive_multicross(&rgb_effect_params); // Max ?? ms Avg ?? ms | |
421 | break; | |
422 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS | |
423 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS | |
424 | case RGB_MATRIX_SOLID_REACTIVE_NEXUS: | |
425 | rendering = rgb_matrix_solid_reactive_nexus(&rgb_effect_params); // Max ?? ms Avg ?? ms | |
426 | break; | |
427 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS | |
428 | #ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS | |
429 | case RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS: | |
430 | rendering = rgb_matrix_solid_reactive_multinexus(&rgb_effect_params); // Max ?? ms Avg ?? ms | |
431 | break; | |
432 | #endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS | |
c98247e3 X |
433 | #ifndef DISABLE_RGB_MATRIX_SPLASH |
434 | case RGB_MATRIX_SPLASH: | |
435 | rendering = rgb_matrix_splash(&rgb_effect_params); // Max 5ms Avg 3ms | |
436 | break; | |
437 | #endif // DISABLE_RGB_MATRIX_SPLASH | |
438 | #ifndef DISABLE_RGB_MATRIX_MULTISPLASH | |
439 | case RGB_MATRIX_MULTISPLASH: | |
440 | rendering = rgb_matrix_multisplash(&rgb_effect_params); // Max 10ms Avg 5ms | |
441 | break; | |
442 | #endif // DISABLE_RGB_MATRIX_MULTISPLASH | |
443 | #ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH | |
444 | case RGB_MATRIX_SOLID_SPLASH: | |
445 | rendering = rgb_matrix_solid_splash(&rgb_effect_params); // Max 5ms Avg 3ms | |
446 | break; | |
447 | #endif // DISABLE_RGB_MATRIX_SOLID_SPLASH | |
448 | #ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH | |
449 | case RGB_MATRIX_SOLID_MULTISPLASH: | |
450 | rendering = rgb_matrix_solid_multisplash(&rgb_effect_params); // Max 10ms Avg 5ms | |
451 | break; | |
452 | #endif // DISABLE_RGB_MATRIX_SOLID_MULTISPLASH | |
453 | #endif // RGB_MATRIX_KEYREACTIVE_ENABLED | |
14b7602a | 454 | |
1d784f0f DP |
455 | #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) |
456 | #define RGB_MATRIX_EFFECT(name, ...) \ | |
457 | case RGB_MATRIX_CUSTOM_##name: \ | |
458 | rendering = name(&rgb_effect_params); \ | |
459 | break; | |
460 | #ifdef RGB_MATRIX_CUSTOM_KB | |
461 | #include "rgb_matrix_kb.inc" | |
462 | #endif | |
463 | #ifdef RGB_MATRIX_CUSTOM_USER | |
464 | #include "rgb_matrix_user.inc" | |
465 | #endif | |
466 | #undef RGB_MATRIX_EFFECT | |
467 | #endif | |
468 | ||
c98247e3 X |
469 | // Factory default magic value |
470 | case UINT8_MAX: { | |
471 | rgb_matrix_test(); | |
472 | rgb_task_state = FLUSHING; | |
473 | } | |
474 | return; | |
475 | } | |
14b7602a | 476 | |
c98247e3 | 477 | rgb_effect_params.iter++; |
14b7602a | 478 | |
c98247e3 X |
479 | // next task |
480 | if (!rendering) { | |
481 | rgb_task_state = FLUSHING; | |
482 | if (!rgb_effect_params.init && effect == RGB_MATRIX_NONE) { | |
483 | // We only need to flush once if we are RGB_MATRIX_NONE | |
484 | rgb_task_state = SYNCING; | |
14b7602a | 485 | } |
c98247e3 | 486 | } |
14b7602a JH |
487 | } |
488 | ||
c98247e3 X |
489 | static void rgb_task_flush(uint8_t effect) { |
490 | // update last trackers after the first full render so we can init over several frames | |
491 | rgb_last_effect = effect; | |
492 | rgb_last_enable = rgb_matrix_config.enable; | |
4d5705ea | 493 | |
c98247e3 X |
494 | // update pwm buffers |
495 | rgb_matrix_update_pwm_buffers(); | |
4d5705ea | 496 | |
c98247e3 X |
497 | // next task |
498 | rgb_task_state = SYNCING; | |
14b7602a JH |
499 | } |
500 | ||
501 | void rgb_matrix_task(void) { | |
c98247e3 X |
502 | rgb_task_timers(); |
503 | ||
504 | // Ideally we would also stop sending zeros to the LED driver PWM buffers | |
505 | // while suspended and just do a software shutdown. This is a cheap hack for now. | |
506 | bool suspend_backlight = ((g_suspend_state && RGB_DISABLE_WHEN_USB_SUSPENDED) || (RGB_DISABLE_AFTER_TIMEOUT > 0 && g_rgb_counters.any_key_hit > RGB_DISABLE_AFTER_TIMEOUT * 60 * 20)); | |
507 | uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode; | |
508 | ||
509 | switch (rgb_task_state) { | |
510 | case STARTING: | |
511 | rgb_task_start(); | |
512 | break; | |
513 | case RENDERING: | |
514 | rgb_task_render(effect); | |
515 | break; | |
516 | case FLUSHING: | |
517 | rgb_task_flush(effect); | |
518 | break; | |
519 | case SYNCING: | |
520 | rgb_task_sync(); | |
521 | break; | |
522 | } | |
14b7602a | 523 | |
c98247e3 X |
524 | if (!suspend_backlight) { |
525 | rgb_matrix_indicators(); | |
526 | } | |
14b7602a JH |
527 | } |
528 | ||
529 | void rgb_matrix_indicators(void) { | |
c98247e3 X |
530 | rgb_matrix_indicators_kb(); |
531 | rgb_matrix_indicators_user(); | |
14b7602a JH |
532 | } |
533 | ||
534 | __attribute__((weak)) | |
535 | void rgb_matrix_indicators_kb(void) {} | |
536 | ||
537 | __attribute__((weak)) | |
538 | void rgb_matrix_indicators_user(void) {} | |
539 | ||
bad56a4f | 540 | void rgb_matrix_init(void) { |
f70f45ee | 541 | rgb_matrix_driver.init(); |
bad56a4f JH |
542 | |
543 | // TODO: put the 1 second startup delay here? | |
544 | ||
c98247e3 X |
545 | #ifdef RGB_MATRIX_KEYREACTIVE_ENABLED |
546 | g_last_hit_tracker.count = 0; | |
547 | for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { | |
548 | g_last_hit_tracker.tick[i] = UINT16_MAX; | |
bad56a4f JH |
549 | } |
550 | ||
c98247e3 X |
551 | last_hit_buffer.count = 0; |
552 | for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { | |
553 | last_hit_buffer.tick[i] = UINT16_MAX; | |
554 | } | |
555 | #endif // RGB_MATRIX_KEYREACTIVE_ENABLED | |
bad56a4f JH |
556 | |
557 | if (!eeconfig_is_enabled()) { | |
c98247e3 X |
558 | dprintf("rgb_matrix_init_drivers eeconfig is not enabled.\n"); |
559 | eeconfig_init(); | |
560 | eeconfig_update_rgb_matrix_default(); | |
bad56a4f | 561 | } |
c98247e3 | 562 | |
bad56a4f | 563 | rgb_matrix_config.raw = eeconfig_read_rgb_matrix(); |
c98247e3 | 564 | rgb_matrix_config.speed = UINT8_MAX / 2; //EECONFIG needs to be increased to support this |
bad56a4f | 565 | if (!rgb_matrix_config.mode) { |
c98247e3 X |
566 | dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n"); |
567 | eeconfig_update_rgb_matrix_default(); | |
568 | rgb_matrix_config.raw = eeconfig_read_rgb_matrix(); | |
bad56a4f JH |
569 | } |
570 | eeconfig_debug_rgb_matrix(); // display current eeprom values | |
571 | } | |
572 | ||
c98247e3 X |
573 | void rgb_matrix_set_suspend_state(bool state) { |
574 | g_suspend_state = state; | |
14b7602a JH |
575 | } |
576 | ||
da1afe15 | 577 | void rgb_matrix_toggle(void) { |
763b26cd | 578 | rgb_matrix_config.enable++; |
c98247e3 X |
579 | if (!rgb_matrix_config.enable) { |
580 | rgb_task_state = STARTING; | |
581 | } | |
582 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
583 | } |
584 | ||
da1afe15 DJ |
585 | void rgb_matrix_enable(void) { |
586 | rgb_matrix_config.enable = 1; | |
c98247e3 | 587 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); |
da1afe15 DJ |
588 | } |
589 | ||
590 | void rgb_matrix_enable_noeeprom(void) { | |
591 | rgb_matrix_config.enable = 1; | |
592 | } | |
593 | ||
594 | void rgb_matrix_disable(void) { | |
595 | rgb_matrix_config.enable = 0; | |
c98247e3 | 596 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); |
da1afe15 DJ |
597 | } |
598 | ||
599 | void rgb_matrix_disable_noeeprom(void) { | |
600 | rgb_matrix_config.enable = 0; | |
601 | } | |
602 | ||
603 | void rgb_matrix_step(void) { | |
c98247e3 X |
604 | rgb_matrix_config.mode++; |
605 | if (rgb_matrix_config.mode >= RGB_MATRIX_EFFECT_MAX) | |
606 | rgb_matrix_config.mode = 1; | |
607 | rgb_task_state = STARTING; | |
608 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
609 | } |
610 | ||
da1afe15 | 611 | void rgb_matrix_step_reverse(void) { |
c98247e3 X |
612 | rgb_matrix_config.mode--; |
613 | if (rgb_matrix_config.mode < 1) | |
614 | rgb_matrix_config.mode = RGB_MATRIX_EFFECT_MAX - 1; | |
615 | rgb_task_state = STARTING; | |
616 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
617 | } |
618 | ||
da1afe15 | 619 | void rgb_matrix_increase_hue(void) { |
c98247e3 X |
620 | rgb_matrix_config.hue += RGB_MATRIX_HUE_STEP; |
621 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
622 | } |
623 | ||
da1afe15 | 624 | void rgb_matrix_decrease_hue(void) { |
c98247e3 X |
625 | rgb_matrix_config.hue -= RGB_MATRIX_HUE_STEP; |
626 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
627 | } |
628 | ||
da1afe15 | 629 | void rgb_matrix_increase_sat(void) { |
c98247e3 X |
630 | rgb_matrix_config.sat = qadd8(rgb_matrix_config.sat, RGB_MATRIX_SAT_STEP); |
631 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
632 | } |
633 | ||
da1afe15 | 634 | void rgb_matrix_decrease_sat(void) { |
c98247e3 X |
635 | rgb_matrix_config.sat = qsub8(rgb_matrix_config.sat, RGB_MATRIX_SAT_STEP); |
636 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
637 | } |
638 | ||
da1afe15 | 639 | void rgb_matrix_increase_val(void) { |
c98247e3 X |
640 | rgb_matrix_config.val = qadd8(rgb_matrix_config.val, RGB_MATRIX_VAL_STEP); |
641 | if (rgb_matrix_config.val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) | |
642 | rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS; | |
643 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
644 | } |
645 | ||
da1afe15 | 646 | void rgb_matrix_decrease_val(void) { |
c98247e3 X |
647 | rgb_matrix_config.val = qsub8(rgb_matrix_config.val, RGB_MATRIX_VAL_STEP); |
648 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
649 | } |
650 | ||
da1afe15 | 651 | void rgb_matrix_increase_speed(void) { |
c98247e3 X |
652 | rgb_matrix_config.speed = qadd8(rgb_matrix_config.speed, RGB_MATRIX_SPD_STEP); |
653 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this | |
afacd423 | 654 | } |
655 | ||
da1afe15 | 656 | void rgb_matrix_decrease_speed(void) { |
c98247e3 X |
657 | rgb_matrix_config.speed = qsub8(rgb_matrix_config.speed, RGB_MATRIX_SPD_STEP); |
658 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw);//EECONFIG needs to be increased to support this | |
afacd423 | 659 | } |
660 | ||
da1afe15 | 661 | void rgb_matrix_mode(uint8_t mode) { |
c98247e3 X |
662 | rgb_matrix_config.mode = mode; |
663 | rgb_task_state = STARTING; | |
664 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); | |
14b7602a JH |
665 | } |
666 | ||
da1afe15 | 667 | void rgb_matrix_mode_noeeprom(uint8_t mode) { |
c98247e3 | 668 | rgb_matrix_config.mode = mode; |
da1afe15 DJ |
669 | } |
670 | ||
b7688590 | 671 | uint8_t rgb_matrix_get_mode(void) { |
c98247e3 | 672 | return rgb_matrix_config.mode; |
14b7602a | 673 | } |
9aecf4cc | 674 | |
da1afe15 | 675 | void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { |
c98247e3 | 676 | rgb_matrix_sethsv_noeeprom(hue, sat, val); |
9aecf4cc FD |
677 | eeconfig_update_rgb_matrix(rgb_matrix_config.raw); |
678 | } | |
da1afe15 DJ |
679 | |
680 | void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { | |
681 | rgb_matrix_config.hue = hue; | |
682 | rgb_matrix_config.sat = sat; | |
683 | rgb_matrix_config.val = val; | |
c98247e3 X |
684 | if (rgb_matrix_config.val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) |
685 | rgb_matrix_config.val = RGB_MATRIX_MAXIMUM_BRIGHTNESS; | |
da1afe15 | 686 | } |