aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authortmk <tmk@users.noreply.github.com>2014-07-07 12:46:12 +0900
committertmk <tmk@users.noreply.github.com>2014-07-07 12:46:12 +0900
commit34373185b746ae5b49cf56ac956080525c7dd6f8 (patch)
tree960fd040c50fa234b69fa381f065f84b1dd93a17 /common
parent3eeb0a96232af825962fa1e9b05b80ac1cfd1868 (diff)
parentac570686b6bde1e5066ea68636ae780392739cb4 (diff)
downloadqmk_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.c94
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);
30static uint8_t real_mods = 0; 30static uint8_t real_mods = 0;
31static uint8_t weak_mods = 0; 31static 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)
38static int8_t cb_head = 0;
39static int8_t cb_tail = 0;
40static 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 */
167static inline void add_key_byte(uint8_t code) 187static 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
186static inline void del_key_byte(uint8_t code) 253static 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