aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c1093
-rw-r--r--tmk_core/common/action.h127
-rw-r--r--tmk_core/common/action_code.h308
-rw-r--r--tmk_core/common/action_layer.c279
-rw-r--r--tmk_core/common/action_layer.h122
-rw-r--r--tmk_core/common/action_macro.c93
-rw-r--r--tmk_core/common/action_macro.h123
-rw-r--r--tmk_core/common/action_tapping.c426
-rw-r--r--tmk_core/common/action_tapping.h41
-rw-r--r--tmk_core/common/action_util.c427
-rw-r--r--tmk_core/common/action_util.h105
-rw-r--r--tmk_core/common/arm_atsam/_timer.h19
-rw-r--r--tmk_core/common/arm_atsam/platform.c21
-rw-r--r--tmk_core/common/avr/_timer.h19
-rw-r--r--tmk_core/common/avr/_wait.h22
-rw-r--r--tmk_core/common/avr/gpio.h15
-rw-r--r--tmk_core/common/avr/platform.c21
-rw-r--r--tmk_core/common/chibios/_timer.h19
-rw-r--r--tmk_core/common/chibios/bootloader.c5
-rw-r--r--tmk_core/common/chibios/gpio.h16
-rw-r--r--tmk_core/common/chibios/platform.c22
-rw-r--r--tmk_core/common/debug.c25
-rw-r--r--tmk_core/common/debug.h169
-rw-r--r--tmk_core/common/eeconfig.c211
-rw-r--r--tmk_core/common/eeconfig.h113
-rw-r--r--tmk_core/common/host.c33
-rw-r--r--tmk_core/common/host_driver.h2
-rw-r--r--tmk_core/common/keyboard.c534
-rw-r--r--tmk_core/common/keyboard.h90
-rw-r--r--tmk_core/common/keycode.h560
-rw-r--r--tmk_core/common/lib_printf.mk9
-rw-r--r--tmk_core/common/nodebug.h26
-rw-r--r--tmk_core/common/print.h135
-rw-r--r--tmk_core/common/printf.c27
-rw-r--r--tmk_core/common/progmem.h2
-rw-r--r--tmk_core/common/report.h14
-rw-r--r--tmk_core/common/sendchar.h33
-rw-r--r--tmk_core/common/sendchar_null.c19
-rw-r--r--tmk_core/common/sendchar_uart.c23
-rw-r--r--tmk_core/common/sync_timer.c2
-rw-r--r--tmk_core/common/sync_timer.h2
-rw-r--r--tmk_core/common/test/platform.c21
-rw-r--r--tmk_core/common/timer.h20
-rw-r--r--tmk_core/common/usb_util.c2
-rw-r--r--tmk_core/common/usb_util.h2
45 files changed, 266 insertions, 5131 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
deleted file mode 100644
index bd41d28b6..000000000
--- a/tmk_core/common/action.c
+++ /dev/null
@@ -1,1093 +0,0 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "host.h"
18#include "keycode.h"
19#include "keyboard.h"
20#include "mousekey.h"
21#include "command.h"
22#include "led.h"
23#include "action_layer.h"
24#include "action_tapping.h"
25#include "action_macro.h"
26#include "action_util.h"
27#include "action.h"
28#include "wait.h"
29
30#ifdef BACKLIGHT_ENABLE
31# include "backlight.h"
32#endif
33
34#ifdef DEBUG_ACTION
35# include "debug.h"
36#else
37# include "nodebug.h"
38#endif
39
40#ifdef POINTING_DEVICE_ENABLE
41# include "pointing_device.h"
42#endif
43
44int tp_buttons;
45
46#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
47int retro_tapping_counter = 0;
48#endif
49
50#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
51__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; }
52#endif
53
54#ifdef RETRO_TAPPING_PER_KEY
55__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { return false; }
56#endif
57
58#ifndef TAP_CODE_DELAY
59# define TAP_CODE_DELAY 0
60#endif
61#ifndef TAP_HOLD_CAPS_DELAY
62# define TAP_HOLD_CAPS_DELAY 80
63#endif
64/** \brief Called to execute an action.
65 *
66 * FIXME: Needs documentation.
67 */
68void action_exec(keyevent_t event) {
69 if (!IS_NOEVENT(event)) {
70 dprint("\n---- action_exec: start -----\n");
71 dprint("EVENT: ");
72 debug_event(event);
73 dprintln();
74#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
75 retro_tapping_counter++;
76#endif
77 }
78
79 if (event.pressed) {
80 // clear the potential weak mods left by previously pressed keys
81 clear_weak_mods();
82 }
83
84#ifdef SWAP_HANDS_ENABLE
85 if (!IS_NOEVENT(event)) {
86 process_hand_swap(&event);
87 }
88#endif
89
90 keyrecord_t record = {.event = event};
91
92#ifndef NO_ACTION_ONESHOT
93# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
94 if (has_oneshot_layer_timed_out()) {
95 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
96 }
97 if (has_oneshot_mods_timed_out()) {
98 clear_oneshot_mods();
99 }
100# ifdef SWAP_HANDS_ENABLE
101 if (has_oneshot_swaphands_timed_out()) {
102 clear_oneshot_swaphands();
103 }
104# endif
105# endif
106#endif
107
108#ifndef NO_ACTION_TAPPING
109 action_tapping_process(record);
110#else
111 process_record(&record);
112 if (!IS_NOEVENT(record.event)) {
113 dprint("processed: ");
114 debug_record(record);
115 dprintln();
116 }
117#endif
118}
119
120#ifdef SWAP_HANDS_ENABLE
121bool swap_hands = false;
122bool swap_held = false;
123
124/** \brief Process Hand Swap
125 *
126 * FIXME: Needs documentation.
127 */
128void process_hand_swap(keyevent_t *event) {
129 static swap_state_row_t swap_state[MATRIX_ROWS];
130
131 keypos_t pos = event->key;
132 swap_state_row_t col_bit = (swap_state_row_t)1 << pos.col;
133 bool do_swap = event->pressed ? swap_hands : swap_state[pos.row] & (col_bit);
134
135 if (do_swap) {
136 event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row);
137 event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col);
138 swap_state[pos.row] |= col_bit;
139 } else {
140 swap_state[pos.row] &= ~(col_bit);
141 }
142}
143#endif
144
145#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
146bool disable_action_cache = false;
147
148void process_record_nocache(keyrecord_t *record) {
149 disable_action_cache = true;
150 process_record(record);
151 disable_action_cache = false;
152}
153#else
154void process_record_nocache(keyrecord_t *record) { process_record(record); }
155#endif
156
157__attribute__((weak)) bool process_record_quantum(keyrecord_t *record) { return true; }
158
159__attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {}
160
161#ifndef NO_ACTION_TAPPING
162/** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress.
163 *
164 * FIXME: Needs documentation.
165 */
166void process_record_tap_hint(keyrecord_t *record) {
167 action_t action = layer_switch_get_action(record->event.key);
168
169 switch (action.kind.id) {
170# ifdef SWAP_HANDS_ENABLE
171 case ACT_SWAP_HANDS:
172 switch (action.swap.code) {
173 case OP_SH_ONESHOT:
174 break;
175 case OP_SH_TAP_TOGGLE:
176 default:
177 swap_hands = !swap_hands;
178 swap_held = true;
179 }
180 break;
181# endif
182 }
183}
184#endif
185
186/** \brief Take a key event (key press or key release) and processes it.
187 *
188 * FIXME: Needs documentation.
189 */
190void process_record(keyrecord_t *record) {
191 if (IS_NOEVENT(record->event)) {
192 return;
193 }
194
195 if (!process_record_quantum(record)) {
196#ifndef NO_ACTION_ONESHOT
197 if (is_oneshot_layer_active() && record->event.pressed) {
198 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
199 }
200#endif
201 return;
202 }
203
204 process_record_handler(record);
205 post_process_record_quantum(record);
206}
207
208void process_record_handler(keyrecord_t *record) {
209 action_t action = store_or_get_action(record->event.pressed, record->event.key);
210 dprint("ACTION: ");
211 debug_action(action);
212#ifndef NO_ACTION_LAYER
213 dprint(" layer_state: ");
214 layer_debug();
215 dprint(" default_layer_state: ");
216 default_layer_debug();
217#endif
218 dprintln();
219
220 process_action(record, action);
221}
222
223#if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
224void register_button(bool pressed, enum mouse_buttons button) {
225# ifdef PS2_MOUSE_ENABLE
226 tp_buttons = pressed ? tp_buttons | button : tp_buttons & ~button;
227# endif
228# ifdef POINTING_DEVICE_ENABLE
229 report_mouse_t currentReport = pointing_device_get_report();
230 currentReport.buttons = pressed ? currentReport.buttons | button : currentReport.buttons & ~button;
231 pointing_device_set_report(currentReport);
232# endif
233}
234#endif
235
236/** \brief Take an action and processes it.
237 *
238 * FIXME: Needs documentation.
239 */
240void process_action(keyrecord_t *record, action_t action) {
241 keyevent_t event = record->event;
242#ifndef NO_ACTION_TAPPING
243 uint8_t tap_count = record->tap.count;
244#endif
245
246#ifndef NO_ACTION_ONESHOT
247 bool do_release_oneshot = false;
248 // notice we only clear the one shot layer if the pressed key is not a modifier.
249 if (is_oneshot_layer_active() && event.pressed && (action.kind.id == ACT_USAGE || !IS_MOD(action.key.code))
250# ifdef SWAP_HANDS_ENABLE
251 && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)
252# endif
253 ) {
254 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
255 do_release_oneshot = !is_oneshot_layer_active();
256 }
257#endif
258
259 switch (action.kind.id) {
260 /* Key and Mods */
261 case ACT_LMODS:
262 case ACT_RMODS: {
263 uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods << 4;
264 if (event.pressed) {
265 if (mods) {
266 if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
267 // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless.
268 // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT).
269 // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO).
270 add_mods(mods);
271 } else {
272 add_weak_mods(mods);
273 }
274 send_keyboard_report();
275 }
276 register_code(action.key.code);
277 } else {
278 unregister_code(action.key.code);
279 if (mods) {
280 if (IS_MOD(action.key.code) || action.key.code == KC_NO) {
281 del_mods(mods);
282 } else {
283 del_weak_mods(mods);
284 }
285 send_keyboard_report();
286 }
287 }
288 } break;
289#ifndef NO_ACTION_TAPPING
290 case ACT_LMODS_TAP:
291 case ACT_RMODS_TAP: {
292 uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4;
293 switch (action.layer_tap.code) {
294# ifndef NO_ACTION_ONESHOT
295 case MODS_ONESHOT:
296 // Oneshot modifier
297 if (event.pressed) {
298 if (tap_count == 0) {
299 dprint("MODS_TAP: Oneshot: 0\n");
300 register_mods(mods | get_oneshot_mods());
301 } else if (tap_count == 1) {
302 dprint("MODS_TAP: Oneshot: start\n");
303 set_oneshot_mods(mods | get_oneshot_mods());
304# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
305 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
306 dprint("MODS_TAP: Toggling oneshot");
307 clear_oneshot_mods();
308 set_oneshot_locked_mods(mods);
309 register_mods(mods);
310# endif
311 } else {
312 register_mods(mods | get_oneshot_mods());
313 }
314 } else {
315 if (tap_count == 0) {
316 clear_oneshot_mods();
317 unregister_mods(mods);
318 } else if (tap_count == 1) {
319 // Retain Oneshot mods
320# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
321 if (mods & get_mods()) {
322 clear_oneshot_locked_mods();
323 clear_oneshot_mods();
324 unregister_mods(mods);
325 }
326 } else if (tap_count == ONESHOT_TAP_TOGGLE) {
327 // Toggle Oneshot Layer
328# endif
329 } else {
330 clear_oneshot_mods();
331 unregister_mods(mods);
332 }
333 }
334 break;
335# endif
336 case MODS_TAP_TOGGLE:
337 if (event.pressed) {
338 if (tap_count <= TAPPING_TOGGLE) {
339 register_mods(mods);
340 }
341 } else {
342 if (tap_count < TAPPING_TOGGLE) {
343 unregister_mods(mods);
344 }
345 }
346 break;
347 default:
348 if (event.pressed) {
349 if (tap_count > 0) {
350# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
351 if (
352# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
353 !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false), record) &&
354# endif
355 record->tap.interrupted) {
356 dprint("mods_tap: tap: cancel: add_mods\n");
357 // ad hoc: set 0 to cancel tap
358 record->tap.count = 0;
359 register_mods(mods);
360 } else
361# endif
362 {
363 dprint("MODS_TAP: Tap: register_code\n");
364 register_code(action.key.code);
365 }
366 } else {
367 dprint("MODS_TAP: No tap: add_mods\n");
368 register_mods(mods);
369 }
370 } else {
371 if (tap_count > 0) {
372 dprint("MODS_TAP: Tap: unregister_code\n");
373 if (action.layer_tap.code == KC_CAPS) {
374 wait_ms(TAP_HOLD_CAPS_DELAY);
375 } else {
376 wait_ms(TAP_CODE_DELAY);
377 }
378 unregister_code(action.key.code);
379 } else {
380 dprint("MODS_TAP: No tap: add_mods\n");
381 unregister_mods(mods);
382 }
383 }
384 break;
385 }
386 } break;
387#endif
388#ifdef EXTRAKEY_ENABLE
389 /* other HID usage */
390 case ACT_USAGE:
391 switch (action.usage.page) {
392 case PAGE_SYSTEM:
393 if (event.pressed) {
394 host_system_send(action.usage.code);
395 } else {
396 host_system_send(0);
397 }
398 break;
399 case PAGE_CONSUMER:
400 if (event.pressed) {
401 host_consumer_send(action.usage.code);
402 } else {
403 host_consumer_send(0);
404 }
405 break;
406 }
407 break;
408#endif
409#ifdef MOUSEKEY_ENABLE
410 /* Mouse key */
411 case ACT_MOUSEKEY:
412 if (event.pressed) {
413 mousekey_on(action.key.code);
414 } else {
415 mousekey_off(action.key.code);
416 }
417 switch (action.key.code) {
418# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE)
419# ifdef POINTING_DEVICE_ENABLE
420 case KC_MS_BTN1 ... KC_MS_BTN8:
421# else
422 case KC_MS_BTN1 ... KC_MS_BTN3:
423# endif
424 register_button(event.pressed, MOUSE_BTN_MASK(action.key.code - KC_MS_BTN1));
425 break;
426# endif
427 default:
428 mousekey_send();
429 break;
430 }
431 break;
432#endif
433#ifndef NO_ACTION_LAYER
434 case ACT_LAYER:
435 if (action.layer_bitop.on == 0) {
436 /* Default Layer Bitwise Operation */
437 if (!event.pressed) {
438 uint8_t shift = action.layer_bitop.part * 4;
439 layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift;
440 layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0;
441 switch (action.layer_bitop.op) {
442 case OP_BIT_AND:
443 default_layer_and(bits | mask);
444 break;
445 case OP_BIT_OR:
446 default_layer_or(bits | mask);
447 break;
448 case OP_BIT_XOR:
449 default_layer_xor(bits | mask);
450 break;
451 case OP_BIT_SET:
452 default_layer_set(bits | mask);
453 break;
454 }
455 }
456 } else {
457 /* Layer Bitwise Operation */
458 if (event.pressed ? (action.layer_bitop.on & ON_PRESS) : (action.layer_bitop.on & ON_RELEASE)) {
459 uint8_t shift = action.layer_bitop.part * 4;
460 layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift;
461 layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0;
462 switch (action.layer_bitop.op) {
463 case OP_BIT_AND:
464 layer_and(bits | mask);
465 break;
466 case OP_BIT_OR:
467 layer_or(bits | mask);
468 break;
469 case OP_BIT_XOR:
470 layer_xor(bits | mask);
471 break;
472 case OP_BIT_SET:
473 layer_state_set(bits | mask);
474 break;
475 }
476 }
477 }
478 break;
479 case ACT_LAYER_MODS:
480 if (event.pressed) {
481 layer_on(action.layer_mods.layer);
482 register_mods(action.layer_mods.mods);
483 } else {
484 unregister_mods(action.layer_mods.mods);
485 layer_off(action.layer_mods.layer);
486 }
487 break;
488# ifndef NO_ACTION_TAPPING
489 case ACT_LAYER_TAP:
490 case ACT_LAYER_TAP_EXT:
491 switch (action.layer_tap.code) {
492 case OP_TAP_TOGGLE:
493 /* tap toggle */
494 if (event.pressed) {
495 if (tap_count < TAPPING_TOGGLE) {
496 layer_invert(action.layer_tap.val);
497 }
498 } else {
499 if (tap_count <= TAPPING_TOGGLE) {
500 layer_invert(action.layer_tap.val);
501 }
502 }
503 break;
504 case OP_ON_OFF:
505 event.pressed ? layer_on(action.layer_tap.val) : layer_off(action.layer_tap.val);
506 break;
507 case OP_OFF_ON:
508 event.pressed ? layer_off(action.layer_tap.val) : layer_on(action.layer_tap.val);
509 break;
510 case OP_SET_CLEAR:
511 event.pressed ? layer_move(action.layer_tap.val) : layer_clear();
512 break;
513# ifndef NO_ACTION_ONESHOT
514 case OP_ONESHOT:
515 // Oneshot modifier
516# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1
517 do_release_oneshot = false;
518 if (event.pressed) {
519 del_mods(get_oneshot_locked_mods());
520 if (get_oneshot_layer_state() == ONESHOT_TOGGLED) {
521 reset_oneshot_layer();
522 layer_off(action.layer_tap.val);
523 break;
524 } else if (tap_count < ONESHOT_TAP_TOGGLE) {
525 layer_on(action.layer_tap.val);
526 set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
527 }
528 } else {
529 add_mods(get_oneshot_locked_mods());
530 if (tap_count >= ONESHOT_TAP_TOGGLE) {
531 reset_oneshot_layer();
532 clear_oneshot_locked_mods();
533 set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
534 } else {
535 clear_oneshot_layer_state(ONESHOT_PRESSED);
536 }
537 }
538# else
539 if (event.pressed) {
540 layer_on(action.layer_tap.val);
541 set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
542 } else {
543 clear_oneshot_layer_state(ONESHOT_PRESSED);
544 if (tap_count > 1) {
545 clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
546 }
547 }
548# endif
549 break;
550# endif
551 default:
552 /* tap key */
553 if (event.pressed) {
554 if (tap_count > 0) {
555 dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
556 register_code(action.layer_tap.code);
557 } else {
558 dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
559 layer_on(action.layer_tap.val);
560 }
561 } else {
562 if (tap_count > 0) {
563 dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
564 if (action.layer_tap.code == KC_CAPS) {
565 wait_ms(TAP_HOLD_CAPS_DELAY);
566 } else {
567 wait_ms(TAP_CODE_DELAY);
568 }
569 unregister_code(action.layer_tap.code);
570 } else {
571 dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
572 layer_off(action.layer_tap.val);
573 }
574 }
575 break;
576 }
577 break;
578# endif
579#endif
580 /* Extentions */
581#ifndef NO_ACTION_MACRO
582 case ACT_MACRO:
583 action_macro_play(action_get_macro(record, action.func.id, action.func.opt));
584 break;
585#endif
586#ifdef SWAP_HANDS_ENABLE
587 case ACT_SWAP_HANDS:
588 switch (action.swap.code) {
589 case OP_SH_TOGGLE:
590 if (event.pressed) {
591 swap_hands = !swap_hands;
592 }
593 break;
594 case OP_SH_ON_OFF:
595 swap_hands = event.pressed;
596 break;
597 case OP_SH_OFF_ON:
598 swap_hands = !event.pressed;
599 break;
600 case OP_SH_ON:
601 if (!event.pressed) {
602 swap_hands = true;
603 }
604 break;
605 case OP_SH_OFF:
606 if (!event.pressed) {
607 swap_hands = false;
608 }
609 break;
610# ifndef NO_ACTION_ONESHOT
611 case OP_SH_ONESHOT:
612 if (event.pressed) {
613 set_oneshot_swaphands();
614 } else {
615 release_oneshot_swaphands();
616 }
617 break;
618# endif
619
620# ifndef NO_ACTION_TAPPING
621 case OP_SH_TAP_TOGGLE:
622 /* tap toggle */
623
624 if (event.pressed) {
625 if (swap_held) {
626 swap_held = false;
627 } else {
628 swap_hands = !swap_hands;
629 }
630 } else {
631 if (tap_count < TAPPING_TOGGLE) {
632 swap_hands = !swap_hands;
633 }
634 }
635 break;
636 default:
637 /* tap key */
638 if (tap_count > 0) {
639 if (swap_held) {
640 swap_hands = !swap_hands; // undo hold set up in _tap_hint
641 swap_held = false;
642 }
643 if (event.pressed) {
644 register_code(action.swap.code);
645 } else {
646 wait_ms(TAP_CODE_DELAY);
647 unregister_code(action.swap.code);
648 *record = (keyrecord_t){}; // hack: reset tap mode
649 }
650 } else {
651 if (swap_held && !event.pressed) {
652 swap_hands = !swap_hands; // undo hold set up in _tap_hint
653 swap_held = false;
654 }
655 }
656# endif
657 }
658#endif
659#ifndef NO_ACTION_FUNCTION
660 case ACT_FUNCTION:
661 action_function(record, action.func.id, action.func.opt);
662 break;
663#endif
664 default:
665 break;
666 }
667
668#ifndef NO_ACTION_LAYER
669 // if this event is a layer action, update the leds
670 switch (action.kind.id) {
671 case ACT_LAYER:
672 case ACT_LAYER_MODS:
673# ifndef NO_ACTION_TAPPING
674 case ACT_LAYER_TAP:
675 case ACT_LAYER_TAP_EXT:
676# endif
677 led_set(host_keyboard_leds());
678 break;
679 default:
680 break;
681 }
682#endif
683
684#ifndef NO_ACTION_TAPPING
685# if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY)
686 if (!is_tap_action(action)) {
687 retro_tapping_counter = 0;
688 } else {
689 if (event.pressed) {
690 if (tap_count > 0) {
691 retro_tapping_counter = 0;
692 }
693 } else {
694 if (tap_count > 0) {
695 retro_tapping_counter = 0;
696 } else {
697 if (
698# ifdef RETRO_TAPPING_PER_KEY
699 get_retro_tapping(get_event_keycode(record->event, false), record) &&
700# endif
701 retro_tapping_counter == 2) {
702 tap_code(action.layer_tap.code);
703 }
704 retro_tapping_counter = 0;
705 }
706 }
707 }
708# endif
709#endif
710
711#ifdef SWAP_HANDS_ENABLE
712# ifndef NO_ACTION_ONESHOT
713 if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) {
714 use_oneshot_swaphands();
715 }
716# endif
717#endif
718
719#ifndef NO_ACTION_ONESHOT
720 /* Because we switch layers after a oneshot event, we need to release the
721 * key before we leave the layer or no key up event will be generated.
722 */
723 if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED)) {
724 record->event.pressed = false;
725 layer_on(get_oneshot_layer());
726 process_record(record);
727 layer_off(get_oneshot_layer());
728 }
729#endif
730}
731
732/** \brief Utilities for actions. (FIXME: Needs better description)
733 *
734 * FIXME: Needs documentation.
735 */
736void register_code(uint8_t code) {
737 if (code == KC_NO) {
738 return;
739 }
740#ifdef LOCKING_SUPPORT_ENABLE
741 else if (KC_LOCKING_CAPS == code) {
742# ifdef LOCKING_RESYNC_ENABLE
743 // Resync: ignore if caps lock already is on
744 if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return;
745# endif
746 add_key(KC_CAPSLOCK);
747 send_keyboard_report();
748 wait_ms(100);
749 del_key(KC_CAPSLOCK);
750 send_keyboard_report();
751 }
752
753 else if (KC_LOCKING_NUM == code) {
754# ifdef LOCKING_RESYNC_ENABLE
755 if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return;
756# endif
757 add_key(KC_NUMLOCK);
758 send_keyboard_report();
759 wait_ms(100);
760 del_key(KC_NUMLOCK);
761 send_keyboard_report();
762 }
763
764 else if (KC_LOCKING_SCROLL == code) {
765# ifdef LOCKING_RESYNC_ENABLE
766 if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return;
767# endif
768 add_key(KC_SCROLLLOCK);
769 send_keyboard_report();
770 wait_ms(100);
771 del_key(KC_SCROLLLOCK);
772 send_keyboard_report();
773 }
774#endif
775
776 else if IS_KEY (code) {
777 // TODO: should push command_proc out of this block?
778 if (command_proc(code)) return;
779
780#ifndef NO_ACTION_ONESHOT
781/* TODO: remove
782 if (oneshot_state.mods && !oneshot_state.disabled) {
783 uint8_t tmp_mods = get_mods();
784 add_mods(oneshot_state.mods);
785
786 add_key(code);
787 send_keyboard_report();
788
789 set_mods(tmp_mods);
790 send_keyboard_report();
791 oneshot_cancel();
792 } else
793*/
794#endif
795 {
796 // Force a new key press if the key is already pressed
797 // without this, keys with the same keycode, but different
798 // modifiers will be reported incorrectly, see issue #1708
799 if (is_key_pressed(keyboard_report, code)) {
800 del_key(code);
801 send_keyboard_report();
802 }
803 add_key(code);
804 send_keyboard_report();
805 }
806 } else if IS_MOD (code) {
807 add_mods(MOD_BIT(code));
808 send_keyboard_report();
809 }
810#ifdef EXTRAKEY_ENABLE
811 else if IS_SYSTEM (code) {
812 host_system_send(KEYCODE2SYSTEM(code));
813 } else if IS_CONSUMER (code) {
814 host_consumer_send(KEYCODE2CONSUMER(code));
815 }
816#endif
817#ifdef MOUSEKEY_ENABLE
818 else if IS_MOUSEKEY (code) {
819 mousekey_on(code);
820 mousekey_send();
821 }
822#endif
823}
824
825/** \brief Utilities for actions. (FIXME: Needs better description)
826 *
827 * FIXME: Needs documentation.
828 */
829void unregister_code(uint8_t code) {
830 if (code == KC_NO) {
831 return;
832 }
833#ifdef LOCKING_SUPPORT_ENABLE
834 else if (KC_LOCKING_CAPS == code) {
835# ifdef LOCKING_RESYNC_ENABLE
836 // Resync: ignore if caps lock already is off
837 if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return;
838# endif
839 add_key(KC_CAPSLOCK);
840 send_keyboard_report();
841 del_key(KC_CAPSLOCK);
842 send_keyboard_report();
843 }
844
845 else if (KC_LOCKING_NUM == code) {
846# ifdef LOCKING_RESYNC_ENABLE
847 if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return;
848# endif
849 add_key(KC_NUMLOCK);
850 send_keyboard_report();
851 del_key(KC_NUMLOCK);
852 send_keyboard_report();
853 }
854
855 else if (KC_LOCKING_SCROLL == code) {
856# ifdef LOCKING_RESYNC_ENABLE
857 if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return;
858# endif
859 add_key(KC_SCROLLLOCK);
860 send_keyboard_report();
861 del_key(KC_SCROLLLOCK);
862 send_keyboard_report();
863 }
864#endif
865
866 else if IS_KEY (code) {
867 del_key(code);
868 send_keyboard_report();
869 } else if IS_MOD (code) {
870 del_mods(MOD_BIT(code));
871 send_keyboard_report();
872 } else if IS_SYSTEM (code) {
873 host_system_send(0);
874 } else if IS_CONSUMER (code) {
875 host_consumer_send(0);
876 }
877#ifdef MOUSEKEY_ENABLE
878 else if IS_MOUSEKEY (code) {
879 mousekey_off(code);
880 mousekey_send();
881 }
882#endif
883}
884
885/** \brief Tap a keycode with a delay.
886 *
887 * \param code The basic keycode to tap.
888 * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it.
889 */
890void tap_code_delay(uint8_t code, uint16_t delay) {
891 register_code(code);
892 for (uint16_t i = delay; i > 0; i--) {
893 wait_ms(1);
894 }
895 unregister_code(code);
896}
897
898/** \brief Tap a keycode with the default delay.
899 *
900 * \param code The basic keycode to tap. If `code` is `KC_CAPS`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
901 */
902void tap_code(uint8_t code) { tap_code_delay(code, code == KC_CAPS ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); }
903
904/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately.
905 *
906 * \param mods A bitfield of modifiers to register.
907 */
908void register_mods(uint8_t mods) {
909 if (mods) {
910 add_mods(mods);
911 send_keyboard_report();
912 }
913}
914
915/** \brief Removes the given physically pressed modifiers and sends a keyboard report immediately.
916 *
917 * \param mods A bitfield of modifiers to unregister.
918 */
919void unregister_mods(uint8_t mods) {
920 if (mods) {
921 del_mods(mods);
922 send_keyboard_report();
923 }
924}
925
926/** \brief Adds the given weak modifiers and sends a keyboard report immediately.
927 *
928 * \param mods A bitfield of modifiers to register.
929 */
930void register_weak_mods(uint8_t mods) {
931 if (mods) {
932 add_weak_mods(mods);
933 send_keyboard_report();
934 }
935}
936
937/** \brief Removes the given weak modifiers and sends a keyboard report immediately.
938 *
939 * \param mods A bitfield of modifiers to unregister.
940 */
941void unregister_weak_mods(uint8_t mods) {
942 if (mods) {
943 del_weak_mods(mods);
944 send_keyboard_report();
945 }
946}
947
948/** \brief Utilities for actions. (FIXME: Needs better description)
949 *
950 * FIXME: Needs documentation.
951 */
952void clear_keyboard(void) {
953 clear_mods();
954 clear_keyboard_but_mods();
955}
956
957/** \brief Utilities for actions. (FIXME: Needs better description)
958 *
959 * FIXME: Needs documentation.
960 */
961void clear_keyboard_but_mods(void) {
962 clear_keys();
963 clear_keyboard_but_mods_and_keys();
964}
965
966/** \brief Utilities for actions. (FIXME: Needs better description)
967 *
968 * FIXME: Needs documentation.
969 */
970void clear_keyboard_but_mods_and_keys() {
971#ifdef EXTRAKEY_ENABLE
972 host_system_send(0);
973 host_consumer_send(0);
974#endif
975 clear_weak_mods();
976 clear_macro_mods();
977 send_keyboard_report();
978#ifdef MOUSEKEY_ENABLE
979 mousekey_clear();
980 mousekey_send();
981#endif
982}
983
984/** \brief Utilities for actions. (FIXME: Needs better description)
985 *
986 * FIXME: Needs documentation.
987 */
988bool is_tap_key(keypos_t key) {
989 action_t action = layer_switch_get_action(key);
990 return is_tap_action(action);
991}
992
993/** \brief Utilities for actions. (FIXME: Needs better description)
994 *
995 * FIXME: Needs documentation.
996 */
997bool is_tap_action(action_t action) {
998 switch (action.kind.id) {
999 case ACT_LMODS_TAP:
1000 case ACT_RMODS_TAP:
1001 case ACT_LAYER_TAP:
1002 case ACT_LAYER_TAP_EXT:
1003 switch (action.layer_tap.code) {
1004 case KC_NO ... KC_RGUI:
1005 case OP_TAP_TOGGLE:
1006 case OP_ONESHOT:
1007 return true;
1008 }
1009 return false;
1010 case ACT_SWAP_HANDS:
1011 switch (action.swap.code) {
1012 case KC_NO ... KC_RGUI:
1013 case OP_SH_TAP_TOGGLE:
1014 return true;
1015 }
1016 return false;
1017 case ACT_MACRO:
1018 case ACT_FUNCTION:
1019 if (action.func.opt & FUNC_TAP) {
1020 return true;
1021 }
1022 return false;
1023 }
1024 return false;
1025}
1026
1027/** \brief Debug print (FIXME: Needs better description)
1028 *
1029 * FIXME: Needs documentation.
1030 */
1031void debug_event(keyevent_t event) { dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time); }
1032/** \brief Debug print (FIXME: Needs better description)
1033 *
1034 * FIXME: Needs documentation.
1035 */
1036void debug_record(keyrecord_t record) {
1037 debug_event(record.event);
1038#ifndef NO_ACTION_TAPPING
1039 dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' '));
1040#endif
1041}
1042
1043/** \brief Debug print (FIXME: Needs better description)
1044 *
1045 * FIXME: Needs documentation.
1046 */
1047void debug_action(action_t action) {
1048 switch (action.kind.id) {
1049 case ACT_LMODS:
1050 dprint("ACT_LMODS");
1051 break;
1052 case ACT_RMODS:
1053 dprint("ACT_RMODS");
1054 break;
1055 case ACT_LMODS_TAP:
1056 dprint("ACT_LMODS_TAP");
1057 break;
1058 case ACT_RMODS_TAP:
1059 dprint("ACT_RMODS_TAP");
1060 break;
1061 case ACT_USAGE:
1062 dprint("ACT_USAGE");
1063 break;
1064 case ACT_MOUSEKEY:
1065 dprint("ACT_MOUSEKEY");
1066 break;
1067 case ACT_LAYER:
1068 dprint("ACT_LAYER");
1069 break;
1070 case ACT_LAYER_MODS:
1071 dprint("ACT_LAYER_MODS");
1072 break;
1073 case ACT_LAYER_TAP:
1074 dprint("ACT_LAYER_TAP");
1075 break;
1076 case ACT_LAYER_TAP_EXT:
1077 dprint("ACT_LAYER_TAP_EXT");
1078 break;
1079 case ACT_MACRO:
1080 dprint("ACT_MACRO");
1081 break;
1082 case ACT_FUNCTION:
1083 dprint("ACT_FUNCTION");
1084 break;
1085 case ACT_SWAP_HANDS:
1086 dprint("ACT_SWAP_HANDS");
1087 break;
1088 default:
1089 dprint("UNKNOWN");
1090 break;
1091 }
1092 dprintf("[%X:%02X]", action.kind.param >> 8, action.kind.param & 0xff);
1093}
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
deleted file mode 100644
index 8cb4722c6..000000000
--- a/tmk_core/common/action.h
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include <stdbool.h>
22#include "keyboard.h"
23#include "keycode.h"
24#include "action_code.h"
25#include "action_macro.h"
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/* Disable macro and function features when LTO is enabled, since they break */
32#ifdef LTO_ENABLE
33# ifndef NO_ACTION_MACRO
34# define NO_ACTION_MACRO
35# endif
36# ifndef NO_ACTION_FUNCTION
37# define NO_ACTION_FUNCTION
38# endif
39#endif
40
41/* tapping count and state */
42typedef struct {
43 bool interrupted : 1;
44 bool reserved2 : 1;
45 bool reserved1 : 1;
46 bool reserved0 : 1;
47 uint8_t count : 4;
48} tap_t;
49
50/* Key event container for recording */
51typedef struct {
52 keyevent_t event;
53#ifndef NO_ACTION_TAPPING
54 tap_t tap;
55#endif
56} keyrecord_t;
57
58/* Execute action per keyevent */
59void action_exec(keyevent_t event);
60
61/* action for key */
62action_t action_for_key(uint8_t layer, keypos_t key);
63
64/* macro */
65const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
66
67/* user defined special function */
68void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
69
70/* keyboard-specific key event (pre)processing */
71bool process_record_quantum(keyrecord_t *record);
72
73/* Utilities for actions. */
74#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
75extern bool disable_action_cache;
76#endif
77
78/* Code for handling one-handed key modifiers. */
79#ifdef SWAP_HANDS_ENABLE
80extern bool swap_hands;
81extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS];
82# if (MATRIX_COLS <= 8)
83typedef uint8_t swap_state_row_t;
84# elif (MATRIX_COLS <= 16)
85typedef uint16_t swap_state_row_t;
86# elif (MATRIX_COLS <= 32)
87typedef uint32_t swap_state_row_t;
88# else
89# error "MATRIX_COLS: invalid value"
90# endif
91
92void process_hand_swap(keyevent_t *record);
93#endif
94
95void process_record_nocache(keyrecord_t *record);
96void process_record(keyrecord_t *record);
97void process_record_handler(keyrecord_t *record);
98void post_process_record_quantum(keyrecord_t *record);
99void process_action(keyrecord_t *record, action_t action);
100void register_code(uint8_t code);
101void unregister_code(uint8_t code);
102void tap_code(uint8_t code);
103void tap_code_delay(uint8_t code, uint16_t delay);
104void register_mods(uint8_t mods);
105void unregister_mods(uint8_t mods);
106void register_weak_mods(uint8_t mods);
107void unregister_weak_mods(uint8_t mods);
108// void set_mods(uint8_t mods);
109void clear_keyboard(void);
110void clear_keyboard_but_mods(void);
111void clear_keyboard_but_mods_and_keys(void);
112void layer_switch(uint8_t new_layer);
113bool is_tap_key(keypos_t key);
114bool is_tap_action(action_t action);
115
116#ifndef NO_ACTION_TAPPING
117void process_record_tap_hint(keyrecord_t *record);
118#endif
119
120/* debug */
121void debug_event(keyevent_t event);
122void debug_record(keyrecord_t record);
123void debug_action(action_t action);
124
125#ifdef __cplusplus
126}
127#endif
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h
deleted file mode 100644
index eb18c36ae..000000000
--- a/tmk_core/common/action_code.h
+++ /dev/null
@@ -1,308 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20/** \brief Action codes
21 *
22 * 16bit code: action_kind(4bit) + action_parameter(12bit)
23 *
24 * Key Actions(00xx)
25 * -----------------
26 * ACT_MODS(000r):
27 * 000r|0000|0000 0000 No action code
28 * 000r|0000|0000 0001 Transparent code
29 * 000r|0000| keycode Key
30 * 000r|mods|0000 0000 Modifiers
31 * 000r|mods| keycode Modifiers+Key(Modified key)
32 * r: Left/Right flag(Left:0, Right:1)
33 *
34 * ACT_MODS_TAP(001r):
35 * 001r|mods|0000 0000 Modifiers with OneShot
36 * 001r|mods|0000 0001 Modifiers with tap toggle
37 * 001r|mods|0000 00xx (reserved)
38 * 001r|mods| keycode Modifiers with Tap Key(Dual role)
39 *
40 * Other Keys(01xx)
41 * ----------------
42 * ACT_USAGE(0100): TODO: Not needed?
43 * 0100|00| usage(10) System control(0x80) - General Desktop page(0x01)
44 * 0100|01| usage(10) Consumer control(0x01) - Consumer page(0x0C)
45 * 0100|10| usage(10) (reserved)
46 * 0100|11| usage(10) (reserved)
47 *
48 * ACT_MOUSEKEY(0101): TODO: Merge these two actions to conserve space?
49 * 0101|xxxx| keycode Mouse key
50 *
51 * ACT_SWAP_HANDS(0110):
52 * 0110|xxxx| keycode Swap hands (keycode on tap, or options)
53 *
54 * 0111|xxxx xxxx xxxx (reserved)
55 *
56 * Layer Actions(10xx)
57 * -------------------
58 * ACT_LAYER(1000):
59 * 1000|oo00|pppE BBBB Default Layer Bitwise operation
60 * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET)
61 * ppp: 4-bit chunk part(0-7)
62 * EBBBB: bits and extra bit
63 * 1000|ooee|pppE BBBB Layer Bitwise Operation
64 * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET)
65 * ppp: 4-bit chunk part(0-7)
66 * EBBBB: bits and extra bit
67 * ee: on event(01:press, 10:release, 11:both)
68 *
69 * ACT_LAYER_MODS(1001):
70 * 1001|LLLL| mods Layer with modifiers held
71 *
72 * ACT_LAYER_TAP(101x):
73 * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP]
74 * 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP]
75 * 101E|LLLL|1111 0000 Invert with tap toggle (0xF0) [TAP]
76 * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP]
77 * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP]
78 * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP]
79 * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP]
80 * 101E|LLLL|1111 xxxx Reserved (0xF5-FF)
81 * ELLLL: layer 0-31(E: extra bit for layer 16-31)
82 *
83 * Extensions(11xx)
84 * ----------------
85 * ACT_MACRO(1100):
86 * 1100|opt | id(8) Macro play?
87 * 1100|1111| id(8) Macro record?
88 *
89 * 1101|xxxx xxxx xxxx (reserved)
90 * 1110|xxxx xxxx xxxx (reserved)
91 *
92 * ACT_FUNCTION(1111):
93 * 1111| address(12) Function?
94 * 1111|opt | id(8) Function?
95 */
96enum action_kind_id {
97 /* Key Actions */
98 ACT_MODS = 0b0000,
99 ACT_LMODS = 0b0000,
100 ACT_RMODS = 0b0001,
101 ACT_MODS_TAP = 0b0010,
102 ACT_LMODS_TAP = 0b0010,
103 ACT_RMODS_TAP = 0b0011,
104 /* Other Keys */
105 ACT_USAGE = 0b0100,
106 ACT_MOUSEKEY = 0b0101,
107 /* One-hand Support */
108 ACT_SWAP_HANDS = 0b0110,
109 /* Layer Actions */
110 ACT_LAYER = 0b1000,
111 ACT_LAYER_MODS = 0b1001,
112 ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
113 ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */
114 /* Extensions */
115 ACT_MACRO = 0b1100,
116 ACT_FUNCTION = 0b1111
117};
118
119/** \brief Action Code Struct
120 *
121 * NOTE:
122 * In avr-gcc bit field seems to be assigned from LSB(bit0) to MSB(bit15).
123 * AVR looks like a little endian in avr-gcc.
124 * Not portable across compiler/endianness?
125 *
126 * Byte order and bit order of 0x1234:
127 * Big endian: Little endian:
128 * -------------------- --------------------
129 * FEDC BA98 7654 3210 0123 4567 89AB CDEF
130 * 0001 0010 0011 0100 0010 1100 0100 1000
131 * 0x12 0x34 0x34 0x12
132 */
133typedef union {
134 uint16_t code;
135 struct action_kind {
136 uint16_t param : 12;
137 uint8_t id : 4;
138 } kind;
139 struct action_key {
140 uint8_t code : 8;
141 uint8_t mods : 4;
142 uint8_t kind : 4;
143 } key;
144 struct action_layer_bitop {
145 uint8_t bits : 4;
146 uint8_t xbit : 1;
147 uint8_t part : 3;
148 uint8_t on : 2;
149 uint8_t op : 2;
150 uint8_t kind : 4;
151 } layer_bitop;
152 struct action_layer_mods {
153 uint8_t mods : 8;
154 uint8_t layer : 4;
155 uint8_t kind : 4;
156 } layer_mods;
157 struct action_layer_tap {
158 uint8_t code : 8;
159 uint8_t val : 5;
160 uint8_t kind : 3;
161 } layer_tap;
162 struct action_usage {
163 uint16_t code : 10;
164 uint8_t page : 2;
165 uint8_t kind : 4;
166 } usage;
167 struct action_function {
168 uint8_t id : 8;
169 uint8_t opt : 4;
170 uint8_t kind : 4;
171 } func;
172 struct action_swap {
173 uint8_t code : 8;
174 uint8_t opt : 4;
175 uint8_t kind : 4;
176 } swap;
177} action_t;
178
179/* action utility */
180#define ACTION_NO 0
181#define ACTION_TRANSPARENT 1
182#define ACTION(kind, param) ((kind) << 12 | (param))
183
184/** \brief Key Actions
185 *
186 * Mod bits: 43210
187 * bit 0 ||||+- Control
188 * bit 1 |||+-- Shift
189 * bit 2 ||+--- Alt
190 * bit 3 |+---- Gui
191 * bit 4 +----- LR flag(Left:0, Right:1)
192 */
193enum mods_bit {
194 MOD_LCTL = 0x01,
195 MOD_LSFT = 0x02,
196 MOD_LALT = 0x04,
197 MOD_LGUI = 0x08,
198 MOD_RCTL = 0x11,
199 MOD_RSFT = 0x12,
200 MOD_RALT = 0x14,
201 MOD_RGUI = 0x18,
202};
203enum mods_codes {
204 MODS_ONESHOT = 0x00,
205 MODS_TAP_TOGGLE = 0x01,
206};
207#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
208#define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | 0)
209#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | (key))
210#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | (key))
211#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_ONESHOT)
212#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_TAP_TOGGLE)
213
214/** \brief Other Keys
215 */
216enum usage_pages { PAGE_SYSTEM, PAGE_CONSUMER };
217#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id))
218#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id))
219#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)
220
221/** \brief Layer Actions
222 */
223enum layer_param_on {
224 ON_PRESS = 1,
225 ON_RELEASE = 2,
226 ON_BOTH = 3,
227};
228
229/** \brief Layer Actions
230 */
231enum layer_param_bit_op {
232 OP_BIT_AND = 0,
233 OP_BIT_OR = 1,
234 OP_BIT_XOR = 2,
235 OP_BIT_SET = 3,
236};
237
238/** \brief Layer Actions
239 */
240enum layer_param_tap_op {
241 OP_TAP_TOGGLE = 0xF0,
242 OP_ON_OFF,
243 OP_OFF_ON,
244 OP_SET_CLEAR,
245 OP_ONESHOT,
246};
247#define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op) << 10 | (on) << 8 | (part) << 5 | ((bits)&0x1f))
248#define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer) << 8 | (key))
249/* Default Layer */
250#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4))
251/* Layer Operation */
252#define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on))
253#define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer)
254#define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE)
255#define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer) / 4, 1 << ((layer) % 4), (on))
256#define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR((layer) / 4, 1 << ((layer) % 4), (on))
257#define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer) / 4, ~(1 << ((layer) % 4)), (on))
258#define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4), (on))
259#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
260#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
261#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
262#define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT)
263#define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods))
264/* With Tapping */
265#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
266#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
267/* Bitwise Operation */
268#define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on))
269#define ACTION_LAYER_BIT_OR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on))
270#define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on))
271#define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on))
272/* Default Layer Bitwise Operation */
273#define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0)
274#define ACTION_DEFAULT_LAYER_BIT_OR(part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0)
275#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0)
276#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0)
277
278/* Macro */
279#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
280#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP << 8 | (id))
281#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt) << 8 | (id))
282/* Function */
283enum function_opts {
284 FUNC_TAP = 0x8, /* indciates function is tappable */
285};
286#define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
287#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP << 8 | (id))
288#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt) << 8 | (id))
289/* OneHand Support */
290enum swap_hands_param_tap_op {
291 OP_SH_TOGGLE = 0xF0,
292 OP_SH_TAP_TOGGLE,
293 OP_SH_ON_OFF,
294 OP_SH_OFF_ON,
295 OP_SH_OFF,
296 OP_SH_ON,
297 OP_SH_ONESHOT,
298};
299
300#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF()
301#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE)
302#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE)
303#define ACTION_SWAP_HANDS_ONESHOT() ACTION(ACT_SWAP_HANDS, OP_SH_ONESHOT)
304#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key)
305#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF)
306#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON)
307#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON)
308#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF)
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
deleted file mode 100644
index af2d7d964..000000000
--- a/tmk_core/common/action_layer.c
+++ /dev/null
@@ -1,279 +0,0 @@
1#include <stdint.h>
2#include "keyboard.h"
3#include "action.h"
4#include "util.h"
5#include "action_layer.h"
6
7#ifdef DEBUG_ACTION
8# include "debug.h"
9#else
10# include "nodebug.h"
11#endif
12
13/** \brief Default Layer State
14 */
15layer_state_t default_layer_state = 0;
16
17/** \brief Default Layer State Set At user Level
18 *
19 * Run user code on default layer state change
20 */
21__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state) { return state; }
22
23/** \brief Default Layer State Set At Keyboard Level
24 *
25 * Run keyboard code on default layer state change
26 */
27__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state) { return default_layer_state_set_user(state); }
28
29/** \brief Default Layer State Set
30 *
31 * Static function to set the default layer state, prints debug info and clears keys
32 */
33static void default_layer_state_set(layer_state_t state) {
34 state = default_layer_state_set_kb(state);
35 debug("default_layer_state: ");
36 default_layer_debug();
37 debug(" to ");
38 default_layer_state = state;
39 default_layer_debug();
40 debug("\n");
41#ifdef STRICT_LAYER_RELEASE
42 clear_keyboard_but_mods(); // To avoid stuck keys
43#else
44 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
45#endif
46}
47
48/** \brief Default Layer Print
49 *
50 * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit.
51 */
52void default_layer_debug(void) { dprintf("%08lX(%u)", default_layer_state, get_highest_layer(default_layer_state)); }
53
54/** \brief Default Layer Set
55 *
56 * Sets the default layer state.
57 */
58void default_layer_set(layer_state_t state) { default_layer_state_set(state); }
59
60#ifndef NO_ACTION_LAYER
61/** \brief Default Layer Or
62 *
63 * Turns on the default layer based on matching bits between specifed layer and existing layer state
64 */
65void default_layer_or(layer_state_t state) { default_layer_state_set(default_layer_state | state); }
66/** \brief Default Layer And
67 *
68 * Turns on default layer based on matching enabled bits between specifed layer and existing layer state
69 */
70void default_layer_and(layer_state_t state) { default_layer_state_set(default_layer_state & state); }
71/** \brief Default Layer Xor
72 *
73 * Turns on default layer based on non-matching bits between specifed layer and existing layer state
74 */
75void default_layer_xor(layer_state_t state) { default_layer_state_set(default_layer_state ^ state); }
76#endif
77
78#ifndef NO_ACTION_LAYER
79/** \brief Keymap Layer State
80 */
81layer_state_t layer_state = 0;
82
83/** \brief Layer state set user
84 *
85 * Runs user code on layer state change
86 */
87__attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) { return state; }
88
89/** \brief Layer state set keyboard
90 *
91 * Runs keyboard code on layer state change
92 */
93__attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { return layer_state_set_user(state); }
94
95/** \brief Layer state set
96 *
97 * Sets the layer to match the specifed state (a bitmask)
98 */
99void layer_state_set(layer_state_t state) {
100 state = layer_state_set_kb(state);
101 dprint("layer_state: ");
102 layer_debug();
103 dprint(" to ");
104 layer_state = state;
105 layer_debug();
106 dprintln();
107# ifdef STRICT_LAYER_RELEASE
108 clear_keyboard_but_mods(); // To avoid stuck keys
109# else
110 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
111# endif
112}
113
114/** \brief Layer clear
115 *
116 * Turn off all layers
117 */
118void layer_clear(void) { layer_state_set(0); }
119
120/** \brief Layer state is
121 *
122 * Return whether the given state is on (it might still be shadowed by a higher state, though)
123 */
124bool layer_state_is(uint8_t layer) { return layer_state_cmp(layer_state, layer); }
125
126/** \brief Layer state compare
127 *
128 * Used for comparing layers {mostly used for unit testing}
129 */
130bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) {
131 if (!cmp_layer_state) {
132 return layer == 0;
133 }
134 return (cmp_layer_state & (1UL << layer)) != 0;
135}
136
137/** \brief Layer move
138 *
139 * Turns on the given layer and turn off all other layers
140 */
141void layer_move(uint8_t layer) { layer_state_set(1UL << layer); }
142
143/** \brief Layer on
144 *
145 * Turns on given layer
146 */
147void layer_on(uint8_t layer) { layer_state_set(layer_state | (1UL << layer)); }
148
149/** \brief Layer off
150 *
151 * Turns off given layer
152 */
153void layer_off(uint8_t layer) { layer_state_set(layer_state & ~(1UL << layer)); }
154
155/** \brief Layer invert
156 *
157 * Toggle the given layer (set it if it's unset, or unset it if it's set)
158 */
159void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ (1UL << layer)); }
160
161/** \brief Layer or
162 *
163 * Turns on layers based on matching bits between specifed layer and existing layer state
164 */
165void layer_or(layer_state_t state) { layer_state_set(layer_state | state); }
166/** \brief Layer and
167 *
168 * Turns on layers based on matching enabled bits between specifed layer and existing layer state
169 */
170void layer_and(layer_state_t state) { layer_state_set(layer_state & state); }
171/** \brief Layer xor
172 *
173 * Turns on layers based on non-matching bits between specifed layer and existing layer state
174 */
175void layer_xor(layer_state_t state) { layer_state_set(layer_state ^ state); }
176
177/** \brief Layer debug printing
178 *
179 * Print out the hex value of the 32-bit layer state, as well as the value of the highest bit.
180 */
181void layer_debug(void) { dprintf("%08lX(%u)", layer_state, get_highest_layer(layer_state)); }
182#endif
183
184#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
185/** \brief source layer cache
186 */
187
188uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
189
190/** \brief update source layers cache
191 *
192 * Updates the cached keys when changing layers
193 */
194void update_source_layers_cache(keypos_t key, uint8_t layer) {
195 const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
196 const uint8_t storage_row = key_number / 8;
197 const uint8_t storage_bit = key_number % 8;
198
199 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
200 source_layers_cache[storage_row][bit_number] ^= (-((layer & (1U << bit_number)) != 0) ^ source_layers_cache[storage_row][bit_number]) & (1U << storage_bit);
201 }
202}
203
204/** \brief read source layers cache
205 *
206 * reads the cached keys stored when the layer was changed
207 */
208uint8_t read_source_layers_cache(keypos_t key) {
209 const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
210 const uint8_t storage_row = key_number / 8;
211 const uint8_t storage_bit = key_number % 8;
212 uint8_t layer = 0;
213
214 for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
215 layer |= ((source_layers_cache[storage_row][bit_number] & (1U << storage_bit)) != 0) << bit_number;
216 }
217
218 return layer;
219}
220#endif
221
222/** \brief Store or get action (FIXME: Needs better summary)
223 *
224 * Make sure the action triggered when the key is released is the same
225 * one as the one triggered on press. It's important for the mod keys
226 * when the layer is switched after the down event but before the up
227 * event as they may get stuck otherwise.
228 */
229action_t store_or_get_action(bool pressed, keypos_t key) {
230#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
231 if (disable_action_cache) {
232 return layer_switch_get_action(key);
233 }
234
235 uint8_t layer;
236
237 if (pressed) {
238 layer = layer_switch_get_layer(key);
239 update_source_layers_cache(key, layer);
240 } else {
241 layer = read_source_layers_cache(key);
242 }
243 return action_for_key(layer, key);
244#else
245 return layer_switch_get_action(key);
246#endif
247}
248
249/** \brief Layer switch get layer
250 *
251 * Gets the layer based on key info
252 */
253uint8_t layer_switch_get_layer(keypos_t key) {
254#ifndef NO_ACTION_LAYER
255 action_t action;
256 action.code = ACTION_TRANSPARENT;
257
258 layer_state_t layers = layer_state | default_layer_state;
259 /* check top layer first */
260 for (int8_t i = MAX_LAYER - 1; i >= 0; i--) {
261 if (layers & (1UL << i)) {
262 action = action_for_key(i, key);
263 if (action.code != ACTION_TRANSPARENT) {
264 return i;
265 }
266 }
267 }
268 /* fall back to layer 0 */
269 return 0;
270#else
271 return get_highest_layer(default_layer_state);
272#endif
273}
274
275/** \brief Layer switch get layer
276 *
277 * Gets action code based on key position
278 */
279action_t layer_switch_get_action(keypos_t key) { return action_for_key(layer_switch_get_layer(key), key); }
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
deleted file mode 100644
index d72cd3e3a..000000000
--- a/tmk_core/common/action_layer.h
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include "keyboard.h"
22#include "action.h"
23
24#if defined(LAYER_STATE_8BIT)
25typedef uint8_t layer_state_t;
26# define MAX_LAYER_BITS 3
27# ifndef MAX_LAYER
28# define MAX_LAYER 8
29# endif
30# define get_highest_layer(state) biton(state)
31#elif defined(LAYER_STATE_16BIT)
32typedef uint16_t layer_state_t;
33# define MAX_LAYER_BITS 4
34# ifndef MAX_LAYER
35# define MAX_LAYER 16
36# endif
37# define get_highest_layer(state) biton16(state)
38#else
39typedef uint32_t layer_state_t;
40# define MAX_LAYER_BITS 5
41# ifndef MAX_LAYER
42# define MAX_LAYER 32
43# endif
44# define get_highest_layer(state) biton32(state)
45#endif
46
47/*
48 * Default Layer
49 */
50extern layer_state_t default_layer_state;
51void default_layer_debug(void);
52void default_layer_set(layer_state_t state);
53
54__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state);
55__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state);
56
57#ifndef NO_ACTION_LAYER
58/* bitwise operation */
59void default_layer_or(layer_state_t state);
60void default_layer_and(layer_state_t state);
61void default_layer_xor(layer_state_t state);
62#else
63# define default_layer_or(state)
64# define default_layer_and(state)
65# define default_layer_xor(state)
66#endif
67
68/*
69 * Keymap Layer
70 */
71#ifndef NO_ACTION_LAYER
72extern layer_state_t layer_state;
73
74void layer_state_set(layer_state_t state);
75bool layer_state_is(uint8_t layer);
76bool layer_state_cmp(layer_state_t layer1, uint8_t layer2);
77
78void layer_debug(void);
79void layer_clear(void);
80void layer_move(uint8_t layer);
81void layer_on(uint8_t layer);
82void layer_off(uint8_t layer);
83void layer_invert(uint8_t layer);
84/* bitwise operation */
85void layer_or(layer_state_t state);
86void layer_and(layer_state_t state);
87void layer_xor(layer_state_t state);
88layer_state_t layer_state_set_user(layer_state_t state);
89layer_state_t layer_state_set_kb(layer_state_t state);
90#else
91# define layer_state 0
92
93# define layer_state_set(layer)
94# define layer_state_is(layer) (layer == 0)
95# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & 1UL << layer) != 0)
96
97# define layer_debug()
98# define layer_clear()
99# define layer_move(layer) (void)layer
100# define layer_on(layer) (void)layer
101# define layer_off(layer) (void)layer
102# define layer_invert(layer) (void)layer
103# define layer_or(state) (void)state
104# define layer_and(state) (void)state
105# define layer_xor(state) (void)state
106# define layer_state_set_kb(state) (void)state
107# define layer_state_set_user(state) (void)state
108#endif
109
110/* pressed actions cache */
111#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
112
113void update_source_layers_cache(keypos_t key, uint8_t layer);
114uint8_t read_source_layers_cache(keypos_t key);
115#endif
116action_t store_or_get_action(bool pressed, keypos_t key);
117
118/* return the topmost non-transparent layer currently associated with key */
119uint8_t layer_switch_get_layer(keypos_t key);
120
121/* return action depending on current layer status */
122action_t layer_switch_get_action(keypos_t key);
diff --git a/tmk_core/common/action_macro.c b/tmk_core/common/action_macro.c
deleted file mode 100644
index 92228c0ba..000000000
--- a/tmk_core/common/action_macro.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "action.h"
18#include "action_util.h"
19#include "action_macro.h"
20#include "wait.h"
21
22#ifdef DEBUG_ACTION
23# include "debug.h"
24#else
25# include "nodebug.h"
26#endif
27
28#ifndef NO_ACTION_MACRO
29
30# define MACRO_READ() (macro = MACRO_GET(macro_p++))
31/** \brief Action Macro Play
32 *
33 * FIXME: Needs doc
34 */
35void action_macro_play(const macro_t *macro_p) {
36 macro_t macro = END;
37 uint8_t interval = 0;
38
39 if (!macro_p) return;
40 while (true) {
41 switch (MACRO_READ()) {
42 case KEY_DOWN:
43 MACRO_READ();
44 dprintf("KEY_DOWN(%02X)\n", macro);
45 if (IS_MOD(macro)) {
46 add_macro_mods(MOD_BIT(macro));
47 send_keyboard_report();
48 } else {
49 register_code(macro);
50 }
51 break;
52 case KEY_UP:
53 MACRO_READ();
54 dprintf("KEY_UP(%02X)\n", macro);
55 if (IS_MOD(macro)) {
56 del_macro_mods(MOD_BIT(macro));
57 send_keyboard_report();
58 } else {
59 unregister_code(macro);
60 }
61 break;
62 case WAIT:
63 MACRO_READ();
64 dprintf("WAIT(%u)\n", macro);
65 {
66 uint8_t ms = macro;
67 while (ms--) wait_ms(1);
68 }
69 break;
70 case INTERVAL:
71 interval = MACRO_READ();
72 dprintf("INTERVAL(%u)\n", interval);
73 break;
74 case 0x04 ... 0x73:
75 dprintf("DOWN(%02X)\n", macro);
76 register_code(macro);
77 break;
78 case 0x84 ... 0xF3:
79 dprintf("UP(%02X)\n", macro);
80 unregister_code(macro & 0x7F);
81 break;
82 case END:
83 default:
84 return;
85 }
86 // interval
87 {
88 uint8_t ms = interval;
89 while (ms--) wait_ms(1);
90 }
91 }
92}
93#endif
diff --git a/tmk_core/common/action_macro.h b/tmk_core/common/action_macro.h
deleted file mode 100644
index 685e2c6ff..000000000
--- a/tmk_core/common/action_macro.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include "progmem.h"
22
23typedef uint8_t macro_t;
24
25#define MACRO_NONE (macro_t *)0
26#define MACRO(...) \
27 ({ \
28 static const macro_t __m[] PROGMEM = {__VA_ARGS__}; \
29 &__m[0]; \
30 })
31#define MACRO_GET(p) pgm_read_byte(p)
32
33// Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped
34#define MACRO_TAP_HOLD(record, press, release, tap_macro) (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE) : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release)))
35
36// Holds down the modifier mod when the macro key is held, or sends macro instead when tapped
37#define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro)
38
39// Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #)
40#define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod)
41
42// Momentary switch layer when held, sends macro if tapped
43#define MACRO_TAP_HOLD_LAYER(record, macro, layer) \
44 (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({ \
45 layer_on((layer)); \
46 MACRO_NONE; \
47 }) \
48 : MACRO_NONE) \
49 : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({ \
50 layer_off((layer)); \
51 MACRO_NONE; \
52 })))
53
54// Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #)
55#define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer)
56
57#ifndef NO_ACTION_MACRO
58void action_macro_play(const macro_t *macro_p);
59#else
60# define action_macro_play(macro)
61#endif
62
63/* Macro commands
64 * code(0x04-73) // key down(1byte)
65 * code(0x04-73) | 0x80 // key up(1byte)
66 * { KEY_DOWN, code(0x04-0xff) } // key down(2bytes)
67 * { KEY_UP, code(0x04-0xff) } // key up(2bytes)
68 * WAIT // wait milli-seconds
69 * INTERVAL // set interval between macro commands
70 * END // stop macro execution
71 *
72 * Ideas(Not implemented):
73 * modifiers
74 * system usage
75 * consumer usage
76 * unicode usage
77 * function call
78 * conditionals
79 * loop
80 */
81enum macro_command_id {
82 /* 0x00 - 0x03 */
83 END = 0x00,
84 KEY_DOWN,
85 KEY_UP,
86
87 /* 0x04 - 0x73 (reserved for keycode down) */
88
89 /* 0x74 - 0x83 */
90 WAIT = 0x74,
91 INTERVAL,
92
93 /* 0x84 - 0xf3 (reserved for keycode up) */
94
95 /* 0xf4 - 0xff */
96};
97
98/* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed
99 * if keycode between 0x04 and 0x73
100 * keycode / (keycode|0x80)
101 * else
102 * {KEY_DOWN, keycode} / {KEY_UP, keycode}
103 */
104#define DOWN(key) KEY_DOWN, (key)
105#define UP(key) KEY_UP, (key)
106#define TYPE(key) DOWN(key), UP(key)
107#define WAIT(ms) WAIT, (ms)
108#define INTERVAL(ms) INTERVAL, (ms)
109
110/* key down */
111#define D(key) DOWN(KC_##key)
112/* key up */
113#define U(key) UP(KC_##key)
114/* key type */
115#define T(key) TYPE(KC_##key)
116/* wait */
117#define W(ms) WAIT(ms)
118/* interval */
119#define I(ms) INTERVAL(ms)
120
121/* for backward comaptibility */
122#define MD(key) DOWN(KC_##key)
123#define MU(key) UP(KC_##key)
diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c
deleted file mode 100644
index 56044e096..000000000
--- a/tmk_core/common/action_tapping.c
+++ /dev/null
@@ -1,426 +0,0 @@
1#include <stdint.h>
2#include <stdbool.h>
3#include "action.h"
4#include "action_layer.h"
5#include "action_tapping.h"
6#include "keycode.h"
7#include "timer.h"
8
9#ifdef DEBUG_ACTION
10# include "debug.h"
11#else
12# include "nodebug.h"
13#endif
14
15#ifndef NO_ACTION_TAPPING
16
17# define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
18# define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
19# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
20# define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
21
22__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; }
23
24# ifdef TAPPING_TERM_PER_KEY
25# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false), &tapping_key))
26# else
27# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
28# endif
29
30# ifdef TAPPING_FORCE_HOLD_PER_KEY
31__attribute__((weak)) bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { return false; }
32# endif
33
34# ifdef PERMISSIVE_HOLD_PER_KEY
35__attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { return false; }
36# endif
37
38static keyrecord_t tapping_key = {};
39static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
40static uint8_t waiting_buffer_head = 0;
41static uint8_t waiting_buffer_tail = 0;
42
43static bool process_tapping(keyrecord_t *record);
44static bool waiting_buffer_enq(keyrecord_t record);
45static void waiting_buffer_clear(void);
46static bool waiting_buffer_typed(keyevent_t event);
47static bool waiting_buffer_has_anykey_pressed(void);
48static void waiting_buffer_scan_tap(void);
49static void debug_tapping_key(void);
50static void debug_waiting_buffer(void);
51
52/** \brief Action Tapping Process
53 *
54 * FIXME: Needs doc
55 */
56void action_tapping_process(keyrecord_t record) {
57 if (process_tapping(&record)) {
58 if (!IS_NOEVENT(record.event)) {
59 debug("processed: ");
60 debug_record(record);
61 debug("\n");
62 }
63 } else {
64 if (!waiting_buffer_enq(record)) {
65 // clear all in case of overflow.
66 debug("OVERFLOW: CLEAR ALL STATES\n");
67 clear_keyboard();
68 waiting_buffer_clear();
69 tapping_key = (keyrecord_t){};
70 }
71 }
72
73 // process waiting_buffer
74 if (!IS_NOEVENT(record.event) && waiting_buffer_head != waiting_buffer_tail) {
75 debug("---- action_exec: process waiting_buffer -----\n");
76 }
77 for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
78 if (process_tapping(&waiting_buffer[waiting_buffer_tail])) {
79 debug("processed: waiting_buffer[");
80 debug_dec(waiting_buffer_tail);
81 debug("] = ");
82 debug_record(waiting_buffer[waiting_buffer_tail]);
83 debug("\n\n");
84 } else {
85 break;
86 }
87 }
88 if (!IS_NOEVENT(record.event)) {
89 debug("\n");
90 }
91}
92
93/** \brief Tapping
94 *
95 * Rule: Tap key is typed(pressed and released) within TAPPING_TERM.
96 * (without interfering by typing other key)
97 */
98/* return true when key event is processed or consumed. */
99bool process_tapping(keyrecord_t *keyp) {
100 keyevent_t event = keyp->event;
101
102 // if tapping
103 if (IS_TAPPING_PRESSED()) {
104 if (WITHIN_TAPPING_TERM(event)) {
105 if (tapping_key.tap.count == 0) {
106 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
107 // first tap!
108 debug("Tapping: First tap(0->1).\n");
109 tapping_key.tap.count = 1;
110 debug_tapping_key();
111 process_record(&tapping_key);
112
113 // copy tapping state
114 keyp->tap = tapping_key.tap;
115 // enqueue
116 return false;
117 }
118 /* Process a key typed within TAPPING_TERM
119 * This can register the key before settlement of tapping,
120 * useful for long TAPPING_TERM but may prevent fast typing.
121 */
122# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
123 else if (((
124# ifdef TAPPING_TERM_PER_KEY
125 get_tapping_term(get_event_keycode(tapping_key.event, false), keyp)
126# else
127 TAPPING_TERM
128# endif
129 >= 500)
130
131# ifdef PERMISSIVE_HOLD_PER_KEY
132 || get_permissive_hold(get_event_keycode(tapping_key.event, false), keyp)
133# elif defined(PERMISSIVE_HOLD)
134 || true
135# endif
136 ) &&
137 IS_RELEASED(event) && waiting_buffer_typed(event)) {
138 debug("Tapping: End. No tap. Interfered by typing key\n");
139 process_record(&tapping_key);
140 tapping_key = (keyrecord_t){};
141 debug_tapping_key();
142 // enqueue
143 return false;
144 }
145# endif
146 /* Process release event of a key pressed before tapping starts
147 * Without this unexpected repeating will occur with having fast repeating setting
148 * https://github.com/tmk/tmk_keyboard/issues/60
149 */
150 else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) {
151 // Modifier should be retained till end of this tapping.
152 action_t action = layer_switch_get_action(event.key);
153 switch (action.kind.id) {
154 case ACT_LMODS:
155 case ACT_RMODS:
156 if (action.key.mods && !action.key.code) return false;
157 if (IS_MOD(action.key.code)) return false;
158 break;
159 case ACT_LMODS_TAP:
160 case ACT_RMODS_TAP:
161 if (action.key.mods && keyp->tap.count == 0) return false;
162 if (IS_MOD(action.key.code)) return false;
163 break;
164 }
165 // Release of key should be process immediately.
166 debug("Tapping: release event of a key pressed before tapping\n");
167 process_record(keyp);
168 return true;
169 } else {
170 // set interrupted flag when other key preesed during tapping
171 if (event.pressed) {
172 tapping_key.tap.interrupted = true;
173 }
174 // enqueue
175 return false;
176 }
177 }
178 // tap_count > 0
179 else {
180 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
181 debug("Tapping: Tap release(");
182 debug_dec(tapping_key.tap.count);
183 debug(")\n");
184 keyp->tap = tapping_key.tap;
185 process_record(keyp);
186 tapping_key = *keyp;
187 debug_tapping_key();
188 return true;
189 } else if (is_tap_key(event.key) && event.pressed) {
190 if (tapping_key.tap.count > 1) {
191 debug("Tapping: Start new tap with releasing last tap(>1).\n");
192 // unregister key
193 process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false});
194 } else {
195 debug("Tapping: Start while last tap(1).\n");
196 }
197 tapping_key = *keyp;
198 waiting_buffer_scan_tap();
199 debug_tapping_key();
200 return true;
201 } else {
202 if (!IS_NOEVENT(event)) {
203 debug("Tapping: key event while last tap(>0).\n");
204 }
205 process_record(keyp);
206 return true;
207 }
208 }
209 }
210 // after TAPPING_TERM
211 else {
212 if (tapping_key.tap.count == 0) {
213 debug("Tapping: End. Timeout. Not tap(0): ");
214 debug_event(event);
215 debug("\n");
216 process_record(&tapping_key);
217 tapping_key = (keyrecord_t){};
218 debug_tapping_key();
219 return false;
220 } else {
221 if (IS_TAPPING_KEY(event.key) && !event.pressed) {
222 debug("Tapping: End. last timeout tap release(>0).");
223 keyp->tap = tapping_key.tap;
224 process_record(keyp);
225 tapping_key = (keyrecord_t){};
226 return true;
227 } else if (is_tap_key(event.key) && event.pressed) {
228 if (tapping_key.tap.count > 1) {
229 debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
230 // unregister key
231 process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false});
232 } else {
233 debug("Tapping: Start while last timeout tap(1).\n");
234 }
235 tapping_key = *keyp;
236 waiting_buffer_scan_tap();
237 debug_tapping_key();
238 return true;
239 } else {
240 if (!IS_NOEVENT(event)) {
241 debug("Tapping: key event while last timeout tap(>0).\n");
242 }
243 process_record(keyp);
244 return true;
245 }
246 }
247 }
248 } else if (IS_TAPPING_RELEASED()) {
249 if (WITHIN_TAPPING_TERM(event)) {
250 if (event.pressed) {
251 if (IS_TAPPING_KEY(event.key)) {
252//# ifndef TAPPING_FORCE_HOLD
253# if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY)
254 if (
255# ifdef TAPPING_FORCE_HOLD_PER_KEY
256 !get_tapping_force_hold(get_event_keycode(tapping_key.event, false), keyp) &&
257# endif
258 !tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
259 // sequential tap.
260 keyp->tap = tapping_key.tap;
261 if (keyp->tap.count < 15) keyp->tap.count += 1;
262 debug("Tapping: Tap press(");
263 debug_dec(keyp->tap.count);
264 debug(")\n");
265 process_record(keyp);
266 tapping_key = *keyp;
267 debug_tapping_key();
268 return true;
269 }
270# endif
271 // FIX: start new tap again
272 tapping_key = *keyp;
273 return true;
274 } else if (is_tap_key(event.key)) {
275 // Sequential tap can be interfered with other tap key.
276 debug("Tapping: Start with interfering other tap.\n");
277 tapping_key = *keyp;
278 waiting_buffer_scan_tap();
279 debug_tapping_key();
280 return true;
281 } else {
282 // should none in buffer
283 // FIX: interrupted when other key is pressed
284 tapping_key.tap.interrupted = true;
285 process_record(keyp);
286 return true;
287 }
288 } else {
289 if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n");
290 process_record(keyp);
291 return true;
292 }
293 } else {
294 // FIX: process_action here?
295 // timeout. no sequential tap.
296 debug("Tapping: End(Timeout after releasing last tap): ");
297 debug_event(event);
298 debug("\n");
299 tapping_key = (keyrecord_t){};
300 debug_tapping_key();
301 return false;
302 }
303 }
304 // not tapping state
305 else {
306 if (event.pressed && is_tap_key(event.key)) {
307 debug("Tapping: Start(Press tap key).\n");
308 tapping_key = *keyp;
309 process_record_tap_hint(&tapping_key);
310 waiting_buffer_scan_tap();
311 debug_tapping_key();
312 return true;
313 } else {
314 process_record(keyp);
315 return true;
316 }
317 }
318}
319
320/** \brief Waiting buffer enq
321 *
322 * FIXME: Needs docs
323 */
324bool waiting_buffer_enq(keyrecord_t record) {
325 if (IS_NOEVENT(record.event)) {
326 return true;
327 }
328
329 if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) {
330 debug("waiting_buffer_enq: Over flow.\n");
331 return false;
332 }
333
334 waiting_buffer[waiting_buffer_head] = record;
335 waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
336
337 debug("waiting_buffer_enq: ");
338 debug_waiting_buffer();
339 return true;
340}
341
342/** \brief Waiting buffer clear
343 *
344 * FIXME: Needs docs
345 */
346void waiting_buffer_clear(void) {
347 waiting_buffer_head = 0;
348 waiting_buffer_tail = 0;
349}
350
351/** \brief Waiting buffer typed
352 *
353 * FIXME: Needs docs
354 */
355bool waiting_buffer_typed(keyevent_t event) {
356 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
357 if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
358 return true;
359 }
360 }
361 return false;
362}
363
364/** \brief Waiting buffer has anykey pressed
365 *
366 * FIXME: Needs docs
367 */
368__attribute__((unused)) bool waiting_buffer_has_anykey_pressed(void) {
369 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
370 if (waiting_buffer[i].event.pressed) return true;
371 }
372 return false;
373}
374
375/** \brief Scan buffer for tapping
376 *
377 * FIXME: Needs docs
378 */
379void waiting_buffer_scan_tap(void) {
380 // tapping already is settled
381 if (tapping_key.tap.count > 0) return;
382 // invalid state: tapping_key released && tap.count == 0
383 if (!tapping_key.event.pressed) return;
384
385 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
386 if (IS_TAPPING_KEY(waiting_buffer[i].event.key) && !waiting_buffer[i].event.pressed && WITHIN_TAPPING_TERM(waiting_buffer[i].event)) {
387 tapping_key.tap.count = 1;
388 waiting_buffer[i].tap.count = 1;
389 process_record(&tapping_key);
390
391 debug("waiting_buffer_scan_tap: found at [");
392 debug_dec(i);
393 debug("]\n");
394 debug_waiting_buffer();
395 return;
396 }
397 }
398}
399
400/** \brief Tapping key debug print
401 *
402 * FIXME: Needs docs
403 */
404static void debug_tapping_key(void) {
405 debug("TAPPING_KEY=");
406 debug_record(tapping_key);
407 debug("\n");
408}
409
410/** \brief Waiting buffer debug print
411 *
412 * FIXME: Needs docs
413 */
414static void debug_waiting_buffer(void) {
415 debug("{ ");
416 for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
417 debug("[");
418 debug_dec(i);
419 debug("]=");
420 debug_record(waiting_buffer[i]);
421 debug(" ");
422 }
423 debug("}\n");
424}
425
426#endif
diff --git a/tmk_core/common/action_tapping.h b/tmk_core/common/action_tapping.h
deleted file mode 100644
index 893ccb1ce..000000000
--- a/tmk_core/common/action_tapping.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20/* period of tapping(ms) */
21#ifndef TAPPING_TERM
22# define TAPPING_TERM 200
23#endif
24
25/* tap count needed for toggling a feature */
26#ifndef TAPPING_TOGGLE
27# define TAPPING_TOGGLE 5
28#endif
29
30#define WAITING_BUFFER_SIZE 8
31
32#ifndef NO_ACTION_TAPPING
33uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
34void action_tapping_process(keyrecord_t record);
35
36uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record);
37bool get_permissive_hold(uint16_t keycode, keyrecord_t *record);
38bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record);
39bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record);
40bool get_retro_tapping(uint16_t keycode, keyrecord_t *record);
41#endif
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
deleted file mode 100644
index a57c8bf66..000000000
--- a/tmk_core/common/action_util.c
+++ /dev/null
@@ -1,427 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "host.h"
18#include "report.h"
19#include "debug.h"
20#include "action_util.h"
21#include "action_layer.h"
22#include "timer.h"
23#include "keycode_config.h"
24
25extern keymap_config_t keymap_config;
26
27static uint8_t real_mods = 0;
28static uint8_t weak_mods = 0;
29static uint8_t macro_mods = 0;
30
31#ifdef USB_6KRO_ENABLE
32# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
33# define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
34# define RO_INC(a) RO_ADD(a, 1)
35# define RO_DEC(a) RO_SUB(a, 1)
36static int8_t cb_head = 0;
37static int8_t cb_tail = 0;
38static int8_t cb_count = 0;
39#endif
40
41// TODO: pointer variable is not needed
42// report_keyboard_t keyboard_report = {};
43report_keyboard_t *keyboard_report = &(report_keyboard_t){};
44
45extern inline void add_key(uint8_t key);
46extern inline void del_key(uint8_t key);
47extern inline void clear_keys(void);
48
49#ifndef NO_ACTION_ONESHOT
50static uint8_t oneshot_mods = 0;
51static uint8_t oneshot_locked_mods = 0;
52uint8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; }
53void set_oneshot_locked_mods(uint8_t mods) {
54 if (mods != oneshot_locked_mods) {
55 oneshot_locked_mods = mods;
56 oneshot_locked_mods_changed_kb(oneshot_locked_mods);
57 }
58}
59void clear_oneshot_locked_mods(void) {
60 if (oneshot_locked_mods) {
61 oneshot_locked_mods = 0;
62 oneshot_locked_mods_changed_kb(oneshot_locked_mods);
63 }
64}
65# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
66static uint16_t oneshot_time = 0;
67bool has_oneshot_mods_timed_out(void) { return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; }
68# else
69bool has_oneshot_mods_timed_out(void) { return false; }
70# endif
71#endif
72
73/* oneshot layer */
74#ifndef NO_ACTION_ONESHOT
75/** \brief oneshot_layer_data bits
76 * LLLL LSSS
77 * where:
78 * L => are layer bits
79 * S => oneshot state bits
80 */
81static int8_t oneshot_layer_data = 0;
82
83inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
84inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
85
86# ifdef SWAP_HANDS_ENABLE
87enum {
88 SHO_OFF,
89 SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet
90 SHO_PRESSED, // Swap hands button is currently pressed
91 SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys
92} swap_hands_oneshot = SHO_OFF;
93# endif
94
95# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
96static uint16_t oneshot_layer_time = 0;
97inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); }
98# ifdef SWAP_HANDS_ENABLE
99static uint16_t oneshot_swaphands_time = 0;
100inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE); }
101# endif
102# endif
103
104# ifdef SWAP_HANDS_ENABLE
105
106void set_oneshot_swaphands(void) {
107 swap_hands_oneshot = SHO_PRESSED;
108 swap_hands = true;
109# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
110 oneshot_swaphands_time = timer_read();
111 if (oneshot_layer_time != 0) {
112 oneshot_layer_time = oneshot_swaphands_time;
113 }
114# endif
115}
116
117void release_oneshot_swaphands(void) {
118 if (swap_hands_oneshot == SHO_PRESSED) {
119 swap_hands_oneshot = SHO_ACTIVE;
120 }
121 if (swap_hands_oneshot == SHO_USED) {
122 clear_oneshot_swaphands();
123 }
124}
125
126void use_oneshot_swaphands(void) {
127 if (swap_hands_oneshot == SHO_PRESSED) {
128 swap_hands_oneshot = SHO_USED;
129 }
130 if (swap_hands_oneshot == SHO_ACTIVE) {
131 clear_oneshot_swaphands();
132 }
133}
134
135void clear_oneshot_swaphands(void) {
136 swap_hands_oneshot = SHO_OFF;
137 swap_hands = false;
138# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
139 oneshot_swaphands_time = 0;
140# endif
141}
142
143# endif
144
145/** \brief Set oneshot layer
146 *
147 * FIXME: needs doc
148 */
149void set_oneshot_layer(uint8_t layer, uint8_t state) {
150 if (!keymap_config.oneshot_disable) {
151 oneshot_layer_data = layer << 3 | state;
152 layer_on(layer);
153# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
154 oneshot_layer_time = timer_read();
155# endif
156 oneshot_layer_changed_kb(get_oneshot_layer());
157 } else {
158 layer_on(layer);
159 }
160}
161/** \brief Reset oneshot layer
162 *
163 * FIXME: needs doc
164 */
165void reset_oneshot_layer(void) {
166 oneshot_layer_data = 0;
167# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
168 oneshot_layer_time = 0;
169# endif
170 oneshot_layer_changed_kb(get_oneshot_layer());
171}
172/** \brief Clear oneshot layer
173 *
174 * FIXME: needs doc
175 */
176void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
177 uint8_t start_state = oneshot_layer_data;
178 oneshot_layer_data &= ~state;
179 if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) {
180 layer_off(get_oneshot_layer());
181 reset_oneshot_layer();
182 }
183}
184/** \brief Is oneshot layer active
185 *
186 * FIXME: needs doc
187 */
188bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); }
189
190/** \brief set oneshot
191 *
192 * FIXME: needs doc
193 */
194void oneshot_set(bool active) {
195 if (keymap_config.oneshot_disable != active) {
196 keymap_config.oneshot_disable = active;
197 eeconfig_update_keymap(keymap_config.raw);
198 dprintf("Oneshot: active: %d\n", active);
199 }
200}
201
202/** \brief toggle oneshot
203 *
204 * FIXME: needs doc
205 */
206void oneshot_toggle(void) { oneshot_set(!keymap_config.oneshot_disable); }
207
208/** \brief enable oneshot
209 *
210 * FIXME: needs doc
211 */
212void oneshot_enable(void) { oneshot_set(true); }
213
214/** \brief disable oneshot
215 *
216 * FIXME: needs doc
217 */
218void oneshot_disable(void) { oneshot_set(false); }
219
220bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; }
221
222#endif
223
224/** \brief Send keyboard report
225 *
226 * FIXME: needs doc
227 */
228void send_keyboard_report(void) {
229 keyboard_report->mods = real_mods;
230 keyboard_report->mods |= weak_mods;
231 keyboard_report->mods |= macro_mods;
232#ifndef NO_ACTION_ONESHOT
233 if (oneshot_mods) {
234# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
235 if (has_oneshot_mods_timed_out()) {
236 dprintf("Oneshot: timeout\n");
237 clear_oneshot_mods();
238 }
239# endif
240 keyboard_report->mods |= oneshot_mods;
241 if (has_anykey(keyboard_report)) {
242 clear_oneshot_mods();
243 }
244 }
245
246#endif
247 host_keyboard_send(keyboard_report);
248}
249
250/** \brief Get mods
251 *
252 * FIXME: needs doc
253 */
254uint8_t get_mods(void) { return real_mods; }
255/** \brief add mods
256 *
257 * FIXME: needs doc
258 */
259void add_mods(uint8_t mods) { real_mods |= mods; }
260/** \brief del mods
261 *
262 * FIXME: needs doc
263 */
264void del_mods(uint8_t mods) { real_mods &= ~mods; }
265/** \brief set mods
266 *
267 * FIXME: needs doc
268 */
269void set_mods(uint8_t mods) { real_mods = mods; }
270/** \brief clear mods
271 *
272 * FIXME: needs doc
273 */
274void clear_mods(void) { real_mods = 0; }
275
276/** \brief get weak mods
277 *
278 * FIXME: needs doc
279 */
280uint8_t get_weak_mods(void) { return weak_mods; }
281/** \brief add weak mods
282 *
283 * FIXME: needs doc
284 */
285void add_weak_mods(uint8_t mods) { weak_mods |= mods; }
286/** \brief del weak mods
287 *
288 * FIXME: needs doc
289 */
290void del_weak_mods(uint8_t mods) { weak_mods &= ~mods; }
291/** \brief set weak mods
292 *
293 * FIXME: needs doc
294 */
295void set_weak_mods(uint8_t mods) { weak_mods = mods; }
296/** \brief clear weak mods
297 *
298 * FIXME: needs doc
299 */
300void clear_weak_mods(void) { weak_mods = 0; }
301
302/* macro modifier */
303/** \brief get macro mods
304 *
305 * FIXME: needs doc
306 */
307uint8_t get_macro_mods(void) { return macro_mods; }
308/** \brief add macro mods
309 *
310 * FIXME: needs doc
311 */
312void add_macro_mods(uint8_t mods) { macro_mods |= mods; }
313/** \brief del macro mods
314 *
315 * FIXME: needs doc
316 */
317void del_macro_mods(uint8_t mods) { macro_mods &= ~mods; }
318/** \brief set macro mods
319 *
320 * FIXME: needs doc
321 */
322void set_macro_mods(uint8_t mods) { macro_mods = mods; }
323/** \brief clear macro mods
324 *
325 * FIXME: needs doc
326 */
327void clear_macro_mods(void) { macro_mods = 0; }
328
329#ifndef NO_ACTION_ONESHOT
330/** \brief get oneshot mods
331 *
332 * FIXME: needs doc
333 */
334uint8_t get_oneshot_mods(void) { return oneshot_mods; }
335
336void add_oneshot_mods(uint8_t mods) {
337 if ((oneshot_mods & mods) != mods) {
338# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
339 oneshot_time = timer_read();
340# endif
341 oneshot_mods |= mods;
342 oneshot_mods_changed_kb(mods);
343 }
344}
345
346void del_oneshot_mods(uint8_t mods) {
347 if (oneshot_mods & mods) {
348 oneshot_mods &= ~mods;
349# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
350 oneshot_time = oneshot_mods ? timer_read() : 0;
351# endif
352 oneshot_mods_changed_kb(oneshot_mods);
353 }
354}
355
356/** \brief set oneshot mods
357 *
358 * FIXME: needs doc
359 */
360void set_oneshot_mods(uint8_t mods) {
361 if (!keymap_config.oneshot_disable) {
362 if (oneshot_mods != mods) {
363# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
364 oneshot_time = timer_read();
365# endif
366 oneshot_mods = mods;
367 oneshot_mods_changed_kb(mods);
368 }
369 }
370}
371
372/** \brief clear oneshot mods
373 *
374 * FIXME: needs doc
375 */
376void clear_oneshot_mods(void) {
377 if (oneshot_mods) {
378 oneshot_mods = 0;
379# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
380 oneshot_time = 0;
381# endif
382 oneshot_mods_changed_kb(oneshot_mods);
383 }
384}
385#endif
386
387/** \brief Called when the one shot modifiers have been changed.
388 *
389 * \param mods Contains the active modifiers active after the change.
390 */
391__attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {}
392
393/** \brief Called when the locked one shot modifiers have been changed.
394 *
395 * \param mods Contains the active modifiers active after the change.
396 */
397__attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) { oneshot_locked_mods_changed_user(mods); }
398
399/** \brief Called when the one shot modifiers have been changed.
400 *
401 * \param mods Contains the active modifiers active after the change.
402 */
403__attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {}
404
405/** \brief Called when the one shot modifiers have been changed.
406 *
407 * \param mods Contains the active modifiers active after the change.
408 */
409__attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) { oneshot_mods_changed_user(mods); }
410
411/** \brief Called when the one shot layers have been changed.
412 *
413 * \param layer Contains the layer that is toggled on, or zero when toggled off.
414 */
415__attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {}
416
417/** \brief Called when the one shot layers have been changed.
418 *
419 * \param layer Contains the layer that is toggled on, or zero when toggled off.
420 */
421__attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) { oneshot_layer_changed_user(layer); }
422
423/** \brief inspect keyboard state
424 *
425 * FIXME: needs doc
426 */
427uint8_t has_anymod(void) { return bitpop(real_mods); }
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h
deleted file mode 100644
index f2b3897ae..000000000
--- a/tmk_core/common/action_util.h
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include "report.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27extern report_keyboard_t *keyboard_report;
28
29void send_keyboard_report(void);
30
31/* key */
32inline void add_key(uint8_t key) { add_key_to_report(keyboard_report, key); }
33
34inline void del_key(uint8_t key) { del_key_from_report(keyboard_report, key); }
35
36inline void clear_keys(void) { clear_keys_from_report(keyboard_report); }
37
38/* modifier */
39uint8_t get_mods(void);
40void add_mods(uint8_t mods);
41void del_mods(uint8_t mods);
42void set_mods(uint8_t mods);
43void clear_mods(void);
44
45/* weak modifier */
46uint8_t get_weak_mods(void);
47void add_weak_mods(uint8_t mods);
48void del_weak_mods(uint8_t mods);
49void set_weak_mods(uint8_t mods);
50void clear_weak_mods(void);
51
52/* macro modifier */
53uint8_t get_macro_mods(void);
54void add_macro_mods(uint8_t mods);
55void del_macro_mods(uint8_t mods);
56void set_macro_mods(uint8_t mods);
57void clear_macro_mods(void);
58
59/* oneshot modifier */
60uint8_t get_oneshot_mods(void);
61void add_oneshot_mods(uint8_t mods);
62void del_oneshot_mods(uint8_t mods);
63void set_oneshot_mods(uint8_t mods);
64void clear_oneshot_mods(void);
65bool has_oneshot_mods_timed_out(void);
66
67uint8_t get_oneshot_locked_mods(void);
68void set_oneshot_locked_mods(uint8_t mods);
69void clear_oneshot_locked_mods(void);
70
71typedef enum { ONESHOT_PRESSED = 0b01, ONESHOT_OTHER_KEY_PRESSED = 0b10, ONESHOT_START = 0b11, ONESHOT_TOGGLED = 0b100 } oneshot_fullfillment_t;
72void set_oneshot_layer(uint8_t layer, uint8_t state);
73uint8_t get_oneshot_layer(void);
74void clear_oneshot_layer_state(oneshot_fullfillment_t state);
75void reset_oneshot_layer(void);
76bool is_oneshot_layer_active(void);
77uint8_t get_oneshot_layer_state(void);
78bool has_oneshot_layer_timed_out(void);
79bool has_oneshot_swaphands_timed_out(void);
80
81void oneshot_locked_mods_changed_user(uint8_t mods);
82void oneshot_locked_mods_changed_kb(uint8_t mods);
83void oneshot_mods_changed_user(uint8_t mods);
84void oneshot_mods_changed_kb(uint8_t mods);
85void oneshot_layer_changed_user(uint8_t layer);
86void oneshot_layer_changed_kb(uint8_t layer);
87
88void oneshot_toggle(void);
89void oneshot_enable(void);
90void oneshot_disable(void);
91bool is_oneshot_enabled(void);
92
93/* inspect */
94uint8_t has_anymod(void);
95
96#ifdef SWAP_HANDS_ENABLE
97void set_oneshot_swaphands(void);
98void release_oneshot_swaphands(void);
99void use_oneshot_swaphands(void);
100void clear_oneshot_swaphands(void);
101#endif
102
103#ifdef __cplusplus
104}
105#endif
diff --git a/tmk_core/common/arm_atsam/_timer.h b/tmk_core/common/arm_atsam/_timer.h
new file mode 100644
index 000000000..77402b612
--- /dev/null
+++ b/tmk_core/common/arm_atsam/_timer.h
@@ -0,0 +1,19 @@
1/* Copyright 2021 Simon Arlott
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#pragma once
17
18// The platform is 32-bit, so prefer 32-bit timers to avoid overflow
19#define FAST_TIMER_T_SIZE 32
diff --git a/tmk_core/common/arm_atsam/platform.c b/tmk_core/common/arm_atsam/platform.c
new file mode 100644
index 000000000..3e35b4fe4
--- /dev/null
+++ b/tmk_core/common/arm_atsam/platform.c
@@ -0,0 +1,21 @@
1/* Copyright 2021 QMK
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 3 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#include "platform_deps.h"
18
19void platform_setup(void) {
20 // do nothing
21}
diff --git a/tmk_core/common/avr/_timer.h b/tmk_core/common/avr/_timer.h
new file mode 100644
index 000000000..b81e0f68b
--- /dev/null
+++ b/tmk_core/common/avr/_timer.h
@@ -0,0 +1,19 @@
1/* Copyright 2021 Simon Arlott
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#pragma once
17
18// The platform is 8-bit, so prefer 16-bit timers to reduce code size
19#define FAST_TIMER_T_SIZE 16
diff --git a/tmk_core/common/avr/_wait.h b/tmk_core/common/avr/_wait.h
index 56eb316fa..ae1a25131 100644
--- a/tmk_core/common/avr/_wait.h
+++ b/tmk_core/common/avr/_wait.h
@@ -17,8 +17,26 @@
17 17
18#include <util/delay.h> 18#include <util/delay.h>
19 19
20#define wait_ms(ms) _delay_ms(ms) 20#define wait_ms(ms) \
21#define wait_us(us) _delay_us(us) 21 do { \
22 if (__builtin_constant_p(ms)) { \
23 _delay_ms(ms); \
24 } else { \
25 for (uint16_t i = ms; i > 0; i--) { \
26 _delay_ms(1); \
27 } \
28 } \
29 } while (0)
30#define wait_us(us) \
31 do { \
32 if (__builtin_constant_p(us)) { \
33 _delay_us(us); \
34 } else { \
35 for (uint16_t i = us; i > 0; i--) { \
36 _delay_us(1); \
37 } \
38 } \
39 } while (0)
22 40
23/* The AVR series GPIOs have a one clock read delay for changes in the digital input signal. 41/* The AVR series GPIOs have a one clock read delay for changes in the digital input signal.
24 * But here's more margin to make it two clocks. */ 42 * But here's more margin to make it two clocks. */
diff --git a/tmk_core/common/avr/gpio.h b/tmk_core/common/avr/gpio.h
index 231556c29..e9be68491 100644
--- a/tmk_core/common/avr/gpio.h
+++ b/tmk_core/common/avr/gpio.h
@@ -20,6 +20,8 @@
20 20
21typedef uint8_t pin_t; 21typedef uint8_t pin_t;
22 22
23/* Operation of GPIO by pin. */
24
23#define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF)) 25#define setPinInput(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) &= ~_BV((pin)&0xF))
24#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF)) 26#define setPinInputHigh(pin) (DDRx_ADDRESS(pin) &= ~_BV((pin)&0xF), PORTx_ADDRESS(pin) |= _BV((pin)&0xF))
25#define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low") 27#define setPinInputLow(pin) _Static_assert(0, "AVR processors cannot implement an input as pull low")
@@ -32,3 +34,16 @@ typedef uint8_t pin_t;
32#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF))) 34#define readPin(pin) ((bool)(PINx_ADDRESS(pin) & _BV((pin)&0xF)))
33 35
34#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF)) 36#define togglePin(pin) (PORTx_ADDRESS(pin) ^= _BV((pin)&0xF))
37
38/* Operation of GPIO by port. */
39
40typedef uint8_t port_data_t;
41
42#define readPort(port) PINx_ADDRESS(port)
43
44#define setPortBitInput(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) &= ~_BV((bit)&0xF))
45#define setPortBitInputHigh(port, bit) (DDRx_ADDRESS(port) &= ~_BV((bit)&0xF), PORTx_ADDRESS(port) |= _BV((bit)&0xF))
46#define setPortBitOutput(port, bit) (DDRx_ADDRESS(port) |= _BV((bit)&0xF))
47
48#define writePortBitLow(port, bit) (PORTx_ADDRESS(port) &= ~_BV((bit)&0xF))
49#define writePortBitHigh(port, bit) (PORTx_ADDRESS(port) |= _BV((bit)&0xF))
diff --git a/tmk_core/common/avr/platform.c b/tmk_core/common/avr/platform.c
new file mode 100644
index 000000000..3e35b4fe4
--- /dev/null
+++ b/tmk_core/common/avr/platform.c
@@ -0,0 +1,21 @@
1/* Copyright 2021 QMK
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 3 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#include "platform_deps.h"
18
19void platform_setup(void) {
20 // do nothing
21}
diff --git a/tmk_core/common/chibios/_timer.h b/tmk_core/common/chibios/_timer.h
new file mode 100644
index 000000000..77402b612
--- /dev/null
+++ b/tmk_core/common/chibios/_timer.h
@@ -0,0 +1,19 @@
1/* Copyright 2021 Simon Arlott
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#pragma once
17
18// The platform is 32-bit, so prefer 32-bit timers to avoid overflow
19#define FAST_TIMER_T_SIZE 32
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c
index 11f7abf43..f9514ee5f 100644
--- a/tmk_core/common/chibios/bootloader.c
+++ b/tmk_core/common/chibios/bootloader.c
@@ -95,7 +95,7 @@ void enter_bootloader_mode_if_requested(void) {
95 } 95 }
96} 96}
97 97
98#elif defined(KL2x) || defined(K20x) || defined(MK66F18) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS 98#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
99/* Kinetis */ 99/* Kinetis */
100 100
101# if defined(BOOTLOADER_KIIBOHD) 101# if defined(BOOTLOADER_KIIBOHD)
@@ -103,7 +103,8 @@ void enter_bootloader_mode_if_requested(void) {
103# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 103# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
104const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; 104const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff";
105__attribute__((weak)) void bootloader_jump(void) { 105__attribute__((weak)) void bootloader_jump(void) {
106 __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); 106 void *volatile vbat = (void *)VBAT;
107 __builtin_memcpy(vbat, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
107 // request reset 108 // request reset
108 SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; 109 SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
109} 110}
diff --git a/tmk_core/common/chibios/gpio.h b/tmk_core/common/chibios/gpio.h
index 5d0e142ab..4d057f1ca 100644
--- a/tmk_core/common/chibios/gpio.h
+++ b/tmk_core/common/chibios/gpio.h
@@ -20,6 +20,8 @@
20 20
21typedef ioline_t pin_t; 21typedef ioline_t pin_t;
22 22
23/* Operation of GPIO by pin. */
24
23#define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT) 25#define setPinInput(pin) palSetLineMode(pin, PAL_MODE_INPUT)
24#define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP) 26#define setPinInputHigh(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)
25#define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN) 27#define setPinInputLow(pin) palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)
@@ -32,3 +34,17 @@ typedef ioline_t pin_t;
32#define readPin(pin) palReadLine(pin) 34#define readPin(pin) palReadLine(pin)
33 35
34#define togglePin(pin) palToggleLine(pin) 36#define togglePin(pin) palToggleLine(pin)
37
38/* Operation of GPIO by port. */
39
40typedef uint16_t port_data_t;
41
42#define readPort(pin) palReadPort(PAL_PORT(pin))
43
44#define setPortBitInput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT)
45#define setPortBitInputHigh(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLUP)
46#define setPortBitInputLow(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_INPUT_PULLDOWN)
47#define setPortBitOutput(pin, bit) palSetPadMode(PAL_PORT(pin), bit, PAL_MODE_OUTPUT_PUSHPULL)
48
49#define writePortBitLow(pin, bit) palClearLine(PAL_LINE(PAL_PORT(pin), bit))
50#define writePortBitHigh(pin, bit) palSetLine(PAL_LINE(PAL_PORT(pin), bit))
diff --git a/tmk_core/common/chibios/platform.c b/tmk_core/common/chibios/platform.c
new file mode 100644
index 000000000..d4a229f27
--- /dev/null
+++ b/tmk_core/common/chibios/platform.c
@@ -0,0 +1,22 @@
1/* Copyright 2021 QMK
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 3 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#include "platform_deps.h"
18
19void platform_setup(void) {
20 halInit();
21 chSysInit();
22} \ No newline at end of file
diff --git a/tmk_core/common/debug.c b/tmk_core/common/debug.c
deleted file mode 100644
index ea62deaa8..000000000
--- a/tmk_core/common/debug.c
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "debug.h"
18
19debug_config_t debug_config = {
20 .enable = false, //
21 .matrix = false, //
22 .keyboard = false, //
23 .mouse = false, //
24 .reserved = 0 //
25};
diff --git a/tmk_core/common/debug.h b/tmk_core/common/debug.h
deleted file mode 100644
index 3d2e2315e..000000000
--- a/tmk_core/common/debug.h
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdbool.h>
21#include "print.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27/*
28 * Debug output control
29 */
30typedef union {
31 struct {
32 bool enable : 1;
33 bool matrix : 1;
34 bool keyboard : 1;
35 bool mouse : 1;
36 uint8_t reserved : 4;
37 };
38 uint8_t raw;
39} debug_config_t;
40
41extern debug_config_t debug_config;
42
43#ifdef __cplusplus
44}
45#endif
46
47/* for backward compatibility */
48#define debug_enable (debug_config.enable)
49#define debug_matrix (debug_config.matrix)
50#define debug_keyboard (debug_config.keyboard)
51#define debug_mouse (debug_config.mouse)
52
53/*
54 * Debug print utils
55 */
56#ifndef NO_DEBUG
57
58# define dprint(s) \
59 do { \
60 if (debug_enable) print(s); \
61 } while (0)
62# define dprintln(s) \
63 do { \
64 if (debug_enable) println(s); \
65 } while (0)
66# define dprintf(fmt, ...) \
67 do { \
68 if (debug_enable) xprintf(fmt, ##__VA_ARGS__); \
69 } while (0)
70# define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s))
71
72/* Deprecated. DO NOT USE these anymore, use dprintf instead. */
73# define debug(s) \
74 do { \
75 if (debug_enable) print(s); \
76 } while (0)
77# define debugln(s) \
78 do { \
79 if (debug_enable) println(s); \
80 } while (0)
81# define debug_msg(s) \
82 do { \
83 if (debug_enable) { \
84 print(__FILE__); \
85 print(" at "); \
86 print_dec(__LINE__); \
87 print(" in "); \
88 print(": "); \
89 print(s); \
90 } \
91 } while (0)
92# define debug_dec(data) \
93 do { \
94 if (debug_enable) print_dec(data); \
95 } while (0)
96# define debug_decs(data) \
97 do { \
98 if (debug_enable) print_decs(data); \
99 } while (0)
100# define debug_hex4(data) \
101 do { \
102 if (debug_enable) print_hex4(data); \
103 } while (0)
104# define debug_hex8(data) \
105 do { \
106 if (debug_enable) print_hex8(data); \
107 } while (0)
108# define debug_hex16(data) \
109 do { \
110 if (debug_enable) print_hex16(data); \
111 } while (0)
112# define debug_hex32(data) \
113 do { \
114 if (debug_enable) print_hex32(data); \
115 } while (0)
116# define debug_bin8(data) \
117 do { \
118 if (debug_enable) print_bin8(data); \
119 } while (0)
120# define debug_bin16(data) \
121 do { \
122 if (debug_enable) print_bin16(data); \
123 } while (0)
124# define debug_bin32(data) \
125 do { \
126 if (debug_enable) print_bin32(data); \
127 } while (0)
128# define debug_bin_reverse8(data) \
129 do { \
130 if (debug_enable) print_bin_reverse8(data); \
131 } while (0)
132# define debug_bin_reverse16(data) \
133 do { \
134 if (debug_enable) print_bin_reverse16(data); \
135 } while (0)
136# define debug_bin_reverse32(data) \
137 do { \
138 if (debug_enable) print_bin_reverse32(data); \
139 } while (0)
140# define debug_hex(data) debug_hex8(data)
141# define debug_bin(data) debug_bin8(data)
142# define debug_bin_reverse(data) debug_bin8(data)
143
144#else /* NO_DEBUG */
145
146# define dprint(s)
147# define dprintln(s)
148# define dprintf(fmt, ...)
149# define dmsg(s)
150# define debug(s)
151# define debugln(s)
152# define debug_msg(s)
153# define debug_dec(data)
154# define debug_decs(data)
155# define debug_hex4(data)
156# define debug_hex8(data)
157# define debug_hex16(data)
158# define debug_hex32(data)
159# define debug_bin8(data)
160# define debug_bin16(data)
161# define debug_bin32(data)
162# define debug_bin_reverse8(data)
163# define debug_bin_reverse16(data)
164# define debug_bin_reverse32(data)
165# define debug_hex(data)
166# define debug_bin(data)
167# define debug_bin_reverse(data)
168
169#endif /* NO_DEBUG */
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
deleted file mode 100644
index ffa56ab56..000000000
--- a/tmk_core/common/eeconfig.c
+++ /dev/null
@@ -1,211 +0,0 @@
1#include <stdint.h>
2#include <stdbool.h>
3#include "eeprom.h"
4#include "eeconfig.h"
5#include "action_layer.h"
6
7#ifdef STM32_EEPROM_ENABLE
8# include <hal.h>
9# include "eeprom_stm32.h"
10#endif
11
12#if defined(EEPROM_DRIVER)
13# include "eeprom_driver.h"
14#endif
15
16#if defined(HAPTIC_ENABLE)
17# include "haptic.h"
18#endif
19
20/** \brief eeconfig enable
21 *
22 * FIXME: needs doc
23 */
24__attribute__((weak)) void eeconfig_init_user(void) {
25 // Reset user EEPROM value to blank, rather than to a set value
26 eeconfig_update_user(0);
27}
28
29__attribute__((weak)) void eeconfig_init_kb(void) {
30 // Reset Keyboard EEPROM value to blank, rather than to a set value
31 eeconfig_update_kb(0);
32
33 eeconfig_init_user();
34}
35
36/*
37 * FIXME: needs doc
38 */
39void eeconfig_init_quantum(void) {
40#ifdef STM32_EEPROM_ENABLE
41 EEPROM_Erase();
42#endif
43#if defined(EEPROM_DRIVER)
44 eeprom_driver_erase();
45#endif
46 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
47 eeprom_update_byte(EECONFIG_DEBUG, 0);
48 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
49 default_layer_state = 0;
50 eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, 0);
51 eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, 0);
52 eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
53 eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
54 eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
55 eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
56 eeprom_update_byte(EECONFIG_STENOMODE, 0);
57 eeprom_update_dword(EECONFIG_HAPTIC, 0);
58 eeprom_update_byte(EECONFIG_VELOCIKEY, 0);
59 eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
60 eeprom_update_word(EECONFIG_RGB_MATRIX_EXTENDED, 0);
61
62 // TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS
63 // within the emulated eeprom via dfu-util or another tool
64#if defined INIT_EE_HANDS_LEFT
65# pragma message "Faking EE_HANDS for left hand"
66 eeprom_update_byte(EECONFIG_HANDEDNESS, 1);
67#elif defined INIT_EE_HANDS_RIGHT
68# pragma message "Faking EE_HANDS for right hand"
69 eeprom_update_byte(EECONFIG_HANDEDNESS, 0);
70#endif
71
72#if defined(HAPTIC_ENABLE)
73 haptic_reset();
74#else
75 // this is used in case haptic is disabled, but we still want sane defaults
76 // in the haptic configuration eeprom. All zero will trigger a haptic_reset
77 // when a haptic-enabled firmware is loaded onto the keyboard.
78 eeprom_update_dword(EECONFIG_HAPTIC, 0);
79#endif
80
81 eeconfig_init_kb();
82}
83
84/** \brief eeconfig initialization
85 *
86 * FIXME: needs doc
87 */
88void eeconfig_init(void) { eeconfig_init_quantum(); }
89
90/** \brief eeconfig enable
91 *
92 * FIXME: needs doc
93 */
94void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); }
95
96/** \brief eeconfig disable
97 *
98 * FIXME: needs doc
99 */
100void eeconfig_disable(void) {
101#ifdef STM32_EEPROM_ENABLE
102 EEPROM_Erase();
103#endif
104#if defined(EEPROM_DRIVER)
105 eeprom_driver_erase();
106#endif
107 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
108}
109
110/** \brief eeconfig is enabled
111 *
112 * FIXME: needs doc
113 */
114bool eeconfig_is_enabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); }
115
116/** \brief eeconfig is disabled
117 *
118 * FIXME: needs doc
119 */
120bool eeconfig_is_disabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); }
121
122/** \brief eeconfig read debug
123 *
124 * FIXME: needs doc
125 */
126uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); }
127/** \brief eeconfig update debug
128 *
129 * FIXME: needs doc
130 */
131void eeconfig_update_debug(uint8_t val) { eeprom_update_byte(EECONFIG_DEBUG, val); }
132
133/** \brief eeconfig read default layer
134 *
135 * FIXME: needs doc
136 */
137uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); }
138/** \brief eeconfig update default layer
139 *
140 * FIXME: needs doc
141 */
142void eeconfig_update_default_layer(uint8_t val) { eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val); }
143
144/** \brief eeconfig read keymap
145 *
146 * FIXME: needs doc
147 */
148uint16_t eeconfig_read_keymap(void) { return (eeprom_read_byte(EECONFIG_KEYMAP_LOWER_BYTE) | (eeprom_read_byte(EECONFIG_KEYMAP_UPPER_BYTE) << 8)); }
149/** \brief eeconfig update keymap
150 *
151 * FIXME: needs doc
152 */
153void eeconfig_update_keymap(uint16_t val) {
154 eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, val & 0xFF);
155 eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, (val >> 8) & 0xFF);
156}
157
158/** \brief eeconfig read audio
159 *
160 * FIXME: needs doc
161 */
162uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO); }
163/** \brief eeconfig update audio
164 *
165 * FIXME: needs doc
166 */
167void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
168
169/** \brief eeconfig read kb
170 *
171 * FIXME: needs doc
172 */
173uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
174/** \brief eeconfig update kb
175 *
176 * FIXME: needs doc
177 */
178void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); }
179
180/** \brief eeconfig read user
181 *
182 * FIXME: needs doc
183 */
184uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
185/** \brief eeconfig update user
186 *
187 * FIXME: needs doc
188 */
189void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); }
190
191/** \brief eeconfig read haptic
192 *
193 * FIXME: needs doc
194 */
195uint32_t eeconfig_read_haptic(void) { return eeprom_read_dword(EECONFIG_HAPTIC); }
196/** \brief eeconfig update haptic
197 *
198 * FIXME: needs doc
199 */
200void eeconfig_update_haptic(uint32_t val) { eeprom_update_dword(EECONFIG_HAPTIC, val); }
201
202/** \brief eeconfig read split handedness
203 *
204 * FIXME: needs doc
205 */
206bool eeconfig_read_handedness(void) { return !!eeprom_read_byte(EECONFIG_HANDEDNESS); }
207/** \brief eeconfig update split handedness
208 *
209 * FIXME: needs doc
210 */
211void eeconfig_update_handedness(bool val) { eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); }
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
deleted file mode 100644
index a88071729..000000000
--- a/tmk_core/common/eeconfig.h
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include <stdbool.h>
22
23#ifndef EECONFIG_MAGIC_NUMBER
24# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEA // When changing, decrement this value to avoid future re-init issues
25#endif
26#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
27
28/* EEPROM parameter address */
29#define EECONFIG_MAGIC (uint16_t *)0
30#define EECONFIG_DEBUG (uint8_t *)2
31#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
32#define EECONFIG_KEYMAP (uint8_t *)4
33#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
34#define EECONFIG_BACKLIGHT (uint8_t *)6
35#define EECONFIG_AUDIO (uint8_t *)7
36#define EECONFIG_RGBLIGHT (uint32_t *)8
37#define EECONFIG_UNICODEMODE (uint8_t *)12
38#define EECONFIG_STENOMODE (uint8_t *)13
39// EEHANDS for two handed boards
40#define EECONFIG_HANDEDNESS (uint8_t *)14
41#define EECONFIG_KEYBOARD (uint32_t *)15
42#define EECONFIG_USER (uint32_t *)19
43#define EECONFIG_VELOCIKEY (uint8_t *)23
44
45#define EECONFIG_HAPTIC (uint32_t *)24
46
47// Mutually exclusive
48#define EECONFIG_LED_MATRIX (uint32_t *)28
49#define EECONFIG_RGB_MATRIX (uint32_t *)28
50// Speed & Flags
51#define EECONFIG_LED_MATRIX_EXTENDED (uint16_t *)32
52#define EECONFIG_RGB_MATRIX_EXTENDED (uint16_t *)32
53
54// TODO: Combine these into a single word and single block of EEPROM
55#define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)34
56// Size of EEPROM being used, other code can refer to this for available EEPROM
57#define EECONFIG_SIZE 35
58/* debug bit */
59#define EECONFIG_DEBUG_ENABLE (1 << 0)
60#define EECONFIG_DEBUG_MATRIX (1 << 1)
61#define EECONFIG_DEBUG_KEYBOARD (1 << 2)
62#define EECONFIG_DEBUG_MOUSE (1 << 3)
63
64/* keyconf bit */
65#define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1 << 0)
66#define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1 << 1)
67#define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1 << 2)
68#define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1 << 3)
69#define EECONFIG_KEYMAP_NO_GUI (1 << 4)
70#define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1 << 5)
71#define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1 << 6)
72#define EECONFIG_KEYMAP_NKRO (1 << 7)
73
74#define EECONFIG_KEYMAP_LOWER_BYTE EECONFIG_KEYMAP
75
76bool eeconfig_is_enabled(void);
77bool eeconfig_is_disabled(void);
78
79void eeconfig_init(void);
80void eeconfig_init_quantum(void);
81void eeconfig_init_kb(void);
82void eeconfig_init_user(void);
83
84void eeconfig_enable(void);
85
86void eeconfig_disable(void);
87
88uint8_t eeconfig_read_debug(void);
89void eeconfig_update_debug(uint8_t val);
90
91uint8_t eeconfig_read_default_layer(void);
92void eeconfig_update_default_layer(uint8_t val);
93
94uint16_t eeconfig_read_keymap(void);
95void eeconfig_update_keymap(uint16_t val);
96
97#ifdef AUDIO_ENABLE
98uint8_t eeconfig_read_audio(void);
99void eeconfig_update_audio(uint8_t val);
100#endif
101
102uint32_t eeconfig_read_kb(void);
103void eeconfig_update_kb(uint32_t val);
104uint32_t eeconfig_read_user(void);
105void eeconfig_update_user(uint32_t val);
106
107#ifdef HAPTIC_ENABLE
108uint32_t eeconfig_read_haptic(void);
109void eeconfig_update_haptic(uint32_t val);
110#endif
111
112bool eeconfig_read_handedness(void);
113void eeconfig_update_handedness(bool val);
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index e7d92cfac..f0c396b18 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -17,10 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18#include <stdint.h> 18#include <stdint.h>
19//#include <avr/interrupt.h> 19//#include <avr/interrupt.h>
20#include "keyboard.h"
20#include "keycode.h" 21#include "keycode.h"
21#include "host.h" 22#include "host.h"
22#include "util.h" 23#include "util.h"
23#include "debug.h" 24#include "debug.h"
25#include "digitizer.h"
24 26
25#ifdef NKRO_ENABLE 27#ifdef NKRO_ENABLE
26# include "keycode_config.h" 28# include "keycode_config.h"
@@ -35,15 +37,20 @@ void host_set_driver(host_driver_t *d) { driver = d; }
35 37
36host_driver_t *host_get_driver(void) { return driver; } 38host_driver_t *host_get_driver(void) { return driver; }
37 39
40#ifdef SPLIT_KEYBOARD
41uint8_t split_led_state = 0;
42void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; }
43#endif
44
38uint8_t host_keyboard_leds(void) { 45uint8_t host_keyboard_leds(void) {
46#ifdef SPLIT_KEYBOARD
47 if (!is_keyboard_master()) return split_led_state;
48#endif
39 if (!driver) return 0; 49 if (!driver) return 0;
40 return (*driver->keyboard_leds)(); 50 return (*driver->keyboard_leds)();
41} 51}
42 52
43led_t host_keyboard_led_state(void) { 53led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); }
44 if (!driver) return (led_t){0};
45 return (led_t)((*driver->keyboard_leds)());
46}
47 54
48/* send report */ 55/* send report */
49void host_keyboard_send(report_keyboard_t *report) { 56void host_keyboard_send(report_keyboard_t *report) {
@@ -97,6 +104,24 @@ void host_consumer_send(uint16_t report) {
97 (*driver->send_consumer)(report); 104 (*driver->send_consumer)(report);
98} 105}
99 106
107void host_digitizer_send(digitizer_t *digitizer) {
108 if (!driver) return;
109
110 report_digitizer_t report = {
111#ifdef DIGITIZER_SHARED_EP
112 .report_id = REPORT_ID_DIGITIZER,
113#endif
114 .tip = digitizer->tipswitch & 0x1,
115 .inrange = digitizer->inrange & 0x1,
116 .x = (uint16_t)(digitizer->x * 0x7FFF),
117 .y = (uint16_t)(digitizer->y * 0x7FFF),
118 };
119
120 send_digitizer(&report);
121}
122
123__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
124
100uint16_t host_last_system_report(void) { return last_system_report; } 125uint16_t host_last_system_report(void) { return last_system_report; }
101 126
102uint16_t host_last_consumer_report(void) { return last_consumer_report; } 127uint16_t host_last_consumer_report(void) { return last_consumer_report; }
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h
index f34a22053..2aebca043 100644
--- a/tmk_core/common/host_driver.h
+++ b/tmk_core/common/host_driver.h
@@ -30,3 +30,5 @@ typedef struct {
30 void (*send_system)(uint16_t); 30 void (*send_system)(uint16_t);
31 void (*send_consumer)(uint16_t); 31 void (*send_consumer)(uint16_t);
32} host_driver_t; 32} host_driver_t;
33
34void send_digitizer(report_digitizer_t *report); \ No newline at end of file
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
deleted file mode 100644
index 3d6092e71..000000000
--- a/tmk_core/common/keyboard.c
+++ /dev/null
@@ -1,534 +0,0 @@
1/*
2Copyright 2011, 2012, 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <stdint.h>
19#include "keyboard.h"
20#include "matrix.h"
21#include "keymap.h"
22#include "host.h"
23#include "led.h"
24#include "keycode.h"
25#include "timer.h"
26#include "sync_timer.h"
27#include "print.h"
28#include "debug.h"
29#include "command.h"
30#include "util.h"
31#include "sendchar.h"
32#include "eeconfig.h"
33#include "action_layer.h"
34#ifdef BACKLIGHT_ENABLE
35# include "backlight.h"
36#endif
37#ifdef MOUSEKEY_ENABLE
38# include "mousekey.h"
39#endif
40#ifdef PS2_MOUSE_ENABLE
41# include "ps2_mouse.h"
42#endif
43#ifdef SERIAL_MOUSE_ENABLE
44# include "serial_mouse.h"
45#endif
46#ifdef ADB_MOUSE_ENABLE
47# include "adb.h"
48#endif
49#ifdef RGBLIGHT_ENABLE
50# include "rgblight.h"
51#endif
52#ifdef LED_MATRIX_ENABLE
53# include "led_matrix.h"
54#endif
55#ifdef RGB_MATRIX_ENABLE
56# include "rgb_matrix.h"
57#endif
58#ifdef ENCODER_ENABLE
59# include "encoder.h"
60#endif
61#ifdef STENO_ENABLE
62# include "process_steno.h"
63#endif
64#ifdef SERIAL_LINK_ENABLE
65# include "serial_link/system/serial_link.h"
66#endif
67#ifdef VISUALIZER_ENABLE
68# include "visualizer/visualizer.h"
69#endif
70#ifdef POINTING_DEVICE_ENABLE
71# include "pointing_device.h"
72#endif
73#ifdef MIDI_ENABLE
74# include "process_midi.h"
75#endif
76#ifdef JOYSTICK_ENABLE
77# include "process_joystick.h"
78#endif
79#ifdef HD44780_ENABLE
80# include "hd44780.h"
81#endif
82#ifdef QWIIC_ENABLE
83# include "qwiic.h"
84#endif
85#ifdef OLED_DRIVER_ENABLE
86# include "oled_driver.h"
87#endif
88#ifdef VELOCIKEY_ENABLE
89# include "velocikey.h"
90#endif
91#ifdef VIA_ENABLE
92# include "via.h"
93#endif
94#ifdef DIP_SWITCH_ENABLE
95# include "dip_switch.h"
96#endif
97#ifdef STM32_EEPROM_ENABLE
98# include "eeprom_stm32.h"
99#endif
100#ifdef EEPROM_DRIVER
101# include "eeprom_driver.h"
102#endif
103
104static uint32_t last_input_modification_time = 0;
105uint32_t last_input_activity_time(void) { return last_input_modification_time; }
106uint32_t last_input_activity_elapsed(void) { return timer_elapsed32(last_input_modification_time); }
107
108static uint32_t last_matrix_modification_time = 0;
109uint32_t last_matrix_activity_time(void) { return last_matrix_modification_time; }
110uint32_t last_matrix_activity_elapsed(void) { return timer_elapsed32(last_matrix_modification_time); }
111void last_matrix_activity_trigger(void) { last_matrix_modification_time = last_input_modification_time = timer_read32(); }
112
113static uint32_t last_encoder_modification_time = 0;
114uint32_t last_encoder_activity_time(void) { return last_encoder_modification_time; }
115uint32_t last_encoder_activity_elapsed(void) { return timer_elapsed32(last_encoder_modification_time); }
116void last_encoder_activity_trigger(void) { last_encoder_modification_time = last_input_modification_time = timer_read32(); }
117
118// Only enable this if console is enabled to print to
119#if defined(DEBUG_MATRIX_SCAN_RATE)
120static uint32_t matrix_timer = 0;
121static uint32_t matrix_scan_count = 0;
122static uint32_t last_matrix_scan_count = 0;
123
124void matrix_scan_perf_task(void) {
125 matrix_scan_count++;
126
127 uint32_t timer_now = timer_read32();
128 if (TIMER_DIFF_32(timer_now, matrix_timer) > 1000) {
129# if defined(CONSOLE_ENABLE)
130 dprintf("matrix scan frequency: %lu\n", matrix_scan_count);
131# endif
132 last_matrix_scan_count = matrix_scan_count;
133 matrix_timer = timer_now;
134 matrix_scan_count = 0;
135 }
136}
137
138uint32_t get_matrix_scan_rate(void) { return last_matrix_scan_count; }
139#else
140# define matrix_scan_perf_task()
141#endif
142
143#ifdef MATRIX_HAS_GHOST
144extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
145static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) {
146 matrix_row_t out = 0;
147 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
148 // read each key in the row data and check if the keymap defines it as a real key
149 if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1 << col))) {
150 // this creates new row data, if a key is defined in the keymap, it will be set here
151 out |= 1 << col;
152 }
153 }
154 return out;
155}
156
157static inline bool popcount_more_than_one(matrix_row_t rowdata) {
158 rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero
159 return rowdata;
160}
161
162static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) {
163 /* No ghost exists when less than 2 keys are down on the row.
164 If there are "active" blanks in the matrix, the key can't be pressed by the user,
165 there is no doubt as to which keys are really being pressed.
166 The ghosts will be ignored, they are KC_NO. */
167 rowdata = get_real_keys(row, rowdata);
168 if ((popcount_more_than_one(rowdata)) == 0) {
169 return false;
170 }
171 /* Ghost occurs when the row shares a column line with other row,
172 and two columns are read on each row. Blanks in the matrix don't matter,
173 so they are filtered out.
174 If there are two or more real keys pressed and they match columns with
175 at least two of another row's real keys, the row will be ignored. Keep in mind,
176 we are checking one row at a time, not all of them at once.
177 */
178 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
179 if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) {
180 return true;
181 }
182 }
183 return false;
184}
185
186#endif
187
188void disable_jtag(void) {
189// To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles.
190#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
191 MCUCR |= _BV(JTD);
192 MCUCR |= _BV(JTD);
193#elif defined(__AVR_ATmega32A__)
194 MCUCSR |= _BV(JTD);
195 MCUCSR |= _BV(JTD);
196#endif
197}
198
199/** \brief matrix_setup
200 *
201 * FIXME: needs doc
202 */
203__attribute__((weak)) void matrix_setup(void) {}
204
205/** \brief keyboard_pre_init_user
206 *
207 * FIXME: needs doc
208 */
209__attribute__((weak)) void keyboard_pre_init_user(void) {}
210
211/** \brief keyboard_pre_init_kb
212 *
213 * FIXME: needs doc
214 */
215__attribute__((weak)) void keyboard_pre_init_kb(void) { keyboard_pre_init_user(); }
216
217/** \brief keyboard_post_init_user
218 *
219 * FIXME: needs doc
220 */
221
222__attribute__((weak)) void keyboard_post_init_user() {}
223
224/** \brief keyboard_post_init_kb
225 *
226 * FIXME: needs doc
227 */
228
229__attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user(); }
230
231/** \brief keyboard_setup
232 *
233 * FIXME: needs doc
234 */
235void keyboard_setup(void) {
236#ifndef NO_JTAG_DISABLE
237 disable_jtag();
238#endif
239 print_set_sendchar(sendchar);
240#ifdef STM32_EEPROM_ENABLE
241 EEPROM_Init();
242#endif
243#ifdef EEPROM_DRIVER
244 eeprom_driver_init();
245#endif
246 matrix_setup();
247 keyboard_pre_init_kb();
248}
249
250/** \brief is_keyboard_master
251 *
252 * FIXME: needs doc
253 */
254__attribute__((weak)) bool is_keyboard_master(void) { return true; }
255
256/** \brief is_keyboard_left
257 *
258 * FIXME: needs doc
259 */
260__attribute__((weak)) bool is_keyboard_left(void) { return true; }
261
262/** \brief should_process_keypress
263 *
264 * Override this function if you have a condition where keypresses processing should change:
265 * - splits where the slave side needs to process for rgb/oled functionality
266 */
267__attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master(); }
268
269/** \brief housekeeping_task_kb
270 *
271 * Override this function if you have a need to execute code for every keyboard main loop iteration.
272 * This is specific to keyboard-level functionality.
273 */
274__attribute__((weak)) void housekeeping_task_kb(void) {}
275
276/** \brief housekeeping_task_user
277 *
278 * Override this function if you have a need to execute code for every keyboard main loop iteration.
279 * This is specific to user/keymap-level functionality.
280 */
281__attribute__((weak)) void housekeeping_task_user(void) {}
282
283/** \brief housekeeping_task
284 *
285 * Invokes hooks for executing code after QMK is done after each loop iteration.
286 */
287void housekeeping_task(void) {
288 housekeeping_task_kb();
289 housekeeping_task_user();
290}
291
292/** \brief keyboard_init
293 *
294 * FIXME: needs doc
295 */
296void keyboard_init(void) {
297 timer_init();
298 sync_timer_init();
299 matrix_init();
300#ifdef VIA_ENABLE
301 via_init();
302#endif
303#ifdef QWIIC_ENABLE
304 qwiic_init();
305#endif
306#ifdef OLED_DRIVER_ENABLE
307 oled_init(OLED_ROTATION_0);
308#endif
309#ifdef PS2_MOUSE_ENABLE
310 ps2_mouse_init();
311#endif
312#ifdef SERIAL_MOUSE_ENABLE
313 serial_mouse_init();
314#endif
315#ifdef ADB_MOUSE_ENABLE
316 adb_mouse_init();
317#endif
318#ifdef BACKLIGHT_ENABLE
319 backlight_init();
320#endif
321#ifdef RGBLIGHT_ENABLE
322 rgblight_init();
323#endif
324#ifdef ENCODER_ENABLE
325 encoder_init();
326#endif
327#ifdef STENO_ENABLE
328 steno_init();
329#endif
330#ifdef POINTING_DEVICE_ENABLE
331 pointing_device_init();
332#endif
333#if defined(NKRO_ENABLE) && defined(FORCE_NKRO)
334 keymap_config.nkro = 1;
335 eeconfig_update_keymap(keymap_config.raw);
336#endif
337#ifdef DIP_SWITCH_ENABLE
338 dip_switch_init();
339#endif
340
341#if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
342 debug_enable = true;
343#endif
344
345 keyboard_post_init_kb(); /* Always keep this last */
346}
347
348/** \brief key_event_task
349 *
350 * This function is responsible for calling into other systems when they need to respond to electrical switch press events.
351 * This is differnet than keycode events as no layer processing, or filtering occurs.
352 */
353void switch_events(uint8_t row, uint8_t col, bool pressed) {
354#if defined(LED_MATRIX_ENABLE)
355 process_led_matrix(row, col, pressed);
356#endif
357#if defined(RGB_MATRIX_ENABLE)
358 process_rgb_matrix(row, col, pressed);
359#endif
360}
361
362/** \brief Keyboard task: Do keyboard routine jobs
363 *
364 * Do routine keyboard jobs:
365 *
366 * * scan matrix
367 * * handle mouse movements
368 * * run visualizer code
369 * * handle midi commands
370 * * light LEDs
371 *
372 * This is repeatedly called as fast as possible.
373 */
374void keyboard_task(void) {
375 static matrix_row_t matrix_prev[MATRIX_ROWS];
376 static uint8_t led_status = 0;
377 matrix_row_t matrix_row = 0;
378 matrix_row_t matrix_change = 0;
379#ifdef QMK_KEYS_PER_SCAN
380 uint8_t keys_processed = 0;
381#endif
382#ifdef ENCODER_ENABLE
383 bool encoders_changed = false;
384#endif
385
386 uint8_t matrix_changed = matrix_scan();
387 if (matrix_changed) last_matrix_activity_trigger();
388
389 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
390 matrix_row = matrix_get_row(r);
391 matrix_change = matrix_row ^ matrix_prev[r];
392 if (matrix_change) {
393#ifdef MATRIX_HAS_GHOST
394 if (has_ghost_in_row(r, matrix_row)) {
395 continue;
396 }
397#endif
398 if (debug_matrix) matrix_print();
399 matrix_row_t col_mask = 1;
400 for (uint8_t c = 0; c < MATRIX_COLS; c++, col_mask <<= 1) {
401 if (matrix_change & col_mask) {
402 if (should_process_keypress()) {
403 action_exec((keyevent_t){
404 .key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & col_mask), .time = (timer_read() | 1) /* time should not be 0 */
405 });
406 }
407 // record a processed key
408 matrix_prev[r] ^= col_mask;
409
410 switch_events(r, c, (matrix_row & col_mask));
411
412#ifdef QMK_KEYS_PER_SCAN
413 // only jump out if we have processed "enough" keys.
414 if (++keys_processed >= QMK_KEYS_PER_SCAN)
415#endif
416 // process a key per task call
417 goto MATRIX_LOOP_END;
418 }
419 }
420 }
421 }
422 // call with pseudo tick event when no real key event.
423#ifdef QMK_KEYS_PER_SCAN
424 // we can get here with some keys processed now.
425 if (!keys_processed)
426#endif
427 action_exec(TICK);
428
429MATRIX_LOOP_END:
430
431#ifdef DEBUG_MATRIX_SCAN_RATE
432 matrix_scan_perf_task();
433#endif
434
435#if defined(RGBLIGHT_ENABLE)
436 rgblight_task();
437#endif
438
439#ifdef LED_MATRIX_ENABLE
440 led_matrix_task();
441#endif
442#ifdef RGB_MATRIX_ENABLE
443 rgb_matrix_task();
444#endif
445
446#if defined(BACKLIGHT_ENABLE)
447# if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)
448 backlight_task();
449# endif
450#endif
451
452#ifdef ENCODER_ENABLE
453 encoders_changed = encoder_read();
454 if (encoders_changed) last_encoder_activity_trigger();
455#endif
456
457#ifdef QWIIC_ENABLE
458 qwiic_task();
459#endif
460
461#ifdef OLED_DRIVER_ENABLE
462 oled_task();
463# ifndef OLED_DISABLE_TIMEOUT
464 // Wake up oled if user is using those fabulous keys or spinning those encoders!
465# ifdef ENCODER_ENABLE
466 if (matrix_changed || encoders_changed) oled_on();
467# else
468 if (matrix_changed) oled_on();
469# endif
470# endif
471#endif
472
473#ifdef MOUSEKEY_ENABLE
474 // mousekey repeat & acceleration
475 mousekey_task();
476#endif
477
478#ifdef PS2_MOUSE_ENABLE
479 ps2_mouse_task();
480#endif
481
482#ifdef SERIAL_MOUSE_ENABLE
483 serial_mouse_task();
484#endif
485
486#ifdef ADB_MOUSE_ENABLE
487 adb_mouse_task();
488#endif
489
490#ifdef SERIAL_LINK_ENABLE
491 serial_link_update();
492#endif
493
494#ifdef VISUALIZER_ENABLE
495 visualizer_update(default_layer_state, layer_state, visualizer_get_mods(), host_keyboard_leds());
496#endif
497
498#ifdef POINTING_DEVICE_ENABLE
499 pointing_device_task();
500#endif
501
502#ifdef MIDI_ENABLE
503 midi_task();
504#endif
505
506#ifdef VELOCIKEY_ENABLE
507 if (velocikey_enabled()) {
508 velocikey_decelerate();
509 }
510#endif
511
512#ifdef JOYSTICK_ENABLE
513 joystick_task();
514#endif
515
516 // update LED
517 if (led_status != host_keyboard_leds()) {
518 led_status = host_keyboard_leds();
519 keyboard_set_leds(led_status);
520 }
521}
522
523/** \brief keyboard set leds
524 *
525 * FIXME: needs doc
526 */
527void keyboard_set_leds(uint8_t leds) {
528 if (debug_keyboard) {
529 debug("keyboard_set_led: ");
530 debug_hex8(leds);
531 debug("\n");
532 }
533 led_set(leds);
534}
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
deleted file mode 100644
index 08f4e84f9..000000000
--- a/tmk_core/common/keyboard.h
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdbool.h>
21#include <stdint.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27/* key matrix position */
28typedef struct {
29 uint8_t col;
30 uint8_t row;
31} keypos_t;
32
33/* key event */
34typedef struct {
35 keypos_t key;
36 bool pressed;
37 uint16_t time;
38} keyevent_t;
39
40/* equivalent test of keypos_t */
41#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
42
43/* Rules for No Event:
44 * 1) (time == 0) to handle (keyevent_t){} as empty event
45 * 2) Matrix(255, 255) to make TICK event available
46 */
47static inline bool IS_NOEVENT(keyevent_t event) { return event.time == 0 || (event.key.row == 255 && event.key.col == 255); }
48static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) && event.pressed); }
49static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
50
51/* Tick event */
52#define TICK \
53 (keyevent_t) { .key = (keypos_t){.row = 255, .col = 255}, .pressed = false, .time = (timer_read() | 1) }
54
55/* it runs once at early stage of startup before keyboard_init. */
56void keyboard_setup(void);
57/* it runs once after initializing host side protocol, debug and MCU peripherals. */
58void keyboard_init(void);
59/* it runs repeatedly in main loop */
60void keyboard_task(void);
61/* it runs when host LED status is updated */
62void keyboard_set_leds(uint8_t leds);
63/* it runs whenever code has to behave differently on a slave */
64bool is_keyboard_master(void);
65/* it runs whenever code has to behave differently on left vs right split */
66bool is_keyboard_left(void);
67
68void keyboard_pre_init_kb(void);
69void keyboard_pre_init_user(void);
70void keyboard_post_init_kb(void);
71void keyboard_post_init_user(void);
72
73void housekeeping_task(void); // To be executed by the main loop in each backend TMK protocol
74void housekeeping_task_kb(void); // To be overridden by keyboard-level code
75void housekeeping_task_user(void); // To be overridden by user/keymap-level code
76
77uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder activity
78uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder activity
79
80uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity
81uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity
82
83uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity
84uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity
85
86uint32_t get_matrix_scan_rate(void);
87
88#ifdef __cplusplus
89}
90#endif
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
deleted file mode 100644
index 8facabd81..000000000
--- a/tmk_core/common/keycode.h
+++ /dev/null
@@ -1,560 +0,0 @@
1/*
2Copyright 2011,2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18/*
19 * Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C)
20 *
21 * See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
22 * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older)
23 */
24
25#pragma once
26
27/* FIXME: Add doxygen comments here */
28
29#define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED)
30#define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF)
31#define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL)
32#define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI)
33
34#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
35#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
36#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
37
38#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
39
40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8)
43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
45
46#define MOD_BIT(code) (1 << MOD_INDEX(code))
47#define MOD_INDEX(code) ((code)&0x07)
48
49#define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL))
50#define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))
51#define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))
52#define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))
53#define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT)
54#define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT)
55#define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI)
56#define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT)
57#define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI)
58#define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI)
59#define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT)
60#define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI)
61#define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI)
62#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
63#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
64
65#define FN_BIT(code) (1 << FN_INDEX(code))
66#define FN_INDEX(code) ((code)-KC_FN0)
67#define FN_MIN KC_FN0
68#define FN_MAX KC_FN31
69
70/*
71 * Short names for ease of definition of keymap
72 */
73/* Transparent */
74#define KC_TRANSPARENT 0x01
75#define KC_TRNS KC_TRANSPARENT
76
77/* Punctuation */
78#define KC_ENT KC_ENTER
79#define KC_ESC KC_ESCAPE
80#define KC_BSPC KC_BSPACE
81#define KC_SPC KC_SPACE
82#define KC_MINS KC_MINUS
83#define KC_EQL KC_EQUAL
84#define KC_LBRC KC_LBRACKET
85#define KC_RBRC KC_RBRACKET
86#define KC_BSLS KC_BSLASH
87#define KC_NUHS KC_NONUS_HASH
88#define KC_SCLN KC_SCOLON
89#define KC_QUOT KC_QUOTE
90#define KC_GRV KC_GRAVE
91#define KC_COMM KC_COMMA
92#define KC_SLSH KC_SLASH
93#define KC_NUBS KC_NONUS_BSLASH
94
95/* Lock Keys */
96#define KC_CLCK KC_CAPSLOCK
97#define KC_CAPS KC_CAPSLOCK
98#define KC_SLCK KC_SCROLLLOCK
99#define KC_NLCK KC_NUMLOCK
100#define KC_LCAP KC_LOCKING_CAPS
101#define KC_LNUM KC_LOCKING_NUM
102#define KC_LSCR KC_LOCKING_SCROLL
103
104/* Commands */
105#define KC_PSCR KC_PSCREEN
106#define KC_PAUS KC_PAUSE
107#define KC_BRK KC_PAUSE
108#define KC_INS KC_INSERT
109#define KC_DEL KC_DELETE
110#define KC_PGDN KC_PGDOWN
111#define KC_RGHT KC_RIGHT
112#define KC_APP KC_APPLICATION
113#define KC_EXEC KC_EXECUTE
114#define KC_SLCT KC_SELECT
115#define KC_AGIN KC_AGAIN
116#define KC_PSTE KC_PASTE
117#define KC_ERAS KC_ALT_ERASE
118#define KC_CLR KC_CLEAR
119
120/* Keypad */
121#define KC_PSLS KC_KP_SLASH
122#define KC_PAST KC_KP_ASTERISK
123#define KC_PMNS KC_KP_MINUS
124#define KC_PPLS KC_KP_PLUS
125#define KC_PENT KC_KP_ENTER
126#define KC_P1 KC_KP_1
127#define KC_P2 KC_KP_2
128#define KC_P3 KC_KP_3
129#define KC_P4 KC_KP_4
130#define KC_P5 KC_KP_5
131#define KC_P6 KC_KP_6
132#define KC_P7 KC_KP_7
133#define KC_P8 KC_KP_8
134#define KC_P9 KC_KP_9
135#define KC_P0 KC_KP_0
136#define KC_PDOT KC_KP_DOT
137#define KC_PEQL KC_KP_EQUAL
138#define KC_PCMM KC_KP_COMMA
139
140/* Japanese specific */
141#define KC_ZKHK KC_GRAVE
142#define KC_RO KC_INT1
143#define KC_KANA KC_INT2
144#define KC_JYEN KC_INT3
145#define KC_HENK KC_INT4
146#define KC_MHEN KC_INT5
147
148/* Korean specific */
149#define KC_HAEN KC_LANG1
150#define KC_HANJ KC_LANG2
151
152/* Modifiers */
153#define KC_LCTL KC_LCTRL
154#define KC_LSFT KC_LSHIFT
155#define KC_LOPT KC_LALT
156#define KC_LCMD KC_LGUI
157#define KC_LWIN KC_LGUI
158#define KC_RCTL KC_RCTRL
159#define KC_RSFT KC_RSHIFT
160#define KC_ALGR KC_RALT
161#define KC_ROPT KC_RALT
162#define KC_RCMD KC_RGUI
163#define KC_RWIN KC_RGUI
164
165/* Generic Desktop Page (0x01) */
166#define KC_PWR KC_SYSTEM_POWER
167#define KC_SLEP KC_SYSTEM_SLEEP
168#define KC_WAKE KC_SYSTEM_WAKE
169
170/* Consumer Page (0x0C) */
171#define KC_MUTE KC_AUDIO_MUTE
172#define KC_VOLU KC_AUDIO_VOL_UP
173#define KC_VOLD KC_AUDIO_VOL_DOWN
174#define KC_MNXT KC_MEDIA_NEXT_TRACK
175#define KC_MPRV KC_MEDIA_PREV_TRACK
176#define KC_MSTP KC_MEDIA_STOP
177#define KC_MPLY KC_MEDIA_PLAY_PAUSE
178#define KC_MSEL KC_MEDIA_SELECT
179#define KC_EJCT KC_MEDIA_EJECT
180#define KC_CALC KC_CALCULATOR
181#define KC_MYCM KC_MY_COMPUTER
182#define KC_WSCH KC_WWW_SEARCH
183#define KC_WHOM KC_WWW_HOME
184#define KC_WBAK KC_WWW_BACK
185#define KC_WFWD KC_WWW_FORWARD
186#define KC_WSTP KC_WWW_STOP
187#define KC_WREF KC_WWW_REFRESH
188#define KC_WFAV KC_WWW_FAVORITES
189#define KC_MFFD KC_MEDIA_FAST_FORWARD
190#define KC_MRWD KC_MEDIA_REWIND
191#define KC_BRIU KC_BRIGHTNESS_UP
192#define KC_BRID KC_BRIGHTNESS_DOWN
193
194/* System Specific */
195#define KC_BRMU KC_PAUSE
196#define KC_BRMD KC_SCROLLLOCK
197
198/* Mouse Keys */
199#define KC_MS_U KC_MS_UP
200#define KC_MS_D KC_MS_DOWN
201#define KC_MS_L KC_MS_LEFT
202#define KC_MS_R KC_MS_RIGHT
203#define KC_BTN1 KC_MS_BTN1
204#define KC_BTN2 KC_MS_BTN2
205#define KC_BTN3 KC_MS_BTN3
206#define KC_BTN4 KC_MS_BTN4
207#define KC_BTN5 KC_MS_BTN5
208#define KC_BTN6 KC_MS_BTN6
209#define KC_BTN7 KC_MS_BTN7
210#define KC_BTN8 KC_MS_BTN8
211#define KC_WH_U KC_MS_WH_UP
212#define KC_WH_D KC_MS_WH_DOWN
213#define KC_WH_L KC_MS_WH_LEFT
214#define KC_WH_R KC_MS_WH_RIGHT
215#define KC_ACL0 KC_MS_ACCEL0
216#define KC_ACL1 KC_MS_ACCEL1
217#define KC_ACL2 KC_MS_ACCEL2
218
219/* Keyboard/Keypad Page (0x07) */
220enum hid_keyboard_keypad_usage {
221 KC_NO = 0x00,
222 KC_ROLL_OVER,
223 KC_POST_FAIL,
224 KC_UNDEFINED,
225 KC_A,
226 KC_B,
227 KC_C,
228 KC_D,
229 KC_E,
230 KC_F,
231 KC_G,
232 KC_H,
233 KC_I,
234 KC_J,
235 KC_K,
236 KC_L,
237 KC_M, // 0x10
238 KC_N,
239 KC_O,
240 KC_P,
241 KC_Q,
242 KC_R,
243 KC_S,
244 KC_T,
245 KC_U,
246 KC_V,
247 KC_W,
248 KC_X,
249 KC_Y,
250 KC_Z,
251 KC_1,
252 KC_2,
253 KC_3, // 0x20
254 KC_4,
255 KC_5,
256 KC_6,
257 KC_7,
258 KC_8,
259 KC_9,
260 KC_0,
261 KC_ENTER,
262 KC_ESCAPE,
263 KC_BSPACE,
264 KC_TAB,
265 KC_SPACE,
266 KC_MINUS,
267 KC_EQUAL,
268 KC_LBRACKET,
269 KC_RBRACKET, // 0x30
270 KC_BSLASH,
271 KC_NONUS_HASH,
272 KC_SCOLON,
273 KC_QUOTE,
274 KC_GRAVE,
275 KC_COMMA,
276 KC_DOT,
277 KC_SLASH,
278 KC_CAPSLOCK,
279 KC_F1,
280 KC_F2,
281 KC_F3,
282 KC_F4,
283 KC_F5,
284 KC_F6,
285 KC_F7, // 0x40
286 KC_F8,
287 KC_F9,
288 KC_F10,
289 KC_F11,
290 KC_F12,
291 KC_PSCREEN,
292 KC_SCROLLLOCK,
293 KC_PAUSE,
294 KC_INSERT,
295 KC_HOME,
296 KC_PGUP,
297 KC_DELETE,
298 KC_END,
299 KC_PGDOWN,
300 KC_RIGHT,
301 KC_LEFT, // 0x50
302 KC_DOWN,
303 KC_UP,
304 KC_NUMLOCK,
305 KC_KP_SLASH,
306 KC_KP_ASTERISK,
307 KC_KP_MINUS,
308 KC_KP_PLUS,
309 KC_KP_ENTER,
310 KC_KP_1,
311 KC_KP_2,
312 KC_KP_3,
313 KC_KP_4,
314 KC_KP_5,
315 KC_KP_6,
316 KC_KP_7,
317 KC_KP_8, // 0x60
318 KC_KP_9,
319 KC_KP_0,
320 KC_KP_DOT,
321 KC_NONUS_BSLASH,
322 KC_APPLICATION,
323 KC_POWER,
324 KC_KP_EQUAL,
325 KC_F13,
326 KC_F14,
327 KC_F15,
328 KC_F16,
329 KC_F17,
330 KC_F18,
331 KC_F19,
332 KC_F20,
333 KC_F21, // 0x70
334 KC_F22,
335 KC_F23,
336 KC_F24,
337 KC_EXECUTE,
338 KC_HELP,
339 KC_MENU,
340 KC_SELECT,
341 KC_STOP,
342 KC_AGAIN,
343 KC_UNDO,
344 KC_CUT,
345 KC_COPY,
346 KC_PASTE,
347 KC_FIND,
348 KC__MUTE,
349 KC__VOLUP, // 0x80
350 KC__VOLDOWN,
351 KC_LOCKING_CAPS,
352 KC_LOCKING_NUM,
353 KC_LOCKING_SCROLL,
354 KC_KP_COMMA,
355 KC_KP_EQUAL_AS400,
356 KC_INT1,
357 KC_INT2,
358 KC_INT3,
359 KC_INT4,
360 KC_INT5,
361 KC_INT6,
362 KC_INT7,
363 KC_INT8,
364 KC_INT9,
365 KC_LANG1, // 0x90
366 KC_LANG2,
367 KC_LANG3,
368 KC_LANG4,
369 KC_LANG5,
370 KC_LANG6,
371 KC_LANG7,
372 KC_LANG8,
373 KC_LANG9,
374 KC_ALT_ERASE,
375 KC_SYSREQ,
376 KC_CANCEL,
377 KC_CLEAR,
378 KC_PRIOR,
379 KC_RETURN,
380 KC_SEPARATOR,
381 KC_OUT, // 0xA0
382 KC_OPER,
383 KC_CLEAR_AGAIN,
384 KC_CRSEL,
385 KC_EXSEL,
386
387#if 0
388 // ***************************************************************
389 // These keycodes are present in the HID spec, but are *
390 // nonfunctional on modern OSes. QMK uses this range (0xA5-0xDF) *
391 // for the media and function keys instead - see below. *
392 // ***************************************************************
393
394 KC_KP_00 = 0xB0,
395 KC_KP_000,
396 KC_THOUSANDS_SEPARATOR,
397 KC_DECIMAL_SEPARATOR,
398 KC_CURRENCY_UNIT,
399 KC_CURRENCY_SUB_UNIT,
400 KC_KP_LPAREN,
401 KC_KP_RPAREN,
402 KC_KP_LCBRACKET,
403 KC_KP_RCBRACKET,
404 KC_KP_TAB,
405 KC_KP_BSPACE,
406 KC_KP_A,
407 KC_KP_B,
408 KC_KP_C,
409 KC_KP_D,
410 KC_KP_E, //0xC0
411 KC_KP_F,
412 KC_KP_XOR,
413 KC_KP_HAT,
414 KC_KP_PERC,
415 KC_KP_LT,
416 KC_KP_GT,
417 KC_KP_AND,
418 KC_KP_LAZYAND,
419 KC_KP_OR,
420 KC_KP_LAZYOR,
421 KC_KP_COLON,
422 KC_KP_HASH,
423 KC_KP_SPACE,
424 KC_KP_ATMARK,
425 KC_KP_EXCLAMATION,
426 KC_KP_MEM_STORE, //0xD0
427 KC_KP_MEM_RECALL,
428 KC_KP_MEM_CLEAR,
429 KC_KP_MEM_ADD,
430 KC_KP_MEM_SUB,
431 KC_KP_MEM_MUL,
432 KC_KP_MEM_DIV,
433 KC_KP_PLUS_MINUS,
434 KC_KP_CLEAR,
435 KC_KP_CLEAR_ENTRY,
436 KC_KP_BINARY,
437 KC_KP_OCTAL,
438 KC_KP_DECIMAL,
439 KC_KP_HEXADECIMAL,
440#endif
441
442 /* Modifiers */
443 KC_LCTRL = 0xE0,
444 KC_LSHIFT,
445 KC_LALT,
446 KC_LGUI,
447 KC_RCTRL,
448 KC_RSHIFT,
449 KC_RALT,
450 KC_RGUI
451
452 // **********************************************
453 // * 0xF0-0xFF are unallocated in the HID spec. *
454 // * QMK uses these for Mouse Keys - see below. *
455 // **********************************************
456};
457
458/* Media and Function keys */
459enum internal_special_keycodes {
460 /* Generic Desktop Page (0x01) */
461 KC_SYSTEM_POWER = 0xA5,
462 KC_SYSTEM_SLEEP,
463 KC_SYSTEM_WAKE,
464
465 /* Consumer Page (0x0C) */
466 KC_AUDIO_MUTE,
467 KC_AUDIO_VOL_UP,
468 KC_AUDIO_VOL_DOWN,
469 KC_MEDIA_NEXT_TRACK,
470 KC_MEDIA_PREV_TRACK,
471 KC_MEDIA_STOP,
472 KC_MEDIA_PLAY_PAUSE,
473 KC_MEDIA_SELECT,
474 KC_MEDIA_EJECT, // 0xB0
475 KC_MAIL,
476 KC_CALCULATOR,
477 KC_MY_COMPUTER,
478 KC_WWW_SEARCH,
479 KC_WWW_HOME,
480 KC_WWW_BACK,
481 KC_WWW_FORWARD,
482 KC_WWW_STOP,
483 KC_WWW_REFRESH,
484 KC_WWW_FAVORITES,
485 KC_MEDIA_FAST_FORWARD,
486 KC_MEDIA_REWIND,
487 KC_BRIGHTNESS_UP,
488 KC_BRIGHTNESS_DOWN,
489
490 /* Fn keys */
491 KC_FN0 = 0xC0,
492 KC_FN1,
493 KC_FN2,
494 KC_FN3,
495 KC_FN4,
496 KC_FN5,
497 KC_FN6,
498 KC_FN7,
499 KC_FN8,
500 KC_FN9,
501 KC_FN10,
502 KC_FN11,
503 KC_FN12,
504 KC_FN13,
505 KC_FN14,
506 KC_FN15,
507 KC_FN16, // 0xD0
508 KC_FN17,
509 KC_FN18,
510 KC_FN19,
511 KC_FN20,
512 KC_FN21,
513 KC_FN22,
514 KC_FN23,
515 KC_FN24,
516 KC_FN25,
517 KC_FN26,
518 KC_FN27,
519 KC_FN28,
520 KC_FN29,
521 KC_FN30,
522 KC_FN31
523};
524
525enum mouse_keys {
526/* Mouse Buttons */
527#ifdef VIA_ENABLE
528 KC_MS_UP = 0xF0,
529#else
530 KC_MS_UP = 0xED,
531#endif
532 KC_MS_DOWN,
533 KC_MS_LEFT,
534 KC_MS_RIGHT, // 0xF0
535 KC_MS_BTN1,
536 KC_MS_BTN2,
537 KC_MS_BTN3,
538 KC_MS_BTN4,
539 KC_MS_BTN5,
540#ifdef VIA_ENABLE
541 KC_MS_BTN6 = KC_MS_BTN5,
542 KC_MS_BTN7 = KC_MS_BTN5,
543 KC_MS_BTN8 = KC_MS_BTN5,
544#else
545 KC_MS_BTN6,
546 KC_MS_BTN7,
547 KC_MS_BTN8,
548#endif
549
550 /* Mouse Wheel */
551 KC_MS_WH_UP,
552 KC_MS_WH_DOWN,
553 KC_MS_WH_LEFT,
554 KC_MS_WH_RIGHT,
555
556 /* Acceleration */
557 KC_MS_ACCEL0,
558 KC_MS_ACCEL1,
559 KC_MS_ACCEL2 // 0xFF
560};
diff --git a/tmk_core/common/lib_printf.mk b/tmk_core/common/lib_printf.mk
deleted file mode 100644
index 10d2d8468..000000000
--- a/tmk_core/common/lib_printf.mk
+++ /dev/null
@@ -1,9 +0,0 @@
1PRINTF_PATH = $(LIB_PATH)/printf
2
3TMK_COMMON_SRC += $(PRINTF_PATH)/printf.c
4TMK_COMMON_SRC += $(COMMON_DIR)/printf.c
5TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_FLOAT
6TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_EXPONENTIAL
7TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_LONG_LONG
8TMK_COMMON_DEFS += -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T
9VPATH += $(PRINTF_PATH)
diff --git a/tmk_core/common/nodebug.h b/tmk_core/common/nodebug.h
deleted file mode 100644
index 0b176684b..000000000
--- a/tmk_core/common/nodebug.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2Copyright 2013 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#ifndef NO_DEBUG
21# define NO_DEBUG
22# include "debug.h"
23# undef NO_DEBUG
24#else
25# include "debug.h"
26#endif
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
deleted file mode 100644
index 8c055f549..000000000
--- a/tmk_core/common/print.h
+++ /dev/null
@@ -1,135 +0,0 @@
1/* Copyright 2012 Jun Wako <wakojun@gmail.com> */
2/* Very basic print functions, intended to be used with usb_debug_only.c
3 * http://www.pjrc.com/teensy/
4 * Copyright (c) 2008 PJRC.COM, LLC
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#pragma once
26
27#include <stdint.h>
28#include <stdbool.h>
29#include "util.h"
30#include "sendchar.h"
31#include "progmem.h"
32
33void print_set_sendchar(sendchar_func_t func);
34
35#ifndef NO_PRINT
36# if __has_include_next("_print.h")
37# include_next "_print.h" /* Include the platforms print.h */
38# else
39// Fall back to lib/printf
40# include "printf.h" // lib/printf/printf.h
41
42// Create user & normal print defines
43# define print(s) printf(s)
44# define println(s) printf(s "\r\n")
45# define xprintf printf
46# define uprint(s) printf(s)
47# define uprintln(s) printf(s "\r\n")
48# define uprintf printf
49
50# endif /* __has_include_next("_print.h") */
51#else /* NO_PRINT */
52# undef xprintf
53// Remove print defines
54# define print(s)
55# define println(s)
56# define xprintf(fmt, ...)
57# define uprintf(fmt, ...)
58# define uprint(s)
59# define uprintln(s)
60
61#endif /* NO_PRINT */
62
63#ifdef USER_PRINT
64// Remove normal print defines
65# undef print
66# undef println
67# undef xprintf
68# define print(s)
69# define println(s)
70# define xprintf(fmt, ...)
71#endif
72
73#define print_dec(i) xprintf("%u", i)
74#define print_decs(i) xprintf("%d", i)
75/* hex */
76#define print_hex4(i) xprintf("%X", i)
77#define print_hex8(i) xprintf("%02X", i)
78#define print_hex16(i) xprintf("%04X", i)
79#define print_hex32(i) xprintf("%08lX", i)
80/* binary */
81#define print_bin4(i) xprintf("%04b", i)
82#define print_bin8(i) xprintf("%08b", i)
83#define print_bin16(i) xprintf("%016b", i)
84#define print_bin32(i) xprintf("%032lb", i)
85#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
86#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
87#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
88/* print value utility */
89#define print_val_dec(v) xprintf(#v ": %u\n", v)
90#define print_val_decs(v) xprintf(#v ": %d\n", v)
91#define print_val_hex8(v) xprintf(#v ": %X\n", v)
92#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
93#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
94#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
95#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
96#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
97#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
98#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
99#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
100
101// User print disables the normal print messages in the body of QMK/TMK code and
102// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
103// a spot of debugging but lack flash resources for allowing all of the codebase to
104// print (and store their wasteful strings).
105//
106// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!!
107
108/* decimal */
109#define uprint_dec(i) uprintf("%u", i)
110#define uprint_decs(i) uprintf("%d", i)
111/* hex */
112#define uprint_hex4(i) uprintf("%X", i)
113#define uprint_hex8(i) uprintf("%02X", i)
114#define uprint_hex16(i) uprintf("%04X", i)
115#define uprint_hex32(i) uprintf("%08lX", i)
116/* binary */
117#define uprint_bin4(i) uprintf("%04b", i)
118#define uprint_bin8(i) uprintf("%08b", i)
119#define uprint_bin16(i) uprintf("%016b", i)
120#define uprint_bin32(i) uprintf("%032lb", i)
121#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
122#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
123#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
124/* print value utility */
125#define uprint_val_dec(v) uprintf(#v ": %u\n", v)
126#define uprint_val_decs(v) uprintf(#v ": %d\n", v)
127#define uprint_val_hex8(v) uprintf(#v ": %X\n", v)
128#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v)
129#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v)
130#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v)
131#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v)
132#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v)
133#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v))
134#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v))
135#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v))
diff --git a/tmk_core/common/printf.c b/tmk_core/common/printf.c
deleted file mode 100644
index e8440e55e..000000000
--- a/tmk_core/common/printf.c
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include <stddef.h>
18#include "sendchar.h"
19
20// bind lib/printf to console interface - sendchar
21
22static int8_t null_sendchar_func(uint8_t c) { return 0; }
23static sendchar_func_t func = null_sendchar_func;
24
25void print_set_sendchar(sendchar_func_t send) { func = send; }
26
27void _putchar(char character) { func(character); }
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index 4e4771e52..a70d8e299 100644
--- a/tmk_core/common/progmem.h
+++ b/tmk_core/common/progmem.h
@@ -3,7 +3,9 @@
3#if defined(__AVR__) 3#if defined(__AVR__)
4# include <avr/pgmspace.h> 4# include <avr/pgmspace.h>
5#else 5#else
6# include <string.h>
6# define PROGMEM 7# define PROGMEM
8# define __flash
7# define PSTR(x) x 9# define PSTR(x) x
8# define PGM_P const char* 10# define PGM_P const char*
9# define memcpy_P(dest, src, n) memcpy(dest, src, n) 11# define memcpy_P(dest, src, n) memcpy(dest, src, n)
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index db6370657..f2223e806 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -30,7 +30,8 @@ enum hid_report_ids {
30 REPORT_ID_SYSTEM, 30 REPORT_ID_SYSTEM,
31 REPORT_ID_CONSUMER, 31 REPORT_ID_CONSUMER,
32 REPORT_ID_NKRO, 32 REPORT_ID_NKRO,
33 REPORT_ID_JOYSTICK 33 REPORT_ID_JOYSTICK,
34 REPORT_ID_DIGITIZER
34}; 35};
35 36
36/* Mouse buttons */ 37/* Mouse buttons */
@@ -206,6 +207,17 @@ typedef struct {
206} __attribute__((packed)) report_mouse_t; 207} __attribute__((packed)) report_mouse_t;
207 208
208typedef struct { 209typedef struct {
210#ifdef DIGITIZER_SHARED_EP
211 uint8_t report_id;
212#endif
213 uint8_t tip : 1;
214 uint8_t inrange : 1;
215 uint8_t pad2 : 6;
216 uint16_t x;
217 uint16_t y;
218} __attribute__((packed)) report_digitizer_t;
219
220typedef struct {
209#if JOYSTICK_AXES_COUNT > 0 221#if JOYSTICK_AXES_COUNT > 0
210# if JOYSTICK_AXES_RESOLUTION > 8 222# if JOYSTICK_AXES_RESOLUTION > 8
211 int16_t axes[JOYSTICK_AXES_COUNT]; 223 int16_t axes[JOYSTICK_AXES_COUNT];
diff --git a/tmk_core/common/sendchar.h b/tmk_core/common/sendchar.h
deleted file mode 100644
index edcddaa6b..000000000
--- a/tmk_core/common/sendchar.h
+++ /dev/null
@@ -1,33 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26typedef int8_t (*sendchar_func_t)(uint8_t c);
27
28/* transmit a character. return 0 on success, -1 on error. */
29int8_t sendchar(uint8_t c);
30
31#ifdef __cplusplus
32}
33#endif
diff --git a/tmk_core/common/sendchar_null.c b/tmk_core/common/sendchar_null.c
deleted file mode 100644
index fb67f7086..000000000
--- a/tmk_core/common/sendchar_null.c
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "sendchar.h"
18
19__attribute__((weak)) int8_t sendchar(uint8_t c) { return 0; }
diff --git a/tmk_core/common/sendchar_uart.c b/tmk_core/common/sendchar_uart.c
deleted file mode 100644
index 2fc48baff..000000000
--- a/tmk_core/common/sendchar_uart.c
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17#include "uart.h"
18#include "sendchar.h"
19
20int8_t sendchar(uint8_t c) {
21 uart_putchar(c);
22 return 0;
23}
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
index de24b463b..68b92d8b4 100644
--- a/tmk_core/common/sync_timer.c
+++ b/tmk_core/common/sync_timer.c
@@ -26,7 +26,7 @@ SOFTWARE.
26#include "sync_timer.h" 26#include "sync_timer.h"
27#include "keyboard.h" 27#include "keyboard.h"
28 28
29#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) 29#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER)
30volatile int32_t sync_timer_ms; 30volatile int32_t sync_timer_ms;
31 31
32void sync_timer_init(void) { sync_timer_ms = 0; } 32void sync_timer_init(void) { sync_timer_ms = 0; }
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
index 9ddef45bb..744e2b50d 100644
--- a/tmk_core/common/sync_timer.h
+++ b/tmk_core/common/sync_timer.h
@@ -32,7 +32,7 @@ SOFTWARE.
32extern "C" { 32extern "C" {
33#endif 33#endif
34 34
35#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) 35#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER)
36void sync_timer_init(void); 36void sync_timer_init(void);
37void sync_timer_update(uint32_t time); 37void sync_timer_update(uint32_t time);
38uint16_t sync_timer_read(void); 38uint16_t sync_timer_read(void);
diff --git a/tmk_core/common/test/platform.c b/tmk_core/common/test/platform.c
new file mode 100644
index 000000000..8ddceeda8
--- /dev/null
+++ b/tmk_core/common/test/platform.c
@@ -0,0 +1,21 @@
1/* Copyright 2021 QMK
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 3 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#include "platform_deps.h"
18
19void platform_setup(void) {
20 // do nothing
21} \ No newline at end of file
diff --git a/tmk_core/common/timer.h b/tmk_core/common/timer.h
index abddcea85..02e39e79e 100644
--- a/tmk_core/common/timer.h
+++ b/tmk_core/common/timer.h
@@ -1,5 +1,6 @@
1/* 1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com> 2Copyright 2011 Jun Wako <wakojun@gmail.com>
3Copyright 2021 Simon Arlott
3 4
4This program is free software: you can redistribute it and/or modify 5This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 6it under the terms of the GNU General Public License as published by
@@ -17,6 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
17 18
18#pragma once 19#pragma once
19 20
21#if __has_include_next("_timer.h")
22# include_next "_timer.h" /* Include the platform's _timer.h */
23#endif
24
20#include <stdint.h> 25#include <stdint.h>
21 26
22#define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a))))) 27#define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a)))))
@@ -42,6 +47,21 @@ uint32_t timer_elapsed32(uint32_t last);
42#define timer_expired(current, future) ((uint16_t)(current - future) < UINT16_MAX / 2) 47#define timer_expired(current, future) ((uint16_t)(current - future) < UINT16_MAX / 2)
43#define timer_expired32(current, future) ((uint32_t)(current - future) < UINT32_MAX / 2) 48#define timer_expired32(current, future) ((uint32_t)(current - future) < UINT32_MAX / 2)
44 49
50// Use an appropriate timer integer size based on architecture (16-bit will overflow sooner)
51#if FAST_TIMER_T_SIZE < 32
52# define TIMER_DIFF_FAST(a, b) TIMER_DIFF_16(a, b)
53# define timer_expired_fast(current, future) timer_expired(current, future)
54typedef uint16_t fast_timer_t;
55fast_timer_t inline timer_read_fast(void) { return timer_read(); }
56fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed(last); }
57#else
58# define TIMER_DIFF_FAST(a, b) TIMER_DIFF_32(a, b)
59# define timer_expired_fast(current, future) timer_expired32(current, future)
60typedef uint32_t fast_timer_t;
61fast_timer_t inline timer_read_fast(void) { return timer_read32(); }
62fast_timer_t inline timer_elapsed_fast(fast_timer_t last) { return timer_elapsed32(last); }
63#endif
64
45#ifdef __cplusplus 65#ifdef __cplusplus
46} 66}
47#endif 67#endif
diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c
index d4134a044..dd1deeaa1 100644
--- a/tmk_core/common/usb_util.c
+++ b/tmk_core/common/usb_util.c
@@ -16,7 +16,7 @@
16#include "quantum.h" 16#include "quantum.h"
17#include "usb_util.h" 17#include "usb_util.h"
18 18
19__attribute__((weak)) void usb_disable(void) {} 19__attribute__((weak)) void usb_disconnect(void) {}
20__attribute__((weak)) bool usb_connected_state(void) { return true; } 20__attribute__((weak)) bool usb_connected_state(void) { return true; }
21__attribute__((weak)) bool usb_vbus_state(void) { 21__attribute__((weak)) bool usb_vbus_state(void) {
22#ifdef USB_VBUS_PIN 22#ifdef USB_VBUS_PIN
diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h
index 4ebedb1e7..13db9fbfb 100644
--- a/tmk_core/common/usb_util.h
+++ b/tmk_core/common/usb_util.h
@@ -17,6 +17,6 @@
17 17
18#include <stdbool.h> 18#include <stdbool.h>
19 19
20void usb_disable(void); 20void usb_disconnect(void);
21bool usb_connected_state(void); 21bool usb_connected_state(void);
22bool usb_vbus_state(void); 22bool usb_vbus_state(void);