Commit | Line | Data |
---|---|---|
320822d7 W |
1 | /* Copyright 2019 Jason Williams (Wilba) |
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 | ||
17 | #ifndef RAW_ENABLE | |
18 | # error "RAW_ENABLE is not enabled" | |
19 | #endif | |
20 | ||
21 | #ifndef DYNAMIC_KEYMAP_ENABLE | |
22 | # error "DYNAMIC_KEYMAP_ENABLE is not enabled" | |
23 | #endif | |
24 | ||
484a9b12 W |
25 | // If VIA_CUSTOM_LIGHTING_ENABLE is not defined, then VIA_QMK_BACKLIGHT_ENABLE is set |
26 | // if BACKLIGHT_ENABLE is set, so handling of QMK Backlight values happens here by default. | |
27 | // if VIA_CUSTOM_LIGHTING_ENABLE is defined, then VIA_QMK_BACKLIGHT_ENABLE must be explicitly | |
28 | // set in keyboard-level config.h, so handling of QMK Backlight values happens here | |
29 | #if defined(BACKLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
30 | # define VIA_QMK_BACKLIGHT_ENABLE | |
31 | #endif | |
32 | ||
33 | // If VIA_CUSTOM_LIGHTING_ENABLE is not defined, then VIA_QMK_RGBLIGHT_ENABLE is set | |
34 | // if RGBLIGHT_ENABLE is set, so handling of QMK RGBLIGHT values happens here by default. | |
35 | // If VIA_CUSTOM_LIGHTING_ENABLE is defined, then VIA_QMK_RGBLIGHT_ENABLE must be explicitly | |
36 | // set in keyboard-level config.h, so handling of QMK RGBLIGHT values happens here | |
37 | #if defined(RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
38 | # define VIA_QMK_RGBLIGHT_ENABLE | |
39 | #endif | |
40 | ||
320822d7 W |
41 | #include "quantum.h" |
42 | ||
43 | #include "via.h" | |
484a9b12 | 44 | |
320822d7 W |
45 | #include "raw_hid.h" |
46 | #include "dynamic_keymap.h" | |
47 | #include "tmk_core/common/eeprom.h" | |
667045b4 | 48 | #include "version.h" // for QMK_BUILDDATE used in EEPROM magic |
320822d7 | 49 | |
484a9b12 W |
50 | // Forward declare some helpers. |
51 | #if defined(VIA_QMK_BACKLIGHT_ENABLE) | |
52 | void via_qmk_backlight_set_value(uint8_t *data); | |
53 | void via_qmk_backlight_get_value(uint8_t *data); | |
54 | #endif | |
55 | ||
56 | #if defined(VIA_QMK_RGBLIGHT_ENABLE) | |
57 | void via_qmk_rgblight_set_value(uint8_t *data); | |
58 | void via_qmk_rgblight_get_value(uint8_t *data); | |
59 | #endif | |
60 | ||
320822d7 W |
61 | // Can be called in an overriding via_init_kb() to test if keyboard level code usage of |
62 | // EEPROM is invalid and use/save defaults. | |
667045b4 JC |
63 | bool via_eeprom_is_valid(void) { |
64 | char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" | |
65 | uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); | |
66 | uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); | |
67 | uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); | |
320822d7 | 68 | |
667045b4 | 69 | return (eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0) == magic0 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1) == magic1 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2) == magic2); |
320822d7 W |
70 | } |
71 | ||
72 | // Sets VIA/keyboard level usage of EEPROM to valid/invalid | |
73 | // Keyboard level code (eg. via_init_kb()) should not call this | |
667045b4 JC |
74 | void via_eeprom_set_valid(bool valid) { |
75 | char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" | |
76 | uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); | |
77 | uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); | |
78 | uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); | |
320822d7 | 79 | |
667045b4 JC |
80 | eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, valid ? magic0 : 0xFF); |
81 | eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, valid ? magic1 : 0xFF); | |
82 | eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, valid ? magic2 : 0xFF); | |
320822d7 W |
83 | } |
84 | ||
85 | // Flag QMK and VIA/keyboard level EEPROM as invalid. | |
86 | // Used in bootmagic_lite() and VIA command handler. | |
87 | // Keyboard level code should not need to call this. | |
667045b4 | 88 | void via_eeprom_reset(void) { |
320822d7 W |
89 | // Set the VIA specific EEPROM state as invalid. |
90 | via_eeprom_set_valid(false); | |
91 | // Set the TMK/QMK EEPROM state as invalid. | |
92 | eeconfig_disable(); | |
93 | } | |
94 | ||
95 | // Override bootmagic_lite() so it can flag EEPROM as invalid | |
96 | // as well as jump to bootloader, thus performing a "factory reset" | |
97 | // of dynamic keymaps and optionally backlight/other settings. | |
667045b4 | 98 | void bootmagic_lite(void) { |
320822d7 W |
99 | // The lite version of TMK's bootmagic based on Wilba. |
100 | // 100% less potential for accidentally making the | |
101 | // keyboard do stupid things. | |
102 | ||
103 | // We need multiple scans because debouncing can't be turned off. | |
104 | matrix_scan(); | |
105 | #if defined(DEBOUNCE) && DEBOUNCE > 0 | |
106 | wait_ms(DEBOUNCE * 2); | |
107 | #else | |
108 | wait_ms(30); | |
109 | #endif | |
110 | matrix_scan(); | |
111 | ||
112 | // If the Esc and space bar are held down on power up, | |
113 | // reset the EEPROM valid state and jump to bootloader. | |
114 | // Assumes Esc is at [0,0]. | |
115 | // This isn't very generalized, but we need something that doesn't | |
116 | // rely on user's keymaps in firmware or EEPROM. | |
117 | if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { | |
118 | // This is the only difference from the default implementation. | |
119 | via_eeprom_reset(); | |
120 | // Jump to bootloader. | |
121 | bootloader_jump(); | |
122 | } | |
123 | } | |
124 | ||
125 | // Override this at the keyboard code level to check | |
126 | // VIA's EEPROM valid state and reset to defaults as needed. | |
127 | // Used by keyboards that store their own state in EEPROM, | |
128 | // for backlight, rotary encoders, etc. | |
129 | // The override should not set via_eeprom_set_valid(true) as | |
130 | // the caller also needs to check the valid state. | |
667045b4 | 131 | __attribute__((weak)) void via_init_kb(void) {} |
320822d7 W |
132 | |
133 | // Called by QMK core to initialize dynamic keymaps etc. | |
667045b4 | 134 | void via_init(void) { |
320822d7 W |
135 | // Let keyboard level test EEPROM valid state, |
136 | // but not set it valid, it is done here. | |
137 | via_init_kb(); | |
138 | ||
139 | // If the EEPROM has the magic, the data is good. | |
140 | // OK to load from EEPROM. | |
141 | if (via_eeprom_is_valid()) { | |
667045b4 | 142 | } else { |
320822d7 W |
143 | // This resets the layout options |
144 | via_set_layout_options(0); | |
145 | // This resets the keymaps in EEPROM to what is in flash. | |
146 | dynamic_keymap_reset(); | |
147 | // This resets the macros in EEPROM to nothing. | |
148 | dynamic_keymap_macro_reset(); | |
149 | // Save the magic number last, in case saving was interrupted | |
150 | via_eeprom_set_valid(true); | |
151 | } | |
152 | } | |
153 | ||
154 | // This is generalized so the layout options EEPROM usage can be | |
155 | // variable, between 1 and 4 bytes. | |
667045b4 | 156 | uint32_t via_get_layout_options(void) { |
320822d7 W |
157 | uint32_t value = 0; |
158 | // Start at the most significant byte | |
667045b4 JC |
159 | void *source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR); |
160 | for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) { | |
320822d7 W |
161 | value = value << 8; |
162 | value |= eeprom_read_byte(source); | |
163 | source++; | |
164 | } | |
165 | return value; | |
166 | } | |
167 | ||
667045b4 | 168 | void via_set_layout_options(uint32_t value) { |
320822d7 | 169 | // Start at the least significant byte |
667045b4 JC |
170 | void *target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE - 1); |
171 | for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) { | |
172 | eeprom_update_byte(target, value & 0xFF); | |
320822d7 W |
173 | value = value >> 8; |
174 | target--; | |
175 | } | |
176 | } | |
177 | ||
178 | // Called by QMK core to process VIA-specific keycodes. | |
667045b4 | 179 | bool process_record_via(uint16_t keycode, keyrecord_t *record) { |
320822d7 W |
180 | // Handle macros |
181 | if (record->event.pressed) { | |
667045b4 | 182 | if (keycode >= MACRO00 && keycode <= MACRO15) { |
320822d7 W |
183 | uint8_t id = keycode - MACRO00; |
184 | dynamic_keymap_macro_send(id); | |
185 | return false; | |
186 | } | |
187 | } | |
188 | ||
189 | // TODO: ideally this would be generalized and refactored into | |
190 | // QMK core as advanced keycodes, until then, the simple case | |
191 | // can be available here to keyboards using VIA | |
667045b4 | 192 | switch (keycode) { |
320822d7 W |
193 | case FN_MO13: |
194 | if (record->event.pressed) { | |
195 | layer_on(1); | |
196 | update_tri_layer(1, 2, 3); | |
197 | } else { | |
198 | layer_off(1); | |
199 | update_tri_layer(1, 2, 3); | |
200 | } | |
201 | return false; | |
202 | break; | |
203 | case FN_MO23: | |
204 | if (record->event.pressed) { | |
205 | layer_on(2); | |
206 | update_tri_layer(1, 2, 3); | |
207 | } else { | |
208 | layer_off(2); | |
209 | update_tri_layer(1, 2, 3); | |
210 | } | |
211 | return false; | |
212 | break; | |
213 | } | |
214 | return true; | |
215 | } | |
216 | ||
217 | // Keyboard level code can override this to handle custom messages from VIA. | |
218 | // See raw_hid_receive() implementation. | |
219 | // DO NOT call raw_hid_send() in the overide function. | |
220 | __attribute__((weak)) void raw_hid_receive_kb(uint8_t *data, uint8_t length) { | |
221 | uint8_t *command_id = &(data[0]); | |
667045b4 | 222 | *command_id = id_unhandled; |
320822d7 W |
223 | } |
224 | ||
225 | // VIA handles received HID messages first, and will route to | |
226 | // raw_hid_receive_kb() for command IDs that are not handled here. | |
227 | // This gives the keyboard code level the ability to handle the command | |
228 | // specifically. | |
229 | // | |
667045b4 | 230 | // raw_hid_send() is called at the end, with the same buffer, which was |
320822d7 | 231 | // possibly modified with returned values. |
667045b4 JC |
232 | void raw_hid_receive(uint8_t *data, uint8_t length) { |
233 | uint8_t *command_id = &(data[0]); | |
320822d7 | 234 | uint8_t *command_data = &(data[1]); |
667045b4 JC |
235 | switch (*command_id) { |
236 | case id_get_protocol_version: { | |
320822d7 W |
237 | command_data[0] = VIA_PROTOCOL_VERSION >> 8; |
238 | command_data[1] = VIA_PROTOCOL_VERSION & 0xFF; | |
239 | break; | |
240 | } | |
667045b4 JC |
241 | case id_get_keyboard_value: { |
242 | switch (command_data[0]) { | |
243 | case id_uptime: { | |
244 | uint32_t value = timer_read32(); | |
245 | command_data[1] = (value >> 24) & 0xFF; | |
246 | command_data[2] = (value >> 16) & 0xFF; | |
247 | command_data[3] = (value >> 8) & 0xFF; | |
320822d7 W |
248 | command_data[4] = value & 0xFF; |
249 | break; | |
250 | } | |
667045b4 JC |
251 | case id_layout_options: { |
252 | uint32_t value = via_get_layout_options(); | |
253 | command_data[1] = (value >> 24) & 0xFF; | |
254 | command_data[2] = (value >> 16) & 0xFF; | |
255 | command_data[3] = (value >> 8) & 0xFF; | |
320822d7 W |
256 | command_data[4] = value & 0xFF; |
257 | break; | |
258 | } | |
667045b4 JC |
259 | case id_switch_matrix_state: { |
260 | #if ((MATRIX_COLS / 8 + 1) * MATRIX_ROWS <= 28) | |
320822d7 | 261 | uint8_t i = 1; |
667045b4 | 262 | for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
320822d7 | 263 | matrix_row_t value = matrix_get_row(row); |
667045b4 JC |
264 | # if (MATRIX_COLS > 24) |
265 | command_data[i++] = (value >> 24) & 0xFF; | |
266 | # endif | |
267 | # if (MATRIX_COLS > 16) | |
268 | command_data[i++] = (value >> 16) & 0xFF; | |
269 | # endif | |
270 | # if (MATRIX_COLS > 8) | |
271 | command_data[i++] = (value >> 8) & 0xFF; | |
272 | # endif | |
320822d7 W |
273 | command_data[i++] = value & 0xFF; |
274 | } | |
275 | #endif | |
276 | break; | |
277 | } | |
667045b4 JC |
278 | default: { |
279 | raw_hid_receive_kb(data, length); | |
320822d7 W |
280 | break; |
281 | } | |
282 | } | |
283 | break; | |
284 | } | |
667045b4 JC |
285 | case id_set_keyboard_value: { |
286 | switch (command_data[0]) { | |
287 | case id_layout_options: { | |
288 | uint32_t value = ((uint32_t)command_data[1] << 24) | ((uint32_t)command_data[2] << 16) | ((uint32_t)command_data[3] << 8) | (uint32_t)command_data[4]; | |
320822d7 W |
289 | via_set_layout_options(value); |
290 | break; | |
291 | } | |
667045b4 JC |
292 | default: { |
293 | raw_hid_receive_kb(data, length); | |
320822d7 W |
294 | break; |
295 | } | |
296 | } | |
297 | break; | |
298 | } | |
667045b4 JC |
299 | case id_dynamic_keymap_get_keycode: { |
300 | uint16_t keycode = dynamic_keymap_get_keycode(command_data[0], command_data[1], command_data[2]); | |
301 | command_data[3] = keycode >> 8; | |
302 | command_data[4] = keycode & 0xFF; | |
320822d7 W |
303 | break; |
304 | } | |
667045b4 JC |
305 | case id_dynamic_keymap_set_keycode: { |
306 | dynamic_keymap_set_keycode(command_data[0], command_data[1], command_data[2], (command_data[3] << 8) | command_data[4]); | |
320822d7 W |
307 | break; |
308 | } | |
667045b4 | 309 | case id_dynamic_keymap_reset: { |
320822d7 W |
310 | dynamic_keymap_reset(); |
311 | break; | |
312 | } | |
484a9b12 W |
313 | case id_lighting_set_value: { |
314 | #if defined(VIA_QMK_BACKLIGHT_ENABLE) | |
315 | via_qmk_backlight_set_value(command_data); | |
316 | #endif | |
317 | #if defined(VIA_QMK_RGBLIGHT_ENABLE) | |
318 | via_qmk_rgblight_set_value(command_data); | |
319 | #endif | |
320 | #if defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
320822d7 | 321 | raw_hid_receive_kb(data, length); |
484a9b12 W |
322 | #endif |
323 | #if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
324 | // Return the unhandled state | |
325 | *command_id = id_unhandled; | |
326 | #endif | |
327 | break; | |
328 | } | |
329 | case id_lighting_get_value: { | |
330 | #if defined(VIA_QMK_BACKLIGHT_ENABLE) | |
331 | via_qmk_backlight_get_value(command_data); | |
332 | #endif | |
333 | #if defined(VIA_QMK_RGBLIGHT_ENABLE) | |
334 | via_qmk_rgblight_get_value(command_data); | |
335 | #endif | |
336 | #if defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
337 | raw_hid_receive_kb(data, length); | |
338 | #endif | |
339 | #if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
340 | // Return the unhandled state | |
341 | *command_id = id_unhandled; | |
342 | #endif | |
343 | break; | |
344 | } | |
345 | case id_lighting_save: { | |
346 | #if defined(VIA_QMK_BACKLIGHT_ENABLE) | |
347 | eeconfig_update_backlight_current(); | |
348 | #endif | |
349 | #if defined(VIA_QMK_RGBLIGHT_ENABLE) | |
350 | eeconfig_update_rgblight_current(); | |
351 | #endif | |
352 | #if defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
353 | raw_hid_receive_kb(data, length); | |
354 | #endif | |
355 | #if !defined(VIA_QMK_BACKLIGHT_ENABLE) && !defined(VIA_QMK_RGBLIGHT_ENABLE) && !defined(VIA_CUSTOM_LIGHTING_ENABLE) | |
356 | // Return the unhandled state | |
357 | *command_id = id_unhandled; | |
358 | #endif | |
320822d7 W |
359 | break; |
360 | } | |
667045b4 | 361 | case id_dynamic_keymap_macro_get_count: { |
320822d7 W |
362 | command_data[0] = dynamic_keymap_macro_get_count(); |
363 | break; | |
364 | } | |
667045b4 JC |
365 | case id_dynamic_keymap_macro_get_buffer_size: { |
366 | uint16_t size = dynamic_keymap_macro_get_buffer_size(); | |
320822d7 W |
367 | command_data[0] = size >> 8; |
368 | command_data[1] = size & 0xFF; | |
369 | break; | |
370 | } | |
667045b4 JC |
371 | case id_dynamic_keymap_macro_get_buffer: { |
372 | uint16_t offset = (command_data[0] << 8) | command_data[1]; | |
373 | uint16_t size = command_data[2]; // size <= 28 | |
374 | dynamic_keymap_macro_get_buffer(offset, size, &command_data[3]); | |
320822d7 W |
375 | break; |
376 | } | |
667045b4 JC |
377 | case id_dynamic_keymap_macro_set_buffer: { |
378 | uint16_t offset = (command_data[0] << 8) | command_data[1]; | |
379 | uint16_t size = command_data[2]; // size <= 28 | |
380 | dynamic_keymap_macro_set_buffer(offset, size, &command_data[3]); | |
320822d7 W |
381 | break; |
382 | } | |
667045b4 | 383 | case id_dynamic_keymap_macro_reset: { |
320822d7 W |
384 | dynamic_keymap_macro_reset(); |
385 | break; | |
386 | } | |
667045b4 | 387 | case id_dynamic_keymap_get_layer_count: { |
320822d7 W |
388 | command_data[0] = dynamic_keymap_get_layer_count(); |
389 | break; | |
390 | } | |
667045b4 JC |
391 | case id_dynamic_keymap_get_buffer: { |
392 | uint16_t offset = (command_data[0] << 8) | command_data[1]; | |
393 | uint16_t size = command_data[2]; // size <= 28 | |
394 | dynamic_keymap_get_buffer(offset, size, &command_data[3]); | |
320822d7 W |
395 | break; |
396 | } | |
667045b4 JC |
397 | case id_dynamic_keymap_set_buffer: { |
398 | uint16_t offset = (command_data[0] << 8) | command_data[1]; | |
399 | uint16_t size = command_data[2]; // size <= 28 | |
400 | dynamic_keymap_set_buffer(offset, size, &command_data[3]); | |
320822d7 W |
401 | break; |
402 | } | |
667045b4 | 403 | case id_eeprom_reset: { |
320822d7 W |
404 | via_eeprom_reset(); |
405 | break; | |
406 | } | |
667045b4 | 407 | case id_bootloader_jump: { |
320822d7 W |
408 | // Need to send data back before the jump |
409 | // Informs host that the command is handled | |
667045b4 | 410 | raw_hid_send(data, length); |
320822d7 W |
411 | // Give host time to read it |
412 | wait_ms(100); | |
413 | bootloader_jump(); | |
414 | break; | |
415 | } | |
667045b4 | 416 | default: { |
320822d7 W |
417 | // The command ID is not known |
418 | // Return the unhandled state | |
419 | *command_id = id_unhandled; | |
420 | break; | |
421 | } | |
422 | } | |
423 | ||
424 | // Return the same buffer, optionally with values changed | |
425 | // (i.e. returning state to the host, or the unhandled state). | |
667045b4 | 426 | raw_hid_send(data, length); |
320822d7 | 427 | } |
484a9b12 W |
428 | |
429 | #if defined(VIA_QMK_BACKLIGHT_ENABLE) | |
430 | ||
431 | # if BACKLIGHT_LEVELS == 0 | |
432 | # error BACKLIGHT_LEVELS == 0 | |
433 | # endif | |
434 | ||
435 | void via_qmk_backlight_get_value(uint8_t *data) { | |
436 | uint8_t *value_id = &(data[0]); | |
437 | uint8_t *value_data = &(data[1]); | |
438 | switch (*value_id) { | |
439 | case id_qmk_backlight_brightness: { | |
440 | // level / BACKLIGHT_LEVELS * 255 | |
441 | value_data[0] = ((uint16_t)get_backlight_level()) * 255 / BACKLIGHT_LEVELS; | |
442 | break; | |
443 | } | |
444 | case id_qmk_backlight_effect: { | |
445 | # ifdef BACKLIGHT_BREATHING | |
446 | value_data[0] = is_backlight_breathing() ? 1 : 0; | |
447 | # else | |
448 | value_data[0] = 0; | |
449 | # endif | |
450 | break; | |
451 | } | |
452 | } | |
453 | } | |
454 | ||
455 | void via_qmk_backlight_set_value(uint8_t *data) { | |
456 | uint8_t *value_id = &(data[0]); | |
457 | uint8_t *value_data = &(data[1]); | |
458 | switch (*value_id) { | |
459 | case id_qmk_backlight_brightness: { | |
460 | // level / 255 * BACKLIGHT_LEVELS | |
461 | backlight_level_noeeprom(((uint16_t)value_data[0]) * BACKLIGHT_LEVELS / 255); | |
462 | break; | |
463 | } | |
464 | case id_qmk_backlight_effect: { | |
465 | # ifdef BACKLIGHT_BREATHING | |
466 | if (value_data[0] == 0) { | |
467 | backlight_disable_breathing(); | |
468 | } else { | |
469 | backlight_enable_breathing(); | |
470 | } | |
471 | # endif | |
472 | break; | |
473 | } | |
474 | } | |
475 | } | |
476 | ||
477 | #endif // #if defined(VIA_QMK_BACKLIGHT_ENABLE) | |
478 | ||
479 | #if defined(VIA_QMK_RGBLIGHT_ENABLE) | |
480 | ||
481 | void via_qmk_rgblight_get_value(uint8_t *data) { | |
482 | uint8_t *value_id = &(data[0]); | |
483 | uint8_t *value_data = &(data[1]); | |
484 | switch (*value_id) { | |
485 | case id_qmk_rgblight_brightness: { | |
486 | value_data[0] = rgblight_get_val(); | |
487 | break; | |
488 | } | |
489 | case id_qmk_rgblight_effect: { | |
490 | value_data[0] = rgblight_get_mode(); | |
491 | break; | |
492 | } | |
493 | case id_qmk_rgblight_effect_speed: { | |
494 | value_data[0] = rgblight_get_speed(); | |
495 | break; | |
496 | } | |
497 | case id_qmk_rgblight_color: { | |
498 | value_data[0] = rgblight_get_hue(); | |
499 | value_data[1] = rgblight_get_sat(); | |
500 | break; | |
501 | } | |
502 | } | |
503 | } | |
504 | ||
505 | void via_qmk_rgblight_set_value(uint8_t *data) { | |
506 | uint8_t *value_id = &(data[0]); | |
507 | uint8_t *value_data = &(data[1]); | |
508 | switch (*value_id) { | |
509 | case id_qmk_rgblight_brightness: { | |
510 | rgblight_sethsv_noeeprom(rgblight_get_hue(), rgblight_get_sat(), value_data[0]); | |
511 | break; | |
512 | } | |
513 | case id_qmk_rgblight_effect: { | |
514 | rgblight_mode_noeeprom(value_data[0]); | |
515 | if (value_data[0] == 0) { | |
516 | rgblight_disable_noeeprom(); | |
517 | } else { | |
518 | rgblight_enable_noeeprom(); | |
519 | } | |
520 | break; | |
521 | } | |
522 | case id_qmk_rgblight_effect_speed: { | |
523 | rgblight_set_speed_noeeprom(value_data[0]); | |
524 | break; | |
525 | } | |
526 | case id_qmk_rgblight_color: { | |
527 | rgblight_sethsv_noeeprom(value_data[0], value_data[1], rgblight_get_val()); | |
528 | break; | |
529 | } | |
530 | } | |
531 | } | |
532 | ||
533 | #endif // #if defined(VIA_QMK_RGBLIGHT_ENABLE) |