Skip to main content
Graduate II
September 28, 2023
Solved

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

  • September 28, 2023
  • 19 replies
  • 11653 views

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).

 

 

USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
 USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);

 

 

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.

USBX-D.png

USBX-B.png

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

    Hello @TDJ 

     

    To conclude, this is not hardware issue. MSI should not feed USB_OTG_HS clk source. In RM0456 page 487, it is mentioned, MSI provides a very accurate clock source that can be used by the OTG_FS, or the USB, and feeds the PLL.

    An internal ticket 172770 is reported to CubeMX to exclude this option in the configuration,

    19 replies

    TDJAuthor
    Graduate II
    January 21, 2024

    Hi @waclawek.jan, The problem is solved. It appears to be strictly related to IP clock source and has been confirmed by another engineer here. Since more engineers seem to be struggling with USB-C on U5, I posted my complete, working and documented solution on GitHub (Nucleo-U5A5ZJ-USBX).

    Technical Moderator
    January 22, 2024

    Hello @TDJ 

    IP clock source selected is not compliant with 400ppm. Since, the source for PLL1P clocked with MSIS.

    According to the datasheet, MSI output characteristics are stated as follows.

    FBelaid_0-1705929861739.jpeg

    According to the reference manual, section 11.4.19 OTG_HS clock, MSI is not suitable for this USB OTG HS use case.

     

    FBelaid_1-1705930106349.png

    I hope this helps!

     

    TDJAuthor
    Graduate II
    January 22, 2024

    @FBL,
    1. The problem I reported here is this:
    "The problem I found and cannot explain is that after when this line [see here] 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 [..]."
    Do you believe that the described problem may be caused by insufficient IP clock source accuracy?

    2. Is the accuracy of MSIS clock CRS SYNC-ed with LSE using 20ppm crystal sufficient to be used as OTG_HS USB IP clock source?

    Technical Moderator
    January 22, 2024
    1. There is an issue linked to description of register interface in SVD file related to stm32u5a9xx.h USB_OTG mess · Issue #31 · STMicroelectronics/STM32CubeU5 (github.com)An internal ticket 170738 is submitted for an update.
    2. In USB standards, input clk of USB should be 500ppm compliant. I'm afraid to tell you the answer is no.

    TDJAuthor
    Graduate II
    January 22, 2024

    @FBL I believe STM32CubeU5 Issue #31 has nothing to do with SVD register description. If it did, I would know it since it was me who submitted this issue.
    What is the accuracy of MSIS clock CRS SYNC-ed with LSE using 20ppm crystal? How far insufficient is it for the purpose of USB clock?

    Technical Moderator
    January 24, 2024

    Hello @TDJ 

    Thank you for your inputs. Indeed, it is true the issue is more linked to CMSIS definitions but I thought you see them in debug as I did a consequence SVD files are not inline with RM0456. 

    The accuracy of the MSIS clock CRS SYNC-ed with LSE using a 20ppm crystal in the STM32U5 series is not explicitly stated in the available resources. I guess it would result in a clock accuracy more than +/- 20 ppm from LSE's nominal frequency as LSE can be influenced by several factors including temperature, voltage, and the quality of the crystal. Also, VCO frequency is proportional to the voltage at the input. For further information check AN2867 section 4.2 How to select an STM32-compatible crystal.

    Thank you for your feedback.

    TDJAuthor
    Graduate II
    January 25, 2024

    @tjaekel Thank you for sharing your observations. For the main part my problem appears to be solved, I posted working code here. All now I try to accomplish is to find out why it was not working.
    I believe MSIS clock CRS SYNC-ed with LSE using 20ppm crystal is stable enough to be used for USB. I actually measured it and confirmed.

    My numerous tests indicate that PLL1P USB clock source must be used with /2 divider.

    The problem with such bold claim is that, I admit, it sound unbelievable so those who kindly try to help you first assume that most likely you do not know what you are doing. As a result, this thread is quite long. However, at least one person seems to experience the same issue and confirms the same solution - see STM32CubeU5 issue #34. "Working only with PLL1P/2. With PLL1P still facing timeout issue"

    As far as UCPD; Nucleo-U5A5 uses TCPP01-M12 chip designed only to receive power (sink), not to provide it.
    I believe NDK 32kHz NX1610 crystal used on this board has sufficient 20ppm accuracy. See NDK specs here.

    Technical Moderator
    January 25, 2024

    Hello @TDJ 

    I am trying to reproduce the behavior on myside as you described, and I will come back to you ASAP as this potential issue should be linked to product not the IP controller. 

    Thank you for your understanding.

    Visitor II
    January 27, 2024

    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;

    #else

    PeriphClkInit.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_PLL1_DIV2; //RCC_USBPHYCLKSOURCE_PLL1; //RCC_USBPHYCLKSOURCE_PLL1_DIV2;

    #endif

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

    {

    Error_Handler();

    }

     

    /** Set the OTG PHY reference clock selection

    */

    HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1);

     

    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)

     

    TDJAuthor
    Graduate II
    January 27, 2024

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

    Technical Moderator
    January 31, 2024

    Hello @TDJ 

     

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

    FBelaid_0-1706717723213.png

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

    Super User
    January 31, 2024

    Hi @FBL ,

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

    waclawekjan_0-1706723261723.png

    JW

     

    TDJAuthor
    Graduate II
    January 31, 2024

    @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%.

    Visitor II
    February 1, 2024

    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.

    Technical Moderator
    February 1, 2024

    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.

    TDJAuthor
    Graduate II
    February 1, 2024

    @FBL Thank you for looking into this issue. I created another branch with failing code:
    tdjastrzebski/Nucleo-U5A5ZJ-USBX at failing1 (github.com)
    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.

    Visitor II
    February 2, 2024

    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).

    FBLAnswer
    Technical Moderator
    February 6, 2024

    Hello @TDJ 

     

    To conclude, this is not hardware issue. MSI should not feed USB_OTG_HS clk source. In RM0456 page 487, it is mentioned, MSI provides a very accurate clock source that can be used by the OTG_FS, or the USB, and feeds the PLL.

    An internal ticket 172770 is reported to CubeMX to exclude this option in the configuration,

    TDJAuthor
    Graduate II
    February 6, 2024

    @FBL  It may be a good idea to update RM0456 and clearly state that MSI is not supported as OTG_HS clk source. True, p. 487 does not mention OTG_HS, but it does not necessarily mean that it is not supported. I think the only relevant requirement stated in RM0456 is 400 ppm accuracy which I think can be fulfilled using MSIS LSE sync-ed.

    Anyway, although it is not a good news, thank you for the clarification and confirmation: OTG_HS requires HSE.
    As a result, new MCUs equipped with OTG_HS requires HSE - no matter if one actually uses high speed or not.
    It is a considerable disadvantage to be aware of, something to be taken into account designing a new hardware.

    Technical Moderator
    February 7, 2024

    Hi @TDJ 

    We are considering your valuable feedback in order to provide best customer experience. If your question is answered, would you please close this post by selecting Accept as Solution. 

    Thanks