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"
33 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
35 case QK_MODS ... QK_MODS_MAX:
50 if (code < QK_RMODS_MIN) return;
62 static inline void qk_register_weak_mods(uint8_t kc) {
63 add_weak_mods(MOD_BIT(kc));
64 send_keyboard_report();
67 static inline void qk_unregister_weak_mods(uint8_t kc) {
68 del_weak_mods(MOD_BIT(kc));
69 send_keyboard_report();
72 static inline void qk_register_mods(uint8_t kc) {
73 add_weak_mods(MOD_BIT(kc));
74 send_keyboard_report();
77 static inline void qk_unregister_mods(uint8_t kc) {
78 del_weak_mods(MOD_BIT(kc));
79 send_keyboard_report();
82 void register_code16 (uint16_t code) {
83 if (IS_MOD(code) || code == KC_NO) {
84 do_code16 (code, qk_register_mods);
86 do_code16 (code, qk_register_weak_mods);
91 void unregister_code16 (uint16_t code) {
92 unregister_code (code);
93 if (IS_MOD(code) || code == KC_NO) {
94 do_code16 (code, qk_unregister_mods);
96 do_code16 (code, qk_unregister_weak_mods);
100 __attribute__ ((weak))
101 bool process_action_kb(keyrecord_t *record) {
105 __attribute__ ((weak))
106 bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
107 return process_record_user(keycode, record);
110 __attribute__ ((weak))
111 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
115 void reset_keyboard(void) {
117 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
118 music_all_notes_off();
122 #ifdef CATERINA_BOOTLOADER
123 *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
128 // Shift / paren setup
131 #define LSPO_KEY KC_9
134 #define RSPC_KEY KC_0
137 static bool shift_interrupted[2] = {0, 0};
138 static uint16_t scs_timer[2] = {0, 0};
140 bool process_record_quantum(keyrecord_t *record) {
142 /* This gets the keycode from the key pressed */
143 keypos_t key = record->event.key;
146 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
147 /* TODO: Use store_or_get_action() or a similar function. */
148 if (!disable_action_cache) {
151 if (record->event.pressed) {
152 layer = layer_switch_get_layer(key);
153 update_source_layers_cache(key, layer);
155 layer = read_source_layers_cache(key);
157 keycode = keymap_key_to_keycode(layer, key);
160 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
162 // This is how you use actions here
163 // if (keycode == KC_LEAD) {
165 // action.code = ACTION_DEFAULT_LAYER_SET(0);
166 // process_action(record, action);
171 process_record_kb(keycode, record) &&
172 #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
173 process_midi(keycode, record) &&
176 process_audio(keycode, record) &&
178 #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
179 process_music(keycode, record) &&
181 #ifdef TAP_DANCE_ENABLE
182 process_tap_dance(keycode, record) &&
184 #ifndef DISABLE_LEADER
185 process_leader(keycode, record) &&
187 #ifndef DISABLE_CHORDING
188 process_chording(keycode, record) &&
191 process_combo(keycode, record) &&
193 #ifdef UNICODE_ENABLE
194 process_unicode(keycode, record) &&
197 process_ucis(keycode, record) &&
199 #ifdef PRINTING_ENABLE
200 process_printer(keycode, record) &&
202 #ifdef UNICODEMAP_ENABLE
203 process_unicode_map(keycode, record) &&
209 // Shift / paren setup
213 if (record->event.pressed) {
219 if (record->event.pressed) {
220 print("\nDEBUG: enabled.\n");
225 #ifdef FAUXCLICKY_ENABLE
227 if (record->event.pressed) {
233 if (record->event.pressed) {
239 if (record->event.pressed) {
245 #ifdef RGBLIGHT_ENABLE
247 if (record->event.pressed) {
253 if (record->event.pressed) {
259 if (record->event.pressed) {
260 rgblight_increase_hue();
265 if (record->event.pressed) {
266 rgblight_decrease_hue();
271 if (record->event.pressed) {
272 rgblight_increase_sat();
277 if (record->event.pressed) {
278 rgblight_decrease_sat();
283 if (record->event.pressed) {
284 rgblight_increase_val();
289 if (record->event.pressed) {
290 rgblight_decrease_val();
297 if (record->event.pressed) {
298 set_output(OUTPUT_AUTO);
303 if (record->event.pressed) {
304 set_output(OUTPUT_USB);
308 #ifdef BLUETOOTH_ENABLE
310 if (record->event.pressed) {
311 set_output(OUTPUT_BLUETOOTH);
317 case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
318 if (record->event.pressed) {
319 // MAGIC actions (BOOTMAGIC without the boot)
320 if (!eeconfig_is_enabled()) {
324 keymap_config.raw = eeconfig_read_keymap();
327 case MAGIC_SWAP_CONTROL_CAPSLOCK:
328 keymap_config.swap_control_capslock = true;
330 case MAGIC_CAPSLOCK_TO_CONTROL:
331 keymap_config.capslock_to_control = true;
333 case MAGIC_SWAP_LALT_LGUI:
334 keymap_config.swap_lalt_lgui = true;
336 case MAGIC_SWAP_RALT_RGUI:
337 keymap_config.swap_ralt_rgui = true;
340 keymap_config.no_gui = true;
342 case MAGIC_SWAP_GRAVE_ESC:
343 keymap_config.swap_grave_esc = true;
345 case MAGIC_SWAP_BACKSLASH_BACKSPACE:
346 keymap_config.swap_backslash_backspace = true;
348 case MAGIC_HOST_NKRO:
349 keymap_config.nkro = true;
351 case MAGIC_SWAP_ALT_GUI:
352 keymap_config.swap_lalt_lgui = true;
353 keymap_config.swap_ralt_rgui = true;
355 case MAGIC_UNSWAP_CONTROL_CAPSLOCK:
356 keymap_config.swap_control_capslock = false;
358 case MAGIC_UNCAPSLOCK_TO_CONTROL:
359 keymap_config.capslock_to_control = false;
361 case MAGIC_UNSWAP_LALT_LGUI:
362 keymap_config.swap_lalt_lgui = false;
364 case MAGIC_UNSWAP_RALT_RGUI:
365 keymap_config.swap_ralt_rgui = false;
368 keymap_config.no_gui = false;
370 case MAGIC_UNSWAP_GRAVE_ESC:
371 keymap_config.swap_grave_esc = false;
373 case MAGIC_UNSWAP_BACKSLASH_BACKSPACE:
374 keymap_config.swap_backslash_backspace = false;
376 case MAGIC_UNHOST_NKRO:
377 keymap_config.nkro = false;
379 case MAGIC_UNSWAP_ALT_GUI:
380 keymap_config.swap_lalt_lgui = false;
381 keymap_config.swap_ralt_rgui = false;
383 case MAGIC_TOGGLE_NKRO:
384 keymap_config.nkro = !keymap_config.nkro;
389 eeconfig_update_keymap(keymap_config.raw);
390 clear_keyboard(); // clear to prevent stuck keys
396 if (record->event.pressed) {
397 shift_interrupted[0] = false;
398 scs_timer[0] = timer_read ();
399 register_mods(MOD_BIT(KC_LSFT));
402 #ifdef DISABLE_SPACE_CADET_ROLLOVER
403 if (get_mods() & MOD_BIT(KC_RSFT)) {
404 shift_interrupted[0] = true;
405 shift_interrupted[1] = true;
408 if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
409 register_code(LSPO_KEY);
410 unregister_code(LSPO_KEY);
412 unregister_mods(MOD_BIT(KC_LSFT));
419 if (record->event.pressed) {
420 shift_interrupted[1] = false;
421 scs_timer[1] = timer_read ();
422 register_mods(MOD_BIT(KC_RSFT));
425 #ifdef DISABLE_SPACE_CADET_ROLLOVER
426 if (get_mods() & MOD_BIT(KC_LSFT)) {
427 shift_interrupted[0] = true;
428 shift_interrupted[1] = true;
431 if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
432 register_code(RSPC_KEY);
433 unregister_code(RSPC_KEY);
435 unregister_mods(MOD_BIT(KC_RSFT));
441 void (*method)(uint8_t) = (record->event.pressed) ? &add_key : &del_key;
442 uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
443 |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
445 method(shifted ? KC_GRAVE : KC_ESCAPE);
446 send_keyboard_report();
449 shift_interrupted[0] = true;
450 shift_interrupted[1] = true;
455 return process_action_kb(record);
458 const bool ascii_to_qwerty_shift_lut[0x80] PROGMEM = {
459 0, 0, 0, 0, 0, 0, 0, 0,
460 0, 0, 0, 0, 0, 0, 0, 0,
461 0, 0, 0, 0, 0, 0, 0, 0,
462 0, 0, 0, 0, 0, 0, 0, 0,
463 0, 1, 1, 1, 1, 1, 1, 0,
464 1, 1, 1, 1, 0, 0, 0, 0,
465 0, 0, 0, 0, 0, 0, 0, 0,
466 0, 0, 1, 0, 1, 0, 1, 1,
467 1, 1, 1, 1, 1, 1, 1, 1,
468 1, 1, 1, 1, 1, 1, 1, 1,
469 1, 1, 1, 1, 1, 1, 1, 1,
470 1, 1, 1, 0, 0, 0, 1, 1,
471 0, 0, 0, 0, 0, 0, 0, 0,
472 0, 0, 0, 0, 0, 0, 0, 0,
473 0, 0, 0, 0, 0, 0, 0, 0,
474 0, 0, 0, 1, 1, 1, 1, 0
477 const uint8_t ascii_to_qwerty_keycode_lut[0x80] PROGMEM = {
478 0, 0, 0, 0, 0, 0, 0, 0,
479 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
480 0, 0, 0, 0, 0, 0, 0, 0,
481 0, 0, 0, KC_ESC, 0, 0, 0, 0,
482 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
483 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
484 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
485 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
486 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
487 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
488 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
489 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
490 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
491 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
492 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
493 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
496 /* for users whose OSes are set to Colemak */
498 #include "keymap_colemak.h"
500 const bool ascii_to_colemak_shift_lut[0x80] PROGMEM = {
501 0, 0, 0, 0, 0, 0, 0, 0,
502 0, 0, 0, 0, 0, 0, 0, 0,
503 0, 0, 0, 0, 0, 0, 0, 0,
504 0, 0, 0, 0, 0, 0, 0, 0,
505 0, 1, 1, 1, 1, 1, 1, 0,
506 1, 1, 1, 1, 0, 0, 0, 0,
507 0, 0, 0, 0, 0, 0, 0, 0,
508 0, 0, 1, 0, 1, 0, 1, 1,
509 1, 1, 1, 1, 1, 1, 1, 1,
510 1, 1, 1, 1, 1, 1, 1, 1,
511 1, 1, 1, 1, 1, 1, 1, 1,
512 1, 1, 1, 0, 0, 0, 1, 1,
513 0, 0, 0, 0, 0, 0, 0, 0,
514 0, 0, 0, 0, 0, 0, 0, 0,
515 0, 0, 0, 0, 0, 0, 0, 0,
516 0, 0, 0, 1, 1, 1, 1, 0
519 const uint8_t ascii_to_colemak_keycode_lut[0x80] PROGMEM = {
520 0, 0, 0, 0, 0, 0, 0, 0,
521 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
522 0, 0, 0, 0, 0, 0, 0, 0,
523 0, 0, 0, KC_ESC, 0, 0, 0, 0,
524 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
525 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
526 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
527 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
528 KC_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
529 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
530 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
531 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
532 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
533 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
534 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
535 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
540 void send_string(const char *str) {
543 uint8_t ascii_code = pgm_read_byte(str);
544 if (!ascii_code) break;
545 keycode = pgm_read_byte(&ascii_to_qwerty_keycode_lut[ascii_code]);
546 if (pgm_read_byte(&ascii_to_qwerty_shift_lut[ascii_code])) {
547 register_code(KC_LSFT);
548 register_code(keycode);
549 unregister_code(keycode);
550 unregister_code(KC_LSFT);
553 register_code(keycode);
554 unregister_code(keycode);
560 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
561 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
568 void tap_random_base64(void) {
569 #if defined(__AVR_ATmega32U4__)
570 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
572 uint8_t key = rand() % 64;
576 register_code(KC_LSFT);
577 register_code(key + KC_A);
578 unregister_code(key + KC_A);
579 unregister_code(KC_LSFT);
582 register_code(key - 26 + KC_A);
583 unregister_code(key - 26 + KC_A);
587 unregister_code(KC_0);
590 register_code(key - 53 + KC_1);
591 unregister_code(key - 53 + KC_1);
594 register_code(KC_LSFT);
595 register_code(KC_EQL);
596 unregister_code(KC_EQL);
597 unregister_code(KC_LSFT);
600 register_code(KC_SLSH);
601 unregister_code(KC_SLSH);
606 void matrix_init_quantum() {
607 #ifdef BACKLIGHT_ENABLE
608 backlight_init_ports();
613 void matrix_scan_quantum() {
618 #ifdef TAP_DANCE_ENABLE
619 matrix_scan_tap_dance();
626 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
633 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
635 static const uint8_t backlight_pin = BACKLIGHT_PIN;
637 #if BACKLIGHT_PIN == B7
638 # define COM1x1 COM1C1
640 #elif BACKLIGHT_PIN == B6
641 # define COM1x1 COM1B1
643 #elif BACKLIGHT_PIN == B5
644 # define COM1x1 COM1A1
647 # define NO_BACKLIGHT_CLOCK
650 #ifndef BACKLIGHT_ON_STATE
651 #define BACKLIGHT_ON_STATE 0
654 __attribute__ ((weak))
655 void backlight_init_ports(void)
658 // Setup backlight pin as output and output to on state.
660 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
661 #if BACKLIGHT_ON_STATE == 0
663 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
666 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
669 #ifndef NO_BACKLIGHT_CLOCK
670 // Use full 16-bit resolution.
673 // I could write a wall of text here to explain... but TL;DW
674 // Go read the ATmega32u4 datasheet.
675 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
677 // Pin PB7 = OCR1C (Timer 1, Channel C)
678 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
679 // (i.e. start high, go low when counter matches.)
680 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
681 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
683 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
684 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
688 #ifdef BACKLIGHT_BREATHING
689 breathing_defaults();
693 __attribute__ ((weak))
694 void backlight_set(uint8_t level)
696 // Prevent backlight blink on lowest level
697 // #if BACKLIGHT_ON_STATE == 0
699 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
702 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
706 #ifndef NO_BACKLIGHT_CLOCK
707 // Turn off PWM control on backlight pin, revert to output low.
708 TCCR1A &= ~(_BV(COM1x1));
711 // #if BACKLIGHT_ON_STATE == 0
713 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
716 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
720 #ifndef NO_BACKLIGHT_CLOCK
721 else if ( level == BACKLIGHT_LEVELS ) {
722 // Turn on PWM control of backlight pin
723 TCCR1A |= _BV(COM1x1);
724 // Set the brightness
728 // Turn on PWM control of backlight pin
729 TCCR1A |= _BV(COM1x1);
730 // Set the brightness
731 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
735 #ifdef BACKLIGHT_BREATHING
736 breathing_intensity_default();
740 uint8_t backlight_tick = 0;
742 void backlight_task(void) {
743 #ifdef NO_BACKLIGHT_CLOCK
744 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
745 #if BACKLIGHT_ON_STATE == 0
747 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
750 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
753 #if BACKLIGHT_ON_STATE == 0
755 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
758 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
761 backlight_tick = (backlight_tick + 1) % 16;
765 #ifdef BACKLIGHT_BREATHING
767 #define BREATHING_NO_HALT 0
768 #define BREATHING_HALT_OFF 1
769 #define BREATHING_HALT_ON 2
771 static uint8_t breath_intensity;
772 static uint8_t breath_speed;
773 static uint16_t breathing_index;
774 static uint8_t breathing_halt;
776 void breathing_enable(void)
778 if (get_backlight_level() == 0)
784 // Set breathing_index to be at the midpoint (brightest point)
785 breathing_index = 0x20 << breath_speed;
788 breathing_halt = BREATHING_NO_HALT;
790 // Enable breathing interrupt
791 TIMSK1 |= _BV(OCIE1A);
794 void breathing_pulse(void)
796 if (get_backlight_level() == 0)
802 // Set breathing_index to be at the midpoint + 1 (brightest point)
803 breathing_index = 0x21 << breath_speed;
806 breathing_halt = BREATHING_HALT_ON;
808 // Enable breathing interrupt
809 TIMSK1 |= _BV(OCIE1A);
812 void breathing_disable(void)
814 // Disable breathing interrupt
815 TIMSK1 &= ~_BV(OCIE1A);
816 backlight_set(get_backlight_level());
819 void breathing_self_disable(void)
821 if (get_backlight_level() == 0)
823 breathing_halt = BREATHING_HALT_OFF;
827 breathing_halt = BREATHING_HALT_ON;
830 //backlight_set(get_backlight_level());
833 void breathing_toggle(void)
837 if (get_backlight_level() == 0)
843 // Set breathing_index to be at the midpoint + 1 (brightest point)
844 breathing_index = 0x21 << breath_speed;
847 breathing_halt = BREATHING_NO_HALT;
850 // Toggle breathing interrupt
851 TIMSK1 ^= _BV(OCIE1A);
853 // Restore backlight level
856 backlight_set(get_backlight_level());
860 bool is_breathing(void)
862 return (TIMSK1 && _BV(OCIE1A));
865 void breathing_intensity_default(void)
867 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
868 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
871 void breathing_intensity_set(uint8_t value)
873 breath_intensity = value;
876 void breathing_speed_default(void)
881 void breathing_speed_set(uint8_t value)
883 bool is_breathing_now = is_breathing();
884 uint8_t old_breath_speed = breath_speed;
886 if (is_breathing_now)
888 // Disable breathing interrupt
889 TIMSK1 &= ~_BV(OCIE1A);
892 breath_speed = value;
894 if (is_breathing_now)
896 // Adjust index to account for new speed
897 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
899 // Enable breathing interrupt
900 TIMSK1 |= _BV(OCIE1A);
905 void breathing_speed_inc(uint8_t value)
907 if ((uint16_t)(breath_speed - value) > 10 )
909 breathing_speed_set(0);
913 breathing_speed_set(breath_speed - value);
917 void breathing_speed_dec(uint8_t value)
919 if ((uint16_t)(breath_speed + value) > 10 )
921 breathing_speed_set(10);
925 breathing_speed_set(breath_speed + value);
929 void breathing_defaults(void)
931 breathing_intensity_default();
932 breathing_speed_default();
933 breathing_halt = BREATHING_NO_HALT;
936 /* Breathing Sleep LED brighness(PWM On period) table
937 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
939 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
940 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
942 static const uint8_t breathing_table[64] PROGMEM = {
943 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
944 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
945 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
946 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
949 ISR(TIMER1_COMPA_vect)
951 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
954 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
956 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
958 // Disable breathing interrupt
959 TIMSK1 &= ~_BV(OCIE1A);
962 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
972 __attribute__ ((weak))
973 void backlight_init_ports(void)
978 __attribute__ ((weak))
979 void backlight_set(uint8_t level)
987 // Functions for spitting out values
990 void send_dword(uint32_t number) { // this might not actually work
991 uint16_t word = (number >> 16);
993 send_word(number & 0xFFFFUL);
996 void send_word(uint16_t number) {
997 uint8_t byte = number >> 8;
999 send_byte(number & 0xFF);
1002 void send_byte(uint8_t number) {
1003 uint8_t nibble = number >> 4;
1004 send_nibble(nibble);
1005 send_nibble(number & 0xF);
1008 void send_nibble(uint8_t number) {
1011 register_code(KC_0);
1012 unregister_code(KC_0);
1015 register_code(KC_1 + (number - 1));
1016 unregister_code(KC_1 + (number - 1));
1019 register_code(KC_A + (number - 0xA));
1020 unregister_code(KC_A + (number - 0xA));
1026 __attribute__((weak))
1027 uint16_t hex_to_keycode(uint8_t hex)
1031 } else if (hex < 0xA) {
1032 return KC_1 + (hex - 0x1);
1034 return KC_A + (hex - 0xA);
1038 void api_send_unicode(uint32_t unicode) {
1041 dword_to_bytes(unicode, chunk);
1042 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1046 __attribute__ ((weak))
1047 void led_set_user(uint8_t usb_led) {
1051 __attribute__ ((weak))
1052 void led_set_kb(uint8_t usb_led) {
1053 led_set_user(usb_led);
1056 __attribute__ ((weak))
1057 void led_init_ports(void)
1062 __attribute__ ((weak))
1063 void led_set(uint8_t usb_led)
1068 // // Using PE6 Caps Lock LED
1069 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1079 // PORTE &= ~(1<<6);
1082 led_set_kb(usb_led);
1086 //------------------------------------------------------------------------------
1087 // Override these functions in your keymap file to play different tunes on
1088 // different events such as startup and bootloader jump
1090 __attribute__ ((weak))
1091 void startup_user() {}
1093 __attribute__ ((weak))
1094 void shutdown_user() {}
1096 //------------------------------------------------------------------------------