diff options
author | tmk <tmk@users.noreply.github.com> | 2014-07-07 12:46:12 +0900 |
---|---|---|
committer | tmk <tmk@users.noreply.github.com> | 2014-07-07 12:46:12 +0900 |
commit | 34373185b746ae5b49cf56ac956080525c7dd6f8 (patch) | |
tree | 960fd040c50fa234b69fa381f065f84b1dd93a17 /common | |
parent | 3eeb0a96232af825962fa1e9b05b80ac1cfd1868 (diff) | |
parent | ac570686b6bde1e5066ea68636ae780392739cb4 (diff) | |
download | qmk_firmware-34373185b746ae5b49cf56ac956080525c7dd6f8.tar.gz qmk_firmware-34373185b746ae5b49cf56ac956080525c7dd6f8.zip |
Merge pull request #124 from kairyu/6kro
USB 6KRO with pseudo- or half- NKRO feature
Diffstat (limited to 'common')
-rw-r--r-- | common/action_util.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/common/action_util.c b/common/action_util.c index 99a3adaab..5f44b3812 100644 --- a/common/action_util.c +++ b/common/action_util.c | |||
@@ -30,6 +30,15 @@ static inline void del_key_bit(uint8_t code); | |||
30 | static uint8_t real_mods = 0; | 30 | static uint8_t real_mods = 0; |
31 | static uint8_t weak_mods = 0; | 31 | static uint8_t weak_mods = 0; |
32 | 32 | ||
33 | #ifdef USB_6KRO_ENABLE | ||
34 | #define RO_ADD(a, b) ((a + b) % REPORT_KEYS) | ||
35 | #define RO_SUB(a, b) ((a - b + REPORT_KEYS) % REPORT_KEYS) | ||
36 | #define RO_INC(a) RO_ADD(a, 1) | ||
37 | #define RO_DEC(a) RO_SUB(a, 1) | ||
38 | static int8_t cb_head = 0; | ||
39 | static int8_t cb_tail = 0; | ||
40 | static int8_t cb_count = 0; | ||
41 | #endif | ||
33 | 42 | ||
34 | // TODO: pointer variable is not needed | 43 | // TODO: pointer variable is not needed |
35 | //report_keyboard_t keyboard_report = {}; | 44 | //report_keyboard_t keyboard_report = {}; |
@@ -158,7 +167,18 @@ uint8_t get_first_key(void) | |||
158 | return i<<3 | biton(keyboard_report->nkro.bits[i]); | 167 | return i<<3 | biton(keyboard_report->nkro.bits[i]); |
159 | } | 168 | } |
160 | #endif | 169 | #endif |
170 | #ifdef USB_6KRO_ENABLE | ||
171 | uint8_t i = cb_head; | ||
172 | do { | ||
173 | if (keyboard_report->keys[i] != 0) { | ||
174 | break; | ||
175 | } | ||
176 | i = RO_INC(i); | ||
177 | } while (i != cb_tail); | ||
178 | return keyboard_report->keys[i]; | ||
179 | #else | ||
161 | return keyboard_report->keys[0]; | 180 | return keyboard_report->keys[0]; |
181 | #endif | ||
162 | } | 182 | } |
163 | 183 | ||
164 | 184 | ||
@@ -166,6 +186,52 @@ uint8_t get_first_key(void) | |||
166 | /* local functions */ | 186 | /* local functions */ |
167 | static inline void add_key_byte(uint8_t code) | 187 | static inline void add_key_byte(uint8_t code) |
168 | { | 188 | { |
189 | #ifdef USB_6KRO_ENABLE | ||
190 | int8_t i = cb_head; | ||
191 | int8_t empty = -1; | ||
192 | if (cb_count) { | ||
193 | do { | ||
194 | if (keyboard_report->keys[i] == code) { | ||
195 | return; | ||
196 | } | ||
197 | if (empty == -1 && keyboard_report->keys[i] == 0) { | ||
198 | empty = i; | ||
199 | } | ||
200 | i = RO_INC(i); | ||
201 | } while (i != cb_tail); | ||
202 | if (i == cb_tail) { | ||
203 | if (cb_tail == cb_head) { | ||
204 | // buffer is full | ||
205 | if (empty == -1) { | ||
206 | // pop head when has no empty space | ||
207 | cb_head = RO_INC(cb_head); | ||
208 | cb_count--; | ||
209 | } | ||
210 | else { | ||
211 | // left shift when has empty space | ||
212 | uint8_t offset = 1; | ||
213 | i = RO_INC(empty); | ||
214 | do { | ||
215 | if (keyboard_report->keys[i] != 0) { | ||
216 | keyboard_report->keys[empty] = keyboard_report->keys[i]; | ||
217 | keyboard_report->keys[i] = 0; | ||
218 | empty = RO_INC(empty); | ||
219 | } | ||
220 | else { | ||
221 | offset++; | ||
222 | } | ||
223 | i = RO_INC(i); | ||
224 | } while (i != cb_tail); | ||
225 | cb_tail = RO_SUB(cb_tail, offset); | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | } | ||
230 | // add to tail | ||
231 | keyboard_report->keys[cb_tail] = code; | ||
232 | cb_tail = RO_INC(cb_tail); | ||
233 | cb_count++; | ||
234 | #else | ||
169 | int8_t i = 0; | 235 | int8_t i = 0; |
170 | int8_t empty = -1; | 236 | int8_t empty = -1; |
171 | for (; i < REPORT_KEYS; i++) { | 237 | for (; i < REPORT_KEYS; i++) { |
@@ -181,15 +247,43 @@ static inline void add_key_byte(uint8_t code) | |||
181 | keyboard_report->keys[empty] = code; | 247 | keyboard_report->keys[empty] = code; |
182 | } | 248 | } |
183 | } | 249 | } |
250 | #endif | ||
184 | } | 251 | } |
185 | 252 | ||
186 | static inline void del_key_byte(uint8_t code) | 253 | static inline void del_key_byte(uint8_t code) |
187 | { | 254 | { |
255 | #ifdef USB_6KRO_ENABLE | ||
256 | uint8_t i = cb_head; | ||
257 | if (cb_count) { | ||
258 | do { | ||
259 | if (keyboard_report->keys[i] == code) { | ||
260 | keyboard_report->keys[i] = 0; | ||
261 | cb_count--; | ||
262 | if (cb_count == 0) { | ||
263 | // reset head and tail | ||
264 | cb_tail = cb_head = 0; | ||
265 | } | ||
266 | if (i == RO_DEC(cb_tail)) { | ||
267 | // left shift when next to tail | ||
268 | do { | ||
269 | cb_tail = RO_DEC(cb_tail); | ||
270 | if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) { | ||
271 | break; | ||
272 | } | ||
273 | } while (cb_tail != cb_head); | ||
274 | } | ||
275 | break; | ||
276 | } | ||
277 | i = RO_INC(i); | ||
278 | } while (i != cb_tail); | ||
279 | } | ||
280 | #else | ||
188 | for (uint8_t i = 0; i < REPORT_KEYS; i++) { | 281 | for (uint8_t i = 0; i < REPORT_KEYS; i++) { |
189 | if (keyboard_report->keys[i] == code) { | 282 | if (keyboard_report->keys[i] == code) { |
190 | keyboard_report->keys[i] = 0; | 283 | keyboard_report->keys[i] = 0; |
191 | } | 284 | } |
192 | } | 285 | } |
286 | #endif | ||
193 | } | 287 | } |
194 | 288 | ||
195 | #ifdef NKRO_ENABLE | 289 | #ifdef NKRO_ENABLE |