diff options
Diffstat (limited to 'quantum/quantum.c')
| -rw-r--r-- | quantum/quantum.c | 262 |
1 files changed, 220 insertions, 42 deletions
diff --git a/quantum/quantum.c b/quantum/quantum.c index 63ffe2074..4f4cee4e9 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
| @@ -1,9 +1,35 @@ | |||
| 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 | ||
| 2 | 21 | ||
| 3 | #ifndef TAPPING_TERM | 22 | #ifndef TAPPING_TERM |
| 4 | #define TAPPING_TERM 200 | 23 | #define TAPPING_TERM 200 |
| 5 | #endif | 24 | #endif |
| 6 | 25 | ||
| 26 | #include "backlight.h" | ||
| 27 | extern backlight_config_t backlight_config; | ||
| 28 | |||
| 29 | #ifdef FAUXCLICKY_ENABLE | ||
| 30 | #include "fauxclicky.h" | ||
| 31 | #endif | ||
| 32 | |||
| 7 | static void do_code16 (uint16_t code, void (*f) (uint8_t)) { | 33 | static void do_code16 (uint16_t code, void (*f) (uint8_t)) { |
| 8 | switch (code) { | 34 | switch (code) { |
| 9 | case QK_MODS ... QK_MODS_MAX: | 35 | case QK_MODS ... QK_MODS_MAX: |
| @@ -33,14 +59,42 @@ static void do_code16 (uint16_t code, void (*f) (uint8_t)) { | |||
| 33 | f(KC_RGUI); | 59 | f(KC_RGUI); |
| 34 | } | 60 | } |
| 35 | 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 | |||
| 36 | void register_code16 (uint16_t code) { | 82 | void register_code16 (uint16_t code) { |
| 37 | 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 | } | ||
| 38 | register_code (code); | 88 | register_code (code); |
| 39 | } | 89 | } |
| 40 | 90 | ||
| 41 | void unregister_code16 (uint16_t code) { | 91 | void unregister_code16 (uint16_t code) { |
| 42 | unregister_code (code); | 92 | unregister_code (code); |
| 43 | 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 | } | ||
| 44 | } | 98 | } |
| 45 | 99 | ||
| 46 | __attribute__ ((weak)) | 100 | __attribute__ ((weak)) |
| @@ -60,8 +114,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
| 60 | 114 | ||
| 61 | void reset_keyboard(void) { | 115 | void reset_keyboard(void) { |
| 62 | clear_keyboard(); | 116 | clear_keyboard(); |
| 63 | #ifdef AUDIO_ENABLE | 117 | #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC)) |
| 64 | stop_all_notes(); | 118 | music_all_notes_off(); |
| 65 | shutdown_user(); | 119 | shutdown_user(); |
| 66 | #endif | 120 | #endif |
| 67 | wait_ms(250); | 121 | wait_ms(250); |
| @@ -81,7 +135,7 @@ void reset_keyboard(void) { | |||
| 81 | #endif | 135 | #endif |
| 82 | 136 | ||
| 83 | static bool shift_interrupted[2] = {0, 0}; | 137 | static bool shift_interrupted[2] = {0, 0}; |
| 84 | static uint16_t scs_timer = 0; | 138 | static uint16_t scs_timer[2] = {0, 0}; |
| 85 | 139 | ||
| 86 | bool process_record_quantum(keyrecord_t *record) { | 140 | bool process_record_quantum(keyrecord_t *record) { |
| 87 | 141 | ||
| @@ -115,10 +169,13 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 115 | 169 | ||
| 116 | if (!( | 170 | if (!( |
| 117 | process_record_kb(keycode, record) && | 171 | process_record_kb(keycode, record) && |
| 118 | #ifdef MIDI_ENABLE | 172 | #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) |
| 119 | process_midi(keycode, record) && | 173 | process_midi(keycode, record) && |
| 120 | #endif | 174 | #endif |
| 121 | #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)) | ||
| 122 | process_music(keycode, record) && | 179 | process_music(keycode, record) && |
| 123 | #endif | 180 | #endif |
| 124 | #ifdef TAP_DANCE_ENABLE | 181 | #ifdef TAP_DANCE_ENABLE |
| @@ -130,6 +187,9 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 130 | #ifndef DISABLE_CHORDING | 187 | #ifndef DISABLE_CHORDING |
| 131 | process_chording(keycode, record) && | 188 | process_chording(keycode, record) && |
| 132 | #endif | 189 | #endif |
| 190 | #ifdef COMBO_ENABLE | ||
| 191 | process_combo(keycode, record) && | ||
| 192 | #endif | ||
| 133 | #ifdef UNICODE_ENABLE | 193 | #ifdef UNICODE_ENABLE |
| 134 | process_unicode(keycode, record) && | 194 | process_unicode(keycode, record) && |
| 135 | #endif | 195 | #endif |
| @@ -162,6 +222,26 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 162 | } | 222 | } |
| 163 | return false; | 223 | return false; |
| 164 | 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 | ||
| 165 | #ifdef RGBLIGHT_ENABLE | 245 | #ifdef RGBLIGHT_ENABLE |
| 166 | case RGB_TOG: | 246 | case RGB_TOG: |
| 167 | if (record->event.pressed) { | 247 | if (record->event.pressed) { |
| @@ -212,6 +292,28 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 212 | return false; | 292 | return false; |
| 213 | break; | 293 | break; |
| 214 | #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 | ||
| 215 | case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: | 317 | case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO: |
| 216 | if (record->event.pressed) { | 318 | if (record->event.pressed) { |
| 217 | // MAGIC actions (BOOTMAGIC without the boot) | 319 | // MAGIC actions (BOOTMAGIC without the boot) |
| @@ -293,7 +395,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 293 | case KC_LSPO: { | 395 | case KC_LSPO: { |
| 294 | if (record->event.pressed) { | 396 | if (record->event.pressed) { |
| 295 | shift_interrupted[0] = false; | 397 | shift_interrupted[0] = false; |
| 296 | scs_timer = timer_read (); | 398 | scs_timer[0] = timer_read (); |
| 297 | register_mods(MOD_BIT(KC_LSFT)); | 399 | register_mods(MOD_BIT(KC_LSFT)); |
| 298 | } | 400 | } |
| 299 | else { | 401 | else { |
| @@ -303,7 +405,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 303 | shift_interrupted[1] = true; | 405 | shift_interrupted[1] = true; |
| 304 | } | 406 | } |
| 305 | #endif | 407 | #endif |
| 306 | if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) { | 408 | if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) { |
| 307 | register_code(LSPO_KEY); | 409 | register_code(LSPO_KEY); |
| 308 | unregister_code(LSPO_KEY); | 410 | unregister_code(LSPO_KEY); |
| 309 | } | 411 | } |
| @@ -316,7 +418,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 316 | case KC_RSPC: { | 418 | case KC_RSPC: { |
| 317 | if (record->event.pressed) { | 419 | if (record->event.pressed) { |
| 318 | shift_interrupted[1] = false; | 420 | shift_interrupted[1] = false; |
| 319 | scs_timer = timer_read (); | 421 | scs_timer[1] = timer_read (); |
| 320 | register_mods(MOD_BIT(KC_RSFT)); | 422 | register_mods(MOD_BIT(KC_RSFT)); |
| 321 | } | 423 | } |
| 322 | else { | 424 | else { |
| @@ -326,7 +428,7 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 326 | shift_interrupted[1] = true; | 428 | shift_interrupted[1] = true; |
| 327 | } | 429 | } |
| 328 | #endif | 430 | #endif |
| 329 | if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) { | 431 | if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) { |
| 330 | register_code(RSPC_KEY); | 432 | register_code(RSPC_KEY); |
| 331 | unregister_code(RSPC_KEY); | 433 | unregister_code(RSPC_KEY); |
| 332 | } | 434 | } |
| @@ -508,6 +610,15 @@ void matrix_scan_quantum() { | |||
| 508 | #ifdef TAP_DANCE_ENABLE | 610 | #ifdef TAP_DANCE_ENABLE |
| 509 | matrix_scan_tap_dance(); | 611 | matrix_scan_tap_dance(); |
| 510 | #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 | |||
| 511 | matrix_scan_kb(); | 622 | matrix_scan_kb(); |
| 512 | } | 623 | } |
| 513 | 624 | ||
| @@ -525,34 +636,45 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN; | |||
| 525 | # define COM1x1 COM1A1 | 636 | # define COM1x1 COM1A1 |
| 526 | # define OCR1x OCR1A | 637 | # define OCR1x OCR1A |
| 527 | #else | 638 | #else |
| 528 | # 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 | ||
| 529 | #endif | 644 | #endif |
| 530 | 645 | ||
| 531 | __attribute__ ((weak)) | 646 | __attribute__ ((weak)) |
| 532 | void backlight_init_ports(void) | 647 | void backlight_init_ports(void) |
| 533 | { | 648 | { |
| 534 | 649 | ||
| 535 | // Setup backlight pin as output and output low. | 650 | // Setup backlight pin as output and output to on state. |
| 536 | // DDRx |= n | 651 | // DDRx |= n |
| 537 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); | 652 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); |
| 538 | // PORTx &= ~n | 653 | #if BACKLIGHT_ON_STATE == 0 |
| 539 | _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 | ||
| 540 | 660 | ||
| 541 | // Use full 16-bit resolution. | 661 | #ifndef NO_BACKLIGHT_CLOCK |
| 542 | ICR1 = 0xFFFF; | 662 | // Use full 16-bit resolution. |
| 663 | ICR1 = 0xFFFF; | ||
| 543 | 664 | ||
| 544 | // 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 |
| 545 | // Go read the ATmega32u4 datasheet. | 666 | // Go read the ATmega32u4 datasheet. |
| 546 | // 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 |
| 547 | 668 | ||
| 548 | // Pin PB7 = OCR1C (Timer 1, Channel C) | 669 | // Pin PB7 = OCR1C (Timer 1, Channel C) |
| 549 | // 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 |
| 550 | // (i.e. start high, go low when counter matches.) | 671 | // (i.e. start high, go low when counter matches.) |
| 551 | // 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 |
| 552 | // 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 |
| 553 | 674 | ||
| 554 | TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; | 675 | TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; |
| 555 | TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; | 676 | TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; |
| 677 | #endif | ||
| 556 | 678 | ||
| 557 | backlight_init(); | 679 | backlight_init(); |
| 558 | #ifdef BACKLIGHT_BREATHING | 680 | #ifdef BACKLIGHT_BREATHING |
| @@ -564,30 +686,73 @@ __attribute__ ((weak)) | |||
| 564 | void backlight_set(uint8_t level) | 686 | void backlight_set(uint8_t level) |
| 565 | { | 687 | { |
| 566 | // Prevent backlight blink on lowest level | 688 | // Prevent backlight blink on lowest level |
| 567 | // PORTx &= ~n | 689 | // #if BACKLIGHT_ON_STATE == 0 |
| 568 | _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 | ||
| 569 | 696 | ||
| 570 | if ( level == 0 ) { | 697 | if ( level == 0 ) { |
| 571 | // Turn off PWM control on backlight pin, revert to output low. | 698 | #ifndef NO_BACKLIGHT_CLOCK |
| 572 | TCCR1A &= ~(_BV(COM1x1)); | 699 | // Turn off PWM control on backlight pin, revert to output low. |
| 573 | OCR1x = 0x0; | 700 | TCCR1A &= ~(_BV(COM1x1)); |
| 574 | } else if ( level == BACKLIGHT_LEVELS ) { | 701 | OCR1x = 0x0; |
| 575 | // Turn on PWM control of backlight pin | 702 | #else |
| 576 | TCCR1A |= _BV(COM1x1); | 703 | // #if BACKLIGHT_ON_STATE == 0 |
| 577 | // Set the brightness | 704 | // // PORTx |= n |
| 578 | OCR1x = 0xFFFF; | 705 | // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); |
| 579 | } else { | 706 | // #else |
| 580 | // Turn on PWM control of backlight pin | 707 | // // PORTx &= ~n |
| 581 | TCCR1A |= _BV(COM1x1); | 708 | // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); |
| 582 | // Set the brightness | 709 | // #endif |
| 583 | OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); | 710 | #endif |
| 584 | } | 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 | ||
| 585 | 726 | ||
| 586 | #ifdef BACKLIGHT_BREATHING | 727 | #ifdef BACKLIGHT_BREATHING |
| 587 | breathing_intensity_default(); | 728 | breathing_intensity_default(); |
| 588 | #endif | 729 | #endif |
| 589 | } | 730 | } |
| 590 | 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 | } | ||
| 591 | 756 | ||
| 592 | #ifdef BACKLIGHT_BREATHING | 757 | #ifdef BACKLIGHT_BREATHING |
| 593 | 758 | ||
| @@ -849,6 +1014,19 @@ void send_nibble(uint8_t number) { | |||
| 849 | } | 1014 | } |
| 850 | } | 1015 | } |
| 851 | 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 | |||
| 852 | void api_send_unicode(uint32_t unicode) { | 1030 | void api_send_unicode(uint32_t unicode) { |
| 853 | #ifdef API_ENABLE | 1031 | #ifdef API_ENABLE |
| 854 | uint8_t chunk[4]; | 1032 | uint8_t chunk[4]; |
