From c758f1cc147da100d346d5f7db26293fca1bcd46 Mon Sep 17 00:00:00 2001 From: Marc Desvaux Date: Mon, 6 Nov 2023 09:25:47 +0100 Subject: [PATCH] drivers: usb: device: usb_dc_stm32 issue USB drivers Isochronous endpoint issue with USB drivers on STM32G491 we setup an isochronous endpoint and are having an issue where every other frame sends the desired data sandwiched between garbage data. For isochronous the parameter ep_kind into the fonction : HAL_PCDEx_PMAConfig(PCD_HandleTypeDef *hpcd, uint16_t ep_addr, uint16_t ep_kind, uint32_t pmaadress) must be PCD_DBL_BUF. The parameter pmaadress (EP address in The PMA) is like that: EP address in The PMA: In case of single buffer endpoint this parameter is 16-bit value providing the address in PMA allocated to endpoint. In case of double buffer endpoint this parameter is a 32-bit value providing the endpoint buffer 0 address in the LSB part of 32-bit value and endpoint buffer 1 address in the MSB part of 32-bit value. Signed-off-by: Marc Desvaux --- drivers/usb/device/usb_dc_stm32.c | 35 ++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/drivers/usb/device/usb_dc_stm32.c b/drivers/usb/device/usb_dc_stm32.c index de0a8bc2a27..fe2c0b65f5d 100644 --- a/drivers/usb/device/usb_dc_stm32.c +++ b/drivers/usb/device/usb_dc_stm32.c @@ -639,20 +639,39 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const ep_cfg) LOG_DBG("ep 0x%02x, previous ep_mps %u, ep_mps %u, ep_type %u", ep_cfg->ep_addr, ep_state->ep_mps, ep_cfg->ep_mps, ep_cfg->ep_type); - #if defined(USB) || defined(USB_DRD_FS) if (ep_cfg->ep_mps > ep_state->ep_pma_buf_len) { - if (USB_RAM_SIZE <= - (usb_dc_stm32_state.pma_offset + ep_cfg->ep_mps)) { + if (ep_cfg->ep_type == USB_DC_EP_ISOCHRONOUS) { + if (USB_RAM_SIZE <= + (usb_dc_stm32_state.pma_offset + ep_cfg->ep_mps*2)) { + return -EINVAL; + } + } else if (USB_RAM_SIZE <= + (usb_dc_stm32_state.pma_offset + ep_cfg->ep_mps)) { return -EINVAL; } - HAL_PCDEx_PMAConfig(&usb_dc_stm32_state.pcd, ep, PCD_SNG_BUF, - usb_dc_stm32_state.pma_offset); - ep_state->ep_pma_buf_len = ep_cfg->ep_mps; - usb_dc_stm32_state.pma_offset += ep_cfg->ep_mps; + + if (ep_cfg->ep_type == USB_DC_EP_ISOCHRONOUS) { + HAL_PCDEx_PMAConfig(&usb_dc_stm32_state.pcd, ep, PCD_DBL_BUF, + usb_dc_stm32_state.pma_offset + + ((usb_dc_stm32_state.pma_offset + ep_cfg->ep_mps) << 16)); + ep_state->ep_pma_buf_len = ep_cfg->ep_mps*2; + usb_dc_stm32_state.pma_offset += ep_cfg->ep_mps*2; + } else { + HAL_PCDEx_PMAConfig(&usb_dc_stm32_state.pcd, ep, PCD_SNG_BUF, + usb_dc_stm32_state.pma_offset); + ep_state->ep_pma_buf_len = ep_cfg->ep_mps; + usb_dc_stm32_state.pma_offset += ep_cfg->ep_mps; + } } -#endif + if (ep_cfg->ep_type == USB_DC_EP_ISOCHRONOUS) { + ep_state->ep_mps = ep_cfg->ep_mps*2; + } else { + ep_state->ep_mps = ep_cfg->ep_mps; + } +#else ep_state->ep_mps = ep_cfg->ep_mps; +#endif switch (ep_cfg->ep_type) { case USB_DC_EP_CONTROL: