aboutsummaryrefslogtreecommitdiff
path: root/quantum/quantum.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/quantum.c')
-rw-r--r--quantum/quantum.c313
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"
27extern backlight_config_t backlight_config;
28
29#ifdef FAUXCLICKY_ENABLE
30#include "fauxclicky.h"
31#endif
2 32
3static void do_code16 (uint16_t code, void (*f) (uint8_t)) { 33static 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
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
30void register_code16 (uint16_t code) { 82void 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
35void unregister_code16 (uint16_t code) { 91void 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
55void reset_keyboard(void) { 115void 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
77static bool shift_interrupted[2] = {0, 0}; 137static bool shift_interrupted[2] = {0, 0};
138static uint16_t scs_timer = 0;
78 139
79bool process_record_quantum(keyrecord_t *record) { 140bool 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))
520void backlight_init_ports(void) 647void 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))
552void backlight_set(uint8_t level) 686void 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
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}
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
982void 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
988void send_word(uint16_t number) {
989 uint8_t byte = number >> 8;
990 send_byte(byte);
991 send_byte(number & 0xFF);
992}
993
994void send_byte(uint8_t number) {
995 uint8_t nibble = number >> 4;
996 send_nibble(nibble);
997 send_nibble(number & 0xF);
998}
999
1000void 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))
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
1030void 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))
804void led_set_user(uint8_t usb_led) { 1039void led_set_user(uint8_t usb_led) {