cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6 USBX Standalone Guide

csaji
Associate II

Is there a guide that shows how to set up a CDC USB device on the STM32N6 without using ThreadX in baremetal mode?

 

I've tried following both, but it seems to hardfault on both examples crash at __lib_init_array(). I've tried increasing the stack and heap sizes to no success:

https://community.st.com/t5/stm32-mcus/how-to-use-stmicroelectronics-classic-usb-device-middleware-with/ta-p/599274 

 

https://community.st.com/t5/stm32-mcus/how-to-implement-usbx-in-standalone-mode/ta-p/614435 

 

It's frustrating that the old USB_Device middleware got removed. We shouldn't be forced to use an RTOS where it is not needed...

1 ACCEPTED SOLUTION

Accepted Solutions
FBL
ST Employee

Yess @csaji .You must configure PHY reference clock and insert delay as explained here section 2.3 STM32N6 use case. 

This delay is necessary to avoid the situation where the CSRT bit in OTG_GRSTCTL gets stuck, which can result in a timeout error. The need for this delay is related to the dependency on compiler optimization, PHY frequency, and CPU frequency.

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.




Best regards,
FBL

View solution in original post

9 REPLIES 9
FBL
ST Employee

Hi @csaji 

You can get classic core middleware apps for N6 from here

Regarding the USBX standalone, you can start with this example and modify it in standalone (without threadX). If you face any issue, share your project so that we can help you.

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.




Best regards,
FBL
csaji
Associate II

I integrated the USB drivers from the classic core middleware and modified several files to suit my needs, since I only require a generic CDC interface.

 

When I connect the USB, my computer does not detect any device. I noticed that the USB1 OTG HS interrupt was not enabled, but enabling it causes a hard fault.

 

For context, I am running the project using an FSBL load-and-run configuration. The hard fault appears to occur when the FSBL attempts to jump to the application. Specifically, it happens during the application startup, at the bl __libc_init_array. My heap and stack are configured to 0x300 and 0x4000, respectively.

csaji_0-1777403268742.png

 

What could be wrong?

FBL
ST Employee

Hi @csaji 

I'm suspecting your linker file for FSBL context and Run context? In this case, this article can be helpful. You need to check the FSBL header.

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.




Best regards,
FBL
csaji
Associate II

I've followed various tutorials and forum posts already to set up the FSBL load and run configuration. I don't believe its that. Its when I add my USB library in everything hardfaults and crashes, specifically in the application project startup file at bl __libc_init_array.

 

For sake of thoroughness, I'll go through everything I've done so far in terms of setup:

Device: STM32 - Nucleo-N657X0-Q

RCC:
HSE: Crystal/Cermamic Resonator (Uses default 48MHz OSC)

LSE: Disabled

 

XSPIM:

Runtime context: FSBL

Mode: Direct (XSPI1 to Port1; XPI2 to Port2; XSPI3 not used)

 

XSPI2:

csaji_0-1777478125390.png

 

EXTMEM_MANAGER:

csaji_1-1777478190946.png

 

EXTMEM_LOADER:

csaji_2-1777478211946.png

 

USB1_OTG_HS:

Runtime Context: Application

Speed: Device HS 480MBits/s

Physical Interface: Internal HS Phy

Ref Clock Selection: 24 MHz

Everything else disabled.

 

Clock Configuration:
XPI2 Source Mux is set to IC3 @ 50MHz

To OTGHS1 is set to 48 MHz. I've seen forum posts for the H5 say to set this to 60MHz, but I can't seem to set it to that value.

 

For both CORTEX_M55_FSBL and CORTEX_M55_S, the I and D cache are disabled for now, as well as the MPU.

 

Linker Scripts:

For the FSBL project, I used the default STM32N6XX_AXISRAM2_fsbl.ld.

_Min_Heap_Size = 0x200; /* required amount of heap */

_Min_Stack_Size = 0x800; /* required amount of stack */

 

/* Memories definition */

MEMORY

{

ROM (xrw) : ORIGIN = 0x34180400, LENGTH = 255K

RAM (xrw) : ORIGIN = 0x341C0000, LENGTH = 256K

}

 

For the Application project, I use the default STM32N6XX_LRUN.ld. I've increased the stack and heap sizes.

_Min_Heap_Size = 0x3000; /* required amount of heap */

_Min_Stack_Size = 0x3000; /* required amount of stack */

 

/* Memories definition */

MEMORY

{

ROM (xrw) : ORIGIN = 0x34000400, LENGTH = 511K

RAM (xrw) : ORIGIN = 0x34080000, LENGTH = 1536K

}

 

Header Signing:

I run this command to sign both the FSBL and application in the post-build steps;

cd "${ProjDirPath}/Debug" && echo y | "/home/christopher/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_SigningTool_CLI" -bin "${ProjName}.bin" -nk -of 0x80000000 -t fsbl -o "${ProjName}-Trusted.bin" -hv 2.3 -dump "${ProjName}-Trusted.bin" -align

 

Am I doing something inherently wrong here? Is there something with the USB peripheral I'm missing? Do I need to configure any other peripehral? Is there any power setup I have to do? The board examples don't seem to help much either.

 

If there is any other information I can provide that could help, please don't hesitate to ask. Thanks

FBL
ST Employee

Hi @csaji 

Would you attach your project to investigate further? If possible to comment it and see what kind of issues that may pop up ?

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.




Best regards,
FBL
csaji
Associate II

Attached below is my project. I appreciate you looking at this.


I've realized my project was hard faulting in the startup file because I didn't increase the source code size in the extmem_manager. Now I'm getting the USB interrupt but it hardfaults in the USB IRQ handler. Something I'm doing in my USB_DEVICE folder is wrong.

 

 

It figured out why it's hardfaulting. I was using the wrong PCD_HandlerTypeDef variable. I had one declared in main and one declared in usbd_conf.c. The PC detects the device, but it fails the enumeration process... Getting closer.

I think I figured it out. I can get it to enumerate. By default, the HAL_PCD_MspInit function in the stm32n6xx_hal.msp.c is called. The one I have commented out in usbd_conf.c is the correct version that allows it to enumerate.

Is something wrong with the provided function in the stm32n6xx_hal.msp.c? 

Also apologies for the spammy replies 

In stm32n6xx_hal.msp.c:

/**

* @brief PCD MSP Initialization

* This function configures the hardware resources used in this example

* @param hpcd: PCD handle pointer

* @retval None

*/

void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)

{

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

if(hpcd->Instance==USB1_OTG_HS)

{

/* USER CODE BEGIN USB1_OTG_HS_MspInit 0 */

 

/* USER CODE END USB1_OTG_HS_MspInit 0 */

 

/** Initializes the peripherals clock

*/

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1;

PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBOTGHS1CLKSOURCE_HSE_DIRECT;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/* Enable VDDUSB */

HAL_PWREx_EnableVddUSB();

/* Peripheral clock enable */

__HAL_RCC_USB1_OTG_HS_CLK_ENABLE();

__HAL_RCC_USB1_OTG_HS_PHY_CLK_ENABLE();

/* USB1_OTG_HS interrupt Init */

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 */

 

}

 

}

 

 

 

Correct Version:

void HAL_PCD_MspInit(PCD_HandleTypeDef *pcdHandle)

{

if (pcdHandle->Instance == USB1_OTG_HS)

{

/* Enable VDDUSB */

 

__HAL_RCC_PWR_CLK_ENABLE();

HAL_PWREx_EnableVddUSBVMEN();

while (__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY));

HAL_PWREx_EnableVddUSB();

 

/** Initializes the peripherals clock

*/

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USBOTGHS1;

PeriphClkInitStruct.UsbOtgHs1ClockSelection = RCC_USBOTGHS1CLKSOURCE_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_USBPHY1CLKSOURCE_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);

 

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();

 

/* USB_OTG_HS interrupt Init */

HAL_NVIC_SetPriority(USB1_OTG_HS_IRQn, 7, 0);

HAL_NVIC_EnableIRQ(USB1_OTG_HS_IRQn);

 

/* USER CODE BEGIN USB_OTG_HS_MspInit 1 */

 

/* USER CODE END USB_OTG_HS_MspInit 1 */

}

}

 

FBL
ST Employee

Yess @csaji .You must configure PHY reference clock and insert delay as explained here section 2.3 STM32N6 use case. 

This delay is necessary to avoid the situation where the CSRT bit in OTG_GRSTCTL gets stuck, which can result in a timeout error. The need for this delay is related to the dependency on compiler optimization, PHY frequency, and CPU frequency.

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.




Best regards,
FBL