USBD_LL_GetRxDataSize/HAL_PCD_EP_GetRxCount return wrong value
davekeck opened this issue · 2 comments
When both of these conditions are true:
- A USB OTG HS device has DMA enabled ("Enable internal IP DMA" checkbox in the UI)
USBD_LL_PrepareReceive
is used to initiate a transfer that's larger than the max packet size
Under these circumstances, when the DataOut USB callback is called as a result of USBD_LL_PrepareReceive
, USBD_LL_GetRxDataSize
/HAL_PCD_EP_GetRxCount
return an incorrect value for the number of bytes received.
The bug appears to be due to these lines in PCD_EP_OutXfrComplete_int
:
STM32CubeF7/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_pcd.c
Lines 1986 to 1990 in 08376dc
Th above math incorrectly uses the the max packet size (instead of the transfer size), so that when the transfer size is larger than the max packet size, xfer_count
is assigned to an incorrect value, which breaks USBD_LL_GetRxDataSize
/HAL_PCD_EP_GetRxCount
.
This replacement code fixes the issue for me:
const uint32_t xfer_len = hpcd->OUT_ep[epnum].xfer_len;
const uint32_t xfrsiz = (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ);
if (xfer_len) {
const uint32_t xfer_count = xfer_len - xfrsiz;
hpcd->OUT_ep[epnum].xfer_count = xfer_count;
hpcd->OUT_ep[epnum].xfer_buff += xfer_count;
} else {
hpcd->OUT_ep[epnum].xfer_count = 0;
}
Hi @davekeck,
Thank you for this clear and concise report and for the fix proposal. It has been forwarded to our development teams. I will get to you as soon as they provide their feedback.
With regards,
ST Internal Reference: 120891