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_ENABLE_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) {
290 if (record->event.pressed) {
295 // same as RBG_MOD, but if shift is pressed, it will use the reverese direction instead.
296 if (record->event.pressed) {
297 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
299 rgblight_step_reverse();
307 if (record->event.pressed) {
308 rgblight_increase_hue();
312 if (record->event.pressed) {
313 rgblight_decrease_hue();
317 if (record->event.pressed) {
318 rgblight_increase_sat();
322 if (record->event.pressed) {
323 rgblight_decrease_sat();
327 if (record->event.pressed) {
328 rgblight_increase_val();
332 if (record->event.pressed) {
333 rgblight_decrease_val();
337 if (record->event.pressed) {
341 case RGB_MODE_BREATHE:
342 if (record->event.pressed) {
343 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
350 case RGB_MODE_RAINBOW:
351 if (record->event.pressed) {
352 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
360 if (record->event.pressed) {
361 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
369 if (record->event.pressed) {
370 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
377 case RGB_MODE_KNIGHT:
378 if (record->event.pressed) {
379 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
387 if (record->event.pressed) {
391 case RGB_MODE_GRADIENT:
392 if (record->event.pressed) {
393 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
403 if (record->event.pressed) {
404 set_output(OUTPUT_AUTO);
408 if (record->event.pressed) {
409 set_output(OUTPUT_USB);
412 #ifdef BLUETOOTH_ENABLE
414 if (record->event.pressed) {
415 set_output(OUTPUT_BLUETOOTH);
420 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
421 if (record->event.pressed) {
422 // MAGIC actions (BOOTMAGIC without the boot)
423 if (!eeconfig_is_enabled()) {
427 keymap_config.raw = eeconfig_read_keymap();
430 case MAGIC_SWAP_CONTROL_CAPSLOCK:
431 keymap_config.swap_control_capslock = true;
433 case MAGIC_CAPSLOCK_TO_CONTROL:
434 keymap_config.capslock_to_control = true;
436 case MAGIC_SWAP_LALT_LGUI:
437 keymap_config.swap_lalt_lgui = true;
439 case MAGIC_SWAP_RALT_RGUI:
440 keymap_config.swap_ralt_rgui = true;
443 keymap_config.no_gui = true;
445 case MAGIC_SWAP_GRAVE_ESC:
446 keymap_config.swap_grave_esc = true;
448 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
449 keymap_config.swap_backslash_backspace = true;
451 case MAGIC_HOST_NKRO:
452 keymap_config.nkro = true;
454 case MAGIC_SWAP_ALT_GUI:
455 keymap_config.swap_lalt_lgui = true;
456 keymap_config.swap_ralt_rgui = true;
458 PLAY_SONG(ag_swap_song);
461 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
462 keymap_config.swap_control_capslock = false;
464 case MAGIC_UNCAPSLOCK_TO_CONTROL:
465 keymap_config.capslock_to_control = false;
467 case MAGIC_UNSWAP_LALT_LGUI:
468 keymap_config.swap_lalt_lgui = false;
470 case MAGIC_UNSWAP_RALT_RGUI:
471 keymap_config.swap_ralt_rgui = false;
474 keymap_config.no_gui = false;
476 case MAGIC_UNSWAP_GRAVE_ESC:
477 keymap_config.swap_grave_esc = false;
479 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
480 keymap_config.swap_backslash_backspace = false;
482 case MAGIC_UNHOST_NKRO:
483 keymap_config.nkro = false;
485 case MAGIC_UNSWAP_ALT_GUI:
486 keymap_config.swap_lalt_lgui = false;
487 keymap_config.swap_ralt_rgui = false;
489 PLAY_SONG(ag_norm_song);
492 case MAGIC_TOGGLE_NKRO:
493 keymap_config.nkro = !keymap_config.nkro;
498 eeconfig_update_keymap(keymap_config.raw);
499 clear_keyboard(); // clear to prevent stuck keys
505 if (record->event.pressed) {
506 shift_interrupted[0] = false;
507 scs_timer[0] = timer_read ();
508 register_mods(MOD_BIT(KC_LSFT));
511 #ifdef DISABLE_SPACE_CADET_ROLLOVER
512 if (get_mods() & MOD_BIT(KC_RSFT)) {
513 shift_interrupted[0] = true;
514 shift_interrupted[1] = true;
517 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
518 register_code(LSPO_KEY);
519 unregister_code(LSPO_KEY);
521 unregister_mods(MOD_BIT(KC_LSFT));
527 if (record->event.pressed) {
528 shift_interrupted[1] = false;
529 scs_timer[1] = timer_read ();
530 register_mods(MOD_BIT(KC_RSFT));
533 #ifdef DISABLE_SPACE_CADET_ROLLOVER
534 if (get_mods() & MOD_BIT(KC_LSFT)) {
535 shift_interrupted[0] = true;
536 shift_interrupted[1] = true;
539 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
540 register_code(RSPC_KEY);
541 unregister_code(RSPC_KEY);
543 unregister_mods(MOD_BIT(KC_RSFT));
548 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
549 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
551 #ifdef GRAVE_ESC_ALT_OVERRIDE
552 // if ALT is pressed, ESC is always sent
553 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
554 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
559 #ifdef GRAVE_ESC_CTRL_OVERRIDE
560 // if CTRL is pressed, ESC is always sent
561 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
562 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
567 #ifdef GRAVE_ESC_GUI_OVERRIDE
568 // if GUI is pressed, ESC is always sent
569 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
574 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
575 // if SHIFT is pressed, ESC is always sent
576 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
581 if (record->event.pressed) {
582 grave_esc_was_shifted = shifted;
583 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
586 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
589 send_keyboard_report();
592 shift_interrupted[0] = true;
593 shift_interrupted[1] = true;
598 return process_action_kb(record);
601 __attribute__ ((weak))
602 const bool ascii_to_shift_lut[0x80] PROGMEM = {
603 0, 0, 0, 0, 0, 0, 0, 0,
604 0, 0, 0, 0, 0, 0, 0, 0,
605 0, 0, 0, 0, 0, 0, 0, 0,
606 0, 0, 0, 0, 0, 0, 0, 0,
607 0, 1, 1, 1, 1, 1, 1, 0,
608 1, 1, 1, 1, 0, 0, 0, 0,
609 0, 0, 0, 0, 0, 0, 0, 0,
610 0, 0, 1, 0, 1, 0, 1, 1,
611 1, 1, 1, 1, 1, 1, 1, 1,
612 1, 1, 1, 1, 1, 1, 1, 1,
613 1, 1, 1, 1, 1, 1, 1, 1,
614 1, 1, 1, 0, 0, 0, 1, 1,
615 0, 0, 0, 0, 0, 0, 0, 0,
616 0, 0, 0, 0, 0, 0, 0, 0,
617 0, 0, 0, 0, 0, 0, 0, 0,
618 0, 0, 0, 1, 1, 1, 1, 0
621 __attribute__ ((weak))
622 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
623 0, 0, 0, 0, 0, 0, 0, 0,
624 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
625 0, 0, 0, 0, 0, 0, 0, 0,
626 0, 0, 0, KC_ESC, 0, 0, 0, 0,
627 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
628 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
629 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
630 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
631 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
632 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
633 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
634 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
635 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
636 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
637 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
638 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
641 void send_string(const char *str) {
642 send_string_with_delay(str, 0);
645 void send_string_P(const char *str) {
646 send_string_with_delay_P(str, 0);
649 void send_string_with_delay(const char *str, uint8_t interval) {
651 char ascii_code = *str;
652 if (!ascii_code) break;
653 if (ascii_code == 1) {
655 uint8_t keycode = *(++str);
656 register_code(keycode);
657 unregister_code(keycode);
658 } else if (ascii_code == 2) {
660 uint8_t keycode = *(++str);
661 register_code(keycode);
662 } else if (ascii_code == 3) {
664 uint8_t keycode = *(++str);
665 unregister_code(keycode);
667 send_char(ascii_code);
671 { uint8_t ms = interval; while (ms--) wait_ms(1); }
675 void send_string_with_delay_P(const char *str, uint8_t interval) {
677 char ascii_code = pgm_read_byte(str);
678 if (!ascii_code) break;
679 if (ascii_code == 1) {
681 uint8_t keycode = pgm_read_byte(++str);
682 register_code(keycode);
683 unregister_code(keycode);
684 } else if (ascii_code == 2) {
686 uint8_t keycode = pgm_read_byte(++str);
687 register_code(keycode);
688 } else if (ascii_code == 3) {
690 uint8_t keycode = pgm_read_byte(++str);
691 unregister_code(keycode);
693 send_char(ascii_code);
697 { uint8_t ms = interval; while (ms--) wait_ms(1); }
701 void send_char(char ascii_code) {
703 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
704 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
705 register_code(KC_LSFT);
706 register_code(keycode);
707 unregister_code(keycode);
708 unregister_code(KC_LSFT);
710 register_code(keycode);
711 unregister_code(keycode);
715 void set_single_persistent_default_layer(uint8_t default_layer) {
716 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
717 PLAY_SONG(default_layer_songs[default_layer]);
719 eeconfig_update_default_layer(1U<<default_layer);
720 default_layer_set(1U<<default_layer);
723 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
724 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
731 void tap_random_base64(void) {
732 #if defined(__AVR_ATmega32U4__)
733 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
735 uint8_t key = rand() % 64;
739 register_code(KC_LSFT);
740 register_code(key + KC_A);
741 unregister_code(key + KC_A);
742 unregister_code(KC_LSFT);
745 register_code(key - 26 + KC_A);
746 unregister_code(key - 26 + KC_A);
750 unregister_code(KC_0);
753 register_code(key - 53 + KC_1);
754 unregister_code(key - 53 + KC_1);
757 register_code(KC_LSFT);
758 register_code(KC_EQL);
759 unregister_code(KC_EQL);
760 unregister_code(KC_LSFT);
763 register_code(KC_SLSH);
764 unregister_code(KC_SLSH);
769 void matrix_init_quantum() {
770 #ifdef BACKLIGHT_ENABLE
771 backlight_init_ports();
779 void matrix_scan_quantum() {
784 #ifdef TAP_DANCE_ENABLE
785 matrix_scan_tap_dance();
792 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
799 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
801 static const uint8_t backlight_pin = BACKLIGHT_PIN;
803 #if BACKLIGHT_PIN == B7
804 # define COM1x1 COM1C1
806 #elif BACKLIGHT_PIN == B6
807 # define COM1x1 COM1B1
809 #elif BACKLIGHT_PIN == B5
810 # define COM1x1 COM1A1
813 # define NO_BACKLIGHT_CLOCK
816 #ifndef BACKLIGHT_ON_STATE
817 #define BACKLIGHT_ON_STATE 0
820 __attribute__ ((weak))
821 void backlight_init_ports(void)
824 // Setup backlight pin as output and output to on state.
826 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
827 #if BACKLIGHT_ON_STATE == 0
829 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
832 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
835 #ifndef NO_BACKLIGHT_CLOCK
836 // Use full 16-bit resolution.
839 // I could write a wall of text here to explain... but TL;DW
840 // Go read the ATmega32u4 datasheet.
841 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
843 // Pin PB7 = OCR1C (Timer 1, Channel C)
844 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
845 // (i.e. start high, go low when counter matches.)
846 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
847 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
849 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
850 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
854 #ifdef BACKLIGHT_BREATHING
855 breathing_defaults();
859 __attribute__ ((weak))
860 void backlight_set(uint8_t level)
862 // Prevent backlight blink on lowest level
863 // #if BACKLIGHT_ON_STATE == 0
865 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
868 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
872 #ifndef NO_BACKLIGHT_CLOCK
873 // Turn off PWM control on backlight pin, revert to output low.
874 TCCR1A &= ~(_BV(COM1x1));
877 // #if BACKLIGHT_ON_STATE == 0
879 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
882 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
886 #ifndef NO_BACKLIGHT_CLOCK
887 else if ( level == BACKLIGHT_LEVELS ) {
888 // Turn on PWM control of backlight pin
889 TCCR1A |= _BV(COM1x1);
890 // Set the brightness
894 // Turn on PWM control of backlight pin
895 TCCR1A |= _BV(COM1x1);
896 // Set the brightness
897 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
901 #ifdef BACKLIGHT_BREATHING
902 breathing_intensity_default();
906 uint8_t backlight_tick = 0;
908 void backlight_task(void) {
909 #ifdef NO_BACKLIGHT_CLOCK
910 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
911 #if BACKLIGHT_ON_STATE == 0
913 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
916 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
919 #if BACKLIGHT_ON_STATE == 0
921 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
924 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
927 backlight_tick = (backlight_tick + 1) % 16;
931 #ifdef BACKLIGHT_BREATHING
933 #define BREATHING_NO_HALT 0
934 #define BREATHING_HALT_OFF 1
935 #define BREATHING_HALT_ON 2
937 static uint8_t breath_intensity;
938 static uint8_t breath_speed;
939 static uint16_t breathing_index;
940 static uint8_t breathing_halt;
942 void breathing_enable(void)
944 if (get_backlight_level() == 0)
950 // Set breathing_index to be at the midpoint (brightest point)
951 breathing_index = 0x20 << breath_speed;
954 breathing_halt = BREATHING_NO_HALT;
956 // Enable breathing interrupt
957 TIMSK1 |= _BV(OCIE1A);
960 void breathing_pulse(void)
962 if (get_backlight_level() == 0)
968 // Set breathing_index to be at the midpoint + 1 (brightest point)
969 breathing_index = 0x21 << breath_speed;
972 breathing_halt = BREATHING_HALT_ON;
974 // Enable breathing interrupt
975 TIMSK1 |= _BV(OCIE1A);
978 void breathing_disable(void)
980 // Disable breathing interrupt
981 TIMSK1 &= ~_BV(OCIE1A);
982 backlight_set(get_backlight_level());
985 void breathing_self_disable(void)
987 if (get_backlight_level() == 0)
989 breathing_halt = BREATHING_HALT_OFF;
993 breathing_halt = BREATHING_HALT_ON;
996 //backlight_set(get_backlight_level());
999 void breathing_toggle(void)
1001 if (!is_breathing())
1003 if (get_backlight_level() == 0)
1005 breathing_index = 0;
1009 // Set breathing_index to be at the midpoint + 1 (brightest point)
1010 breathing_index = 0x21 << breath_speed;
1013 breathing_halt = BREATHING_NO_HALT;
1016 // Toggle breathing interrupt
1017 TIMSK1 ^= _BV(OCIE1A);
1019 // Restore backlight level
1020 if (!is_breathing())
1022 backlight_set(get_backlight_level());
1026 bool is_breathing(void)
1028 return (TIMSK1 && _BV(OCIE1A));
1031 void breathing_intensity_default(void)
1033 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
1034 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
1037 void breathing_intensity_set(uint8_t value)
1039 breath_intensity = value;
1042 void breathing_speed_default(void)
1047 void breathing_speed_set(uint8_t value)
1049 bool is_breathing_now = is_breathing();
1050 uint8_t old_breath_speed = breath_speed;
1052 if (is_breathing_now)
1054 // Disable breathing interrupt
1055 TIMSK1 &= ~_BV(OCIE1A);
1058 breath_speed = value;
1060 if (is_breathing_now)
1062 // Adjust index to account for new speed
1063 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
1065 // Enable breathing interrupt
1066 TIMSK1 |= _BV(OCIE1A);
1071 void breathing_speed_inc(uint8_t value)
1073 if ((uint16_t)(breath_speed - value) > 10 )
1075 breathing_speed_set(0);
1079 breathing_speed_set(breath_speed - value);
1083 void breathing_speed_dec(uint8_t value)
1085 if ((uint16_t)(breath_speed + value) > 10 )
1087 breathing_speed_set(10);
1091 breathing_speed_set(breath_speed + value);
1095 void breathing_defaults(void)
1097 breathing_intensity_default();
1098 breathing_speed_default();
1099 breathing_halt = BREATHING_NO_HALT;
1102 /* Breathing Sleep LED brighness(PWM On period) table
1103 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
1105 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
1106 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
1108 static const uint8_t breathing_table[64] PROGMEM = {
1109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
1110 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
1111 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
1112 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1115 ISR(TIMER1_COMPA_vect)
1117 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
1120 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
1122 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
1124 // Disable breathing interrupt
1125 TIMSK1 &= ~_BV(OCIE1A);
1128 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
1136 __attribute__ ((weak))
1137 void backlight_init_ports(void)
1142 __attribute__ ((weak))
1143 void backlight_set(uint8_t level)
1151 // Functions for spitting out values
1154 void send_dword(uint32_t number) { // this might not actually work
1155 uint16_t word = (number >> 16);
1157 send_word(number & 0xFFFFUL);
1160 void send_word(uint16_t number) {
1161 uint8_t byte = number >> 8;
1163 send_byte(number & 0xFF);
1166 void send_byte(uint8_t number) {
1167 uint8_t nibble = number >> 4;
1168 send_nibble(nibble);
1169 send_nibble(number & 0xF);
1172 void send_nibble(uint8_t number) {
1175 register_code(KC_0);
1176 unregister_code(KC_0);
1179 register_code(KC_1 + (number - 1));
1180 unregister_code(KC_1 + (number - 1));
1183 register_code(KC_A + (number - 0xA));
1184 unregister_code(KC_A + (number - 0xA));
1190 __attribute__((weak))
1191 uint16_t hex_to_keycode(uint8_t hex)
1196 } else if (hex < 0xA) {
1197 return KC_1 + (hex - 0x1);
1199 return KC_A + (hex - 0xA);
1203 void api_send_unicode(uint32_t unicode) {
1206 dword_to_bytes(unicode, chunk);
1207 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1211 __attribute__ ((weak))
1212 void led_set_user(uint8_t usb_led) {
1216 __attribute__ ((weak))
1217 void led_set_kb(uint8_t usb_led) {
1218 led_set_user(usb_led);
1221 __attribute__ ((weak))
1222 void led_init_ports(void)
1227 __attribute__ ((weak))
1228 void led_set(uint8_t usb_led)
1233 // // Using PE6 Caps Lock LED
1234 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1244 // PORTE &= ~(1<<6);
1247 led_set_kb(usb_led);
1251 //------------------------------------------------------------------------------
1252 // Override these functions in your keymap file to play different tunes on
1253 // different events such as startup and bootloader jump
1255 __attribute__ ((weak))
1256 void startup_user() {}
1258 __attribute__ ((weak))
1259 void shutdown_user() {}
1261 //------------------------------------------------------------------------------