aboutsummaryrefslogtreecommitdiff
path: root/quantum/led_matrix.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/led_matrix.c')
-rw-r--r--quantum/led_matrix.c455
1 files changed, 279 insertions, 176 deletions
diff --git a/quantum/led_matrix.c b/quantum/led_matrix.c
index 4f1f06c7a..c40e5bd7d 100644
--- a/quantum/led_matrix.c
+++ b/quantum/led_matrix.c
@@ -17,17 +17,15 @@
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20#include <stdint.h>
21#include <stdbool.h>
22#include "quantum.h"
23#include "led_matrix.h" 20#include "led_matrix.h"
24#include "progmem.h" 21#include "progmem.h"
25#include "config.h" 22#include "config.h"
26#include "eeprom.h" 23#include "eeprom.h"
27#include <string.h> 24#include <string.h>
28#include <math.h> 25#include <math.h>
26#include "led_tables.h"
29 27
30led_eeconfig_t led_matrix_eeconfig; 28#include <lib/lib8tion/lib8tion.h>
31 29
32#ifndef MAX 30#ifndef MAX
33# define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) 31# define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
@@ -37,59 +35,90 @@ led_eeconfig_t led_matrix_eeconfig;
37# define MIN(a, b) ((a) < (b) ? (a) : (b)) 35# define MIN(a, b) ((a) < (b) ? (a) : (b))
38#endif 36#endif
39 37
40#ifndef LED_DISABLE_AFTER_TIMEOUT 38#if defined(LED_DISABLE_AFTER_TIMEOUT) && !defined(LED_DISABLE_TIMEOUT)
41# define LED_DISABLE_AFTER_TIMEOUT 0 39# define LED_DISABLE_TIMEOUT (LED_DISABLE_AFTER_TIMEOUT * 1200UL)
40#endif
41
42#ifndef LED_DISABLE_TIMEOUT
43# define LED_DISABLE_TIMEOUT 0
42#endif 44#endif
43 45
44#ifndef LED_DISABLE_WHEN_USB_SUSPENDED 46#ifndef LED_DISABLE_WHEN_USB_SUSPENDED
45# define LED_DISABLE_WHEN_USB_SUSPENDED false 47# define LED_DISABLE_WHEN_USB_SUSPENDED false
46#endif 48#endif
47 49
48#ifndef EECONFIG_LED_MATRIX 50#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX
49# define EECONFIG_LED_MATRIX EECONFIG_RGBLIGHT 51# undef LED_MATRIX_MAXIMUM_BRIGHTNESS
52# define LED_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX
50#endif 53#endif
51 54
52#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > 255 55#if !defined(LED_MATRIX_VAL_STEP)
53# define LED_MATRIX_MAXIMUM_BRIGHTNESS 255 56# define LED_MATRIX_VAL_STEP 8
54#endif 57#endif
55 58
56bool g_suspend_state = false; 59#if !defined(LED_MATRIX_SPD_STEP)
60# define LED_MATRIX_SPD_STEP 16
61#endif
57 62
58// Global tick at 20 Hz 63#if !defined(LED_MATRIX_STARTUP_MODE)
59uint32_t g_tick = 0; 64# define LED_MATRIX_STARTUP_MODE LED_MATRIX_UNIFORM_BRIGHTNESS
65#endif
60 66
61// Ticks since this key was last hit. 67#if !defined(LED_MATRIX_STARTUP_VAL)
62uint8_t g_key_hit[DRIVER_LED_TOTAL]; 68# define LED_MATRIX_STARTUP_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS
69#endif
63 70
64// Ticks since any key was last hit. 71#if !defined(LED_MATRIX_STARTUP_SPD)
65uint32_t g_any_key_hit = 0; 72# define LED_MATRIX_STARTUP_SPD UINT8_MAX / 2
73#endif
66 74
67uint32_t eeconfig_read_led_matrix(void) { return eeprom_read_dword(EECONFIG_LED_MATRIX); } 75// globals
76bool g_suspend_state = false;
77led_eeconfig_t led_matrix_eeconfig; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr
78uint32_t g_led_timer;
68 79
69void eeconfig_update_led_matrix(uint32_t config_value) { eeprom_update_dword(EECONFIG_LED_MATRIX, config_value); } 80// internals
81static uint8_t led_last_enable = UINT8_MAX;
82static uint8_t led_last_effect = UINT8_MAX;
83static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false};
84static led_task_states led_task_state = SYNCING;
85#if LED_DISABLE_TIMEOUT > 0
86static uint32_t led_anykey_timer;
87#endif // LED_DISABLE_TIMEOUT > 0
88
89// double buffers
90static uint32_t led_timer_buffer;
91
92void eeconfig_read_led_matrix(void) { eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }
93
94void eeconfig_update_led_matrix(void) { eeprom_update_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); }
70 95
71void eeconfig_update_led_matrix_default(void) { 96void eeconfig_update_led_matrix_default(void) {
72 dprintf("eeconfig_update_led_matrix_default\n"); 97 dprintf("eeconfig_update_led_matrix_default\n");
73 led_matrix_eeconfig.enable = 1; 98 led_matrix_eeconfig.enable = 1;
74 led_matrix_eeconfig.mode = LED_MATRIX_UNIFORM_BRIGHTNESS; 99 led_matrix_eeconfig.mode = LED_MATRIX_STARTUP_MODE;
75 led_matrix_eeconfig.val = 128; 100 led_matrix_eeconfig.val = LED_MATRIX_STARTUP_VAL;
76 led_matrix_eeconfig.speed = 0; 101 led_matrix_eeconfig.speed = LED_MATRIX_STARTUP_SPD;
77 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 102 led_matrix_eeconfig.flags = LED_FLAG_ALL;
103 eeconfig_update_led_matrix();
78} 104}
79 105
80void eeconfig_debug_led_matrix(void) { 106void eeconfig_debug_led_matrix(void) {
81 dprintf("led_matrix_eeconfig eeprom\n"); 107 dprintf("led_matrix_eeconfig EEPROM\n");
82 dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable); 108 dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable);
83 dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode); 109 dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode);
84 dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val); 110 dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val);
85 dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed); 111 dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed);
112 dprintf("led_matrix_eeconfig.flags = %d\n", led_matrix_eeconfig.flags);
86} 113}
87 114
88uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255}; 115uint8_t g_last_led_hit[LED_HITS_TO_REMEMBER] = {255};
89uint8_t g_last_led_count = 0; 116uint8_t g_last_led_count = 0;
90 117
91uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { 118__attribute__((weak)) uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { return 0; }
92 uint8_t led_count = 0; 119
120uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
121 uint8_t led_count = led_matrix_map_row_column_to_led_kb(row, column, led_i);
93 uint8_t led_index = g_led_config.matrix_co[row][column]; 122 uint8_t led_index = g_led_config.matrix_co[row][column];
94 if (led_index != NO_LED) { 123 if (led_index != NO_LED) {
95 led_i[led_count] = led_index; 124 led_i[led_count] = led_index;
@@ -100,14 +129,30 @@ uint8_t map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) {
100 129
101void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); } 130void led_matrix_update_pwm_buffers(void) { led_matrix_driver.flush(); }
102 131
103void led_matrix_set_index_value(int index, uint8_t value) { led_matrix_driver.set_value(index, value); } 132void led_matrix_set_value(int index, uint8_t value) {
133#ifdef USE_CIE1931_CURVE
134 led_matrix_driver.set_value(index, pgm_read_byte(&CIE1931_CURVE[value]));
135#else
136 led_matrix_driver.set_value(index, value);
137#endif
138}
139
140void led_matrix_set_value_all(uint8_t value) {
141#ifdef USE_CIE1931_CURVE
142 led_matrix_driver.set_value_all(pgm_read_byte(&CIE1931_CURVE[value]));
143#else
144 led_matrix_driver.set_value_all(value);
145#endif
146}
104 147
105void led_matrix_set_index_value_all(uint8_t value) { led_matrix_driver.set_value_all(value); } 148void process_led_matrix(uint8_t row, uint8_t col, bool pressed) {
149#if LED_DISABLE_TIMEOUT > 0
150 led_anykey_timer = 0;
151#endif // LED_DISABLE_TIMEOUT > 0
106 152
107bool process_led_matrix(uint16_t keycode, keyrecord_t *record) { 153 if (pressed) {
108 if (record->event.pressed) {
109 uint8_t led[8]; 154 uint8_t led[8];
110 uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led); 155 uint8_t led_count = led_matrix_map_row_column_to_led(row, col, led);
111 if (led_count > 0) { 156 if (led_count > 0) {
112 for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) { 157 for (uint8_t i = LED_HITS_TO_REMEMBER; i > 1; i--) {
113 g_last_led_hit[i - 1] = g_last_led_hit[i - 2]; 158 g_last_led_hit[i - 1] = g_last_led_hit[i - 2];
@@ -115,73 +160,143 @@ bool process_led_matrix(uint16_t keycode, keyrecord_t *record) {
115 g_last_led_hit[0] = led[0]; 160 g_last_led_hit[0] = led[0];
116 g_last_led_count = MIN(LED_HITS_TO_REMEMBER, g_last_led_count + 1); 161 g_last_led_count = MIN(LED_HITS_TO_REMEMBER, g_last_led_count + 1);
117 } 162 }
118 for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 0;
119 g_any_key_hit = 0;
120 } else { 163 } else {
121#ifdef LED_MATRIX_KEYRELEASES 164#ifdef LED_MATRIX_KEYRELEASES
122 uint8_t led[8]; 165 uint8_t led[8];
123 uint8_t led_count = map_row_column_to_led(record->event.key.row, record->event.key.col, led); 166 uint8_t led_count = led_matrix_map_row_column_to_led(row, .col, led);
124 for (uint8_t i = 0; i < led_count; i++) g_key_hit[led[i]] = 255;
125
126 g_any_key_hit = 255;
127#endif 167#endif
128 } 168 }
129 return true;
130} 169}
131 170
132void led_matrix_set_suspend_state(bool state) { g_suspend_state = state; } 171static bool led_matrix_none(effect_params_t *params) {
172 if (!params->init) {
173 return false;
174 }
133 175
134// All LEDs off 176 led_matrix_set_value_all(0);
135void led_matrix_all_off(void) { led_matrix_set_index_value_all(0); } 177 return false;
178}
136 179
137// Uniform brightness 180static bool led_matrix_uniform_brightness(effect_params_t *params) {
138void led_matrix_uniform_brightness(void) { led_matrix_set_index_value_all(LED_MATRIX_MAXIMUM_BRIGHTNESS / BACKLIGHT_LEVELS * led_matrix_eeconfig.val); } 181 LED_MATRIX_USE_LIMITS(led_min, led_max);
139 182
140void led_matrix_custom(void) {} 183 uint8_t val = led_matrix_eeconfig.val;
184 for (uint8_t i = led_min; i < led_max; i++) {
185 LED_MATRIX_TEST_LED_FLAGS();
186 led_matrix_set_value(i, val);
187 }
188 return led_max < DRIVER_LED_TOTAL;
189}
141 190
142void led_matrix_task(void) { 191static void led_task_timers(void) {
143 if (!led_matrix_eeconfig.enable) { 192#if LED_DISABLE_TIMEOUT > 0
144 led_matrix_all_off(); 193 uint32_t deltaTime = sync_timer_elapsed32(led_timer_buffer);
145 led_matrix_indicators(); 194#endif // LED_DISABLE_TIMEOUT > 0
146 return; 195 led_timer_buffer = sync_timer_read32();
196
197 // Update double buffer timers
198#if LED_DISABLE_TIMEOUT > 0
199 if (led_anykey_timer < UINT32_MAX) {
200 if (UINT32_MAX - deltaTime < led_anykey_timer) {
201 led_anykey_timer = UINT32_MAX;
202 } else {
203 led_anykey_timer += deltaTime;
204 }
147 } 205 }
206#endif // LED_DISABLE_TIMEOUT > 0
207}
148 208
149 g_tick++; 209static void led_task_sync(void) {
210 // next task
211 if (sync_timer_elapsed32(g_led_timer) >= LED_MATRIX_LED_FLUSH_LIMIT) led_task_state = STARTING;
212}
150 213
151 if (g_any_key_hit < 0xFFFFFFFF) { 214static void led_task_start(void) {
152 g_any_key_hit++; 215 // reset iter
153 } 216 led_effect_params.iter = 0;
154 217
155 for (int led = 0; led < DRIVER_LED_TOTAL; led++) { 218 // update double buffers
156 if (g_key_hit[led] < 255) { 219 g_led_timer = led_timer_buffer;
157 if (g_key_hit[led] == 254) g_last_led_count = MAX(g_last_led_count - 1, 0);
158 g_key_hit[led]++;
159 }
160 }
161 220
162 // Ideally we would also stop sending zeros to the LED driver PWM buffers 221 // next task
163 // while suspended and just do a software shutdown. This is a cheap hack for now. 222 led_task_state = RENDERING;
164 bool suspend_backlight = ((g_suspend_state && LED_DISABLE_WHEN_USB_SUSPENDED) || (LED_DISABLE_AFTER_TIMEOUT > 0 && g_any_key_hit > LED_DISABLE_AFTER_TIMEOUT * 60 * 20)); 223}
165 uint8_t effect = suspend_backlight ? 0 : led_matrix_eeconfig.mode; 224
225static void led_task_render(uint8_t effect) {
226 bool rendering = false;
227 led_effect_params.init = (effect != led_last_effect) || (led_matrix_eeconfig.enable != led_last_enable);
228 if (led_effect_params.flags != led_matrix_eeconfig.flags) {
229 led_effect_params.flags = led_matrix_eeconfig.flags;
230 led_matrix_set_value_all(0);
231 }
166 232
167 // this gets ticked at 20 Hz.
168 // each effect can opt to do calculations 233 // each effect can opt to do calculations
169 // and/or request PWM buffer updates. 234 // and/or request PWM buffer updates.
170 switch (effect) { 235 switch (effect) {
236 case LED_MATRIX_NONE:
237 rendering = led_matrix_none(&led_effect_params);
171 case LED_MATRIX_UNIFORM_BRIGHTNESS: 238 case LED_MATRIX_UNIFORM_BRIGHTNESS:
172 led_matrix_uniform_brightness(); 239 rendering = led_matrix_uniform_brightness(&led_effect_params);
173 break;
174 default:
175 led_matrix_custom();
176 break; 240 break;
177 } 241 }
178 242
179 if (!suspend_backlight) { 243 led_effect_params.iter++;
180 led_matrix_indicators(); 244
245 // next task
246 if (!rendering) {
247 led_task_state = FLUSHING;
248 if (!led_effect_params.init && effect == LED_MATRIX_NONE) {
249 // We only need to flush once if we are LED_MATRIX_NONE
250 led_task_state = SYNCING;
251 }
181 } 252 }
253}
254
255static void led_task_flush(uint8_t effect) {
256 // update last trackers after the first full render so we can init over several frames
257 led_last_effect = effect;
258 led_last_enable = led_matrix_eeconfig.enable;
259
260 // update pwm buffers
261 led_matrix_update_pwm_buffers();
262
263 // next task
264 led_task_state = SYNCING;
265}
266
267void led_matrix_task(void) {
268 led_task_timers();
182 269
183 // Tell the LED driver to update its state 270 // Ideally we would also stop sending zeros to the LED driver PWM buffers
184 led_matrix_driver.flush(); 271 // while suspended and just do a software shutdown. This is a cheap hack for now.
272 bool suspend_backlight =
273#if LED_DISABLE_WHEN_USB_SUSPENDED == true
274 g_suspend_state ||
275#endif // LED_DISABLE_WHEN_USB_SUSPENDED == true
276#if LED_DISABLE_TIMEOUT > 0
277 (led_anykey_timer > (uint32_t)LED_DISABLE_TIMEOUT) ||
278#endif // LED_DISABLE_TIMEOUT > 0
279 false;
280
281 uint8_t effect = suspend_backlight || !led_matrix_eeconfig.enable ? 0 : led_matrix_eeconfig.mode;
282
283 switch (led_task_state) {
284 case STARTING:
285 led_task_start();
286 break;
287 case RENDERING:
288 led_task_render(effect);
289 if (effect) {
290 led_matrix_indicators();
291 }
292 break;
293 case FLUSHING:
294 led_task_flush(effect);
295 break;
296 case SYNCING:
297 led_task_sync();
298 break;
299 }
185} 300}
186 301
187void led_matrix_indicators(void) { 302void led_matrix_indicators(void) {
@@ -193,156 +308,144 @@ __attribute__((weak)) void led_matrix_indicators_kb(void) {}
193 308
194__attribute__((weak)) void led_matrix_indicators_user(void) {} 309__attribute__((weak)) void led_matrix_indicators_user(void) {}
195 310
196// void led_matrix_set_indicator_index(uint8_t *index, uint8_t row, uint8_t column)
197// {
198// if (row >= MATRIX_ROWS)
199// {
200// // Special value, 255=none, 254=all
201// *index = row;
202// }
203// else
204// {
205// // This needs updated to something like
206// // uint8_t led[8];
207// // uint8_t led_count = map_row_column_to_led(row, column, led);
208// // for(uint8_t i = 0; i < led_count; i++)
209// map_row_column_to_led(row, column, index);
210// }
211// }
212
213void led_matrix_init(void) { 311void led_matrix_init(void) {
214 led_matrix_driver.init(); 312 led_matrix_driver.init();
215 313
216 // Wait half a second for the driver to finish initializing
217 wait_ms(500);
218
219 // clear the key hits
220 for (int led = 0; led < DRIVER_LED_TOTAL; led++) {
221 g_key_hit[led] = 255;
222 }
223
224 if (!eeconfig_is_enabled()) { 314 if (!eeconfig_is_enabled()) {
225 dprintf("led_matrix_init_drivers eeconfig is not enabled.\n"); 315 dprintf("led_matrix_init_drivers eeconfig is not enabled.\n");
226 eeconfig_init(); 316 eeconfig_init();
227 eeconfig_update_led_matrix_default(); 317 eeconfig_update_led_matrix_default();
228 } 318 }
229 319
230 led_matrix_eeconfig.raw = eeconfig_read_led_matrix(); 320 eeconfig_read_led_matrix();
231
232 if (!led_matrix_eeconfig.mode) { 321 if (!led_matrix_eeconfig.mode) {
233 dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n"); 322 dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n");
234 eeconfig_update_led_matrix_default(); 323 eeconfig_update_led_matrix_default();
235 led_matrix_eeconfig.raw = eeconfig_read_led_matrix();
236 } 324 }
237
238 eeconfig_debug_led_matrix(); // display current eeprom values 325 eeconfig_debug_led_matrix(); // display current eeprom values
239} 326}
240 327
241// Deals with the messy details of incrementing an integer 328void led_matrix_set_suspend_state(bool state) {
242static uint8_t increment(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { 329 if (LED_DISABLE_WHEN_USB_SUSPENDED && state) {
243 int16_t new_value = value; 330 led_matrix_set_value_all(0); // turn off all LEDs when suspending
244 new_value += step; 331 }
245 return MIN(MAX(new_value, min), max); 332 g_suspend_state = state;
246} 333}
247 334
248static uint8_t decrement(uint8_t value, uint8_t step, uint8_t min, uint8_t max) { 335bool led_matrix_get_suspend_state(void) { return g_suspend_state; }
249 int16_t new_value = value;
250 new_value -= step;
251 return MIN(MAX(new_value, min), max);
252}
253 336
254// void *backlight_get_custom_key_value_eeprom_address(uint8_t led) { 337void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) {
255// // 3 bytes per value
256// return EECONFIG_LED_MATRIX + (led * 3);
257// }
258
259// void backlight_get_key_value(uint8_t led, uint8_t *value) {
260// void *address = backlight_get_custom_key_value_eeprom_address(led);
261// value = eeprom_read_byte(address);
262// }
263
264// void backlight_set_key_value(uint8_t row, uint8_t column, uint8_t value) {
265// uint8_t led[8];
266// uint8_t led_count = map_row_column_to_led(row, column, led);
267// for(uint8_t i = 0; i < led_count; i++) {
268// if (led[i] < DRIVER_LED_TOTAL) {
269// void *address = backlight_get_custom_key_value_eeprom_address(led[i]);
270// eeprom_update_byte(address, value);
271// }
272// }
273// }
274
275uint32_t led_matrix_get_tick(void) { return g_tick; }
276
277void led_matrix_toggle(void) {
278 led_matrix_eeconfig.enable ^= 1; 338 led_matrix_eeconfig.enable ^= 1;
279 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 339 led_task_state = STARTING;
340 if (write_to_eeprom) {
341 eeconfig_update_led_matrix();
342 }
343 dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable);
280} 344}
345void led_matrix_toggle_noeeprom(void) { led_matrix_toggle_eeprom_helper(false); }
346void led_matrix_toggle(void) { led_matrix_toggle_eeprom_helper(true); }
281 347
282void led_matrix_enable(void) { 348void led_matrix_enable(void) {
283 led_matrix_eeconfig.enable = 1; 349 led_matrix_enable_noeeprom();
284 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 350 eeconfig_update_led_matrix();
285} 351}
286 352
287void led_matrix_enable_noeeprom(void) { led_matrix_eeconfig.enable = 1; } 353void led_matrix_enable_noeeprom(void) {
354 if (!led_matrix_eeconfig.enable) led_task_state = STARTING;
355 led_matrix_eeconfig.enable = 1;
356}
288 357
289void led_matrix_disable(void) { 358void led_matrix_disable(void) {
359 led_matrix_disable_noeeprom();
360 eeconfig_update_led_matrix();
361}
362
363void led_matrix_disable_noeeprom(void) {
364 if (led_matrix_eeconfig.enable) led_task_state = STARTING;
290 led_matrix_eeconfig.enable = 0; 365 led_matrix_eeconfig.enable = 0;
291 eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
292} 366}
293 367
294void led_matrix_disable_noeeprom(void) { led_matrix_eeconfig.enable = 0; } 368uint8_t led_matrix_is_enabled(void) { return led_matrix_eeconfig.enable; }
295 369
296void led_matrix_step(void) { 370void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
297 led_matrix_eeconfig.mode++; 371 if (!led_matrix_eeconfig.enable) {
298 if (led_matrix_eeconfig.mode >= LED_MATRIX_EFFECT_MAX) { 372 return;
299 led_matrix_eeconfig.mode = 1;
300 } 373 }
301 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 374 if (mode < 1) {
302} 375 led_matrix_eeconfig.mode = 1;
303 376 } else if (mode >= LED_MATRIX_EFFECT_MAX) {
304void led_matrix_step_reverse(void) {
305 led_matrix_eeconfig.mode--;
306 if (led_matrix_eeconfig.mode < 1) {
307 led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1; 377 led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1;
378 } else {
379 led_matrix_eeconfig.mode = mode;
380 }
381 led_task_state = STARTING;
382 if (write_to_eeprom) {
383 eeconfig_update_led_matrix();
308 } 384 }
309 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 385 dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode);
310} 386}
387void led_matrix_mode_noeeprom(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, false); }
388void led_matrix_mode(uint8_t mode) { led_matrix_mode_eeprom_helper(mode, true); }
311 389
312void led_matrix_increase_val(void) { 390uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; }
313 led_matrix_eeconfig.val = increment(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS);
314 eeconfig_update_led_matrix(led_matrix_eeconfig.raw);
315}
316 391
317void led_matrix_decrease_val(void) { 392void led_matrix_step_helper(bool write_to_eeprom) {
318 led_matrix_eeconfig.val = decrement(led_matrix_eeconfig.val, 8, 0, LED_MATRIX_MAXIMUM_BRIGHTNESS); 393 uint8_t mode = led_matrix_eeconfig.mode + 1;
319 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 394 led_matrix_mode_eeprom_helper((mode < LED_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom);
320} 395}
396void led_matrix_step_noeeprom(void) { led_matrix_step_helper(false); }
397void led_matrix_step(void) { led_matrix_step_helper(true); }
321 398
322void led_matrix_increase_speed(void) { 399void led_matrix_step_reverse_helper(bool write_to_eeprom) {
323 led_matrix_eeconfig.speed = increment(led_matrix_eeconfig.speed, 1, 0, 3); 400 uint8_t mode = led_matrix_eeconfig.mode - 1;
324 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this 401 led_matrix_mode_eeprom_helper((mode < 1) ? LED_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom);
325} 402}
403void led_matrix_step_reverse_noeeprom(void) { led_matrix_step_reverse_helper(false); }
404void led_matrix_step_reverse(void) { led_matrix_step_reverse_helper(true); }
326 405
327void led_matrix_decrease_speed(void) { 406void led_matrix_set_val_eeprom_helper(uint8_t val, bool write_to_eeprom) {
328 led_matrix_eeconfig.speed = decrement(led_matrix_eeconfig.speed, 1, 0, 3); 407 if (!led_matrix_eeconfig.enable) {
329 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); // EECONFIG needs to be increased to support this 408 return;
409 }
410 led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val;
411 if (write_to_eeprom) {
412 eeconfig_update_led_matrix();
413 }
414 dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val);
330} 415}
416void led_matrix_set_val_noeeprom(uint8_t val) { led_matrix_set_val_eeprom_helper(val, false); }
417void led_matrix_set_val(uint8_t val) { led_matrix_set_val_eeprom_helper(val, true); }
418
419uint8_t led_matrix_get_val(void) { return led_matrix_eeconfig.val; }
331 420
332void led_matrix_mode(uint8_t mode, bool eeprom_write) { 421void led_matrix_increase_val_helper(bool write_to_eeprom) { led_matrix_set_val_eeprom_helper(qadd8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); }
333 led_matrix_eeconfig.mode = mode; 422void led_matrix_increase_val_noeeprom(void) { led_matrix_increase_val_helper(false); }
334 if (eeprom_write) { 423void led_matrix_increase_val(void) { led_matrix_increase_val_helper(true); }
335 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 424
425void led_matrix_decrease_val_helper(bool write_to_eeprom) { led_matrix_set_val_eeprom_helper(qsub8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); }
426void led_matrix_decrease_val_noeeprom(void) { led_matrix_decrease_val_helper(false); }
427void led_matrix_decrease_val(void) { led_matrix_decrease_val_helper(true); }
428
429void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) {
430 led_matrix_eeconfig.speed = speed;
431 if (write_to_eeprom) {
432 eeconfig_update_led_matrix();
336 } 433 }
434 dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed);
337} 435}
436void led_matrix_set_speed_noeeprom(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, false); }
437void led_matrix_set_speed(uint8_t speed) { led_matrix_set_speed_eeprom_helper(speed, true); }
338 438
339uint8_t led_matrix_get_mode(void) { return led_matrix_eeconfig.mode; } 439uint8_t led_matrix_get_speed(void) { return led_matrix_eeconfig.speed; }
340 440
341void led_matrix_set_value_noeeprom(uint8_t val) { led_matrix_eeconfig.val = val; } 441void led_matrix_increase_speed_helper(bool write_to_eeprom) { led_matrix_set_speed_eeprom_helper(qadd8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); }
442void led_matrix_increase_speed_noeeprom(void) { led_matrix_increase_speed_helper(false); }
443void led_matrix_increase_speed(void) { led_matrix_increase_speed_helper(true); }
342 444
343void led_matrix_set_value(uint8_t val) { 445void led_matrix_decrease_speed_helper(bool write_to_eeprom) { led_matrix_set_speed_eeprom_helper(qsub8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); }
344 led_matrix_set_value_noeeprom(val); 446void led_matrix_decrease_speed_noeeprom(void) { led_matrix_decrease_speed_helper(false); }
345 eeconfig_update_led_matrix(led_matrix_eeconfig.raw); 447void led_matrix_decrease_speed(void) { led_matrix_decrease_speed_helper(true); }
346} 448
449led_flags_t led_matrix_get_flags(void) { return led_matrix_eeconfig.flags; }
347 450
348void backlight_set(uint8_t val) { led_matrix_set_value(val); } 451void led_matrix_set_flags(led_flags_t flags) { led_matrix_eeconfig.flags = flags; }