From f77b7d5926661318dd990726eae6dbea36b9e803 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Mon, 23 Oct 2023 15:46:27 +1100 Subject: [PATCH 1/5] V-USB: Add generic `send_report()` function --- tmk_core/protocol/vusb/vusb.c | 96 +++++++++++++++++------------------ 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index d2c774993783..4b17a1e9e870 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -101,6 +101,45 @@ static uint8_t kbuf_tail = 0; static report_keyboard_t keyboard_report_sent; +static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { + switch (endpoint) { + case 1: + while (!usbInterruptIsReady()) { + usbPoll(); + } + usbSetInterrupt(data, size); + break; + case USB_CFG_EP3_NUMBER: + while (!usbInterruptIsReady3()) { + usbPoll(); + } + usbSetInterrupt3(data, size); + break; + case USB_CFG_EP4_NUMBER: + while (!usbInterruptIsReady4()) { + usbPoll(); + } + usbSetInterrupt4(data, size); + break; + } +} + +static void send_report(uint8_t endpoint, void *report, size_t size) { + uint8_t *temp = (uint8_t *)report; + + // Send as many full packets as possible + for (uint8_t i = 0; i < size / 8; i++) { + send_report_fragment(endpoint, temp, 8); + temp += 8; + } + + // Send any data left over + uint8_t remainder = size % 8; + if (remainder) { + send_report_fragment(endpoint, temp, remainder); + } +} + #define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10 /* transfer keyboard report from buffer */ @@ -145,18 +184,7 @@ void raw_hid_send(uint8_t *data, uint8_t length) { return; } - uint8_t *temp = data; - for (uint8_t i = 0; i < 4; i++) { - while (!usbInterruptIsReady4()) { - usbPoll(); - } - usbSetInterrupt4(temp, 8); - temp += 8; - } - while (!usbInterruptIsReady4()) { - usbPoll(); - } - usbSetInterrupt4(0, 0); + send_report(4, data, 32); } __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) { @@ -185,19 +213,6 @@ int8_t sendchar(uint8_t c) { return 0; } -static inline bool usbSendData3(char *data, uint8_t len) { - uint8_t retries = 5; - while (!usbInterruptIsReady3()) { - if (!(retries--)) { - return false; - } - usbPoll(); - } - - usbSetInterrupt3((unsigned char *)data, len); - return true; -} - void console_task(void) { if (!usbConfiguration) { return; @@ -214,16 +229,7 @@ void console_task(void) { send_buf[send_buf_count++] = rbuf_dequeue(); } - char *temp = send_buf; - for (uint8_t i = 0; i < 4; i++) { - if (!usbSendData3(temp, 8)) { - break; - } - temp += 8; - } - - usbSendData3(0, 0); - usbPoll(); + send_report(3, send_buf, CONSOLE_BUFFER_SIZE); } #endif @@ -275,41 +281,31 @@ static void send_nkro(report_nkro_t *report) { static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_mouse_t)); - } + send_report(3, report, sizeof(report_mouse_t)); #endif } static void send_extra(report_extra_t *report) { #ifdef EXTRAKEY_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_extra_t)); - } + send_report(3, report, sizeof(report_extra_t)); #endif } void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_joystick_t)); - } + send_report(3, report, sizeof(report_joystick_t)); #endif } void send_digitizer(report_digitizer_t *report) { #ifdef DIGITIZER_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_digitizer_t)); - } + send_report(3, report, sizeof(report_digitizer_t)); #endif } void send_programmable_button(report_programmable_button_t *report) { #ifdef PROGRAMMABLE_BUTTON_ENABLE - if (usbInterruptIsReadyShared()) { - usbSetInterruptShared((void *)report, sizeof(report_programmable_button_t)); - } + send_report(3, report, sizeof(report_programmable_button_t)); #endif } From 8fcd58b0e314d5a1f21535f74b2e978412b8c179 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Tue, 24 Oct 2023 12:45:42 +1100 Subject: [PATCH 2/5] Eliminate potential infinite loop --- tmk_core/protocol/vusb/vusb.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index 4b17a1e9e870..76cde066d569 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -104,22 +104,19 @@ static report_keyboard_t keyboard_report_sent; static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { switch (endpoint) { case 1: - while (!usbInterruptIsReady()) { - usbPoll(); + if (usbInterruptIsReady()) { + usbSetInterrupt(data, size); } - usbSetInterrupt(data, size); break; case USB_CFG_EP3_NUMBER: - while (!usbInterruptIsReady3()) { - usbPoll(); + if (usbInterruptIsReady3()) { + usbSetInterrupt3(data, size); } - usbSetInterrupt3(data, size); break; case USB_CFG_EP4_NUMBER: - while (!usbInterruptIsReady4()) { - usbPoll(); + if (usbInterruptIsReady4()) { + usbSetInterrupt4(data, size); } - usbSetInterrupt4(data, size); break; } } From 46568e2609cebf8dcf454b610e145181bc8fdc54 Mon Sep 17 00:00:00 2001 From: fauxpark Date: Tue, 24 Oct 2023 12:50:17 +1100 Subject: [PATCH 3/5] Fix up endpoint selection --- tmk_core/protocol/vusb/vusb.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index 76cde066d569..a575ad360b5b 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -269,40 +269,40 @@ static void send_nkro(report_nkro_t *report) { } #ifndef KEYBOARD_SHARED_EP -# define usbInterruptIsReadyShared usbInterruptIsReady3 -# define usbSetInterruptShared usbSetInterrupt3 +# define MOUSE_IN_EPNUM 3 +# define SHARED_IN_EPNUM 3 #else -# define usbInterruptIsReadyShared usbInterruptIsReady -# define usbSetInterruptShared usbSetInterrupt +# define MOUSE_IN_EPNUM 1 +# define SHARED_IN_EPNUM 1 #endif static void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE - send_report(3, report, sizeof(report_mouse_t)); + send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t)); #endif } static void send_extra(report_extra_t *report) { #ifdef EXTRAKEY_ENABLE - send_report(3, report, sizeof(report_extra_t)); + send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t)); #endif } void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE - send_report(3, report, sizeof(report_joystick_t)); + send_report(SHARED_IN_EPNUM, report, sizeof(report_joystick_t)); #endif } void send_digitizer(report_digitizer_t *report) { #ifdef DIGITIZER_ENABLE - send_report(3, report, sizeof(report_digitizer_t)); + send_report(SHARED_IN_EPNUM, report, sizeof(report_digitizer_t)); #endif } void send_programmable_button(report_programmable_button_t *report) { #ifdef PROGRAMMABLE_BUTTON_ENABLE - send_report(3, report, sizeof(report_programmable_button_t)); + send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t)); #endif } From 38ac0031e8343e698444a4cb5618f05b2d245ada Mon Sep 17 00:00:00 2001 From: fauxpark Date: Tue, 24 Oct 2023 13:00:41 +1100 Subject: [PATCH 4/5] Simplify keyboard report sending --- tmk_core/protocol/vusb/protocol.c | 1 - tmk_core/protocol/vusb/vusb.c | 46 ++----------------------------- tmk_core/protocol/vusb/vusb.h | 1 - 3 files changed, 3 insertions(+), 45 deletions(-) diff --git a/tmk_core/protocol/vusb/protocol.c b/tmk_core/protocol/vusb/protocol.c index ae99680ce4b6..1f64561274b6 100644 --- a/tmk_core/protocol/vusb/protocol.c +++ b/tmk_core/protocol/vusb/protocol.c @@ -153,7 +153,6 @@ void protocol_task(void) { if (usbConfiguration && usbInterruptIsReady()) { keyboard_task(); } - vusb_transfer_keyboard(); #ifdef RAW_ENABLE usbPoll(); diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index a575ad360b5b..4c6caab54ffe 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -93,12 +93,6 @@ static uint8_t keyboard_led_state = 0; static uint8_t vusb_idle_rate = 0; uint8_t keyboard_protocol = 1; -/* Keyboard report send buffer */ -#define KBUF_SIZE 16 -static report_keyboard_t kbuf[KBUF_SIZE]; -static uint8_t kbuf_head = 0; -static uint8_t kbuf_tail = 0; - static report_keyboard_t keyboard_report_sent; static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { @@ -137,35 +131,6 @@ static void send_report(uint8_t endpoint, void *report, size_t size) { } } -#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10 - -/* transfer keyboard report from buffer */ -void vusb_transfer_keyboard(void) { - for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) { - if (usbInterruptIsReady()) { - if (kbuf_head != kbuf_tail) { -#ifndef KEYBOARD_SHARED_EP - usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t)); -#else - // Ugly hack! :( - usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t) - 1); - while (!usbInterruptIsReady()) { - usbPoll(); - } - usbSetInterrupt((void *)(&(kbuf[kbuf_tail].keys[5])), 1); -#endif - kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE; - if (debug_keyboard) { - dprintf("V-USB: kbuf[%d->%d](%02X)\n", kbuf_tail, kbuf_head, (kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail)); - } - } - break; - } - usbPoll(); - wait_ms(1); - } -} - /*------------------------------------------------------------------* * RAW HID *------------------------------------------------------------------*/ @@ -250,17 +215,12 @@ static uint8_t keyboard_leds(void) { } static void send_keyboard(report_keyboard_t *report) { - uint8_t next = (kbuf_head + 1) % KBUF_SIZE; - if (next != kbuf_tail) { - kbuf[kbuf_head] = *report; - kbuf_head = next; + if (!keyboard_protocol) { + send_report(1, &report->mods, 8); } else { - dprint("kbuf: full\n"); + send_report(1, report, sizeof(report_keyboard_t)); } - // NOTE: send key strokes of Macro - usbPoll(); - vusb_transfer_keyboard(); keyboard_report_sent = *report; } diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h index c5cb27ded684..ae17e5e014c3 100644 --- a/tmk_core/protocol/vusb/vusb.h +++ b/tmk_core/protocol/vusb/vusb.h @@ -121,4 +121,3 @@ typedef struct usbConfigurationDescriptor { extern bool vusb_suspended; host_driver_t *vusb_driver(void); -void vusb_transfer_keyboard(void); From 46512a736063ac59be02aa577a8ba154f038e1ca Mon Sep 17 00:00:00 2001 From: fauxpark Date: Tue, 21 Nov 2023 17:45:38 +1100 Subject: [PATCH 5/5] Implement retries --- tmk_core/protocol/vusb/vusb.c | 42 ++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index 4c6caab54ffe..84c3322a9e96 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -96,22 +96,32 @@ uint8_t keyboard_protocol = 1; static report_keyboard_t keyboard_report_sent; static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { - switch (endpoint) { - case 1: - if (usbInterruptIsReady()) { - usbSetInterrupt(data, size); - } - break; - case USB_CFG_EP3_NUMBER: - if (usbInterruptIsReady3()) { - usbSetInterrupt3(data, size); - } - break; - case USB_CFG_EP4_NUMBER: - if (usbInterruptIsReady4()) { - usbSetInterrupt4(data, size); - } - break; + for (uint8_t retries = 5; retries > 0; retries--) { + switch (endpoint) { + case 1: + if (usbInterruptIsReady()) { + usbSetInterrupt(data, size); + return; + } + break; + case USB_CFG_EP3_NUMBER: + if (usbInterruptIsReady3()) { + usbSetInterrupt3(data, size); + return; + } + break; + case USB_CFG_EP4_NUMBER: + if (usbInterruptIsReady4()) { + usbSetInterrupt4(data, size); + return; + } + break; + default: + return; + } + + usbPoll(); + wait_ms(5); } }