From d6b612257ed1026cccd18c620d3d6cb51d5b2cb2 Mon Sep 17 00:00:00 2001 From: Simon Kueppers Date: Thu, 5 Jan 2023 14:39:23 +0100 Subject: [PATCH] Fixed bug where with some devices, the TU_ASSERT inserted with this commit gets triggered for ISOCHRONOUS endpoints. It is necessary for those endpoints to set the NUM_BLOCK and BLSIZE for the receiving buffer in both, USB_COUNTn_TX and USB_COUNTn_RX. Despite the datasheet showing those fields only for the USB_COUNTn_RX register --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 15 ++++++++++++--- .../st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h | 9 +++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 648e8f8d0..fdcb2c48d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -562,6 +562,8 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) count = pcd_get_ep_rx_cnt(USB, EPindex); } + TU_ASSERT(count <= xfer->max_packet_size, /**/); + // Clear RX CTR interrupt flag if(ep_addr != 0u) { @@ -599,7 +601,12 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) } else { pcd_set_ep_rx_bufsize(USB, EPindex,remaining); } - pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + + if (!((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS)) { + /* Set endpoint active again for receiving more data. + * Note that isochronous endpoints stay active always */ + pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + } } } @@ -881,7 +888,8 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc (void)rhport; uint8_t const epnum = dcd_ep_alloc(p_endpoint_desc->bEndpointAddress, p_endpoint_desc->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); - const uint16_t buffer_size = pcd_aligned_buffer_size(tu_edpt_packet_size(p_endpoint_desc)); + const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); + const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint16_t pma_addr; uint32_t wType; @@ -921,6 +929,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc if( (dir == TUSB_DIR_IN) || (wType == USB_EP_ISOCHRONOUS) ) { *pcd_ep_tx_address_ptr(USB, epnum) = pma_addr; + pcd_set_ep_tx_bufsize(USB, epnum, buffer_size); pcd_clear_tx_dtog(USB, epnum); } @@ -948,7 +957,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc } } - xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = buffer_size; + xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->max_packet_size = packet_size; xfer_ctl_ptr(p_endpoint_desc->bEndpointAddress)->epnum = epnum; return true; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h index 98cf008d4..f4966907a 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev_pvt_st.h @@ -281,6 +281,13 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); } +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_bufsize(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) +{ + __IO uint16_t *pdwReg = pcd_ep_tx_cnt_ptr((USBx),(bEpNum)); + wCount = pcd_aligned_buffer_size(wCount); + pcd_set_ep_cnt_reg(pdwReg, wCount); +} + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_bufsize(USB_TypeDef * USBx, uint32_t bEpNum, uint32_t wCount) { __IO uint16_t *pdwReg = pcd_ep_rx_cnt_ptr((USBx),(bEpNum)); @@ -310,6 +317,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx { regVal ^= USB_EPTX_DTOG2; } + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpNum, regVal); } /* pcd_set_ep_tx_status */ @@ -337,6 +345,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx { regVal ^= USB_EPRX_DTOG2; } + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpNum, regVal); } /* pcd_set_ep_rx_status */