~ruther/qmk_firmware

83be1aed7631efdeccf9fbcd5d702b3048f08fd7 — xyzz 5 years ago c293d90
chibios/usb_main: re-check USB status in send_keyboard after sleeping the thread (#7784)

* chibios/usb_main: re-check USB status in send_keyboard after sleeping the thread

* change send_keyboard to only have 1 exit point
1 files changed, 14 insertions(+), 7 deletions(-)

M tmk_core/protocol/chibios/usb_main.c
M tmk_core/protocol/chibios/usb_main.c => tmk_core/protocol/chibios/usb_main.c +14 -7
@@ 620,10 620,8 @@ uint8_t keyboard_leds(void) { return (uint8_t)(keyboard_led_stats & 0xFF); }
void send_keyboard(report_keyboard_t *report) {
    osalSysLock();
    if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
        osalSysUnlock();
        return;
        goto unlock;
    }
    osalSysUnlock();

#ifdef NKRO_ENABLE
    if (keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */


@@ 632,28 630,35 @@ void send_keyboard(report_keyboard_t *report) {
         * until *after* the packet has been transmitted. I think
         * this is more efficient */
        /* busy wait, should be short and not very common */
        osalSysLock();
        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);

            /* 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));
        osalSysUnlock();
    } 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 */
        osalSysLock();
        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) {


@@ 664,9 669,11 @@ void send_keyboard(report_keyboard_t *report) {
            size = 8;
        }
        usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size);
        osalSysUnlock();
    }
    keyboard_report_sent = *report;

unlock:
    osalSysUnlock();
}

/* ---------------------------------------------------------