aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/dynamic_keymap.c55
-rw-r--r--quantum/quantum.c7
-rw-r--r--quantum/quantum.h8
-rw-r--r--quantum/via.c400
-rw-r--r--quantum/via.h151
5 files changed, 594 insertions, 27 deletions
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index ca056f630..11d28592d 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -20,28 +20,37 @@
20#include "progmem.h" // to read default from flash 20#include "progmem.h" // to read default from flash
21#include "quantum.h" // for send_string() 21#include "quantum.h" // for send_string()
22#include "dynamic_keymap.h" 22#include "dynamic_keymap.h"
23 23#include "via.h" // for default VIA_EEPROM_ADDR_END
24#ifdef DYNAMIC_KEYMAP_ENABLE 24
25 25#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
26# ifndef DYNAMIC_KEYMAP_EEPROM_ADDR 26# define DYNAMIC_KEYMAP_LAYER_COUNT 4
27# error DYNAMIC_KEYMAP_EEPROM_ADDR not defined 27#endif
28# endif 28
29 29#ifndef DYNAMIC_KEYMAP_MACRO_COUNT
30# ifndef DYNAMIC_KEYMAP_LAYER_COUNT 30# define DYNAMIC_KEYMAP_MACRO_COUNT 16
31# error DYNAMIC_KEYMAP_LAYER_COUNT not defined 31#endif
32# endif 32
33 33// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h,
34# ifndef DYNAMIC_KEYMAP_MACRO_COUNT 34// default it start after VIA_EEPROM_CUSTOM_ADDR+VIA_EEPROM_CUSTOM_SIZE
35# error DYNAMIC_KEYMAP_MACRO_COUNT not defined 35#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
36# endif 36# ifdef VIA_EEPROM_CUSTOM_CONFIG_ADDR
37 37# define DYNAMIC_KEYMAP_EEPROM_ADDR (VIA_EEPROM_CUSTOM_CONFIG_ADDR+VIA_EEPROM_CUSTOM_CONFIG_SIZE)
38# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 38# else
39# error DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR not defined 39# error DYNAMIC_KEYMAP_EEPROM_ADDR not defined
40# endif 40# endif
41 41#endif
42# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 42
43# error DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE not defined 43// Dynamic macro starts after dynamic keymaps
44# endif 44#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR
45# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR+(DYNAMIC_KEYMAP_LAYER_COUNT*MATRIX_ROWS*MATRIX_COLS*2))
46#endif
47
48// Dynamic macro uses up all remaining memory
49// Assumes 1K EEPROM on ATMega32U4
50// Override for anything different
51#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE
52# define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (1024-DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR)
53#endif
45 54
46uint8_t dynamic_keymap_get_layer_count(void) { return DYNAMIC_KEYMAP_LAYER_COUNT; } 55uint8_t dynamic_keymap_get_layer_count(void) { return DYNAMIC_KEYMAP_LAYER_COUNT; }
47 56
@@ -208,5 +217,3 @@ void dynamic_keymap_macro_send(uint8_t id) {
208 send_string(data); 217 send_string(data);
209 } 218 }
210} 219}
211
212#endif // DYNAMIC_KEYMAP_ENABLE
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 695da5fdc..bf159644a 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -213,6 +213,9 @@ bool process_record_quantum(keyrecord_t *record) {
213#if defined(RGB_MATRIX_ENABLE) 213#if defined(RGB_MATRIX_ENABLE)
214 process_rgb_matrix(keycode, record) && 214 process_rgb_matrix(keycode, record) &&
215#endif 215#endif
216#if defined(VIA_ENABLE)
217 process_record_via(keycode, record) &&
218#endif
216 process_record_kb(keycode, record) && 219 process_record_kb(keycode, record) &&
217#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) 220#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
218 process_midi(keycode, record) && 221 process_midi(keycode, record) &&
@@ -560,9 +563,7 @@ __attribute__((weak)) void bootmagic_lite(void) {
560 563
561 // We need multiple scans because debouncing can't be turned off. 564 // We need multiple scans because debouncing can't be turned off.
562 matrix_scan(); 565 matrix_scan();
563#if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0 566#if defined(DEBOUNCE) && DEBOUNCE > 0
564 wait_ms(DEBOUNCING_DELAY * 2);
565#elif defined(DEBOUNCE) && DEBOUNCE > 0
566 wait_ms(DEBOUNCE * 2); 567 wait_ms(DEBOUNCE * 2);
567#else 568#else
568 wait_ms(30); 569 wait_ms(30);
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 053b33b91..9758374f6 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -162,6 +162,14 @@ extern layer_state_t layer_state;
162# include "process_dynamic_macro.h" 162# include "process_dynamic_macro.h"
163#endif 163#endif
164 164
165#ifdef DYNAMIC_KEYMAP_ENABLE
166# include "dynamic_keymap.h"
167#endif
168
169#ifdef VIA_ENABLE
170# include "via.h"
171#endif
172
165// Function substitutions to ease GPIO manipulation 173// Function substitutions to ease GPIO manipulation
166#if defined(__AVR__) 174#if defined(__AVR__)
167typedef uint8_t pin_t; 175typedef uint8_t pin_t;
diff --git a/quantum/via.c b/quantum/via.c
new file mode 100644
index 000000000..64b05324a
--- /dev/null
+++ b/quantum/via.c
@@ -0,0 +1,400 @@
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
25#include "quantum.h"
26
27#include "via.h"
28#include "raw_hid.h"
29#include "dynamic_keymap.h"
30#include "tmk_core/common/eeprom.h"
31#include "version.h" // for QMK_BUILDDATE used in EEPROM magic
32
33// Can be called in an overriding via_init_kb() to test if keyboard level code usage of
34// EEPROM is invalid and use/save defaults.
35bool via_eeprom_is_valid(void)
36{
37 char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
38 uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
39 uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
40 uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
41
42 return (eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0 ) == magic0 &&
43 eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1 ) == magic1 &&
44 eeprom_read_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2 ) == magic2 );
45}
46
47// Sets VIA/keyboard level usage of EEPROM to valid/invalid
48// Keyboard level code (eg. via_init_kb()) should not call this
49void via_eeprom_set_valid(bool valid)
50{
51 char *p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54"
52 uint8_t magic0 = ( ( p[2] & 0x0F ) << 4 ) | ( p[3] & 0x0F );
53 uint8_t magic1 = ( ( p[5] & 0x0F ) << 4 ) | ( p[6] & 0x0F );
54 uint8_t magic2 = ( ( p[8] & 0x0F ) << 4 ) | ( p[9] & 0x0F );
55
56 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+0, valid ? magic0 : 0xFF);
57 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+1, valid ? magic1 : 0xFF);
58 eeprom_update_byte( (void*)VIA_EEPROM_MAGIC_ADDR+2, valid ? magic2 : 0xFF);
59}
60
61// Flag QMK and VIA/keyboard level EEPROM as invalid.
62// Used in bootmagic_lite() and VIA command handler.
63// Keyboard level code should not need to call this.
64void via_eeprom_reset(void)
65{
66 // Set the VIA specific EEPROM state as invalid.
67 via_eeprom_set_valid(false);
68 // Set the TMK/QMK EEPROM state as invalid.
69 eeconfig_disable();
70}
71
72// Override bootmagic_lite() so it can flag EEPROM as invalid
73// as well as jump to bootloader, thus performing a "factory reset"
74// of dynamic keymaps and optionally backlight/other settings.
75void bootmagic_lite(void)
76{
77 // The lite version of TMK's bootmagic based on Wilba.
78 // 100% less potential for accidentally making the
79 // keyboard do stupid things.
80
81 // We need multiple scans because debouncing can't be turned off.
82 matrix_scan();
83#if defined(DEBOUNCE) && DEBOUNCE > 0
84 wait_ms(DEBOUNCE * 2);
85#else
86 wait_ms(30);
87#endif
88 matrix_scan();
89
90 // If the Esc and space bar are held down on power up,
91 // reset the EEPROM valid state and jump to bootloader.
92 // Assumes Esc is at [0,0].
93 // This isn't very generalized, but we need something that doesn't
94 // rely on user's keymaps in firmware or EEPROM.
95 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
96 // This is the only difference from the default implementation.
97 via_eeprom_reset();
98 // Jump to bootloader.
99 bootloader_jump();
100 }
101}
102
103// Override this at the keyboard code level to check
104// VIA's EEPROM valid state and reset to defaults as needed.
105// Used by keyboards that store their own state in EEPROM,
106// for backlight, rotary encoders, etc.
107// The override should not set via_eeprom_set_valid(true) as
108// the caller also needs to check the valid state.
109__attribute__((weak)) void via_init_kb(void) {
110}
111
112// Called by QMK core to initialize dynamic keymaps etc.
113void via_init(void)
114{
115 // Let keyboard level test EEPROM valid state,
116 // but not set it valid, it is done here.
117 via_init_kb();
118
119 // If the EEPROM has the magic, the data is good.
120 // OK to load from EEPROM.
121 if (via_eeprom_is_valid()) {
122 } else {
123 // This resets the layout options
124 via_set_layout_options(0);
125 // This resets the keymaps in EEPROM to what is in flash.
126 dynamic_keymap_reset();
127 // This resets the macros in EEPROM to nothing.
128 dynamic_keymap_macro_reset();
129 // Save the magic number last, in case saving was interrupted
130 via_eeprom_set_valid(true);
131 }
132}
133
134// This is generalized so the layout options EEPROM usage can be
135// variable, between 1 and 4 bytes.
136uint32_t via_get_layout_options(void)
137{
138 uint32_t value = 0;
139 // Start at the most significant byte
140 void * source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR);
141 for ( uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++ ) {
142 value = value << 8;
143 value |= eeprom_read_byte(source);
144 source++;
145 }
146 return value;
147}
148
149void via_set_layout_options(uint32_t value)
150{
151 // Start at the least significant byte
152 void * target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR+VIA_EEPROM_LAYOUT_OPTIONS_SIZE-1);
153 for ( uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++ ) {
154 eeprom_update_byte(target, value & 0xFF );
155 value = value >> 8;
156 target--;
157 }
158}
159
160// Called by QMK core to process VIA-specific keycodes.
161bool process_record_via(uint16_t keycode, keyrecord_t *record)
162{
163 // Handle macros
164 if (record->event.pressed) {
165 if ( keycode >= MACRO00 && keycode <= MACRO15 )
166 {
167 uint8_t id = keycode - MACRO00;
168 dynamic_keymap_macro_send(id);
169 return false;
170 }
171 }
172
173 // TODO: ideally this would be generalized and refactored into
174 // QMK core as advanced keycodes, until then, the simple case
175 // can be available here to keyboards using VIA
176 switch(keycode) {
177 case FN_MO13:
178 if (record->event.pressed) {
179 layer_on(1);
180 update_tri_layer(1, 2, 3);
181 } else {
182 layer_off(1);
183 update_tri_layer(1, 2, 3);
184 }
185 return false;
186 break;
187 case FN_MO23:
188 if (record->event.pressed) {
189 layer_on(2);
190 update_tri_layer(1, 2, 3);
191 } else {
192 layer_off(2);
193 update_tri_layer(1, 2, 3);
194 }
195 return false;
196 break;
197 }
198 return true;
199}
200
201// Keyboard level code can override this to handle custom messages from VIA.
202// See raw_hid_receive() implementation.
203// DO NOT call raw_hid_send() in the overide function.
204__attribute__((weak)) void raw_hid_receive_kb(uint8_t *data, uint8_t length) {
205 uint8_t *command_id = &(data[0]);
206 *command_id = id_unhandled;
207}
208
209// VIA handles received HID messages first, and will route to
210// raw_hid_receive_kb() for command IDs that are not handled here.
211// This gives the keyboard code level the ability to handle the command
212// specifically.
213//
214// raw_hid_send() is called at the end, with the same buffer, which was
215// possibly modified with returned values.
216void raw_hid_receive( uint8_t *data, uint8_t length )
217{
218 uint8_t *command_id = &(data[0]);
219 uint8_t *command_data = &(data[1]);
220 switch ( *command_id )
221 {
222 case id_get_protocol_version:
223 {
224 command_data[0] = VIA_PROTOCOL_VERSION >> 8;
225 command_data[1] = VIA_PROTOCOL_VERSION & 0xFF;
226 break;
227 }
228 case id_get_keyboard_value:
229 {
230 switch ( command_data[0] )
231 {
232 case id_uptime:
233 {
234 uint32_t value = timer_read32();
235 command_data[1] = (value >> 24 ) & 0xFF;
236 command_data[2] = (value >> 16 ) & 0xFF;
237 command_data[3] = (value >> 8 ) & 0xFF;
238 command_data[4] = value & 0xFF;
239 break;
240 }
241 case id_layout_options:
242 {
243 uint32_t value = via_get_layout_options();
244 command_data[1] = (value >> 24 ) & 0xFF;
245 command_data[2] = (value >> 16 ) & 0xFF;
246 command_data[3] = (value >> 8 ) & 0xFF;
247 command_data[4] = value & 0xFF;
248 break;
249 }
250 case id_switch_matrix_state:
251 {
252#if ( (MATRIX_COLS/8+1)*MATRIX_ROWS <= 28 )
253 uint8_t i = 1;
254 for ( uint8_t row=0; row<MATRIX_ROWS; row++ ) {
255 matrix_row_t value = matrix_get_row(row);
256#if (MATRIX_COLS > 24)
257 command_data[i++] = (value >> 24 ) & 0xFF;
258#endif
259#if (MATRIX_COLS > 16)
260 command_data[i++] = (value >> 16 ) & 0xFF;
261#endif
262#if (MATRIX_COLS > 8)
263 command_data[i++] = (value >> 8 ) & 0xFF;
264#endif
265 command_data[i++] = value & 0xFF;
266 }
267#endif
268 break;
269 }
270 default:
271 {
272 raw_hid_receive_kb(data,length);
273 break;
274 }
275 }
276 break;
277 }
278 case id_set_keyboard_value:
279 {
280 switch ( command_data[0] )
281 {
282 case id_layout_options:
283 {
284 uint32_t value = ( (uint32_t)command_data[1] << 24 ) |
285 ( (uint32_t)command_data[2] << 16 ) |
286 ( (uint32_t)command_data[3] << 8 ) |
287 (uint32_t)command_data[4];
288 via_set_layout_options(value);
289 break;
290 }
291 default:
292 {
293 raw_hid_receive_kb(data,length);
294 break;
295 }
296 }
297 break;
298 }
299 case id_dynamic_keymap_get_keycode:
300 {
301 uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
302 command_data[3] = keycode >> 8;
303 command_data[4] = keycode & 0xFF;
304 break;
305 }
306 case id_dynamic_keymap_set_keycode:
307 {
308 dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
309 break;
310 }
311 case id_dynamic_keymap_reset:
312 {
313 dynamic_keymap_reset();
314 break;
315 }
316 case id_backlight_config_set_value:
317 case id_backlight_config_get_value:
318 case id_backlight_config_save:
319 {
320 raw_hid_receive_kb(data, length);
321 break;
322 }
323 case id_dynamic_keymap_macro_get_count:
324 {
325 command_data[0] = dynamic_keymap_macro_get_count();
326 break;
327 }
328 case id_dynamic_keymap_macro_get_buffer_size:
329 {
330 uint16_t size = dynamic_keymap_macro_get_buffer_size();
331 command_data[0] = size >> 8;
332 command_data[1] = size & 0xFF;
333 break;
334 }
335 case id_dynamic_keymap_macro_get_buffer:
336 {
337 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
338 uint16_t size = command_data[2]; // size <= 28
339 dynamic_keymap_macro_get_buffer( offset, size, &command_data[3] );
340 break;
341 }
342 case id_dynamic_keymap_macro_set_buffer:
343 {
344 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
345 uint16_t size = command_data[2]; // size <= 28
346 dynamic_keymap_macro_set_buffer( offset, size, &command_data[3] );
347 break;
348 }
349 case id_dynamic_keymap_macro_reset:
350 {
351 dynamic_keymap_macro_reset();
352 break;
353 }
354 case id_dynamic_keymap_get_layer_count:
355 {
356 command_data[0] = dynamic_keymap_get_layer_count();
357 break;
358 }
359 case id_dynamic_keymap_get_buffer:
360 {
361 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
362 uint16_t size = command_data[2]; // size <= 28
363 dynamic_keymap_get_buffer( offset, size, &command_data[3] );
364 break;
365 }
366 case id_dynamic_keymap_set_buffer:
367 {
368 uint16_t offset = ( command_data[0] << 8 ) | command_data[1];
369 uint16_t size = command_data[2]; // size <= 28
370 dynamic_keymap_set_buffer( offset, size, &command_data[3] );
371 break;
372 }
373 case id_eeprom_reset:
374 {
375 via_eeprom_reset();
376 break;
377 }
378 case id_bootloader_jump:
379 {
380 // Need to send data back before the jump
381 // Informs host that the command is handled
382 raw_hid_send( data, length );
383 // Give host time to read it
384 wait_ms(100);
385 bootloader_jump();
386 break;
387 }
388 default:
389 {
390 // The command ID is not known
391 // Return the unhandled state
392 *command_id = id_unhandled;
393 break;
394 }
395 }
396
397 // Return the same buffer, optionally with values changed
398 // (i.e. returning state to the host, or the unhandled state).
399 raw_hid_send( data, length );
400}
diff --git a/quantum/via.h b/quantum/via.h
new file mode 100644
index 000000000..f9a8017b2
--- /dev/null
+++ b/quantum/via.h
@@ -0,0 +1,151 @@
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#pragma once
18
19#include <tmk_core/common/eeconfig.h> // for EECONFIG_SIZE
20
21// Keyboard level code can change where VIA stores the magic.
22// The magic is the build date YYMMDD encoded as BCD in 3 bytes,
23// thus installing firmware built on a different date to the one
24// already installed can be detected and the EEPROM data is reset.
25// The only reason this is important is in case EEPROM usage changes
26// and the EEPROM was not explicitly reset by bootmagic lite.
27#ifndef VIA_EEPROM_MAGIC_ADDR
28# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE)
29#endif
30
31#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR+3)
32
33// Changing the layout options size after release will invalidate EEPROM,
34// but this is something that should be set correctly on initial implementation.
35// 1 byte is enough for most uses (i.e. 8 binary states, or 6 binary + 1 ternary/quaternary )
36#ifndef VIA_EEPROM_LAYOUT_OPTIONS_SIZE
37# define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 1
38#endif
39
40// The end of the EEPROM memory used by VIA
41// By default, dynamic keymaps will start at this if there is no
42// custom config
43#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR+VIA_EEPROM_LAYOUT_OPTIONS_SIZE)
44
45#ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE
46# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0
47#endif
48
49// This is changed only when the command IDs change,
50// so VIA Configurator can detect compatible firmware.
51#define VIA_PROTOCOL_VERSION 0x0009
52
53enum via_command_id
54{
55 id_get_protocol_version = 0x01, // always 0x01
56 id_get_keyboard_value,
57 id_set_keyboard_value,
58 id_dynamic_keymap_get_keycode,
59 id_dynamic_keymap_set_keycode,
60 id_dynamic_keymap_reset,
61 id_backlight_config_set_value,
62 id_backlight_config_get_value,
63 id_backlight_config_save,
64 id_eeprom_reset,
65 id_bootloader_jump,
66 id_dynamic_keymap_macro_get_count,
67 id_dynamic_keymap_macro_get_buffer_size,
68 id_dynamic_keymap_macro_get_buffer,
69 id_dynamic_keymap_macro_set_buffer,
70 id_dynamic_keymap_macro_reset,
71 id_dynamic_keymap_get_layer_count,
72 id_dynamic_keymap_get_buffer,
73 id_dynamic_keymap_set_buffer,
74 id_unhandled = 0xFF,
75};
76
77enum via_keyboard_value_id
78{
79 id_uptime = 0x01,
80 id_layout_options,
81 id_switch_matrix_state
82};
83
84// Can't use SAFE_RANGE here, it might change if someone adds
85// new values to enum quantum_keycodes.
86// Need to keep checking 0x5F10 is still in the safe range.
87// TODO: merge this into quantum_keycodes
88// Backlight keycodes are in range 0x5F00-0x5F0F
89enum via_keycodes {
90 FN_MO13 = 0x5F10,
91 FN_MO23,
92 MACRO00,
93 MACRO01,
94 MACRO02,
95 MACRO03,
96 MACRO04,
97 MACRO05,
98 MACRO06,
99 MACRO07,
100 MACRO08,
101 MACRO09,
102 MACRO10,
103 MACRO11,
104 MACRO12,
105 MACRO13,
106 MACRO14,
107 MACRO15,
108};
109
110enum user_keycodes {
111 USER00 = 0x5F80,
112 USER01,
113 USER02,
114 USER03,
115 USER04,
116 USER05,
117 USER06,
118 USER07,
119 USER08,
120 USER09,
121 USER10,
122 USER11,
123 USER12,
124 USER13,
125 USER14,
126 USER15,
127};
128
129// Can be called in an overriding via_init_kb() to test if keyboard level code usage of
130// EEPROM is invalid and use/save defaults.
131bool via_eeprom_is_valid(void);
132
133// Sets VIA/keyboard level usage of EEPROM to valid/invalid
134// Keyboard level code (eg. via_init_kb()) should not call this
135void via_eeprom_set_valid(bool valid);
136
137// Flag QMK and VIA/keyboard level EEPROM as invalid.
138// Used in bootmagic_lite() and VIA command handler.
139// Keyboard level code should not need to call this.
140void via_eeprom_reset(void);
141
142// Called by QMK core to initialize dynamic keymaps etc.
143void via_init(void);
144
145// Used by VIA to store and retrieve the layout options.
146uint32_t via_get_layout_options(void);
147void via_set_layout_options(uint32_t value);
148
149// Called by QMK core to process VIA-specific keycodes.
150bool process_record_via(uint16_t keycode, keyrecord_t *record);
151