2024-11-07 04:22 AM - edited 2024-11-07 05:56 AM
Hello,
I'm trying to use the USB-HS peripheral with the built-in PHY on Nucleo STM32H7S3L8
I'm using CubeMX generated code from CubeIDE. I have not chosen the Nucleo board on CubeMX, because it was causing some issues with the MPU. Instead, I've chosen the MCU (STM32H7S3L8).
The peripheral times out during initialization at a usb core soft reset, just after enabling the internal PHY. What am I doing wrong? Has anyone been able to use the USB HS PHY on this device/board.
This is the USB_CoreReset call where I am getting a HAL_TIMEOUT:
HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
{
HAL_StatusTypeDef ret;
#if defined (USB_OTG_HS)
if (USBx == USB_OTG_HS)
{
if (cfg.phy_itface == USB_OTG_HS_EMBEDDED_PHY)
{
/* Init The UTMI Interface */
USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS);
}
/* Reset after a PHY select */
ret = USB_CoreReset(USBx);
...
These are the things in the code which are possibly relevant :
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USBPHYC;
PeriphClkInit.UsbPhycClockSelection = RCC_USBPHYCCLKSOURCE_HSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { die(); }
__HAL_RCC_USBPHYC_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
HAL_NVIC_SetPriority(USB_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USB_IRQn);
if(HAL_PWREx_EnableUSBVoltageDetector() != HAL_OK) { die(); }
usb_hpcd.Instance = USB_OTG_HS;
usb_hpcd.Init.speed = PCD_SPEED_HIGH;
usb_hpcd.Init.dev_endpoints = CFG_TUD_ENDPOINTS;
usb_hpcd.Init.dma_enable = DISABLE;
usb_hpcd.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY;
usb_hpcd.Init.Sof_enable = DISABLE;
usb_hpcd.Init.low_power_enable = DISABLE;
usb_hpcd.Init.lpm_enable = ENABLE;
usb_hpcd.Init.vbus_sensing_enable = DISABLE;
usb_hpcd.Init.use_dedicated_ep1 = DISABLE;
usb_hpcd.Init.vbus_sensing_enable = DISABLE;
HAL_StatusTypeDef result = HAL_PCD_Init(&usb_hpcd);
if (result != HAL_OK){
die();
};
This is the main clock configuration :
void clock_set_default(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE0) != HAL_OK)
{
die();
}
/** Configure LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE
|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL1.PLLM = 2;
RCC_OscInitStruct.PLL1.PLLN = 50;
RCC_OscInitStruct.PLL1.PLLP = 1;
RCC_OscInitStruct.PLL1.PLLQ = 2;
RCC_OscInitStruct.PLL1.PLLR = 2;
RCC_OscInitStruct.PLL1.PLLS = 2;
RCC_OscInitStruct.PLL1.PLLT = 2;
RCC_OscInitStruct.PLL1.PLLFractional = 0;
RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL2.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL2.PLLM = 3;
RCC_OscInitStruct.PLL2.PLLN = 50;
RCC_OscInitStruct.PLL2.PLLP = 2;
RCC_OscInitStruct.PLL2.PLLQ = 4;
RCC_OscInitStruct.PLL2.PLLR = 2;
RCC_OscInitStruct.PLL2.PLLS = 2;
RCC_OscInitStruct.PLL2.PLLT = 1;
RCC_OscInitStruct.PLL2.PLLFractional = 0;
RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL3.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL3.PLLM = 3;
RCC_OscInitStruct.PLL3.PLLN = 50;
RCC_OscInitStruct.PLL3.PLLP = 2;
RCC_OscInitStruct.PLL3.PLLQ = 4;
RCC_OscInitStruct.PLL3.PLLR = 4;
RCC_OscInitStruct.PLL3.PLLS = 8;
RCC_OscInitStruct.PLL3.PLLT = 2;
RCC_OscInitStruct.PLL3.PLLFractional = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
die();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_PCLK4|RCC_CLOCKTYPE_PCLK5;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
RCC_ClkInitStruct.APB5CLKDivider = RCC_APB5_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
{
die();
}
}
The HSE on the board is 24MHz, though I don't think there is any place in the code where this is defined for the USB PLL to be correctly configured. I also don't seem to have done anything to enable the USB PHY other than too enable the PHYC clock.
I have also not done anything with the UCPD, though the nucleo is wired to a Type C port with another IC involved for USB C PD control. Could this cause the PHY to not startup?
Any suggestions would be appreciated.
Solved! Go to Solution.
2024-11-08 10:06 PM
Thank you for your input, I expect I might have figured out the problem based on the example you linked to. I have figured out what the problem was by trial and error, though : USB HS requires the USB HS regulator enabled.
This might be specified somewhere in the datasheet, but I could not find it. I suspect there is a gap in the documentation here. Enabling USB HS on CubeMX does not automatically enable the USB HS regulator, either, though I don't know of any other alternate power sources for the USB HS PHY.
There are two regulators on the chip :
- USBREG
- USBHSREG
USBREG is discussed in some detail in the reference manual, and the schematics of the nucleo show that it is connected to an external 3.3V supply. This supply is related to the VDD33USB pin. Enabling USBREG makes HAL_PWREx_EnableUSBVoltageDetector() error out.
USBHSREG does not seem to be discussed in the reference manual, and the phrase "USBHSREG" shows up only in the register map. It does need to be enabled. If it is not enabled, HAL_PWREx_EnableUSBVoltageDetector() reports no errors, but the PHY remains unpowered.
From the power control block diagram, I assumed the HS PHY draws power from DVDD, which is powered by VCAP in the schematic. The internal LDO is enabled by `HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY)`, so VCAP should be powered and I presumed that would be enough. My reading of the documentation was that USBREG and USBHSREG are similar, one for the FS and the other for the HS.
On a side note, I have not had to do any configuration of RCC_MCOConfig. As far as I can tell, MCO is disabled. USB HS works fine. The STM32H7S3L8 has an internal HS PHY - perhaps the MCO config is needed when using an external PHY?
2024-11-08 03:46 AM
Hi @chintal
First you can check the clock being correctly configured with
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1);
Then ensure that the USB PHY is correctly initialized.
__HAL_RCC_USBPHYC_CLK_ENABLE();
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USBPHYC;
PeriphClkInit.UsbPhycClockSelection = RCC_USBPHYCCLKSOURCE_HSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
while(1);
}
Check HAL_PWREx_EnableUSBVoltageDetector and VDDUSB is configured.
You can refer to the example provided in Cube as a starting point STM32CubeH7RS/Projects/NUCLEO-H7S3L8/Applications/USB_Device at main · STMicroelectronics/STM32CubeH7RS
For basic data transfer and fixed power supply, UCPD controller is not necessary but you need to check your hardware setup like the following example implementing TCPP port for sinking power connected to CC lines and enables VBUS power path.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2024-11-08 10:06 PM
Thank you for your input, I expect I might have figured out the problem based on the example you linked to. I have figured out what the problem was by trial and error, though : USB HS requires the USB HS regulator enabled.
This might be specified somewhere in the datasheet, but I could not find it. I suspect there is a gap in the documentation here. Enabling USB HS on CubeMX does not automatically enable the USB HS regulator, either, though I don't know of any other alternate power sources for the USB HS PHY.
There are two regulators on the chip :
- USBREG
- USBHSREG
USBREG is discussed in some detail in the reference manual, and the schematics of the nucleo show that it is connected to an external 3.3V supply. This supply is related to the VDD33USB pin. Enabling USBREG makes HAL_PWREx_EnableUSBVoltageDetector() error out.
USBHSREG does not seem to be discussed in the reference manual, and the phrase "USBHSREG" shows up only in the register map. It does need to be enabled. If it is not enabled, HAL_PWREx_EnableUSBVoltageDetector() reports no errors, but the PHY remains unpowered.
From the power control block diagram, I assumed the HS PHY draws power from DVDD, which is powered by VCAP in the schematic. The internal LDO is enabled by `HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY)`, so VCAP should be powered and I presumed that would be enough. My reading of the documentation was that USBREG and USBHSREG are similar, one for the FS and the other for the HS.
On a side note, I have not had to do any configuration of RCC_MCOConfig. As far as I can tell, MCO is disabled. USB HS works fine. The STM32H7S3L8 has an internal HS PHY - perhaps the MCO config is needed when using an external PHY?