From bf0e8d158fad3845cc3d7b6895e2d8ba11806721 Mon Sep 17 00:00:00 2001 From: cumin <13809292481@163.com> Date: Thu, 27 Aug 2026 15:55:27 +0800 Subject: [PATCH 1/5] feat(usb): add STM32C5 HAL v2 USB device support --- libraries/SrcWrapper/inc/stm32_def.h | 6 +- libraries/USBDevice/inc/usbd_conf.h | 14 +- libraries/USBDevice/inc/usbd_ep_conf.h | 13 +- libraries/USBDevice/src/cdc/usbd_cdc.c | 12 +- libraries/USBDevice/src/usbd_conf.c | 5 +- libraries/USBDevice/src/usbd_confv2.c | 251 +++++++++++++++++++++++++ libraries/USBDevice/src/usbd_ep_conf.c | 3 +- 7 files changed, 289 insertions(+), 15 deletions(-) create mode 100644 libraries/USBDevice/src/usbd_confv2.c diff --git a/libraries/SrcWrapper/inc/stm32_def.h b/libraries/SrcWrapper/inc/stm32_def.h index e057418c0c..f63b83de26 100644 --- a/libraries/SrcWrapper/inc/stm32_def.h +++ b/libraries/SrcWrapper/inc/stm32_def.h @@ -203,11 +203,13 @@ __STATIC_INLINE void LL_RTC_SetBinMixBCDU(RTC_TypeDef *RTCx, uint32_t BinMixBcdU } #endif // STM32U0xx -/* STM32G0xx, STM32U0xx and some STM32U5xx defined USB_DRD_FS */ +/* Some STM32 series define USB_DRD_FS instead of the legacy USB instance. */ #if !defined(USB) && defined(USB_DRD_FS) #define USB USB_DRD_FS #define PinMap_USB PinMap_USB_DRD_FS - #if defined(STM32H5xx) || defined(STM32U0xx) ||\ + #if defined(STM32C5xx) + #define USB_BASE USB_DRD_FS_BASE + #elif defined(STM32H5xx) || defined(STM32U0xx) ||\ defined(STM32U3xx) || defined(STM32U5xx) #define USB_BASE USB_DRD_BASE #if !defined(__HAL_RCC_USB_CLK_ENABLE) diff --git a/libraries/USBDevice/inc/usbd_conf.h b/libraries/USBDevice/inc/usbd_conf.h index a08fa61e7e..326a9e01c3 100644 --- a/libraries/USBDevice/inc/usbd_conf.h +++ b/libraries/USBDevice/inc/usbd_conf.h @@ -29,9 +29,6 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ #include "stm32_def.h" -#if defined(USE_HALV2_DRIVER) -#error "USB library is not yet compatible with HALv2 driver." -#else #if !defined(USB_BASE) && !defined(USB_OTG_DEVICE_BASE) #error "This board does not support USB! Select 'None' in the 'Tools->USB interface' menu" #endif @@ -40,8 +37,6 @@ extern "C" { #endif #if !defined(USB_BASE) && !defined(USB_OTG_FS) && defined(USB_OTG_HS) && !defined(USE_USB_HS) #error "This board support only USB High Speed! Select 'High Speed' or 'High Speed in Full Speed mode' in the 'Tools->USB interface' menu" -#endif - #endif #include #include @@ -77,7 +72,7 @@ extern "C" { #elif defined(STM32G0B1xx) || defined(STM32G0C1xx) #define USB_IRQn USB_UCPD1_2_IRQn #define USB_IRQHandler USB_UCPD1_2_IRQHandler -#elif defined(STM32C0xx) || defined(STM32H5xx) || defined(STM32U0xx) +#elif defined(STM32C0xx) || defined(STM32C5xx) || defined(STM32H5xx) || defined(STM32U0xx) #define USB_IRQn USB_DRD_FS_IRQn #define USB_IRQHandler USB_DRD_FS_IRQHandler #elif defined(STM32U5xx) && !defined(USB_DRD_FS) @@ -90,6 +85,13 @@ extern "C" { #endif /* USB_BASE */ +#if !defined(PCD_SNG_BUF) && defined(HAL_PCD_SNG_BUF) +#define PCD_SNG_BUF HAL_PCD_SNG_BUF +#endif +#if !defined(PCD_DBL_BUF) && defined(HAL_PCD_DBL_BUF) +#define PCD_DBL_BUF HAL_PCD_DBL_BUF +#endif + #ifndef __HAL_PCD_GATE_PHYCLOCK #define __HAL_PCD_GATE_PHYCLOCK(_DUMMY_) #endif diff --git a/libraries/USBDevice/inc/usbd_ep_conf.h b/libraries/USBDevice/inc/usbd_ep_conf.h index 354b6f4d0c..b305b64e4f 100644 --- a/libraries/USBDevice/inc/usbd_ep_conf.h +++ b/libraries/USBDevice/inc/usbd_ep_conf.h @@ -69,10 +69,21 @@ typedef struct { #ifdef USBD_USE_CDC #define PMA_CDC_OUT_BASE (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE) +#if defined(STM32C5xx) +/* + * The C5 USB DRD FS peripheral is used with bulk double buffering disabled. + * Keep each CDC endpoint in its own 64-byte PMA area; in particular, the + * interrupt IN endpoint must not overlap the bulk IN data buffer. + */ +#define PMA_CDC_OUT_ADDR PMA_CDC_OUT_BASE +#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) +#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + USB_FS_MAX_PACKET_SIZE) +#else #define PMA_CDC_OUT_ADDR ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \ (PMA_CDC_OUT_BASE << 16U)) #define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2) #define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE) +#endif #endif /* USBD_USE_CDC */ #ifdef USBD_USE_HID_COMPOSITE #define PMA_MOUSE_IN_ADDR (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE) @@ -86,4 +97,4 @@ extern const ep_desc_t ep_def[DEV_NUM_EP + 1]; #endif /* USBCON */ #endif /* __USBD_EP_CONF_H */ -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/libraries/USBDevice/src/cdc/usbd_cdc.c b/libraries/USBDevice/src/cdc/usbd_cdc.c index d2e8cf7dfb..803476aca9 100644 --- a/libraries/USBDevice/src/cdc/usbd_cdc.c +++ b/libraries/USBDevice/src/cdc/usbd_cdc.c @@ -701,7 +701,11 @@ static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc; +#if defined(USE_HALV2_DRIVER) + hal_pcd_handle_t *hpcd = (hal_pcd_handle_t *)pdev->pData; +#else PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData; +#endif if (pdev->pClassDataCmsit[pdev->classId] == NULL) { return (uint8_t)USBD_FAIL; @@ -710,7 +714,13 @@ static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum) hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId]; if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) && - ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U)) { + ((pdev->ep_in[epnum & 0xFU].total_length % +#if defined(USE_HALV2_DRIVER) + hpcd->in_ep[epnum & 0xFU].max_packet +#else + hpcd->IN_ep[epnum & 0xFU].maxpacket +#endif + ) == 0U)) { /* Update the packet total length */ pdev->ep_in[epnum & 0xFU].total_length = 0U; diff --git a/libraries/USBDevice/src/usbd_conf.c b/libraries/USBDevice/src/usbd_conf.c index 8b0d8184aa..85398b8bea 100644 --- a/libraries/USBDevice/src/usbd_conf.c +++ b/libraries/USBDevice/src/usbd_conf.c @@ -16,7 +16,7 @@ * ****************************************************************************** */ -#ifdef USBCON +#if defined(USBCON) && !defined(USE_HALV2_DRIVER) /* Includes ------------------------------------------------------------------*/ #include "usbd_core.h" #include "usbd_if.h" @@ -718,6 +718,5 @@ void USBD_LL_Delay(uint32_t Delay) HAL_Delay(Delay); } #endif /* HAL_PCD_MODULE_ENABLED */ -#endif /* USBCON */ +#endif /* USBCON && !USE_HALV2_DRIVER */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - diff --git a/libraries/USBDevice/src/usbd_confv2.c b/libraries/USBDevice/src/usbd_confv2.c new file mode 100644 index 0000000000..f6c56ac66b --- /dev/null +++ b/libraries/USBDevice/src/usbd_confv2.c @@ -0,0 +1,251 @@ +/** + ****************************************************************************** + * @file usbd_confv2.c + * @brief HAL v2 USB device low-level adapter. + ****************************************************************************** + */ + +#if defined(USBCON) && defined(USE_HALV2_DRIVER) + +#include "usbd_core.h" +#include "usbd_if.h" +#include "usbd_ep_conf.h" + +#ifndef USE_HAL_PCD_MODULE + #error "USE_HAL_PCD_MODULE is required" +#endif + +static hal_pcd_handle_t g_hpcd; +static USBD_HandleTypeDef *g_pdev; +static uint8_t g_stalled_in; +static uint8_t g_stalled_out; + +static void USBD_V2_ConfigPinsAndIrq(void) +{ + /* The HAL v2 USB DRD FS PCD owns PA11/PA12 and configures these fixed USB + * pins during peripheral initialization. */ + + HAL_RCC_USB_EnableClock(); + HAL_CORTEX_NVIC_SetPriority(USB_IRQn, USBD_IRQ_PRIO, USBD_IRQ_SUBPRIO); + HAL_CORTEX_NVIC_EnableIRQ(USB_IRQn); +} + +void HAL_PCD_SetupStageCallback(hal_pcd_handle_t *hpcd) +{ + USBD_LL_SetupStage(g_pdev, (uint8_t *)hpcd->setup); +} + +void HAL_PCD_DataOutStageCallback(hal_pcd_handle_t *hpcd, uint8_t epnum) +{ + USBD_LL_DataOutStage(g_pdev, epnum, hpcd->out_ep[epnum].p_xfer_buffer); +} + +void HAL_PCD_DataInStageCallback(hal_pcd_handle_t *hpcd, uint8_t epnum) +{ + USBD_LL_DataInStage(g_pdev, epnum, hpcd->in_ep[epnum].p_xfer_buffer); +} + +void HAL_PCD_SofCallback(hal_pcd_handle_t *hpcd) +{ + (void)hpcd; + USBD_LL_SOF(g_pdev); +} + +void HAL_PCD_ResetCallback(hal_pcd_handle_t *hpcd) +{ + (void)hpcd; + USBD_LL_Reset(g_pdev); + USBD_LL_SetSpeed(g_pdev, USBD_SPEED_FULL); +} + +void HAL_PCD_SuspendCallback(hal_pcd_handle_t *hpcd) +{ + (void)hpcd; + USBD_LL_Suspend(g_pdev); +} + +void HAL_PCD_ResumeCallback(hal_pcd_handle_t *hpcd) +{ + (void)hpcd; + USBD_LL_Resume(g_pdev); +} + +void HAL_PCD_ISOOUTIncompleteCallback(hal_pcd_handle_t *hpcd, uint8_t epnum) +{ + (void)hpcd; + USBD_LL_IsoOUTIncomplete(g_pdev, epnum); +} + +void HAL_PCD_ISOINIncompleteCallback(hal_pcd_handle_t *hpcd, uint8_t epnum) +{ + (void)hpcd; + USBD_LL_IsoINIncomplete(g_pdev, epnum); +} + +void HAL_PCD_ConnectCallback(hal_pcd_handle_t *hpcd) +{ + (void)hpcd; + USBD_LL_DevConnected(g_pdev); +} + +void HAL_PCD_DisconnectCallback(hal_pcd_handle_t *hpcd) +{ + (void)hpcd; + USBD_LL_DevDisconnected(g_pdev); +} + +void USB_IRQHandler(void) +{ + HAL_PCD_IRQHandler(&g_hpcd); +} + +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + hal_pcd_config_t config = { + .dma_enable = HAL_PCD_DMA_DISABLED, + .pcd_speed = HAL_PCD_SPEED_FS, + .phy_interface = HAL_PCD_PHY_EMBEDDED_FS, + .sof_enable = HAL_PCD_SOF_DISABLED, + .lpm_enable = HAL_PCD_LPM_DISABLED, + .battery_charging_enable = HAL_PCD_BCD_DISABLED, + .vbus_sensing_enable = HAL_PCD_VBUS_SENSE_DISABLED, + .bulk_doublebuffer_enable = HAL_PCD_BULK_DB_DISABLED, + }; + + USBD_V2_ConfigPinsAndIrq(); + + g_pdev = pdev; + g_stalled_in = 0U; + g_stalled_out = 0U; + pdev->pData = &g_hpcd; + + if (HAL_PCD_Init(&g_hpcd, HAL_PCD_DRD_FS) != HAL_OK) { + Error_Handler(); + } + if (HAL_PCD_SetConfig(&g_hpcd, &config) != HAL_OK) { + Error_Handler(); + } + + for (uint32_t i = 0U; i < (DEV_NUM_EP + 1U); i++) { + if (HAL_PCD_PMAConfig(&g_hpcd, ep_def[i].ep_adress, ep_def[i].ep_kind, + ep_def[i].ep_size) != HAL_OK) { + Error_Handler(); + } + } + + /* HAL v2 exposes the USB pull-up through the PCD device-connect API. Do + * the startup detach after the PCD has been initialized instead of reaching + * into a board-specific GPIO pin from the common re-enumeration helper. + * HAL_PCD_Start() performs the matching attach once USB is ready. */ + (void)HAL_PCD_DeviceDisconnect(&g_hpcd); + HAL_Delay(USBD_ENUM_DELAY); + + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + (void)pdev; + HAL_CORTEX_NVIC_DisableIRQ(USB_IRQn); + HAL_PCD_DeInit(&g_hpcd); + HAL_RCC_USB_DisableClock(); + g_pdev = NULL; + return USBD_OK; +} + +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + (void)pdev; + return (HAL_PCD_Start(&g_hpcd) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + (void)pdev; + return (HAL_PCD_Stop(&g_hpcd) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t ep_type, uint16_t ep_mps) +{ + (void)pdev; + return (HAL_PCD_OpenEndpoint(&g_hpcd, ep_addr, ep_mps, + (hal_pcd_ep_type_t)ep_type) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + (void)pdev; + return (HAL_PCD_CloseEndpoint(&g_hpcd, ep_addr) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + (void)pdev; + return (HAL_PCD_FlushEndpoint(&g_hpcd, ep_addr) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + uint8_t mask = (uint8_t)(1U << (ep_addr & 0x0FU)); + (void)pdev; + if ((ep_addr & 0x80U) != 0U) { + g_stalled_in |= mask; + } else { + g_stalled_out |= mask; + } + return (HAL_PCD_SetEndpointStall(&g_hpcd, ep_addr) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + uint8_t mask = (uint8_t)(1U << (ep_addr & 0x0FU)); + (void)pdev; + if ((ep_addr & 0x80U) != 0U) { + g_stalled_in &= (uint8_t)~mask; + } else { + g_stalled_out &= (uint8_t)~mask; + } + return (HAL_PCD_ClearEndpointStall(&g_hpcd, ep_addr) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + uint8_t mask = (uint8_t)(1U << (ep_addr & 0x0FU)); + (void)pdev; + return ((ep_addr & 0x80U) != 0U) ? ((g_stalled_in & mask) != 0U) : + ((g_stalled_out & mask) != 0U); +} + +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + (void)pdev; + return (HAL_PCD_SetDeviceAddress(&g_hpcd, dev_addr) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size) +{ + (void)pdev; + return (HAL_PCD_SetEndpointTransmit(&g_hpcd, ep_addr, pbuf, size) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, + uint8_t *pbuf, uint32_t size) +{ + (void)pdev; + return (HAL_PCD_SetEndpointReceive(&g_hpcd, ep_addr, pbuf, size) == HAL_OK) ? USBD_OK : USBD_FAIL; +} + +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + (void)pdev; + return HAL_PCD_EP_GetRxCount(&g_hpcd, ep_addr); +} + +void USBD_LL_Delay(uint32_t delay) +{ + HAL_Delay(delay); +} + +#endif /* USBCON && USE_HALV2_DRIVER */ diff --git a/libraries/USBDevice/src/usbd_ep_conf.c b/libraries/USBDevice/src/usbd_ep_conf.c index d872acca5f..8759e49fda 100644 --- a/libraries/USBDevice/src/usbd_ep_conf.c +++ b/libraries/USBDevice/src/usbd_ep_conf.c @@ -37,7 +37,7 @@ const ep_desc_t ep_def[] = { #else {0x00, PMA_EP0_OUT_ADDR, PCD_SNG_BUF}, {0x80, PMA_EP0_IN_ADDR, PCD_SNG_BUF}, -#ifndef USBD_CDC_USE_SINGLE_BUFFER +#if !defined(STM32C5xx) && !defined(USBD_CDC_USE_SINGLE_BUFFER) {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_DBL_BUF}, #else {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_SNG_BUF}, @@ -72,4 +72,3 @@ const ep_desc_t ep_def[] = { #endif /* HAL_PCD_MODULE_ENABLED && USBCON */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ - From ba35658279b3a8f34ee8923417342796d9a98b62 Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 8 Sep 2026 16:33:54 +0200 Subject: [PATCH 2/5] chore(cmake): update database Signed-off-by: Frederic Pillon --- libraries/USBDevice/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/USBDevice/CMakeLists.txt b/libraries/USBDevice/CMakeLists.txt index cdf27f3bec..f1270cf7cb 100644 --- a/libraries/USBDevice/CMakeLists.txt +++ b/libraries/USBDevice/CMakeLists.txt @@ -28,6 +28,7 @@ add_library(USBDevice_bin OBJECT EXCLUDE_FROM_ALL src/usb_device_ctlreq.c src/usb_device_ioreq.c src/usbd_conf.c + src/usbd_confv2.c src/usbd_desc.c src/usbd_ep_conf.c src/usbd_if.c From 4745b2364400faeb3c0dfd78e72be2aeb5874b14 Mon Sep 17 00:00:00 2001 From: cumin <13809292481@163.com> Date: Mon, 7 Sep 2026 10:54:26 +0800 Subject: [PATCH 3/5] fix(usb): route HAL v2 re-enumeration through PCD adapter Signed-off-by: cumin <13809292481@163.com> --- libraries/USBDevice/src/usbd_if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/USBDevice/src/usbd_if.c b/libraries/USBDevice/src/usbd_if.c index fb76a5a778..6353c09e4f 100644 --- a/libraries/USBDevice/src/usbd_if.c +++ b/libraries/USBDevice/src/usbd_if.c @@ -11,7 +11,7 @@ #include "usbd_cdc_if.h" #include "stm32yyxx_ll_system.h" -#if !defined(USBD_REENUM_DISABLED) +#if !defined(USBD_REENUM_DISABLED) && !defined(USE_HALV2_DRIVER) /* * Below, support for re-attaching to USB is handled. USB-attachment is From e142d868deaca7760dcd6a817b9b00595700df4a Mon Sep 17 00:00:00 2001 From: cumin <13809292481@163.com> Date: Mon, 7 Sep 2026 11:18:33 +0800 Subject: [PATCH 4/5] fix(usb): defer HAL v2 reconnect until device start Signed-off-by: cumin <13809292481@163.com> --- libraries/USBDevice/src/usbd_confv2.c | 30 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/libraries/USBDevice/src/usbd_confv2.c b/libraries/USBDevice/src/usbd_confv2.c index f6c56ac66b..7e135f9566 100644 --- a/libraries/USBDevice/src/usbd_confv2.c +++ b/libraries/USBDevice/src/usbd_confv2.c @@ -30,6 +30,28 @@ static void USBD_V2_ConfigPinsAndIrq(void) HAL_CORTEX_NVIC_EnableIRQ(USB_IRQn); } +#if !defined(USBD_REENUM_DISABLED) +/* HAL v2 adapters own USB pull-up control. Keep the common re-enumeration + * entry point, but implement it through the PCD API rather than the legacy + * USB_DevConnect/USB_DevDisconnect helpers. */ +void USBD_reenumerate(void) +{ + if ((g_hpcd.global_state == HAL_PCD_STATE_IDLE) || + (g_hpcd.global_state == HAL_PCD_STATE_ACTIVE)) { + const uint32_t was_active = (g_hpcd.global_state == HAL_PCD_STATE_ACTIVE); + + (void)HAL_PCD_DeviceDisconnect(&g_hpcd); + HAL_Delay(USBD_ENUM_DELAY); + + /* HAL_PCD_Start() connects the device when startup is still in the IDLE + * state. Only reconnect here when the device was already running. */ + if (was_active != 0U) { + (void)HAL_PCD_DeviceConnect(&g_hpcd); + } + } +} +#endif + void HAL_PCD_SetupStageCallback(hal_pcd_handle_t *hpcd) { USBD_LL_SetupStage(g_pdev, (uint8_t *)hpcd->setup); @@ -133,12 +155,8 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) } } - /* HAL v2 exposes the USB pull-up through the PCD device-connect API. Do - * the startup detach after the PCD has been initialized instead of reaching - * into a board-specific GPIO pin from the common re-enumeration helper. - * HAL_PCD_Start() performs the matching attach once USB is ready. */ - (void)HAL_PCD_DeviceDisconnect(&g_hpcd); - HAL_Delay(USBD_ENUM_DELAY); + /* HAL v2 exposes the USB pull-up through the PCD device-connect API. */ + USBD_reenumerate(); return USBD_OK; } From 8adf1fc5df9c096fcf5fd58b16ce4aae2a0dbe0a Mon Sep 17 00:00:00 2001 From: Frederic Pillon Date: Tue, 15 Sep 2026 15:40:52 +0200 Subject: [PATCH 5/5] fix(usb): double buffer management also enable USB double buffer for HALv2 Signed-off-by: Frederic Pillon --- cores/arduino/stm32/stm32yyxx_hal_conf.h | 5 +++++ libraries/USBDevice/inc/usbd_ep_conf.h | 20 +++++++++----------- libraries/USBDevice/src/usbd_ep_conf.c | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/cores/arduino/stm32/stm32yyxx_hal_conf.h b/cores/arduino/stm32/stm32yyxx_hal_conf.h index b4d7393229..53a2437544 100644 --- a/cores/arduino/stm32/stm32yyxx_hal_conf.h +++ b/cores/arduino/stm32/stm32yyxx_hal_conf.h @@ -148,6 +148,11 @@ #undef USE_HAL_PCD_MODULE #endif #define USE_HAL_PCD_MODULE 1U + #if defined(USBD_CDC_USE_SINGLE_BUFFER) + #define USE_HAL_PCD_USB_DOUBLE_BUFFER 0U + #else + #define USE_HAL_PCD_USB_DOUBLE_BUFFER 1U + #endif #endif #else /* HALv1 */ diff --git a/libraries/USBDevice/inc/usbd_ep_conf.h b/libraries/USBDevice/inc/usbd_ep_conf.h index b305b64e4f..4636b36ae5 100644 --- a/libraries/USBDevice/inc/usbd_ep_conf.h +++ b/libraries/USBDevice/inc/usbd_ep_conf.h @@ -25,6 +25,10 @@ #include #include "usbd_def.h" +#if defined (USE_HAL_PCD_USB_DOUBLE_BUFFER) && (USE_HAL_PCD_USB_DOUBLE_BUFFER == 0) + #define USBD_CDC_USE_SINGLE_BUFFER +#endif + typedef struct { uint32_t ep_adress; /* Endpoint address */ uint32_t ep_size; /* Endpoint size */ @@ -69,21 +73,15 @@ typedef struct { #ifdef USBD_USE_CDC #define PMA_CDC_OUT_BASE (PMA_EP0_IN_ADDR + USB_MAX_EP0_SIZE) -#if defined(STM32C5xx) -/* - * The C5 USB DRD FS peripheral is used with bulk double buffering disabled. - * Keep each CDC endpoint in its own 64-byte PMA area; in particular, the - * interrupt IN endpoint must not overlap the bulk IN data buffer. - */ -#define PMA_CDC_OUT_ADDR PMA_CDC_OUT_BASE -#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) -#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + USB_FS_MAX_PACKET_SIZE) -#else +#if !defined(USBD_CDC_USE_SINGLE_BUFFER) #define PMA_CDC_OUT_ADDR ((PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) | \ (PMA_CDC_OUT_BASE << 16U)) #define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE * 2) -#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE) +#else +#define PMA_CDC_OUT_ADDR PMA_CDC_OUT_BASE +#define PMA_CDC_IN_ADDR (PMA_CDC_OUT_BASE + USB_FS_MAX_PACKET_SIZE) #endif +#define PMA_CDC_CMD_ADDR (PMA_CDC_IN_ADDR + CDC_CMD_PACKET_SIZE) #endif /* USBD_USE_CDC */ #ifdef USBD_USE_HID_COMPOSITE #define PMA_MOUSE_IN_ADDR (PMA_EP0_IN_ADDR + HID_MOUSE_EPIN_SIZE) diff --git a/libraries/USBDevice/src/usbd_ep_conf.c b/libraries/USBDevice/src/usbd_ep_conf.c index 8759e49fda..3689fd5eed 100644 --- a/libraries/USBDevice/src/usbd_ep_conf.c +++ b/libraries/USBDevice/src/usbd_ep_conf.c @@ -37,7 +37,7 @@ const ep_desc_t ep_def[] = { #else {0x00, PMA_EP0_OUT_ADDR, PCD_SNG_BUF}, {0x80, PMA_EP0_IN_ADDR, PCD_SNG_BUF}, -#if !defined(STM32C5xx) && !defined(USBD_CDC_USE_SINGLE_BUFFER) +#if !defined(USBD_CDC_USE_SINGLE_BUFFER) {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_DBL_BUF}, #else {CDC_OUT_EP, PMA_CDC_OUT_ADDR, PCD_SNG_BUF},