Relocate grave keycode processing (#8082)
[jackhill/qmk/firmware.git] / quantum / quantum.c
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
17 #include "quantum.h"
18
19 #ifdef PROTOCOL_LUFA
20 # include "outputselect.h"
21 #endif
22
23 #ifdef BACKLIGHT_ENABLE
24 # include "backlight.h"
25 extern backlight_config_t backlight_config;
26 #endif
27
28 #ifdef FAUXCLICKY_ENABLE
29 # include "fauxclicky.h"
30 #endif
31
32 #ifdef API_ENABLE
33 # include "api.h"
34 #endif
35
36 #ifdef MIDI_ENABLE
37 # include "process_midi.h"
38 #endif
39
40 #ifdef VELOCIKEY_ENABLE
41 # include "velocikey.h"
42 #endif
43
44 #ifdef HAPTIC_ENABLE
45 # include "haptic.h"
46 #endif
47
48 #ifdef ENCODER_ENABLE
49 # include "encoder.h"
50 #endif
51
52 #ifdef AUDIO_ENABLE
53 # ifndef GOODBYE_SONG
54 # define GOODBYE_SONG SONG(GOODBYE_SOUND)
55 # endif
56 float goodbye_song[][2] = GOODBYE_SONG;
57 # ifdef DEFAULT_LAYER_SONGS
58 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
59 # endif
60 # ifdef SENDSTRING_BELL
61 float bell_song[][2] = SONG(TERMINAL_SOUND);
62 # endif
63 #endif
64
65 static 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
73 uint8_t mods_to_send = 0;
74
75 if (code & QK_RMODS_MIN) { // Right mod flag is set
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 }
86
87 f(mods_to_send);
88 }
89
90 void register_code16(uint16_t code) {
91 if (IS_MOD(code) || code == KC_NO) {
92 do_code16(code, register_mods);
93 } else {
94 do_code16(code, register_weak_mods);
95 }
96 register_code(code);
97 }
98
99 void unregister_code16(uint16_t code) {
100 unregister_code(code);
101 if (IS_MOD(code) || code == KC_NO) {
102 do_code16(code, unregister_mods);
103 } else {
104 do_code16(code, unregister_weak_mods);
105 }
106 }
107
108 void tap_code16(uint16_t code) {
109 register_code16(code);
110 #if TAP_CODE_DELAY > 0
111 wait_ms(TAP_CODE_DELAY);
112 #endif
113 unregister_code16(code);
114 }
115
116 __attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; }
117
118 __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); }
119
120 __attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; }
121
122 void reset_keyboard(void) {
123 clear_keyboard();
124 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
125 process_midi_all_notes_off();
126 #endif
127 #ifdef AUDIO_ENABLE
128 # ifndef NO_MUSIC_MODE
129 music_all_notes_off();
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();
136 #else
137 shutdown_user();
138 wait_ms(250);
139 #endif
140 #ifdef HAPTIC_ENABLE
141 haptic_shutdown();
142 #endif
143 // this is also done later in bootloader.c - not sure if it's neccesary here
144 #ifdef BOOTLOADER_CATERINA
145 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
146 #endif
147 bootloader_jump();
148 }
149
150 /* Convert record into usable keycode via the contained event. */
151 uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
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 */
156 uint16_t get_event_keycode(keyevent_t event) {
157 #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
158 /* TODO: Use store_or_get_action() or a similar function. */
159 if (!disable_action_cache) {
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);
169 } else
170 #endif
171 return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key);
172 }
173
174 /* Main keycode processing function. Hands off handling to other functions,
175 * then processes internal Quantum keycodes, then processes ACTIONs.
176 */
177 bool process_record_quantum(keyrecord_t *record) {
178 uint16_t keycode = get_record_keycode(record);
179
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
188 #ifdef VELOCIKEY_ENABLE
189 if (velocikey_enabled() && record->event.pressed) {
190 velocikey_accelerate();
191 }
192 #endif
193
194 #ifdef TAP_DANCE_ENABLE
195 preprocess_tap_dance(keycode, record);
196 #endif
197
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
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
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) &&
215 #endif
216 #if defined(VIA_ENABLE)
217 process_record_via(keycode, record) &&
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) &&
255 #endif
256 #ifdef MAGIC_KEYCODE_ENABLE
257 process_magic(keycode, record) &&
258 #endif
259 #ifdef GRAVE_ESC_ENABLE
260 process_grave_esc(keycode, record) &&
261 #endif
262 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
263 process_rgb(keycode, record) &&
264 #endif
265 true)) {
266 return false;
267 }
268
269 if (record->event.pressed) {
270 switch (keycode) {
271 case RESET:
272 reset_keyboard();
273 return false;
274 #ifndef NO_DEBUG
275 case DEBUG:
276 debug_enable ^= 1;
277 if (debug_enable) {
278 print("DEBUG: enabled.\n");
279 } else {
280 print("DEBUG: disabled.\n");
281 }
282 #endif
283 return false;
284 case EEPROM_RESET:
285 eeconfig_init();
286 return false;
287 #ifdef FAUXCLICKY_ENABLE
288 case FC_TOG:
289 FAUXCLICKY_TOGGLE;
290 return false;
291 case FC_ON:
292 FAUXCLICKY_ON;
293 return false;
294 case FC_OFF:
295 FAUXCLICKY_OFF;
296 return false;
297 #endif
298 #ifdef VELOCIKEY_ENABLE
299 case VLK_TOG:
300 velocikey_toggle();
301 return false;
302 #endif
303 #ifdef BLUETOOTH_ENABLE
304 case OUT_AUTO:
305 set_output(OUTPUT_AUTO);
306 return false;
307 case OUT_USB:
308 set_output(OUTPUT_USB);
309 return false;
310 case OUT_BT:
311 set_output(OUTPUT_BLUETOOTH);
312 return false;
313 #endif
314 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
315 case BL_BRTG:
316 backlight_toggle_breathing();
317 return false;
318 #endif
319 }
320 }
321
322 return process_action_kb(record);
323 }
324
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
333 // clang-format off
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};
367 // clang-format on
368
369 void send_string(const char *str) { send_string_with_delay(str, 0); }
370
371 void send_string_P(const char *str) { send_string_with_delay_P(str, 0); }
372
373 void send_string_with_delay(const char *str, uint8_t interval) {
374 while (1) {
375 char ascii_code = *str;
376 if (!ascii_code) break;
377 if (ascii_code == SS_TAP_CODE) {
378 // tap
379 uint8_t keycode = *(++str);
380 register_code(keycode);
381 unregister_code(keycode);
382 } else if (ascii_code == SS_DOWN_CODE) {
383 // down
384 uint8_t keycode = *(++str);
385 register_code(keycode);
386 } else if (ascii_code == SS_UP_CODE) {
387 // up
388 uint8_t keycode = *(++str);
389 unregister_code(keycode);
390 } else {
391 send_char(ascii_code);
392 }
393 ++str;
394 // interval
395 {
396 uint8_t ms = interval;
397 while (ms--) wait_ms(1);
398 }
399 }
400 }
401
402 void 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;
406 if (ascii_code == SS_TAP_CODE) {
407 // tap
408 uint8_t keycode = pgm_read_byte(++str);
409 register_code(keycode);
410 unregister_code(keycode);
411 } else if (ascii_code == SS_DOWN_CODE) {
412 // down
413 uint8_t keycode = pgm_read_byte(++str);
414 register_code(keycode);
415 } else if (ascii_code == SS_UP_CODE) {
416 // up
417 uint8_t keycode = pgm_read_byte(++str);
418 unregister_code(keycode);
419 } else {
420 send_char(ascii_code);
421 }
422 ++str;
423 // interval
424 {
425 uint8_t ms = interval;
426 while (ms--) wait_ms(1);
427 }
428 }
429 }
430
431 void send_char(char ascii_code) {
432 #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
433 if (ascii_code == '\a') { // BEL
434 PLAY_SONG(bell_song);
435 return;
436 }
437 #endif
438
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 }
456 }
457
458 void set_single_persistent_default_layer(uint8_t default_layer) {
459 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
460 PLAY_SONG(default_layer_songs[default_layer]);
461 #endif
462 eeconfig_update_default_layer(1U << default_layer);
463 default_layer_set(1U << default_layer);
464 }
465
466 layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
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);
470 }
471
472 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); }
473
474 void tap_random_base64(void) {
475 #if defined(__AVR_ATmega32U4__)
476 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
477 #else
478 uint8_t key = rand() % 64;
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 }
510 }
511
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.
516
517 // We need multiple scans because debouncing can't be turned off.
518 matrix_scan();
519 #if defined(DEBOUNCE) && DEBOUNCE > 0
520 wait_ms(DEBOUNCE * 2);
521 #else
522 wait_ms(30);
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 }
536 }
537
538 void matrix_init_quantum() {
539 #ifdef BOOTMAGIC_LITE
540 bootmagic_lite();
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
553 audio_init();
554 #endif
555 #ifdef RGB_MATRIX_ENABLE
556 rgb_matrix_init();
557 #endif
558 #ifdef ENCODER_ENABLE
559 encoder_init();
560 #endif
561 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
562 unicode_input_mode_init();
563 #endif
564 #ifdef HAPTIC_ENABLE
565 haptic_init();
566 #endif
567 #ifdef OUTPUT_AUTO_ENABLE
568 set_output(OUTPUT_AUTO);
569 #endif
570 #ifdef DIP_SWITCH_ENABLE
571 dip_switch_init();
572 #endif
573
574 matrix_init_kb();
575 }
576
577 void matrix_scan_quantum() {
578 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
579 matrix_scan_music();
580 #endif
581
582 #ifdef TAP_DANCE_ENABLE
583 matrix_scan_tap_dance();
584 #endif
585
586 #ifdef COMBO_ENABLE
587 matrix_scan_combo();
588 #endif
589
590 #ifdef LED_MATRIX_ENABLE
591 led_matrix_task();
592 #endif
593
594 #ifdef RGB_MATRIX_ENABLE
595 rgb_matrix_task();
596 #endif
597
598 #ifdef ENCODER_ENABLE
599 encoder_read();
600 #endif
601
602 #ifdef HAPTIC_ENABLE
603 haptic_task();
604 #endif
605
606 #ifdef DIP_SWITCH_ENABLE
607 dip_switch_read(false);
608 #endif
609
610 matrix_scan_kb();
611 }
612
613 #ifdef HD44780_ENABLED
614 # include "hd44780.h"
615 #endif
616
617 // Functions for spitting out values
618 //
619
620 void send_dword(uint32_t number) { // this might not actually work
621 uint16_t word = (number >> 16);
622 send_word(word);
623 send_word(number & 0xFFFFUL);
624 }
625
626 void send_word(uint16_t number) {
627 uint8_t byte = number >> 8;
628 send_byte(byte);
629 send_byte(number & 0xFF);
630 }
631
632 void send_byte(uint8_t number) {
633 uint8_t nibble = number >> 4;
634 send_nibble(nibble);
635 send_nibble(number & 0xF);
636 }
637
638 void 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
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 }
664 }
665
666 void api_send_unicode(uint32_t unicode) {
667 #ifdef API_ENABLE
668 uint8_t chunk[4];
669 dword_to_bytes(unicode, chunk);
670 MT_SEND_DATA(DT_UNICODE, chunk, 5);
671 #endif
672 }
673
674 /** \brief Lock LED set callback - keymap/user level
675 *
676 * \deprecated Use led_update_user() instead.
677 */
678 __attribute__((weak)) void led_set_user(uint8_t usb_led) {}
679
680 /** \brief Lock LED set callback - keyboard level
681 *
682 * \deprecated Use led_update_kb() instead.
683 */
684 __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
685
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
698 __attribute__((weak)) void led_init_ports(void) {}
699
700 __attribute__((weak)) void led_set(uint8_t usb_led) {
701 #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
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 }
714
715 // Set level without modify backlight_config to keep ability to restore state
716 backlight_set(bl_toggle_lvl);
717 #endif
718
719 led_set_kb(usb_led);
720 led_update_kb((led_t)usb_led);
721 }
722
723 //------------------------------------------------------------------------------
724 // Override these functions in your keymap file to play different tunes on
725 // different events such as startup and bootloader jump
726
727 __attribute__((weak)) void startup_user() {}
728
729 __attribute__((weak)) void shutdown_user() {}
730
731 //------------------------------------------------------------------------------