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 #include "outputselect.h"
23 #define TAPPING_TERM 200
26 #ifndef BREATHING_PERIOD
27 #define BREATHING_PERIOD 6
30 #include "backlight.h"
31 extern backlight_config_t backlight_config;
33 #ifdef FAUXCLICKY_ENABLE
34 #include "fauxclicky.h"
42 #include "process_midi.h"
47 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
50 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
53 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
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;
63 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
65 case QK_MODS ... QK_MODS_MAX:
80 if (code < QK_RMODS_MIN) return;
92 static inline void qk_register_weak_mods(uint8_t kc) {
93 add_weak_mods(MOD_BIT(kc));
94 send_keyboard_report();
97 static inline void qk_unregister_weak_mods(uint8_t kc) {
98 del_weak_mods(MOD_BIT(kc));
99 send_keyboard_report();
102 static inline void qk_register_mods(uint8_t kc) {
103 add_weak_mods(MOD_BIT(kc));
104 send_keyboard_report();
107 static inline void qk_unregister_mods(uint8_t kc) {
108 del_weak_mods(MOD_BIT(kc));
109 send_keyboard_report();
112 void register_code16 (uint16_t code) {
113 if (IS_MOD(code) || code == KC_NO) {
114 do_code16 (code, qk_register_mods);
116 do_code16 (code, qk_register_weak_mods);
118 register_code (code);
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);
126 do_code16 (code, qk_unregister_weak_mods);
130 __attribute__ ((weak))
131 bool process_action_kb(keyrecord_t *record) {
135 __attribute__ ((weak))
136 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
137 return process_record_user(keycode, record);
140 __attribute__ ((weak))
141 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
145 void reset_keyboard(void) {
147 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
148 process_midi_all_notes_off();
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);
155 while(timer_elapsed(timer_start) < 250)
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
168 // Shift / paren setup
171 #define LSPO_KEY KC_9
174 #define RSPC_KEY KC_0
177 // Shift / Enter setup
179 #define SFTENT_KEY KC_ENT
182 static bool shift_interrupted[2] = {0, 0};
183 static uint16_t scs_timer[2] = {0, 0};
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 bool process_record_quantum(keyrecord_t *record) {
192 /* This gets the keycode from the key pressed */
193 keypos_t key = record->event.key;
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) {
201 if (record->event.pressed) {
202 layer = layer_switch_get_layer(key);
203 update_source_layers_cache(key, layer);
205 layer = read_source_layers_cache(key);
207 keycode = keymap_key_to_keycode(layer, key);
210 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
212 // This is how you use actions here
213 // if (keycode == KC_LEAD) {
215 // action.code = ACTION_DEFAULT_LAYER_SET(0);
216 // process_action(record, action);
220 #ifdef TAP_DANCE_ENABLE
221 preprocess_tap_dance(keycode, record);
225 #if defined(KEY_LOCK_ENABLE)
226 // Must run first to be able to mask key_up events.
227 process_key_lock(&keycode, record) &&
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) &&
236 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
237 process_midi(keycode, record) &&
240 process_audio(keycode, record) &&
243 process_steno(keycode, record) &&
245 #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
246 process_music(keycode, record) &&
248 #ifdef TAP_DANCE_ENABLE
249 process_tap_dance(keycode, record) &&
251 #ifndef DISABLE_LEADER
252 process_leader(keycode, record) &&
254 #ifndef DISABLE_CHORDING
255 process_chording(keycode, record) &&
258 process_combo(keycode, record) &&
260 #ifdef UNICODE_ENABLE
261 process_unicode(keycode, record) &&
264 process_ucis(keycode, record) &&
266 #ifdef PRINTING_ENABLE
267 process_printer(keycode, record) &&
269 #ifdef AUTO_SHIFT_ENABLE
270 process_auto_shift(keycode, record) &&
272 #ifdef UNICODEMAP_ENABLE
273 process_unicode_map(keycode, record) &&
275 #ifdef TERMINAL_ENABLE
276 process_terminal(keycode, record) &&
282 // Shift / paren setup
286 if (record->event.pressed) {
291 if (record->event.pressed) {
293 print("DEBUG: enabled.\n");
296 #ifdef FAUXCLICKY_ENABLE
298 if (record->event.pressed) {
303 if (record->event.pressed) {
308 if (record->event.pressed) {
313 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
315 if (record->event.pressed) {
319 case RGB_MODE_FORWARD:
320 if (record->event.pressed) {
321 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
323 rgblight_step_reverse();
330 case RGB_MODE_REVERSE:
331 if (record->event.pressed) {
332 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
337 rgblight_step_reverse();
342 if (record->event.pressed) {
343 rgblight_increase_hue();
347 if (record->event.pressed) {
348 rgblight_decrease_hue();
352 if (record->event.pressed) {
353 rgblight_increase_sat();
357 if (record->event.pressed) {
358 rgblight_decrease_sat();
362 if (record->event.pressed) {
363 rgblight_increase_val();
367 if (record->event.pressed) {
368 rgblight_decrease_val();
372 if (record->event.pressed) {
373 rgblight_increase_speed();
377 if (record->event.pressed) {
378 rgblight_decrease_speed();
382 if (record->event.pressed) {
386 case RGB_MODE_BREATHE:
387 if (record->event.pressed) {
388 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
395 case RGB_MODE_RAINBOW:
396 if (record->event.pressed) {
397 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
405 if (record->event.pressed) {
406 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
414 if (record->event.pressed) {
415 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
422 case RGB_MODE_KNIGHT:
423 if (record->event.pressed) {
424 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
432 if (record->event.pressed) {
436 case RGB_MODE_GRADIENT:
437 if (record->event.pressed) {
438 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
448 if (record->event.pressed) {
449 set_output(OUTPUT_AUTO);
453 if (record->event.pressed) {
454 set_output(OUTPUT_USB);
457 #ifdef BLUETOOTH_ENABLE
459 if (record->event.pressed) {
460 set_output(OUTPUT_BLUETOOTH);
465 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
466 if (record->event.pressed) {
467 // MAGIC actions (BOOTMAGIC without the boot)
468 if (!eeconfig_is_enabled()) {
472 keymap_config.raw = eeconfig_read_keymap();
475 case MAGIC_SWAP_CONTROL_CAPSLOCK:
476 keymap_config.swap_control_capslock = true;
478 case MAGIC_CAPSLOCK_TO_CONTROL:
479 keymap_config.capslock_to_control = true;
481 case MAGIC_SWAP_LALT_LGUI:
482 keymap_config.swap_lalt_lgui = true;
484 case MAGIC_SWAP_RALT_RGUI:
485 keymap_config.swap_ralt_rgui = true;
488 keymap_config.no_gui = true;
490 case MAGIC_SWAP_GRAVE_ESC:
491 keymap_config.swap_grave_esc = true;
493 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
494 keymap_config.swap_backslash_backspace = true;
496 case MAGIC_HOST_NKRO:
497 keymap_config.nkro = true;
499 case MAGIC_SWAP_ALT_GUI:
500 keymap_config.swap_lalt_lgui = true;
501 keymap_config.swap_ralt_rgui = true;
503 PLAY_SONG(ag_swap_song);
506 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
507 keymap_config.swap_control_capslock = false;
509 case MAGIC_UNCAPSLOCK_TO_CONTROL:
510 keymap_config.capslock_to_control = false;
512 case MAGIC_UNSWAP_LALT_LGUI:
513 keymap_config.swap_lalt_lgui = false;
515 case MAGIC_UNSWAP_RALT_RGUI:
516 keymap_config.swap_ralt_rgui = false;
519 keymap_config.no_gui = false;
521 case MAGIC_UNSWAP_GRAVE_ESC:
522 keymap_config.swap_grave_esc = false;
524 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
525 keymap_config.swap_backslash_backspace = false;
527 case MAGIC_UNHOST_NKRO:
528 keymap_config.nkro = false;
530 case MAGIC_UNSWAP_ALT_GUI:
531 keymap_config.swap_lalt_lgui = false;
532 keymap_config.swap_ralt_rgui = false;
534 PLAY_SONG(ag_norm_song);
537 case MAGIC_TOGGLE_NKRO:
538 keymap_config.nkro = !keymap_config.nkro;
543 eeconfig_update_keymap(keymap_config.raw);
544 clear_keyboard(); // clear to prevent stuck keys
550 if (record->event.pressed) {
551 shift_interrupted[0] = false;
552 scs_timer[0] = timer_read ();
553 register_mods(MOD_BIT(KC_LSFT));
556 #ifdef DISABLE_SPACE_CADET_ROLLOVER
557 if (get_mods() & MOD_BIT(KC_RSFT)) {
558 shift_interrupted[0] = true;
559 shift_interrupted[1] = true;
562 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
563 register_code(LSPO_KEY);
564 unregister_code(LSPO_KEY);
566 unregister_mods(MOD_BIT(KC_LSFT));
572 if (record->event.pressed) {
573 shift_interrupted[1] = false;
574 scs_timer[1] = timer_read ();
575 register_mods(MOD_BIT(KC_RSFT));
578 #ifdef DISABLE_SPACE_CADET_ROLLOVER
579 if (get_mods() & MOD_BIT(KC_LSFT)) {
580 shift_interrupted[0] = true;
581 shift_interrupted[1] = true;
584 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
585 register_code(RSPC_KEY);
586 unregister_code(RSPC_KEY);
588 unregister_mods(MOD_BIT(KC_RSFT));
594 if (record->event.pressed) {
595 shift_interrupted[1] = false;
596 scs_timer[1] = timer_read ();
597 register_mods(MOD_BIT(KC_RSFT));
599 else if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
600 unregister_mods(MOD_BIT(KC_RSFT));
601 register_code(SFTENT_KEY);
602 unregister_code(SFTENT_KEY);
605 unregister_mods(MOD_BIT(KC_RSFT));
611 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
612 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
614 #ifdef GRAVE_ESC_ALT_OVERRIDE
615 // if ALT is pressed, ESC is always sent
616 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
617 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
622 #ifdef GRAVE_ESC_CTRL_OVERRIDE
623 // if CTRL is pressed, ESC is always sent
624 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
625 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
630 #ifdef GRAVE_ESC_GUI_OVERRIDE
631 // if GUI is pressed, ESC is always sent
632 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
637 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
638 // if SHIFT is pressed, ESC is always sent
639 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
644 if (record->event.pressed) {
645 grave_esc_was_shifted = shifted;
646 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
649 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
652 send_keyboard_report();
656 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
658 if (record->event.pressed)
665 shift_interrupted[0] = true;
666 shift_interrupted[1] = true;
671 return process_action_kb(record);
674 __attribute__ ((weak))
675 const bool ascii_to_shift_lut[0x80] PROGMEM = {
676 0, 0, 0, 0, 0, 0, 0, 0,
677 0, 0, 0, 0, 0, 0, 0, 0,
678 0, 0, 0, 0, 0, 0, 0, 0,
679 0, 0, 0, 0, 0, 0, 0, 0,
680 0, 1, 1, 1, 1, 1, 1, 0,
681 1, 1, 1, 1, 0, 0, 0, 0,
682 0, 0, 0, 0, 0, 0, 0, 0,
683 0, 0, 1, 0, 1, 0, 1, 1,
684 1, 1, 1, 1, 1, 1, 1, 1,
685 1, 1, 1, 1, 1, 1, 1, 1,
686 1, 1, 1, 1, 1, 1, 1, 1,
687 1, 1, 1, 0, 0, 0, 1, 1,
688 0, 0, 0, 0, 0, 0, 0, 0,
689 0, 0, 0, 0, 0, 0, 0, 0,
690 0, 0, 0, 0, 0, 0, 0, 0,
691 0, 0, 0, 1, 1, 1, 1, 0
694 __attribute__ ((weak))
695 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
696 0, 0, 0, 0, 0, 0, 0, 0,
697 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
698 0, 0, 0, 0, 0, 0, 0, 0,
699 0, 0, 0, KC_ESC, 0, 0, 0, 0,
700 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
701 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
702 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
703 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
704 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
705 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
706 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
707 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
708 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
709 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
710 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
711 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
714 void send_string(const char *str) {
715 send_string_with_delay(str, 0);
718 void send_string_P(const char *str) {
719 send_string_with_delay_P(str, 0);
722 void send_string_with_delay(const char *str, uint8_t interval) {
724 char ascii_code = *str;
725 if (!ascii_code) break;
726 if (ascii_code == 1) {
728 uint8_t keycode = *(++str);
729 register_code(keycode);
730 unregister_code(keycode);
731 } else if (ascii_code == 2) {
733 uint8_t keycode = *(++str);
734 register_code(keycode);
735 } else if (ascii_code == 3) {
737 uint8_t keycode = *(++str);
738 unregister_code(keycode);
740 send_char(ascii_code);
744 { uint8_t ms = interval; while (ms--) wait_ms(1); }
748 void send_string_with_delay_P(const char *str, uint8_t interval) {
750 char ascii_code = pgm_read_byte(str);
751 if (!ascii_code) break;
752 if (ascii_code == 1) {
754 uint8_t keycode = pgm_read_byte(++str);
755 register_code(keycode);
756 unregister_code(keycode);
757 } else if (ascii_code == 2) {
759 uint8_t keycode = pgm_read_byte(++str);
760 register_code(keycode);
761 } else if (ascii_code == 3) {
763 uint8_t keycode = pgm_read_byte(++str);
764 unregister_code(keycode);
766 send_char(ascii_code);
770 { uint8_t ms = interval; while (ms--) wait_ms(1); }
774 void send_char(char ascii_code) {
776 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
777 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
778 register_code(KC_LSFT);
779 register_code(keycode);
780 unregister_code(keycode);
781 unregister_code(KC_LSFT);
783 register_code(keycode);
784 unregister_code(keycode);
788 void set_single_persistent_default_layer(uint8_t default_layer) {
789 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
790 PLAY_SONG(default_layer_songs[default_layer]);
792 eeconfig_update_default_layer(1U<<default_layer);
793 default_layer_set(1U<<default_layer);
796 uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
797 uint32_t mask12 = (1UL << layer1) | (1UL << layer2);
798 uint32_t mask3 = 1UL << layer3;
799 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
802 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
803 layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
806 void tap_random_base64(void) {
807 #if defined(__AVR_ATmega32U4__)
808 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
810 uint8_t key = rand() % 64;
814 register_code(KC_LSFT);
815 register_code(key + KC_A);
816 unregister_code(key + KC_A);
817 unregister_code(KC_LSFT);
820 register_code(key - 26 + KC_A);
821 unregister_code(key - 26 + KC_A);
825 unregister_code(KC_0);
828 register_code(key - 53 + KC_1);
829 unregister_code(key - 53 + KC_1);
832 register_code(KC_LSFT);
833 register_code(KC_EQL);
834 unregister_code(KC_EQL);
835 unregister_code(KC_LSFT);
838 register_code(KC_SLSH);
839 unregister_code(KC_SLSH);
844 void matrix_init_quantum() {
845 #ifdef BACKLIGHT_ENABLE
846 backlight_init_ports();
851 #ifdef RGB_MATRIX_ENABLE
852 rgb_matrix_init_drivers();
857 uint8_t rgb_matrix_task_counter = 0;
859 #ifndef RGB_MATRIX_SKIP_FRAMES
860 #define RGB_MATRIX_SKIP_FRAMES 1
863 void matrix_scan_quantum() {
864 #if defined(AUDIO_ENABLE)
868 #ifdef TAP_DANCE_ENABLE
869 matrix_scan_tap_dance();
876 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
880 #ifdef RGB_MATRIX_ENABLE
882 if (rgb_matrix_task_counter == 0) {
883 rgb_matrix_update_pwm_buffers();
885 rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1));
890 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
892 static const uint8_t backlight_pin = BACKLIGHT_PIN;
894 // depending on the pin, we use a different output compare unit
895 #if BACKLIGHT_PIN == B7
896 # define COM1x1 COM1C1
898 #elif BACKLIGHT_PIN == B6
899 # define COM1x1 COM1B1
901 #elif BACKLIGHT_PIN == B5
902 # define COM1x1 COM1A1
905 # define NO_HARDWARE_PWM
908 #ifndef BACKLIGHT_ON_STATE
909 #define BACKLIGHT_ON_STATE 0
912 #ifdef NO_HARDWARE_PWM // pwm through software
914 __attribute__ ((weak))
915 void backlight_init_ports(void)
917 // Setup backlight pin as output and output to on state.
919 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
920 #if BACKLIGHT_ON_STATE == 0
922 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
925 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
929 __attribute__ ((weak))
930 void backlight_set(uint8_t level) {}
932 uint8_t backlight_tick = 0;
934 #ifndef BACKLIGHT_CUSTOM_DRIVER
935 void backlight_task(void) {
936 if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
937 #if BACKLIGHT_ON_STATE == 0
939 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
942 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
945 #if BACKLIGHT_ON_STATE == 0
947 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
950 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
953 backlight_tick = (backlight_tick + 1) % 16;
957 #ifdef BACKLIGHT_BREATHING
958 #ifndef BACKLIGHT_CUSTOM_DRIVER
959 #error "Backlight breathing only available with hardware PWM. Please disable."
963 #else // pwm through timer
965 #define TIMER_TOP 0xFFFFU
967 // See http://jared.geek.nz/2013/feb/linear-led-pwm
968 static uint16_t cie_lightness(uint16_t v) {
969 if (v <= 5243) // if below 8% of max
970 return v / 9; // same as dividing by 900%
972 uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
973 // to get a useful result with integer division, we shift left in the expression above
974 // and revert what we've done again after squaring.
976 if (y > 0xFFFFUL) // prevent overflow
983 // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
984 static inline void set_pwm(uint16_t val) {
988 #ifndef BACKLIGHT_CUSTOM_DRIVER
989 __attribute__ ((weak))
990 void backlight_set(uint8_t level) {
991 if (level > BACKLIGHT_LEVELS)
992 level = BACKLIGHT_LEVELS;
995 // Turn off PWM control on backlight pin
996 TCCR1A &= ~(_BV(COM1x1));
998 // Turn on PWM control of backlight pin
999 TCCR1A |= _BV(COM1x1);
1001 // Set the brightness
1002 set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
1005 void backlight_task(void) {}
1006 #endif // BACKLIGHT_CUSTOM_DRIVER
1008 #ifdef BACKLIGHT_BREATHING
1010 #define BREATHING_NO_HALT 0
1011 #define BREATHING_HALT_OFF 1
1012 #define BREATHING_HALT_ON 2
1013 #define BREATHING_STEPS 128
1015 static uint8_t breathing_period = BREATHING_PERIOD;
1016 static uint8_t breathing_halt = BREATHING_NO_HALT;
1017 static uint16_t breathing_counter = 0;
1019 bool is_breathing(void) {
1020 return !!(TIMSK1 & _BV(TOIE1));
1023 #define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0)
1024 #define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0)
1025 #define breathing_min() do {breathing_counter = 0;} while (0)
1026 #define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
1028 void breathing_enable(void)
1030 breathing_counter = 0;
1031 breathing_halt = BREATHING_NO_HALT;
1032 breathing_interrupt_enable();
1035 void breathing_pulse(void)
1037 if (get_backlight_level() == 0)
1041 breathing_halt = BREATHING_HALT_ON;
1042 breathing_interrupt_enable();
1045 void breathing_disable(void)
1047 breathing_interrupt_disable();
1048 // Restore backlight level
1049 backlight_set(get_backlight_level());
1052 void breathing_self_disable(void)
1054 if (get_backlight_level() == 0)
1055 breathing_halt = BREATHING_HALT_OFF;
1057 breathing_halt = BREATHING_HALT_ON;
1060 void breathing_toggle(void) {
1062 breathing_disable();
1067 void breathing_period_set(uint8_t value)
1071 breathing_period = value;
1074 void breathing_period_default(void) {
1075 breathing_period_set(BREATHING_PERIOD);
1078 void breathing_period_inc(void)
1080 breathing_period_set(breathing_period+1);
1083 void breathing_period_dec(void)
1085 breathing_period_set(breathing_period-1);
1088 /* To generate breathing curve in python:
1089 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
1091 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};
1093 // Use this before the cie_lightness function.
1094 static inline uint16_t scale_backlight(uint16_t v) {
1095 return v / BACKLIGHT_LEVELS * get_backlight_level();
1098 /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1099 * about 244 times per second.
1101 ISR(TIMER1_OVF_vect)
1103 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
1104 // resetting after one period to prevent ugly reset at overflow.
1105 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
1106 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
1108 if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
1109 ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
1111 breathing_interrupt_disable();
1114 set_pwm(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
1117 #endif // BACKLIGHT_BREATHING
1119 __attribute__ ((weak))
1120 void backlight_init_ports(void)
1122 // Setup backlight pin as output and output to on state.
1124 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
1125 #if BACKLIGHT_ON_STATE == 0
1127 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1130 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1132 // I could write a wall of text here to explain... but TL;DW
1133 // Go read the ATmega32u4 datasheet.
1134 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
1136 // Pin PB7 = OCR1C (Timer 1, Channel C)
1137 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
1138 // (i.e. start high, go low when counter matches.)
1139 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
1140 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
1144 "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 [..]."
1145 "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)."
1148 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
1149 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1150 // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0.
1154 #ifdef BACKLIGHT_BREATHING
1159 #endif // NO_HARDWARE_PWM
1163 __attribute__ ((weak))
1164 void backlight_init_ports(void) {}
1166 __attribute__ ((weak))
1167 void backlight_set(uint8_t level) {}
1172 // Functions for spitting out values
1175 void send_dword(uint32_t number) { // this might not actually work
1176 uint16_t word = (number >> 16);
1178 send_word(number & 0xFFFFUL);
1181 void send_word(uint16_t number) {
1182 uint8_t byte = number >> 8;
1184 send_byte(number & 0xFF);
1187 void send_byte(uint8_t number) {
1188 uint8_t nibble = number >> 4;
1189 send_nibble(nibble);
1190 send_nibble(number & 0xF);
1193 void send_nibble(uint8_t number) {
1196 register_code(KC_0);
1197 unregister_code(KC_0);
1200 register_code(KC_1 + (number - 1));
1201 unregister_code(KC_1 + (number - 1));
1204 register_code(KC_A + (number - 0xA));
1205 unregister_code(KC_A + (number - 0xA));
1211 __attribute__((weak))
1212 uint16_t hex_to_keycode(uint8_t hex)
1217 } else if (hex < 0xA) {
1218 return KC_1 + (hex - 0x1);
1220 return KC_A + (hex - 0xA);
1224 void api_send_unicode(uint32_t unicode) {
1227 dword_to_bytes(unicode, chunk);
1228 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1232 __attribute__ ((weak))
1233 void led_set_user(uint8_t usb_led) {
1237 __attribute__ ((weak))
1238 void led_set_kb(uint8_t usb_led) {
1239 led_set_user(usb_led);
1242 __attribute__ ((weak))
1243 void led_init_ports(void)
1248 __attribute__ ((weak))
1249 void led_set(uint8_t usb_led)
1254 // // Using PE6 Caps Lock LED
1255 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1265 // PORTE &= ~(1<<6);
1268 led_set_kb(usb_led);
1272 //------------------------------------------------------------------------------
1273 // Override these functions in your keymap file to play different tunes on
1274 // different events such as startup and bootloader jump
1276 __attribute__ ((weak))
1277 void startup_user() {}
1279 __attribute__ ((weak))
1280 void shutdown_user() {}
1282 //------------------------------------------------------------------------------