Parent directory

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