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 #ifndef BREATHING_PERIOD
27 #define BREATHING_PERIOD 6
30 #include "backlight.h"
31 extern backlight_config_t backlight_config;
33 #ifdef FAUXCLICKY_ENABLE
34 #include "fauxclicky.h"
39 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
42 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
45 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
47 float goodbye_song[][2] = GOODBYE_SONG;
48 float ag_norm_song[][2] = AG_NORM_SONG;
49 float ag_swap_song[][2] = AG_SWAP_SONG;
50 #ifdef DEFAULT_LAYER_SONGS
51 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
55 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
57 case QK_MODS ... QK_MODS_MAX:
72 if (code < QK_RMODS_MIN) return;
84 static inline void qk_register_weak_mods(uint8_t kc) {
85 add_weak_mods(MOD_BIT(kc));
86 send_keyboard_report();
89 static inline void qk_unregister_weak_mods(uint8_t kc) {
90 del_weak_mods(MOD_BIT(kc));
91 send_keyboard_report();
94 static inline void qk_register_mods(uint8_t kc) {
95 add_weak_mods(MOD_BIT(kc));
96 send_keyboard_report();
99 static inline void qk_unregister_mods(uint8_t kc) {
100 del_weak_mods(MOD_BIT(kc));
101 send_keyboard_report();
104 void register_code16 (uint16_t code) {
105 if (IS_MOD(code) || code == KC_NO) {
106 do_code16 (code, qk_register_mods);
108 do_code16 (code, qk_register_weak_mods);
110 register_code (code);
113 void unregister_code16 (uint16_t code) {
114 unregister_code (code);
115 if (IS_MOD(code) || code == KC_NO) {
116 do_code16 (code, qk_unregister_mods);
118 do_code16 (code, qk_unregister_weak_mods);
122 __attribute__ ((weak))
123 bool process_action_kb(keyrecord_t *record) {
127 __attribute__ ((weak))
128 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
129 return process_record_user(keycode, record);
132 __attribute__ ((weak))
133 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
137 void reset_keyboard(void) {
139 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
140 process_midi_all_notes_off();
142 #if defined(AUDIO_ENABLE)
143 music_all_notes_off();
144 uint16_t timer_start = timer_read();
145 PLAY_SONG(goodbye_song);
147 while(timer_elapsed(timer_start) < 250)
153 // this is also done later in bootloader.c - not sure if it's neccesary here
154 #ifdef BOOTLOADER_CATERINA
155 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
160 // Shift / paren setup
163 #define LSPO_KEY KC_9
166 #define RSPC_KEY KC_0
169 // Shift / Enter setup
171 #define SFTENT_KEY KC_ENT
174 static bool shift_interrupted[2] = {0, 0};
175 static uint16_t scs_timer[2] = {0, 0};
177 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
178 * Used to ensure that the correct keycode is released if the key is released.
180 static bool grave_esc_was_shifted = false;
182 bool process_record_quantum(keyrecord_t *record) {
184 /* This gets the keycode from the key pressed */
185 keypos_t key = record->event.key;
188 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
189 /* TODO: Use store_or_get_action() or a similar function. */
190 if (!disable_action_cache) {
193 if (record->event.pressed) {
194 layer = layer_switch_get_layer(key);
195 update_source_layers_cache(key, layer);
197 layer = read_source_layers_cache(key);
199 keycode = keymap_key_to_keycode(layer, key);
202 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
204 // This is how you use actions here
205 // if (keycode == KC_LEAD) {
207 // action.code = ACTION_DEFAULT_LAYER_SET(0);
208 // process_action(record, action);
212 #ifdef TAP_DANCE_ENABLE
213 preprocess_tap_dance(keycode, record);
217 #if defined(KEY_LOCK_ENABLE)
218 // Must run first to be able to mask key_up events.
219 process_key_lock(&keycode, record) &&
221 process_record_kb(keycode, record) &&
222 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
223 process_midi(keycode, record) &&
226 process_audio(keycode, record) &&
229 process_steno(keycode, record) &&
231 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
232 process_music(keycode, record) &&
234 #ifdef TAP_DANCE_ENABLE
235 process_tap_dance(keycode, record) &&
237 #ifndef DISABLE_LEADER
238 process_leader(keycode, record) &&
240 #ifndef DISABLE_CHORDING
241 process_chording(keycode, record) &&
244 process_combo(keycode, record) &&
246 #ifdef UNICODE_ENABLE
247 process_unicode(keycode, record) &&
250 process_ucis(keycode, record) &&
252 #ifdef PRINTING_ENABLE
253 process_printer(keycode, record) &&
255 #ifdef AUTO_SHIFT_ENABLE
256 process_auto_shift(keycode, record) &&
258 #ifdef UNICODEMAP_ENABLE
259 process_unicode_map(keycode, record) &&
261 #ifdef TERMINAL_ENABLE
262 process_terminal(keycode, record) &&
268 // Shift / paren setup
272 if (record->event.pressed) {
277 if (record->event.pressed) {
279 print("DEBUG: enabled.\n");
282 #ifdef FAUXCLICKY_ENABLE
284 if (record->event.pressed) {
289 if (record->event.pressed) {
294 if (record->event.pressed) {
299 #ifdef RGBLIGHT_ENABLE
301 if (record->event.pressed) {
305 case RGB_MODE_FORWARD:
306 if (record->event.pressed) {
307 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
309 rgblight_step_reverse();
316 case RGB_MODE_REVERSE:
317 if (record->event.pressed) {
318 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
323 rgblight_step_reverse();
328 if (record->event.pressed) {
329 rgblight_increase_hue();
333 if (record->event.pressed) {
334 rgblight_decrease_hue();
338 if (record->event.pressed) {
339 rgblight_increase_sat();
343 if (record->event.pressed) {
344 rgblight_decrease_sat();
348 if (record->event.pressed) {
349 rgblight_increase_val();
353 if (record->event.pressed) {
354 rgblight_decrease_val();
358 if (record->event.pressed) {
362 case RGB_MODE_BREATHE:
363 if (record->event.pressed) {
364 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
371 case RGB_MODE_RAINBOW:
372 if (record->event.pressed) {
373 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
381 if (record->event.pressed) {
382 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
390 if (record->event.pressed) {
391 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
398 case RGB_MODE_KNIGHT:
399 if (record->event.pressed) {
400 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
408 if (record->event.pressed) {
412 case RGB_MODE_GRADIENT:
413 if (record->event.pressed) {
414 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
424 if (record->event.pressed) {
425 set_output(OUTPUT_AUTO);
429 if (record->event.pressed) {
430 set_output(OUTPUT_USB);
433 #ifdef BLUETOOTH_ENABLE
435 if (record->event.pressed) {
436 set_output(OUTPUT_BLUETOOTH);
441 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
442 if (record->event.pressed) {
443 // MAGIC actions (BOOTMAGIC without the boot)
444 if (!eeconfig_is_enabled()) {
448 keymap_config.raw = eeconfig_read_keymap();
451 case MAGIC_SWAP_CONTROL_CAPSLOCK:
452 keymap_config.swap_control_capslock = true;
454 case MAGIC_CAPSLOCK_TO_CONTROL:
455 keymap_config.capslock_to_control = true;
457 case MAGIC_SWAP_LALT_LGUI:
458 keymap_config.swap_lalt_lgui = true;
460 case MAGIC_SWAP_RALT_RGUI:
461 keymap_config.swap_ralt_rgui = true;
464 keymap_config.no_gui = true;
466 case MAGIC_SWAP_GRAVE_ESC:
467 keymap_config.swap_grave_esc = true;
469 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
470 keymap_config.swap_backslash_backspace = true;
472 case MAGIC_HOST_NKRO:
473 keymap_config.nkro = true;
475 case MAGIC_SWAP_ALT_GUI:
476 keymap_config.swap_lalt_lgui = true;
477 keymap_config.swap_ralt_rgui = true;
479 PLAY_SONG(ag_swap_song);
482 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
483 keymap_config.swap_control_capslock = false;
485 case MAGIC_UNCAPSLOCK_TO_CONTROL:
486 keymap_config.capslock_to_control = false;
488 case MAGIC_UNSWAP_LALT_LGUI:
489 keymap_config.swap_lalt_lgui = false;
491 case MAGIC_UNSWAP_RALT_RGUI:
492 keymap_config.swap_ralt_rgui = false;
495 keymap_config.no_gui = false;
497 case MAGIC_UNSWAP_GRAVE_ESC:
498 keymap_config.swap_grave_esc = false;
500 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
501 keymap_config.swap_backslash_backspace = false;
503 case MAGIC_UNHOST_NKRO:
504 keymap_config.nkro = false;
506 case MAGIC_UNSWAP_ALT_GUI:
507 keymap_config.swap_lalt_lgui = false;
508 keymap_config.swap_ralt_rgui = false;
510 PLAY_SONG(ag_norm_song);
513 case MAGIC_TOGGLE_NKRO:
514 keymap_config.nkro = !keymap_config.nkro;
519 eeconfig_update_keymap(keymap_config.raw);
520 clear_keyboard(); // clear to prevent stuck keys
526 if (record->event.pressed) {
527 shift_interrupted[0] = false;
528 scs_timer[0] = timer_read ();
529 register_mods(MOD_BIT(KC_LSFT));
532 #ifdef DISABLE_SPACE_CADET_ROLLOVER
533 if (get_mods() & MOD_BIT(KC_RSFT)) {
534 shift_interrupted[0] = true;
535 shift_interrupted[1] = true;
538 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
539 register_code(LSPO_KEY);
540 unregister_code(LSPO_KEY);
542 unregister_mods(MOD_BIT(KC_LSFT));
548 if (record->event.pressed) {
549 shift_interrupted[1] = false;
550 scs_timer[1] = timer_read ();
551 register_mods(MOD_BIT(KC_RSFT));
554 #ifdef DISABLE_SPACE_CADET_ROLLOVER
555 if (get_mods() & MOD_BIT(KC_LSFT)) {
556 shift_interrupted[0] = true;
557 shift_interrupted[1] = true;
560 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
561 register_code(RSPC_KEY);
562 unregister_code(RSPC_KEY);
564 unregister_mods(MOD_BIT(KC_RSFT));
570 if (record->event.pressed) {
571 shift_interrupted[1] = false;
572 scs_timer[1] = timer_read ();
573 register_mods(MOD_BIT(KC_RSFT));
575 else if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
576 unregister_mods(MOD_BIT(KC_RSFT));
577 register_code(SFTENT_KEY);
578 unregister_code(SFTENT_KEY);
581 unregister_mods(MOD_BIT(KC_RSFT));
587 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
588 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
590 #ifdef GRAVE_ESC_ALT_OVERRIDE
591 // if ALT is pressed, ESC is always sent
592 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
593 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
598 #ifdef GRAVE_ESC_CTRL_OVERRIDE
599 // if CTRL is pressed, ESC is always sent
600 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
601 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
606 #ifdef GRAVE_ESC_GUI_OVERRIDE
607 // if GUI is pressed, ESC is always sent
608 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
613 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
614 // if SHIFT is pressed, ESC is always sent
615 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
620 if (record->event.pressed) {
621 grave_esc_was_shifted = shifted;
622 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
625 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
628 send_keyboard_report();
632 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
634 if (record->event.pressed)
641 shift_interrupted[0] = true;
642 shift_interrupted[1] = true;
647 return process_action_kb(record);
650 __attribute__ ((weak))
651 const bool ascii_to_shift_lut[0x80] PROGMEM = {
652 0, 0, 0, 0, 0, 0, 0, 0,
653 0, 0, 0, 0, 0, 0, 0, 0,
654 0, 0, 0, 0, 0, 0, 0, 0,
655 0, 0, 0, 0, 0, 0, 0, 0,
656 0, 1, 1, 1, 1, 1, 1, 0,
657 1, 1, 1, 1, 0, 0, 0, 0,
658 0, 0, 0, 0, 0, 0, 0, 0,
659 0, 0, 1, 0, 1, 0, 1, 1,
660 1, 1, 1, 1, 1, 1, 1, 1,
661 1, 1, 1, 1, 1, 1, 1, 1,
662 1, 1, 1, 1, 1, 1, 1, 1,
663 1, 1, 1, 0, 0, 0, 1, 1,
664 0, 0, 0, 0, 0, 0, 0, 0,
665 0, 0, 0, 0, 0, 0, 0, 0,
666 0, 0, 0, 0, 0, 0, 0, 0,
667 0, 0, 0, 1, 1, 1, 1, 0
670 __attribute__ ((weak))
671 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
672 0, 0, 0, 0, 0, 0, 0, 0,
673 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
674 0, 0, 0, 0, 0, 0, 0, 0,
675 0, 0, 0, KC_ESC, 0, 0, 0, 0,
676 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
677 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
678 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
679 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
680 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
681 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
682 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
683 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
684 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
685 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
686 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
687 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
690 void send_string(const char *str) {
691 send_string_with_delay(str, 0);
694 void send_string_P(const char *str) {
695 send_string_with_delay_P(str, 0);
698 void send_string_with_delay(const char *str, uint8_t interval) {
700 char ascii_code = *str;
701 if (!ascii_code) break;
702 if (ascii_code == 1) {
704 uint8_t keycode = *(++str);
705 register_code(keycode);
706 unregister_code(keycode);
707 } else if (ascii_code == 2) {
709 uint8_t keycode = *(++str);
710 register_code(keycode);
711 } else if (ascii_code == 3) {
713 uint8_t keycode = *(++str);
714 unregister_code(keycode);
716 send_char(ascii_code);
720 { uint8_t ms = interval; while (ms--) wait_ms(1); }
724 void send_string_with_delay_P(const char *str, uint8_t interval) {
726 char ascii_code = pgm_read_byte(str);
727 if (!ascii_code) break;
728 if (ascii_code == 1) {
730 uint8_t keycode = pgm_read_byte(++str);
731 register_code(keycode);
732 unregister_code(keycode);
733 } else if (ascii_code == 2) {
735 uint8_t keycode = pgm_read_byte(++str);
736 register_code(keycode);
737 } else if (ascii_code == 3) {
739 uint8_t keycode = pgm_read_byte(++str);
740 unregister_code(keycode);
742 send_char(ascii_code);
746 { uint8_t ms = interval; while (ms--) wait_ms(1); }
750 void send_char(char ascii_code) {
752 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
753 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
754 register_code(KC_LSFT);
755 register_code(keycode);
756 unregister_code(keycode);
757 unregister_code(KC_LSFT);
759 register_code(keycode);
760 unregister_code(keycode);
764 void set_single_persistent_default_layer(uint8_t default_layer) {
765 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
766 PLAY_SONG(default_layer_songs[default_layer]);
768 eeconfig_update_default_layer(1U<<default_layer);
769 default_layer_set(1U<<default_layer);
772 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
773 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
780 void tap_random_base64(void) {
781 #if defined(__AVR_ATmega32U4__)
782 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
784 uint8_t key = rand() % 64;
788 register_code(KC_LSFT);
789 register_code(key + KC_A);
790 unregister_code(key + KC_A);
791 unregister_code(KC_LSFT);
794 register_code(key - 26 + KC_A);
795 unregister_code(key - 26 + KC_A);
799 unregister_code(KC_0);
802 register_code(key - 53 + KC_1);
803 unregister_code(key - 53 + KC_1);
806 register_code(KC_LSFT);
807 register_code(KC_EQL);
808 unregister_code(KC_EQL);
809 unregister_code(KC_LSFT);
812 register_code(KC_SLSH);
813 unregister_code(KC_SLSH);
818 void matrix_init_quantum() {
819 #ifdef BACKLIGHT_ENABLE
820 backlight_init_ports();
828 void matrix_scan_quantum() {
833 #ifdef TAP_DANCE_ENABLE
834 matrix_scan_tap_dance();
841 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
848 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
850 static const uint8_t backlight_pin = BACKLIGHT_PIN;
852 // depending on the pin, we use a different output compare unit
853 #if BACKLIGHT_PIN == B7
854 # define COM1x1 COM1C1
856 #elif BACKLIGHT_PIN == B6
857 # define COM1x1 COM1B1
859 #elif BACKLIGHT_PIN == B5
860 # define COM1x1 COM1A1
863 # define NO_HARDWARE_PWM
866 #ifndef BACKLIGHT_ON_STATE
867 #define BACKLIGHT_ON_STATE 0
870 #ifdef NO_HARDWARE_PWM // pwm through software
872 __attribute__ ((weak))
873 void backlight_init_ports(void)
875 // Setup backlight pin as output and output to on state.
877 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
878 #if BACKLIGHT_ON_STATE == 0
880 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
883 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
887 __attribute__ ((weak))
888 void backlight_set(uint8_t level) {}
890 uint8_t backlight_tick = 0;
892 #ifndef BACKLIGHT_CUSTOM_DRIVER
893 void backlight_task(void) {
894 if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
895 #if BACKLIGHT_ON_STATE == 0
897 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
900 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
903 #if BACKLIGHT_ON_STATE == 0
905 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
908 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
911 backlight_tick = (backlight_tick + 1) % 16;
915 #ifdef BACKLIGHT_BREATHING
916 #ifndef BACKLIGHT_CUSTOM_DRIVER
917 #error "Backlight breathing only available with hardware PWM. Please disable."
921 #else // pwm through timer
923 #define TIMER_TOP 0xFFFFU
925 // See http://jared.geek.nz/2013/feb/linear-led-pwm
926 static uint16_t cie_lightness(uint16_t v) {
927 if (v <= 5243) // if below 8% of max
928 return v / 9; // same as dividing by 900%
930 uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
931 // to get a useful result with integer division, we shift left in the expression above
932 // and revert what we've done again after squaring.
934 if (y > 0xFFFFUL) // prevent overflow
941 // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
942 static inline void set_pwm(uint16_t val) {
946 #ifndef BACKLIGHT_CUSTOM_DRIVER
947 __attribute__ ((weak))
948 void backlight_set(uint8_t level) {
949 if (level > BACKLIGHT_LEVELS)
950 level = BACKLIGHT_LEVELS;
953 // Turn off PWM control on backlight pin
954 TCCR1A &= ~(_BV(COM1x1));
956 // Turn on PWM control of backlight pin
957 TCCR1A |= _BV(COM1x1);
959 // Set the brightness
960 set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
963 void backlight_task(void) {}
964 #endif // BACKLIGHT_CUSTOM_DRIVER
966 #ifdef BACKLIGHT_BREATHING
968 #define BREATHING_NO_HALT 0
969 #define BREATHING_HALT_OFF 1
970 #define BREATHING_HALT_ON 2
971 #define BREATHING_STEPS 128
973 static uint8_t breathing_period = BREATHING_PERIOD;
974 static uint8_t breathing_halt = BREATHING_NO_HALT;
975 static uint16_t breathing_counter = 0;
977 bool is_breathing(void) {
978 return !!(TIMSK1 & _BV(TOIE1));
981 #define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0)
982 #define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0)
983 #define breathing_min() do {breathing_counter = 0;} while (0)
984 #define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
986 void breathing_enable(void)
988 breathing_counter = 0;
989 breathing_halt = BREATHING_NO_HALT;
990 breathing_interrupt_enable();
993 void breathing_pulse(void)
995 if (get_backlight_level() == 0)
999 breathing_halt = BREATHING_HALT_ON;
1000 breathing_interrupt_enable();
1003 void breathing_disable(void)
1005 breathing_interrupt_disable();
1006 // Restore backlight level
1007 backlight_set(get_backlight_level());
1010 void breathing_self_disable(void)
1012 if (get_backlight_level() == 0)
1013 breathing_halt = BREATHING_HALT_OFF;
1015 breathing_halt = BREATHING_HALT_ON;
1018 void breathing_toggle(void) {
1020 breathing_disable();
1025 void breathing_period_set(uint8_t value)
1029 breathing_period = value;
1032 void breathing_period_default(void) {
1033 breathing_period_set(BREATHING_PERIOD);
1036 void breathing_period_inc(void)
1038 breathing_period_set(breathing_period+1);
1041 void breathing_period_dec(void)
1043 breathing_period_set(breathing_period-1);
1046 /* To generate breathing curve in python:
1047 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
1049 static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1051 // Use this before the cie_lightness function.
1052 static inline uint16_t scale_backlight(uint16_t v) {
1053 return v / BACKLIGHT_LEVELS * get_backlight_level();
1056 /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1057 * about 244 times per second.
1059 ISR(TIMER1_OVF_vect)
1061 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
1062 // resetting after one period to prevent ugly reset at overflow.
1063 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
1064 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
1066 if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
1067 ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
1069 breathing_interrupt_disable();
1072 set_pwm(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
1075 #endif // BACKLIGHT_BREATHING
1077 __attribute__ ((weak))
1078 void backlight_init_ports(void)
1080 // Setup backlight pin as output and output to on state.
1082 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
1083 #if BACKLIGHT_ON_STATE == 0
1085 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1088 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1090 // I could write a wall of text here to explain... but TL;DW
1091 // Go read the ATmega32u4 datasheet.
1092 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
1094 // Pin PB7 = OCR1C (Timer 1, Channel C)
1095 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
1096 // (i.e. start high, go low when counter matches.)
1097 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
1098 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
1102 "In fast PWM mode, the compare units allow generation of PWM waveforms on the OCnx pins. Setting the COMnx1:0 bits to two will produce a non-inverted PWM [..]."
1103 "In fast PWM mode the counter is incremented until the counter value matches either one of the fixed values 0x00FF, 0x01FF, or 0x03FF (WGMn3:0 = 5, 6, or 7), the value in ICRn (WGMn3:0 = 14), or the value in OCRnA (WGMn3:0 = 15)."
1106 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
1107 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1108 // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0.
1112 #ifdef BACKLIGHT_BREATHING
1117 #endif // NO_HARDWARE_PWM
1121 __attribute__ ((weak))
1122 void backlight_init_ports(void) {}
1124 __attribute__ ((weak))
1125 void backlight_set(uint8_t level) {}
1130 // Functions for spitting out values
1133 void send_dword(uint32_t number) { // this might not actually work
1134 uint16_t word = (number >> 16);
1136 send_word(number & 0xFFFFUL);
1139 void send_word(uint16_t number) {
1140 uint8_t byte = number >> 8;
1142 send_byte(number & 0xFF);
1145 void send_byte(uint8_t number) {
1146 uint8_t nibble = number >> 4;
1147 send_nibble(nibble);
1148 send_nibble(number & 0xF);
1151 void send_nibble(uint8_t number) {
1154 register_code(KC_0);
1155 unregister_code(KC_0);
1158 register_code(KC_1 + (number - 1));
1159 unregister_code(KC_1 + (number - 1));
1162 register_code(KC_A + (number - 0xA));
1163 unregister_code(KC_A + (number - 0xA));
1169 __attribute__((weak))
1170 uint16_t hex_to_keycode(uint8_t hex)
1175 } else if (hex < 0xA) {
1176 return KC_1 + (hex - 0x1);
1178 return KC_A + (hex - 0xA);
1182 void api_send_unicode(uint32_t unicode) {
1185 dword_to_bytes(unicode, chunk);
1186 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1190 __attribute__ ((weak))
1191 void led_set_user(uint8_t usb_led) {
1195 __attribute__ ((weak))
1196 void led_set_kb(uint8_t usb_led) {
1197 led_set_user(usb_led);
1200 __attribute__ ((weak))
1201 void led_init_ports(void)
1206 __attribute__ ((weak))
1207 void led_set(uint8_t usb_led)
1212 // // Using PE6 Caps Lock LED
1213 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1223 // PORTE &= ~(1<<6);
1226 led_set_kb(usb_led);
1230 //------------------------------------------------------------------------------
1231 // Override these functions in your keymap file to play different tunes on
1232 // different events such as startup and bootloader jump
1234 __attribute__ ((weak))
1235 void startup_user() {}
1237 __attribute__ ((weak))
1238 void shutdown_user() {}
1240 //------------------------------------------------------------------------------