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 AUTO_SHIFT_ENABLE
239 process_auto_shift(keycode, record) &&
241 #ifdef UNICODEMAP_ENABLE
242 process_unicode_map(keycode, record) &&
244 #ifdef TERMINAL_ENABLE
245 process_terminal(keycode, record) &&
251 // Shift / paren setup
255 if (record->event.pressed) {
260 if (record->event.pressed) {
262 print("DEBUG: enabled.\n");
265 #ifdef FAUXCLICKY_ENABLE
267 if (record->event.pressed) {
272 if (record->event.pressed) {
277 if (record->event.pressed) {
282 #ifdef RGBLIGHT_ENABLE
284 if (record->event.pressed) {
289 if (record->event.pressed) {
294 if (record->event.pressed) {
295 rgblight_increase_hue();
299 if (record->event.pressed) {
300 rgblight_decrease_hue();
304 if (record->event.pressed) {
305 rgblight_increase_sat();
309 if (record->event.pressed) {
310 rgblight_decrease_sat();
314 if (record->event.pressed) {
315 rgblight_increase_val();
319 if (record->event.pressed) {
320 rgblight_decrease_val();
324 if (record->event.pressed) {
328 case RGB_MODE_BREATHE:
329 if (record->event.pressed) {
330 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
337 case RGB_MODE_RAINBOW:
338 if (record->event.pressed) {
339 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
347 if (record->event.pressed) {
348 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
356 if (record->event.pressed) {
357 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
364 case RGB_MODE_KNIGHT:
365 if (record->event.pressed) {
366 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
374 if (record->event.pressed) {
378 case RGB_MODE_GRADIENT:
379 if (record->event.pressed) {
380 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
390 if (record->event.pressed) {
391 set_output(OUTPUT_AUTO);
395 if (record->event.pressed) {
396 set_output(OUTPUT_USB);
399 #ifdef BLUETOOTH_ENABLE
401 if (record->event.pressed) {
402 set_output(OUTPUT_BLUETOOTH);
407 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
408 if (record->event.pressed) {
409 // MAGIC actions (BOOTMAGIC without the boot)
410 if (!eeconfig_is_enabled()) {
414 keymap_config.raw = eeconfig_read_keymap();
417 case MAGIC_SWAP_CONTROL_CAPSLOCK:
418 keymap_config.swap_control_capslock = true;
420 case MAGIC_CAPSLOCK_TO_CONTROL:
421 keymap_config.capslock_to_control = true;
423 case MAGIC_SWAP_LALT_LGUI:
424 keymap_config.swap_lalt_lgui = true;
426 case MAGIC_SWAP_RALT_RGUI:
427 keymap_config.swap_ralt_rgui = true;
430 keymap_config.no_gui = true;
432 case MAGIC_SWAP_GRAVE_ESC:
433 keymap_config.swap_grave_esc = true;
435 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
436 keymap_config.swap_backslash_backspace = true;
438 case MAGIC_HOST_NKRO:
439 keymap_config.nkro = true;
441 case MAGIC_SWAP_ALT_GUI:
442 keymap_config.swap_lalt_lgui = true;
443 keymap_config.swap_ralt_rgui = true;
445 PLAY_SONG(ag_swap_song);
448 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
449 keymap_config.swap_control_capslock = false;
451 case MAGIC_UNCAPSLOCK_TO_CONTROL:
452 keymap_config.capslock_to_control = false;
454 case MAGIC_UNSWAP_LALT_LGUI:
455 keymap_config.swap_lalt_lgui = false;
457 case MAGIC_UNSWAP_RALT_RGUI:
458 keymap_config.swap_ralt_rgui = false;
461 keymap_config.no_gui = false;
463 case MAGIC_UNSWAP_GRAVE_ESC:
464 keymap_config.swap_grave_esc = false;
466 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
467 keymap_config.swap_backslash_backspace = false;
469 case MAGIC_UNHOST_NKRO:
470 keymap_config.nkro = false;
472 case MAGIC_UNSWAP_ALT_GUI:
473 keymap_config.swap_lalt_lgui = false;
474 keymap_config.swap_ralt_rgui = false;
476 PLAY_SONG(ag_norm_song);
479 case MAGIC_TOGGLE_NKRO:
480 keymap_config.nkro = !keymap_config.nkro;
485 eeconfig_update_keymap(keymap_config.raw);
486 clear_keyboard(); // clear to prevent stuck keys
492 if (record->event.pressed) {
493 shift_interrupted[0] = false;
494 scs_timer[0] = timer_read ();
495 register_mods(MOD_BIT(KC_LSFT));
498 #ifdef DISABLE_SPACE_CADET_ROLLOVER
499 if (get_mods() & MOD_BIT(KC_RSFT)) {
500 shift_interrupted[0] = true;
501 shift_interrupted[1] = true;
504 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
505 register_code(LSPO_KEY);
506 unregister_code(LSPO_KEY);
508 unregister_mods(MOD_BIT(KC_LSFT));
514 if (record->event.pressed) {
515 shift_interrupted[1] = false;
516 scs_timer[1] = timer_read ();
517 register_mods(MOD_BIT(KC_RSFT));
520 #ifdef DISABLE_SPACE_CADET_ROLLOVER
521 if (get_mods() & MOD_BIT(KC_LSFT)) {
522 shift_interrupted[0] = true;
523 shift_interrupted[1] = true;
526 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
527 register_code(RSPC_KEY);
528 unregister_code(RSPC_KEY);
530 unregister_mods(MOD_BIT(KC_RSFT));
535 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
536 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
538 #ifdef GRAVE_ESC_CTRL_OVERRIDE
539 // if CTRL is pressed, ESC is always read as ESC, even if SHIFT or GUI is pressed.
540 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
541 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)))
545 if (record->event.pressed) {
546 grave_esc_was_shifted = shifted;
547 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
550 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
553 send_keyboard_report();
556 shift_interrupted[0] = true;
557 shift_interrupted[1] = true;
562 return process_action_kb(record);
565 __attribute__ ((weak))
566 const bool ascii_to_shift_lut[0x80] PROGMEM = {
567 0, 0, 0, 0, 0, 0, 0, 0,
568 0, 0, 0, 0, 0, 0, 0, 0,
569 0, 0, 0, 0, 0, 0, 0, 0,
570 0, 0, 0, 0, 0, 0, 0, 0,
571 0, 1, 1, 1, 1, 1, 1, 0,
572 1, 1, 1, 1, 0, 0, 0, 0,
573 0, 0, 0, 0, 0, 0, 0, 0,
574 0, 0, 1, 0, 1, 0, 1, 1,
575 1, 1, 1, 1, 1, 1, 1, 1,
576 1, 1, 1, 1, 1, 1, 1, 1,
577 1, 1, 1, 1, 1, 1, 1, 1,
578 1, 1, 1, 0, 0, 0, 1, 1,
579 0, 0, 0, 0, 0, 0, 0, 0,
580 0, 0, 0, 0, 0, 0, 0, 0,
581 0, 0, 0, 0, 0, 0, 0, 0,
582 0, 0, 0, 1, 1, 1, 1, 0
585 __attribute__ ((weak))
586 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
587 0, 0, 0, 0, 0, 0, 0, 0,
588 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
589 0, 0, 0, 0, 0, 0, 0, 0,
590 0, 0, 0, KC_ESC, 0, 0, 0, 0,
591 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
592 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
593 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
594 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
595 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
596 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
597 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
598 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
599 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
600 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
601 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
602 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
605 void send_string(const char *str) {
606 send_string_with_delay(str, 0);
609 void send_string_P(const char *str) {
610 send_string_with_delay_P(str, 0);
613 void send_string_with_delay(const char *str, uint8_t interval) {
615 char ascii_code = *str;
616 if (!ascii_code) break;
617 if (ascii_code == 1) {
619 uint8_t keycode = *(++str);
620 register_code(keycode);
621 unregister_code(keycode);
622 } else if (ascii_code == 2) {
624 uint8_t keycode = *(++str);
625 register_code(keycode);
626 } else if (ascii_code == 3) {
628 uint8_t keycode = *(++str);
629 unregister_code(keycode);
631 send_char(ascii_code);
635 { uint8_t ms = interval; while (ms--) wait_ms(1); }
639 void send_string_with_delay_P(const char *str, uint8_t interval) {
641 char ascii_code = pgm_read_byte(str);
642 if (!ascii_code) break;
643 if (ascii_code == 1) {
645 uint8_t keycode = pgm_read_byte(++str);
646 register_code(keycode);
647 unregister_code(keycode);
648 } else if (ascii_code == 2) {
650 uint8_t keycode = pgm_read_byte(++str);
651 register_code(keycode);
652 } else if (ascii_code == 3) {
654 uint8_t keycode = pgm_read_byte(++str);
655 unregister_code(keycode);
657 send_char(ascii_code);
661 { uint8_t ms = interval; while (ms--) wait_ms(1); }
665 void send_char(char ascii_code) {
667 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
668 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
669 register_code(KC_LSFT);
670 register_code(keycode);
671 unregister_code(keycode);
672 unregister_code(KC_LSFT);
674 register_code(keycode);
675 unregister_code(keycode);
679 void set_single_persistent_default_layer(uint8_t default_layer) {
680 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
681 PLAY_SONG(default_layer_songs[default_layer]);
683 eeconfig_update_default_layer(1U<<default_layer);
684 default_layer_set(1U<<default_layer);
687 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
688 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
695 void tap_random_base64(void) {
696 #if defined(__AVR_ATmega32U4__)
697 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
699 uint8_t key = rand() % 64;
703 register_code(KC_LSFT);
704 register_code(key + KC_A);
705 unregister_code(key + KC_A);
706 unregister_code(KC_LSFT);
709 register_code(key - 26 + KC_A);
710 unregister_code(key - 26 + KC_A);
714 unregister_code(KC_0);
717 register_code(key - 53 + KC_1);
718 unregister_code(key - 53 + KC_1);
721 register_code(KC_LSFT);
722 register_code(KC_EQL);
723 unregister_code(KC_EQL);
724 unregister_code(KC_LSFT);
727 register_code(KC_SLSH);
728 unregister_code(KC_SLSH);
733 void matrix_init_quantum() {
734 #ifdef BACKLIGHT_ENABLE
735 backlight_init_ports();
743 void matrix_scan_quantum() {
748 #ifdef TAP_DANCE_ENABLE
749 matrix_scan_tap_dance();
756 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
763 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
765 static const uint8_t backlight_pin = BACKLIGHT_PIN;
767 #if BACKLIGHT_PIN == B7
768 # define COM1x1 COM1C1
770 #elif BACKLIGHT_PIN == B6
771 # define COM1x1 COM1B1
773 #elif BACKLIGHT_PIN == B5
774 # define COM1x1 COM1A1
777 # define NO_BACKLIGHT_CLOCK
780 #ifndef BACKLIGHT_ON_STATE
781 #define BACKLIGHT_ON_STATE 0
784 __attribute__ ((weak))
785 void backlight_init_ports(void)
788 // Setup backlight pin as output and output to on state.
790 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
791 #if BACKLIGHT_ON_STATE == 0
793 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
796 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
799 #ifndef NO_BACKLIGHT_CLOCK
800 // Use full 16-bit resolution.
803 // I could write a wall of text here to explain... but TL;DW
804 // Go read the ATmega32u4 datasheet.
805 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
807 // Pin PB7 = OCR1C (Timer 1, Channel C)
808 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
809 // (i.e. start high, go low when counter matches.)
810 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
811 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
813 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
814 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
818 #ifdef BACKLIGHT_BREATHING
819 breathing_defaults();
823 __attribute__ ((weak))
824 void backlight_set(uint8_t level)
826 // Prevent backlight blink on lowest level
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);
836 #ifndef NO_BACKLIGHT_CLOCK
837 // Turn off PWM control on backlight pin, revert to output low.
838 TCCR1A &= ~(_BV(COM1x1));
841 // #if BACKLIGHT_ON_STATE == 0
843 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
846 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
850 #ifndef NO_BACKLIGHT_CLOCK
851 else if ( level == BACKLIGHT_LEVELS ) {
852 // Turn on PWM control of backlight pin
853 TCCR1A |= _BV(COM1x1);
854 // Set the brightness
858 // Turn on PWM control of backlight pin
859 TCCR1A |= _BV(COM1x1);
860 // Set the brightness
861 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
865 #ifdef BACKLIGHT_BREATHING
866 breathing_intensity_default();
870 uint8_t backlight_tick = 0;
872 void backlight_task(void) {
873 #ifdef NO_BACKLIGHT_CLOCK
874 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
875 #if BACKLIGHT_ON_STATE == 0
877 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
880 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
883 #if BACKLIGHT_ON_STATE == 0
885 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
888 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
891 backlight_tick = (backlight_tick + 1) % 16;
895 #ifdef BACKLIGHT_BREATHING
897 #define BREATHING_NO_HALT 0
898 #define BREATHING_HALT_OFF 1
899 #define BREATHING_HALT_ON 2
901 static uint8_t breath_intensity;
902 static uint8_t breath_speed;
903 static uint16_t breathing_index;
904 static uint8_t breathing_halt;
906 void breathing_enable(void)
908 if (get_backlight_level() == 0)
914 // Set breathing_index to be at the midpoint (brightest point)
915 breathing_index = 0x20 << breath_speed;
918 breathing_halt = BREATHING_NO_HALT;
920 // Enable breathing interrupt
921 TIMSK1 |= _BV(OCIE1A);
924 void breathing_pulse(void)
926 if (get_backlight_level() == 0)
932 // Set breathing_index to be at the midpoint + 1 (brightest point)
933 breathing_index = 0x21 << breath_speed;
936 breathing_halt = BREATHING_HALT_ON;
938 // Enable breathing interrupt
939 TIMSK1 |= _BV(OCIE1A);
942 void breathing_disable(void)
944 // Disable breathing interrupt
945 TIMSK1 &= ~_BV(OCIE1A);
946 backlight_set(get_backlight_level());
949 void breathing_self_disable(void)
951 if (get_backlight_level() == 0)
953 breathing_halt = BREATHING_HALT_OFF;
957 breathing_halt = BREATHING_HALT_ON;
960 //backlight_set(get_backlight_level());
963 void breathing_toggle(void)
967 if (get_backlight_level() == 0)
973 // Set breathing_index to be at the midpoint + 1 (brightest point)
974 breathing_index = 0x21 << breath_speed;
977 breathing_halt = BREATHING_NO_HALT;
980 // Toggle breathing interrupt
981 TIMSK1 ^= _BV(OCIE1A);
983 // Restore backlight level
986 backlight_set(get_backlight_level());
990 bool is_breathing(void)
992 return (TIMSK1 && _BV(OCIE1A));
995 void breathing_intensity_default(void)
997 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
998 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
1001 void breathing_intensity_set(uint8_t value)
1003 breath_intensity = value;
1006 void breathing_speed_default(void)
1011 void breathing_speed_set(uint8_t value)
1013 bool is_breathing_now = is_breathing();
1014 uint8_t old_breath_speed = breath_speed;
1016 if (is_breathing_now)
1018 // Disable breathing interrupt
1019 TIMSK1 &= ~_BV(OCIE1A);
1022 breath_speed = value;
1024 if (is_breathing_now)
1026 // Adjust index to account for new speed
1027 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
1029 // Enable breathing interrupt
1030 TIMSK1 |= _BV(OCIE1A);
1035 void breathing_speed_inc(uint8_t value)
1037 if ((uint16_t)(breath_speed - value) > 10 )
1039 breathing_speed_set(0);
1043 breathing_speed_set(breath_speed - value);
1047 void breathing_speed_dec(uint8_t value)
1049 if ((uint16_t)(breath_speed + value) > 10 )
1051 breathing_speed_set(10);
1055 breathing_speed_set(breath_speed + value);
1059 void breathing_defaults(void)
1061 breathing_intensity_default();
1062 breathing_speed_default();
1063 breathing_halt = BREATHING_NO_HALT;
1066 /* Breathing Sleep LED brighness(PWM On period) table
1067 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
1069 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
1070 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
1072 static const uint8_t breathing_table[64] PROGMEM = {
1073 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
1074 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
1075 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
1076 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1079 ISR(TIMER1_COMPA_vect)
1081 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
1084 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
1086 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
1088 // Disable breathing interrupt
1089 TIMSK1 &= ~_BV(OCIE1A);
1092 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
1102 __attribute__ ((weak))
1103 void backlight_init_ports(void)
1108 __attribute__ ((weak))
1109 void backlight_set(uint8_t level)
1117 // Functions for spitting out values
1120 void send_dword(uint32_t number) { // this might not actually work
1121 uint16_t word = (number >> 16);
1123 send_word(number & 0xFFFFUL);
1126 void send_word(uint16_t number) {
1127 uint8_t byte = number >> 8;
1129 send_byte(number & 0xFF);
1132 void send_byte(uint8_t number) {
1133 uint8_t nibble = number >> 4;
1134 send_nibble(nibble);
1135 send_nibble(number & 0xF);
1138 void send_nibble(uint8_t number) {
1141 register_code(KC_0);
1142 unregister_code(KC_0);
1145 register_code(KC_1 + (number - 1));
1146 unregister_code(KC_1 + (number - 1));
1149 register_code(KC_A + (number - 0xA));
1150 unregister_code(KC_A + (number - 0xA));
1156 __attribute__((weak))
1157 uint16_t hex_to_keycode(uint8_t hex)
1161 } else if (hex < 0xA) {
1162 return KC_1 + (hex - 0x1);
1164 return KC_A + (hex - 0xA);
1168 void api_send_unicode(uint32_t unicode) {
1171 dword_to_bytes(unicode, chunk);
1172 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1176 __attribute__ ((weak))
1177 void led_set_user(uint8_t usb_led) {
1181 __attribute__ ((weak))
1182 void led_set_kb(uint8_t usb_led) {
1183 led_set_user(usb_led);
1186 __attribute__ ((weak))
1187 void led_init_ports(void)
1192 __attribute__ ((weak))
1193 void led_set(uint8_t usb_led)
1198 // // Using PE6 Caps Lock LED
1199 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1209 // PORTE &= ~(1<<6);
1212 led_set_kb(usb_led);
1216 //------------------------------------------------------------------------------
1217 // Override these functions in your keymap file to play different tunes on
1218 // different events such as startup and bootloader jump
1220 __attribute__ ((weak))
1221 void startup_user() {}
1223 __attribute__ ((weak))
1224 void shutdown_user() {}
1226 //------------------------------------------------------------------------------