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 #if defined SENDSTRING_JIS_KEYCODE
459 /* for users with JIS keyboards */
460 const bool ascii_to_shift_lut[0x80] PROGMEM = {
461 0, 0, 0, 0, 0, 0, 0, 0,
462 0, 0, 0, 0, 0, 0, 0, 0,
463 0, 0, 0, 0, 0, 0, 0, 0,
464 0, 0, 0, 0, 0, 0, 0, 0,
465 0, 1, 1, 1, 1, 1, 1, 1,
466 1, 1, 1, 1, 0, 0, 0, 0,
467 0, 0, 0, 0, 0, 0, 0, 0,
468 0, 0, 0, 0, 1, 1, 1, 1,
469 0, 1, 1, 1, 1, 1, 1, 1,
470 1, 1, 1, 1, 1, 1, 1, 1,
471 1, 1, 1, 1, 1, 1, 1, 1,
472 1, 1, 1, 0, 0, 0, 0, 1,
473 1, 0, 0, 0, 0, 0, 0, 0,
474 0, 0, 0, 0, 0, 0, 0, 0,
475 0, 0, 0, 0, 0, 0, 0, 0,
476 0, 0, 0, 1, 1, 1, 1, 0
479 /* for standard keycodes */
480 const bool ascii_to_shift_lut[0x80] PROGMEM = {
481 0, 0, 0, 0, 0, 0, 0, 0,
482 0, 0, 0, 0, 0, 0, 0, 0,
483 0, 0, 0, 0, 0, 0, 0, 0,
484 0, 0, 0, 0, 0, 0, 0, 0,
485 0, 1, 1, 1, 1, 1, 1, 0,
486 1, 1, 1, 1, 0, 0, 0, 0,
487 0, 0, 0, 0, 0, 0, 0, 0,
488 0, 0, 1, 0, 1, 0, 1, 1,
489 1, 1, 1, 1, 1, 1, 1, 1,
490 1, 1, 1, 1, 1, 1, 1, 1,
491 1, 1, 1, 1, 1, 1, 1, 1,
492 1, 1, 1, 0, 0, 0, 1, 1,
493 0, 0, 0, 0, 0, 0, 0, 0,
494 0, 0, 0, 0, 0, 0, 0, 0,
495 0, 0, 0, 0, 0, 0, 0, 0,
496 0, 0, 0, 1, 1, 1, 1, 0
500 #if defined SENDSTRING_JIS_KEYCODE
501 /* for users with JIS keyboards */
502 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
503 0, 0, 0, 0, 0, 0, 0, 0,
504 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
505 0, 0, 0, 0, 0, 0, 0, 0,
506 0, 0, 0, KC_ESC, 0, 0, 0, 0,
507 KC_SPC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
508 KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
509 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
510 KC_8, KC_9, KC_QUOT, KC_SCLN, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
511 KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
512 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
513 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
514 KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_RO,
515 KC_LBRC, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
516 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
517 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
518 KC_X, KC_Y, KC_Z, KC_RBRC, KC_JYEN, KC_BSLS, KC_EQL, KC_DEL,
520 #elif defined SENDSTRING_COLEMAK_KEYCODE
521 /* for users whose OSes are set to Colemak */
522 #include "keymap_colemak.h"
523 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
524 0, 0, 0, 0, 0, 0, 0, 0,
525 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
526 0, 0, 0, 0, 0, 0, 0, 0,
527 0, 0, 0, KC_ESC, 0, 0, 0, 0,
528 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
529 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
530 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
531 KC_8, KC_9, CM_SCLN, CM_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
532 KC_2, 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_6, KC_MINS,
536 KC_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G,
537 CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O,
538 CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W,
539 CM_X, CM_Y, CM_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
541 #elif defined SENDSTRING_DVORAK_KEYCODE
542 /* for users whose OSes are set to Dvorak */
543 #include "keymap_dvorak.h"
544 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
545 0, 0, 0, 0, 0, 0, 0, 0,
546 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
547 0, 0, 0, 0, 0, 0, 0, 0,
548 0, 0, 0, KC_ESC, 0, 0, 0, 0,
549 KC_SPC, DV_1, DV_QUOT, DV_3, DV_4, DV_5, DV_7, DV_QUOT,
550 DV_9, DV_0, DV_8, DV_EQL, DV_COMM, DV_MINS, DV_DOT, DV_SLSH,
551 DV_0, DV_1, DV_2, DV_3, DV_4, DV_5, DV_6, DV_7,
552 DV_8, DV_9, DV_SCLN, DV_SCLN, DV_COMM, DV_EQL, DV_DOT, DV_SLSH,
553 DV_2, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G,
554 DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O,
555 DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W,
556 DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_6, DV_MINS,
557 DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G,
558 DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O,
559 DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W,
560 DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_GRV, KC_DEL
563 /* For users with default keyboard layout in OS */
564 const uint8_t ascii_to_keycode_lut[0x80] PROGMEM = {
565 0, 0, 0, 0, 0, 0, 0, 0,
566 KC_BSPC, KC_TAB, KC_ENT, 0, 0, 0, 0, 0,
567 0, 0, 0, 0, 0, 0, 0, 0,
568 0, 0, 0, KC_ESC, 0, 0, 0, 0,
569 KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT,
570 KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH,
571 KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7,
572 KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH,
573 KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
574 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
575 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
576 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS,
577 KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G,
578 KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O,
579 KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W,
580 KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL
584 void send_string(const char *str) {
585 send_string_with_delay(str, 0);
588 void send_string_with_delay(const char *str, uint8_t interval) {
591 uint8_t ascii_code = pgm_read_byte(str);
592 if (!ascii_code) break;
593 keycode = pgm_read_byte(&ascii_to_keycode_lut[ascii_code]);
594 if (pgm_read_byte(&ascii_to_shift_lut[ascii_code])) {
595 register_code(KC_LSFT);
596 register_code(keycode);
597 unregister_code(keycode);
598 unregister_code(KC_LSFT);
601 register_code(keycode);
602 unregister_code(keycode);
606 { uint8_t ms = interval; while (ms--) wait_ms(1); }
610 void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
611 if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
618 void tap_random_base64(void) {
619 #if defined(__AVR_ATmega32U4__)
620 uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64;
622 uint8_t key = rand() % 64;
626 register_code(KC_LSFT);
627 register_code(key + KC_A);
628 unregister_code(key + KC_A);
629 unregister_code(KC_LSFT);
632 register_code(key - 26 + KC_A);
633 unregister_code(key - 26 + KC_A);
637 unregister_code(KC_0);
640 register_code(key - 53 + KC_1);
641 unregister_code(key - 53 + KC_1);
644 register_code(KC_LSFT);
645 register_code(KC_EQL);
646 unregister_code(KC_EQL);
647 unregister_code(KC_LSFT);
650 register_code(KC_SLSH);
651 unregister_code(KC_SLSH);
656 void matrix_init_quantum() {
657 #ifdef BACKLIGHT_ENABLE
658 backlight_init_ports();
663 void matrix_scan_quantum() {
668 #ifdef TAP_DANCE_ENABLE
669 matrix_scan_tap_dance();
676 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
683 #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
685 static const uint8_t backlight_pin = BACKLIGHT_PIN;
687 #if BACKLIGHT_PIN == B7
688 # define COM1x1 COM1C1
690 #elif BACKLIGHT_PIN == B6
691 # define COM1x1 COM1B1
693 #elif BACKLIGHT_PIN == B5
694 # define COM1x1 COM1A1
697 # define NO_BACKLIGHT_CLOCK
700 #ifndef BACKLIGHT_ON_STATE
701 #define BACKLIGHT_ON_STATE 0
704 __attribute__ ((weak))
705 void backlight_init_ports(void)
708 // Setup backlight pin as output and output to on state.
710 _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF);
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);
719 #ifndef NO_BACKLIGHT_CLOCK
720 // Use full 16-bit resolution.
723 // I could write a wall of text here to explain... but TL;DW
724 // Go read the ATmega32u4 datasheet.
725 // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
727 // Pin PB7 = OCR1C (Timer 1, Channel C)
728 // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
729 // (i.e. start high, go low when counter matches.)
730 // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
731 // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
733 TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010;
734 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
738 #ifdef BACKLIGHT_BREATHING
739 breathing_defaults();
743 __attribute__ ((weak))
744 void backlight_set(uint8_t level)
746 // Prevent backlight blink on lowest level
747 // #if BACKLIGHT_ON_STATE == 0
749 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
752 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
756 #ifndef NO_BACKLIGHT_CLOCK
757 // Turn off PWM control on backlight pin, revert to output low.
758 TCCR1A &= ~(_BV(COM1x1));
761 // #if BACKLIGHT_ON_STATE == 0
763 // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
766 // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
770 #ifndef NO_BACKLIGHT_CLOCK
771 else if ( level == BACKLIGHT_LEVELS ) {
772 // Turn on PWM control of backlight pin
773 TCCR1A |= _BV(COM1x1);
774 // Set the brightness
778 // Turn on PWM control of backlight pin
779 TCCR1A |= _BV(COM1x1);
780 // Set the brightness
781 OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2));
785 #ifdef BACKLIGHT_BREATHING
786 breathing_intensity_default();
790 uint8_t backlight_tick = 0;
792 void backlight_task(void) {
793 #ifdef NO_BACKLIGHT_CLOCK
794 if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) {
795 #if BACKLIGHT_ON_STATE == 0
797 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
800 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
803 #if BACKLIGHT_ON_STATE == 0
805 _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
808 _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
811 backlight_tick = (backlight_tick + 1) % 16;
815 #ifdef BACKLIGHT_BREATHING
817 #define BREATHING_NO_HALT 0
818 #define BREATHING_HALT_OFF 1
819 #define BREATHING_HALT_ON 2
821 static uint8_t breath_intensity;
822 static uint8_t breath_speed;
823 static uint16_t breathing_index;
824 static uint8_t breathing_halt;
826 void breathing_enable(void)
828 if (get_backlight_level() == 0)
834 // Set breathing_index to be at the midpoint (brightest point)
835 breathing_index = 0x20 << breath_speed;
838 breathing_halt = BREATHING_NO_HALT;
840 // Enable breathing interrupt
841 TIMSK1 |= _BV(OCIE1A);
844 void breathing_pulse(void)
846 if (get_backlight_level() == 0)
852 // Set breathing_index to be at the midpoint + 1 (brightest point)
853 breathing_index = 0x21 << breath_speed;
856 breathing_halt = BREATHING_HALT_ON;
858 // Enable breathing interrupt
859 TIMSK1 |= _BV(OCIE1A);
862 void breathing_disable(void)
864 // Disable breathing interrupt
865 TIMSK1 &= ~_BV(OCIE1A);
866 backlight_set(get_backlight_level());
869 void breathing_self_disable(void)
871 if (get_backlight_level() == 0)
873 breathing_halt = BREATHING_HALT_OFF;
877 breathing_halt = BREATHING_HALT_ON;
880 //backlight_set(get_backlight_level());
883 void breathing_toggle(void)
887 if (get_backlight_level() == 0)
893 // Set breathing_index to be at the midpoint + 1 (brightest point)
894 breathing_index = 0x21 << breath_speed;
897 breathing_halt = BREATHING_NO_HALT;
900 // Toggle breathing interrupt
901 TIMSK1 ^= _BV(OCIE1A);
903 // Restore backlight level
906 backlight_set(get_backlight_level());
910 bool is_breathing(void)
912 return (TIMSK1 && _BV(OCIE1A));
915 void breathing_intensity_default(void)
917 //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS);
918 breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2));
921 void breathing_intensity_set(uint8_t value)
923 breath_intensity = value;
926 void breathing_speed_default(void)
931 void breathing_speed_set(uint8_t value)
933 bool is_breathing_now = is_breathing();
934 uint8_t old_breath_speed = breath_speed;
936 if (is_breathing_now)
938 // Disable breathing interrupt
939 TIMSK1 &= ~_BV(OCIE1A);
942 breath_speed = value;
944 if (is_breathing_now)
946 // Adjust index to account for new speed
947 breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed;
949 // Enable breathing interrupt
950 TIMSK1 |= _BV(OCIE1A);
955 void breathing_speed_inc(uint8_t value)
957 if ((uint16_t)(breath_speed - value) > 10 )
959 breathing_speed_set(0);
963 breathing_speed_set(breath_speed - value);
967 void breathing_speed_dec(uint8_t value)
969 if ((uint16_t)(breath_speed + value) > 10 )
971 breathing_speed_set(10);
975 breathing_speed_set(breath_speed + value);
979 void breathing_defaults(void)
981 breathing_intensity_default();
982 breathing_speed_default();
983 breathing_halt = BREATHING_NO_HALT;
986 /* Breathing Sleep LED brighness(PWM On period) table
987 * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
989 * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
990 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
992 static const uint8_t breathing_table[64] PROGMEM = {
993 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
994 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
995 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
996 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
999 ISR(TIMER1_COMPA_vect)
1001 // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity;
1004 uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F;
1006 if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F)))
1008 // Disable breathing interrupt
1009 TIMSK1 &= ~_BV(OCIE1A);
1012 OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity;
1022 __attribute__ ((weak))
1023 void backlight_init_ports(void)
1028 __attribute__ ((weak))
1029 void backlight_set(uint8_t level)
1037 // Functions for spitting out values
1040 void send_dword(uint32_t number) { // this might not actually work
1041 uint16_t word = (number >> 16);
1043 send_word(number & 0xFFFFUL);
1046 void send_word(uint16_t number) {
1047 uint8_t byte = number >> 8;
1049 send_byte(number & 0xFF);
1052 void send_byte(uint8_t number) {
1053 uint8_t nibble = number >> 4;
1054 send_nibble(nibble);
1055 send_nibble(number & 0xF);
1058 void send_nibble(uint8_t number) {
1061 register_code(KC_0);
1062 unregister_code(KC_0);
1065 register_code(KC_1 + (number - 1));
1066 unregister_code(KC_1 + (number - 1));
1069 register_code(KC_A + (number - 0xA));
1070 unregister_code(KC_A + (number - 0xA));
1076 __attribute__((weak))
1077 uint16_t hex_to_keycode(uint8_t hex)
1081 } else if (hex < 0xA) {
1082 return KC_1 + (hex - 0x1);
1084 return KC_A + (hex - 0xA);
1088 void api_send_unicode(uint32_t unicode) {
1091 dword_to_bytes(unicode, chunk);
1092 MT_SEND_DATA(DT_UNICODE, chunk, 5);
1096 __attribute__ ((weak))
1097 void led_set_user(uint8_t usb_led) {
1101 __attribute__ ((weak))
1102 void led_set_kb(uint8_t usb_led) {
1103 led_set_user(usb_led);
1106 __attribute__ ((weak))
1107 void led_init_ports(void)
1112 __attribute__ ((weak))
1113 void led_set(uint8_t usb_led)
1118 // // Using PE6 Caps Lock LED
1119 // if (usb_led & (1<<USB_LED_CAPS_LOCK))
1129 // PORTE &= ~(1<<6);
1132 led_set_kb(usb_led);
1136 //------------------------------------------------------------------------------
1137 // Override these functions in your keymap file to play different tunes on
1138 // different events such as startup and bootloader jump
1140 __attribute__ ((weak))
1141 void startup_user() {}
1143 __attribute__ ((weak))
1144 void shutdown_user() {}
1146 //------------------------------------------------------------------------------