Relocate grave keycode processing (#8082)
[jackhill/qmk/firmware.git] / quantum / quantum.c
CommitLineData
23839b8c 1/* Copyright 2016-2017 Jack Humbert
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
1a8c0dd2 17#include "quantum.h"
2e8b32b9 18
e7c4f621 19#ifdef PROTOCOL_LUFA
b624f32f 20# include "outputselect.h"
2bef8b5b 21#endif
1a8c0dd2 22
abfd6ed9
JC
23#ifdef BACKLIGHT_ENABLE
24# include "backlight.h"
542cb0a8 25extern backlight_config_t backlight_config;
abfd6ed9 26#endif
db1e9a46 27
8c93c5d9 28#ifdef FAUXCLICKY_ENABLE
b624f32f 29# include "fauxclicky.h"
8c93c5d9 30#endif
8d0fdf10 31
53ff8a31 32#ifdef API_ENABLE
b624f32f 33# include "api.h"
53ff8a31 34#endif
35
36#ifdef MIDI_ENABLE
b624f32f 37# include "process_midi.h"
53ff8a31 38#endif
39
c1c5922a 40#ifdef VELOCIKEY_ENABLE
b624f32f 41# include "velocikey.h"
c1c5922a
CL
42#endif
43
2cee371b 44#ifdef HAPTIC_ENABLE
b624f32f 45# include "haptic.h"
2cee371b 46#endif
85688e5b
JH
47
48#ifdef ENCODER_ENABLE
b624f32f 49# include "encoder.h"
85688e5b
JH
50#endif
51
6a3c6677 52#ifdef AUDIO_ENABLE
b624f32f 53# ifndef GOODBYE_SONG
54# define GOODBYE_SONG SONG(GOODBYE_SOUND)
55# endif
b624f32f 56float goodbye_song[][2] = GOODBYE_SONG;
b624f32f 57# ifdef DEFAULT_LAYER_SONGS
58float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
59# endif
e5501d48 60# ifdef SENDSTRING_BELL
61float bell_song[][2] = SONG(TERMINAL_SOUND);
62# endif
b624f32f 63#endif
64
65static void do_code16(uint16_t code, void (*f)(uint8_t)) {
66 switch (code) {
67 case QK_MODS ... QK_MODS_MAX:
68 break;
69 default:
70 return;
71 }
72
63f4806d 73 uint8_t mods_to_send = 0;
b624f32f 74
542cb0a8 75 if (code & QK_RMODS_MIN) { // Right mod flag is set
63f4806d 76 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RCTL);
77 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RSFT);
78 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RALT);
79 if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RGUI);
80 } else {
81 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LCTL);
82 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LSFT);
83 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LALT);
84 if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LGUI);
85 }
2b385993 86
63f4806d 87 f(mods_to_send);
2b385993
S
88}
89
b624f32f 90void register_code16(uint16_t code) {
91 if (IS_MOD(code) || code == KC_NO) {
63f4806d 92 do_code16(code, register_mods);
b624f32f 93 } else {
63f4806d 94 do_code16(code, register_weak_mods);
b624f32f 95 }
96 register_code(code);
0d28787c
GN
97}
98
b624f32f 99void unregister_code16(uint16_t code) {
100 unregister_code(code);
101 if (IS_MOD(code) || code == KC_NO) {
63f4806d 102 do_code16(code, unregister_mods);
b624f32f 103 } else {
63f4806d 104 do_code16(code, unregister_weak_mods);
b624f32f 105 }
0d28787c
GN
106}
107
02d44beb 108void tap_code16(uint16_t code) {
b624f32f 109 register_code16(code);
110#if TAP_CODE_DELAY > 0
02d44beb 111 wait_ms(TAP_CODE_DELAY);
b624f32f 112#endif
113 unregister_code16(code);
02d44beb
DJ
114}
115
b624f32f 116__attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; }
1a8c0dd2 117
b624f32f 118__attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); }
17977a7e 119
b624f32f 120__attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; }
17977a7e 121
a28a6e5b 122void reset_keyboard(void) {
b624f32f 123 clear_keyboard();
e6b91549 124#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
b624f32f 125 process_midi_all_notes_off();
365b8635 126#endif
ef5b161b 127#ifdef AUDIO_ENABLE
b624f32f 128# ifndef NO_MUSIC_MODE
ef5b161b 129 music_all_notes_off();
b624f32f 130# endif
131 uint16_t timer_start = timer_read();
132 PLAY_SONG(goodbye_song);
133 shutdown_user();
134 while (timer_elapsed(timer_start) < 250) wait_ms(1);
135 stop_all_notes();
6a3c6677 136#else
b624f32f 137 shutdown_user();
138 wait_ms(250);
6a3c6677 139#endif
2cee371b 140#ifdef HAPTIC_ENABLE
b624f32f 141 haptic_shutdown();
2cee371b 142#endif
9fdc2762
JH
143// this is also done later in bootloader.c - not sure if it's neccesary here
144#ifdef BOOTLOADER_CATERINA
b624f32f 145 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
a28a6e5b 146#endif
b624f32f 147 bootloader_jump();
a28a6e5b
PV
148}
149
5701b75e 150/* Convert record into usable keycode via the contained event. */
b624f32f 151uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
5701b75e
DJ
152
153/* Convert event into usable keycode. Checks the layer cache to ensure that it
154 * retains the correct keycode after a layer change, if the key is still pressed.
155 */
156uint16_t get_event_keycode(keyevent_t event) {
b624f32f 157#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
644c8c79
WS
158 /* TODO: Use store_or_get_action() or a similar function. */
159 if (!disable_action_cache) {
b624f32f 160 uint8_t layer;
161
162 if (event.pressed) {
163 layer = layer_switch_get_layer(event.key);
164 update_source_layers_cache(event.key, layer);
165 } else {
166 layer = read_source_layers_cache(event.key);
167 }
168 return keymap_key_to_keycode(layer, event.key);
644c8c79 169 } else
b624f32f 170#endif
171 return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key);
5701b75e
DJ
172}
173
174/* Main keycode processing function. Hands off handling to other functions,
175 * then processes internal Quantum keycodes, then processes ACTIONs.
176 */
177bool process_record_quantum(keyrecord_t *record) {
178 uint16_t keycode = get_record_keycode(record);
1a8c0dd2 179
bf5c2cce
JH
180 // This is how you use actions here
181 // if (keycode == KC_LEAD) {
182 // action_t action;
183 // action.code = ACTION_DEFAULT_LAYER_SET(0);
184 // process_action(record, action);
185 // return false;
186 // }
187
b624f32f 188#ifdef VELOCIKEY_ENABLE
189 if (velocikey_enabled() && record->event.pressed) {
190 velocikey_accelerate();
191 }
192#endif
c1c5922a 193
b624f32f 194#ifdef TAP_DANCE_ENABLE
9fcda953 195 preprocess_tap_dance(keycode, record);
b624f32f 196#endif
558f3ec1 197
b624f32f 198 if (!(
199#if defined(KEY_LOCK_ENABLE)
200 // Must run first to be able to mask key_up events.
201 process_key_lock(&keycode, record) &&
202#endif
542cb0a8
DJ
203#if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL)
204 // Must run asap to ensure all keypresses are recorded.
205 process_dynamic_macro(keycode, record) &&
206#endif
b624f32f 207#if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
208 process_clicky(keycode, record) &&
209#endif // AUDIO_CLICKY
210#ifdef HAPTIC_ENABLE
211 process_haptic(keycode, record) &&
212#endif // HAPTIC_ENABLE
213#if defined(RGB_MATRIX_ENABLE)
214 process_rgb_matrix(keycode, record) &&
320822d7
W
215#endif
216#if defined(VIA_ENABLE)
217 process_record_via(keycode, record) &&
b624f32f 218#endif
219 process_record_kb(keycode, record) &&
220#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
221 process_midi(keycode, record) &&
222#endif
223#ifdef AUDIO_ENABLE
224 process_audio(keycode, record) &&
225#endif
226#ifdef STENO_ENABLE
227 process_steno(keycode, record) &&
228#endif
229#if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
230 process_music(keycode, record) &&
231#endif
232#ifdef TAP_DANCE_ENABLE
233 process_tap_dance(keycode, record) &&
234#endif
235#if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
236 process_unicode_common(keycode, record) &&
237#endif
238#ifdef LEADER_ENABLE
239 process_leader(keycode, record) &&
240#endif
241#ifdef COMBO_ENABLE
242 process_combo(keycode, record) &&
243#endif
244#ifdef PRINTING_ENABLE
245 process_printer(keycode, record) &&
246#endif
247#ifdef AUTO_SHIFT_ENABLE
248 process_auto_shift(keycode, record) &&
249#endif
250#ifdef TERMINAL_ENABLE
251 process_terminal(keycode, record) &&
252#endif
253#ifdef SPACE_CADET_ENABLE
254 process_space_cadet(keycode, record) &&
d598f01c
JC
255#endif
256#ifdef MAGIC_KEYCODE_ENABLE
257 process_magic(keycode, record) &&
ae40fc49 258#endif
393937b4
JC
259#ifdef GRAVE_ESC_ENABLE
260 process_grave_esc(keycode, record) &&
261#endif
ae40fc49
JC
262#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
263 process_rgb(keycode, record) &&
b624f32f 264#endif
265 true)) {
db32864c 266 return false;
b624f32f 267 }
8a1e6560 268
1604f796
YFL
269 if (record->event.pressed) {
270 switch (keycode) {
271 case RESET:
b624f32f 272 reset_keyboard();
1604f796 273 return false;
2048df88 274#ifndef NO_DEBUG
1604f796 275 case DEBUG:
b624f32f 276 debug_enable ^= 1;
277 if (debug_enable) {
278 print("DEBUG: enabled.\n");
279 } else {
280 print("DEBUG: disabled.\n");
281 }
2048df88 282#endif
1604f796
YFL
283 return false;
284 case EEPROM_RESET:
b624f32f 285 eeconfig_init();
1604f796 286 return false;
b624f32f 287#ifdef FAUXCLICKY_ENABLE
1604f796 288 case FC_TOG:
b624f32f 289 FAUXCLICKY_TOGGLE;
1604f796
YFL
290 return false;
291 case FC_ON:
b624f32f 292 FAUXCLICKY_ON;
1604f796
YFL
293 return false;
294 case FC_OFF:
b624f32f 295 FAUXCLICKY_OFF;
1604f796
YFL
296 return false;
297#endif
298#ifdef VELOCIKEY_ENABLE
299 case VLK_TOG:
300 velocikey_toggle();
301 return false;
302#endif
2048df88 303#ifdef BLUETOOTH_ENABLE
ae40fc49 304 case OUT_AUTO:
1604f796
YFL
305 set_output(OUTPUT_AUTO);
306 return false;
ae40fc49 307 case OUT_USB:
1604f796
YFL
308 set_output(OUTPUT_USB);
309 return false;
ae40fc49 310 case OUT_BT:
1604f796
YFL
311 set_output(OUTPUT_BLUETOOTH);
312 return false;
de4eb79c
JC
313#endif
314#if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
ae40fc49 315 case BL_BRTG:
de4eb79c
JC
316 backlight_toggle_breathing();
317 return false;
b624f32f 318#endif
1604f796
YFL
319 }
320 }
321
b624f32f 322 return process_action_kb(record);
fdc2e805
SH
323}
324
b624f32f 325__attribute__((weak)) const bool ascii_to_shift_lut[128] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
326
327 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0};
328
329__attribute__((weak)) const bool ascii_to_altgr_lut[128] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
332
667045b4 333// clang-format off
b624f32f 334__attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {// NUL SOH STX ETX EOT ENQ ACK BEL
335 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
336 // BS TAB LF VT FF CR SO SI
337 KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
338 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
339 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
340 // CAN EM SUB ESC FS GS RS US
341 XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
342
343 // ! " # $ % & '
344 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
345 // ( ) * + , - . /
346 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
347 // 0 1 2 3 4 5 6 7
348 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
349 // 8 9 : ; < = > ?
350 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
351 // @ A B C D E F G
352 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
353 // H I J K L M N O
354 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
355 // P Q R S T U V W
356 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
357 // X Y Z [ \ ] ^ _
358 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
359 // ` a b c d e f g
360 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
361 // h i j k l m n o
362 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
363 // p q r s t u v w
364 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
365 // x y z { | } ~ DEL
366 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL};
667045b4 367// clang-format on
b624f32f 368
369void send_string(const char *str) { send_string_with_delay(str, 0); }
370
371void send_string_P(const char *str) { send_string_with_delay_P(str, 0); }
7ad924ba 372
fdc2e805 373void send_string_with_delay(const char *str, uint8_t interval) {
5dae013f 374 while (1) {
7ad924ba 375 char ascii_code = *str;
5dae013f 376 if (!ascii_code) break;
d15bb05c 377 if (ascii_code == SS_TAP_CODE) {
b624f32f 378 // tap
379 uint8_t keycode = *(++str);
380 register_code(keycode);
381 unregister_code(keycode);
d15bb05c 382 } else if (ascii_code == SS_DOWN_CODE) {
b624f32f 383 // down
384 uint8_t keycode = *(++str);
385 register_code(keycode);
d15bb05c 386 } else if (ascii_code == SS_UP_CODE) {
b624f32f 387 // up
388 uint8_t keycode = *(++str);
389 unregister_code(keycode);
7ad924ba 390 } else {
b624f32f 391 send_char(ascii_code);
5dae013f 392 }
7ad924ba
JH
393 ++str;
394 // interval
b624f32f 395 {
396 uint8_t ms = interval;
397 while (ms--) wait_ms(1);
398 }
7ad924ba
JH
399 }
400}
401
402void send_string_with_delay_P(const char *str, uint8_t interval) {
403 while (1) {
404 char ascii_code = pgm_read_byte(str);
405 if (!ascii_code) break;
d15bb05c 406 if (ascii_code == SS_TAP_CODE) {
b624f32f 407 // tap
408 uint8_t keycode = pgm_read_byte(++str);
409 register_code(keycode);
410 unregister_code(keycode);
d15bb05c 411 } else if (ascii_code == SS_DOWN_CODE) {
b624f32f 412 // down
413 uint8_t keycode = pgm_read_byte(++str);
414 register_code(keycode);
d15bb05c 415 } else if (ascii_code == SS_UP_CODE) {
b624f32f 416 // up
417 uint8_t keycode = pgm_read_byte(++str);
418 unregister_code(keycode);
7ad924ba 419 } else {
b624f32f 420 send_char(ascii_code);
5dae013f 421 }
422 ++str;
fdc2e805 423 // interval
b624f32f 424 {
425 uint8_t ms = interval;
426 while (ms--) wait_ms(1);
427 }
5dae013f 428 }
429}
430
7ad924ba 431void send_char(char ascii_code) {
e5501d48 432#if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
667045b4 433 if (ascii_code == '\a') { // BEL
e5501d48 434 PLAY_SONG(bell_song);
435 return;
436 }
437#endif
438
b624f32f 439 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
440 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]);
441 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]);
442
443 if (is_shifted) {
444 register_code(KC_LSFT);
445 }
446 if (is_altgred) {
447 register_code(KC_RALT);
448 }
449 tap_code(keycode);
450 if (is_altgred) {
451 unregister_code(KC_RALT);
452 }
453 if (is_shifted) {
454 unregister_code(KC_LSFT);
455 }
7ad924ba
JH
456}
457
6a3c6677 458void set_single_persistent_default_layer(uint8_t default_layer) {
b624f32f 459#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
6a3c6677 460 PLAY_SONG(default_layer_songs[default_layer]);
b624f32f 461#endif
462 eeconfig_update_default_layer(1U << default_layer);
463 default_layer_set(1U << default_layer);
6a3c6677
JH
464}
465
b62e160a 466layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
b624f32f 467 layer_state_t mask12 = (1UL << layer1) | (1UL << layer2);
468 layer_state_t mask3 = 1UL << layer3;
469 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
66e40529
MS
470}
471
b624f32f 472void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); }
1c9f33c0 473
197f152d 474void tap_random_base64(void) {
b624f32f 475#if defined(__AVR_ATmega32U4__)
60fd885a 476 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
b624f32f 477#else
60fd885a 478 uint8_t key = rand() % 64;
b624f32f 479#endif
480 switch (key) {
481 case 0 ... 25:
482 register_code(KC_LSFT);
483 register_code(key + KC_A);
484 unregister_code(key + KC_A);
485 unregister_code(KC_LSFT);
486 break;
487 case 26 ... 51:
488 register_code(key - 26 + KC_A);
489 unregister_code(key - 26 + KC_A);
490 break;
491 case 52:
492 register_code(KC_0);
493 unregister_code(KC_0);
494 break;
495 case 53 ... 61:
496 register_code(key - 53 + KC_1);
497 unregister_code(key - 53 + KC_1);
498 break;
499 case 62:
500 register_code(KC_LSFT);
501 register_code(KC_EQL);
502 unregister_code(KC_EQL);
503 unregister_code(KC_LSFT);
504 break;
505 case 63:
506 register_code(KC_SLSH);
507 unregister_code(KC_SLSH);
508 break;
509 }
197f152d
JH
510}
511
b624f32f 512__attribute__((weak)) void bootmagic_lite(void) {
513 // The lite version of TMK's bootmagic based on Wilba.
514 // 100% less potential for accidentally making the
515 // keyboard do stupid things.
4ffcacd9 516
b624f32f 517 // We need multiple scans because debouncing can't be turned off.
518 matrix_scan();
320822d7 519#if defined(DEBOUNCE) && DEBOUNCE > 0
4ffcacd9 520 wait_ms(DEBOUNCE * 2);
b624f32f 521#else
4ffcacd9 522 wait_ms(30);
b624f32f 523#endif
524 matrix_scan();
525
526 // If the Esc and space bar are held down on power up,
527 // reset the EEPROM valid state and jump to bootloader.
528 // Assumes Esc is at [0,0].
529 // This isn't very generalized, but we need something that doesn't
530 // rely on user's keymaps in firmware or EEPROM.
531 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
532 eeconfig_disable();
533 // Jump to bootloader.
534 bootloader_jump();
535 }
4ffcacd9
DJ
536}
537
1a8c0dd2 538void matrix_init_quantum() {
b624f32f 539#ifdef BOOTMAGIC_LITE
4ffcacd9 540 bootmagic_lite();
b624f32f 541#endif
542 if (!eeconfig_is_enabled()) {
543 eeconfig_init();
544 }
545#ifdef BACKLIGHT_ENABLE
546# ifdef LED_MATRIX_ENABLE
547 led_matrix_init();
548# else
549 backlight_init_ports();
550# endif
551#endif
552#ifdef AUDIO_ENABLE
6a3c6677 553 audio_init();
b624f32f 554#endif
555#ifdef RGB_MATRIX_ENABLE
bad56a4f 556 rgb_matrix_init();
b624f32f 557#endif
558#ifdef ENCODER_ENABLE
85688e5b 559 encoder_init();
b624f32f 560#endif
561#if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
fdeec296 562 unicode_input_mode_init();
b624f32f 563#endif
564#ifdef HAPTIC_ENABLE
2cee371b 565 haptic_init();
b624f32f 566#endif
567#ifdef OUTPUT_AUTO_ENABLE
b60413af 568 set_output(OUTPUT_AUTO);
b624f32f 569#endif
dab4967f
DJ
570#ifdef DIP_SWITCH_ENABLE
571 dip_switch_init();
572#endif
573
b624f32f 574 matrix_init_kb();
1a8c0dd2
EZ
575}
576
577void matrix_scan_quantum() {
b624f32f 578#if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
65faab3b 579 matrix_scan_music();
b624f32f 580#endif
fde477a9 581
b624f32f 582#ifdef TAP_DANCE_ENABLE
65faab3b 583 matrix_scan_tap_dance();
b624f32f 584#endif
b6bf4e0d 585
b624f32f 586#ifdef COMBO_ENABLE
b6bf4e0d 587 matrix_scan_combo();
b624f32f 588#endif
b6bf4e0d 589
ba628a28 590#ifdef LED_MATRIX_ENABLE
b624f32f 591 led_matrix_task();
b624f32f 592#endif
8d0fdf10 593
b624f32f 594#ifdef RGB_MATRIX_ENABLE
14b7602a 595 rgb_matrix_task();
b624f32f 596#endif
14b7602a 597
b624f32f 598#ifdef ENCODER_ENABLE
85688e5b 599 encoder_read();
b624f32f 600#endif
85688e5b 601
b624f32f 602#ifdef HAPTIC_ENABLE
2cee371b 603 haptic_task();
b624f32f 604#endif
2cee371b 605
dab4967f
DJ
606#ifdef DIP_SWITCH_ENABLE
607 dip_switch_read(false);
608#endif
609
b624f32f 610 matrix_scan_kb();
0428214b 611}
13bb6b4b 612
bbea9dad 613#ifdef HD44780_ENABLED
b624f32f 614# include "hd44780.h"
bbea9dad
MA
615#endif
616
664c0a03
JH
617// Functions for spitting out values
618//
619
b624f32f 620void send_dword(uint32_t number) { // this might not actually work
664c0a03
JH
621 uint16_t word = (number >> 16);
622 send_word(word);
623 send_word(number & 0xFFFFUL);
624}
625
626void send_word(uint16_t number) {
627 uint8_t byte = number >> 8;
628 send_byte(byte);
629 send_byte(number & 0xFF);
630}
631
632void send_byte(uint8_t number) {
633 uint8_t nibble = number >> 4;
634 send_nibble(nibble);
635 send_nibble(number & 0xF);
636}
637
638void send_nibble(uint8_t number) {
639 switch (number) {
640 case 0:
641 register_code(KC_0);
642 unregister_code(KC_0);
643 break;
644 case 1 ... 9:
645 register_code(KC_1 + (number - 1));
646 unregister_code(KC_1 + (number - 1));
647 break;
648 case 0xA ... 0xF:
649 register_code(KC_A + (number - 0xA));
650 unregister_code(KC_A + (number - 0xA));
651 break;
652 }
653}
654
b624f32f 655__attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) {
656 hex = hex & 0xF;
657 if (hex == 0x0) {
658 return KC_0;
659 } else if (hex < 0xA) {
660 return KC_1 + (hex - 0x1);
661 } else {
662 return KC_A + (hex - 0xA);
663 }
cbabb4d4
JH
664}
665
7edac212
JH
666void api_send_unicode(uint32_t unicode) {
667#ifdef API_ENABLE
cefa8468
JH
668 uint8_t chunk[4];
669 dword_to_bytes(unicode, chunk);
670 MT_SEND_DATA(DT_UNICODE, chunk, 5);
7edac212 671#endif
cefa8468 672}
13bb6b4b 673
dfb78d2a 674/** \brief Lock LED set callback - keymap/user level
675 *
676 * \deprecated Use led_update_user() instead.
677 */
b624f32f 678__attribute__((weak)) void led_set_user(uint8_t usb_led) {}
13bb6b4b 679
dfb78d2a 680/** \brief Lock LED set callback - keyboard level
681 *
682 * \deprecated Use led_update_kb() instead.
683 */
b624f32f 684__attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
13bb6b4b 685
dfb78d2a 686/** \brief Lock LED update callback - keymap/user level
687 *
688 * \return True if led_update_kb() should run its own code, false otherwise.
689 */
690__attribute__((weak)) bool led_update_user(led_t led_state) { return true; }
691
692/** \brief Lock LED update callback - keyboard level
693 *
694 * \return Ignored for now.
695 */
696__attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); }
697
b624f32f 698__attribute__((weak)) void led_init_ports(void) {}
13bb6b4b 699
b624f32f 700__attribute__((weak)) void led_set(uint8_t usb_led) {
df251d7a 701#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
b624f32f 702 // Use backlight as Caps Lock indicator
703 uint8_t bl_toggle_lvl = 0;
704
705 if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) {
706 // Turning Caps Lock ON and backlight is disabled in config
707 // Toggling backlight to the brightest level
708 bl_toggle_lvl = BACKLIGHT_LEVELS;
709 } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) {
710 // Turning Caps Lock OFF and backlight is enabled in config
711 // Toggling backlight and restoring config level
712 bl_toggle_lvl = backlight_config.level;
713 }
df251d7a 714
b624f32f 715 // Set level without modify backlight_config to keep ability to restore state
716 backlight_set(bl_toggle_lvl);
df251d7a
R
717#endif
718
b624f32f 719 led_set_kb(usb_led);
a91c0c47 720 led_update_kb((led_t)usb_led);
13bb6b4b
JH
721}
722
287eb7ad 723//------------------------------------------------------------------------------
794aed37 724// Override these functions in your keymap file to play different tunes on
287eb7ad
JH
725// different events such as startup and bootloader jump
726
b624f32f 727__attribute__((weak)) void startup_user() {}
287eb7ad 728
b624f32f 729__attribute__((weak)) void shutdown_user() {}
287eb7ad 730
12370259 731//------------------------------------------------------------------------------