aboutsummaryrefslogtreecommitdiff
path: root/quantum/quantum.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/quantum.c')
-rw-r--r--quantum/quantum.c262
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"
27extern backlight_config_t backlight_config;
28
29#ifdef FAUXCLICKY_ENABLE
30#include "fauxclicky.h"
31#endif
32
7static void do_code16 (uint16_t code, void (*f) (uint8_t)) { 33static 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
62static inline void qk_register_weak_mods(uint8_t kc) {
63 add_weak_mods(MOD_BIT(kc));
64 send_keyboard_report();
65}
66
67static inline void qk_unregister_weak_mods(uint8_t kc) {
68 del_weak_mods(MOD_BIT(kc));
69 send_keyboard_report();
70}
71
72static inline void qk_register_mods(uint8_t kc) {
73 add_weak_mods(MOD_BIT(kc));
74 send_keyboard_report();
75}
76
77static inline void qk_unregister_mods(uint8_t kc) {
78 del_weak_mods(MOD_BIT(kc));
79 send_keyboard_report();
80}
81
36void register_code16 (uint16_t code) { 82void 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
41void unregister_code16 (uint16_t code) { 91void 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
61void reset_keyboard(void) { 115void 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
83static bool shift_interrupted[2] = {0, 0}; 137static bool shift_interrupted[2] = {0, 0};
84static uint16_t scs_timer = 0; 138static uint16_t scs_timer[2] = {0, 0};
85 139
86bool process_record_quantum(keyrecord_t *record) { 140bool 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))
532void backlight_init_ports(void) 647void 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))
564void backlight_set(uint8_t level) 686void 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
732uint8_t backlight_tick = 0;
733
734void 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))
1019uint16_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
852void api_send_unicode(uint32_t unicode) { 1030void api_send_unicode(uint32_t unicode) {
853#ifdef API_ENABLE 1031#ifdef API_ENABLE
854 uint8_t chunk[4]; 1032 uint8_t chunk[4];