Lets split eh (#3120)
[jackhill/qmk/firmware.git] / quantum / quantum.c
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 #ifdef PROTOCOL_LUFA
19 #include "outputselect.h"
20 #endif
21
22 #ifndef TAPPING_TERM
23 #define TAPPING_TERM 200
24 #endif
25
26 #ifndef BREATHING_PERIOD
27 #define BREATHING_PERIOD 6
28 #endif
29
30 #include "backlight.h"
31 extern backlight_config_t backlight_config;
32
33 #ifdef FAUXCLICKY_ENABLE
34 #include "fauxclicky.h"
35 #endif
36
37 #ifdef API_ENABLE
38 #include "api.h"
39 #endif
40
41 #ifdef MIDI_ENABLE
42 #include "process_midi.h"
43 #endif
44
45 #ifdef AUDIO_ENABLE
46 #ifndef GOODBYE_SONG
47 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
48 #endif
49 #ifndef AG_NORM_SONG
50 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
51 #endif
52 #ifndef AG_SWAP_SONG
53 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
54 #endif
55 float goodbye_song[][2] = GOODBYE_SONG;
56 float ag_norm_song[][2] = AG_NORM_SONG;
57 float ag_swap_song[][2] = AG_SWAP_SONG;
58 #ifdef DEFAULT_LAYER_SONGS
59 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
60 #endif
61 #endif
62
63 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
64 switch (code) {
65 case QK_MODS ... QK_MODS_MAX:
66 break;
67 default:
68 return;
69 }
70
71 if (code & QK_LCTL)
72 f(KC_LCTL);
73 if (code & QK_LSFT)
74 f(KC_LSFT);
75 if (code & QK_LALT)
76 f(KC_LALT);
77 if (code & QK_LGUI)
78 f(KC_LGUI);
79
80 if (code < QK_RMODS_MIN) return;
81
82 if (code & QK_RCTL)
83 f(KC_RCTL);
84 if (code & QK_RSFT)
85 f(KC_RSFT);
86 if (code & QK_RALT)
87 f(KC_RALT);
88 if (code & QK_RGUI)
89 f(KC_RGUI);
90 }
91
92 static inline void qk_register_weak_mods(uint8_t kc) {
93 add_weak_mods(MOD_BIT(kc));
94 send_keyboard_report();
95 }
96
97 static inline void qk_unregister_weak_mods(uint8_t kc) {
98 del_weak_mods(MOD_BIT(kc));
99 send_keyboard_report();
100 }
101
102 static inline void qk_register_mods(uint8_t kc) {
103 add_weak_mods(MOD_BIT(kc));
104 send_keyboard_report();
105 }
106
107 static inline void qk_unregister_mods(uint8_t kc) {
108 del_weak_mods(MOD_BIT(kc));
109 send_keyboard_report();
110 }
111
112 void register_code16 (uint16_t code) {
113 if (IS_MOD(code) || code == KC_NO) {
114 do_code16 (code, qk_register_mods);
115 } else {
116 do_code16 (code, qk_register_weak_mods);
117 }
118 register_code (code);
119 }
120
121 void unregister_code16 (uint16_t code) {
122 unregister_code (code);
123 if (IS_MOD(code) || code == KC_NO) {
124 do_code16 (code, qk_unregister_mods);
125 } else {
126 do_code16 (code, qk_unregister_weak_mods);
127 }
128 }
129
130 __attribute__ ((weak))
131 bool process_action_kb(keyrecord_t *record) {
132 return true;
133 }
134
135 __attribute__ ((weak))
136 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
137 return process_record_user(keycode, record);
138 }
139
140 __attribute__ ((weak))
141 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
142 return true;
143 }
144
145 void reset_keyboard(void) {
146 clear_keyboard();
147 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
148 process_midi_all_notes_off();
149 #endif
150 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
151 music_all_notes_off();
152 uint16_t timer_start = timer_read();
153 PLAY_SONG(goodbye_song);
154 shutdown_user();
155 while(timer_elapsed(timer_start) < 250)
156 wait_ms(1);
157 stop_all_notes();
158 #else
159 wait_ms(250);
160 #endif
161 // this is also done later in bootloader.c - not sure if it's neccesary here
162 #ifdef BOOTLOADER_CATERINA
163 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
164 #endif
165 bootloader_jump();
166 }
167
168 // Shift / paren setup
169
170 #ifndef LSPO_KEY
171 #define LSPO_KEY KC_9
172 #endif
173 #ifndef RSPC_KEY
174 #define RSPC_KEY KC_0
175 #endif
176
177 // Shift / Enter setup
178 #ifndef SFTENT_KEY
179 #define SFTENT_KEY KC_ENT
180 #endif
181
182 static bool shift_interrupted[2] = {0, 0};
183 static uint16_t scs_timer[2] = {0, 0};
184
185 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
186 * Used to ensure that the correct keycode is released if the key is released.
187 */
188 static bool grave_esc_was_shifted = false;
189
190 bool process_record_quantum(keyrecord_t *record) {
191
192 /* This gets the keycode from the key pressed */
193 keypos_t key = record->event.key;
194 uint16_t keycode;
195
196 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
197 /* TODO: Use store_or_get_action() or a similar function. */
198 if (!disable_action_cache) {
199 uint8_t layer;
200
201 if (record->event.pressed) {
202 layer = layer_switch_get_layer(key);
203 update_source_layers_cache(key, layer);
204 } else {
205 layer = read_source_layers_cache(key);
206 }
207 keycode = keymap_key_to_keycode(layer, key);
208 } else
209 #endif
210 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
211
212 // This is how you use actions here
213 // if (keycode == KC_LEAD) {
214 // action_t action;
215 // action.code = ACTION_DEFAULT_LAYER_SET(0);
216 // process_action(record, action);
217 // return false;
218 // }
219
220 #ifdef TAP_DANCE_ENABLE
221 preprocess_tap_dance(keycode, record);
222 #endif
223
224 if (!(
225 #if defined(KEY_LOCK_ENABLE)
226 // Must run first to be able to mask key_up events.
227 process_key_lock(&keycode, record) &&
228 #endif
229 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
230 process_clicky(keycode, record) &&
231 #endif //AUDIO_CLICKY
232 process_record_kb(keycode, record) &&
233 #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
234 process_rgb_matrix(keycode, record) &&
235 #endif
236 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
237 process_midi(keycode, record) &&
238 #endif
239 #ifdef AUDIO_ENABLE
240 process_audio(keycode, record) &&
241 #endif
242 #ifdef STENO_ENABLE
243 process_steno(keycode, record) &&
244 #endif
245 #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
246 process_music(keycode, record) &&
247 #endif
248 #ifdef TAP_DANCE_ENABLE
249 process_tap_dance(keycode, record) &&
250 #endif
251 #ifndef DISABLE_LEADER
252 process_leader(keycode, record) &&
253 #endif
254 #ifndef DISABLE_CHORDING
255 process_chording(keycode, record) &&
256 #endif
257 #ifdef COMBO_ENABLE
258 process_combo(keycode, record) &&
259 #endif
260 #ifdef UNICODE_ENABLE
261 process_unicode(keycode, record) &&
262 #endif
263 #ifdef UCIS_ENABLE
264 process_ucis(keycode, record) &&
265 #endif
266 #ifdef PRINTING_ENABLE
267 process_printer(keycode, record) &&
268 #endif
269 #ifdef AUTO_SHIFT_ENABLE
270 process_auto_shift(keycode, record) &&
271 #endif
272 #ifdef UNICODEMAP_ENABLE
273 process_unicode_map(keycode, record) &&
274 #endif
275 #ifdef TERMINAL_ENABLE
276 process_terminal(keycode, record) &&
277 #endif
278 true)) {
279 return false;
280 }
281
282 // Shift / paren setup
283
284 switch(keycode) {
285 case RESET:
286 if (record->event.pressed) {
287 reset_keyboard();
288 }
289 return false;
290 case DEBUG:
291 if (record->event.pressed) {
292 debug_enable = true;
293 print("DEBUG: enabled.\n");
294 }
295 return false;
296 #ifdef FAUXCLICKY_ENABLE
297 case FC_TOG:
298 if (record->event.pressed) {
299 FAUXCLICKY_TOGGLE;
300 }
301 return false;
302 case FC_ON:
303 if (record->event.pressed) {
304 FAUXCLICKY_ON;
305 }
306 return false;
307 case FC_OFF:
308 if (record->event.pressed) {
309 FAUXCLICKY_OFF;
310 }
311 return false;
312 #endif
313 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
314 case RGB_TOG:
315 // Split keyboards need to trigger on key-up for edge-case issue
316 #ifndef SPLIT_KEYBOARD
317 if (record->event.pressed) {
318 #else
319 if (!record->event.pressed) {
320 #endif
321 rgblight_toggle();
322 #ifdef SPLIT_KEYBOARD
323 RGB_DIRTY = true;
324 #endif
325 }
326 return false;
327 case RGB_MODE_FORWARD:
328 if (record->event.pressed) {
329 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
330 if(shifted) {
331 rgblight_step_reverse();
332 }
333 else {
334 rgblight_step();
335 }
336 #ifdef SPLIT_KEYBOARD
337 RGB_DIRTY = true;
338 #endif
339 }
340 return false;
341 case RGB_MODE_REVERSE:
342 if (record->event.pressed) {
343 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
344 if(shifted) {
345 rgblight_step();
346 }
347 else {
348 rgblight_step_reverse();
349 }
350 #ifdef SPLIT_KEYBOARD
351 RGB_DIRTY = true;
352 #endif
353 }
354 return false;
355 case RGB_HUI:
356 // Split keyboards need to trigger on key-up for edge-case issue
357 #ifndef SPLIT_KEYBOARD
358 if (record->event.pressed) {
359 #else
360 if (!record->event.pressed) {
361 #endif
362 rgblight_increase_hue();
363 #ifdef SPLIT_KEYBOARD
364 RGB_DIRTY = true;
365 #endif
366 }
367 return false;
368 case RGB_HUD:
369 // Split keyboards need to trigger on key-up for edge-case issue
370 #ifndef SPLIT_KEYBOARD
371 if (record->event.pressed) {
372 #else
373 if (!record->event.pressed) {
374 #endif
375 rgblight_decrease_hue();
376 #ifdef SPLIT_KEYBOARD
377 RGB_DIRTY = true;
378 #endif
379 }
380 return false;
381 case RGB_SAI:
382 // Split keyboards need to trigger on key-up for edge-case issue
383 #ifndef SPLIT_KEYBOARD
384 if (record->event.pressed) {
385 #else
386 if (!record->event.pressed) {
387 #endif
388 rgblight_increase_sat();
389 #ifdef SPLIT_KEYBOARD
390 RGB_DIRTY = true;
391 #endif
392 }
393 return false;
394 case RGB_SAD:
395 // Split keyboards need to trigger on key-up for edge-case issue
396 #ifndef SPLIT_KEYBOARD
397 if (record->event.pressed) {
398 #else
399 if (!record->event.pressed) {
400 #endif
401 rgblight_decrease_sat();
402 #ifdef SPLIT_KEYBOARD
403 RGB_DIRTY = true;
404 #endif
405 }
406 return false;
407 case RGB_VAI:
408 // Split keyboards need to trigger on key-up for edge-case issue
409 #ifndef SPLIT_KEYBOARD
410 if (record->event.pressed) {
411 #else
412 if (!record->event.pressed) {
413 #endif
414 rgblight_increase_val();
415 #ifdef SPLIT_KEYBOARD
416 RGB_DIRTY = true;
417 #endif
418 }
419 return false;
420 case RGB_VAD:
421 // Split keyboards need to trigger on key-up for edge-case issue
422 #ifndef SPLIT_KEYBOARD
423 if (record->event.pressed) {
424 #else
425 if (!record->event.pressed) {
426 #endif
427 rgblight_decrease_val();
428 #ifdef SPLIT_KEYBOARD
429 RGB_DIRTY = true;
430 #endif
431 }
432 return false;
433 case RGB_SPI:
434 if (record->event.pressed) {
435 rgblight_increase_speed();
436 }
437 return false;
438 case RGB_SPD:
439 if (record->event.pressed) {
440 rgblight_decrease_speed();
441 }
442 return false;
443 case RGB_MODE_PLAIN:
444 if (record->event.pressed) {
445 rgblight_mode(1);
446 #ifdef SPLIT_KEYBOARD
447 RGB_DIRTY = true;
448 #endif
449 }
450 return false;
451 case RGB_MODE_BREATHE:
452 if (record->event.pressed) {
453 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
454 rgblight_step();
455 } else {
456 rgblight_mode(2);
457 }
458 }
459 return false;
460 case RGB_MODE_RAINBOW:
461 if (record->event.pressed) {
462 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
463 rgblight_step();
464 } else {
465 rgblight_mode(6);
466 }
467 }
468 return false;
469 case RGB_MODE_SWIRL:
470 if (record->event.pressed) {
471 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
472 rgblight_step();
473 } else {
474 rgblight_mode(9);
475 }
476 }
477 return false;
478 case RGB_MODE_SNAKE:
479 if (record->event.pressed) {
480 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
481 rgblight_step();
482 } else {
483 rgblight_mode(15);
484 }
485 }
486 return false;
487 case RGB_MODE_KNIGHT:
488 if (record->event.pressed) {
489 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
490 rgblight_step();
491 } else {
492 rgblight_mode(21);
493 }
494 }
495 return false;
496 case RGB_MODE_XMAS:
497 if (record->event.pressed) {
498 rgblight_mode(24);
499 }
500 return false;
501 case RGB_MODE_GRADIENT:
502 if (record->event.pressed) {
503 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
504 rgblight_step();
505 } else {
506 rgblight_mode(25);
507 }
508 }
509 return false;
510 case RGB_MODE_RGBTEST:
511 if (record->event.pressed) {
512 rgblight_mode(35);
513 }
514 return false;
515 #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
516 #ifdef PROTOCOL_LUFA
517 case OUT_AUTO:
518 if (record->event.pressed) {
519 set_output(OUTPUT_AUTO);
520 }
521 return false;
522 case OUT_USB:
523 if (record->event.pressed) {
524 set_output(OUTPUT_USB);
525 }
526 return false;
527 #ifdef BLUETOOTH_ENABLE
528 case OUT_BT:
529 if (record->event.pressed) {
530 set_output(OUTPUT_BLUETOOTH);
531 }
532 return false;
533 #endif
534 #endif
535 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
536 if (record->event.pressed) {
537 // MAGIC actions (BOOTMAGIC without the boot)
538 if (!eeconfig_is_enabled()) {
539 eeconfig_init();
540 }
541 /* keymap config */
542 keymap_config.raw = eeconfig_read_keymap();
543 switch (keycode)
544 {
545 case MAGIC_SWAP_CONTROL_CAPSLOCK:
546 keymap_config.swap_control_capslock = true;
547 break;
548 case MAGIC_CAPSLOCK_TO_CONTROL:
549 keymap_config.capslock_to_control = true;
550 break;
551 case MAGIC_SWAP_LALT_LGUI:
552 keymap_config.swap_lalt_lgui = true;
553 break;
554 case MAGIC_SWAP_RALT_RGUI:
555 keymap_config.swap_ralt_rgui = true;
556 break;
557 case MAGIC_NO_GUI:
558 keymap_config.no_gui = true;
559 break;
560 case MAGIC_SWAP_GRAVE_ESC:
561 keymap_config.swap_grave_esc = true;
562 break;
563 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
564 keymap_config.swap_backslash_backspace = true;
565 break;
566 case MAGIC_HOST_NKRO:
567 keymap_config.nkro = true;
568 break;
569 case MAGIC_SWAP_ALT_GUI:
570 keymap_config.swap_lalt_lgui = true;
571 keymap_config.swap_ralt_rgui = true;
572 #ifdef AUDIO_ENABLE
573 PLAY_SONG(ag_swap_song);
574 #endif
575 break;
576 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
577 keymap_config.swap_control_capslock = false;
578 break;
579 case MAGIC_UNCAPSLOCK_TO_CONTROL:
580 keymap_config.capslock_to_control = false;
581 break;
582 case MAGIC_UNSWAP_LALT_LGUI:
583 keymap_config.swap_lalt_lgui = false;
584 break;
585 case MAGIC_UNSWAP_RALT_RGUI:
586 keymap_config.swap_ralt_rgui = false;
587 break;
588 case MAGIC_UNNO_GUI:
589 keymap_config.no_gui = false;
590 break;
591 case MAGIC_UNSWAP_GRAVE_ESC:
592 keymap_config.swap_grave_esc = false;
593 break;
594 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
595 keymap_config.swap_backslash_backspace = false;
596 break;
597 case MAGIC_UNHOST_NKRO:
598 keymap_config.nkro = false;
599 break;
600 case MAGIC_UNSWAP_ALT_GUI:
601 keymap_config.swap_lalt_lgui = false;
602 keymap_config.swap_ralt_rgui = false;
603 #ifdef AUDIO_ENABLE
604 PLAY_SONG(ag_norm_song);
605 #endif
606 break;
607 case MAGIC_TOGGLE_NKRO:
608 keymap_config.nkro = !keymap_config.nkro;
609 break;
610 default:
611 break;
612 }
613 eeconfig_update_keymap(keymap_config.raw);
614 clear_keyboard(); // clear to prevent stuck keys
615
616 return false;
617 }
618 break;
619 case KC_LSPO: {
620 if (record->event.pressed) {
621 shift_interrupted[0] = false;
622 scs_timer[0] = timer_read ();
623 register_mods(MOD_BIT(KC_LSFT));
624 }
625 else {
626 #ifdef DISABLE_SPACE_CADET_ROLLOVER
627 if (get_mods() & MOD_BIT(KC_RSFT)) {
628 shift_interrupted[0] = true;
629 shift_interrupted[1] = true;
630 }
631 #endif
632 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
633 register_code(LSPO_KEY);
634 unregister_code(LSPO_KEY);
635 }
636 unregister_mods(MOD_BIT(KC_LSFT));
637 }
638 return false;
639 }
640
641 case KC_RSPC: {
642 if (record->event.pressed) {
643 shift_interrupted[1] = false;
644 scs_timer[1] = timer_read ();
645 register_mods(MOD_BIT(KC_RSFT));
646 }
647 else {
648 #ifdef DISABLE_SPACE_CADET_ROLLOVER
649 if (get_mods() & MOD_BIT(KC_LSFT)) {
650 shift_interrupted[0] = true;
651 shift_interrupted[1] = true;
652 }
653 #endif
654 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
655 register_code(RSPC_KEY);
656 unregister_code(RSPC_KEY);
657 }
658 unregister_mods(MOD_BIT(KC_RSFT));
659 }
660 return false;
661 }
662
663 case KC_SFTENT: {
664 if (record->event.pressed) {
665 shift_interrupted[1] = false;
666 scs_timer[1] = timer_read ();
667 register_mods(MOD_BIT(KC_RSFT));
668 }
669 else if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
670 unregister_mods(MOD_BIT(KC_RSFT));
671 register_code(SFTENT_KEY);
672 unregister_code(SFTENT_KEY);
673 }
674 else {
675 unregister_mods(MOD_BIT(KC_RSFT));
676 }
677 return false;
678 }
679
680 case GRAVE_ESC: {
681 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
682 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
683
684 #ifdef GRAVE_ESC_ALT_OVERRIDE
685 // if ALT is pressed, ESC is always sent
686 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
687 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
688 shifted = 0;
689 }
690 #endif
691
692 #ifdef GRAVE_ESC_CTRL_OVERRIDE
693 // if CTRL is pressed, ESC is always sent
694 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
695 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
696 shifted = 0;
697 }
698 #endif
699
700 #ifdef GRAVE_ESC_GUI_OVERRIDE
701 // if GUI is pressed, ESC is always sent
702 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
703 shifted = 0;
704 }
705 #endif
706
707 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
708 // if SHIFT is pressed, ESC is always sent
709 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
710 shifted = 0;
711 }
712 #endif
713
714 if (record->event.pressed) {
715 grave_esc_was_shifted = shifted;
716 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
717 }
718 else {
719 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
720 }
721
722 send_keyboard_report();
723 return false;
724 }
725
726 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
727 case BL_BRTG: {
728 if (record->event.pressed)
729 breathing_toggle();
730 return false;
731 }
732 #endif
733
734 default: {
735 shift_interrupted[0] = true;
736 shift_interrupted[1] = true;
737 break;
738 }
739 }
740
741 return process_action_kb(record);
742 }
743
744 __attribute__ ((weak))
745 const bool ascii_to_shift_lut[0x80] PROGMEM = {
746 0, 0, 0, 0, 0, 0, 0, 0,
747 0, 0, 0, 0, 0, 0, 0, 0,
748 0, 0, 0, 0, 0, 0, 0, 0,
749 0, 0, 0, 0, 0, 0, 0, 0,
750 0, 1, 1, 1, 1, 1, 1, 0,
751 1, 1, 1, 1, 0, 0, 0, 0,
752 0, 0, 0, 0, 0, 0, 0, 0,
753 0, 0, 1, 0, 1, 0, 1, 1,
754 1, 1, 1, 1, 1, 1, 1, 1,
755 1, 1, 1, 1, 1, 1, 1, 1,
756 1, 1, 1, 1, 1, 1, 1, 1,
757 1, 1, 1, 0, 0, 0, 1, 1,
758 0, 0, 0, 0, 0, 0, 0, 0,
759 0, 0, 0, 0, 0, 0, 0, 0,
760 0, 0, 0, 0, 0, 0, 0, 0,
761 0, 0, 0, 1, 1, 1, 1, 0
762 };
763
764 __attribute__ ((weak))
765 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
766 0, 0, 0, 0, 0, 0, 0, 0,
767 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
768 0, 0, 0, 0, 0, 0, 0, 0,
769 0, 0, 0, KC_ESC, 0, 0, 0, 0,
770 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
771 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
772 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
773 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
774 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
775 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
776 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
777 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
778 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
779 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
780 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
781 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
782 };
783
784 void send_string(const char *str) {
785 send_string_with_delay(str, 0);
786 }
787
788 void send_string_P(const char *str) {
789 send_string_with_delay_P(str, 0);
790 }
791
792 void send_string_with_delay(const char *str, uint8_t interval) {
793 while (1) {
794 char ascii_code = *str;
795 if (!ascii_code) break;
796 if (ascii_code == 1) {
797 // tap
798 uint8_t keycode = *(++str);
799 register_code(keycode);
800 unregister_code(keycode);
801 } else if (ascii_code == 2) {
802 // down
803 uint8_t keycode = *(++str);
804 register_code(keycode);
805 } else if (ascii_code == 3) {
806 // up
807 uint8_t keycode = *(++str);
808 unregister_code(keycode);
809 } else {
810 send_char(ascii_code);
811 }
812 ++str;
813 // interval
814 { uint8_t ms = interval; while (ms--) wait_ms(1); }
815 }
816 }
817
818 void send_string_with_delay_P(const char *str, uint8_t interval) {
819 while (1) {
820 char ascii_code = pgm_read_byte(str);
821 if (!ascii_code) break;
822 if (ascii_code == 1) {
823 // tap
824 uint8_t keycode = pgm_read_byte(++str);
825 register_code(keycode);
826 unregister_code(keycode);
827 } else if (ascii_code == 2) {
828 // down
829 uint8_t keycode = pgm_read_byte(++str);
830 register_code(keycode);
831 } else if (ascii_code == 3) {
832 // up
833 uint8_t keycode = pgm_read_byte(++str);
834 unregister_code(keycode);
835 } else {
836 send_char(ascii_code);
837 }
838 ++str;
839 // interval
840 { uint8_t ms = interval; while (ms--) wait_ms(1); }
841 }
842 }
843
844 void send_char(char ascii_code) {
845 uint8_t keycode;
846 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
847 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
848 register_code(KC_LSFT);
849 register_code(keycode);
850 unregister_code(keycode);
851 unregister_code(KC_LSFT);
852 } else {
853 register_code(keycode);
854 unregister_code(keycode);
855 }
856 }
857
858 void set_single_persistent_default_layer(uint8_t default_layer) {
859 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
860 PLAY_SONG(default_layer_songs[default_layer]);
861 #endif
862 eeconfig_update_default_layer(1U<<default_layer);
863 default_layer_set(1U<<default_layer);
864 }
865
866 uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
867 uint32_t mask12 = (1UL << layer1) | (1UL << layer2);
868 uint32_t mask3 = 1UL << layer3;
869 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
870 }
871
872 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
873 layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
874 }
875
876 void tap_random_base64(void) {
877 #if defined(__AVR_ATmega32U4__)
878 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
879 #else
880 uint8_t key = rand() % 64;
881 #endif
882 switch (key) {
883 case 0 ... 25:
884 register_code(KC_LSFT);
885 register_code(key + KC_A);
886 unregister_code(key + KC_A);
887 unregister_code(KC_LSFT);
888 break;
889 case 26 ... 51:
890 register_code(key - 26 + KC_A);
891 unregister_code(key - 26 + KC_A);
892 break;
893 case 52:
894 register_code(KC_0);
895 unregister_code(KC_0);
896 break;
897 case 53 ... 61:
898 register_code(key - 53 + KC_1);
899 unregister_code(key - 53 + KC_1);
900 break;
901 case 62:
902 register_code(KC_LSFT);
903 register_code(KC_EQL);
904 unregister_code(KC_EQL);
905 unregister_code(KC_LSFT);
906 break;
907 case 63:
908 register_code(KC_SLSH);
909 unregister_code(KC_SLSH);
910 break;
911 }
912 }
913
914 void matrix_init_quantum() {
915 #ifdef BACKLIGHT_ENABLE
916 backlight_init_ports();
917 #endif
918 #ifdef AUDIO_ENABLE
919 audio_init();
920 #endif
921 #ifdef RGB_MATRIX_ENABLE
922 rgb_matrix_init();
923 #endif
924 matrix_init_kb();
925 }
926
927 uint8_t rgb_matrix_task_counter = 0;
928
929 #ifndef RGB_MATRIX_SKIP_FRAMES
930 #define RGB_MATRIX_SKIP_FRAMES 1
931 #endif
932
933 void matrix_scan_quantum() {
934 #if defined(AUDIO_ENABLE)
935 matrix_scan_music();
936 #endif
937
938 #ifdef TAP_DANCE_ENABLE
939 matrix_scan_tap_dance();
940 #endif
941
942 #ifdef COMBO_ENABLE
943 matrix_scan_combo();
944 #endif
945
946 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
947 backlight_task();
948 #endif
949
950 #ifdef RGB_MATRIX_ENABLE
951 rgb_matrix_task();
952 if (rgb_matrix_task_counter == 0) {
953 rgb_matrix_update_pwm_buffers();
954 }
955 rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1));
956 #endif
957
958 matrix_scan_kb();
959 }
960 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
961
962 static const uint8_t backlight_pin = BACKLIGHT_PIN;
963
964 // depending on the pin, we use a different output compare unit
965 #if BACKLIGHT_PIN == B7
966 # define TCCRxA TCCR1A
967 # define TCCRxB TCCR1B
968 # define COMxx1 COM1C1
969 # define OCRxx OCR1C
970 # define ICRx ICR1
971 #elif BACKLIGHT_PIN == B6
972 # define TCCRxA TCCR1A
973 # define TCCRxB TCCR1B
974 # define COMxx1 COM1B1
975 # define OCRxx OCR1B
976 # define ICRx ICR1
977 #elif BACKLIGHT_PIN == B5
978 # define TCCRxA TCCR1A
979 # define TCCRxB TCCR1B
980 # define COMxx1 COM1A1
981 # define OCRxx OCR1A
982 # define ICRx ICR1
983 #elif BACKLIGHT_PIN == C6
984 # define TCCRxA TCCR3A
985 # define TCCRxB TCCR3B
986 # define COMxx1 COM1A1
987 # define OCRxx OCR3A
988 # define ICRx ICR3
989 #else
990 # define NO_HARDWARE_PWM
991 #endif
992
993 #ifndef BACKLIGHT_ON_STATE
994 #define BACKLIGHT_ON_STATE 0
995 #endif
996
997 #ifdef NO_HARDWARE_PWM // pwm through software
998
999 __attribute__ ((weak))
1000 void backlight_init_ports(void)
1001 {
1002 // Setup backlight pin as output and output to on state.
1003 // DDRx |= n
1004 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
1005 #if BACKLIGHT_ON_STATE == 0
1006 // PORTx &= ~n
1007 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1008 #else
1009 // PORTx |= n
1010 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1011 #endif
1012 }
1013
1014 __attribute__ ((weak))
1015 void backlight_set(uint8_t level) {}
1016
1017 uint8_t backlight_tick = 0;
1018
1019 #ifndef BACKLIGHT_CUSTOM_DRIVER
1020 void backlight_task(void) {
1021 if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
1022 #if BACKLIGHT_ON_STATE == 0
1023 // PORTx &= ~n
1024 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1025 #else
1026 // PORTx |= n
1027 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1028 #endif
1029 } else {
1030 #if BACKLIGHT_ON_STATE == 0
1031 // PORTx |= n
1032 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1033 #else
1034 // PORTx &= ~n
1035 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1036 #endif
1037 }
1038 backlight_tick = (backlight_tick + 1) % 16;
1039 }
1040 #endif
1041
1042 #ifdef BACKLIGHT_BREATHING
1043 #ifndef BACKLIGHT_CUSTOM_DRIVER
1044 #error "Backlight breathing only available with hardware PWM. Please disable."
1045 #endif
1046 #endif
1047
1048 #else // pwm through timer
1049
1050 #define TIMER_TOP 0xFFFFU
1051
1052 // See http://jared.geek.nz/2013/feb/linear-led-pwm
1053 static uint16_t cie_lightness(uint16_t v) {
1054 if (v <= 5243) // if below 8% of max
1055 return v / 9; // same as dividing by 900%
1056 else {
1057 uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
1058 // to get a useful result with integer division, we shift left in the expression above
1059 // and revert what we've done again after squaring.
1060 y = y * y * y >> 8;
1061 if (y > 0xFFFFUL) // prevent overflow
1062 return 0xFFFFU;
1063 else
1064 return (uint16_t) y;
1065 }
1066 }
1067
1068 // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
1069 static inline void set_pwm(uint16_t val) {
1070 OCRxx = val;
1071 }
1072
1073 #ifndef BACKLIGHT_CUSTOM_DRIVER
1074 __attribute__ ((weak))
1075 void backlight_set(uint8_t level) {
1076 if (level > BACKLIGHT_LEVELS)
1077 level = BACKLIGHT_LEVELS;
1078
1079 if (level == 0) {
1080 // Turn off PWM control on backlight pin
1081 TCCRxA &= ~(_BV(COMxx1));
1082 } else {
1083 // Turn on PWM control of backlight pin
1084 TCCRxA |= _BV(COMxx1);
1085 }
1086 // Set the brightness
1087 set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
1088 }
1089
1090 void backlight_task(void) {}
1091 #endif // BACKLIGHT_CUSTOM_DRIVER
1092
1093 #ifdef BACKLIGHT_BREATHING
1094
1095 #define BREATHING_NO_HALT 0
1096 #define BREATHING_HALT_OFF 1
1097 #define BREATHING_HALT_ON 2
1098 #define BREATHING_STEPS 128
1099
1100 static uint8_t breathing_period = BREATHING_PERIOD;
1101 static uint8_t breathing_halt = BREATHING_NO_HALT;
1102 static uint16_t breathing_counter = 0;
1103
1104 bool is_breathing(void) {
1105 return !!(TIMSK1 & _BV(TOIE1));
1106 }
1107
1108 #define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0)
1109 #define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0)
1110 #define breathing_min() do {breathing_counter = 0;} while (0)
1111 #define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
1112
1113 void breathing_enable(void)
1114 {
1115 breathing_counter = 0;
1116 breathing_halt = BREATHING_NO_HALT;
1117 breathing_interrupt_enable();
1118 }
1119
1120 void breathing_pulse(void)
1121 {
1122 if (get_backlight_level() == 0)
1123 breathing_min();
1124 else
1125 breathing_max();
1126 breathing_halt = BREATHING_HALT_ON;
1127 breathing_interrupt_enable();
1128 }
1129
1130 void breathing_disable(void)
1131 {
1132 breathing_interrupt_disable();
1133 // Restore backlight level
1134 backlight_set(get_backlight_level());
1135 }
1136
1137 void breathing_self_disable(void)
1138 {
1139 if (get_backlight_level() == 0)
1140 breathing_halt = BREATHING_HALT_OFF;
1141 else
1142 breathing_halt = BREATHING_HALT_ON;
1143 }
1144
1145 void breathing_toggle(void) {
1146 if (is_breathing())
1147 breathing_disable();
1148 else
1149 breathing_enable();
1150 }
1151
1152 void breathing_period_set(uint8_t value)
1153 {
1154 if (!value)
1155 value = 1;
1156 breathing_period = value;
1157 }
1158
1159 void breathing_period_default(void) {
1160 breathing_period_set(BREATHING_PERIOD);
1161 }
1162
1163 void breathing_period_inc(void)
1164 {
1165 breathing_period_set(breathing_period+1);
1166 }
1167
1168 void breathing_period_dec(void)
1169 {
1170 breathing_period_set(breathing_period-1);
1171 }
1172
1173 /* To generate breathing curve in python:
1174 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
1175 */
1176 static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1177
1178 // Use this before the cie_lightness function.
1179 static inline uint16_t scale_backlight(uint16_t v) {
1180 return v / BACKLIGHT_LEVELS * get_backlight_level();
1181 }
1182
1183 /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1184 * about 244 times per second.
1185 */
1186 ISR(TIMER1_OVF_vect)
1187 {
1188 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
1189 // resetting after one period to prevent ugly reset at overflow.
1190 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
1191 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
1192
1193 if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
1194 ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
1195 {
1196 breathing_interrupt_disable();
1197 }
1198
1199 set_pwm(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
1200 }
1201
1202 #endif // BACKLIGHT_BREATHING
1203
1204 __attribute__ ((weak))
1205 void backlight_init_ports(void)
1206 {
1207 // Setup backlight pin as output and output to on state.
1208 // DDRx |= n
1209 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
1210 #if BACKLIGHT_ON_STATE == 0
1211 // PORTx &= ~n
1212 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1213 #else
1214 // PORTx |= n
1215 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1216 #endif
1217 // I could write a wall of text here to explain... but TL;DW
1218 // Go read the ATmega32u4 datasheet.
1219 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
1220
1221 // Pin PB7 = OCR1C (Timer 1, Channel C)
1222 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
1223 // (i.e. start high, go low when counter matches.)
1224 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
1225 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
1226
1227 /*
1228 14.8.3:
1229 "In fast PWM mode, the compare units allow generation of PWM waveforms on the OCnx pins. Setting the COMnx1:0 bits to two will produce a non-inverted PWM [..]."
1230 "In fast PWM mode the counter is incremented until the counter value matches either one of the fixed values 0x00FF, 0x01FF, or 0x03FF (WGMn3:0 = 5, 6, or 7), the value in ICRn (WGMn3:0 = 14), or the value in OCRnA (WGMn3:0 = 15)."
1231 */
1232 TCCRxA = _BV(COMxx1) | _BV(WGM11); // = 0b00001010;
1233 TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1234 // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0.
1235 ICRx = TIMER_TOP;
1236
1237 backlight_init();
1238 #ifdef BACKLIGHT_BREATHING
1239 breathing_enable();
1240 #endif
1241 }
1242
1243 #endif // NO_HARDWARE_PWM
1244
1245 #else // backlight
1246
1247 __attribute__ ((weak))
1248 void backlight_init_ports(void) {}
1249
1250 __attribute__ ((weak))
1251 void backlight_set(uint8_t level) {}
1252
1253 #endif // backlight
1254
1255 #ifdef HD44780_ENABLED
1256 #include "hd44780.h"
1257 #endif
1258
1259
1260 // Functions for spitting out values
1261 //
1262
1263 void send_dword(uint32_t number) { // this might not actually work
1264 uint16_t word = (number >> 16);
1265 send_word(word);
1266 send_word(number & 0xFFFFUL);
1267 }
1268
1269 void send_word(uint16_t number) {
1270 uint8_t byte = number >> 8;
1271 send_byte(byte);
1272 send_byte(number & 0xFF);
1273 }
1274
1275 void send_byte(uint8_t number) {
1276 uint8_t nibble = number >> 4;
1277 send_nibble(nibble);
1278 send_nibble(number & 0xF);
1279 }
1280
1281 void send_nibble(uint8_t number) {
1282 switch (number) {
1283 case 0:
1284 register_code(KC_0);
1285 unregister_code(KC_0);
1286 break;
1287 case 1 ... 9:
1288 register_code(KC_1 + (number - 1));
1289 unregister_code(KC_1 + (number - 1));
1290 break;
1291 case 0xA ... 0xF:
1292 register_code(KC_A + (number - 0xA));
1293 unregister_code(KC_A + (number - 0xA));
1294 break;
1295 }
1296 }
1297
1298
1299 __attribute__((weak))
1300 uint16_t hex_to_keycode(uint8_t hex)
1301 {
1302 hex = hex & 0xF;
1303 if (hex == 0x0) {
1304 return KC_0;
1305 } else if (hex < 0xA) {
1306 return KC_1 + (hex - 0x1);
1307 } else {
1308 return KC_A + (hex - 0xA);
1309 }
1310 }
1311
1312 void api_send_unicode(uint32_t unicode) {
1313 #ifdef API_ENABLE
1314 uint8_t chunk[4];
1315 dword_to_bytes(unicode, chunk);
1316 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1317 #endif
1318 }
1319
1320 __attribute__ ((weak))
1321 void led_set_user(uint8_t usb_led) {
1322
1323 }
1324
1325 __attribute__ ((weak))
1326 void led_set_kb(uint8_t usb_led) {
1327 led_set_user(usb_led);
1328 }
1329
1330 __attribute__ ((weak))
1331 void led_init_ports(void)
1332 {
1333
1334 }
1335
1336 __attribute__ ((weak))
1337 void led_set(uint8_t usb_led)
1338 {
1339
1340 // Example LED Code
1341 //
1342 // // Using PE6 Caps Lock LED
1343 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1344 // {
1345 // // Output high.
1346 // DDRE |= (1<<6);
1347 // PORTE |= (1<<6);
1348 // }
1349 // else
1350 // {
1351 // // Output low.
1352 // DDRE &= ~(1<<6);
1353 // PORTE &= ~(1<<6);
1354 // }
1355
1356 led_set_kb(usb_led);
1357 }
1358
1359
1360 //------------------------------------------------------------------------------
1361 // Override these functions in your keymap file to play different tunes on
1362 // different events such as startup and bootloader jump
1363
1364 __attribute__ ((weak))
1365 void startup_user() {}
1366
1367 __attribute__ ((weak))
1368 void shutdown_user() {}
1369
1370 //------------------------------------------------------------------------------