Skip to content

Commit 855712a

Browse files
committed
Fix Kinetis bug causing USB to get stuck sending
If an IN endpoint is stalled during a transfer by writing to the USB ENDPOINT register then the data being sent will repeat and flood the USB bus. This patch prevents the register write from occurring by instead writing to the buffer descriptor in RAM and letting the USB hardware handle setting the stall bit. Note - Control requests on endpoint 0 do still set the STALL bit directly. This is not a problem since control endpoints cannot be stalled externally while a transfer is ongoing.
1 parent 709839a commit 855712a

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,11 +411,23 @@ void USBPhyHw::endpoint_remove(usb_ep_t endpoint)
411411

412412
void USBPhyHw::endpoint_stall(usb_ep_t endpoint)
413413
{
414-
USB0->ENDPOINT[DESC_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK;
414+
if (DESC_TO_LOG(endpoint) == 0) {
415+
USB0->ENDPOINT[DESC_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK;
416+
} else {
417+
uint8_t dir = DESC_EP_IN(endpoint) ? TX : RX;
418+
uint32_t idx = EP_BDT_IDX(DESC_TO_LOG(endpoint), dir, 0);
419+
bdt[idx].info |= BD_OWN_MASK | BD_STALL_MASK;
420+
}
415421
}
416422

417423
void USBPhyHw::endpoint_unstall(usb_ep_t endpoint)
418424
{
425+
426+
if (DESC_TO_LOG(endpoint) != 0) {
427+
uint8_t dir = DESC_EP_IN(endpoint) ? TX : RX;
428+
uint32_t idx = EP_BDT_IDX(DESC_TO_LOG(endpoint), dir, 0);
429+
bdt[idx].info &= ~(BD_OWN_MASK | BD_STALL_MASK);
430+
}
419431
USB0->ENDPOINT[DESC_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK;
420432
}
421433

0 commit comments

Comments
 (0)