Showing results for 
Search instead for 
Did you mean: 

Why OTG_HS USB/USBX Host on STM32U5Axx just does not work? (2)

Senior III

I encountered a problem while desperately trying to make USB OTG_HS Host configured on a new Nucleo-U5A5ZJ-Q using CubeMX and ThreadX+USBX. I know that this board is not designed to provide USB power, but this can be overcome with undocumented SB8-10 jumpers and UCPD is not an issue here. I am also aware that at the beginning of the HAL_HCD_MspInit() function __HAL_RCC_SYSCFG_CLK_ENABLE(); line needs to be added.

After several evenings of research (see here) I think I nailed down the problem to USB_HostInit() function.
At the end of this function, host mode events are enabled using GINTMSK register (RM0456, section 73.14.8 OTG interrupt mask register [alternate] (OTG_GINTMSK), offset 0x18).



                  USB_OTG_GINTMSK_SOFM             | USB_OTG_GINTSTS_DISCINT | \



The problem I found and cannot explain is that after when this line is executed, GINTMSK register value is still zero. Other OTG_HS registers get correctly set so probably the problem is NOT caused by misconfigured or not enabled RCC AHB2 peripheral clock (RM0456, 11.8.30 RCC AHB2 peripheral clock enable register 1, bits 14 & 15 - OTGEN & OTGHSPHYEN flags).

Please advise, I start to suspect some hardware bug or incorrect GINTMSK register offset.

Probably a separate issue is that GAHBCFG.GINTMSK register flag is not set (Global interrupt mask, RM0456, 73.14.3).

The second screenshot presents OTG_HS-related registers' state after when MX_USB_OTG_HS_HCD_Init() function was finished and HAL_HCD_Start() function was called.




Just to throw in more comments:

The 32 KHz LSI clock is not related to USB. As I understand: you have to use HSE (the external XTAl or an external OSC chip).

What I saw (on a U5A5 chip with embedded HS PHY): check which clock source is used for USB:

void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)

and there:

/** Initializes the peripherals clock


PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USBPHY;

#ifdef ORI_16MHz_OSC

PeriphClkInit.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_HSE;




if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)





/** Set the OTG PHY reference clock selection




which clock source for USB is used (and which divider settings).
As I understand: the USB PHY needs a specific, correct clock, e.g. 16 MHz (or other, but fix clock frequencies). It can come directly from an external HSE XTAL,

or CMOS OSC chip - which provides 16 MHz. In my case - I have an 8 MHz OSC chip - I had to use the PLL1 (PLLP) so that

my void SystemClock_Config(void) has something like this:

//16 MHz XTAL, NUCLEO board

RCC_OscInitStruct.PLL.PLLM = 1;

RCC_OscInitStruct.PLL.PLLN = 20; //

RCC_OscInitStruct.PLL.PLLP = 10; //32 MHz needed here! - we provide as DIV2 for USB (16 MHz)


@tjaekel LSE, not LSI. In this context it is a substantial difference.

ST Employee

Hello @TDJ 


Would you please try this config (PLL1M=0x0 PLL1N=0x13 PLL1P=0x13 OTGHSEL=0x1). It is working from myside. 


Otherwise, could you share the failing config? and more explicitly where exactly occurs the fail?

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.

Hi @FBL ,

Have you clicked the "PLL1P" option in the mux in CubeMX, as @TDJ has shown in one of the first posts above?




Senior III

@FBL@waclawek.jan Exactly, the code I shared was working correctly.
Now, to reproduce the problem select PLL1P as OTG clock source without /2 divider and decrease PLL1P frequency to 50%.

Great. Well done!
Does it mean: it works now? After you have changed a bit on the PLL settings?

This is what I saw as well: just a specific PLL setting works, a different one with other PLLM (BTW: it can never be 0), but actually resulting in the same frequency on PLLP - it fails. For me it looks like: PLLM must be 1 and set the other PLL values (esp. PLL1P) accordingly.
And make sure you generate the correct frequency for the USB HS PHY, e.g. via: PeriphClkInit.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_PLL1_DIV2;

There are just few frequencies which can work: PLLP has to be configured for one of these frequencies. And see the code line above, which reflects this config.

#define RCC_USBPHYCLKSOURCE_HSE        ((uint32_t)0x00000000U)      /*!< HSE clock selected as USBPHYC clock */
#define RCC_USBPHYCLKSOURCE_HSE_DIV2   RCC_CCIPR2_USBPHYCSEL_1      /*!< HSE clock divided by 2 selected as USBPHYC clock */
#define RCC_USBPHYCLKSOURCE_PLL1       RCC_CCIPR2_USBPHYCSEL_0      /*!< PLL1 divider P selected as USBPHYC clock */
#define RCC_USBPHYCLKSOURCE_PLL1_DIV2  (RCC_CCIPR2_USBPHYCSEL_1 | RCC_CCIPR2_USBPHYCSEL_0) /*!< PLL1 divider P divided by 2 selected as USBPHYC clock */

The STM32U5A5 internal HS PHY seems to be very sensitive for the PLL setting. It needs also an external HSE and a pretty good frequency tolerance on XTAL/OSC.

ST Employee

Hello All

I have already tried this configuration as I mentioned in my last comment (PLL1M=0x0 PLL1N=0x13 PLL1P=0x13 OTGHSEL=0x1 in register level) as counter example also checked different configurations, there are failing configs but not specifically a clock path. Would you please guide me directly to the failing project?


> As far as UCPD; Nucleo-U5A5 uses TCPP01-M12 chip designed only to receive power (sink), not to provide it.

This should be managed by software in case of enabling the protection. A device can indeed operate in SINK mode for power and simultaneously act as a Data-device for the attachment. Then, it can transition to Host-data mode while still remaining in SINK mode for power. However, Nucleo is not designed to deliver power. It is always in power SINK.

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.

Senior III

@FBL Thank you for looking into this issue. I created another branch with failing code:
tdjastrzebski/Nucleo-U5A5ZJ-USBX at failing1 (
Although one may argue that using HSE as the primary OTG clock source is the safest option, my goal is not just to get it working with Nucleo board - which I already did. I design a new hardware and try to avoid using additional components. For this reason MSIS CRS-synced with LSE is my preferred solution since I need LSE anyway. My measurements show that although CRS-synced MSIS clock 'floats' a bit, the required 400ppm accuracy is maintained.

As F.Belaid has pointed out:
NUCLEO-U5A5 is only a SINK (not possible to run as host: no VBUS provided by board).

And U5A5 runs only USB OTH HS (internal PHY!) with an external HSE.
The U575 can get the clock for the USB OTG FS from somewhere else (it looks like also from internal 48MHz RC OSC).

If you have different MCUs (like I use U575 and U5A5) - you have to deal with the differences (e.g. #ifdef STM32U5A5xx vs. #ifdef STM32U575xx). The same code does not run without "conditional changes" on both.
I have my USB VCP UART project working this way (changing macro defines and toggle between HS and FS PHY).

@tjaekel It has been proven beyond any doubt that NUCLEO-U5A5 can provide power. For that purpose jumpers SB8-10 have to be used. However, USB power is irrelevant to this thread. If you want to discuss this interested topic, please start a new discussion.

"U5A5 runs only USB OTH HS (internal PHY!) with an external HSE" - How do you know that? Maybe this is true, although I think I have already proven otherwise.