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