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 #include "backlight.h"
27 extern backlight_config_t backlight_config;
29 #ifdef FAUXCLICKY_ENABLE
30 #include "fauxclicky.h"
35 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
38 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
41 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
43 float goodbye_song[][2] = GOODBYE_SONG;
44 float ag_norm_song[][2] = AG_NORM_SONG;
45 float ag_swap_song[][2] = AG_SWAP_SONG;
46 #ifdef DEFAULT_LAYER_SONGS
47 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
51 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
53 case QK_MODS ... QK_MODS_MAX:
68 if (code < QK_RMODS_MIN) return;
80 static inline void qk_register_weak_mods(uint8_t kc) {
81 add_weak_mods(MOD_BIT(kc));
82 send_keyboard_report();
85 static inline void qk_unregister_weak_mods(uint8_t kc) {
86 del_weak_mods(MOD_BIT(kc));
87 send_keyboard_report();
90 static inline void qk_register_mods(uint8_t kc) {
91 add_weak_mods(MOD_BIT(kc));
92 send_keyboard_report();
95 static inline void qk_unregister_mods(uint8_t kc) {
96 del_weak_mods(MOD_BIT(kc));
97 send_keyboard_report();
100 void register_code16 (uint16_t code) {
101 if (IS_MOD(code) || code == KC_NO) {
102 do_code16 (code, qk_register_mods);
104 do_code16 (code, qk_register_weak_mods);
106 register_code (code);
109 void unregister_code16 (uint16_t code) {
110 unregister_code (code);
111 if (IS_MOD(code) || code == KC_NO) {
112 do_code16 (code, qk_unregister_mods);
114 do_code16 (code, qk_unregister_weak_mods);
118 __attribute__ ((weak))
119 bool process_action_kb(keyrecord_t *record) {
123 __attribute__ ((weak))
124 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
125 return process_record_user(keycode, record);
128 __attribute__ ((weak))
129 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
133 void reset_keyboard(void) {
135 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
136 music_all_notes_off();
137 uint16_t timer_start = timer_read();
138 PLAY_SONG(goodbye_song);
140 while(timer_elapsed(timer_start) < 250)
146 // this is also done later in bootloader.c - not sure if it's neccesary here
147 #ifdef BOOTLOADER_CATERINA
148 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
153 // Shift / paren setup
156 #define LSPO_KEY KC_9
159 #define RSPC_KEY KC_0
162 static bool shift_interrupted[2] = {0, 0};
163 static uint16_t scs_timer[2] = {0, 0};
165 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
166 * Used to ensure that the correct keycode is released if the key is released.
168 static bool grave_esc_was_shifted = false;
170 bool process_record_quantum(keyrecord_t *record) {
172 /* This gets the keycode from the key pressed */
173 keypos_t key = record->event.key;
176 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
177 /* TODO: Use store_or_get_action() or a similar function. */
178 if (!disable_action_cache) {
181 if (record->event.pressed) {
182 layer = layer_switch_get_layer(key);
183 update_source_layers_cache(key, layer);
185 layer = read_source_layers_cache(key);
187 keycode = keymap_key_to_keycode(layer, key);
190 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
192 // This is how you use actions here
193 // if (keycode == KC_LEAD) {
195 // action.code = ACTION_DEFAULT_LAYER_SET(0);
196 // process_action(record, action);
201 #if defined(KEY_LOCK_ENABLE)
202 // Must run first to be able to mask key_up events.
203 process_key_lock(&keycode, record) &&
205 process_record_kb(keycode, record) &&
206 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
207 process_midi(keycode, record) &&
210 process_audio(keycode, record) &&
213 process_steno(keycode, record) &&
215 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
216 process_music(keycode, record) &&
218 #ifdef TAP_DANCE_ENABLE
219 process_tap_dance(keycode, record) &&
221 #ifndef DISABLE_LEADER
222 process_leader(keycode, record) &&
224 #ifndef DISABLE_CHORDING
225 process_chording(keycode, record) &&
228 process_combo(keycode, record) &&
230 #ifdef UNICODE_ENABLE
231 process_unicode(keycode, record) &&
234 process_ucis(keycode, record) &&
236 #ifdef PRINTING_ENABLE
237 process_printer(keycode, record) &&
239 #ifdef AUTO_SHIFT_ENABLE
240 process_auto_shift(keycode, record) &&
242 #ifdef UNICODEMAP_ENABLE
243 process_unicode_map(keycode, record) &&
245 #ifdef TERMINAL_ENABLE
246 process_terminal(keycode, record) &&
252 // Shift / paren setup
256 if (record->event.pressed) {
261 if (record->event.pressed) {
263 print("DEBUG: enabled.\n");
266 #ifdef FAUXCLICKY_ENABLE
268 if (record->event.pressed) {
273 if (record->event.pressed) {
278 if (record->event.pressed) {
283 #ifdef RGBLIGHT_ENABLE
285 if (record->event.pressed) {
289 case RGB_MODE_FORWARD:
290 if (record->event.pressed) {
291 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
293 rgblight_step_reverse();
300 case RGB_MODE_REVERSE:
301 if (record->event.pressed) {
302 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
307 rgblight_step_reverse();
312 if (record->event.pressed) {
313 rgblight_increase_hue();
317 if (record->event.pressed) {
318 rgblight_decrease_hue();
322 if (record->event.pressed) {
323 rgblight_increase_sat();
327 if (record->event.pressed) {
328 rgblight_decrease_sat();
332 if (record->event.pressed) {
333 rgblight_increase_val();
337 if (record->event.pressed) {
338 rgblight_decrease_val();
342 if (record->event.pressed) {
346 case RGB_MODE_BREATHE:
347 if (record->event.pressed) {
348 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
355 case RGB_MODE_RAINBOW:
356 if (record->event.pressed) {
357 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
365 if (record->event.pressed) {
366 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
374 if (record->event.pressed) {
375 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
382 case RGB_MODE_KNIGHT:
383 if (record->event.pressed) {
384 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
392 if (record->event.pressed) {
396 case RGB_MODE_GRADIENT:
397 if (record->event.pressed) {
398 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
408 if (record->event.pressed) {
409 set_output(OUTPUT_AUTO);
413 if (record->event.pressed) {
414 set_output(OUTPUT_USB);
417 #ifdef BLUETOOTH_ENABLE
419 if (record->event.pressed) {
420 set_output(OUTPUT_BLUETOOTH);
425 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
426 if (record->event.pressed) {
427 // MAGIC actions (BOOTMAGIC without the boot)
428 if (!eeconfig_is_enabled()) {
432 keymap_config.raw = eeconfig_read_keymap();
435 case MAGIC_SWAP_CONTROL_CAPSLOCK:
436 keymap_config.swap_control_capslock = true;
438 case MAGIC_CAPSLOCK_TO_CONTROL:
439 keymap_config.capslock_to_control = true;
441 case MAGIC_SWAP_LALT_LGUI:
442 keymap_config.swap_lalt_lgui = true;
444 case MAGIC_SWAP_RALT_RGUI:
445 keymap_config.swap_ralt_rgui = true;
448 keymap_config.no_gui = true;
450 case MAGIC_SWAP_GRAVE_ESC:
451 keymap_config.swap_grave_esc = true;
453 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
454 keymap_config.swap_backslash_backspace = true;
456 case MAGIC_HOST_NKRO:
457 keymap_config.nkro = true;
459 case MAGIC_SWAP_ALT_GUI:
460 keymap_config.swap_lalt_lgui = true;
461 keymap_config.swap_ralt_rgui = true;
463 PLAY_SONG(ag_swap_song);
466 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
467 keymap_config.swap_control_capslock = false;
469 case MAGIC_UNCAPSLOCK_TO_CONTROL:
470 keymap_config.capslock_to_control = false;
472 case MAGIC_UNSWAP_LALT_LGUI:
473 keymap_config.swap_lalt_lgui = false;
475 case MAGIC_UNSWAP_RALT_RGUI:
476 keymap_config.swap_ralt_rgui = false;
479 keymap_config.no_gui = false;
481 case MAGIC_UNSWAP_GRAVE_ESC:
482 keymap_config.swap_grave_esc = false;
484 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
485 keymap_config.swap_backslash_backspace = false;
487 case MAGIC_UNHOST_NKRO:
488 keymap_config.nkro = false;
490 case MAGIC_UNSWAP_ALT_GUI:
491 keymap_config.swap_lalt_lgui = false;
492 keymap_config.swap_ralt_rgui = false;
494 PLAY_SONG(ag_norm_song);
497 case MAGIC_TOGGLE_NKRO:
498 keymap_config.nkro = !keymap_config.nkro;
503 eeconfig_update_keymap(keymap_config.raw);
504 clear_keyboard(); // clear to prevent stuck keys
510 if (record->event.pressed) {
511 shift_interrupted[0] = false;
512 scs_timer[0] = timer_read ();
513 register_mods(MOD_BIT(KC_LSFT));
516 #ifdef DISABLE_SPACE_CADET_ROLLOVER
517 if (get_mods() & MOD_BIT(KC_RSFT)) {
518 shift_interrupted[0] = true;
519 shift_interrupted[1] = true;
522 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
523 register_code(LSPO_KEY);
524 unregister_code(LSPO_KEY);
526 unregister_mods(MOD_BIT(KC_LSFT));
532 if (record->event.pressed) {
533 shift_interrupted[1] = false;
534 scs_timer[1] = timer_read ();
535 register_mods(MOD_BIT(KC_RSFT));
538 #ifdef DISABLE_SPACE_CADET_ROLLOVER
539 if (get_mods() & MOD_BIT(KC_LSFT)) {
540 shift_interrupted[0] = true;
541 shift_interrupted[1] = true;
544 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
545 register_code(RSPC_KEY);
546 unregister_code(RSPC_KEY);
548 unregister_mods(MOD_BIT(KC_RSFT));
553 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
554 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
556 #ifdef GRAVE_ESC_ALT_OVERRIDE
557 // if ALT is pressed, ESC is always sent
558 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
559 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
564 #ifdef GRAVE_ESC_CTRL_OVERRIDE
565 // if CTRL is pressed, ESC is always sent
566 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
567 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
572 #ifdef GRAVE_ESC_GUI_OVERRIDE
573 // if GUI is pressed, ESC is always sent
574 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
579 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
580 // if SHIFT is pressed, ESC is always sent
581 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
586 if (record->event.pressed) {
587 grave_esc_was_shifted = shifted;
588 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
591 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
594 send_keyboard_report();
597 shift_interrupted[0] = true;
598 shift_interrupted[1] = true;
603 return process_action_kb(record);
606 __attribute__ ((weak))
607 const bool ascii_to_shift_lut[0x80] PROGMEM = {
608 0, 0, 0, 0, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0,
610 0, 0, 0, 0, 0, 0, 0, 0,
611 0, 0, 0, 0, 0, 0, 0, 0,
612 0, 1, 1, 1, 1, 1, 1, 0,
613 1, 1, 1, 1, 0, 0, 0, 0,
614 0, 0, 0, 0, 0, 0, 0, 0,
615 0, 0, 1, 0, 1, 0, 1, 1,
616 1, 1, 1, 1, 1, 1, 1, 1,
617 1, 1, 1, 1, 1, 1, 1, 1,
618 1, 1, 1, 1, 1, 1, 1, 1,
619 1, 1, 1, 0, 0, 0, 1, 1,
620 0, 0, 0, 0, 0, 0, 0, 0,
621 0, 0, 0, 0, 0, 0, 0, 0,
622 0, 0, 0, 0, 0, 0, 0, 0,
623 0, 0, 0, 1, 1, 1, 1, 0
626 __attribute__ ((weak))
627 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
628 0, 0, 0, 0, 0, 0, 0, 0,
629 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
630 0, 0, 0, 0, 0, 0, 0, 0,
631 0, 0, 0, KC_ESC, 0, 0, 0, 0,
632 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
633 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
634 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
635 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
636 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
637 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
638 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
639 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
640 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
641 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
642 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
643 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
646 void send_string(const char *str) {
647 send_string_with_delay(str, 0);
650 void send_string_P(const char *str) {
651 send_string_with_delay_P(str, 0);
654 void send_string_with_delay(const char *str, uint8_t interval) {
656 char ascii_code = *str;
657 if (!ascii_code) break;
658 if (ascii_code == 1) {
660 uint8_t keycode = *(++str);
661 register_code(keycode);
662 unregister_code(keycode);
663 } else if (ascii_code == 2) {
665 uint8_t keycode = *(++str);
666 register_code(keycode);
667 } else if (ascii_code == 3) {
669 uint8_t keycode = *(++str);
670 unregister_code(keycode);
672 send_char(ascii_code);
676 { uint8_t ms = interval; while (ms--) wait_ms(1); }
680 void send_string_with_delay_P(const char *str, uint8_t interval) {
682 char ascii_code = pgm_read_byte(str);
683 if (!ascii_code) break;
684 if (ascii_code == 1) {
686 uint8_t keycode = pgm_read_byte(++str);
687 register_code(keycode);
688 unregister_code(keycode);
689 } else if (ascii_code == 2) {
691 uint8_t keycode = pgm_read_byte(++str);
692 register_code(keycode);
693 } else if (ascii_code == 3) {
695 uint8_t keycode = pgm_read_byte(++str);
696 unregister_code(keycode);
698 send_char(ascii_code);
702 { uint8_t ms = interval; while (ms--) wait_ms(1); }
706 void send_char(char ascii_code) {
708 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
709 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
710 register_code(KC_LSFT);
711 register_code(keycode);
712 unregister_code(keycode);
713 unregister_code(KC_LSFT);
715 register_code(keycode);
716 unregister_code(keycode);
720 void set_single_persistent_default_layer(uint8_t default_layer) {
721 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
722 PLAY_SONG(default_layer_songs[default_layer]);
724 eeconfig_update_default_layer(1U<<default_layer);
725 default_layer_set(1U<<default_layer);
728 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
729 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
736 void tap_random_base64(void) {
737 #if defined(__AVR_ATmega32U4__)
738 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
740 uint8_t key = rand() % 64;
744 register_code(KC_LSFT);
745 register_code(key + KC_A);
746 unregister_code(key + KC_A);
747 unregister_code(KC_LSFT);
750 register_code(key - 26 + KC_A);
751 unregister_code(key - 26 + KC_A);
755 unregister_code(KC_0);
758 register_code(key - 53 + KC_1);
759 unregister_code(key - 53 + KC_1);
762 register_code(KC_LSFT);
763 register_code(KC_EQL);
764 unregister_code(KC_EQL);
765 unregister_code(KC_LSFT);
768 register_code(KC_SLSH);
769 unregister_code(KC_SLSH);
774 void matrix_init_quantum() {
775 #ifdef BACKLIGHT_ENABLE
776 backlight_init_ports();
784 void matrix_scan_quantum() {
789 #ifdef TAP_DANCE_ENABLE
790 matrix_scan_tap_dance();
797 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
804 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
806 static const uint8_t backlight_pin = BACKLIGHT_PIN;
808 #if BACKLIGHT_PIN == B7
809 # define COM1x1 COM1C1
811 #elif BACKLIGHT_PIN == B6
812 # define COM1x1 COM1B1
814 #elif BACKLIGHT_PIN == B5
815 # define COM1x1 COM1A1
818 # define NO_BACKLIGHT_CLOCK
821 #ifndef BACKLIGHT_ON_STATE
822 #define BACKLIGHT_ON_STATE 0
825 __attribute__ ((weak))
826 void backlight_init_ports(void)
829 // Setup backlight pin as output and output to on state.
831 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
832 #if BACKLIGHT_ON_STATE == 0
834 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
837 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
840 #ifndef NO_BACKLIGHT_CLOCK
841 // Use full 16-bit resolution.
844 // I could write a wall of text here to explain... but TL;DW
845 // Go read the ATmega32u4 datasheet.
846 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
848 // Pin PB7 = OCR1C (Timer 1, Channel C)
849 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
850 // (i.e. start high, go low when counter matches.)
851 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
852 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
854 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
855 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
859 #ifdef BACKLIGHT_BREATHING
860 breathing_defaults();
864 __attribute__ ((weak))
865 void backlight_set(uint8_t level)
867 // Prevent backlight blink on lowest level
868 // #if BACKLIGHT_ON_STATE == 0
870 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
873 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
877 #ifndef NO_BACKLIGHT_CLOCK
878 // Turn off PWM control on backlight pin, revert to output low.
879 TCCR1A &= ~(_BV(COM1x1));
882 // #if BACKLIGHT_ON_STATE == 0
884 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
887 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
891 #ifndef NO_BACKLIGHT_CLOCK
892 else if ( level == BACKLIGHT_LEVELS ) {
893 // Turn on PWM control of backlight pin
894 TCCR1A |= _BV(COM1x1);
895 // Set the brightness
899 // Turn on PWM control of backlight pin
900 TCCR1A |= _BV(COM1x1);
901 // Set the brightness
902 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
906 #ifdef BACKLIGHT_BREATHING
907 breathing_intensity_default();
911 uint8_t backlight_tick = 0;
913 void backlight_task(void) {
914 #ifdef NO_BACKLIGHT_CLOCK
915 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
916 #if BACKLIGHT_ON_STATE == 0
918 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
921 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
924 #if BACKLIGHT_ON_STATE == 0
926 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
929 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
932 backlight_tick = (backlight_tick + 1) % 16;
936 #ifdef BACKLIGHT_BREATHING
938 #ifdef NO_BACKLIGHT_CLOCK
939 void breathing_defaults(void) {}
940 void breathing_intensity_default(void) {}
943 #define BREATHING_NO_HALT 0
944 #define BREATHING_HALT_OFF 1
945 #define BREATHING_HALT_ON 2
947 static uint8_t breath_intensity;
948 static uint8_t breath_speed;
949 static uint16_t breathing_index;
950 static uint8_t breathing_halt;
952 void breathing_enable(void)
954 if (get_backlight_level() == 0)
960 // Set breathing_index to be at the midpoint (brightest point)
961 breathing_index = 0x20 << breath_speed;
964 breathing_halt = BREATHING_NO_HALT;
966 // Enable breathing interrupt
967 TIMSK1 |= _BV(OCIE1A);
970 void breathing_pulse(void)
972 if (get_backlight_level() == 0)
978 // Set breathing_index to be at the midpoint + 1 (brightest point)
979 breathing_index = 0x21 << breath_speed;
982 breathing_halt = BREATHING_HALT_ON;
984 // Enable breathing interrupt
985 TIMSK1 |= _BV(OCIE1A);
988 void breathing_disable(void)
990 // Disable breathing interrupt
991 TIMSK1 &= ~_BV(OCIE1A);
992 backlight_set(get_backlight_level());
995 void breathing_self_disable(void)
997 if (get_backlight_level() == 0)
999 breathing_halt = BREATHING_HALT_OFF;
1003 breathing_halt = BREATHING_HALT_ON;
1006 //backlight_set(get_backlight_level());
1009 void breathing_toggle(void)
1011 if (!is_breathing())
1013 if (get_backlight_level() == 0)
1015 breathing_index = 0;
1019 // Set breathing_index to be at the midpoint + 1 (brightest point)
1020 breathing_index = 0x21 << breath_speed;
1023 breathing_halt = BREATHING_NO_HALT;
1026 // Toggle breathing interrupt
1027 TIMSK1 ^= _BV(OCIE1A);
1029 // Restore backlight level
1030 if (!is_breathing())
1032 backlight_set(get_backlight_level());
1036 bool is_breathing(void)
1038 return (TIMSK1 && _BV(OCIE1A));
1041 void breathing_intensity_default(void)
1043 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
1044 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
1047 void breathing_intensity_set(uint8_t value)
1049 breath_intensity = value;
1052 void breathing_speed_default(void)
1057 void breathing_speed_set(uint8_t value)
1059 bool is_breathing_now = is_breathing();
1060 uint8_t old_breath_speed = breath_speed;
1062 if (is_breathing_now)
1064 // Disable breathing interrupt
1065 TIMSK1 &= ~_BV(OCIE1A);
1068 breath_speed = value;
1070 if (is_breathing_now)
1072 // Adjust index to account for new speed
1073 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
1075 // Enable breathing interrupt
1076 TIMSK1 |= _BV(OCIE1A);
1081 void breathing_speed_inc(uint8_t value)
1083 if ((uint16_t)(breath_speed - value) > 10 )
1085 breathing_speed_set(0);
1089 breathing_speed_set(breath_speed - value);
1093 void breathing_speed_dec(uint8_t value)
1095 if ((uint16_t)(breath_speed + value) > 10 )
1097 breathing_speed_set(10);
1101 breathing_speed_set(breath_speed + value);
1105 void breathing_defaults(void)
1107 breathing_intensity_default();
1108 breathing_speed_default();
1109 breathing_halt = BREATHING_NO_HALT;
1112 /* Breathing Sleep LED brighness(PWM On period) table
1113 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
1115 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
1116 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
1118 static const uint8_t breathing_table[64] PROGMEM = {
1119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
1120 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
1121 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
1122 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1125 ISR(TIMER1_COMPA_vect)
1127 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
1130 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
1132 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
1134 // Disable breathing interrupt
1135 TIMSK1 &= ~_BV(OCIE1A);
1138 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
1142 #endif // NO_BACKLIGHT_CLOCK
1147 __attribute__ ((weak))
1148 void backlight_init_ports(void)
1153 __attribute__ ((weak))
1154 void backlight_set(uint8_t level)
1162 // Functions for spitting out values
1165 void send_dword(uint32_t number) { // this might not actually work
1166 uint16_t word = (number >> 16);
1168 send_word(number & 0xFFFFUL);
1171 void send_word(uint16_t number) {
1172 uint8_t byte = number >> 8;
1174 send_byte(number & 0xFF);
1177 void send_byte(uint8_t number) {
1178 uint8_t nibble = number >> 4;
1179 send_nibble(nibble);
1180 send_nibble(number & 0xF);
1183 void send_nibble(uint8_t number) {
1186 register_code(KC_0);
1187 unregister_code(KC_0);
1190 register_code(KC_1 + (number - 1));
1191 unregister_code(KC_1 + (number - 1));
1194 register_code(KC_A + (number - 0xA));
1195 unregister_code(KC_A + (number - 0xA));
1201 __attribute__((weak))
1202 uint16_t hex_to_keycode(uint8_t hex)
1207 } else if (hex < 0xA) {
1208 return KC_1 + (hex - 0x1);
1210 return KC_A + (hex - 0xA);
1214 void api_send_unicode(uint32_t unicode) {
1217 dword_to_bytes(unicode, chunk);
1218 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1222 __attribute__ ((weak))
1223 void led_set_user(uint8_t usb_led) {
1227 __attribute__ ((weak))
1228 void led_set_kb(uint8_t usb_led) {
1229 led_set_user(usb_led);
1232 __attribute__ ((weak))
1233 void led_init_ports(void)
1238 __attribute__ ((weak))
1239 void led_set(uint8_t usb_led)
1244 // // Using PE6 Caps Lock LED
1245 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1255 // PORTE &= ~(1<<6);
1258 led_set_kb(usb_led);
1262 //------------------------------------------------------------------------------
1263 // Override these functions in your keymap file to play different tunes on
1264 // different events such as startup and bootloader jump
1266 __attribute__ ((weak))
1267 void startup_user() {}
1269 __attribute__ ((weak))
1270 void shutdown_user() {}
1272 //------------------------------------------------------------------------------