Skip to content

Commit a2825da

Browse files
committed
Fix USB Host issues
1 parent 26a1906 commit a2825da

File tree

3 files changed

+136
-3
lines changed

3 files changed

+136
-3
lines changed

src/USBHost/dbg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#define USB_DEBUG_H
1919

2020
//Debug is disabled by default
21-
#define DEBUG 0 /*INFO,ERR,WARN*/
21+
#define DEBUG 4 /*INFO,ERR,WARN*/
2222
#define DEBUG_TRANSFER 0
2323
#define DEBUG_EP_STATE 0
2424
#define DEBUG_EVENT 0

src/targets/TARGET_STM/USBEndpoint_STM.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,12 @@ USB_TYPE USBEndpoint::queueTransfer()
178178
}
179179
ep_queue.get(0);
180180
MBED_ASSERT(*addr == 0);
181+
#if ARC_USB_FULL_SIZE
182+
transfer_len = td_current->size;
183+
#else
181184
transfer_len = td_current->size <= max_size ? td_current->size : max_size;
185+
#endif
186+
182187
buf_start = (uint8_t *)td_current->currBufPtr;
183188

184189
//Now add this free TD at this end of the queue

src/targets/TARGET_STM/USBHALHost_STM.cpp

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,98 @@ uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chnum)
9191
// - URB_NOTREADY = a NAK, NYET, or not more than a couple of repeats of some of the errors that will
9292
// become URB_ERROR if they repeat several times in a row
9393
//
94+
#if ARC_USB_FULL_SIZE
95+
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *pHcd, uint8_t uChannel, HCD_URBStateTypeDef urbState)
96+
{
97+
USBHALHost_Private_t *pPriv = (USBHALHost_Private_t *)(pHcd->pData);
98+
99+
HCTD *pTransferDescriptor = (HCTD *)pPriv->addr[uChannel];
100+
101+
102+
103+
if (pTransferDescriptor)
104+
{
105+
constexpr uint32_t uRetryCount = 10;
106+
107+
uint32_t endpointType = pHcd->hc[uChannel].ep_type;
108+
109+
if ((endpointType == EP_TYPE_INTR))
110+
{
111+
// Disable the channel interupt and retransfer below
112+
pTransferDescriptor->state = USB_TYPE_IDLE ;
113+
HAL_HCD_DisableInt(pHcd, uChannel);
114+
}
115+
else if ((endpointType == EP_TYPE_BULK) || (endpointType == EP_TYPE_CTRL))
116+
{
117+
switch(urbState)
118+
{
119+
case URB_NOTREADY:
120+
{
121+
// If we have transfered any data then disable retries
122+
if(pHcd->hc[uChannel].xfer_count > 0)
123+
pTransferDescriptor->retry = 0xffffffff; // Disable retries
124+
else
125+
{
126+
// if the retry count is 0 then initialise downward counting retry
127+
// otherwise decrement retry count
128+
if(pTransferDescriptor->retry == 0)
129+
pTransferDescriptor->retry = uRetryCount;
130+
else
131+
pTransferDescriptor->retry--;
132+
}
133+
134+
// If our retry count has got down to 0 or we are an Ack then submit request again
135+
if((pTransferDescriptor->retry == 0) || (pTransferDescriptor->size==0))
136+
{
137+
// initialise downward counting retry
138+
pTransferDescriptor->retry = uRetryCount;
139+
140+
// resubmit the request.
141+
HAL_HCD_HC_SubmitRequest(pHcd, uChannel, pHcd->hc[uChannel].ep_is_in, endpointType, !pTransferDescriptor->setup, (uint8_t *) pTransferDescriptor->currBufPtr, pTransferDescriptor->size, 0);
142+
HAL_HCD_EnableInt(pHcd, uChannel);
143+
}
144+
}
145+
break;
146+
147+
case URB_DONE:
148+
{
149+
// this will be handled below for USB_TYPE_IDLE
150+
pTransferDescriptor->state = USB_TYPE_IDLE;
151+
}
152+
break;
153+
154+
case URB_ERROR:
155+
{
156+
// While USB_TYPE_ERROR in the endpoint state is used to activate error recovery, this value is actually never used.
157+
// Going here will lead to a timeout at a higher layer, because of ep_queue.get() timeout, which will activate error
158+
// recovery indirectly.
159+
pTransferDescriptor->state = USB_TYPE_ERROR;
160+
}
161+
break;
162+
163+
default:
164+
{
165+
pTransferDescriptor->state = USB_TYPE_PROCESSING;
166+
}
167+
break;
168+
}
169+
}
170+
171+
if (pTransferDescriptor->state == USB_TYPE_IDLE)
172+
{
173+
// Disable retrues
174+
pTransferDescriptor->retry = 0xffffffff; // Disable retries
175+
176+
// Update transfer descriptor buffer pointer
177+
pTransferDescriptor->currBufPtr += HAL_HCD_HC_GetXferCount(pHcd, uChannel);
178+
179+
// Call transferCompleted on correct object
180+
void (USBHALHost::*func)(volatile uint32_t addr) = pPriv->transferCompleted;
181+
(pPriv->inst->*func)(reinterpret_cast<std::uintptr_t>(pTransferDescriptor));
182+
}
183+
}
184+
}
185+
#else
94186
void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
95187
{
96188
USBHALHost_Private_t *priv = (USBHALHost_Private_t *)(hhcd->pData);
@@ -168,6 +260,7 @@ void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum,
168260
}
169261
}
170262
}
263+
#endif
171264

172265
USBHALHost *USBHALHost::instHost;
173266

@@ -348,6 +441,41 @@ void USBHALHost::_usbisr(void)
348441

349442
void USBHALHost::UsbIrqhandler()
350443
{
351-
HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
352-
}
444+
#if ARC_USB_FULL_SIZE
445+
// fix from Lix Paulian : https://community.st.com/t5/stm32-mcus-products/stm32f4-stm32f7-usb-host-core-interrupt-flood/td-p/436225/page/4
446+
447+
// Enable USB_OTG_HCINT_NAK interupts for CTRL and BULK on USB_OTG_GINTSTS_SOF (1ms)
448+
uint32_t ch_num;
449+
HCD_HandleTypeDef* hhcd = (HCD_HandleTypeDef *)usb_hcca;
450+
451+
if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF) && hhcd->Init.dma_enable == 0)
452+
{
453+
for (ch_num = 0; ch_num < hhcd->Init.Host_channels; ch_num++)
454+
{
455+
// workaround the interrupts flood issue: re-enable NAK interrupt
456+
USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINT_NAK;
457+
}
458+
}
459+
460+
HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
461+
462+
// Disable USB_OTG_HCINT_NAK interupts for CTRL and BULK on USB_OTG_GINTSTS_HCINT
463+
if (__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT) && hhcd->Init.dma_enable == 0)
464+
{
465+
for (ch_num = 0; ch_num < hhcd->Init.Host_channels; ch_num++)
466+
{
467+
if (USBx_HC(ch_num)->HCINT & USB_OTG_HCINT_NAK)
468+
{
469+
if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL) || (hhcd->hc[ch_num].ep_type == EP_TYPE_BULK))
470+
{
471+
// workaround the interrupts flood issue: disable NAK interrupt
472+
USBx_HC(ch_num)->HCINTMSK &= ~USB_OTG_HCINT_NAK;
473+
}
474+
}
475+
}
476+
}
477+
#else
478+
HAL_HCD_IRQHandler((HCD_HandleTypeDef *)usb_hcca);
353479
#endif
480+
}
481+
#endif

0 commit comments

Comments
 (0)