cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6 getting stuck in USB_CoreReset( )

johndoeEngg
Associate II

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.

 

1 ACCEPTED SOLUTION

Accepted Solutions
FBL
ST Employee

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
        }

 

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.


View solution in original post

3 REPLIES 3
FBL
ST Employee

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
        }

 

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.


johndoeEngg
Associate II

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

FBL
ST Employee

Hi @johndoeEngg 

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

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.