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};
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
,
393 KC_SPC
, KC_1
, KC_QUOT
, KC_3
, KC_4
, KC_5
, KC_7
, KC_QUOT
,
395 KC_9
, KC_0
, KC_8
, KC_EQL
, KC_COMM
, KC_MINS
, KC_DOT
, KC_SLSH
,
397 KC_0
, KC_1
, KC_2
, KC_3
, KC_4
, KC_5
, KC_6
, KC_7
,
399 KC_8
, KC_9
, KC_SCLN
, KC_SCLN
, KC_COMM
, KC_EQL
, KC_DOT
, KC_SLSH
,
401 KC_2
, KC_A
, KC_B
, KC_C
, KC_D
, KC_E
, KC_F
, KC_G
,
403 KC_H
, KC_I
, KC_J
, KC_K
, KC_L
, KC_M
, KC_N
, KC_O
,
405 KC_P
, KC_Q
, KC_R
, KC_S
, KC_T
, KC_U
, KC_V
, KC_W
,
407 KC_X
, KC_Y
, KC_Z
, KC_LBRC
, KC_BSLS
, KC_RBRC
, KC_6
, KC_MINS
,
409 KC_GRV
, KC_A
, KC_B
, KC_C
, KC_D
, KC_E
, KC_F
, KC_G
,
411 KC_H
, KC_I
, KC_J
, KC_K
, KC_L
, KC_M
, KC_N
, KC_O
,
413 KC_P
, KC_Q
, KC_R
, KC_S
, KC_T
, KC_U
, KC_V
, KC_W
,
415 KC_X
, KC_Y
, KC_Z
, KC_LBRC
, KC_BSLS
, KC_RBRC
, KC_GRV
, KC_DEL
};
418 void send_string(const char *str
) { send_string_with_delay(str
, 0); }
420 void send_string_P(const char *str
) { send_string_with_delay_P(str
, 0); }
422 void send_string_with_delay(const char *str
, uint8_t interval
) {
424 char ascii_code
= *str
;
425 if (!ascii_code
) break;
426 if (ascii_code
== SS_TAP_CODE
) {
428 uint8_t keycode
= *(++str
);
429 register_code(keycode
);
430 unregister_code(keycode
);
431 } else if (ascii_code
== SS_DOWN_CODE
) {
433 uint8_t keycode
= *(++str
);
434 register_code(keycode
);
435 } else if (ascii_code
== SS_UP_CODE
) {
437 uint8_t keycode
= *(++str
);
438 unregister_code(keycode
);
440 send_char(ascii_code
);
445 uint8_t ms
= interval
;
446 while (ms
--) wait_ms(1);
451 void send_string_with_delay_P(const char *str
, uint8_t interval
) {
453 char ascii_code
= pgm_read_byte(str
);
454 if (!ascii_code
) break;
455 if (ascii_code
== SS_TAP_CODE
) {
457 uint8_t keycode
= pgm_read_byte(++str
);
458 register_code(keycode
);
459 unregister_code(keycode
);
460 } else if (ascii_code
== SS_DOWN_CODE
) {
462 uint8_t keycode
= pgm_read_byte(++str
);
463 register_code(keycode
);
464 } else if (ascii_code
== SS_UP_CODE
) {
466 uint8_t keycode
= pgm_read_byte(++str
);
467 unregister_code(keycode
);
469 send_char(ascii_code
);
474 uint8_t ms
= interval
;
475 while (ms
--) wait_ms(1);
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
);
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
]);
493 register_code(KC_LSFT
);
496 register_code(KC_RALT
);
500 unregister_code(KC_RALT
);
503 unregister_code(KC_LSFT
);
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
]);
511 eeconfig_update_default_layer(1U << default_layer
);
512 default_layer_set(1U << default_layer
);
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
);
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
)); }
523 void tap_random_base64(void) {
524 #if defined(__AVR_ATmega32U4__)
525 uint8_t key
= (TCNT0
+ TCNT1
+ TCNT3
+ TCNT4
) % 64;
527 uint8_t key
= rand() % 64;
531 register_code(KC_LSFT
);
532 register_code(key
+ KC_A
);
533 unregister_code(key
+ KC_A
);
534 unregister_code(KC_LSFT
);
537 register_code(key
- 26 + KC_A
);
538 unregister_code(key
- 26 + KC_A
);
542 unregister_code(KC_0
);
545 register_code(key
- 53 + KC_1
);
546 unregister_code(key
- 53 + KC_1
);
549 register_code(KC_LSFT
);
550 register_code(KC_EQL
);
551 unregister_code(KC_EQL
);
552 unregister_code(KC_LSFT
);
555 register_code(KC_SLSH
);
556 unregister_code(KC_SLSH
);
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.
566 // We need multiple scans because debouncing can't be turned off.
568 #if defined(DEBOUNCE) && DEBOUNCE > 0
569 wait_ms(DEBOUNCE
* 2);
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
)) {
582 // Jump to bootloader.
587 void matrix_init_quantum() {
588 #ifdef BOOTMAGIC_LITE
591 if (!eeconfig_is_enabled()) {
594 #ifdef BACKLIGHT_ENABLE
595 # ifdef LED_MATRIX_ENABLE
598 backlight_init_ports();
604 #ifdef RGB_MATRIX_ENABLE
607 #ifdef ENCODER_ENABLE
610 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
611 unicode_input_mode_init();
616 #ifdef OUTPUT_AUTO_ENABLE
617 set_output(OUTPUT_AUTO
);
619 #ifdef DIP_SWITCH_ENABLE
626 void matrix_scan_quantum() {
627 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
631 #ifdef TAP_DANCE_ENABLE
632 matrix_scan_tap_dance();
639 #ifdef LED_MATRIX_ENABLE
643 #ifdef RGB_MATRIX_ENABLE
647 #ifdef ENCODER_ENABLE
655 #ifdef DIP_SWITCH_ENABLE
656 dip_switch_read(false);
662 #ifdef HD44780_ENABLED
663 # include "hd44780.h"
666 // Functions for spitting out values
669 void send_dword(uint32_t number
) { // this might not actually work
670 uint16_t word
= (number
>> 16);
672 send_word(number
& 0xFFFFUL
);
675 void send_word(uint16_t number
) {
676 uint8_t byte
= number
>> 8;
678 send_byte(number
& 0xFF);
681 void send_byte(uint8_t number
) {
682 uint8_t nibble
= number
>> 4;
684 send_nibble(number
& 0xF);
687 void send_nibble(uint8_t number
) {
691 unregister_code(KC_0
);
694 register_code(KC_1
+ (number
- 1));
695 unregister_code(KC_1
+ (number
- 1));
698 register_code(KC_A
+ (number
- 0xA));
699 unregister_code(KC_A
+ (number
- 0xA));
704 __attribute__((weak
)) uint16_t hex_to_keycode(uint8_t hex
) {
708 } else if (hex
< 0xA) {
709 return KC_1
+ (hex
- 0x1);
711 return KC_A
+ (hex
- 0xA);
715 void api_send_unicode(uint32_t unicode
) {
718 dword_to_bytes(unicode
, chunk
);
719 MT_SEND_DATA(DT_UNICODE
, chunk
, 5);
723 /** \brief Lock LED set callback - keymap/user level
725 * \deprecated Use led_update_user() instead.
727 __attribute__((weak
)) void led_set_user(uint8_t usb_led
) {}
729 /** \brief Lock LED set callback - keyboard level
731 * \deprecated Use led_update_kb() instead.
733 __attribute__((weak
)) void led_set_kb(uint8_t usb_led
) { led_set_user(usb_led
); }
735 /** \brief Lock LED update callback - keymap/user level
737 * \return True if led_update_kb() should run its own code, false otherwise.
739 __attribute__((weak
)) bool led_update_user(led_t led_state
) { return true; }
741 /** \brief Lock LED update callback - keyboard level
743 * \return Ignored for now.
745 __attribute__((weak
)) bool led_update_kb(led_t led_state
) { return led_update_user(led_state
); }
747 __attribute__((weak
)) void led_init_ports(void) {}
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;
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
;
764 // Set level without modify backlight_config to keep ability to restore state
765 backlight_set(bl_toggle_lvl
);
769 led_update_kb((led_t
)usb_led
);
772 //------------------------------------------------------------------------------
773 // Override these functions in your keymap file to play different tunes on
774 // different events such as startup and bootloader jump
776 __attribute__((weak
)) void startup_user() {}
778 __attribute__((weak
)) void shutdown_user() {}
780 //------------------------------------------------------------------------------