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 #ifdef CATERINA_BOOTLOADER
147 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
152 // Shift / paren setup
155 #define LSPO_KEY KC_9
158 #define RSPC_KEY KC_0
161 static bool shift_interrupted[2] = {0, 0};
162 static uint16_t scs_timer[2] = {0, 0};
164 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
165 * Used to ensure that the correct keycode is released if the key is released.
167 static bool grave_esc_was_shifted = false;
169 bool process_record_quantum(keyrecord_t *record) {
171 /* This gets the keycode from the key pressed */
172 keypos_t key = record->event.key;
175 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
176 /* TODO: Use store_or_get_action() or a similar function. */
177 if (!disable_action_cache) {
180 if (record->event.pressed) {
181 layer = layer_switch_get_layer(key);
182 update_source_layers_cache(key, layer);
184 layer = read_source_layers_cache(key);
186 keycode = keymap_key_to_keycode(layer, key);
189 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
191 // This is how you use actions here
192 // if (keycode == KC_LEAD) {
194 // action.code = ACTION_DEFAULT_LAYER_SET(0);
195 // process_action(record, action);
200 #if defined(KEY_LOCK_ENABLE)
201 // Must run first to be able to mask key_up events.
202 process_key_lock(&keycode, record) &&
204 process_record_kb(keycode, record) &&
205 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
206 process_midi(keycode, record) &&
209 process_audio(keycode, record) &&
212 process_steno(keycode, record) &&
214 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
215 process_music(keycode, record) &&
217 #ifdef TAP_DANCE_ENABLE
218 process_tap_dance(keycode, record) &&
220 #ifndef DISABLE_LEADER
221 process_leader(keycode, record) &&
223 #ifndef DISABLE_CHORDING
224 process_chording(keycode, record) &&
227 process_combo(keycode, record) &&
229 #ifdef UNICODE_ENABLE
230 process_unicode(keycode, record) &&
233 process_ucis(keycode, record) &&
235 #ifdef PRINTING_ENABLE
236 process_printer(keycode, record) &&
238 #ifdef UNICODEMAP_ENABLE
239 process_unicode_map(keycode, record) &&
241 #ifdef TERMINAL_ENABLE
242 process_terminal(keycode, record) &&
248 // Shift / paren setup
252 if (record->event.pressed) {
257 if (record->event.pressed) {
259 print("DEBUG: enabled.\n");
262 #ifdef FAUXCLICKY_ENABLE
264 if (record->event.pressed) {
269 if (record->event.pressed) {
274 if (record->event.pressed) {
279 #ifdef RGBLIGHT_ENABLE
281 if (record->event.pressed) {
286 if (record->event.pressed) {
291 if (record->event.pressed) {
292 rgblight_increase_hue();
296 if (record->event.pressed) {
297 rgblight_decrease_hue();
301 if (record->event.pressed) {
302 rgblight_increase_sat();
306 if (record->event.pressed) {
307 rgblight_decrease_sat();
311 if (record->event.pressed) {
312 rgblight_increase_val();
316 if (record->event.pressed) {
317 rgblight_decrease_val();
321 if (record->event.pressed) {
325 case RGB_MODE_BREATHE:
326 if (record->event.pressed) {
327 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
334 case RGB_MODE_RAINBOW:
335 if (record->event.pressed) {
336 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
344 if (record->event.pressed) {
345 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
353 if (record->event.pressed) {
354 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
361 case RGB_MODE_KNIGHT:
362 if (record->event.pressed) {
363 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
371 if (record->event.pressed) {
375 case RGB_MODE_GRADIENT:
376 if (record->event.pressed) {
377 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
387 if (record->event.pressed) {
388 set_output(OUTPUT_AUTO);
392 if (record->event.pressed) {
393 set_output(OUTPUT_USB);
396 #ifdef BLUETOOTH_ENABLE
398 if (record->event.pressed) {
399 set_output(OUTPUT_BLUETOOTH);
404 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
405 if (record->event.pressed) {
406 // MAGIC actions (BOOTMAGIC without the boot)
407 if (!eeconfig_is_enabled()) {
411 keymap_config.raw = eeconfig_read_keymap();
414 case MAGIC_SWAP_CONTROL_CAPSLOCK:
415 keymap_config.swap_control_capslock = true;
417 case MAGIC_CAPSLOCK_TO_CONTROL:
418 keymap_config.capslock_to_control = true;
420 case MAGIC_SWAP_LALT_LGUI:
421 keymap_config.swap_lalt_lgui = true;
423 case MAGIC_SWAP_RALT_RGUI:
424 keymap_config.swap_ralt_rgui = true;
427 keymap_config.no_gui = true;
429 case MAGIC_SWAP_GRAVE_ESC:
430 keymap_config.swap_grave_esc = true;
432 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
433 keymap_config.swap_backslash_backspace = true;
435 case MAGIC_HOST_NKRO:
436 keymap_config.nkro = true;
438 case MAGIC_SWAP_ALT_GUI:
439 keymap_config.swap_lalt_lgui = true;
440 keymap_config.swap_ralt_rgui = true;
442 PLAY_SONG(ag_swap_song);
445 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
446 keymap_config.swap_control_capslock = false;
448 case MAGIC_UNCAPSLOCK_TO_CONTROL:
449 keymap_config.capslock_to_control = false;
451 case MAGIC_UNSWAP_LALT_LGUI:
452 keymap_config.swap_lalt_lgui = false;
454 case MAGIC_UNSWAP_RALT_RGUI:
455 keymap_config.swap_ralt_rgui = false;
458 keymap_config.no_gui = false;
460 case MAGIC_UNSWAP_GRAVE_ESC:
461 keymap_config.swap_grave_esc = false;
463 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
464 keymap_config.swap_backslash_backspace = false;
466 case MAGIC_UNHOST_NKRO:
467 keymap_config.nkro = false;
469 case MAGIC_UNSWAP_ALT_GUI:
470 keymap_config.swap_lalt_lgui = false;
471 keymap_config.swap_ralt_rgui = false;
473 PLAY_SONG(ag_norm_song);
476 case MAGIC_TOGGLE_NKRO:
477 keymap_config.nkro = !keymap_config.nkro;
482 eeconfig_update_keymap(keymap_config.raw);
483 clear_keyboard(); // clear to prevent stuck keys
489 if (record->event.pressed) {
490 shift_interrupted[0] = false;
491 scs_timer[0] = timer_read ();
492 register_mods(MOD_BIT(KC_LSFT));
495 #ifdef DISABLE_SPACE_CADET_ROLLOVER
496 if (get_mods() & MOD_BIT(KC_RSFT)) {
497 shift_interrupted[0] = true;
498 shift_interrupted[1] = true;
501 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
502 register_code(LSPO_KEY);
503 unregister_code(LSPO_KEY);
505 unregister_mods(MOD_BIT(KC_LSFT));
511 if (record->event.pressed) {
512 shift_interrupted[1] = false;
513 scs_timer[1] = timer_read ();
514 register_mods(MOD_BIT(KC_RSFT));
517 #ifdef DISABLE_SPACE_CADET_ROLLOVER
518 if (get_mods() & MOD_BIT(KC_LSFT)) {
519 shift_interrupted[0] = true;
520 shift_interrupted[1] = true;
523 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
524 register_code(RSPC_KEY);
525 unregister_code(RSPC_KEY);
527 unregister_mods(MOD_BIT(KC_RSFT));
532 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
533 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
535 #ifdef GRAVE_ESC_CTRL_OVERRIDE
536 // if CTRL is pressed, ESC is always read as ESC, even if SHIFT or GUI is pressed.
537 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
538 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)))
542 if (record->event.pressed) {
543 grave_esc_was_shifted = shifted;
544 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
547 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
550 send_keyboard_report();
553 shift_interrupted[0] = true;
554 shift_interrupted[1] = true;
559 return process_action_kb(record);
562 __attribute__ ((weak))
563 const bool ascii_to_shift_lut[0x80] PROGMEM = {
564 0, 0, 0, 0, 0, 0, 0, 0,
565 0, 0, 0, 0, 0, 0, 0, 0,
566 0, 0, 0, 0, 0, 0, 0, 0,
567 0, 0, 0, 0, 0, 0, 0, 0,
568 0, 1, 1, 1, 1, 1, 1, 0,
569 1, 1, 1, 1, 0, 0, 0, 0,
570 0, 0, 0, 0, 0, 0, 0, 0,
571 0, 0, 1, 0, 1, 0, 1, 1,
572 1, 1, 1, 1, 1, 1, 1, 1,
573 1, 1, 1, 1, 1, 1, 1, 1,
574 1, 1, 1, 1, 1, 1, 1, 1,
575 1, 1, 1, 0, 0, 0, 1, 1,
576 0, 0, 0, 0, 0, 0, 0, 0,
577 0, 0, 0, 0, 0, 0, 0, 0,
578 0, 0, 0, 0, 0, 0, 0, 0,
579 0, 0, 0, 1, 1, 1, 1, 0
582 __attribute__ ((weak))
583 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
584 0, 0, 0, 0, 0, 0, 0, 0,
585 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
586 0, 0, 0, 0, 0, 0, 0, 0,
587 0, 0, 0, KC_ESC, 0, 0, 0, 0,
588 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
589 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
590 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
591 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
592 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
593 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
594 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
595 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
596 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
597 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
598 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
599 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
602 void send_string(const char *str) {
603 send_string_with_delay(str, 0);
606 void send_string_P(const char *str) {
607 send_string_with_delay_P(str, 0);
610 void send_string_with_delay(const char *str, uint8_t interval) {
612 char ascii_code = *str;
613 if (!ascii_code) break;
614 if (ascii_code == 1) {
616 uint8_t keycode = *(++str);
617 register_code(keycode);
618 unregister_code(keycode);
619 } else if (ascii_code == 2) {
621 uint8_t keycode = *(++str);
622 register_code(keycode);
623 } else if (ascii_code == 3) {
625 uint8_t keycode = *(++str);
626 unregister_code(keycode);
628 send_char(ascii_code);
632 { uint8_t ms = interval; while (ms--) wait_ms(1); }
636 void send_string_with_delay_P(const char *str, uint8_t interval) {
638 char ascii_code = pgm_read_byte(str);
639 if (!ascii_code) break;
640 if (ascii_code == 1) {
642 uint8_t keycode = pgm_read_byte(++str);
643 register_code(keycode);
644 unregister_code(keycode);
645 } else if (ascii_code == 2) {
647 uint8_t keycode = pgm_read_byte(++str);
648 register_code(keycode);
649 } else if (ascii_code == 3) {
651 uint8_t keycode = pgm_read_byte(++str);
652 unregister_code(keycode);
654 send_char(ascii_code);
658 { uint8_t ms = interval; while (ms--) wait_ms(1); }
662 void send_char(char ascii_code) {
664 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
665 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
666 register_code(KC_LSFT);
667 register_code(keycode);
668 unregister_code(keycode);
669 unregister_code(KC_LSFT);
671 register_code(keycode);
672 unregister_code(keycode);
676 void set_single_persistent_default_layer(uint8_t default_layer) {
677 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
678 PLAY_SONG(default_layer_songs[default_layer]);
680 eeconfig_update_default_layer(1U<<default_layer);
681 default_layer_set(1U<<default_layer);
684 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
685 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
692 void tap_random_base64(void) {
693 #if defined(__AVR_ATmega32U4__)
694 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
696 uint8_t key = rand() % 64;
700 register_code(KC_LSFT);
701 register_code(key + KC_A);
702 unregister_code(key + KC_A);
703 unregister_code(KC_LSFT);
706 register_code(key - 26 + KC_A);
707 unregister_code(key - 26 + KC_A);
711 unregister_code(KC_0);
714 register_code(key - 53 + KC_1);
715 unregister_code(key - 53 + KC_1);
718 register_code(KC_LSFT);
719 register_code(KC_EQL);
720 unregister_code(KC_EQL);
721 unregister_code(KC_LSFT);
724 register_code(KC_SLSH);
725 unregister_code(KC_SLSH);
730 void matrix_init_quantum() {
731 #ifdef BACKLIGHT_ENABLE
732 backlight_init_ports();
740 void matrix_scan_quantum() {
745 #ifdef TAP_DANCE_ENABLE
746 matrix_scan_tap_dance();
753 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
760 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
762 static const uint8_t backlight_pin = BACKLIGHT_PIN;
764 #if BACKLIGHT_PIN == B7
765 # define COM1x1 COM1C1
767 #elif BACKLIGHT_PIN == B6
768 # define COM1x1 COM1B1
770 #elif BACKLIGHT_PIN == B5
771 # define COM1x1 COM1A1
774 # define NO_BACKLIGHT_CLOCK
777 #ifndef BACKLIGHT_ON_STATE
778 #define BACKLIGHT_ON_STATE 0
781 __attribute__ ((weak))
782 void backlight_init_ports(void)
785 // Setup backlight pin as output and output to on state.
787 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
788 #if BACKLIGHT_ON_STATE == 0
790 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
793 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
796 #ifndef NO_BACKLIGHT_CLOCK
797 // Use full 16-bit resolution.
800 // I could write a wall of text here to explain... but TL;DW
801 // Go read the ATmega32u4 datasheet.
802 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
804 // Pin PB7 = OCR1C (Timer 1, Channel C)
805 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
806 // (i.e. start high, go low when counter matches.)
807 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
808 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
810 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
811 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
815 #ifdef BACKLIGHT_BREATHING
816 breathing_defaults();
820 __attribute__ ((weak))
821 void backlight_set(uint8_t level)
823 // Prevent backlight blink on lowest level
824 // #if BACKLIGHT_ON_STATE == 0
826 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
829 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
833 #ifndef NO_BACKLIGHT_CLOCK
834 // Turn off PWM control on backlight pin, revert to output low.
835 TCCR1A &= ~(_BV(COM1x1));
838 // #if BACKLIGHT_ON_STATE == 0
840 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
843 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
847 #ifndef NO_BACKLIGHT_CLOCK
848 else if ( level == BACKLIGHT_LEVELS ) {
849 // Turn on PWM control of backlight pin
850 TCCR1A |= _BV(COM1x1);
851 // Set the brightness
855 // Turn on PWM control of backlight pin
856 TCCR1A |= _BV(COM1x1);
857 // Set the brightness
858 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
862 #ifdef BACKLIGHT_BREATHING
863 breathing_intensity_default();
867 uint8_t backlight_tick = 0;
869 void backlight_task(void) {
870 #ifdef NO_BACKLIGHT_CLOCK
871 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
872 #if BACKLIGHT_ON_STATE == 0
874 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
877 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
880 #if BACKLIGHT_ON_STATE == 0
882 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
885 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
888 backlight_tick = (backlight_tick + 1) % 16;
892 #ifdef BACKLIGHT_BREATHING
894 #define BREATHING_NO_HALT 0
895 #define BREATHING_HALT_OFF 1
896 #define BREATHING_HALT_ON 2
898 static uint8_t breath_intensity;
899 static uint8_t breath_speed;
900 static uint16_t breathing_index;
901 static uint8_t breathing_halt;
903 void breathing_enable(void)
905 if (get_backlight_level() == 0)
911 // Set breathing_index to be at the midpoint (brightest point)
912 breathing_index = 0x20 << breath_speed;
915 breathing_halt = BREATHING_NO_HALT;
917 // Enable breathing interrupt
918 TIMSK1 |= _BV(OCIE1A);
921 void breathing_pulse(void)
923 if (get_backlight_level() == 0)
929 // Set breathing_index to be at the midpoint + 1 (brightest point)
930 breathing_index = 0x21 << breath_speed;
933 breathing_halt = BREATHING_HALT_ON;
935 // Enable breathing interrupt
936 TIMSK1 |= _BV(OCIE1A);
939 void breathing_disable(void)
941 // Disable breathing interrupt
942 TIMSK1 &= ~_BV(OCIE1A);
943 backlight_set(get_backlight_level());
946 void breathing_self_disable(void)
948 if (get_backlight_level() == 0)
950 breathing_halt = BREATHING_HALT_OFF;
954 breathing_halt = BREATHING_HALT_ON;
957 //backlight_set(get_backlight_level());
960 void breathing_toggle(void)
964 if (get_backlight_level() == 0)
970 // Set breathing_index to be at the midpoint + 1 (brightest point)
971 breathing_index = 0x21 << breath_speed;
974 breathing_halt = BREATHING_NO_HALT;
977 // Toggle breathing interrupt
978 TIMSK1 ^= _BV(OCIE1A);
980 // Restore backlight level
983 backlight_set(get_backlight_level());
987 bool is_breathing(void)
989 return (TIMSK1 && _BV(OCIE1A));
992 void breathing_intensity_default(void)
994 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
995 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
998 void breathing_intensity_set(uint8_t value)
1000 breath_intensity = value;
1003 void breathing_speed_default(void)
1008 void breathing_speed_set(uint8_t value)
1010 bool is_breathing_now = is_breathing();
1011 uint8_t old_breath_speed = breath_speed;
1013 if (is_breathing_now)
1015 // Disable breathing interrupt
1016 TIMSK1 &= ~_BV(OCIE1A);
1019 breath_speed = value;
1021 if (is_breathing_now)
1023 // Adjust index to account for new speed
1024 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
1026 // Enable breathing interrupt
1027 TIMSK1 |= _BV(OCIE1A);
1032 void breathing_speed_inc(uint8_t value)
1034 if ((uint16_t)(breath_speed - value) > 10 )
1036 breathing_speed_set(0);
1040 breathing_speed_set(breath_speed - value);
1044 void breathing_speed_dec(uint8_t value)
1046 if ((uint16_t)(breath_speed + value) > 10 )
1048 breathing_speed_set(10);
1052 breathing_speed_set(breath_speed + value);
1056 void breathing_defaults(void)
1058 breathing_intensity_default();
1059 breathing_speed_default();
1060 breathing_halt = BREATHING_NO_HALT;
1063 /* Breathing Sleep LED brighness(PWM On period) table
1064 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
1066 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
1067 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
1069 static const uint8_t breathing_table[64] PROGMEM = {
1070 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
1071 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
1072 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
1073 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1076 ISR(TIMER1_COMPA_vect)
1078 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
1081 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
1083 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
1085 // Disable breathing interrupt
1086 TIMSK1 &= ~_BV(OCIE1A);
1089 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
1099 __attribute__ ((weak))
1100 void backlight_init_ports(void)
1105 __attribute__ ((weak))
1106 void backlight_set(uint8_t level)
1114 // Functions for spitting out values
1117 void send_dword(uint32_t number) { // this might not actually work
1118 uint16_t word = (number >> 16);
1120 send_word(number & 0xFFFFUL);
1123 void send_word(uint16_t number) {
1124 uint8_t byte = number >> 8;
1126 send_byte(number & 0xFF);
1129 void send_byte(uint8_t number) {
1130 uint8_t nibble = number >> 4;
1131 send_nibble(nibble);
1132 send_nibble(number & 0xF);
1135 void send_nibble(uint8_t number) {
1138 register_code(KC_0);
1139 unregister_code(KC_0);
1142 register_code(KC_1 + (number - 1));
1143 unregister_code(KC_1 + (number - 1));
1146 register_code(KC_A + (number - 0xA));
1147 unregister_code(KC_A + (number - 0xA));
1153 __attribute__((weak))
1154 uint16_t hex_to_keycode(uint8_t hex)
1158 } else if (hex < 0xA) {
1159 return KC_1 + (hex - 0x1);
1161 return KC_A + (hex - 0xA);
1165 void api_send_unicode(uint32_t unicode) {
1168 dword_to_bytes(unicode, chunk);
1169 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1173 __attribute__ ((weak))
1174 void led_set_user(uint8_t usb_led) {
1178 __attribute__ ((weak))
1179 void led_set_kb(uint8_t usb_led) {
1180 led_set_user(usb_led);
1183 __attribute__ ((weak))
1184 void led_init_ports(void)
1189 __attribute__ ((weak))
1190 void led_set(uint8_t usb_led)
1195 // // Using PE6 Caps Lock LED
1196 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1206 // PORTE &= ~(1<<6);
1209 led_set_kb(usb_led);
1213 //------------------------------------------------------------------------------
1214 // Override these functions in your keymap file to play different tunes on
1215 // different events such as startup and bootloader jump
1217 __attribute__ ((weak))
1218 void startup_user() {}
1220 __attribute__ ((weak))
1221 void shutdown_user() {}
1223 //------------------------------------------------------------------------------