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/>.
19 #if !defined(RGBLIGHT_ENABLE) && !defined(RGB_MATRIX_ENABLE)
24 # include "outputselect.h"
27 #ifndef BREATHING_PERIOD
28 # define BREATHING_PERIOD 6
31 #include "backlight.h"
32 extern backlight_config_t backlight_config;
34 #ifdef FAUXCLICKY_ENABLE
35 # include "fauxclicky.h"
43 # include "process_midi.h"
46 #ifdef VELOCIKEY_ENABLE
47 # include "velocikey.h"
60 # define GOODBYE_SONG SONG(GOODBYE_SOUND)
63 # define AG_NORM_SONG SONG(AG_NORM_SOUND)
66 # define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
69 # define CG_NORM_SONG SONG(AG_NORM_SOUND)
72 # define CG_SWAP_SONG SONG(AG_SWAP_SOUND)
74 float goodbye_song[][2] = GOODBYE_SONG;
75 float ag_norm_song[][2] = AG_NORM_SONG;
76 float ag_swap_song[][2] = AG_SWAP_SONG;
77 float cg_norm_song[][2] = CG_NORM_SONG;
78 float cg_swap_song[][2] = CG_SWAP_SONG;
79 # ifdef DEFAULT_LAYER_SONGS
80 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
84 static void do_code16(uint16_t code, void (*f)(uint8_t)) {
86 case QK_MODS ... QK_MODS_MAX:
92 if (code & QK_LCTL) f(KC_LCTL);
93 if (code & QK_LSFT) f(KC_LSFT);
94 if (code & QK_LALT) f(KC_LALT);
95 if (code & QK_LGUI) f(KC_LGUI);
97 if (code < QK_RMODS_MIN) return;
99 if (code & QK_RCTL) f(KC_RCTL);
100 if (code & QK_RSFT) f(KC_RSFT);
101 if (code & QK_RALT) f(KC_RALT);
102 if (code & QK_RGUI) f(KC_RGUI);
105 static inline void qk_register_weak_mods(uint8_t kc) {
106 add_weak_mods(MOD_BIT(kc));
107 send_keyboard_report();
110 static inline void qk_unregister_weak_mods(uint8_t kc) {
111 del_weak_mods(MOD_BIT(kc));
112 send_keyboard_report();
115 static inline void qk_register_mods(uint8_t kc) {
116 add_weak_mods(MOD_BIT(kc));
117 send_keyboard_report();
120 static inline void qk_unregister_mods(uint8_t kc) {
121 del_weak_mods(MOD_BIT(kc));
122 send_keyboard_report();
125 void register_code16(uint16_t code) {
126 if (IS_MOD(code) || code == KC_NO) {
127 do_code16(code, qk_register_mods);
129 do_code16(code, qk_register_weak_mods);
134 void unregister_code16(uint16_t code) {
135 unregister_code(code);
136 if (IS_MOD(code) || code == KC_NO) {
137 do_code16(code, qk_unregister_mods);
139 do_code16(code, qk_unregister_weak_mods);
143 void tap_code16(uint16_t code) {
144 register_code16(code);
145 #if TAP_CODE_DELAY > 0
146 wait_ms(TAP_CODE_DELAY);
148 unregister_code16(code);
151 __attribute__((weak)) bool process_action_kb(keyrecord_t *record) { return true; }
153 __attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { return process_record_user(keycode, record); }
155 __attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { return true; }
157 void reset_keyboard(void) {
159 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
160 process_midi_all_notes_off();
163 # ifndef NO_MUSIC_MODE
164 music_all_notes_off();
166 uint16_t timer_start = timer_read();
167 PLAY_SONG(goodbye_song);
169 while (timer_elapsed(timer_start) < 250) wait_ms(1);
178 // this is also done later in bootloader.c - not sure if it's neccesary here
179 #ifdef BOOTLOADER_CATERINA
180 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
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.
188 static bool grave_esc_was_shifted = false;
190 /* Convert record into usable keycode via the contained event. */
191 uint16_t get_record_keycode(keyrecord_t *record) { return get_event_keycode(record->event); }
193 /* Convert event into usable keycode. Checks the layer cache to ensure that it
194 * retains the correct keycode after a layer change, if the key is still pressed.
196 uint16_t get_event_keycode(keyevent_t event) {
197 #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
198 /* TODO: Use store_or_get_action() or a similar function. */
199 if (!disable_action_cache) {
203 layer = layer_switch_get_layer(event.key);
204 update_source_layers_cache(event.key, layer);
206 layer = read_source_layers_cache(event.key);
208 return keymap_key_to_keycode(layer, event.key);
211 return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key);
214 /* Main keycode processing function. Hands off handling to other functions,
215 * then processes internal Quantum keycodes, then processes ACTIONs.
217 bool process_record_quantum(keyrecord_t *record) {
218 uint16_t keycode = get_record_keycode(record);
220 // This is how you use actions here
221 // if (keycode == KC_LEAD) {
223 // action.code = ACTION_DEFAULT_LAYER_SET(0);
224 // process_action(record, action);
228 #ifdef VELOCIKEY_ENABLE
229 if (velocikey_enabled() && record->event.pressed) {
230 velocikey_accelerate();
234 #ifdef TAP_DANCE_ENABLE
235 preprocess_tap_dance(keycode, record);
239 #if defined(KEY_LOCK_ENABLE)
240 // Must run first to be able to mask key_up events.
241 process_key_lock(&keycode, record) &&
243 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
244 process_clicky(keycode, record) &&
245 #endif // AUDIO_CLICKY
247 process_haptic(keycode, record) &&
248 #endif // HAPTIC_ENABLE
249 #if defined(RGB_MATRIX_ENABLE)
250 process_rgb_matrix(keycode, record) &&
252 process_record_kb(keycode, record) &&
253 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
254 process_midi(keycode, record) &&
257 process_audio(keycode, record) &&
260 process_steno(keycode, record) &&
262 #if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
263 process_music(keycode, record) &&
265 #ifdef TAP_DANCE_ENABLE
266 process_tap_dance(keycode, record) &&
268 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
269 process_unicode_common(keycode, record) &&
272 process_leader(keycode, record) &&
275 process_combo(keycode, record) &&
277 #ifdef PRINTING_ENABLE
278 process_printer(keycode, record) &&
280 #ifdef AUTO_SHIFT_ENABLE
281 process_auto_shift(keycode, record) &&
283 #ifdef TERMINAL_ENABLE
284 process_terminal(keycode, record) &&
286 #ifdef SPACE_CADET_ENABLE
287 process_space_cadet(keycode, record) &&
293 // Shift / paren setup
297 if (record->event.pressed) {
302 if (record->event.pressed) {
305 print("DEBUG: enabled.\n");
307 print("DEBUG: disabled.\n");
312 if (record->event.pressed) {
316 #ifdef FAUXCLICKY_ENABLE
318 if (record->event.pressed) {
323 if (record->event.pressed) {
328 if (record->event.pressed) {
333 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
335 // Split keyboards need to trigger on key-up for edge-case issue
336 # ifndef SPLIT_KEYBOARD
337 if (record->event.pressed) {
339 if (!record->event.pressed) {
344 case RGB_MODE_FORWARD:
345 if (record->event.pressed) {
346 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
348 rgblight_step_reverse();
354 case RGB_MODE_REVERSE:
355 if (record->event.pressed) {
356 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
360 rgblight_step_reverse();
365 // Split keyboards need to trigger on key-up for edge-case issue
366 # ifndef SPLIT_KEYBOARD
367 if (record->event.pressed) {
369 if (!record->event.pressed) {
371 rgblight_increase_hue();
375 // Split keyboards need to trigger on key-up for edge-case issue
376 # ifndef SPLIT_KEYBOARD
377 if (record->event.pressed) {
379 if (!record->event.pressed) {
381 rgblight_decrease_hue();
385 // Split keyboards need to trigger on key-up for edge-case issue
386 # ifndef SPLIT_KEYBOARD
387 if (record->event.pressed) {
389 if (!record->event.pressed) {
391 rgblight_increase_sat();
395 // Split keyboards need to trigger on key-up for edge-case issue
396 # ifndef SPLIT_KEYBOARD
397 if (record->event.pressed) {
399 if (!record->event.pressed) {
401 rgblight_decrease_sat();
405 // Split keyboards need to trigger on key-up for edge-case issue
406 # ifndef SPLIT_KEYBOARD
407 if (record->event.pressed) {
409 if (!record->event.pressed) {
411 rgblight_increase_val();
415 // Split keyboards need to trigger on key-up for edge-case issue
416 # ifndef SPLIT_KEYBOARD
417 if (record->event.pressed) {
419 if (!record->event.pressed) {
421 rgblight_decrease_val();
425 if (record->event.pressed) {
426 rgblight_increase_speed();
430 if (record->event.pressed) {
431 rgblight_decrease_speed();
435 if (record->event.pressed) {
436 rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
439 case RGB_MODE_BREATHE:
440 # ifdef RGBLIGHT_EFFECT_BREATHING
441 if (record->event.pressed) {
442 if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
445 rgblight_mode(RGBLIGHT_MODE_BREATHING);
450 case RGB_MODE_RAINBOW:
451 # ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
452 if (record->event.pressed) {
453 if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
456 rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
462 # ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
463 if (record->event.pressed) {
464 if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
467 rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
473 # ifdef RGBLIGHT_EFFECT_SNAKE
474 if (record->event.pressed) {
475 if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
478 rgblight_mode(RGBLIGHT_MODE_SNAKE);
483 case RGB_MODE_KNIGHT:
484 # ifdef RGBLIGHT_EFFECT_KNIGHT
485 if (record->event.pressed) {
486 if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
489 rgblight_mode(RGBLIGHT_MODE_KNIGHT);
495 # ifdef RGBLIGHT_EFFECT_CHRISTMAS
496 if (record->event.pressed) {
497 rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
501 case RGB_MODE_GRADIENT:
502 # ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
503 if (record->event.pressed) {
504 if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) && (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
507 rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
512 case RGB_MODE_RGBTEST:
513 # ifdef RGBLIGHT_EFFECT_RGB_TEST
514 if (record->event.pressed) {
515 rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
519 #endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
520 #ifdef VELOCIKEY_ENABLE
522 if (record->event.pressed) {
529 if (record->event.pressed) {
530 set_output(OUTPUT_AUTO);
534 if (record->event.pressed) {
535 set_output(OUTPUT_USB);
538 # ifdef BLUETOOTH_ENABLE
540 if (record->event.pressed) {
541 set_output(OUTPUT_BLUETOOTH);
546 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_ALT_GUI:
547 case MAGIC_SWAP_LCTL_LGUI ... MAGIC_TOGGLE_CTL_GUI:
548 if (record->event.pressed) {
549 // MAGIC actions (BOOTMAGIC without the boot)
550 if (!eeconfig_is_enabled()) {
554 keymap_config.raw = eeconfig_read_keymap();
556 case MAGIC_SWAP_CONTROL_CAPSLOCK:
557 keymap_config.swap_control_capslock = true;
559 case MAGIC_CAPSLOCK_TO_CONTROL:
560 keymap_config.capslock_to_control = true;
562 case MAGIC_SWAP_LALT_LGUI:
563 keymap_config.swap_lalt_lgui = true;
565 case MAGIC_SWAP_RALT_RGUI:
566 keymap_config.swap_ralt_rgui = true;
568 case MAGIC_SWAP_LCTL_LGUI:
569 keymap_config.swap_lctl_lgui = true;
571 case MAGIC_SWAP_RCTL_RGUI:
572 keymap_config.swap_rctl_rgui = true;
575 keymap_config.no_gui = true;
577 case MAGIC_SWAP_GRAVE_ESC:
578 keymap_config.swap_grave_esc = true;
580 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
581 keymap_config.swap_backslash_backspace = true;
583 case MAGIC_HOST_NKRO:
584 keymap_config.nkro = true;
586 case MAGIC_SWAP_ALT_GUI:
587 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true;
589 PLAY_SONG(ag_swap_song);
592 case MAGIC_SWAP_CTL_GUI:
593 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true;
595 PLAY_SONG(cg_swap_song);
598 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
599 keymap_config.swap_control_capslock = false;
601 case MAGIC_UNCAPSLOCK_TO_CONTROL:
602 keymap_config.capslock_to_control = false;
604 case MAGIC_UNSWAP_LALT_LGUI:
605 keymap_config.swap_lalt_lgui = false;
607 case MAGIC_UNSWAP_RALT_RGUI:
608 keymap_config.swap_ralt_rgui = false;
610 case MAGIC_UNSWAP_LCTL_LGUI:
611 keymap_config.swap_lctl_lgui = false;
613 case MAGIC_UNSWAP_RCTL_RGUI:
614 keymap_config.swap_rctl_rgui = false;
617 keymap_config.no_gui = false;
619 case MAGIC_UNSWAP_GRAVE_ESC:
620 keymap_config.swap_grave_esc = false;
622 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
623 keymap_config.swap_backslash_backspace = false;
625 case MAGIC_UNHOST_NKRO:
626 keymap_config.nkro = false;
628 case MAGIC_UNSWAP_ALT_GUI:
629 keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false;
631 PLAY_SONG(ag_norm_song);
634 case MAGIC_UNSWAP_CTL_GUI:
635 keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false;
637 PLAY_SONG(cg_norm_song);
640 case MAGIC_TOGGLE_ALT_GUI:
641 keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui;
642 keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui;
644 if (keymap_config.swap_ralt_rgui) {
645 PLAY_SONG(ag_swap_song);
647 PLAY_SONG(ag_norm_song);
651 case MAGIC_TOGGLE_CTL_GUI:
652 keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui;
653 keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui;
655 if (keymap_config.swap_rctl_rgui) {
656 PLAY_SONG(cg_swap_song);
658 PLAY_SONG(cg_norm_song);
662 case MAGIC_TOGGLE_NKRO:
663 keymap_config.nkro = !keymap_config.nkro;
668 eeconfig_update_keymap(keymap_config.raw);
669 clear_keyboard(); // clear to prevent stuck keys
676 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT) | MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)));
678 #ifdef GRAVE_ESC_ALT_OVERRIDE
679 // if ALT is pressed, ESC is always sent
680 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
681 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
686 #ifdef GRAVE_ESC_CTRL_OVERRIDE
687 // if CTRL is pressed, ESC is always sent
688 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
689 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
694 #ifdef GRAVE_ESC_GUI_OVERRIDE
695 // if GUI is pressed, ESC is always sent
696 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
701 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
702 // if SHIFT is pressed, ESC is always sent
703 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
708 if (record->event.pressed) {
709 grave_esc_was_shifted = shifted;
710 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
712 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
715 send_keyboard_report();
719 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
721 if (record->event.pressed) {
722 backlight_toggle_breathing();
729 return process_action_kb(record);
732 __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,
734 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};
736 __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,
738 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};
740 __attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = {// NUL SOH STX ETX EOT ENQ ACK BEL
741 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
742 // BS TAB LF VT FF CR SO SI
743 KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
744 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB
745 XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
746 // CAN EM SUB ESC FS GS RS US
747 XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
750 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
752 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
754 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
756 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
758 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
760 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
762 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
764 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
766 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
768 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
770 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
772 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL};
774 void send_string(const char *str) { send_string_with_delay(str, 0); }
776 void send_string_P(const char *str) { send_string_with_delay_P(str, 0); }
778 void send_string_with_delay(const char *str, uint8_t interval) {
780 char ascii_code = *str;
781 if (!ascii_code) break;
782 if (ascii_code == SS_TAP_CODE) {
784 uint8_t keycode = *(++str);
785 register_code(keycode);
786 unregister_code(keycode);
787 } else if (ascii_code == SS_DOWN_CODE) {
789 uint8_t keycode = *(++str);
790 register_code(keycode);
791 } else if (ascii_code == SS_UP_CODE) {
793 uint8_t keycode = *(++str);
794 unregister_code(keycode);
796 send_char(ascii_code);
801 uint8_t ms = interval;
802 while (ms--) wait_ms(1);
807 void send_string_with_delay_P(const char *str, uint8_t interval) {
809 char ascii_code = pgm_read_byte(str);
810 if (!ascii_code) break;
811 if (ascii_code == SS_TAP_CODE) {
813 uint8_t keycode = pgm_read_byte(++str);
814 register_code(keycode);
815 unregister_code(keycode);
816 } else if (ascii_code == SS_DOWN_CODE) {
818 uint8_t keycode = pgm_read_byte(++str);
819 register_code(keycode);
820 } else if (ascii_code == SS_UP_CODE) {
822 uint8_t keycode = pgm_read_byte(++str);
823 unregister_code(keycode);
825 send_char(ascii_code);
830 uint8_t ms = interval;
831 while (ms--) wait_ms(1);
836 void send_char(char ascii_code) {
837 uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
838 bool is_shifted = pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code]);
839 bool is_altgred = pgm_read_byte(&ascii_to_altgr_lut[(uint8_t)ascii_code]);
842 register_code(KC_LSFT);
845 register_code(KC_RALT);
849 unregister_code(KC_RALT);
852 unregister_code(KC_LSFT);
856 void set_single_persistent_default_layer(uint8_t default_layer) {
857 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
858 PLAY_SONG(default_layer_songs[default_layer]);
860 eeconfig_update_default_layer(1U << default_layer);
861 default_layer_set(1U << default_layer);
864 layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
865 layer_state_t mask12 = (1UL << layer1) | (1UL << layer2);
866 layer_state_t mask3 = 1UL << layer3;
867 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
870 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)); }
872 void tap_random_base64(void) {
873 #if defined(__AVR_ATmega32U4__)
874 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
876 uint8_t key = rand() % 64;
880 register_code(KC_LSFT);
881 register_code(key + KC_A);
882 unregister_code(key + KC_A);
883 unregister_code(KC_LSFT);
886 register_code(key - 26 + KC_A);
887 unregister_code(key - 26 + KC_A);
891 unregister_code(KC_0);
894 register_code(key - 53 + KC_1);
895 unregister_code(key - 53 + KC_1);
898 register_code(KC_LSFT);
899 register_code(KC_EQL);
900 unregister_code(KC_EQL);
901 unregister_code(KC_LSFT);
904 register_code(KC_SLSH);
905 unregister_code(KC_SLSH);
910 __attribute__((weak)) void bootmagic_lite(void) {
911 // The lite version of TMK's bootmagic based on Wilba.
912 // 100% less potential for accidentally making the
913 // keyboard do stupid things.
915 // We need multiple scans because debouncing can't be turned off.
917 #if defined(DEBOUNCING_DELAY) && DEBOUNCING_DELAY > 0
918 wait_ms(DEBOUNCING_DELAY * 2);
919 #elif defined(DEBOUNCE) && DEBOUNCE > 0
920 wait_ms(DEBOUNCE * 2);
926 // If the Esc and space bar are held down on power up,
927 // reset the EEPROM valid state and jump to bootloader.
928 // Assumes Esc is at [0,0].
929 // This isn't very generalized, but we need something that doesn't
930 // rely on user's keymaps in firmware or EEPROM.
931 if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
933 // Jump to bootloader.
938 void matrix_init_quantum() {
939 #ifdef BOOTMAGIC_LITE
942 if (!eeconfig_is_enabled()) {
945 #ifdef BACKLIGHT_ENABLE
946 # ifdef LED_MATRIX_ENABLE
949 backlight_init_ports();
955 #ifdef RGB_MATRIX_ENABLE
958 #ifdef ENCODER_ENABLE
961 #if defined(UNICODE_ENABLE) || defined(UNICODEMAP_ENABLE) || defined(UCIS_ENABLE)
962 unicode_input_mode_init();
967 #ifdef OUTPUT_AUTO_ENABLE
968 set_output(OUTPUT_AUTO);
970 #ifdef DIP_SWITCH_ENABLE
977 void matrix_scan_quantum() {
978 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
982 #ifdef TAP_DANCE_ENABLE
983 matrix_scan_tap_dance();
990 #if defined(BACKLIGHT_ENABLE)
991 # if defined(LED_MATRIX_ENABLE)
993 # elif defined(BACKLIGHT_PIN)
998 #ifdef RGB_MATRIX_ENABLE
1002 #ifdef ENCODER_ENABLE
1006 #ifdef HAPTIC_ENABLE
1010 #ifdef DIP_SWITCH_ENABLE
1011 dip_switch_read(false);
1016 #if defined(BACKLIGHT_ENABLE) && (defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS))
1018 // This logic is a bit complex, we support 3 setups:
1020 // 1. Hardware PWM when backlight is wired to a PWM pin.
1021 // Depending on this pin, we use a different output compare unit.
1022 // 2. Software PWM with hardware timers, but the used timer
1023 // depends on the Audio setup (Audio wins over Backlight).
1024 // 3. Full software PWM, driven by the matrix scan, if both timers are used by Audio.
1026 # if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) && (BACKLIGHT_PIN == B5 || BACKLIGHT_PIN == B6 || BACKLIGHT_PIN == B7)
1027 # define HARDWARE_PWM
1029 # define TCCRxA TCCR1A
1030 # define TCCRxB TCCR1B
1031 # define TIMERx_OVF_vect TIMER1_OVF_vect
1032 # define TIMSKx TIMSK1
1033 # define TOIEx TOIE1
1035 # if BACKLIGHT_PIN == B5
1036 # define COMxx1 COM1A1
1037 # define OCRxx OCR1A
1038 # elif BACKLIGHT_PIN == B6
1039 # define COMxx1 COM1B1
1040 # define OCRxx OCR1B
1041 # elif BACKLIGHT_PIN == B7
1042 # define COMxx1 COM1C1
1043 # define OCRxx OCR1C
1045 # elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) && (BACKLIGHT_PIN == C4 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6)
1046 # define HARDWARE_PWM
1048 # define TCCRxA TCCR3A
1049 # define TCCRxB TCCR3B
1050 # define TIMERx_OVF_vect TIMER3_OVF_vect
1051 # define TIMSKx TIMSK3
1052 # define TOIEx TOIE3
1054 # if BACKLIGHT_PIN == C4
1055 # if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
1056 # error This MCU has no C4 pin!
1058 # define COMxx1 COM3C1
1059 # define OCRxx OCR3C
1061 # elif BACKLIGHT_PIN == C5
1062 # if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
1063 # error This MCU has no C5 pin!
1065 # define COMxx1 COM3B1
1066 # define OCRxx OCR3B
1068 # elif BACKLIGHT_PIN == C6
1069 # define COMxx1 COM3A1
1070 # define OCRxx OCR3A
1072 # elif (defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__)) && (BACKLIGHT_PIN == B7 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6)
1073 # define HARDWARE_PWM
1075 # define TCCRxA TCCR1A
1076 # define TCCRxB TCCR1B
1077 # define TIMERx_OVF_vect TIMER1_OVF_vect
1078 # define TIMSKx TIMSK1
1079 # define TOIEx TOIE1
1081 # if BACKLIGHT_PIN == B7
1082 # define COMxx1 COM1C1
1083 # define OCRxx OCR1C
1084 # elif BACKLIGHT_PIN == C5
1085 # define COMxx1 COM1B1
1086 # define OCRxx OCR1B
1087 # elif BACKLIGHT_PIN == C6
1088 # define COMxx1 COM1A1
1089 # define OCRxx OCR1A
1091 # elif defined(__AVR_ATmega32A__) && (BACKLIGHT_PIN == D4 || BACKLIGHT_PIN == D5)
1092 # define HARDWARE_PWM
1094 # define TCCRxA TCCR1A
1095 # define TCCRxB TCCR1B
1096 # define TIMERx_OVF_vect TIMER1_OVF_vect
1097 # define TIMSKx TIMSK
1098 # define TOIEx TOIE1
1100 # if BACKLIGHT_PIN == D4
1101 # define COMxx1 COM1B1
1102 # define OCRxx OCR1B
1103 # elif BACKLIGHT_PIN == D5
1104 # define COMxx1 COM1A1
1105 # define OCRxx OCR1A
1108 # if !defined(BACKLIGHT_CUSTOM_DRIVER)
1109 # if !defined(B5_AUDIO) && !defined(B6_AUDIO) && !defined(B7_AUDIO)
1110 // Timer 1 is not in use by Audio feature, Backlight can use it
1111 # pragma message "Using hardware timer 1 with software PWM"
1112 # define HARDWARE_PWM
1113 # define BACKLIGHT_PWM_TIMER
1115 # define TCCRxA TCCR1A
1116 # define TCCRxB TCCR1B
1117 # define TIMERx_COMPA_vect TIMER1_COMPA_vect
1118 # define TIMERx_OVF_vect TIMER1_OVF_vect
1119 # if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register
1120 # define TIMSKx TIMSK
1122 # define TIMSKx TIMSK1
1124 # define TOIEx TOIE1
1126 # define OCIExA OCIE1A
1127 # define OCRxx OCR1A
1128 # elif !defined(C6_AUDIO) && !defined(C5_AUDIO) && !defined(C4_AUDIO)
1129 # pragma message "Using hardware timer 3 with software PWM"
1130 // Timer 3 is not in use by Audio feature, Backlight can use it
1131 # define HARDWARE_PWM
1132 # define BACKLIGHT_PWM_TIMER
1134 # define TCCRxA TCCR3A
1135 # define TCCRxB TCCR3B
1136 # define TIMERx_COMPA_vect TIMER3_COMPA_vect
1137 # define TIMERx_OVF_vect TIMER3_OVF_vect
1138 # define TIMSKx TIMSK3
1139 # define TOIEx TOIE3
1141 # define OCIExA OCIE3A
1142 # define OCRxx OCR3A
1144 # pragma message "Audio in use - using pure software PWM"
1145 # define NO_HARDWARE_PWM
1148 # pragma message "Custom driver defined - using pure software PWM"
1149 # define NO_HARDWARE_PWM
1153 # ifndef BACKLIGHT_ON_STATE
1154 # define BACKLIGHT_ON_STATE 0
1157 void backlight_on(uint8_t backlight_pin) {
1158 # if BACKLIGHT_ON_STATE == 0
1159 writePinLow(backlight_pin);
1161 writePinHigh(backlight_pin);
1165 void backlight_off(uint8_t backlight_pin) {
1166 # if BACKLIGHT_ON_STATE == 0
1167 writePinHigh(backlight_pin);
1169 writePinLow(backlight_pin);
1173 # if defined(NO_HARDWARE_PWM) || defined(BACKLIGHT_PWM_TIMER) // pwm through software
1175 // we support multiple backlight pins
1176 # ifndef BACKLIGHT_LED_COUNT
1177 # define BACKLIGHT_LED_COUNT 1
1180 # if BACKLIGHT_LED_COUNT == 1
1181 # define BACKLIGHT_PIN_INIT \
1184 # define BACKLIGHT_PIN_INIT BACKLIGHT_PINS
1187 # define FOR_EACH_LED(x) \
1188 for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \
1189 uint8_t backlight_pin = backlight_pins[i]; \
1193 static const uint8_t backlight_pins[BACKLIGHT_LED_COUNT] = BACKLIGHT_PIN_INIT;
1195 # else // full hardware PWM
1197 // we support only one backlight pin
1198 static const uint8_t backlight_pin = BACKLIGHT_PIN;
1199 # define FOR_EACH_LED(x) x
1203 # ifdef NO_HARDWARE_PWM
1204 __attribute__((weak)) void backlight_init_ports(void) {
1205 // Setup backlight pin as output and output to on state.
1206 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);)
1208 # ifdef BACKLIGHT_BREATHING
1209 if (is_backlight_breathing()) {
1215 __attribute__((weak)) void backlight_set(uint8_t level) {}
1217 uint8_t backlight_tick = 0;
1219 # ifndef BACKLIGHT_CUSTOM_DRIVER
1220 void backlight_task(void) {
1221 if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
1222 FOR_EACH_LED(backlight_on(backlight_pin);)
1224 FOR_EACH_LED(backlight_off(backlight_pin);)
1226 backlight_tick = (backlight_tick + 1) % 16;
1230 # ifdef BACKLIGHT_BREATHING
1231 # ifndef BACKLIGHT_CUSTOM_DRIVER
1232 # error "Backlight breathing only available with hardware PWM. Please disable."
1236 # else // hardware pwm through timer
1238 # ifdef BACKLIGHT_PWM_TIMER
1240 // The idea of software PWM assisted by hardware timers is the following
1241 // we use the hardware timer in fast PWM mode like for hardware PWM, but
1242 // instead of letting the Output Match Comparator control the led pin
1243 // (which is not possible since the backlight is not wired to PWM pins on the
1244 // CPU), we do the LED on/off by oursleves.
1245 // The timer is setup to count up to 0xFFFF, and we set the Output Compare
1246 // register to the current 16bits backlight level (after CIE correction).
1247 // This means the CPU will trigger a compare match interrupt when the counter
1248 // reaches the backlight level, where we turn off the LEDs,
1249 // but also an overflow interrupt when the counter rolls back to 0,
1250 // in which we're going to turn on the LEDs.
1251 // The LED will then be on for OCRxx/0xFFFF time, adjusted every 244Hz.
1253 // Triggered when the counter reaches the OCRx value
1254 ISR(TIMERx_COMPA_vect) { FOR_EACH_LED(backlight_off(backlight_pin);) }
1256 // Triggered when the counter reaches the TOP value
1257 // this one triggers at F_CPU/65536 =~ 244 Hz
1258 ISR(TIMERx_OVF_vect) {
1259 # ifdef BACKLIGHT_BREATHING
1260 if (is_breathing()) {
1264 // for very small values of OCRxx (or backlight level)
1265 // we can't guarantee this whole code won't execute
1266 // at the same time as the compare match interrupt
1267 // which means that we might turn on the leds while
1268 // trying to turn them off, leading to flickering
1269 // artifacts (especially while breathing, because breathing_task
1270 // takes many computation cycles).
1271 // so better not turn them on while the counter TOP is very low.
1273 FOR_EACH_LED(backlight_on(backlight_pin);)
1279 # define TIMER_TOP 0xFFFFU
1281 // See http://jared.geek.nz/2013/feb/linear-led-pwm
1282 static uint16_t cie_lightness(uint16_t v) {
1283 if (v <= 5243) // if below 8% of max
1284 return v / 9; // same as dividing by 900%
1286 uint32_t y = (((uint32_t)v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
1287 // to get a useful result with integer division, we shift left in the expression above
1288 // and revert what we've done again after squaring.
1290 if (y > 0xFFFFUL) // prevent overflow
1297 // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
1298 static inline void set_pwm(uint16_t val) { OCRxx = val; }
1300 # ifndef BACKLIGHT_CUSTOM_DRIVER
1301 __attribute__((weak)) void backlight_set(uint8_t level) {
1302 if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS;
1305 # ifdef BACKLIGHT_PWM_TIMER
1307 TIMSKx &= ~(_BV(OCIExA));
1308 TIMSKx &= ~(_BV(TOIEx));
1309 FOR_EACH_LED(backlight_off(backlight_pin);)
1312 // Turn off PWM control on backlight pin
1313 TCCRxA &= ~(_BV(COMxx1));
1316 # ifdef BACKLIGHT_PWM_TIMER
1318 TIMSKx |= _BV(OCIExA);
1319 TIMSKx |= _BV(TOIEx);
1322 // Turn on PWM control of backlight pin
1323 TCCRxA |= _BV(COMxx1);
1326 // Set the brightness
1327 set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
1330 void backlight_task(void) {}
1331 # endif // BACKLIGHT_CUSTOM_DRIVER
1333 # ifdef BACKLIGHT_BREATHING
1335 # define BREATHING_NO_HALT 0
1336 # define BREATHING_HALT_OFF 1
1337 # define BREATHING_HALT_ON 2
1338 # define BREATHING_STEPS 128
1340 static uint8_t breathing_period = BREATHING_PERIOD;
1341 static uint8_t breathing_halt = BREATHING_NO_HALT;
1342 static uint16_t breathing_counter = 0;
1344 # ifdef BACKLIGHT_PWM_TIMER
1345 static bool breathing = false;
1347 bool is_breathing(void) { return breathing; }
1349 # define breathing_interrupt_enable() \
1353 # define breathing_interrupt_disable() \
1355 breathing = false; \
1359 bool is_breathing(void) { return !!(TIMSKx & _BV(TOIEx)); }
1361 # define breathing_interrupt_enable() \
1363 TIMSKx |= _BV(TOIEx); \
1365 # define breathing_interrupt_disable() \
1367 TIMSKx &= ~_BV(TOIEx); \
1371 # define breathing_min() \
1373 breathing_counter = 0; \
1375 # define breathing_max() \
1377 breathing_counter = breathing_period * 244 / 2; \
1380 void breathing_enable(void) {
1381 breathing_counter = 0;
1382 breathing_halt = BREATHING_NO_HALT;
1383 breathing_interrupt_enable();
1386 void breathing_pulse(void) {
1387 if (get_backlight_level() == 0)
1391 breathing_halt = BREATHING_HALT_ON;
1392 breathing_interrupt_enable();
1395 void breathing_disable(void) {
1396 breathing_interrupt_disable();
1397 // Restore backlight level
1398 backlight_set(get_backlight_level());
1401 void breathing_self_disable(void) {
1402 if (get_backlight_level() == 0)
1403 breathing_halt = BREATHING_HALT_OFF;
1405 breathing_halt = BREATHING_HALT_ON;
1408 void breathing_toggle(void) {
1410 breathing_disable();
1415 void breathing_period_set(uint8_t value) {
1416 if (!value) value = 1;
1417 breathing_period = value;
1420 void breathing_period_default(void) { breathing_period_set(BREATHING_PERIOD); }
1422 void breathing_period_inc(void) { breathing_period_set(breathing_period + 1); }
1424 void breathing_period_dec(void) { breathing_period_set(breathing_period - 1); }
1426 /* To generate breathing curve in python:
1427 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
1429 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};
1431 // Use this before the cie_lightness function.
1432 static inline uint16_t scale_backlight(uint16_t v) { return v / BACKLIGHT_LEVELS * get_backlight_level(); }
1434 # ifdef BACKLIGHT_PWM_TIMER
1435 void breathing_task(void)
1437 /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1438 * about 244 times per second.
1440 ISR(TIMERx_OVF_vect)
1443 uint16_t interval = (uint16_t)breathing_period * 244 / BREATHING_STEPS;
1444 // resetting after one period to prevent ugly reset at overflow.
1445 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
1446 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
1448 if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) || ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1))) {
1449 breathing_interrupt_disable();
1452 set_pwm(cie_lightness(scale_backlight((uint16_t)pgm_read_byte(&breathing_table[index]) * 0x0101U)));
1455 # endif // BACKLIGHT_BREATHING
1457 __attribute__((weak)) void backlight_init_ports(void) {
1458 // Setup backlight pin as output and output to on state.
1459 FOR_EACH_LED(setPinOutput(backlight_pin); backlight_on(backlight_pin);)
1461 // I could write a wall of text here to explain... but TL;DW
1462 // Go read the ATmega32u4 datasheet.
1463 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
1465 # ifdef BACKLIGHT_PWM_TIMER
1466 // TimerX setup, Fast PWM mode count to TOP set in ICRx
1467 TCCRxA = _BV(WGM11); // = 0b00000010;
1468 // clock select clk/1
1469 TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1470 # else // hardware PWM
1471 // Pin PB7 = OCR1C (Timer 1, Channel C)
1472 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
1473 // (i.e. start high, go low when counter matches.)
1474 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
1475 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
1479 "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 [..]."
1480 "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)."
1482 TCCRxA = _BV(COMxx1) | _BV(WGM11); // = 0b00001010;
1483 TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1485 // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0.
1489 # ifdef BACKLIGHT_BREATHING
1490 if (is_backlight_breathing()) {
1496 # endif // hardware backlight
1498 #else // no backlight
1500 __attribute__((weak)) void backlight_init_ports(void) {}
1502 __attribute__((weak)) void backlight_set(uint8_t level) {}
1506 #ifdef HD44780_ENABLED
1507 # include "hd44780.h"
1510 // Functions for spitting out values
1513 void send_dword(uint32_t number) { // this might not actually work
1514 uint16_t word = (number >> 16);
1516 send_word(number & 0xFFFFUL);
1519 void send_word(uint16_t number) {
1520 uint8_t byte = number >> 8;
1522 send_byte(number & 0xFF);
1525 void send_byte(uint8_t number) {
1526 uint8_t nibble = number >> 4;
1527 send_nibble(nibble);
1528 send_nibble(number & 0xF);
1531 void send_nibble(uint8_t number) {
1534 register_code(KC_0);
1535 unregister_code(KC_0);
1538 register_code(KC_1 + (number - 1));
1539 unregister_code(KC_1 + (number - 1));
1542 register_code(KC_A + (number - 0xA));
1543 unregister_code(KC_A + (number - 0xA));
1548 __attribute__((weak)) uint16_t hex_to_keycode(uint8_t hex) {
1552 } else if (hex < 0xA) {
1553 return KC_1 + (hex - 0x1);
1555 return KC_A + (hex - 0xA);
1559 void api_send_unicode(uint32_t unicode) {
1562 dword_to_bytes(unicode, chunk);
1563 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1567 __attribute__((weak)) void led_set_user(uint8_t usb_led) {}
1569 __attribute__((weak)) void led_set_kb(uint8_t usb_led) { led_set_user(usb_led); }
1571 __attribute__((weak)) void led_init_ports(void) {}
1573 __attribute__((weak)) void led_set(uint8_t usb_led) {
1574 #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
1575 // Use backlight as Caps Lock indicator
1576 uint8_t bl_toggle_lvl = 0;
1578 if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK) && !backlight_config.enable) {
1579 // Turning Caps Lock ON and backlight is disabled in config
1580 // Toggling backlight to the brightest level
1581 bl_toggle_lvl = BACKLIGHT_LEVELS;
1582 } else if (IS_LED_OFF(usb_led, USB_LED_CAPS_LOCK) && backlight_config.enable) {
1583 // Turning Caps Lock OFF and backlight is enabled in config
1584 // Toggling backlight and restoring config level
1585 bl_toggle_lvl = backlight_config.level;
1588 // Set level without modify backlight_config to keep ability to restore state
1589 backlight_set(bl_toggle_lvl);
1592 led_set_kb(usb_led);
1595 //------------------------------------------------------------------------------
1596 // Override these functions in your keymap file to play different tunes on
1597 // different events such as startup and bootloader jump
1599 __attribute__((weak)) void startup_user() {}
1601 __attribute__((weak)) void shutdown_user() {}
1603 //------------------------------------------------------------------------------