Skip to main content
Graduate
November 7, 2024
Solved

USB HS on the STM32H7S3L8

  • November 7, 2024
  • 3 replies
  • 1790 views

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 :

chintal_0-1730981775847.png

 

 

 

 

 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.

    This topic has been closed for replies.
    Best answer by chintal

    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.

     

    chintal_0-1731132130847.png

    chintal_1-1731132169309.png

     

    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?

    3 replies

    Technical Moderator
    November 8, 2024

    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.

    FBL_0-1731066162691.png

     

    chintalAuthorAnswer
    Graduate
    November 9, 2024

    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.

     

    chintal_0-1731132130847.png

    chintal_1-1731132169309.png

     

    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?

    Graduate
    February 21, 2025

     

    Hello Chintal, 

    I am working on the same board and working on USB-HS device only with class communication device class.

    I stumbled onto your solution for the USB_CoreReset timeout. However, even after activating USB_HS_REGEN in CubeMX, (Pinout&Configuration -> Power&Thermal -> PWR -> USB_REGULATOR -> USB_HS_REGEN) USB_CoreReset still hangs when I run the code in debug mode. 

     

    Additional information / Questions:

    (Pinout&Configuration -> Other -> USB_INTERNAL_REGULATOR) There is an option for USB_INTERNAL_REGULATOR, this is NOT active in the example file CDC_Standalone. Do I need it?

    1. Enabled USB_HS_REGEN
    2. USB OTG HS interrupt is enabled
    3. Clock configuration is identical to yours.
    4. * In 'RCC' set 'CRS SYNC' to 'USB_HS' 
    5. * In 'NVIC' enable the global interrupt for USB 

    * Source: StefanH Associate III

    chintalAuthor
    Graduate
    February 25, 2025

    @AlexShao 

    My impression of CubeMX on the H7S3L8 (and U083, for that matter) is that it is not quite ready. The HAL and LL drivers seem to be (mostly) fine, but not everything works as expected. 

    The USB init code I'm using is here:

    piolib-hal-uc-stm32/src/hal_platform/h7rsxx/usb_impl.c at main · ebs-universe/piolib-hal-uc-stm32

    You can take a look, using _usb_init() as the entry point for USB initialization. I know that this code works for USB HS. As of now, USB FS is not actually implemented on this code. 

    The power initialization I am using is here, which executes before I _usb_init() is called: 

    https://github.com/ebs-universe/piolib-hal-uc-stm32/blob/524c065a5a919ffcce7dd372db11d182021492a3/src/hal_platform/h7rsxx/core_impl.c#L172

    As far as I remember, there should not be anything else needed to make USB HS work. Hopefully this helps.