From 073068aa36349928aba26f8d9b9cb8b93f389b4b Mon Sep 17 00:00:00 2001 From: Russ Butler Date: Wed, 13 Jun 2018 20:25:41 -0500 Subject: [PATCH] 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. --- .../targets/TARGET_Freescale/USBPhy_Kinetis.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp b/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp index 8c277cc10e..763fa9cc13 100644 --- a/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp +++ b/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp @@ -411,11 +411,23 @@ void USBPhyHw::endpoint_remove(usb_ep_t endpoint) void USBPhyHw::endpoint_stall(usb_ep_t endpoint) { - USB0->ENDPOINT[DESC_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK; + if (DESC_TO_LOG(endpoint) == 0) { + USB0->ENDPOINT[DESC_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK; + } else { + uint8_t dir = DESC_EP_IN(endpoint) ? TX : RX; + uint32_t idx = EP_BDT_IDX(DESC_TO_LOG(endpoint), dir, 0); + bdt[idx].info |= BD_OWN_MASK | BD_STALL_MASK; + } } void USBPhyHw::endpoint_unstall(usb_ep_t endpoint) { + + if (DESC_TO_LOG(endpoint) != 0) { + uint8_t dir = DESC_EP_IN(endpoint) ? TX : RX; + uint32_t idx = EP_BDT_IDX(DESC_TO_LOG(endpoint), dir, 0); + bdt[idx].info &= ~(BD_OWN_MASK | BD_STALL_MASK); + } USB0->ENDPOINT[DESC_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; }