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"
42 #include "process_midi.h"
47 #define GOODBYE_SONG SONG(GOODBYE_SOUND)
50 #define AG_NORM_SONG SONG(AG_NORM_SOUND)
53 #define AG_SWAP_SONG SONG(AG_SWAP_SOUND)
55 float goodbye_song[][2] = GOODBYE_SONG;
56 float ag_norm_song[][2] = AG_NORM_SONG;
57 float ag_swap_song[][2] = AG_SWAP_SONG;
58 #ifdef DEFAULT_LAYER_SONGS
59 float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS;
63 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
65 case QK_MODS ... QK_MODS_MAX:
80 if (code < QK_RMODS_MIN) return;
92 static inline void qk_register_weak_mods(uint8_t kc) {
93 add_weak_mods(MOD_BIT(kc));
94 send_keyboard_report();
97 static inline void qk_unregister_weak_mods(uint8_t kc) {
98 del_weak_mods(MOD_BIT(kc));
99 send_keyboard_report();
102 static inline void qk_register_mods(uint8_t kc) {
103 add_weak_mods(MOD_BIT(kc));
104 send_keyboard_report();
107 static inline void qk_unregister_mods(uint8_t kc) {
108 del_weak_mods(MOD_BIT(kc));
109 send_keyboard_report();
112 void register_code16 (uint16_t code) {
113 if (IS_MOD(code) || code == KC_NO) {
114 do_code16 (code, qk_register_mods);
116 do_code16 (code, qk_register_weak_mods);
118 register_code (code);
121 void unregister_code16 (uint16_t code) {
122 unregister_code (code);
123 if (IS_MOD(code) || code == KC_NO) {
124 do_code16 (code, qk_unregister_mods);
126 do_code16 (code, qk_unregister_weak_mods);
130 __attribute__ ((weak))
131 bool process_action_kb(keyrecord_t *record) {
135 __attribute__ ((weak))
136 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
137 return process_record_user(keycode, record);
140 __attribute__ ((weak))
141 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
145 void reset_keyboard(void) {
147 #if defined(MIDI_ENABLE) && defined(MIDI_BASIC)
148 process_midi_all_notes_off();
150 #if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
151 music_all_notes_off();
152 uint16_t timer_start = timer_read();
153 PLAY_SONG(goodbye_song);
155 while(timer_elapsed(timer_start) < 250)
161 // this is also done later in bootloader.c - not sure if it's neccesary here
162 #ifdef BOOTLOADER_CATERINA
163 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
168 // Shift / paren setup
171 #define LSPO_KEY KC_9
174 #define RSPC_KEY KC_0
177 // Shift / Enter setup
179 #define SFTENT_KEY KC_ENT
182 static bool shift_interrupted[2] = {0, 0};
183 static uint16_t scs_timer[2] = {0, 0};
185 /* true if the last press of GRAVE_ESC was shifted (i.e. GUI or SHIFT were pressed), false otherwise.
186 * Used to ensure that the correct keycode is released if the key is released.
188 static bool grave_esc_was_shifted = false;
190 bool process_record_quantum(keyrecord_t *record) {
192 /* This gets the keycode from the key pressed */
193 keypos_t key = record->event.key;
196 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
197 /* TODO: Use store_or_get_action() or a similar function. */
198 if (!disable_action_cache) {
201 if (record->event.pressed) {
202 layer = layer_switch_get_layer(key);
203 update_source_layers_cache(key, layer);
205 layer = read_source_layers_cache(key);
207 keycode = keymap_key_to_keycode(layer, key);
210 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
212 // This is how you use actions here
213 // if (keycode == KC_LEAD) {
215 // action.code = ACTION_DEFAULT_LAYER_SET(0);
216 // process_action(record, action);
220 #ifdef TAP_DANCE_ENABLE
221 preprocess_tap_dance(keycode, record);
225 #if defined(KEY_LOCK_ENABLE)
226 // Must run first to be able to mask key_up events.
227 process_key_lock(&keycode, record) &&
229 #if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY)
230 process_clicky(keycode, record) &&
231 #endif //AUDIO_CLICKY
232 process_record_kb(keycode, record) &&
233 #if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
234 process_rgb_matrix(keycode, record) &&
236 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
237 process_midi(keycode, record) &&
240 process_audio(keycode, record) &&
243 process_steno(keycode, record) &&
245 #if ( defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE)
246 process_music(keycode, record) &&
248 #ifdef TAP_DANCE_ENABLE
249 process_tap_dance(keycode, record) &&
251 #ifndef DISABLE_LEADER
252 process_leader(keycode, record) &&
254 #ifndef DISABLE_CHORDING
255 process_chording(keycode, record) &&
258 process_combo(keycode, record) &&
260 #ifdef UNICODE_ENABLE
261 process_unicode(keycode, record) &&
264 process_ucis(keycode, record) &&
266 #ifdef PRINTING_ENABLE
267 process_printer(keycode, record) &&
269 #ifdef AUTO_SHIFT_ENABLE
270 process_auto_shift(keycode, record) &&
272 #ifdef UNICODEMAP_ENABLE
273 process_unicode_map(keycode, record) &&
275 #ifdef TERMINAL_ENABLE
276 process_terminal(keycode, record) &&
282 // Shift / paren setup
286 if (record->event.pressed) {
291 if (record->event.pressed) {
293 print("DEBUG: enabled.\n");
296 #ifdef FAUXCLICKY_ENABLE
298 if (record->event.pressed) {
303 if (record->event.pressed) {
308 if (record->event.pressed) {
313 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
315 if (record->event.pressed) {
319 case RGB_MODE_FORWARD:
320 if (record->event.pressed) {
321 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
323 rgblight_step_reverse();
330 case RGB_MODE_REVERSE:
331 if (record->event.pressed) {
332 uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
337 rgblight_step_reverse();
342 if (record->event.pressed) {
343 rgblight_increase_hue();
347 if (record->event.pressed) {
348 rgblight_decrease_hue();
352 if (record->event.pressed) {
353 rgblight_increase_sat();
357 if (record->event.pressed) {
358 rgblight_decrease_sat();
362 if (record->event.pressed) {
363 rgblight_increase_val();
367 if (record->event.pressed) {
368 rgblight_decrease_val();
372 if (record->event.pressed) {
376 case RGB_MODE_BREATHE:
377 if (record->event.pressed) {
378 if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
385 case RGB_MODE_RAINBOW:
386 if (record->event.pressed) {
387 if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
395 if (record->event.pressed) {
396 if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
404 if (record->event.pressed) {
405 if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
412 case RGB_MODE_KNIGHT:
413 if (record->event.pressed) {
414 if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
422 if (record->event.pressed) {
426 case RGB_MODE_GRADIENT:
427 if (record->event.pressed) {
428 if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
438 if (record->event.pressed) {
439 set_output(OUTPUT_AUTO);
443 if (record->event.pressed) {
444 set_output(OUTPUT_USB);
447 #ifdef BLUETOOTH_ENABLE
449 if (record->event.pressed) {
450 set_output(OUTPUT_BLUETOOTH);
455 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
456 if (record->event.pressed) {
457 // MAGIC actions (BOOTMAGIC without the boot)
458 if (!eeconfig_is_enabled()) {
462 keymap_config.raw = eeconfig_read_keymap();
465 case MAGIC_SWAP_CONTROL_CAPSLOCK:
466 keymap_config.swap_control_capslock = true;
468 case MAGIC_CAPSLOCK_TO_CONTROL:
469 keymap_config.capslock_to_control = true;
471 case MAGIC_SWAP_LALT_LGUI:
472 keymap_config.swap_lalt_lgui = true;
474 case MAGIC_SWAP_RALT_RGUI:
475 keymap_config.swap_ralt_rgui = true;
478 keymap_config.no_gui = true;
480 case MAGIC_SWAP_GRAVE_ESC:
481 keymap_config.swap_grave_esc = true;
483 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
484 keymap_config.swap_backslash_backspace = true;
486 case MAGIC_HOST_NKRO:
487 keymap_config.nkro = true;
489 case MAGIC_SWAP_ALT_GUI:
490 keymap_config.swap_lalt_lgui = true;
491 keymap_config.swap_ralt_rgui = true;
493 PLAY_SONG(ag_swap_song);
496 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
497 keymap_config.swap_control_capslock = false;
499 case MAGIC_UNCAPSLOCK_TO_CONTROL:
500 keymap_config.capslock_to_control = false;
502 case MAGIC_UNSWAP_LALT_LGUI:
503 keymap_config.swap_lalt_lgui = false;
505 case MAGIC_UNSWAP_RALT_RGUI:
506 keymap_config.swap_ralt_rgui = false;
509 keymap_config.no_gui = false;
511 case MAGIC_UNSWAP_GRAVE_ESC:
512 keymap_config.swap_grave_esc = false;
514 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
515 keymap_config.swap_backslash_backspace = false;
517 case MAGIC_UNHOST_NKRO:
518 keymap_config.nkro = false;
520 case MAGIC_UNSWAP_ALT_GUI:
521 keymap_config.swap_lalt_lgui = false;
522 keymap_config.swap_ralt_rgui = false;
524 PLAY_SONG(ag_norm_song);
527 case MAGIC_TOGGLE_NKRO:
528 keymap_config.nkro = !keymap_config.nkro;
533 eeconfig_update_keymap(keymap_config.raw);
534 clear_keyboard(); // clear to prevent stuck keys
540 if (record->event.pressed) {
541 shift_interrupted[0] = false;
542 scs_timer[0] = timer_read ();
543 register_mods(MOD_BIT(KC_LSFT));
546 #ifdef DISABLE_SPACE_CADET_ROLLOVER
547 if (get_mods() & MOD_BIT(KC_RSFT)) {
548 shift_interrupted[0] = true;
549 shift_interrupted[1] = true;
552 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
553 register_code(LSPO_KEY);
554 unregister_code(LSPO_KEY);
556 unregister_mods(MOD_BIT(KC_LSFT));
562 if (record->event.pressed) {
563 shift_interrupted[1] = false;
564 scs_timer[1] = timer_read ();
565 register_mods(MOD_BIT(KC_RSFT));
568 #ifdef DISABLE_SPACE_CADET_ROLLOVER
569 if (get_mods() & MOD_BIT(KC_LSFT)) {
570 shift_interrupted[0] = true;
571 shift_interrupted[1] = true;
574 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
575 register_code(RSPC_KEY);
576 unregister_code(RSPC_KEY);
578 unregister_mods(MOD_BIT(KC_RSFT));
584 if (record->event.pressed) {
585 shift_interrupted[1] = false;
586 scs_timer[1] = timer_read ();
587 register_mods(MOD_BIT(KC_RSFT));
589 else if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
590 unregister_mods(MOD_BIT(KC_RSFT));
591 register_code(SFTENT_KEY);
592 unregister_code(SFTENT_KEY);
595 unregister_mods(MOD_BIT(KC_RSFT));
601 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
602 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
604 #ifdef GRAVE_ESC_ALT_OVERRIDE
605 // if ALT is pressed, ESC is always sent
606 // this is handy for the cmd+opt+esc shortcut on macOS, among other things.
607 if (get_mods() & (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))) {
612 #ifdef GRAVE_ESC_CTRL_OVERRIDE
613 // if CTRL is pressed, ESC is always sent
614 // this is handy for the ctrl+shift+esc shortcut on windows, among other things.
615 if (get_mods() & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_RCTL))) {
620 #ifdef GRAVE_ESC_GUI_OVERRIDE
621 // if GUI is pressed, ESC is always sent
622 if (get_mods() & (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))) {
627 #ifdef GRAVE_ESC_SHIFT_OVERRIDE
628 // if SHIFT is pressed, ESC is always sent
629 if (get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))) {
634 if (record->event.pressed) {
635 grave_esc_was_shifted = shifted;
636 add_key(shifted ? KC_GRAVE : KC_ESCAPE);
639 del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE);
642 send_keyboard_report();
646 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING)
648 if (record->event.pressed)
655 shift_interrupted[0] = true;
656 shift_interrupted[1] = true;
661 return process_action_kb(record);
664 __attribute__ ((weak))
665 const bool ascii_to_shift_lut[0x80] PROGMEM = {
666 0, 0, 0, 0, 0, 0, 0, 0,
667 0, 0, 0, 0, 0, 0, 0, 0,
668 0, 0, 0, 0, 0, 0, 0, 0,
669 0, 0, 0, 0, 0, 0, 0, 0,
670 0, 1, 1, 1, 1, 1, 1, 0,
671 1, 1, 1, 1, 0, 0, 0, 0,
672 0, 0, 0, 0, 0, 0, 0, 0,
673 0, 0, 1, 0, 1, 0, 1, 1,
674 1, 1, 1, 1, 1, 1, 1, 1,
675 1, 1, 1, 1, 1, 1, 1, 1,
676 1, 1, 1, 1, 1, 1, 1, 1,
677 1, 1, 1, 0, 0, 0, 1, 1,
678 0, 0, 0, 0, 0, 0, 0, 0,
679 0, 0, 0, 0, 0, 0, 0, 0,
680 0, 0, 0, 0, 0, 0, 0, 0,
681 0, 0, 0, 1, 1, 1, 1, 0
684 __attribute__ ((weak))
685 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
686 0, 0, 0, 0, 0, 0, 0, 0,
687 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
688 0, 0, 0, 0, 0, 0, 0, 0,
689 0, 0, 0, KC_ESC, 0, 0, 0, 0,
690 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
691 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
692 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
693 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
694 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
695 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
696 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
697 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
698 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
699 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
700 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
701 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
704 void send_string(const char *str) {
705 send_string_with_delay(str, 0);
708 void send_string_P(const char *str) {
709 send_string_with_delay_P(str, 0);
712 void send_string_with_delay(const char *str, uint8_t interval) {
714 char ascii_code = *str;
715 if (!ascii_code) break;
716 if (ascii_code == 1) {
718 uint8_t keycode = *(++str);
719 register_code(keycode);
720 unregister_code(keycode);
721 } else if (ascii_code == 2) {
723 uint8_t keycode = *(++str);
724 register_code(keycode);
725 } else if (ascii_code == 3) {
727 uint8_t keycode = *(++str);
728 unregister_code(keycode);
730 send_char(ascii_code);
734 { uint8_t ms = interval; while (ms--) wait_ms(1); }
738 void send_string_with_delay_P(const char *str, uint8_t interval) {
740 char ascii_code = pgm_read_byte(str);
741 if (!ascii_code) break;
742 if (ascii_code == 1) {
744 uint8_t keycode = pgm_read_byte(++str);
745 register_code(keycode);
746 unregister_code(keycode);
747 } else if (ascii_code == 2) {
749 uint8_t keycode = pgm_read_byte(++str);
750 register_code(keycode);
751 } else if (ascii_code == 3) {
753 uint8_t keycode = pgm_read_byte(++str);
754 unregister_code(keycode);
756 send_char(ascii_code);
760 { uint8_t ms = interval; while (ms--) wait_ms(1); }
764 void send_char(char ascii_code) {
766 keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]);
767 if (pgm_read_byte(&ascii_to_shift_lut[(uint8_t)ascii_code])) {
768 register_code(KC_LSFT);
769 register_code(keycode);
770 unregister_code(keycode);
771 unregister_code(KC_LSFT);
773 register_code(keycode);
774 unregister_code(keycode);
778 void set_single_persistent_default_layer(uint8_t default_layer) {
779 #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
780 PLAY_SONG(default_layer_songs[default_layer]);
782 eeconfig_update_default_layer(1U<<default_layer);
783 default_layer_set(1U<<default_layer);
786 uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
787 uint32_t mask12 = (1UL << layer1) | (1UL << layer2);
788 uint32_t mask3 = 1UL << layer3;
789 return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
792 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
793 layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
796 void tap_random_base64(void) {
797 #if defined(__AVR_ATmega32U4__)
798 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
800 uint8_t key = rand() % 64;
804 register_code(KC_LSFT);
805 register_code(key + KC_A);
806 unregister_code(key + KC_A);
807 unregister_code(KC_LSFT);
810 register_code(key - 26 + KC_A);
811 unregister_code(key - 26 + KC_A);
815 unregister_code(KC_0);
818 register_code(key - 53 + KC_1);
819 unregister_code(key - 53 + KC_1);
822 register_code(KC_LSFT);
823 register_code(KC_EQL);
824 unregister_code(KC_EQL);
825 unregister_code(KC_LSFT);
828 register_code(KC_SLSH);
829 unregister_code(KC_SLSH);
834 void matrix_init_quantum() {
835 #ifdef BACKLIGHT_ENABLE
836 backlight_init_ports();
841 #ifdef RGB_MATRIX_ENABLE
842 rgb_matrix_init_drivers();
847 uint8_t rgb_matrix_task_counter = 0;
849 #ifndef RGB_MATRIX_SKIP_FRAMES
850 #define RGB_MATRIX_SKIP_FRAMES 1
853 void matrix_scan_quantum() {
854 #if defined(AUDIO_ENABLE)
858 #ifdef TAP_DANCE_ENABLE
859 matrix_scan_tap_dance();
866 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
870 #ifdef RGB_MATRIX_ENABLE
872 if (rgb_matrix_task_counter == 0) {
873 rgb_matrix_update_pwm_buffers();
875 rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1));
880 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
882 static const uint8_t backlight_pin = BACKLIGHT_PIN;
884 // depending on the pin, we use a different output compare unit
885 #if BACKLIGHT_PIN == B7
886 # define COM1x1 COM1C1
888 #elif BACKLIGHT_PIN == B6
889 # define COM1x1 COM1B1
891 #elif BACKLIGHT_PIN == B5
892 # define COM1x1 COM1A1
895 # define NO_HARDWARE_PWM
898 #ifndef BACKLIGHT_ON_STATE
899 #define BACKLIGHT_ON_STATE 0
902 #ifdef NO_HARDWARE_PWM // pwm through software
904 __attribute__ ((weak))
905 void backlight_init_ports(void)
907 // Setup backlight pin as output and output to on state.
909 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
910 #if BACKLIGHT_ON_STATE == 0
912 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
915 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
919 __attribute__ ((weak))
920 void backlight_set(uint8_t level) {}
922 uint8_t backlight_tick = 0;
924 #ifndef BACKLIGHT_CUSTOM_DRIVER
925 void backlight_task(void) {
926 if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
927 #if BACKLIGHT_ON_STATE == 0
929 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
932 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
935 #if BACKLIGHT_ON_STATE == 0
937 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
940 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
943 backlight_tick = (backlight_tick + 1) % 16;
947 #ifdef BACKLIGHT_BREATHING
948 #ifndef BACKLIGHT_CUSTOM_DRIVER
949 #error "Backlight breathing only available with hardware PWM. Please disable."
953 #else // pwm through timer
955 #define TIMER_TOP 0xFFFFU
957 // See http://jared.geek.nz/2013/feb/linear-led-pwm
958 static uint16_t cie_lightness(uint16_t v) {
959 if (v <= 5243) // if below 8% of max
960 return v / 9; // same as dividing by 900%
962 uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
963 // to get a useful result with integer division, we shift left in the expression above
964 // and revert what we've done again after squaring.
966 if (y > 0xFFFFUL) // prevent overflow
973 // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val.
974 static inline void set_pwm(uint16_t val) {
978 #ifndef BACKLIGHT_CUSTOM_DRIVER
979 __attribute__ ((weak))
980 void backlight_set(uint8_t level) {
981 if (level > BACKLIGHT_LEVELS)
982 level = BACKLIGHT_LEVELS;
985 // Turn off PWM control on backlight pin
986 TCCR1A &= ~(_BV(COM1x1));
988 // Turn on PWM control of backlight pin
989 TCCR1A |= _BV(COM1x1);
991 // Set the brightness
992 set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS));
995 void backlight_task(void) {}
996 #endif // BACKLIGHT_CUSTOM_DRIVER
998 #ifdef BACKLIGHT_BREATHING
1000 #define BREATHING_NO_HALT 0
1001 #define BREATHING_HALT_OFF 1
1002 #define BREATHING_HALT_ON 2
1003 #define BREATHING_STEPS 128
1005 static uint8_t breathing_period = BREATHING_PERIOD;
1006 static uint8_t breathing_halt = BREATHING_NO_HALT;
1007 static uint16_t breathing_counter = 0;
1009 bool is_breathing(void) {
1010 return !!(TIMSK1 & _BV(TOIE1));
1013 #define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0)
1014 #define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0)
1015 #define breathing_min() do {breathing_counter = 0;} while (0)
1016 #define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
1018 void breathing_enable(void)
1020 breathing_counter = 0;
1021 breathing_halt = BREATHING_NO_HALT;
1022 breathing_interrupt_enable();
1025 void breathing_pulse(void)
1027 if (get_backlight_level() == 0)
1031 breathing_halt = BREATHING_HALT_ON;
1032 breathing_interrupt_enable();
1035 void breathing_disable(void)
1037 breathing_interrupt_disable();
1038 // Restore backlight level
1039 backlight_set(get_backlight_level());
1042 void breathing_self_disable(void)
1044 if (get_backlight_level() == 0)
1045 breathing_halt = BREATHING_HALT_OFF;
1047 breathing_halt = BREATHING_HALT_ON;
1050 void breathing_toggle(void) {
1052 breathing_disable();
1057 void breathing_period_set(uint8_t value)
1061 breathing_period = value;
1064 void breathing_period_default(void) {
1065 breathing_period_set(BREATHING_PERIOD);
1068 void breathing_period_inc(void)
1070 breathing_period_set(breathing_period+1);
1073 void breathing_period_dec(void)
1075 breathing_period_set(breathing_period-1);
1078 /* To generate breathing curve in python:
1079 * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
1081 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};
1083 // Use this before the cie_lightness function.
1084 static inline uint16_t scale_backlight(uint16_t v) {
1085 return v / BACKLIGHT_LEVELS * get_backlight_level();
1088 /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run
1089 * about 244 times per second.
1091 ISR(TIMER1_OVF_vect)
1093 uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
1094 // resetting after one period to prevent ugly reset at overflow.
1095 breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
1096 uint8_t index = breathing_counter / interval % BREATHING_STEPS;
1098 if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
1099 ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
1101 breathing_interrupt_disable();
1104 set_pwm(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
1107 #endif // BACKLIGHT_BREATHING
1109 __attribute__ ((weak))
1110 void backlight_init_ports(void)
1112 // Setup backlight pin as output and output to on state.
1114 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
1115 #if BACKLIGHT_ON_STATE == 0
1117 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
1120 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
1122 // I could write a wall of text here to explain... but TL;DW
1123 // Go read the ATmega32u4 datasheet.
1124 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
1126 // Pin PB7 = OCR1C (Timer 1, Channel C)
1127 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
1128 // (i.e. start high, go low when counter matches.)
1129 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
1130 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
1134 "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 [..]."
1135 "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)."
1138 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
1139 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
1140 // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0.
1144 #ifdef BACKLIGHT_BREATHING
1149 #endif // NO_HARDWARE_PWM
1153 __attribute__ ((weak))
1154 void backlight_init_ports(void) {}
1156 __attribute__ ((weak))
1157 void backlight_set(uint8_t level) {}
1162 // Functions for spitting out values
1165 void send_dword(uint32_t number) { // this might not actually work
1166 uint16_t word = (number >> 16);
1168 send_word(number & 0xFFFFUL);
1171 void send_word(uint16_t number) {
1172 uint8_t byte = number >> 8;
1174 send_byte(number & 0xFF);
1177 void send_byte(uint8_t number) {
1178 uint8_t nibble = number >> 4;
1179 send_nibble(nibble);
1180 send_nibble(number & 0xF);
1183 void send_nibble(uint8_t number) {
1186 register_code(KC_0);
1187 unregister_code(KC_0);
1190 register_code(KC_1 + (number - 1));
1191 unregister_code(KC_1 + (number - 1));
1194 register_code(KC_A + (number - 0xA));
1195 unregister_code(KC_A + (number - 0xA));
1201 __attribute__((weak))
1202 uint16_t hex_to_keycode(uint8_t hex)
1207 } else if (hex < 0xA) {
1208 return KC_1 + (hex - 0x1);
1210 return KC_A + (hex - 0xA);
1214 void api_send_unicode(uint32_t unicode) {
1217 dword_to_bytes(unicode, chunk);
1218 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1222 __attribute__ ((weak))
1223 void led_set_user(uint8_t usb_led) {
1227 __attribute__ ((weak))
1228 void led_set_kb(uint8_t usb_led) {
1229 led_set_user(usb_led);
1232 __attribute__ ((weak))
1233 void led_init_ports(void)
1238 __attribute__ ((weak))
1239 void led_set(uint8_t usb_led)
1244 // // Using PE6 Caps Lock LED
1245 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1255 // PORTE &= ~(1<<6);
1258 led_set_kb(usb_led);
1262 //------------------------------------------------------------------------------
1263 // Override these functions in your keymap file to play different tunes on
1264 // different events such as startup and bootloader jump
1266 __attribute__ ((weak))
1267 void startup_user() {}
1269 __attribute__ ((weak))
1270 void shutdown_user() {}
1272 //------------------------------------------------------------------------------