on
2025-05-28
7:02 AM
- edited on
2025-06-17
5:14 AM
by
Laurids_PETERSE
This article addresses an issue where the USB_OTG_GRSTCTL_CSRST bit in the GRSTCTL register fails to reset, resulting in a timeout during USB initialization. The problem is related to timing and initialization, particularly with the USB PHY and clock configuration. Below, we provide an in-depth explanation, troubleshooting steps, and specific solutions.
During the USB initialization process, the USB_CoreReset() function is responsible for resetting the USB core by masking the CSRST bit in the GRSTCTL register. However, the bit remains unmasked, causing the function to timeout. The relevant code snippet highlights the problematic loop:
do
{
count++;
if (count > HAL_USB_TIMEOUT)
{
return HAL_TIMEOUT;
}
} while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
The sequence of function calls leading to the issue is as follows:
USB_CoreReset
└ USB_CoreInit
└ HAL_PCD_Init
└ USBD_LL_Init
└ MX_USB_DEVICE_Init
└ main
This suggests that the issue might be related to the initialization of the USB controller or the PHY.
/** Enable USB Voltage detector */
HAL_PWREx_EnableUSBVoltageDetector();
/** Enable USB HS Regulator */
HAL_PWREx_EnableUSBHSregulator();
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
/* PHY clock enable */
__HAL_RCC_USBPHYC_CLK_ENABLE();
For STM32F72x lines, the RCC OTGHSULPIEN is still required even for the internal HS PHY in usbh_conf.c or usbd_conf.c.
/* Enable HS PHY Clock */
__HAL_RCC_OTGPHYC_CLK_ENABLE();
/* Enable USB HS Clocks */
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
/* OTGHSULPIEN is still required even for the internal HS PHY */
__HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
Here is an overview of USB HS controller and USB FS controller extracted from RM0477.
OTG_HS PHY (also called USBPHYC) does not intervene when using FS controller unless selecting its clock source. The following diagram gives an overview of the clock distribution of USB controllers in STM32H7RS.
The STM32H7RS series has a more complex clock distribution for USB controllers. The USBPHYC block is intended for the OTG_HS controller.
If using clk48mohci (from USBPHYC), ensure the USB HS regulator is enabled:
HAL_PWREx_EnableUSBHSRegulator();
Step 1. Set the USB OTG_HS PHY1 reference clock source including setting the clock divider in stm32n6xx_hal_msp.c.
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBPHY1;
PeriphClkInitStruct.UsbPhy1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
Error_Handler();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Resets the USB PHY and OTG HS to their default states*/
LL_AHB5_GRP1_ForceReset(0x00800000);
__HAL_RCC_USB1_OTG_HS_FORCE_RESET();
__HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET();
/*Select HSE clock divided by 2*/
LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock();
/*Release Reset on USB PHY*/
LL_AHB5_GRP1_ReleaseReset(0x00800000);
Step 2. Enable the peripheral clock.
__HAL_RCC_USB1_OTG_HS_CLK_ENABLE();
HAL_Delay(1);
USB1_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4);
USB1_HS_PHYC->USBPHYC_CR |= (0x1 << 16) | (0x2 << 4) | (0x1 << 2) | 0x1U;
__HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET();
HAL_Delay(1);
__HAL_RCC_USB1_OTG_HS_RELEASE_RESET();
__HAL_RCC_USB1_OTG_HS_PHY_CLK_ENABLE();
Step 3. Ensure consistent delays
HAL_Delay(1) introduced here is dependent on CPU frequency and may not be reliable. You can insert __NOP() to ensure that the delay is consistent. The volatile keyword ensures that the loop is not optimized away by the compiler.
/* Required few clock cycles before accessing USB PHY Controller Registers */
for (volatile uint32_t i = 0; i < 10; i++) {
__NOP(); // No Operation instruction to create a delay
}
A delay of 10 cycles of the PHY clock must be inserted between PHY operations, specifically when setting the USB_OTG_GUSBCFG_PHYSE in CoreInit() and setting USB_OTG_GRSTCTL_CSRST in USB_CoreReset().
This delay is necessary to avoid the situation where the CSRT bit in OTG_GRSTCTL gets stuck, which can result in a timeout error. The need for this delay is related to the dependency on compiler optimization, PHY frequency, and CPU frequency.
To conclude, these points indicate that the CSRST bit issue is related to timing and initialization problems across different STM32 platforms. Adjusting the delay between certain operations or manually resetting the module might help mitigate the issue.