1 /* Copyright 2016-2017 Jack Humbert
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.
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.
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/>.
20 # include "outputselect.h"
23 #ifdef BACKLIGHT_ENABLE
24 # include "backlight.h"
25 extern backlight_config_t backlight_config
;
28 #ifdef FAUXCLICKY_ENABLE
29 # include "fauxclicky.h"
37 # include "process_midi.h"
40 #ifdef VELOCIKEY_ENABLE
41 # include "velocikey.h"
54 # define GOODBYE_SONG SONG(GOODBYE_SOUND)
56 float goodbye_song
[][2] = GOODBYE_SONG
;
57 # ifdef DEFAULT_LAYER_SONGS
58 float default_layer_songs
[][16][2] = DEFAULT_LAYER_SONGS
;
60 # ifdef SENDSTRING_BELL
61 float bell_song
[][2] = SONG(TERMINAL_SOUND
);
65 static void do_code16(uint16_t code
, void (*f
)(uint8_t)) {
67 case QK_MODS
... QK_MODS_MAX
:
73 uint8_t mods_to_send
= 0;
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
);
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
);
90 void register_code16(uint16_t code
) {
91 if (IS_MOD(code
) || code
== KC_NO
) {
92 do_code16(code
, register_mods
);
94 do_code16(code
, register_weak_mods
);
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
);
104 do_code16(code
, unregister_weak_mods
);
108 void tap_code16(uint16_t code
) {
109 register_code16(code
);
110 #if TAP_CODE_DELAY > 0
111 wait_ms(TAP_CODE_DELAY
);
113 unregister_code16(code
);
116 __attribute__((weak
)) bool process_action_kb(keyrecord_t
*record
) { return true; }
118 __attribute__((weak
)) bool process_record_kb(uint16_t keycode
, keyrecord_t
*record
) { return process_record_user(keycode
, record
); }
120 __attribute__((weak
)) bool process_record_user(uint16_t keycode
, keyrecord_t
*record
) { return true; }
122 void reset_keyboard(void) {
124 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
125 process_midi_all_notes_off();
128 # ifndef NO_MUSIC_MODE
129 music_all_notes_off();
131 uint16_t timer_start
= timer_read();
132 PLAY_SONG(goodbye_song
);
134 while (timer_elapsed(timer_start
) < 250) wait_ms(1);
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
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
); }
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.
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
) {
163 layer
= layer_switch_get_layer(event
.key
);
164 update_source_layers_cache(event
.key
, layer
);
166 layer
= read_source_layers_cache(event
.key
);
168 return keymap_key_to_keycode(layer
, event
.key
);
171 return keymap_key_to_keycode(layer_switch_get_layer(event
.key
), event
.key
);
174 /* Main keycode processing function. Hands off handling to other functions,
175 * then processes internal Quantum keycodes, then processes ACTIONs.
177 bool process_record_quantum(keyrecord_t
*record
) {
178 uint16_t keycode
= get_record_keycode(record
);
180 // This is how you use actions here
181 // if (keycode == KC_LEAD) {
183 // action.code = ACTION_DEFAULT_LAYER_SET(0);
184 // process_action(record, action);
188 #ifdef VELOCIKEY_ENABLE
189 if (velocikey_enabled() && record
->event
.pressed
) {
190 velocikey_accelerate();
194 #ifdef TAP_DANCE_ENABLE
195 preprocess_tap_dance(keycode
, record
);
199 #if defined(KEY_LOCK_ENABLE)
200 // Must run first to be able to mask key_up events.
201 process_key_lock(&keycode
, record
) &&
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
) &&
207 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
208 process_clicky(keycode
, record
) &&
209 #endif // AUDIO_CLICKY
211 process_haptic(keycode
, record
) &&
212 #endif // HAPTIC_ENABLE
213 #if defined(RGB_MATRIX_ENABLE)
214 process_rgb_matrix(keycode
, record
) &&
216 #if defined(VIA_ENABLE)
217 process_record_via(keycode
, record
) &&
219 process_record_kb(keycode
, record
) &&
220 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
221 process_midi(keycode
, record
) &&
224 process_audio(keycode
, record
) &&
227 process_steno(keycode
, record
) &&
229 #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
230 process_music(keycode
, record
) &&
232 #ifdef TAP_DANCE_ENABLE
233 process_tap_dance(keycode
, record
) &&
235 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
236 process_unicode_common(keycode
, record
) &&
239 process_leader(keycode
, record
) &&
242 process_combo(keycode
, record
) &&
244 #ifdef PRINTING_ENABLE
245 process_printer(keycode
, record
) &&
247 #ifdef AUTO_SHIFT_ENABLE
248 process_auto_shift(keycode
, record
) &&
250 #ifdef TERMINAL_ENABLE
251 process_terminal(keycode
, record
) &&
253 #ifdef SPACE_CADET_ENABLE
254 process_space_cadet(keycode
, record
) &&
256 #ifdef MAGIC_KEYCODE_ENABLE
257 process_magic(keycode
, record
) &&
259 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
260 process_rgb(keycode
, record
) &&
266 if (record
->event
.pressed
) {
275 print("DEBUG: enabled.\n");
277 print("DEBUG: disabled.\n");
284 #ifdef FAUXCLICKY_ENABLE
295 #ifdef VELOCIKEY_ENABLE
300 #ifdef BLUETOOTH_ENABLE
302 set_output(OUTPUT_AUTO
);
305 set_output(OUTPUT_USB
);
308 set_output(OUTPUT_BLUETOOTH
);
311 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
313 backlight_toggle_breathing();
319 // keycodes that depend on both pressed and non-pressed state
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.
325 static bool grave_esc_was_shifted
= false;
327 uint8_t shifted
= get_mods() & ((MOD_BIT(KC_LSHIFT
) | MOD_BIT(KC_RSHIFT
) | MOD_BIT(KC_LGUI
) | MOD_BIT(KC_RGUI
)));
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
))) {
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
))) {
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
))) {
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
))) {
359 if (record
->event
.pressed
) {
360 grave_esc_was_shifted
= shifted
;
361 add_key(shifted
? KC_GRAVE
: KC_ESCAPE
);
363 del_key(grave_esc_was_shifted
? KC_GRAVE
: KC_ESCAPE
);
366 send_keyboard_report();
371 return process_action_kb(record
);
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,
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};
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,
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};
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
,
392 KC_SPC
, KC_1
, KC_QUOT
, KC_3
, KC_4
, KC_5
, KC_7
, KC_QUOT
,
394 KC_9
, KC_0
, KC_8
, KC_EQL
, KC_COMM
, KC_MINS
, KC_DOT
, KC_SLSH
,
396 KC_0
, KC_1
, KC_2
, KC_3
, KC_4
, KC_5
, KC_6
, KC_7
,
398 KC_8
, KC_9
, KC_SCLN
, KC_SCLN
, KC_COMM
, KC_EQL
, KC_DOT
, KC_SLSH
,
400 KC_2
, KC_A
, KC_B
, KC_C
, KC_D
, KC_E
, KC_F
, KC_G
,
402 KC_H
, KC_I
, KC_J
, KC_K
, KC_L
, KC_M
, KC_N
, KC_O
,
404 KC_P
, KC_Q
, KC_R
, KC_S
, KC_T
, KC_U
, KC_V
, KC_W
,
406 KC_X
, KC_Y
, KC_Z
, KC_LBRC
, KC_BSLS
, KC_RBRC
, KC_6
, KC_MINS
,
408 KC_GRV
, KC_A
, KC_B
, KC_C
, KC_D
, KC_E
, KC_F
, KC_G
,
410 KC_H
, KC_I
, KC_J
, KC_K
, KC_L
, KC_M
, KC_N
, KC_O
,
412 KC_P
, KC_Q
, KC_R
, KC_S
, KC_T
, KC_U
, KC_V
, KC_W
,
414 KC_X
, KC_Y
, KC_Z
, KC_LBRC
, KC_BSLS
, KC_RBRC
, KC_GRV
, KC_DEL
};
416 void send_string(const char *str
) { send_string_with_delay(str
, 0); }
418 void send_string_P(const char *str
) { send_string_with_delay_P(str
, 0); }
420 void send_string_with_delay(const char *str
, uint8_t interval
) {
422 char ascii_code
= *str
;
423 if (!ascii_code
) break;
424 if (ascii_code
== SS_TAP_CODE
) {
426 uint8_t keycode
= *(++str
);
427 register_code(keycode
);
428 unregister_code(keycode
);
429 } else if (ascii_code
== SS_DOWN_CODE
) {
431 uint8_t keycode
= *(++str
);
432 register_code(keycode
);
433 } else if (ascii_code
== SS_UP_CODE
) {
435 uint8_t keycode
= *(++str
);
436 unregister_code(keycode
);
438 send_char(ascii_code
);
443 uint8_t ms
= interval
;
444 while (ms
--) wait_ms(1);
449 void send_string_with_delay_P(const char *str
, uint8_t interval
) {
451 char ascii_code
= pgm_read_byte(str
);
452 if (!ascii_code
) break;
453 if (ascii_code
== SS_TAP_CODE
) {
455 uint8_t keycode
= pgm_read_byte(++str
);
456 register_code(keycode
);
457 unregister_code(keycode
);
458 } else if (ascii_code
== SS_DOWN_CODE
) {
460 uint8_t keycode
= pgm_read_byte(++str
);
461 register_code(keycode
);
462 } else if (ascii_code
== SS_UP_CODE
) {
464 uint8_t keycode
= pgm_read_byte(++str
);
465 unregister_code(keycode
);
467 send_char(ascii_code
);
472 uint8_t ms
= interval
;
473 while (ms
--) wait_ms(1);
478 void send_char(char ascii_code
) {
479 #if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL)
480 if (ascii_code
== '\a') { // BEL
481 PLAY_SONG(bell_song
);
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
]);
491 register_code(KC_LSFT
);
494 register_code(KC_RALT
);
498 unregister_code(KC_RALT
);
501 unregister_code(KC_LSFT
);
505 void set_single_persistent_default_layer(uint8_t default_layer
) {
506 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
507 PLAY_SONG(default_layer_songs
[default_layer
]);
509 eeconfig_update_default_layer(1U << default_layer
);
510 default_layer_set(1U << default_layer
);
513 layer_state_t
update_tri_layer_state(layer_state_t state
, uint8_t layer1
, uint8_t layer2
, uint8_t layer3
) {
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
);
519 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
)); }
521 void tap_random_base64(void) {
522 #if defined(__AVR_ATmega32U4__)
523 uint8_t key
= (TCNT0
+ TCNT1
+ TCNT3
+ TCNT4
) % 64;
525 uint8_t key
= rand() % 64;
529 register_code(KC_LSFT
);
530 register_code(key
+ KC_A
);
531 unregister_code(key
+ KC_A
);
532 unregister_code(KC_LSFT
);
535 register_code(key
- 26 + KC_A
);
536 unregister_code(key
- 26 + KC_A
);
540 unregister_code(KC_0
);
543 register_code(key
- 53 + KC_1
);
544 unregister_code(key
- 53 + KC_1
);
547 register_code(KC_LSFT
);
548 register_code(KC_EQL
);
549 unregister_code(KC_EQL
);
550 unregister_code(KC_LSFT
);
553 register_code(KC_SLSH
);
554 unregister_code(KC_SLSH
);
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.
564 // We need multiple scans because debouncing can't be turned off.
566 #if defined(DEBOUNCE) && DEBOUNCE > 0
567 wait_ms(DEBOUNCE
* 2);
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
)) {
580 // Jump to bootloader.
585 void matrix_init_quantum() {
586 #ifdef BOOTMAGIC_LITE
589 if (!eeconfig_is_enabled()) {
592 #ifdef BACKLIGHT_ENABLE
593 # ifdef LED_MATRIX_ENABLE
596 backlight_init_ports();
602 #ifdef RGB_MATRIX_ENABLE
605 #ifdef ENCODER_ENABLE
608 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
609 unicode_input_mode_init();
614 #ifdef OUTPUT_AUTO_ENABLE
615 set_output(OUTPUT_AUTO
);
617 #ifdef DIP_SWITCH_ENABLE
624 void matrix_scan_quantum() {
625 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
629 #ifdef TAP_DANCE_ENABLE
630 matrix_scan_tap_dance();
637 #if defined(BACKLIGHT_ENABLE)
638 # if defined(LED_MATRIX_ENABLE)
640 # elif defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS)
645 #ifdef RGB_MATRIX_ENABLE
649 #ifdef ENCODER_ENABLE
657 #ifdef DIP_SWITCH_ENABLE
658 dip_switch_read(false);
664 #ifdef HD44780_ENABLED
665 # include "hd44780.h"
668 // Functions for spitting out values
671 void send_dword(uint32_t number
) { // this might not actually work
672 uint16_t word
= (number
>> 16);
674 send_word(number
& 0xFFFFUL
);
677 void send_word(uint16_t number
) {
678 uint8_t byte
= number
>> 8;
680 send_byte(number
& 0xFF);
683 void send_byte(uint8_t number
) {
684 uint8_t nibble
= number
>> 4;
686 send_nibble(number
& 0xF);
689 void send_nibble(uint8_t number
) {
693 unregister_code(KC_0
);
696 register_code(KC_1
+ (number
- 1));
697 unregister_code(KC_1
+ (number
- 1));
700 register_code(KC_A
+ (number
- 0xA));
701 unregister_code(KC_A
+ (number
- 0xA));
706 __attribute__((weak
)) uint16_t hex_to_keycode(uint8_t hex
) {
710 } else if (hex
< 0xA) {
711 return KC_1
+ (hex
- 0x1);
713 return KC_A
+ (hex
- 0xA);
717 void api_send_unicode(uint32_t unicode
) {
720 dword_to_bytes(unicode
, chunk
);
721 MT_SEND_DATA(DT_UNICODE
, chunk
, 5);
725 /** \brief Lock LED set callback - keymap/user level
727 * \deprecated Use led_update_user() instead.
729 __attribute__((weak
)) void led_set_user(uint8_t usb_led
) {}
731 /** \brief Lock LED set callback - keyboard level
733 * \deprecated Use led_update_kb() instead.
735 __attribute__((weak
)) void led_set_kb(uint8_t usb_led
) { led_set_user(usb_led
); }
737 /** \brief Lock LED update callback - keymap/user level
739 * \return True if led_update_kb() should run its own code, false otherwise.
741 __attribute__((weak
)) bool led_update_user(led_t led_state
) { return true; }
743 /** \brief Lock LED update callback - keyboard level
745 * \return Ignored for now.
747 __attribute__((weak
)) bool led_update_kb(led_t led_state
) { return led_update_user(led_state
); }
749 __attribute__((weak
)) void led_init_ports(void) {}
751 __attribute__((weak
)) void led_set(uint8_t usb_led
) {
752 #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
753 // Use backlight as Caps Lock indicator
754 uint8_t bl_toggle_lvl
= 0;
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
;
766 // Set level without modify backlight_config to keep ability to restore state
767 backlight_set(bl_toggle_lvl
);
771 led_update_kb((led_t
)usb_led
);
774 //------------------------------------------------------------------------------
775 // Override these functions in your keymap file to play different tunes on
776 // different events such as startup and bootloader jump
778 __attribute__((weak
)) void startup_user() {}
780 __attribute__((weak
)) void shutdown_user() {}
782 //------------------------------------------------------------------------------