format code according to conventions [skip ci]
[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 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
260 process_rgb(keycode, record) &&
261 #endif
262 true)) {
263 return false;
264 }
265
266 if (record->event.pressed) {
267 switch (keycode) {
268 case RESET:
269 reset_keyboard();
270 return false;
271 #ifndef NO_DEBUG
272 case DEBUG:
273 debug_enable ^= 1;
274 if (debug_enable) {
275 print("DEBUG: enabled.\n");
276 } else {
277 print("DEBUG: disabled.\n");
278 }
279 #endif
280 return false;
281 case EEPROM_RESET:
282 eeconfig_init();
283 return false;
284 #ifdef FAUXCLICKY_ENABLE
285 case FC_TOG:
286 FAUXCLICKY_TOGGLE;
287 return false;
288 case FC_ON:
289 FAUXCLICKY_ON;
290 return false;
291 case FC_OFF:
292 FAUXCLICKY_OFF;
293 return false;
294 #endif
295 #ifdef VELOCIKEY_ENABLE
296 case VLK_TOG:
297 velocikey_toggle();
298 return false;
299 #endif
300 #ifdef BLUETOOTH_ENABLE
301 case OUT_AUTO:
302 set_output(OUTPUT_AUTO);
303 return false;
304 case OUT_USB:
305 set_output(OUTPUT_USB);
306 return false;
307 case OUT_BT:
308 set_output(OUTPUT_BLUETOOTH);
309 return false;
310 #endif
311 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
312 case BL_BRTG:
313 backlight_toggle_breathing();
314 return false;
315 #endif
316 }
317 }
318
319 // keycodes that depend on both pressed and non-pressed state
320 switch (keycode) {
321 case GRAVE_ESC: {
322 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
323 * Used to ensure that the correct keycode is released if the key is released.
324 */
325 static bool grave_esc_was_shifted = false;
326
327 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)));
328
329 #ifdef GRAVE_ESC_ALT_OVERRIDE
330 // if ALT is pressed, ESC is always sent
331 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
332 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
333 shifted = 0;
334 }
335 #endif
336
337 #ifdef GRAVE_ESC_CTRL_OVERRIDE
338 // if CTRL is pressed, ESC is always sent
339 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
340 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
341 shifted = 0;
342 }
343 #endif
344
345 #ifdef GRAVE_ESC_GUI_OVERRIDE
346 // if GUI is pressed, ESC is always sent
347 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
348 shifted = 0;
349 }
350 #endif
351
352 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
353 // if SHIFT is pressed, ESC is always sent
354 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
355 shifted = 0;
356 }
357 #endif
358
359 if (record->event.pressed) {
360 grave_esc_was_shifted = shifted;
361 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
362 } else {
363 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
364 }
365
366 send_keyboard_report();
367 return false;
368 }
369 }
370
371 return process_action_kb(record);
372 }
373
374 __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,
375
376 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};
377
378 __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,
379
380 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};
381
382 // clang-format off
383 __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {// NUL SOH STX ETX EOT ENQ ACK BEL
384 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
385 // BS TAB LF VT FF CR SO SI
386 KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
387 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
388 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
389 // CAN EM SUB ESC FS GS RS US
390 XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
391
392 // ! " # $ % & '
393 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
394 // ( ) * + , - . /
395 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
396 // 0 1 2 3 4 5 6 7
397 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
398 // 8 9 : ; < = > ?
399 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
400 // @ A B C D E F G
401 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
402 // H I J K L M N O
403 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
404 // P Q R S T U V W
405 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
406 // X Y Z [ \ ] ^ _
407 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
408 // ` a b c d e f g
409 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
410 // h i j k l m n o
411 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
412 // p q r s t u v w
413 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
414 // x y z { | } ~ DEL
415 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL};
416 // clang-format on
417
418 void send_string(const char *str) { send_string_with_delay(str, 0); }
419
420 void send_string_P(const char *str) { send_string_with_delay_P(str, 0); }
421
422 void send_string_with_delay(const char *str, uint8_t interval) {
423 while (1) {
424 char ascii_code = *str;
425 if (!ascii_code) break;
426 if (ascii_code == SS_TAP_CODE) {
427 // tap
428 uint8_t keycode = *(++str);
429 register_code(keycode);
430 unregister_code(keycode);
431 } else if (ascii_code == SS_DOWN_CODE) {
432 // down
433 uint8_t keycode = *(++str);
434 register_code(keycode);
435 } else if (ascii_code == SS_UP_CODE) {
436 // up
437 uint8_t keycode = *(++str);
438 unregister_code(keycode);
439 } else {
440 send_char(ascii_code);
441 }
442 ++str;
443 // interval
444 {
445 uint8_t ms = interval;
446 while (ms--) wait_ms(1);
447 }
448 }
449 }
450
451 void send_string_with_delay_P(const char *str, uint8_t interval) {
452 while (1) {
453 char ascii_code = pgm_read_byte(str);
454 if (!ascii_code) break;
455 if (ascii_code == SS_TAP_CODE) {
456 // tap
457 uint8_t keycode = pgm_read_byte(++str);
458 register_code(keycode);
459 unregister_code(keycode);
460 } else if (ascii_code == SS_DOWN_CODE) {
461 // down
462 uint8_t keycode = pgm_read_byte(++str);
463 register_code(keycode);
464 } else if (ascii_code == SS_UP_CODE) {
465 // up
466 uint8_t keycode = pgm_read_byte(++str);
467 unregister_code(keycode);
468 } else {
469 send_char(ascii_code);
470 }
471 ++str;
472 // interval
473 {
474 uint8_t ms = interval;
475 while (ms--) wait_ms(1);
476 }
477 }
478 }
479
480 void send_char(char ascii_code) {
481 #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
482 if (ascii_code == '\a') { // BEL
483 PLAY_SONG(bell_song);
484 return;
485 }
486 #endif
487
488 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
489 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]);
490 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]);
491
492 if (is_shifted) {
493 register_code(KC_LSFT);
494 }
495 if (is_altgred) {
496 register_code(KC_RALT);
497 }
498 tap_code(keycode);
499 if (is_altgred) {
500 unregister_code(KC_RALT);
501 }
502 if (is_shifted) {
503 unregister_code(KC_LSFT);
504 }
505 }
506
507 void set_single_persistent_default_layer(uint8_t default_layer) {
508 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
509 PLAY_SONG(default_layer_songs[default_layer]);
510 #endif
511 eeconfig_update_default_layer(1U << default_layer);
512 default_layer_set(1U << default_layer);
513 }
514
515 layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
516 layer_state_t mask12 = (1UL << layer1) | (1UL << layer2);
517 layer_state_t mask3 = 1UL << layer3;
518 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
519 }
520
521 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)); }
522
523 void tap_random_base64(void) {
524 #if defined(__AVR_ATmega32U4__)
525 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
526 #else
527 uint8_t key = rand() % 64;
528 #endif
529 switch (key) {
530 case 0 ... 25:
531 register_code(KC_LSFT);
532 register_code(key + KC_A);
533 unregister_code(key + KC_A);
534 unregister_code(KC_LSFT);
535 break;
536 case 26 ... 51:
537 register_code(key - 26 + KC_A);
538 unregister_code(key - 26 + KC_A);
539 break;
540 case 52:
541 register_code(KC_0);
542 unregister_code(KC_0);
543 break;
544 case 53 ... 61:
545 register_code(key - 53 + KC_1);
546 unregister_code(key - 53 + KC_1);
547 break;
548 case 62:
549 register_code(KC_LSFT);
550 register_code(KC_EQL);
551 unregister_code(KC_EQL);
552 unregister_code(KC_LSFT);
553 break;
554 case 63:
555 register_code(KC_SLSH);
556 unregister_code(KC_SLSH);
557 break;
558 }
559 }
560
561 __attribute__((weak)) void bootmagic_lite(void) {
562 // The lite version of TMK's bootmagic based on Wilba.
563 // 100% less potential for accidentally making the
564 // keyboard do stupid things.
565
566 // We need multiple scans because debouncing can't be turned off.
567 matrix_scan();
568 #if defined(DEBOUNCE) && DEBOUNCE > 0
569 wait_ms(DEBOUNCE * 2);
570 #else
571 wait_ms(30);
572 #endif
573 matrix_scan();
574
575 // If the Esc and space bar are held down on power up,
576 // reset the EEPROM valid state and jump to bootloader.
577 // Assumes Esc is at [0,0].
578 // This isn't very generalized, but we need something that doesn't
579 // rely on user's keymaps in firmware or EEPROM.
580 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
581 eeconfig_disable();
582 // Jump to bootloader.
583 bootloader_jump();
584 }
585 }
586
587 void matrix_init_quantum() {
588 #ifdef BOOTMAGIC_LITE
589 bootmagic_lite();
590 #endif
591 if (!eeconfig_is_enabled()) {
592 eeconfig_init();
593 }
594 #ifdef BACKLIGHT_ENABLE
595 # ifdef LED_MATRIX_ENABLE
596 led_matrix_init();
597 # else
598 backlight_init_ports();
599 # endif
600 #endif
601 #ifdef AUDIO_ENABLE
602 audio_init();
603 #endif
604 #ifdef RGB_MATRIX_ENABLE
605 rgb_matrix_init();
606 #endif
607 #ifdef ENCODER_ENABLE
608 encoder_init();
609 #endif
610 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
611 unicode_input_mode_init();
612 #endif
613 #ifdef HAPTIC_ENABLE
614 haptic_init();
615 #endif
616 #ifdef OUTPUT_AUTO_ENABLE
617 set_output(OUTPUT_AUTO);
618 #endif
619 #ifdef DIP_SWITCH_ENABLE
620 dip_switch_init();
621 #endif
622
623 matrix_init_kb();
624 }
625
626 void matrix_scan_quantum() {
627 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
628 matrix_scan_music();
629 #endif
630
631 #ifdef TAP_DANCE_ENABLE
632 matrix_scan_tap_dance();
633 #endif
634
635 #ifdef COMBO_ENABLE
636 matrix_scan_combo();
637 #endif
638
639 #ifdef LED_MATRIX_ENABLE
640 led_matrix_task();
641 #endif
642
643 #ifdef RGB_MATRIX_ENABLE
644 rgb_matrix_task();
645 #endif
646
647 #ifdef ENCODER_ENABLE
648 encoder_read();
649 #endif
650
651 #ifdef HAPTIC_ENABLE
652 haptic_task();
653 #endif
654
655 #ifdef DIP_SWITCH_ENABLE
656 dip_switch_read(false);
657 #endif
658
659 matrix_scan_kb();
660 }
661
662 #ifdef HD44780_ENABLED
663 # include "hd44780.h"
664 #endif
665
666 // Functions for spitting out values
667 //
668
669 void send_dword(uint32_t number) { // this might not actually work
670 uint16_t word = (number >> 16);
671 send_word(word);
672 send_word(number & 0xFFFFUL);
673 }
674
675 void send_word(uint16_t number) {
676 uint8_t byte = number >> 8;
677 send_byte(byte);
678 send_byte(number & 0xFF);
679 }
680
681 void send_byte(uint8_t number) {
682 uint8_t nibble = number >> 4;
683 send_nibble(nibble);
684 send_nibble(number & 0xF);
685 }
686
687 void send_nibble(uint8_t number) {
688 switch (number) {
689 case 0:
690 register_code(KC_0);
691 unregister_code(KC_0);
692 break;
693 case 1 ... 9:
694 register_code(KC_1 + (number - 1));
695 unregister_code(KC_1 + (number - 1));
696 break;
697 case 0xA ... 0xF:
698 register_code(KC_A + (number - 0xA));
699 unregister_code(KC_A + (number - 0xA));
700 break;
701 }
702 }
703
704 __attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) {
705 hex = hex & 0xF;
706 if (hex == 0x0) {
707 return KC_0;
708 } else if (hex < 0xA) {
709 return KC_1 + (hex - 0x1);
710 } else {
711 return KC_A + (hex - 0xA);
712 }
713 }
714
715 void api_send_unicode(uint32_t unicode) {
716 #ifdef API_ENABLE
717 uint8_t chunk[4];
718 dword_to_bytes(unicode, chunk);
719 MT_SEND_DATA(DT_UNICODE, chunk, 5);
720 #endif
721 }
722
723 /** \brief Lock LED set callback - keymap/user level
724 *
725 * \deprecated Use led_update_user() instead.
726 */
727 __attribute__((weak)) void led_set_user(uint8_t usb_led) {}
728
729 /** \brief Lock LED set callback - keyboard level
730 *
731 * \deprecated Use led_update_kb() instead.
732 */
733 __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
734
735 /** \brief Lock LED update callback - keymap/user level
736 *
737 * \return True if led_update_kb() should run its own code, false otherwise.
738 */
739 __attribute__((weak)) bool led_update_user(led_t led_state) { return true; }
740
741 /** \brief Lock LED update callback - keyboard level
742 *
743 * \return Ignored for now.
744 */
745 __attribute__((weak)) bool led_update_kb(led_t led_state) { return led_update_user(led_state); }
746
747 __attribute__((weak)) void led_init_ports(void) {}
748
749 __attribute__((weak)) void led_set(uint8_t usb_led) {
750 #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
751 // Use backlight as Caps Lock indicator
752 uint8_t bl_toggle_lvl = 0;
753
754 if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) {
755 // Turning Caps Lock ON and backlight is disabled in config
756 // Toggling backlight to the brightest level
757 bl_toggle_lvl = BACKLIGHT_LEVELS;
758 } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) {
759 // Turning Caps Lock OFF and backlight is enabled in config
760 // Toggling backlight and restoring config level
761 bl_toggle_lvl = backlight_config.level;
762 }
763
764 // Set level without modify backlight_config to keep ability to restore state
765 backlight_set(bl_toggle_lvl);
766 #endif
767
768 led_set_kb(usb_led);
769 led_update_kb((led_t)usb_led);
770 }
771
772 //------------------------------------------------------------------------------
773 // Override these functions in your keymap file to play different tunes on
774 // different events such as startup and bootloader jump
775
776 __attribute__((weak)) void startup_user() {}
777
778 __attribute__((weak)) void shutdown_user() {}
779
780 //------------------------------------------------------------------------------