From 7acc3f444993c77ad65836933c4daecbae57d034 Mon Sep 17 00:00:00 2001 From: Ryan Date: Tue, 17 Jan 2023 12:54:26 +1100 Subject: [PATCH] ChibiOS: Consolidate report sending code (#19607) --- tmk_core/protocol/chibios/usb_main.c | 193 ++++++--------------------- 1 file changed, 41 insertions(+), 152 deletions(-) diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index cd4b137d83..b14ca30c1a 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -859,65 +859,48 @@ uint8_t keyboard_leds(void) { return keyboard_led_state; } +void send_report(uint8_t endpoint, void *report, size_t size) { + osalSysLock(); + if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { + osalSysUnlock(); + return; + } + + if (usbGetTransmitStatusI(&USB_DRIVER, endpoint)) { + /* Need to either suspend, or loop and call unlock/lock during + * every iteration - otherwise the system will remain locked, + * no interrupts served, so USB not going through as well. + * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ + if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[endpoint]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { + osalSysUnlock(); + return; + } + } + usbStartTransmitI(&USB_DRIVER, endpoint, report, size); + osalSysUnlock(); +} + /* prepare and start sending a report IN * not callable from ISR or locked state */ void send_keyboard(report_keyboard_t *report) { - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - goto unlock; - } + uint8_t ep = KEYBOARD_IN_EPNUM; + size_t size = KEYBOARD_REPORT_SIZE; + /* If we're in Boot Protocol, don't send any report ID or other funky fields */ + if (!keyboard_protocol) { + send_report(ep, &report->mods, 8); + } else { #ifdef NKRO_ENABLE - if (keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */ - /* need to wait until the previous packet has made it through */ - /* can rewrite this using the synchronous API, then would wait - * until *after* the packet has been transmitted. I think - * this is more efficient */ - /* busy wait, should be short and not very common */ - if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread); + if (keymap_config.nkro) { + ep = SHARED_IN_EPNUM; + size = sizeof(struct nkro_report); + } +#endif - /* after osalThreadSuspendS returns USB status might have changed */ - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - goto unlock; - } - } - usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report)); - } else -#endif /* NKRO_ENABLE */ - { /* regular protocol */ - /* need to wait until the previous packet has made it through */ - /* busy wait, should be short and not very common */ - if (usbGetTransmitStatusI(&USB_DRIVER, KEYBOARD_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread); - - /* after osalThreadSuspendS returns USB status might have changed */ - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - goto unlock; - } - } - uint8_t *data, size; - if (keyboard_protocol) { - data = (uint8_t *)report; - size = KEYBOARD_REPORT_SIZE; - } else { /* boot protocol */ - data = &report->mods; - size = 8; - } - usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size); + send_report(ep, report, size); } - keyboard_report_sent = *report; -unlock: - osalSysUnlock(); + keyboard_report_sent = *report; } /* --------------------------------------------------------- @@ -925,35 +908,13 @@ unlock: * --------------------------------------------------------- */ +void send_mouse(report_mouse_t *report) { #ifdef MOUSE_ENABLE -void send_mouse(report_mouse_t *report) { - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, MOUSE_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[MOUSE_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - usbStartTransmitI(&USB_DRIVER, MOUSE_IN_EPNUM, (uint8_t *)report, sizeof(report_mouse_t)); + send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t)); mouse_report_sent = *report; - osalSysUnlock(); +#endif } -#else /* MOUSE_ENABLE */ -void send_mouse(report_mouse_t *report) { - (void)report; -} -#endif /* MOUSE_ENABLE */ - /* --------------------------------------------------------- * Extrakey functions * --------------------------------------------------------- @@ -961,97 +922,25 @@ void send_mouse(report_mouse_t *report) { void send_extra(report_extra_t *report) { #ifdef EXTRAKEY_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(report_extra_t)); - osalSysUnlock(); + send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t)); #endif } void send_programmable_button(report_programmable_button_t *report) { #ifdef PROGRAMMABLE_BUTTON_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(report_programmable_button_t)); - osalSysUnlock(); + send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t)); #endif } void send_joystick(report_joystick_t *report) { #ifdef JOYSTICK_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, JOYSTICK_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[JOYSTICK_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, JOYSTICK_IN_EPNUM, (uint8_t *)report, sizeof(report_joystick_t)); - osalSysUnlock(); + send_report(JOYSTICK_IN_EPNUM, report, sizeof(report_joystick_t)); #endif } void send_digitizer(report_digitizer_t *report) { #ifdef DIGITIZER_ENABLE - osalSysLock(); - if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { - osalSysUnlock(); - return; - } - - if (usbGetTransmitStatusI(&USB_DRIVER, DIGITIZER_IN_EPNUM)) { - /* Need to either suspend, or loop and call unlock/lock during - * every iteration - otherwise the system will remain locked, - * no interrupts served, so USB not going through as well. - * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ - if (osalThreadSuspendTimeoutS(&(&USB_DRIVER)->epc[DIGITIZER_IN_EPNUM]->in_state->thread, TIME_MS2I(10)) == MSG_TIMEOUT) { - osalSysUnlock(); - return; - } - } - - usbStartTransmitI(&USB_DRIVER, DIGITIZER_IN_EPNUM, (uint8_t *)report, sizeof(report_digitizer_t)); - osalSysUnlock(); + send_report(DIGITIZER_IN_EPNUM, report, sizeof(report_digitizer_t)); #endif }