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) &&
245 // Shift / paren setup
249 if (record->event.pressed) {
254 if (record->event.pressed) {
256 print("DEBUG: enabled.\n");
259 #ifdef FAUXCLICKY_ENABLE
261 if (record->event.pressed) {
266 if (record->event.pressed) {
271 if (record->event.pressed) {
276 #ifdef RGBLIGHT_ENABLE
278 if (record->event.pressed) {
283 if (record->event.pressed) {
288 if (record->event.pressed) {
289 rgblight_increase_hue();
293 if (record->event.pressed) {
294 rgblight_decrease_hue();
298 if (record->event.pressed) {
299 rgblight_increase_sat();
303 if (record->event.pressed) {
304 rgblight_decrease_sat();
308 if (record->event.pressed) {
309 rgblight_increase_val();
313 if (record->event.pressed) {
314 rgblight_decrease_val();
318 if (record->event.pressed) {
322 case RGB_MODE_BREATHE:
323 if (record->event.pressed) {
324 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
331 case RGB_MODE_RAINBOW:
332 if (record->event.pressed) {
333 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
341 if (record->event.pressed) {
342 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
350 if (record->event.pressed) {
351 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
358 case RGB_MODE_KNIGHT:
359 if (record->event.pressed) {
360 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
368 if (record->event.pressed) {
372 case RGB_MODE_GRADIENT:
373 if (record->event.pressed) {
374 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
384 if (record->event.pressed) {
385 set_output(OUTPUT_AUTO);
389 if (record->event.pressed) {
390 set_output(OUTPUT_USB);
393 #ifdef BLUETOOTH_ENABLE
395 if (record->event.pressed) {
396 set_output(OUTPUT_BLUETOOTH);
401 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
402 if (record->event.pressed) {
403 // MAGIC actions (BOOTMAGIC without the boot)
404 if (!eeconfig_is_enabled()) {
408 keymap_config.raw = eeconfig_read_keymap();
411 case MAGIC_SWAP_CONTROL_CAPSLOCK:
412 keymap_config.swap_control_capslock = true;
414 case MAGIC_CAPSLOCK_TO_CONTROL:
415 keymap_config.capslock_to_control = true;
417 case MAGIC_SWAP_LALT_LGUI:
418 keymap_config.swap_lalt_lgui = true;
420 case MAGIC_SWAP_RALT_RGUI:
421 keymap_config.swap_ralt_rgui = true;
424 keymap_config.no_gui = true;
426 case MAGIC_SWAP_GRAVE_ESC:
427 keymap_config.swap_grave_esc = true;
429 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
430 keymap_config.swap_backslash_backspace = true;
432 case MAGIC_HOST_NKRO:
433 keymap_config.nkro = true;
435 case MAGIC_SWAP_ALT_GUI:
436 keymap_config.swap_lalt_lgui = true;
437 keymap_config.swap_ralt_rgui = true;
439 PLAY_SONG(ag_swap_song);
442 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
443 keymap_config.swap_control_capslock = false;
445 case MAGIC_UNCAPSLOCK_TO_CONTROL:
446 keymap_config.capslock_to_control = false;
448 case MAGIC_UNSWAP_LALT_LGUI:
449 keymap_config.swap_lalt_lgui = false;
451 case MAGIC_UNSWAP_RALT_RGUI:
452 keymap_config.swap_ralt_rgui = false;
455 keymap_config.no_gui = false;
457 case MAGIC_UNSWAP_GRAVE_ESC:
458 keymap_config.swap_grave_esc = false;
460 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
461 keymap_config.swap_backslash_backspace = false;
463 case MAGIC_UNHOST_NKRO:
464 keymap_config.nkro = false;
466 case MAGIC_UNSWAP_ALT_GUI:
467 keymap_config.swap_lalt_lgui = false;
468 keymap_config.swap_ralt_rgui = false;
470 PLAY_SONG(ag_norm_song);
473 case MAGIC_TOGGLE_NKRO:
474 keymap_config.nkro = !keymap_config.nkro;
479 eeconfig_update_keymap(keymap_config.raw);
480 clear_keyboard(); // clear to prevent stuck keys
486 if (record->event.pressed) {
487 shift_interrupted[0] = false;
488 scs_timer[0] = timer_read ();
489 register_mods(MOD_BIT(KC_LSFT));
492 #ifdef DISABLE_SPACE_CADET_ROLLOVER
493 if (get_mods() & MOD_BIT(KC_RSFT)) {
494 shift_interrupted[0] = true;
495 shift_interrupted[1] = true;
498 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
499 register_code(LSPO_KEY);
500 unregister_code(LSPO_KEY);
502 unregister_mods(MOD_BIT(KC_LSFT));
508 if (record->event.pressed) {
509 shift_interrupted[1] = false;
510 scs_timer[1] = timer_read ();
511 register_mods(MOD_BIT(KC_RSFT));
514 #ifdef DISABLE_SPACE_CADET_ROLLOVER
515 if (get_mods() & MOD_BIT(KC_LSFT)) {
516 shift_interrupted[0] = true;
517 shift_interrupted[1] = true;
520 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
521 register_code(RSPC_KEY);
522 unregister_code(RSPC_KEY);
524 unregister_mods(MOD_BIT(KC_RSFT));
529 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
530 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
532 #ifdef GRAVE_ESC_CTRL_OVERRIDE
533 // if CTRL is pressed, ESC is always read as ESC, even if SHIFT or GUI is pressed.
534 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
535 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL)))
539 if (record->event.pressed) {
540 grave_esc_was_shifted = shifted;
541 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
544 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
547 send_keyboard_report();
550 shift_interrupted[0] = true;
551 shift_interrupted[1] = true;
556 return process_action_kb(record);
559 __attribute__ ((weak))
560 const bool ascii_to_shift_lut[0x80] PROGMEM = {
561 0, 0, 0, 0, 0, 0, 0, 0,
562 0, 0, 0, 0, 0, 0, 0, 0,
563 0, 0, 0, 0, 0, 0, 0, 0,
564 0, 0, 0, 0, 0, 0, 0, 0,
565 0, 1, 1, 1, 1, 1, 1, 0,
566 1, 1, 1, 1, 0, 0, 0, 0,
567 0, 0, 0, 0, 0, 0, 0, 0,
568 0, 0, 1, 0, 1, 0, 1, 1,
569 1, 1, 1, 1, 1, 1, 1, 1,
570 1, 1, 1, 1, 1, 1, 1, 1,
571 1, 1, 1, 1, 1, 1, 1, 1,
572 1, 1, 1, 0, 0, 0, 1, 1,
573 0, 0, 0, 0, 0, 0, 0, 0,
574 0, 0, 0, 0, 0, 0, 0, 0,
575 0, 0, 0, 0, 0, 0, 0, 0,
576 0, 0, 0, 1, 1, 1, 1, 0
579 __attribute__ ((weak))
580 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
581 0, 0, 0, 0, 0, 0, 0, 0,
582 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
583 0, 0, 0, 0, 0, 0, 0, 0,
584 0, 0, 0, KC_ESC, 0, 0, 0, 0,
585 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
586 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
587 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
588 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
589 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
590 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
591 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
592 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
593 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
594 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
595 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
596 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
599 void send_string(const char *str) {
600 send_string_with_delay(str, 0);
603 void send_string_with_delay(const char *str, uint8_t interval) {
606 uint8_t ascii_code = pgm_read_byte(str);
607 if (!ascii_code) break;
608 keycode = pgm_read_byte(&ascii_to_keycode_lut[ascii_code]);
609 if (pgm_read_byte(&ascii_to_shift_lut[ascii_code])) {
610 register_code(KC_LSFT);
611 register_code(keycode);
612 unregister_code(keycode);
613 unregister_code(KC_LSFT);
616 register_code(keycode);
617 unregister_code(keycode);
621 { uint8_t ms = interval; while (ms--) wait_ms(1); }
625 void set_single_persistent_default_layer(uint8_t default_layer) {
626 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
627 PLAY_SONG(default_layer_songs[default_layer]);
629 eeconfig_update_default_layer(1U<<default_layer);
630 default_layer_set(1U<<default_layer);
633 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
634 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
641 void tap_random_base64(void) {
642 #if defined(__AVR_ATmega32U4__)
643 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
645 uint8_t key = rand() % 64;
649 register_code(KC_LSFT);
650 register_code(key + KC_A);
651 unregister_code(key + KC_A);
652 unregister_code(KC_LSFT);
655 register_code(key - 26 + KC_A);
656 unregister_code(key - 26 + KC_A);
660 unregister_code(KC_0);
663 register_code(key - 53 + KC_1);
664 unregister_code(key - 53 + KC_1);
667 register_code(KC_LSFT);
668 register_code(KC_EQL);
669 unregister_code(KC_EQL);
670 unregister_code(KC_LSFT);
673 register_code(KC_SLSH);
674 unregister_code(KC_SLSH);
679 void matrix_init_quantum() {
680 #ifdef BACKLIGHT_ENABLE
681 backlight_init_ports();
689 void matrix_scan_quantum() {
694 #ifdef TAP_DANCE_ENABLE
695 matrix_scan_tap_dance();
702 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
709 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
711 static const uint8_t backlight_pin = BACKLIGHT_PIN;
713 #if BACKLIGHT_PIN == B7
714 # define COM1x1 COM1C1
716 #elif BACKLIGHT_PIN == B6
717 # define COM1x1 COM1B1
719 #elif BACKLIGHT_PIN == B5
720 # define COM1x1 COM1A1
723 # define NO_BACKLIGHT_CLOCK
726 #ifndef BACKLIGHT_ON_STATE
727 #define BACKLIGHT_ON_STATE 0
730 __attribute__ ((weak))
731 void backlight_init_ports(void)
734 // Setup backlight pin as output and output to on state.
736 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
737 #if BACKLIGHT_ON_STATE == 0
739 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
742 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
745 #ifndef NO_BACKLIGHT_CLOCK
746 // Use full 16-bit resolution.
749 // I could write a wall of text here to explain... but TL;DW
750 // Go read the ATmega32u4 datasheet.
751 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
753 // Pin PB7 = OCR1C (Timer 1, Channel C)
754 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
755 // (i.e. start high, go low when counter matches.)
756 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
757 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
759 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
760 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
764 #ifdef BACKLIGHT_BREATHING
765 breathing_defaults();
769 __attribute__ ((weak))
770 void backlight_set(uint8_t level)
772 // Prevent backlight blink on lowest level
773 // #if BACKLIGHT_ON_STATE == 0
775 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
778 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
782 #ifndef NO_BACKLIGHT_CLOCK
783 // Turn off PWM control on backlight pin, revert to output low.
784 TCCR1A &= ~(_BV(COM1x1));
787 // #if BACKLIGHT_ON_STATE == 0
789 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
792 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
796 #ifndef NO_BACKLIGHT_CLOCK
797 else if ( level == BACKLIGHT_LEVELS ) {
798 // Turn on PWM control of backlight pin
799 TCCR1A |= _BV(COM1x1);
800 // Set the brightness
804 // Turn on PWM control of backlight pin
805 TCCR1A |= _BV(COM1x1);
806 // Set the brightness
807 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
811 #ifdef BACKLIGHT_BREATHING
812 breathing_intensity_default();
816 uint8_t backlight_tick = 0;
818 void backlight_task(void) {
819 #ifdef NO_BACKLIGHT_CLOCK
820 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
821 #if BACKLIGHT_ON_STATE == 0
823 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
826 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
829 #if BACKLIGHT_ON_STATE == 0
831 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
834 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
837 backlight_tick = (backlight_tick + 1) % 16;
841 #ifdef BACKLIGHT_BREATHING
843 #define BREATHING_NO_HALT 0
844 #define BREATHING_HALT_OFF 1
845 #define BREATHING_HALT_ON 2
847 static uint8_t breath_intensity;
848 static uint8_t breath_speed;
849 static uint16_t breathing_index;
850 static uint8_t breathing_halt;
852 void breathing_enable(void)
854 if (get_backlight_level() == 0)
860 // Set breathing_index to be at the midpoint (brightest point)
861 breathing_index = 0x20 << breath_speed;
864 breathing_halt = BREATHING_NO_HALT;
866 // Enable breathing interrupt
867 TIMSK1 |= _BV(OCIE1A);
870 void breathing_pulse(void)
872 if (get_backlight_level() == 0)
878 // Set breathing_index to be at the midpoint + 1 (brightest point)
879 breathing_index = 0x21 << breath_speed;
882 breathing_halt = BREATHING_HALT_ON;
884 // Enable breathing interrupt
885 TIMSK1 |= _BV(OCIE1A);
888 void breathing_disable(void)
890 // Disable breathing interrupt
891 TIMSK1 &= ~_BV(OCIE1A);
892 backlight_set(get_backlight_level());
895 void breathing_self_disable(void)
897 if (get_backlight_level() == 0)
899 breathing_halt = BREATHING_HALT_OFF;
903 breathing_halt = BREATHING_HALT_ON;
906 //backlight_set(get_backlight_level());
909 void breathing_toggle(void)
913 if (get_backlight_level() == 0)
919 // Set breathing_index to be at the midpoint + 1 (brightest point)
920 breathing_index = 0x21 << breath_speed;
923 breathing_halt = BREATHING_NO_HALT;
926 // Toggle breathing interrupt
927 TIMSK1 ^= _BV(OCIE1A);
929 // Restore backlight level
932 backlight_set(get_backlight_level());
936 bool is_breathing(void)
938 return (TIMSK1 && _BV(OCIE1A));
941 void breathing_intensity_default(void)
943 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
944 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
947 void breathing_intensity_set(uint8_t value)
949 breath_intensity = value;
952 void breathing_speed_default(void)
957 void breathing_speed_set(uint8_t value)
959 bool is_breathing_now = is_breathing();
960 uint8_t old_breath_speed = breath_speed;
962 if (is_breathing_now)
964 // Disable breathing interrupt
965 TIMSK1 &= ~_BV(OCIE1A);
968 breath_speed = value;
970 if (is_breathing_now)
972 // Adjust index to account for new speed
973 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
975 // Enable breathing interrupt
976 TIMSK1 |= _BV(OCIE1A);
981 void breathing_speed_inc(uint8_t value)
983 if ((uint16_t)(breath_speed - value) > 10 )
985 breathing_speed_set(0);
989 breathing_speed_set(breath_speed - value);
993 void breathing_speed_dec(uint8_t value)
995 if ((uint16_t)(breath_speed + value) > 10 )
997 breathing_speed_set(10);
1001 breathing_speed_set(breath_speed + value);
1005 void breathing_defaults(void)
1007 breathing_intensity_default();
1008 breathing_speed_default();
1009 breathing_halt = BREATHING_NO_HALT;
1012 /* Breathing Sleep LED brighness(PWM On period) table
1013 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
1015 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
1016 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
1018 static const uint8_t breathing_table[64] PROGMEM = {
1019 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
1020 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
1021 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
1022 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1025 ISR(TIMER1_COMPA_vect)
1027 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
1030 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
1032 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
1034 // Disable breathing interrupt
1035 TIMSK1 &= ~_BV(OCIE1A);
1038 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
1048 __attribute__ ((weak))
1049 void backlight_init_ports(void)
1054 __attribute__ ((weak))
1055 void backlight_set(uint8_t level)
1063 // Functions for spitting out values
1066 void send_dword(uint32_t number) { // this might not actually work
1067 uint16_t word = (number >> 16);
1069 send_word(number & 0xFFFFUL);
1072 void send_word(uint16_t number) {
1073 uint8_t byte = number >> 8;
1075 send_byte(number & 0xFF);
1078 void send_byte(uint8_t number) {
1079 uint8_t nibble = number >> 4;
1080 send_nibble(nibble);
1081 send_nibble(number & 0xF);
1084 void send_nibble(uint8_t number) {
1087 register_code(KC_0);
1088 unregister_code(KC_0);
1091 register_code(KC_1 + (number - 1));
1092 unregister_code(KC_1 + (number - 1));
1095 register_code(KC_A + (number - 0xA));
1096 unregister_code(KC_A + (number - 0xA));
1102 __attribute__((weak))
1103 uint16_t hex_to_keycode(uint8_t hex)
1107 } else if (hex < 0xA) {
1108 return KC_1 + (hex - 0x1);
1110 return KC_A + (hex - 0xA);
1114 void api_send_unicode(uint32_t unicode) {
1117 dword_to_bytes(unicode, chunk);
1118 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1122 __attribute__ ((weak))
1123 void led_set_user(uint8_t usb_led) {
1127 __attribute__ ((weak))
1128 void led_set_kb(uint8_t usb_led) {
1129 led_set_user(usb_led);
1132 __attribute__ ((weak))
1133 void led_init_ports(void)
1138 __attribute__ ((weak))
1139 void led_set(uint8_t usb_led)
1144 // // Using PE6 Caps Lock LED
1145 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1155 // PORTE &= ~(1<<6);
1158 led_set_kb(usb_led);
1162 //------------------------------------------------------------------------------
1163 // Override these functions in your keymap file to play different tunes on
1164 // different events such as startup and bootloader jump
1166 __attribute__ ((weak))
1167 void startup_user() {}
1169 __attribute__ ((weak))
1170 void shutdown_user() {}
1172 //------------------------------------------------------------------------------