diff options
Diffstat (limited to 'quantum/quantum.c')
| -rw-r--r-- | quantum/quantum.c | 313 |
1 files changed, 274 insertions, 39 deletions
diff --git a/quantum/quantum.c b/quantum/quantum.c index 098312e6e..62d9ef923 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
| @@ -1,4 +1,34 @@ | |||
| 1 | /* Copyright 2016-2017 Jack Humbert | ||
| 2 | * | ||
| 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. | ||
| 7 | * | ||
| 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. | ||
| 12 | * | ||
| 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/>. | ||
| 15 | */ | ||
| 16 | |||
| 1 | #include "quantum.h" | 17 | #include "quantum.h" |
| 18 | #ifdef PROTOCOL_LUFA | ||
| 19 | #include "outputselect.h" | ||
| 20 | #endif | ||
| 21 | |||
| 22 | #ifndef TAPPING_TERM | ||
| 23 | #define TAPPING_TERM 200 | ||
| 24 | #endif | ||
| 25 | |||
| 26 | #include "backlight.h" | ||
| 27 | extern backlight_config_t backlight_config; | ||
| 28 | |||
| 29 | #ifdef FAUXCLICKY_ENABLE | ||
| 30 | #include "fauxclicky.h" | ||
| 31 | #endif | ||
| 2 | 32 | ||
| 3 | static void do_code16 (uint16_t code, void (*f) (uint8_t)) { | 33 | static void do_code16 (uint16_t code, void (*f) (uint8_t)) { |
| 4 | switch (code) { | 34 | switch (code) { |
| @@ -17,6 +47,8 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { | |||
| 17 | if (code & QK_LGUI) | 47 | if (code & QK_LGUI) |
| 18 | f(KC_LGUI); | 48 | f(KC_LGUI); |
| 19 | 49 | ||
| 50 | if (code < QK_RMODS_MIN) return; | ||
| 51 | |||
| 20 | if (code & QK_RCTL) | 52 | if (code & QK_RCTL) |
| 21 | f(KC_RCTL); | 53 | f(KC_RCTL); |
| 22 | if (code & QK_RSFT) | 54 | if (code & QK_RSFT) |
| @@ -27,14 +59,42 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { | |||
| 27 | f(KC_RGUI); | 59 | f(KC_RGUI); |
| 28 | } | 60 | } |
| 29 | 61 | ||
| 62 | static inline void qk_register_weak_mods(uint8_t kc) { | ||
| 63 | add_weak_mods(MOD_BIT(kc)); | ||
| 64 | send_keyboard_report(); | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline void qk_unregister_weak_mods(uint8_t kc) { | ||
| 68 | del_weak_mods(MOD_BIT(kc)); | ||
| 69 | send_keyboard_report(); | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline void qk_register_mods(uint8_t kc) { | ||
| 73 | add_weak_mods(MOD_BIT(kc)); | ||
| 74 | send_keyboard_report(); | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline void qk_unregister_mods(uint8_t kc) { | ||
| 78 | del_weak_mods(MOD_BIT(kc)); | ||
| 79 | send_keyboard_report(); | ||
| 80 | } | ||
| 81 | |||
| 30 | void register_code16 (uint16_t code) { | 82 | void register_code16 (uint16_t code) { |
| 31 | do_code16 (code, register_code); | 83 | if (IS_MOD(code) || code == KC_NO) { |
| 84 | do_code16 (code, qk_register_mods); | ||
| 85 | } else { | ||
| 86 | do_code16 (code, qk_register_weak_mods); | ||
| 87 | } | ||
| 32 | register_code (code); | 88 | register_code (code); |
| 33 | } | 89 | } |
| 34 | 90 | ||
| 35 | void unregister_code16 (uint16_t code) { | 91 | void unregister_code16 (uint16_t code) { |
| 36 | unregister_code (code); | 92 | unregister_code (code); |
| 37 | do_code16 (code, unregister_code); | 93 | if (IS_MOD(code) || code == KC_NO) { |
| 94 | do_code16 (code, qk_unregister_mods); | ||
| 95 | } else { | ||
| 96 | do_code16 (code, qk_unregister_weak_mods); | ||
| 97 | } | ||
| 38 | } | 98 | } |
| 39 | 99 | ||
| 40 | __attribute__ ((weak)) | 100 | __attribute__ ((weak)) |
| @@ -54,8 +114,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
| 54 | 114 | ||
| 55 | void reset_keyboard(void) { | 115 | void reset_keyboard(void) { |
| 56 | clear_keyboard(); | 116 | clear_keyboard(); |
| 57 | #ifdef AUDIO_ENABLE | 117 | #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC)) |
| 58 | stop_all_notes(); | 118 | music_all_notes_off(); |
| 59 | shutdown_user(); | 119 | shutdown_user(); |
| 60 | #endif | 120 | #endif |
| 61 | wait_ms(250); | 121 | wait_ms(250); |
| @@ -75,6 +135,7 @@ void reset_keyboard(void) { | |||
| 75 | #endif | 135 | #endif |
| 76 | 136 | ||
| 77 | static bool shift_interrupted[2] = {0, 0}; | 137 | static bool shift_interrupted[2] = {0, 0}; |
| 138 | static uint16_t scs_timer = 0; | ||
| 78 | 139 | ||
| 79 | bool process_record_quantum(keyrecord_t *record) { | 140 | bool process_record_quantum(keyrecord_t *record) { |
| 80 | 141 | ||
| @@ -108,10 +169,13 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 108 | 169 | ||
| 109 | if (!( | 170 | if (!( |
| 110 | process_record_kb(keycode, record) && | 171 | process_record_kb(keycode, record) && |
| 111 | #ifdef MIDI_ENABLE | 172 | #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) |
| 112 | process_midi(keycode, record) && | 173 | process_midi(keycode, record) && |
| 113 | #endif | 174 | #endif |
| 114 | #ifdef AUDIO_ENABLE | 175 | #ifdef AUDIO_ENABLE |
| 176 | process_audio(keycode, record) && | ||
| 177 | #endif | ||
| 178 | #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) | ||
| 115 | process_music(keycode, record) && | 179 | process_music(keycode, record) && |
| 116 | #endif | 180 | #endif |
| 117 | #ifdef TAP_DANCE_ENABLE | 181 | #ifdef TAP_DANCE_ENABLE |
| @@ -123,12 +187,18 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 123 | #ifndef DISABLE_CHORDING | 187 | #ifndef DISABLE_CHORDING |
| 124 | process_chording(keycode, record) && | 188 | process_chording(keycode, record) && |
| 125 | #endif | 189 | #endif |
| 190 | #ifdef COMBO_ENABLE | ||
| 191 | process_combo(keycode, record) && | ||
| 192 | #endif | ||
| 126 | #ifdef UNICODE_ENABLE | 193 | #ifdef UNICODE_ENABLE |
| 127 | process_unicode(keycode, record) && | 194 | process_unicode(keycode, record) && |
| 128 | #endif | 195 | #endif |
| 129 | #ifdef UCIS_ENABLE | 196 | #ifdef UCIS_ENABLE |
| 130 | process_ucis(keycode, record) && | 197 | process_ucis(keycode, record) && |
| 131 | #endif | 198 | #endif |
| 199 | #ifdef PRINTING_ENABLE | ||
| 200 | process_printer(keycode, record) && | ||
| 201 | #endif | ||
| 132 | #ifdef UNICODEMAP_ENABLE | 202 | #ifdef UNICODEMAP_ENABLE |
| 133 | process_unicode_map(keycode, record) && | 203 | process_unicode_map(keycode, record) && |
| 134 | #endif | 204 | #endif |
| @@ -152,6 +222,26 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 152 | } | 222 | } |
| 153 | return false; | 223 | return false; |
| 154 | break; | 224 | break; |
| 225 | #ifdef FAUXCLICKY_ENABLE | ||
| 226 | case FC_TOG: | ||
| 227 | if (record->event.pressed) { | ||
| 228 | FAUXCLICKY_TOGGLE; | ||
| 229 | } | ||
| 230 | return false; | ||
| 231 | break; | ||
| 232 | case FC_ON: | ||
| 233 | if (record->event.pressed) { | ||
| 234 | FAUXCLICKY_ON; | ||
| 235 | } | ||
| 236 | return false; | ||
| 237 | break; | ||
| 238 | case FC_OFF: | ||
| 239 | if (record->event.pressed) { | ||
| 240 | FAUXCLICKY_OFF; | ||
| 241 | } | ||
| 242 | return false; | ||
| 243 | break; | ||
| 244 | #endif | ||
| 155 | #ifdef RGBLIGHT_ENABLE | 245 | #ifdef RGBLIGHT_ENABLE |
| 156 | case RGB_TOG: | 246 | case RGB_TOG: |
| 157 | if (record->event.pressed) { | 247 | if (record->event.pressed) { |
| @@ -202,6 +292,28 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 202 | return false; | 292 | return false; |
| 203 | break; | 293 | break; |
| 204 | #endif | 294 | #endif |
| 295 | #ifdef PROTOCOL_LUFA | ||
| 296 | case OUT_AUTO: | ||
| 297 | if (record->event.pressed) { | ||
| 298 | set_output(OUTPUT_AUTO); | ||
| 299 | } | ||
| 300 | return false; | ||
| 301 | break; | ||
| 302 | case OUT_USB: | ||
| 303 | if (record->event.pressed) { | ||
| 304 | set_output(OUTPUT_USB); | ||
| 305 | } | ||
| 306 | return false; | ||
| 307 | break; | ||
| 308 | #ifdef BLUETOOTH_ENABLE | ||
| 309 | case OUT_BT: | ||
| 310 | if (record->event.pressed) { | ||
| 311 | set_output(OUTPUT_BLUETOOTH); | ||
| 312 | } | ||
| 313 | return false; | ||
| 314 | break; | ||
| 315 | #endif | ||
| 316 | #endif | ||
| 205 | case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: | 317 | case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: |
| 206 | if (record->event.pressed) { | 318 | if (record->event.pressed) { |
| 207 | // MAGIC actions (BOOTMAGIC without the boot) | 319 | // MAGIC actions (BOOTMAGIC without the boot) |
| @@ -283,6 +395,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 283 | case KC_LSPO: { | 395 | case KC_LSPO: { |
| 284 | if (record->event.pressed) { | 396 | if (record->event.pressed) { |
| 285 | shift_interrupted[0] = false; | 397 | shift_interrupted[0] = false; |
| 398 | scs_timer = timer_read (); | ||
| 286 | register_mods(MOD_BIT(KC_LSFT)); | 399 | register_mods(MOD_BIT(KC_LSFT)); |
| 287 | } | 400 | } |
| 288 | else { | 401 | else { |
| @@ -292,7 +405,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 292 | shift_interrupted[1] = true; | 405 | shift_interrupted[1] = true; |
| 293 | } | 406 | } |
| 294 | #endif | 407 | #endif |
| 295 | if (!shift_interrupted[0]) { | 408 | if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) { |
| 296 | register_code(LSPO_KEY); | 409 | register_code(LSPO_KEY); |
| 297 | unregister_code(LSPO_KEY); | 410 | unregister_code(LSPO_KEY); |
| 298 | } | 411 | } |
| @@ -305,6 +418,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 305 | case KC_RSPC: { | 418 | case KC_RSPC: { |
| 306 | if (record->event.pressed) { | 419 | if (record->event.pressed) { |
| 307 | shift_interrupted[1] = false; | 420 | shift_interrupted[1] = false; |
| 421 | scs_timer = timer_read (); | ||
| 308 | register_mods(MOD_BIT(KC_RSFT)); | 422 | register_mods(MOD_BIT(KC_RSFT)); |
| 309 | } | 423 | } |
| 310 | else { | 424 | else { |
| @@ -314,7 +428,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 314 | shift_interrupted[1] = true; | 428 | shift_interrupted[1] = true; |
| 315 | } | 429 | } |
| 316 | #endif | 430 | #endif |
| 317 | if (!shift_interrupted[1]) { | 431 | if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) { |
| 318 | register_code(RSPC_KEY); | 432 | register_code(RSPC_KEY); |
| 319 | unregister_code(RSPC_KEY); | 433 | unregister_code(RSPC_KEY); |
| 320 | } | 434 | } |
| @@ -496,6 +610,15 @@ void matrix_scan_quantum() { | |||
| 496 | #ifdef TAP_DANCE_ENABLE | 610 | #ifdef TAP_DANCE_ENABLE |
| 497 | matrix_scan_tap_dance(); | 611 | matrix_scan_tap_dance(); |
| 498 | #endif | 612 | #endif |
| 613 | |||
| 614 | #ifdef COMBO_ENABLE | ||
| 615 | matrix_scan_combo(); | ||
| 616 | #endif | ||
| 617 | |||
| 618 | #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN) | ||
| 619 | backlight_task(); | ||
| 620 | #endif | ||
| 621 | |||
| 499 | matrix_scan_kb(); | 622 | matrix_scan_kb(); |
| 500 | } | 623 | } |
| 501 | 624 | ||
| @@ -513,34 +636,45 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN; | |||
| 513 | # define COM1x1 COM1A1 | 636 | # define COM1x1 COM1A1 |
| 514 | # define OCR1x OCR1A | 637 | # define OCR1x OCR1A |
| 515 | #else | 638 | #else |
| 516 | # error "Backlight pin not supported - use B5, B6, or B7" | 639 | # define NO_BACKLIGHT_CLOCK |
| 640 | #endif | ||
| 641 | |||
| 642 | #ifndef BACKLIGHT_ON_STATE | ||
| 643 | #define BACKLIGHT_ON_STATE 0 | ||
| 517 | #endif | 644 | #endif |
| 518 | 645 | ||
| 519 | __attribute__ ((weak)) | 646 | __attribute__ ((weak)) |
| 520 | void backlight_init_ports(void) | 647 | void backlight_init_ports(void) |
| 521 | { | 648 | { |
| 522 | 649 | ||
| 523 | // Setup backlight pin as output and output low. | 650 | // Setup backlight pin as output and output to on state. |
| 524 | // DDRx |= n | 651 | // DDRx |= n |
| 525 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); | 652 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); |
| 526 | // PORTx &= ~n | 653 | #if BACKLIGHT_ON_STATE == 0 |
| 527 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | 654 | // PORTx &= ~n |
| 655 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | ||
| 656 | #else | ||
| 657 | // PORTx |= n | ||
| 658 | _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | ||
| 659 | #endif | ||
| 528 | 660 | ||
| 529 | // Use full 16-bit resolution. | 661 | #ifndef NO_BACKLIGHT_CLOCK |
| 530 | ICR1 = 0xFFFF; | 662 | // Use full 16-bit resolution. |
| 663 | ICR1 = 0xFFFF; | ||
| 531 | 664 | ||
| 532 | // I could write a wall of text here to explain... but TL;DW | 665 | // I could write a wall of text here to explain... but TL;DW |
| 533 | // Go read the ATmega32u4 datasheet. | 666 | // Go read the ATmega32u4 datasheet. |
| 534 | // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on | 667 | // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on |
| 535 | 668 | ||
| 536 | // Pin PB7 = OCR1C (Timer 1, Channel C) | 669 | // Pin PB7 = OCR1C (Timer 1, Channel C) |
| 537 | // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 | 670 | // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 |
| 538 | // (i.e. start high, go low when counter matches.) | 671 | // (i.e. start high, go low when counter matches.) |
| 539 | // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 | 672 | // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 |
| 540 | // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 | 673 | // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 |
| 541 | 674 | ||
| 542 | TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; | 675 | TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; |
| 543 | TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; | 676 | TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; |
| 677 | #endif | ||
| 544 | 678 | ||
| 545 | backlight_init(); | 679 | backlight_init(); |
| 546 | #ifdef BACKLIGHT_BREATHING | 680 | #ifdef BACKLIGHT_BREATHING |
| @@ -552,30 +686,73 @@ __attribute__ ((weak)) | |||
| 552 | void backlight_set(uint8_t level) | 686 | void backlight_set(uint8_t level) |
| 553 | { | 687 | { |
| 554 | // Prevent backlight blink on lowest level | 688 | // Prevent backlight blink on lowest level |
| 555 | // PORTx &= ~n | 689 | // #if BACKLIGHT_ON_STATE == 0 |
| 556 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | 690 | // // PORTx &= ~n |
| 691 | // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | ||
| 692 | // #else | ||
| 693 | // // PORTx |= n | ||
| 694 | // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | ||
| 695 | // #endif | ||
| 557 | 696 | ||
| 558 | if ( level == 0 ) { | 697 | if ( level == 0 ) { |
| 559 | // Turn off PWM control on backlight pin, revert to output low. | 698 | #ifndef NO_BACKLIGHT_CLOCK |
| 560 | TCCR1A &= ~(_BV(COM1x1)); | 699 | // Turn off PWM control on backlight pin, revert to output low. |
| 561 | OCR1x = 0x0; | 700 | TCCR1A &= ~(_BV(COM1x1)); |
| 562 | } else if ( level == BACKLIGHT_LEVELS ) { | 701 | OCR1x = 0x0; |
| 563 | // Turn on PWM control of backlight pin | 702 | #else |
| 564 | TCCR1A |= _BV(COM1x1); | 703 | // #if BACKLIGHT_ON_STATE == 0 |
| 565 | // Set the brightness | 704 | // // PORTx |= n |
| 566 | OCR1x = 0xFFFF; | 705 | // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); |
| 567 | } else { | 706 | // #else |
| 568 | // Turn on PWM control of backlight pin | 707 | // // PORTx &= ~n |
| 569 | TCCR1A |= _BV(COM1x1); | 708 | // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); |
| 570 | // Set the brightness | 709 | // #endif |
| 571 | OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); | 710 | #endif |
| 572 | } | 711 | } |
| 712 | #ifndef NO_BACKLIGHT_CLOCK | ||
| 713 | else if ( level == BACKLIGHT_LEVELS ) { | ||
| 714 | // Turn on PWM control of backlight pin | ||
| 715 | TCCR1A |= _BV(COM1x1); | ||
| 716 | // Set the brightness | ||
| 717 | OCR1x = 0xFFFF; | ||
| 718 | } | ||
| 719 | else { | ||
| 720 | // Turn on PWM control of backlight pin | ||
| 721 | TCCR1A |= _BV(COM1x1); | ||
| 722 | // Set the brightness | ||
| 723 | OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); | ||
| 724 | } | ||
| 725 | #endif | ||
| 573 | 726 | ||
| 574 | #ifdef BACKLIGHT_BREATHING | 727 | #ifdef BACKLIGHT_BREATHING |
| 575 | breathing_intensity_default(); | 728 | breathing_intensity_default(); |
| 576 | #endif | 729 | #endif |
| 577 | } | 730 | } |
| 578 | 731 | ||
| 732 | uint8_t backlight_tick = 0; | ||
| 733 | |||
| 734 | void backlight_task(void) { | ||
| 735 | #ifdef NO_BACKLIGHT_CLOCK | ||
| 736 | if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { | ||
| 737 | #if BACKLIGHT_ON_STATE == 0 | ||
| 738 | // PORTx &= ~n | ||
| 739 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | ||
| 740 | #else | ||
| 741 | // PORTx |= n | ||
| 742 | _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | ||
| 743 | #endif | ||
| 744 | } else { | ||
| 745 | #if BACKLIGHT_ON_STATE == 0 | ||
| 746 | // PORTx |= n | ||
| 747 | _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | ||
| 748 | #else | ||
| 749 | // PORTx &= ~n | ||
| 750 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | ||
| 751 | #endif | ||
| 752 | } | ||
| 753 | backlight_tick = (backlight_tick + 1) % 16; | ||
| 754 | #endif | ||
| 755 | } | ||
| 579 | 756 | ||
| 580 | #ifdef BACKLIGHT_BREATHING | 757 | #ifdef BACKLIGHT_BREATHING |
| 581 | 758 | ||
| @@ -799,6 +976,64 @@ void backlight_set(uint8_t level) | |||
| 799 | #endif // backlight | 976 | #endif // backlight |
| 800 | 977 | ||
| 801 | 978 | ||
| 979 | // Functions for spitting out values | ||
| 980 | // | ||
| 981 | |||
| 982 | void send_dword(uint32_t number) { // this might not actually work | ||
| 983 | uint16_t word = (number >> 16); | ||
| 984 | send_word(word); | ||
| 985 | send_word(number & 0xFFFFUL); | ||
| 986 | } | ||
| 987 | |||
| 988 | void send_word(uint16_t number) { | ||
| 989 | uint8_t byte = number >> 8; | ||
| 990 | send_byte(byte); | ||
| 991 | send_byte(number & 0xFF); | ||
| 992 | } | ||
| 993 | |||
| 994 | void send_byte(uint8_t number) { | ||
| 995 | uint8_t nibble = number >> 4; | ||
| 996 | send_nibble(nibble); | ||
| 997 | send_nibble(number & 0xF); | ||
| 998 | } | ||
| 999 | |||
| 1000 | void send_nibble(uint8_t number) { | ||
| 1001 | switch (number) { | ||
| 1002 | case 0: | ||
| 1003 | register_code(KC_0); | ||
| 1004 | unregister_code(KC_0); | ||
| 1005 | break; | ||
| 1006 | case 1 ... 9: | ||
| 1007 | register_code(KC_1 + (number - 1)); | ||
| 1008 | unregister_code(KC_1 + (number - 1)); | ||
| 1009 | break; | ||
| 1010 | case 0xA ... 0xF: | ||
| 1011 | register_code(KC_A + (number - 0xA)); | ||
| 1012 | unregister_code(KC_A + (number - 0xA)); | ||
| 1013 | break; | ||
| 1014 | } | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | |||
| 1018 | __attribute__((weak)) | ||
| 1019 | uint16_t hex_to_keycode(uint8_t hex) | ||
| 1020 | { | ||
| 1021 | if (hex == 0x0) { | ||
| 1022 | return KC_0; | ||
| 1023 | } else if (hex < 0xA) { | ||
| 1024 | return KC_1 + (hex - 0x1); | ||
| 1025 | } else { | ||
| 1026 | return KC_A + (hex - 0xA); | ||
| 1027 | } | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | void api_send_unicode(uint32_t unicode) { | ||
| 1031 | #ifdef API_ENABLE | ||
| 1032 | uint8_t chunk[4]; | ||
| 1033 | dword_to_bytes(unicode, chunk); | ||
| 1034 | MT_SEND_DATA(DT_UNICODE, chunk, 5); | ||
| 1035 | #endif | ||
| 1036 | } | ||
| 802 | 1037 | ||
| 803 | __attribute__ ((weak)) | 1038 | __attribute__ ((weak)) |
| 804 | void led_set_user(uint8_t usb_led) { | 1039 | void led_set_user(uint8_t usb_led) { |
