Skip to main content
Visitor II
April 7, 2025
Solved

STM32N6 getting stuck in USB_CoreReset( )

  • April 7, 2025
  • 3 replies
  • 888 views

I urgently need to get USB High Speed working on USB1 of the STM32N6570-DK. I have attached the .ioc file I am using.

I am able to get the GPIO_IOToggle project working on the board. I am able to put breakpoints step through the code.

I am using  STM32CubeIDE version 1.18.0 (Build: 24413_20250227_1633 (UTC)).

As a second step, I need ThreadX working on the board.

 

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

    Hi @johndoeEngg 

    The issue occurs when the function releases a timeout while waiting for the USB Core Soft Reset to finish. This timeout happens when the bit CSRST is set in the OTG_GRSTCTL register.

    The root cause could be related to the PHY not being properly initialized. After enabling PHY's clock, the sequence should be followed by a delay of 10 cycles before writing core soft reset. This delay is necessary to ensure proper synchronization before resetting USB controller.

     /** Initializes the peripherals clock */
     RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1;
     PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;
    
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
     {
     /* Initialization Error */
     Error_Handler();
     }
    
     /** Set USB OTG HS PHY1 Reference Clock Source */
     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBPHY1;
     PeriphClkInitStruct.UsbPhy1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;
    
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
     {
     /* Initialization Error */
     Error_Handler();
     }
    
     __HAL_RCC_GPIOA_CLK_ENABLE();
    
     LL_AHB5_GRP1_ForceReset(0x00800000);
     __HAL_RCC_USB1_OTG_HS_FORCE_RESET();
     __HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET();
    
     LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock();
     LL_AHB5_GRP1_ReleaseReset(0x00800000);
    
     /* Peripheral clock enable */
     __HAL_RCC_USB1_OTG_HS_CLK_ENABLE();
    
     /* Required few clock cycles before accessing USB PHY Controller Registers */
     HAL_Delay(1);
    
     USB1_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4);
     /*Set the PHY reference clock speed to 24 MHz */
     USB1_HS_PHYC->USBPHYC_CR |= (0x1 << 16) |
     (0x2 << 4) |
     (0x1 << 2) |
     0x1U;
    
     __HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET();
    
     /* Required few clock cycles before Releasing Reset */
     HAL_Delay(1);
    
     __HAL_RCC_USB1_OTG_HS_RELEASE_RESET();
    
     /* Peripheral PHY clock enable */
     __HAL_RCC_USB1_OTG_HS_PHY_CLK_ENABLE();

    HAL_Delay(1) introduced here is dependent on CPU frequency and not 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
     }

     

    3 replies

    FBLAnswer
    Technical Moderator
    April 7, 2025

    Hi @johndoeEngg 

    The issue occurs when the function releases a timeout while waiting for the USB Core Soft Reset to finish. This timeout happens when the bit CSRST is set in the OTG_GRSTCTL register.

    The root cause could be related to the PHY not being properly initialized. After enabling PHY's clock, the sequence should be followed by a delay of 10 cycles before writing core soft reset. This delay is necessary to ensure proper synchronization before resetting USB controller.

     /** Initializes the peripherals clock */
     RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1;
     PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;
    
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
     {
     /* Initialization Error */
     Error_Handler();
     }
    
     /** Set USB OTG HS PHY1 Reference Clock Source */
     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBPHY1;
     PeriphClkInitStruct.UsbPhy1ClockSelection = RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;
    
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
     {
     /* Initialization Error */
     Error_Handler();
     }
    
     __HAL_RCC_GPIOA_CLK_ENABLE();
    
     LL_AHB5_GRP1_ForceReset(0x00800000);
     __HAL_RCC_USB1_OTG_HS_FORCE_RESET();
     __HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET();
    
     LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock();
     LL_AHB5_GRP1_ReleaseReset(0x00800000);
    
     /* Peripheral clock enable */
     __HAL_RCC_USB1_OTG_HS_CLK_ENABLE();
    
     /* Required few clock cycles before accessing USB PHY Controller Registers */
     HAL_Delay(1);
    
     USB1_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4);
     /*Set the PHY reference clock speed to 24 MHz */
     USB1_HS_PHYC->USBPHYC_CR |= (0x1 << 16) |
     (0x2 << 4) |
     (0x1 << 2) |
     0x1U;
    
     __HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET();
    
     /* Required few clock cycles before Releasing Reset */
     HAL_Delay(1);
    
     __HAL_RCC_USB1_OTG_HS_RELEASE_RESET();
    
     /* Peripheral PHY clock enable */
     __HAL_RCC_USB1_OTG_HS_PHY_CLK_ENABLE();

    HAL_Delay(1) introduced here is dependent on CPU frequency and not 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
     }

     

    Visitor II
    April 7, 2025

    Hi FBL,

     Thanks a lot for your quick response. I am able to get past this stage with the code you posted.

     I went back to the configuration and enabled USBX. Does USBX work without ThreadX ?

     I am not able to get the eval board enumerated on my laptop.

     I am guessing I am missing bunch of stuff during initialization and starting the USB HS interface before hitting my simple main loop.

    I am using the STM32N6570-DK which has a 48 MHz HSE. I am configuring OTGPHY1 and OTGHS1 to 24 MHz.

     I am pasting my main( ) function.

     

    int main(void)

    {

     

    /* USER CODE BEGIN 1 */

     

    /* USER CODE END 1 */

     

    /* MCU Configuration--------------------------------------------------------*/

    HAL_Init();

     

    /* USER CODE BEGIN Init */

     

    /* USER CODE END Init */

     

    /* Configure the system clock */

    SystemClock_Config();

     

    /* Configure the peripherals common clocks */

    PeriphCommonClock_Config();

     

    /* USER CODE BEGIN SysInit */

     

    /* USER CODE END SysInit */

     

    /* Initialize all configured peripherals */

    MX_GPIO_Init();

    MX_ADC1_Init();

    MX_I2C1_Init();

    MX_I2C2_Init();

    MX_ICACHE_Init();

    MX_MDF1_Init();

    MX_USART1_UART_Init();

    MX_USB1_OTG_HS_PCD_Init();

    MX_USBX_Init();

    /* USER CODE BEGIN 2 */

     

    /* USER CODE END 2 */

     

    /* Infinite loop */

    /* USER CODE BEGIN WHILE */

    while (1)

    {

    /* USER CODE END WHILE */

     

    HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);

    /* Insert delay 100 ms */

    HAL_Delay(100);

     

    /* USER CODE BEGIN 3 */

    }

    /* USER CODE END 3 */

    }

    Here's my modified HAL_PCD_MspInit( ) function .

     

    void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)

    {

     

    if (hpcd->Instance==USB1_OTG_HS)

    {

    /* USER CODE BEGIN USB1_OTG_HS_MspInit 0 */

     

    /* USER CODE END USB1_OTG_HS_MspInit 0 */

     

    if (1)

    {

    /** Initializes the peripherals clock */

    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1;

    PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBPHY1REFCLKSOURCE_OTGPHY1; // RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;

     

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

    {

    /* Initialization Error */

    Error_Handler();

    }

     

    /** Set USB OTG HS PHY1 Reference Clock Source */

    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBPHY1;

    PeriphClkInitStruct.UsbPhy1ClockSelection = RCC_USBOTGHS1CLKSOURCE_HSE_DIV2; // RCC_USBPHY1REFCLKSOURCE_HSE_DIRECT;

     

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

    {

    /* Initialization Error */

    Error_Handler();

    }

     

    __HAL_RCC_GPIOA_CLK_ENABLE();

     

    LL_AHB5_GRP1_ForceReset(0x00800000);

    __HAL_RCC_USB1_OTG_HS_FORCE_RESET();

    __HAL_RCC_USB1_OTG_HS_PHY_FORCE_RESET();

     

    LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock();

    LL_AHB5_GRP1_ReleaseReset(0x00800000);

     

    /* Peripheral clock enable */

    __HAL_RCC_USB1_OTG_HS_CLK_ENABLE();

     

    /* Required few clock cycles before accessing USB PHY Controller Registers */

    HAL_Delay(10);

     

    USB1_HS_PHYC->USBPHYC_CR &= ~(0x7 << 0x4);

    /*Set the PHY reference clock speed to 24 MHz */

    USB1_HS_PHYC->USBPHYC_CR |= (0x1 << 16) |

    (0x2 << 4) |

    (0x1 << 2) |

    0x1U;

     

    __HAL_RCC_USB1_OTG_HS_PHY_RELEASE_RESET();

     

    /* Required few clock cycles before Releasing Reset */

    HAL_Delay(10);

     

    __HAL_RCC_USB1_OTG_HS_RELEASE_RESET();

     

    /* Peripheral PHY clock enable */

    __HAL_RCC_USB1_OTG_HS_PHY_CLK_ENABLE();

     

    /* USB1_OTG_HS interrupt Init */

    // rkris - added this code

    HAL_NVIC_SetPriority(USB1_OTG_HS_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(USB1_OTG_HS_IRQn);

    }

     

    /* USER CODE BEGIN USB1_OTG_HS_MspInit 1 */

     

    /* USER CODE END USB1_OTG_HS_MspInit 1 */

     

    }

     

    }

     

    I have attached the updated "ioc" file.

    Thanks

    JD

    Technical Moderator
    April 8, 2025

    Hi @johndoeEngg 

    So far, no examples provided covering USBX standalone on STM32N6. Some examples provided using classic middleware.