aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
authorErez Zukerman <bulk@ezuk.org>2016-05-15 00:27:32 -0400
committerJack Humbert <jack.humb@gmail.com>2016-05-15 00:27:32 -0400
commit1a8c0dd22d6a2255511d0db6a456315541b5815b (patch)
tree6c7d5e9dc66f9ce864cfe87a72dfb47e6f06d3a7 /quantum
parent79d26f331a275c99f76a30d34752fbd65bb3f335 (diff)
downloadqmk_firmware-1a8c0dd22d6a2255511d0db6a456315541b5815b.tar.gz
qmk_firmware-1a8c0dd22d6a2255511d0db6a456315541b5815b.zip
Leader key implementation (#326)
* implements leader key for planck experimental * allows override of leader timeout * adds ability to use the leader key in seq * fixes leader keycode * adds chording prototype * fixes keycode detection * moves music mode to quantum.c * disables chording by default * updates process_action functions to return bool
Diffstat (limited to 'quantum')
-rw-r--r--quantum/keymap_common.c2
-rw-r--r--quantum/keymap_common.h4
-rw-r--r--quantum/matrix.c8
-rw-r--r--quantum/quantum.c167
-rw-r--r--quantum/quantum.h48
-rw-r--r--quantum/quantum.mk3
-rw-r--r--quantum/template/template.c7
-rw-r--r--quantum/template/template.h2
8 files changed, 230 insertions, 11 deletions
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 8f00f9cc3..0184770c4 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -251,7 +251,7 @@ static action_t keycode_to_action(uint16_t keycode)
251 } 251 }
252 eeconfig_update_keymap(keymap_config.raw); 252 eeconfig_update_keymap(keymap_config.raw);
253 break; 253 break;
254 case 0x5100 ... 0x5FFF: ; 254 case 0x5100 ... 0x56FF: ;
255 // Layer movement shortcuts 255 // Layer movement shortcuts
256 // See .h to see constraints/usage 256 // See .h to see constraints/usage
257 int type = (keycode >> 0x8) & 0xF; 257 int type = (keycode >> 0x8) & 0xF;
diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h
index 322fda498..2ad1ba6c6 100644
--- a/quantum/keymap_common.h
+++ b/quantum/keymap_common.h
@@ -159,7 +159,7 @@ extern const uint16_t fn_actions[];
159#define S(kc) LSFT(kc) 159#define S(kc) LSFT(kc)
160#define F(kc) FUNC(kc) 160#define F(kc) FUNC(kc)
161 161
162#define M(kc) kc | 0x3000 162#define M(kc) (kc | 0x3000)
163 163
164#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE) 164#define MACRODOWN(...) (record->event.pressed ? MACRO(__VA_ARGS__) : MACRO_NONE)
165 165
@@ -191,6 +191,8 @@ extern const uint16_t fn_actions[];
191 191
192#define RESET 0x5000 192#define RESET 0x5000
193#define DEBUG 0x5001 193#define DEBUG 0x5001
194#define KC_LEAD 0x5014
195
194 196
195// MAGIC keycodes 197// MAGIC keycodes
196#define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002 198#define MAGIC_SWAP_CONTROL_CAPSLOCK 0x5002
diff --git a/quantum/matrix.c b/quantum/matrix.c
index 7d70f728d..cab39e117 100644
--- a/quantum/matrix.c
+++ b/quantum/matrix.c
@@ -55,12 +55,12 @@ static void unselect_rows(void);
55static void select_row(uint8_t row); 55static void select_row(uint8_t row);
56 56
57__attribute__ ((weak)) 57__attribute__ ((weak))
58void matrix_init_kb(void) { 58void matrix_init_quantum(void) {
59 59
60} 60}
61 61
62__attribute__ ((weak)) 62__attribute__ ((weak))
63void matrix_scan_kb(void) { 63void matrix_scan_quantum(void) {
64 64
65} 65}
66 66
@@ -93,7 +93,7 @@ void matrix_init(void)
93 matrix_debouncing[i] = 0; 93 matrix_debouncing[i] = 0;
94 } 94 }
95 95
96 matrix_init_kb(); 96 matrix_init_quantum();
97} 97}
98 98
99 99
@@ -157,7 +157,7 @@ uint8_t matrix_scan(void)
157 } 157 }
158#endif 158#endif
159 159
160 matrix_scan_kb(); 160 matrix_scan_quantum();
161 161
162 return 1; 162 return 1;
163} 163}
diff --git a/quantum/quantum.c b/quantum/quantum.c
new file mode 100644
index 000000000..e274d846f
--- /dev/null
+++ b/quantum/quantum.c
@@ -0,0 +1,167 @@
1#include "quantum.h"
2
3__attribute__ ((weak))
4void matrix_init_kb(void) {}
5
6__attribute__ ((weak))
7void matrix_scan_kb(void) {}
8
9__attribute__ ((weak))
10bool process_action_kb(keyrecord_t *record) {
11 return true;
12}
13
14__attribute__ ((weak))
15void leader_start(void) {}
16
17__attribute__ ((weak))
18void leader_end(void) {}
19
20#ifdef AUDIO_ENABLE
21 uint8_t starting_note = 0x0C;
22 int offset = 0;
23 bool music_activated = false;
24#endif
25
26// Leader key stuff
27bool leading = false;
28uint16_t leader_time = 0;
29
30uint16_t leader_sequence[3] = {0, 0, 0};
31uint8_t leader_sequence_size = 0;
32
33// Chording stuff
34#define CHORDING_MAX 4
35bool chording = false;
36
37uint8_t chord_keys[CHORDING_MAX] = {0};
38uint8_t chord_key_count = 0;
39uint8_t chord_key_down = 0;
40
41bool keys_chord(uint8_t keys[]) {
42 uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
43 bool pass = true;
44 uint8_t in = 0;
45 for (uint8_t i = 0; i < chord_key_count; i++) {
46 bool found = false;
47 for (uint8_t j = 0; j < keys_size; j++) {
48 if (chord_keys[i] == (keys[j] & 0xFF)) {
49 in++; // detects key in chord
50 found = true;
51 break;
52 }
53 }
54 if (found)
55 continue;
56 if (chord_keys[i] != 0) {
57 pass = false; // makes sure rest are blank
58 }
59 }
60 return (pass && (in == keys_size));
61}
62
63bool process_action_quantum(keyrecord_t *record) {
64
65 /* This gets the keycode from the key pressed */
66 keypos_t key = record->event.key;
67 uint16_t keycode;
68
69 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
70 uint8_t layer;
71
72 if (record->event.pressed) {
73 layer = layer_switch_get_layer(key);
74 update_source_layers_cache(key, layer);
75 } else {
76 layer = read_source_layers_cache(key);
77 }
78 keycode = keymap_key_to_keycode(layer, key);
79 #else
80 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
81 #endif
82
83 #ifdef AUDIO_ENABLE
84 if (music_activated) {
85 if (record->event.pressed) {
86 play_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
87 } else {
88 stop_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
89 }
90 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
91 return false;
92 }
93 #endif
94
95
96
97#ifndef DISABLE_LEADER
98 // Leader key set-up
99 if (record->event.pressed) {
100 if (!leading && keycode == KC_LEAD) {
101 leader_start();
102 leading = true;
103 leader_time = timer_read();
104 leader_sequence_size = 0;
105 leader_sequence[0] = 0;
106 leader_sequence[1] = 0;
107 leader_sequence[2] = 0;
108 return false;
109 }
110 if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
111 leader_sequence[leader_sequence_size] = keycode;
112 leader_sequence_size++;
113 return false;
114 }
115 }
116#endif
117
118#define DISABLE_CHORDING
119#ifndef DISABLE_CHORDING
120
121 if (keycode >= 0x5700 && keycode <= 0x57FF) {
122 if (record->event.pressed) {
123 if (!chording) {
124 chording = true;
125 for (uint8_t i = 0; i < CHORDING_MAX; i++)
126 chord_keys[i] = 0;
127 chord_key_count = 0;
128 chord_key_down = 0;
129 }
130 chord_keys[chord_key_count] = (keycode & 0xFF);
131 chord_key_count++;
132 chord_key_down++;
133 return false;
134 } else {
135 if (chording) {
136 chord_key_down--;
137 if (chord_key_down == 0) {
138 chording = false;
139 // Chord Dictionary
140 if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
141 register_code(KC_A);
142 unregister_code(KC_A);
143 return false;
144 }
145 for (uint8_t i = 0; i < chord_key_count; i++) {
146 register_code(chord_keys[i]);
147 unregister_code(chord_keys[i]);
148 return false;
149 }
150 }
151 }
152 }
153 }
154
155#endif
156
157
158 return process_action_kb(record);
159}
160
161void matrix_init_quantum() {
162 matrix_init_kb();
163}
164
165void matrix_scan_quantum() {
166 matrix_scan_kb();
167} \ No newline at end of file
diff --git a/quantum/quantum.h b/quantum/quantum.h
new file mode 100644
index 000000000..db726ad42
--- /dev/null
+++ b/quantum/quantum.h
@@ -0,0 +1,48 @@
1#ifndef QUANTUM_H
2#define QUANTUM_H
3
4#include "matrix.h"
5#include "keymap_common.h"
6#ifdef BACKLIGHT_ENABLE
7 #include "backlight.h"
8#endif
9#ifdef RGBLIGHT_ENABLE
10 #include "rgblight.h"
11#endif
12#ifdef AUDIO_ENABLE
13 #include "audio.h"
14#endif
15#ifdef MIDI_ENABLE
16 #include <keymap_midi.h>
17#endif
18#include "action_layer.h"
19#include "eeconfig.h"
20#include <stddef.h>
21#include <avr/io.h>
22
23extern uint32_t default_layer_state;
24
25#ifndef NO_ACTION_LAYER
26 extern uint32_t layer_state;
27#endif
28
29bool music_activated;
30
31void matrix_init_kb(void);
32void matrix_scan_kb(void);
33bool process_action_kb(keyrecord_t *record);
34
35void leader_start(void);
36void leader_end(void);
37
38#ifndef LEADER_TIMEOUT
39 #define LEADER_TIMEOUT 200
40#endif
41#define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0)
42#define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0)
43#define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3))
44
45#define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[3]; extern uint8_t leader_sequence_size
46#define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT)
47
48#endif \ No newline at end of file
diff --git a/quantum/quantum.mk b/quantum/quantum.mk
index 5f4c2f045..b45ad850a 100644
--- a/quantum/quantum.mk
+++ b/quantum/quantum.mk
@@ -1,7 +1,8 @@
1QUANTUM_DIR = quantum 1QUANTUM_DIR = quantum
2 2
3# # project specific files 3# # project specific files
4SRC += $(QUANTUM_DIR)/keymap_common.c \ 4SRC += $(QUANTUM_DIR)/quantum.c \
5 $(QUANTUM_DIR)/keymap_common.c \
5 $(QUANTUM_DIR)/led.c 6 $(QUANTUM_DIR)/led.c
6 7
7# ifdef KEYMAP_FILE 8# ifdef KEYMAP_FILE
diff --git a/quantum/template/template.c b/quantum/template/template.c
index 6050a2d20..649072eb2 100644
--- a/quantum/template/template.c
+++ b/quantum/template/template.c
@@ -11,8 +11,9 @@ void matrix_scan_user(void) {
11} 11}
12 12
13__attribute__ ((weak)) 13__attribute__ ((weak))
14void process_action_user(keyrecord_t *record) { 14bool process_action_user(keyrecord_t *record) {
15 // leave this function blank - it can be defined in a keymap file 15 // leave this function blank - it can be defined in a keymap file
16 return true;
16} 17}
17 18
18__attribute__ ((weak)) 19__attribute__ ((weak))
@@ -34,11 +35,11 @@ void matrix_scan_kb(void) {
34 matrix_scan_user(); 35 matrix_scan_user();
35} 36}
36 37
37void process_action_kb(keyrecord_t *record) { 38bool process_action_kb(keyrecord_t *record) {
38 // put your per-action keyboard code here 39 // put your per-action keyboard code here
39 // runs for every action, just before processing by the firmware 40 // runs for every action, just before processing by the firmware
40 41
41 process_action_user(record); 42 return process_action_user(record);
42} 43}
43 44
44void led_set_kb(uint8_t usb_led) { 45void led_set_kb(uint8_t usb_led) {
diff --git a/quantum/template/template.h b/quantum/template/template.h
index 22742105a..8537e3b4b 100644
--- a/quantum/template/template.h
+++ b/quantum/template/template.h
@@ -24,7 +24,7 @@
24 24
25void matrix_init_user(void); 25void matrix_init_user(void);
26void matrix_scan_user(void); 26void matrix_scan_user(void);
27void process_action_user(keyrecord_t *record); 27bool process_action_user(keyrecord_t *record);
28void led_set_user(uint8_t usb_led); 28void led_set_user(uint8_t usb_led);
29 29
30#endif 30#endif