quantum.c
19642 bytes
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 BACKLIGHT_ENABLE
20# include "process_backlight.h"
21#endif
22
23#ifdef BLUETOOTH_ENABLE
24# include "process_connection.h"
25#endif
26
27#ifdef GRAVE_ESC_ENABLE
28# include "process_grave_esc.h"
29#endif
30
31#ifdef HAPTIC_ENABLE
32# include "process_haptic.h"
33#endif
34
35#ifdef JOYSTICK_ENABLE
36# include "process_joystick.h"
37#endif
38
39#ifdef LEADER_ENABLE
40# include "process_leader.h"
41#endif
42
43#ifdef LED_MATRIX_ENABLE
44# include "process_led_matrix.h"
45#endif
46
47#ifdef MAGIC_ENABLE
48# include "process_magic.h"
49#endif
50
51#ifdef MIDI_ENABLE
52# include "process_midi.h"
53#endif
54
55#if !defined(NO_ACTION_LAYER)
56# include "process_default_layer.h"
57#endif
58
59#ifdef PROGRAMMABLE_BUTTON_ENABLE
60# include "process_programmable_button.h"
61#endif
62
63#if defined(RGB_MATRIX_ENABLE)
64# include "process_rgb_matrix.h"
65#endif
66
67#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
68# include "process_underglow.h"
69#endif
70
71#ifdef SECURE_ENABLE
72# include "process_secure.h"
73#endif
74
75#ifdef TRI_LAYER_ENABLE
76# include "process_tri_layer.h"
77#endif
78
79#ifdef UNICODE_COMMON_ENABLE
80# include "process_unicode_common.h"
81#endif
82
83#ifdef LAYER_LOCK_ENABLE
84# include "process_layer_lock.h"
85#endif
86
87#ifdef AUDIO_ENABLE
88# ifndef GOODBYE_SONG
89# define GOODBYE_SONG SONG(GOODBYE_SOUND)
90# endif
91float goodbye_song[][2] = GOODBYE_SONG;
92# ifdef DEFAULT_LAYER_SONGS
93float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
94# endif
95#endif
96
97uint8_t extract_mod_bits(uint16_t code) {
98 switch (code) {
99 case QK_MODS ... QK_MODS_MAX:
100 break;
101 default:
102 return 0;
103 }
104
105 uint8_t mods_to_send = 0;
106
107 if (code & QK_RMODS_MIN) { // Right mod flag is set
108 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RIGHT_CTRL);
109 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RIGHT_SHIFT);
110 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RIGHT_ALT);
111 if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RIGHT_GUI);
112 } else {
113 if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LEFT_CTRL);
114 if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LEFT_SHIFT);
115 if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LEFT_ALT);
116 if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LEFT_GUI);
117 }
118
119 return mods_to_send;
120}
121
122void do_code16(uint16_t code, void (*f)(uint8_t)) {
123 f(extract_mod_bits(code));
124}
125
126__attribute__((weak)) void register_code16(uint16_t code) {
127 if (IS_MODIFIER_KEYCODE(code) || code == KC_NO) {
128 do_code16(code, register_mods);
129 } else {
130 do_code16(code, register_weak_mods);
131 }
132 register_code(code);
133}
134
135__attribute__((weak)) void unregister_code16(uint16_t code) {
136 unregister_code(code);
137 if (IS_MODIFIER_KEYCODE(code) || code == KC_NO) {
138 do_code16(code, unregister_mods);
139 } else {
140 do_code16(code, unregister_weak_mods);
141 }
142}
143
144/** \brief Tap a keycode with a delay.
145 *
146 * \param code The modded keycode to tap.
147 * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it.
148 */
149__attribute__((weak)) void tap_code16_delay(uint16_t code, uint16_t delay) {
150 register_code16(code);
151 for (uint16_t i = delay; i > 0; i--) {
152 wait_ms(1);
153 }
154 unregister_code16(code);
155}
156
157/** \brief Tap a keycode with the default delay.
158 *
159 * \param code The modded keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined.
160 */
161__attribute__((weak)) void tap_code16(uint16_t code) {
162 tap_code16_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY);
163}
164
165__attribute__((weak)) bool pre_process_record_kb(uint16_t keycode, keyrecord_t *record) {
166 return pre_process_record_user(keycode, record);
167}
168
169__attribute__((weak)) bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) {
170 return true;
171}
172
173__attribute__((weak)) bool process_action_kb(keyrecord_t *record) {
174 return true;
175}
176
177__attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
178 return process_record_user(keycode, record);
179}
180
181__attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) {
182 return true;
183}
184
185__attribute__((weak)) void post_process_record_kb(uint16_t keycode, keyrecord_t *record) {
186 post_process_record_user(keycode, record);
187}
188
189__attribute__((weak)) void post_process_record_user(uint16_t keycode, keyrecord_t *record) {}
190
191void shutdown_quantum(bool jump_to_bootloader) {
192 clear_keyboard();
193#if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
194 process_midi_all_notes_off();
195#endif
196#ifdef AUDIO_ENABLE
197# ifndef NO_MUSIC_MODE
198 music_all_notes_off();
199# endif
200 uint16_t timer_start = timer_read();
201 PLAY_SONG(goodbye_song);
202 shutdown_kb(jump_to_bootloader);
203 while (timer_elapsed(timer_start) < 250)
204 wait_ms(1);
205 stop_all_notes();
206#else
207 shutdown_kb(jump_to_bootloader);
208 wait_ms(250);
209#endif
210#ifdef HAPTIC_ENABLE
211 haptic_shutdown();
212#endif
213}
214
215void reset_keyboard(void) {
216 shutdown_quantum(true);
217 bootloader_jump();
218}
219
220void soft_reset_keyboard(void) {
221 shutdown_quantum(false);
222 mcu_reset();
223}
224
225/* Convert record into usable keycode via the contained event. */
226uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) {
227#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE)
228 if (record->keycode) {
229 return record->keycode;
230 }
231#endif
232 return get_event_keycode(record->event, update_layer_cache);
233}
234
235/* Convert event into usable keycode. Checks the layer cache to ensure that it
236 * retains the correct keycode after a layer change, if the key is still pressed.
237 * "update_layer_cache" is to ensure that it only updates the layer cache when
238 * appropriate, otherwise, it will update it and cause layer tap (and other keys)
239 * from triggering properly.
240 */
241uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) {
242#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
243 /* TODO: Use store_or_get_action() or a similar function. */
244 if (!disable_action_cache) {
245 uint8_t layer;
246
247 if (event.pressed && update_layer_cache) {
248 layer = layer_switch_get_layer(event.key);
249 update_source_layers_cache(event.key, layer);
250 } else {
251 layer = read_source_layers_cache(event.key);
252 }
253 return keymap_key_to_keycode(layer, event.key);
254 } else
255#endif
256 return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key);
257}
258
259/* Get keycode, and then process pre tapping functionality */
260bool pre_process_record_quantum(keyrecord_t *record) {
261 return pre_process_record_kb(get_record_keycode(record, true), record) &&
262#ifdef COMBO_ENABLE
263 process_combo(get_record_keycode(record, true), record) &&
264#endif
265 true;
266}
267
268/* Get keycode, and then call keyboard function */
269void post_process_record_quantum(keyrecord_t *record) {
270 uint16_t keycode = get_record_keycode(record, false);
271 post_process_record_kb(keycode, record);
272}
273
274/* Core keycode function, hands off handling to other functions,
275 then processes internal quantum keycodes, and then processes
276 ACTIONs. */
277bool process_record_quantum(keyrecord_t *record) {
278 uint16_t keycode = get_record_keycode(record, true);
279
280 // This is how you use actions here
281 // if (keycode == QK_LEADER) {
282 // action_t action;
283 // action.code = ACTION_DEFAULT_LAYER_SET(0);
284 // process_action(record, action);
285 // return false;
286 // }
287
288#if defined(SECURE_ENABLE)
289 if (!preprocess_secure(keycode, record)) {
290 return false;
291 }
292#endif
293
294#ifdef TAP_DANCE_ENABLE
295 if (preprocess_tap_dance(keycode, record)) {
296 // The tap dance might have updated the layer state, therefore the
297 // result of the keycode lookup might change.
298 keycode = get_record_keycode(record, true);
299 }
300#endif
301
302#ifdef RGBLIGHT_ENABLE
303 if (record->event.pressed) {
304 preprocess_rgblight();
305 }
306#endif
307
308#ifdef WPM_ENABLE
309 if (record->event.pressed) {
310 update_wpm(keycode);
311 }
312#endif
313
314 if (!(
315#if defined(KEY_LOCK_ENABLE)
316 // Must run first to be able to mask key_up events.
317 process_key_lock(&keycode, record) &&
318#endif
319#if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL)
320 // Must run asap to ensure all keypresses are recorded.
321 process_dynamic_macro(keycode, record) &&
322#endif
323#ifdef REPEAT_KEY_ENABLE
324 process_last_key(keycode, record) && process_repeat_key(keycode, record) &&
325#endif
326#if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
327 process_clicky(keycode, record) &&
328#endif
329#ifdef HAPTIC_ENABLE
330 process_haptic(keycode, record) &&
331#endif
332#if defined(VIA_ENABLE)
333 process_record_via(keycode, record) &&
334#endif
335#if defined(POINTING_DEVICE_ENABLE) && defined(POINTING_DEVICE_AUTO_MOUSE_ENABLE)
336 process_auto_mouse(keycode, record) &&
337#endif
338 process_record_kb(keycode, record) &&
339#if defined(SECURE_ENABLE)
340 process_secure(keycode, record) &&
341#endif
342#if defined(SEQUENCER_ENABLE)
343 process_sequencer(keycode, record) &&
344#endif
345#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
346 process_midi(keycode, record) &&
347#endif
348#ifdef AUDIO_ENABLE
349 process_audio(keycode, record) &&
350#endif
351#if defined(BACKLIGHT_ENABLE)
352 process_backlight(keycode, record) &&
353#endif
354#if defined(LED_MATRIX_ENABLE)
355 process_led_matrix(keycode, record) &&
356#endif
357#ifdef STENO_ENABLE
358 process_steno(keycode, record) &&
359#endif
360#if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
361 process_music(keycode, record) &&
362#endif
363#ifdef CAPS_WORD_ENABLE
364 process_caps_word(keycode, record) &&
365#endif
366#ifdef KEY_OVERRIDE_ENABLE
367 process_key_override(keycode, record) &&
368#endif
369#ifdef TAP_DANCE_ENABLE
370 process_tap_dance(keycode, record) &&
371#endif
372#if defined(UNICODE_COMMON_ENABLE)
373 process_unicode_common(keycode, record) &&
374#endif
375#ifdef LEADER_ENABLE
376 process_leader(keycode, record) &&
377#endif
378#ifdef AUTO_SHIFT_ENABLE
379 process_auto_shift(keycode, record) &&
380#endif
381#ifdef DYNAMIC_TAPPING_TERM_ENABLE
382 process_dynamic_tapping_term(keycode, record) &&
383#endif
384#ifdef SPACE_CADET_ENABLE
385 process_space_cadet(keycode, record) &&
386#endif
387#ifdef MAGIC_ENABLE
388 process_magic(keycode, record) &&
389#endif
390#ifdef GRAVE_ESC_ENABLE
391 process_grave_esc(keycode, record) &&
392#endif
393#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
394 process_underglow(keycode, record) &&
395#endif
396#if defined(RGB_MATRIX_ENABLE)
397 process_rgb_matrix(keycode, record) &&
398#endif
399#ifdef JOYSTICK_ENABLE
400 process_joystick(keycode, record) &&
401#endif
402#ifdef PROGRAMMABLE_BUTTON_ENABLE
403 process_programmable_button(keycode, record) &&
404#endif
405#ifdef AUTOCORRECT_ENABLE
406 process_autocorrect(keycode, record) &&
407#endif
408#ifdef TRI_LAYER_ENABLE
409 process_tri_layer(keycode, record) &&
410#endif
411#if !defined(NO_ACTION_LAYER)
412 process_default_layer(keycode, record) &&
413#endif
414#ifdef LAYER_LOCK_ENABLE
415 process_layer_lock(keycode, record) &&
416#endif
417#ifdef BLUETOOTH_ENABLE
418 process_connection(keycode, record) &&
419#endif
420 true)) {
421 return false;
422 }
423
424 if (record->event.pressed) {
425 switch (keycode) {
426#ifndef NO_RESET
427 case QK_BOOTLOADER:
428 reset_keyboard();
429 return false;
430 case QK_REBOOT:
431 soft_reset_keyboard();
432 return false;
433#endif
434#ifndef NO_DEBUG
435 case QK_DEBUG_TOGGLE:
436 debug_enable ^= 1;
437 if (debug_enable) {
438 print("DEBUG: enabled.\n");
439 } else {
440 print("DEBUG: disabled.\n");
441 }
442#endif
443 return false;
444 case QK_CLEAR_EEPROM:
445#ifdef NO_RESET
446 eeconfig_init();
447#else
448 eeconfig_disable();
449 soft_reset_keyboard();
450#endif
451 return false;
452#ifdef VELOCIKEY_ENABLE
453 case QK_VELOCIKEY_TOGGLE:
454 velocikey_toggle();
455 return false;
456#endif
457#ifndef NO_ACTION_ONESHOT
458 case QK_ONE_SHOT_TOGGLE:
459 oneshot_toggle();
460 break;
461 case QK_ONE_SHOT_ON:
462 oneshot_enable();
463 break;
464 case QK_ONE_SHOT_OFF:
465 oneshot_disable();
466 break;
467#endif
468#ifdef ENABLE_COMPILE_KEYCODE
469 case QK_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader
470 {
471# ifdef NO_ACTION_ONESHOT
472 const uint8_t temp_mod = mod_config(get_mods());
473# else
474 const uint8_t temp_mod = mod_config(get_mods() | get_oneshot_mods());
475 clear_oneshot_mods();
476# endif
477 clear_mods();
478
479 SEND_STRING_DELAY("qmk", TAP_CODE_DELAY);
480 if (temp_mod & MOD_MASK_SHIFT) { // if shift is held, flash rather than compile
481 SEND_STRING_DELAY(" flash ", TAP_CODE_DELAY);
482 } else {
483 SEND_STRING_DELAY(" compile ", TAP_CODE_DELAY);
484 }
485# if defined(CONVERTER_ENABLED)
486 SEND_STRING_DELAY("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP " -e CONVERT_TO=" CONVERTER_TARGET SS_TAP(X_ENTER), TAP_CODE_DELAY);
487# else
488 SEND_STRING_DELAY("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP SS_TAP(X_ENTER), TAP_CODE_DELAY);
489# endif
490 if (temp_mod & MOD_MASK_SHIFT && temp_mod & MOD_MASK_CTRL) {
491 reset_keyboard();
492 }
493 }
494#endif
495 }
496 }
497
498 return process_action_kb(record);
499}
500
501void set_single_default_layer(uint8_t default_layer) {
502#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
503 PLAY_SONG(default_layer_songs[default_layer]);
504#endif
505 default_layer_set((layer_state_t)1 << default_layer);
506}
507
508void set_single_persistent_default_layer(uint8_t default_layer) {
509 eeconfig_update_default_layer((layer_state_t)1 << default_layer);
510 set_single_default_layer(default_layer);
511}
512
513//------------------------------------------------------------------------------
514// Override these functions in your keymap file to play different tunes on
515// different events such as startup and bootloader jump
516
517__attribute__((weak)) bool shutdown_user(bool jump_to_bootloader) {
518 return true;
519}
520
521__attribute__((weak)) bool shutdown_kb(bool jump_to_bootloader) {
522 if (!shutdown_user(jump_to_bootloader)) {
523 return false;
524 }
525 return true;
526}
527
528void suspend_power_down_quantum(void) {
529 suspend_power_down_kb();
530#ifndef NO_SUSPEND_POWER_DOWN
531// Turn off backlight
532# ifdef BACKLIGHT_ENABLE
533 backlight_level_noeeprom(0);
534# endif
535
536# ifdef LED_MATRIX_ENABLE
537 led_matrix_task();
538# endif
539# ifdef RGB_MATRIX_ENABLE
540 rgb_matrix_task();
541# endif
542
543 // Turn off LED indicators
544 led_suspend();
545
546// Turn off audio
547# ifdef AUDIO_ENABLE
548 stop_all_notes();
549# endif
550
551// Turn off underglow
552# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
553 rgblight_suspend();
554# endif
555
556# if defined(LED_MATRIX_ENABLE)
557 led_matrix_set_suspend_state(true);
558# endif
559# if defined(RGB_MATRIX_ENABLE)
560 rgb_matrix_set_suspend_state(true);
561# endif
562
563# ifdef OLED_ENABLE
564 oled_off();
565# endif
566# ifdef ST7565_ENABLE
567 st7565_off();
568# endif
569# if defined(POINTING_DEVICE_ENABLE)
570 // run to ensure scanning occurs while suspended
571 pointing_device_task();
572# endif
573#endif
574}
575
576__attribute__((weak)) void suspend_wakeup_init_quantum(void) {
577// Turn on backlight
578#ifdef BACKLIGHT_ENABLE
579 backlight_init();
580#endif
581
582 // Restore LED indicators
583 led_wakeup();
584
585// Wake up underglow
586#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
587 rgblight_wakeup();
588#endif
589
590#if defined(LED_MATRIX_ENABLE)
591 led_matrix_set_suspend_state(false);
592#endif
593#if defined(RGB_MATRIX_ENABLE)
594 rgb_matrix_set_suspend_state(false);
595#endif
596 suspend_wakeup_init_kb();
597}
598
599/** \brief converts unsigned integers into char arrays
600 *
601 * Takes an unsigned integer and converts that value into an equivalent char array
602 * A padding character may be specified, ' ' for leading spaces, '0' for leading zeros.
603 */
604
605const char *get_numeric_str(char *buf, size_t buf_len, uint32_t curr_num, char curr_pad) {
606 buf[buf_len - 1] = '\0';
607 for (size_t i = 0; i < buf_len - 1; ++i) {
608 char c = '0' + curr_num % 10;
609 buf[buf_len - 2 - i] = (c == '0' && i == 0) ? '0' : (curr_num > 0 ? c : curr_pad);
610 curr_num /= 10;
611 }
612 return buf;
613}
614
615/** \brief converts uint8_t into char array
616 *
617 * Takes an uint8_t, and uses an internal static buffer to render that value into a char array
618 * A padding character may be specified, ' ' for leading spaces, '0' for leading zeros.
619 *
620 * NOTE: Subsequent invocations will reuse the same static buffer and overwrite the previous
621 * contents. Use the result immediately, instead of caching it.
622 */
623const char *get_u8_str(uint8_t curr_num, char curr_pad) {
624 static char buf[4] = {0};
625 static uint8_t last_num = 0xFF;
626 static char last_pad = '\0';
627 if (last_num == curr_num && last_pad == curr_pad) {
628 return buf;
629 }
630 last_num = curr_num;
631 last_pad = curr_pad;
632 return get_numeric_str(buf, sizeof(buf), curr_num, curr_pad);
633}
634
635/** \brief converts uint16_t into char array
636 *
637 * Takes an uint16_t, and uses an internal static buffer to render that value into a char array
638 * A padding character may be specified, ' ' for leading spaces, '0' for leading zeros.
639 *
640 * NOTE: Subsequent invocations will reuse the same static buffer and overwrite the previous
641 * contents. Use the result immediately, instead of caching it.
642 */
643const char *get_u16_str(uint16_t curr_num, char curr_pad) {
644 static char buf[6] = {0};
645 static uint16_t last_num = 0xFF;
646 static char last_pad = '\0';
647 if (last_num == curr_num && last_pad == curr_pad) {
648 return buf;
649 }
650 last_num = curr_num;
651 last_pad = curr_pad;
652 return get_numeric_str(buf, sizeof(buf), curr_num, curr_pad);
653}
654
655#if defined(SECURE_ENABLE)
656void secure_hook_quantum(secure_status_t secure_status) {
657 // If keys are being held when this is triggered, they may not be released properly
658 // this can result in stuck keys, mods and layers. To prevent that, manually
659 // clear these, when it is triggered.
660
661 if (secure_status == SECURE_PENDING) {
662 clear_keyboard();
663 layer_clear();
664 }
665}
666#endif