Skip to content

Commit

Permalink
Fixed USB driver freeze if host connection lost or in an invalid state.
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Starke <[email protected]>
  • Loading branch information
daniel-starke committed Sep 18, 2023
1 parent f032498 commit 7349de0
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions src/USBCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @author Daniel Starke
* @copyright Copyright 2020-2022 Daniel Starke
* @date 2020-05-21
* @version 2022-09-18
* @version 2023-09-18
*
* Control Endpoint:
* @verbatim
Expand Down Expand Up @@ -155,6 +155,7 @@


/* Timeout for sends and receives. */
#define USB_WFI_TIMEOUT_MS 1000
#define USB_IO_TIMEOUT_MS 70
#define PP_CAT(x, y) x##y
#ifdef __thumb__
Expand Down Expand Up @@ -410,7 +411,11 @@ static bool sendOrBlock(const uint8_t ep, const void * data, const uint32_t len,
HAL_PCD_EP_Transmit(hPcdUsb, ep, bufferPtrEp[epIdx], USB_IO_TX_CHUNK(len));
if ( blocking ) {
/* wait until the transmission completed */
while ((txPendingEp & epMask) != 0) __WFI();
const uint32_t startTime = millis();
while ((txPendingEp & epMask) != 0) {
__WFI();
if (uint32_t(millis() - startTime) >= USB_WFI_TIMEOUT_MS) break;
}
}
return true;
}
Expand Down Expand Up @@ -486,23 +491,37 @@ static uint32_t sendHelper(const uint8_t flags, const uint32_t ep, const void *
__DMB(); __DSB(); __ISB(); /* data and instruction barrier */
const uint8_t * dataBuf = reinterpret_cast<const uint8_t *>(data);
for (uint32_t i = 0; i < len; dataBuf++, i++) {
const uint32_t startTime = millis();
while ( ! buf.fifo.push(((flags & TRANSFER_ZERO) == 0) ? *dataBuf : 0) ) {
if ((txPendingEp & epMask) == 0) {
/* trigger send in case something clogged up */
usbTriggerSend(buf, epNum, false);
break;
}
__WFI();
if (uint32_t(millis() - startTime) >= USB_WFI_TIMEOUT_MS) {
/* interface got stuck -> reattach it */
USBDevice.detach();
USBDevice.attach();
return i;
}
}
}
if ((flags & TRANSFER_RELEASE) != 0) {
const uint32_t startTime = millis();
while ( ! buf.fifo.commitBlock() ) {
if ((txPendingEp & epMask) == 0) {
/* trigger send in case something clogged up */
usbTriggerSend(buf, epNum, false);
break;
}
__WFI();
if (uint32_t(millis() - startTime) >= USB_WFI_TIMEOUT_MS) {
/* interface got stuck -> reattach it */
USBDevice.detach();
USBDevice.attach();
return len;
}
}
}
} else {
Expand Down Expand Up @@ -574,7 +593,11 @@ static bool recvOrFail(const uint8_t ep, void * data, const uint32_t len, const
HAL_PCD_EP_Receive(hPcdUsb, ep, reinterpret_cast<uint8_t *>(data), len);
if ( blocking ) {
/* wait until the reception completed */
while ((rxPendingEp & epMask) != 0) __WFI();
const uint32_t startTime = millis();
while ((rxPendingEp & epMask) != 0) {
__WFI();
if (uint32_t(millis() - startTime) >= USB_WFI_TIMEOUT_MS) break;
}
}
return true;
}
Expand Down Expand Up @@ -1197,7 +1220,6 @@ void USBDeviceClass::flush(uint32_t ep) {
bytesPendingEp[0] = 0;
bytesPendingEp[1] = 0;
} else {

bool canWait = false;
const bool interruptsEnabled = ((__get_PRIMASK() & 0x1) == 0);
if ( interruptsEnabled ) {
Expand All @@ -1219,9 +1241,17 @@ void USBDeviceClass::flush(uint32_t ep) {
usbTriggerSend(buf, epNum, false);
}
}
while ((txPendingEp & epMask) != 0) __WFI();
const uint32_t startTime = millis();
while ((txPendingEp & epMask) != 0) {
__WFI();
if (uint32_t(millis() - startTime) >= USB_WFI_TIMEOUT_MS) break;
}
} else {
while ((rxPendingEp & epMask) != 0) __WFI();
const uint32_t startTime = millis();
while ((rxPendingEp & epMask) != 0) {
__WFI();
if (uint32_t(millis() - startTime) >= USB_WFI_TIMEOUT_MS) break;
}
}
}
}
Expand Down

0 comments on commit 7349de0

Please sign in to comment.