From d2a57d82d5f664364daf9d7440968ee20e3ac6fd Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Mon, 12 May 2014 17:26:31 +0900 Subject: [PATCH 1/4] New branch for 6KRO feature --- common.mk | 4 ++ common/action_util.c | 85 ++++++++++++++++++++++++++++++++++++++++++ keyboard/gh60/Makefile | 3 +- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 09561cba..c0a713ea 100644 --- a/common.mk +++ b/common.mk @@ -48,6 +48,10 @@ ifdef NKRO_ENABLE OPT_DEFS += -DNKRO_ENABLE endif +ifdef GKRO_ENABLE + OPT_DEFS += -D_6KRO_ENABLE +endif + ifdef SLEEP_LED_ENABLE SRC += $(COMMON_DIR)/sleep_led.c OPT_DEFS += -DSLEEP_LED_ENABLE diff --git a/common/action_util.c b/common/action_util.c index 99a3adaa..8aa0b85c 100644 --- a/common/action_util.c +++ b/common/action_util.c @@ -30,6 +30,15 @@ static inline void del_key_bit(uint8_t code); static uint8_t real_mods = 0; static uint8_t weak_mods = 0; +#ifdef _6KRO_ENABLE +#define RO_ADD(a, b) ((a + b) % REPORT_KEYS) +#define RO_SUB(a, b) ((a - b) % REPORT_KEYS) +#define RO_INC(a) RO_ADD(a, 1) +#define RO_DEC(a) RO_SUB(a, 1) +static int8_t cb_head = 0; +static int8_t cb_tail = 0; +static int8_t cb_count = 0; +#endif // TODO: pointer variable is not needed //report_keyboard_t keyboard_report = {}; @@ -166,6 +175,60 @@ uint8_t get_first_key(void) /* local functions */ static inline void add_key_byte(uint8_t code) { +#ifdef _6KRO_ENABLE + int8_t i = cb_head; + int8_t idle = -1; + if (cb_count) { + do { + if (keyboard_report->keys[i] == code) { + break; + } + if (idle == -1 && keyboard_report->keys[i] == 0) { + idle = i; + } + i = RO_INC(i); + } while (i != cb_tail); + } + else { + // buffer is empty + keyboard_report->keys[cb_head] = code; + cb_tail = RO_INC(cb_tail); + cb_count++; + return; + } + // code is unique + if (i == cb_tail) { + // buffer is full + if (cb_tail == cb_head) { + if (idle == -1) { + // pop head when has no idle space + cb_head = RO_INC(cb_head); + cb_count--; + } + else { + // pack when has idle space + uint8_t offset = 1; + i = RO_INC(idle); + do { + if (keyboard_report->keys[i] != 0) { + keyboard_report->keys[idle] = keyboard_report->keys[i]; + keyboard_report->keys[i] = 0; + idle = RO_INC(idle); + } + else { + offset++; + } + i = RO_INC(i); + } while (i != cb_tail); + cb_tail = RO_SUB(cb_tail, offset); + } + } + // add to tail + keyboard_report->keys[cb_tail] = code; + cb_tail = RO_INC(cb_tail); + cb_count++; + } +#else int8_t i = 0; int8_t empty = -1; for (; i < REPORT_KEYS; i++) { @@ -181,15 +244,37 @@ static inline void add_key_byte(uint8_t code) keyboard_report->keys[empty] = code; } } +#endif } static inline void del_key_byte(uint8_t code) { +#ifdef _6KRO_ENABLE + uint8_t i = cb_head; + if (cb_count) { + do { + if (keyboard_report->keys[i] == code) { + keyboard_report->keys[i] = 0; + cb_count--; + if (i == cb_tail) { + do { + cb_tail = RO_DEC(cb_tail); + if (keyboard_report->keys[cb_tail] != 0) { + break; + } + } while (cb_tail != cb_head); + } + break; + } + } while (i != cb_tail); + } +#else for (uint8_t i = 0; i < REPORT_KEYS; i++) { if (keyboard_report->keys[i] == code) { keyboard_report->keys[i] = 0; } } +#endif } #ifdef NKRO_ENABLE diff --git a/keyboard/gh60/Makefile b/keyboard/gh60/Makefile index 56da7779..767f32cc 100644 --- a/keyboard/gh60/Makefile +++ b/keyboard/gh60/Makefile @@ -132,7 +132,8 @@ EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration #SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend -NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA +#NKRO_ENABLE = yes # USB Nkey Rollover +GKRO_ENABLE = yes # USB 6key Rollover #PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support #PS2_USE_BUSYWAIT = yes BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality From ee9913a863706940dd6d443d10d0c2b85cb3fc2e Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Mon, 12 May 2014 18:47:50 +0900 Subject: [PATCH 2/4] Implement 6KRO feature --- common.mk | 4 +- common/action_util.c | 115 +++++++++++++++++++++++++---------------- keyboard/gh60/Makefile | 2 +- 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/common.mk b/common.mk index c0a713ea..635ba058 100644 --- a/common.mk +++ b/common.mk @@ -48,8 +48,8 @@ ifdef NKRO_ENABLE OPT_DEFS += -DNKRO_ENABLE endif -ifdef GKRO_ENABLE - OPT_DEFS += -D_6KRO_ENABLE +ifdef USB_6KRO_ENABLE + OPT_DEFS += -DUSB_6KRO_ENABLE endif ifdef SLEEP_LED_ENABLE diff --git a/common/action_util.c b/common/action_util.c index 8aa0b85c..54ff26ab 100644 --- a/common/action_util.c +++ b/common/action_util.c @@ -30,9 +30,9 @@ static inline void del_key_bit(uint8_t code); static uint8_t real_mods = 0; static uint8_t weak_mods = 0; -#ifdef _6KRO_ENABLE +#ifdef USB_6KRO_ENABLE #define RO_ADD(a, b) ((a + b) % REPORT_KEYS) -#define RO_SUB(a, b) ((a - b) % REPORT_KEYS) +#define RO_SUB(a, b) ((a - b + REPORT_KEYS) % REPORT_KEYS) #define RO_INC(a) RO_ADD(a, 1) #define RO_DEC(a) RO_SUB(a, 1) static int8_t cb_head = 0; @@ -144,12 +144,16 @@ void clear_oneshot_mods(void) */ uint8_t has_anykey(void) { +#ifdef USB_6KRO_ENABLE + return cb_count; +#else uint8_t cnt = 0; for (uint8_t i = 1; i < REPORT_SIZE; i++) { if (keyboard_report->raw[i]) cnt++; } return cnt; +#endif } uint8_t has_anymod(void) @@ -167,7 +171,11 @@ uint8_t get_first_key(void) return i<<3 | biton(keyboard_report->nkro.bits[i]); } #endif +#ifdef USB_6KRO_ENABLE + return keyboard_report->keys[cb_head]; +#else return keyboard_report->keys[0]; +#endif } @@ -175,59 +183,52 @@ uint8_t get_first_key(void) /* local functions */ static inline void add_key_byte(uint8_t code) { -#ifdef _6KRO_ENABLE +#ifdef USB_6KRO_ENABLE int8_t i = cb_head; int8_t idle = -1; if (cb_count) { do { if (keyboard_report->keys[i] == code) { - break; + return; } if (idle == -1 && keyboard_report->keys[i] == 0) { idle = i; } i = RO_INC(i); } while (i != cb_tail); - } - else { - // buffer is empty - keyboard_report->keys[cb_head] = code; - cb_tail = RO_INC(cb_tail); - cb_count++; - return; - } - // code is unique - if (i == cb_tail) { - // buffer is full - if (cb_tail == cb_head) { - if (idle == -1) { - // pop head when has no idle space - cb_head = RO_INC(cb_head); - cb_count--; - } - else { - // pack when has idle space - uint8_t offset = 1; - i = RO_INC(idle); - do { - if (keyboard_report->keys[i] != 0) { - keyboard_report->keys[idle] = keyboard_report->keys[i]; - keyboard_report->keys[i] = 0; - idle = RO_INC(idle); - } - else { - offset++; - } - i = RO_INC(i); - } while (i != cb_tail); - cb_tail = RO_SUB(cb_tail, offset); + if (i == cb_tail) { + // code is unique + if (cb_tail == cb_head) { + // buffer is full + if (idle == -1) { + // pop head when has no idle space + cb_head = RO_INC(cb_head); + cb_count--; + } + else { + // pack when has idle space + uint8_t offset = 1; + i = RO_INC(idle); + do { + if (keyboard_report->keys[i] != 0) { + keyboard_report->keys[idle] = keyboard_report->keys[i]; + keyboard_report->keys[i] = 0; + idle = RO_INC(idle); + } + else { + offset++; + } + i = RO_INC(i); + } while (i != cb_tail); + cb_tail = RO_SUB(cb_tail, offset); + } } } - // add to tail - keyboard_report->keys[cb_tail] = code; - cb_tail = RO_INC(cb_tail); - cb_count++; } + // add to tail + keyboard_report->keys[cb_tail] = code; + cb_tail = RO_INC(cb_tail); + cb_count++; #else int8_t i = 0; int8_t empty = -1; @@ -245,27 +246,42 @@ static inline void add_key_byte(uint8_t code) } } #endif + /* + dprintf("\n"); + for (uint8_t i = 0; i < REPORT_KEYS; i++) { + dprintf("%02X ", keyboard_report->keys[i]); + } + dprintf("\n"); + for (uint8_t i = 0; i < REPORT_KEYS; i++) { + dprintf("%c%c ", i==cb_head?'H':' ', i==cb_tail?'T':' '); + } + dprintf("\n"); + */ } static inline void del_key_byte(uint8_t code) { -#ifdef _6KRO_ENABLE +#ifdef USB_6KRO_ENABLE uint8_t i = cb_head; if (cb_count) { do { if (keyboard_report->keys[i] == code) { keyboard_report->keys[i] = 0; cb_count--; - if (i == cb_tail) { + if (cb_count == 0) { + cb_tail = cb_head = 0; + } + if (i == RO_DEC(cb_tail)) { do { cb_tail = RO_DEC(cb_tail); - if (keyboard_report->keys[cb_tail] != 0) { + if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) { break; } } while (cb_tail != cb_head); } break; } + i = RO_INC(i); } while (i != cb_tail); } #else @@ -275,6 +291,17 @@ static inline void del_key_byte(uint8_t code) } } #endif + /* + dprintf("\n"); + for (uint8_t i = 0; i < REPORT_KEYS; i++) { + dprintf("%02X ", keyboard_report->keys[i]); + } + dprintf("\n"); + for (uint8_t i = 0; i < REPORT_KEYS; i++) { + dprintf("%c%c ", i==cb_head?'H':' ', i==cb_tail?'T':' '); + } + dprintf("\ntail=%d\n", cb_tail); + */ } #ifdef NKRO_ENABLE diff --git a/keyboard/gh60/Makefile b/keyboard/gh60/Makefile index 767f32cc..f4fe4fc7 100644 --- a/keyboard/gh60/Makefile +++ b/keyboard/gh60/Makefile @@ -133,7 +133,7 @@ CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration #SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend #NKRO_ENABLE = yes # USB Nkey Rollover -GKRO_ENABLE = yes # USB 6key Rollover +USB_6KRO_ENABLE = yes # USB 6key Rollover #PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support #PS2_USE_BUSYWAIT = yes BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality From 4f1caf1a90110084b5e5a5de8eb5a8168aaf7805 Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Tue, 13 May 2014 13:55:03 +0900 Subject: [PATCH 3/4] Clean code of 6KRO --- common/action_util.c | 65 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/common/action_util.c b/common/action_util.c index 54ff26ab..e44b2142 100644 --- a/common/action_util.c +++ b/common/action_util.c @@ -178,42 +178,55 @@ uint8_t get_first_key(void) #endif } - +#ifdef USB_6KRO_ENABLE +#ifdef DEBUG +static void dump_report_keys(void) { + dprintf("\n"); + for (uint8_t i = 0; i < REPORT_KEYS; i++) { + dprintf("%02X ", keyboard_report->keys[i]); + } + dprintf("\n"); + for (uint8_t i = 0; i < REPORT_KEYS; i++) { + dprintf("%c%c ", i==cb_head?'H':' ', i==cb_tail?'T':' '); + } + dprintf("\n"); +} +#endif +#endif /* local functions */ static inline void add_key_byte(uint8_t code) { #ifdef USB_6KRO_ENABLE int8_t i = cb_head; - int8_t idle = -1; + int8_t empty = -1; if (cb_count) { do { if (keyboard_report->keys[i] == code) { return; } - if (idle == -1 && keyboard_report->keys[i] == 0) { - idle = i; + if (empty == -1 && keyboard_report->keys[i] == 0) { + empty = i; } i = RO_INC(i); } while (i != cb_tail); if (i == cb_tail) { - // code is unique if (cb_tail == cb_head) { // buffer is full - if (idle == -1) { - // pop head when has no idle space + if (empty == -1) { + // pop head when has no empty space cb_head = RO_INC(cb_head); cb_count--; } else { - // pack when has idle space + // left shift when has empty space uint8_t offset = 1; - i = RO_INC(idle); + i = RO_INC(empty); do { if (keyboard_report->keys[i] != 0) { - keyboard_report->keys[idle] = keyboard_report->keys[i]; + keyboard_report->keys[empty] = keyboard_report->keys[i]; keyboard_report->keys[i] = 0; - idle = RO_INC(idle); + empty = RO_INC(empty); } else { offset++; @@ -229,6 +242,9 @@ static inline void add_key_byte(uint8_t code) keyboard_report->keys[cb_tail] = code; cb_tail = RO_INC(cb_tail); cb_count++; +#ifdef DEBUG + dump_report_keys(); +#endif #else int8_t i = 0; int8_t empty = -1; @@ -246,17 +262,6 @@ static inline void add_key_byte(uint8_t code) } } #endif - /* - dprintf("\n"); - for (uint8_t i = 0; i < REPORT_KEYS; i++) { - dprintf("%02X ", keyboard_report->keys[i]); - } - dprintf("\n"); - for (uint8_t i = 0; i < REPORT_KEYS; i++) { - dprintf("%c%c ", i==cb_head?'H':' ', i==cb_tail?'T':' '); - } - dprintf("\n"); - */ } static inline void del_key_byte(uint8_t code) @@ -269,9 +274,11 @@ static inline void del_key_byte(uint8_t code) keyboard_report->keys[i] = 0; cb_count--; if (cb_count == 0) { + // reset head and tail cb_tail = cb_head = 0; } if (i == RO_DEC(cb_tail)) { + // left shift when next to tail do { cb_tail = RO_DEC(cb_tail); if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) { @@ -284,6 +291,9 @@ static inline void del_key_byte(uint8_t code) i = RO_INC(i); } while (i != cb_tail); } +#ifdef DEBUG + dump_report_keys(); +#endif #else for (uint8_t i = 0; i < REPORT_KEYS; i++) { if (keyboard_report->keys[i] == code) { @@ -291,17 +301,6 @@ static inline void del_key_byte(uint8_t code) } } #endif - /* - dprintf("\n"); - for (uint8_t i = 0; i < REPORT_KEYS; i++) { - dprintf("%02X ", keyboard_report->keys[i]); - } - dprintf("\n"); - for (uint8_t i = 0; i < REPORT_KEYS; i++) { - dprintf("%c%c ", i==cb_head?'H':' ', i==cb_tail?'T':' '); - } - dprintf("\ntail=%d\n", cb_tail); - */ } #ifdef NKRO_ENABLE From 5ccabc844ca92a2d73301fe93c926b4fc264373e Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Tue, 13 May 2014 14:10:56 +0900 Subject: [PATCH 4/4] Fix compatibility with NKRO --- common/action_util.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/common/action_util.c b/common/action_util.c index e44b2142..de9522a0 100644 --- a/common/action_util.c +++ b/common/action_util.c @@ -145,7 +145,13 @@ void clear_oneshot_mods(void) uint8_t has_anykey(void) { #ifdef USB_6KRO_ENABLE - return cb_count; +#ifdef NKRO_ENABLE + if (!keyboard_nkro) { +#endif + return cb_count; +#ifdef NKRO_ENABLE + } +#endif #else uint8_t cnt = 0; for (uint8_t i = 1; i < REPORT_SIZE; i++) { @@ -172,7 +178,14 @@ uint8_t get_first_key(void) } #endif #ifdef USB_6KRO_ENABLE - return keyboard_report->keys[cb_head]; + uint8_t i = cb_head; + do { + if (keyboard_report->keys[i] != 0) { + break; + } + i = RO_INC(i); + } while (i != cb_tail); + return keyboard_report->keys[i]; #else return keyboard_report->keys[0]; #endif