Skip to main content
Explorer
June 25, 2024
Question

How to use USB, FatFS and FreeRTOS with the STM32U5A9NJHxQ

  • June 25, 2024
  • 1 reply
  • 1987 views

Dear All,

For the needs of my project I need to be able to check if an USB drive is attached to my device, if it is then I need to mount it and then I need to be able to do all the different FatFS commands.

So far I have managed to import the FatFS library and got it working with the SDMMC1 peripheral, so I am able to mount an SD card and create, read etc files and folders.

Now I am trying to import the USB libraries needed for this. As a starting point, I took this repository:

https://github.com/STMicroelectronics/stm32_mw_usb_host/tree/8b21b5c4a6b8df42ad46b9df63bb87c47bd7b2f5 

where some drivers are provided.

Based on this I was trying to figure out what is the correct implementation for the functions in the usbh_conf.c should be. To this end I tried loading an example for the STM32F769NIHx chip. But this board seems to be using a peripheral with a somewhat different configuration of that of the STM32U5A9NJHxQ.

In CubeMX I have the following settings:

G_Anastasopoulos_1-1719318924460.png

G_Anastasopoulos_2-1719318942891.png

In my code I am using this inside a thread:

 

FATFS USBDISKFatFs; /* File system object for USB disk logical drive */
FIL MyFile; /* File object */
char USBDISKPath[4]; /* USB Host logical drive path */
USBH_HandleTypeDef hUSB_Host; /* USB Host handle */

static volatile bool is_connected = false;

static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id)
{
 switch(id)
 {
 case HOST_USER_SELECT_CONFIGURATION:
 break;

 case HOST_USER_DISCONNECTION:
	 is_connected = false;
 break;

 case HOST_USER_CLASS_ACTIVE:
	 is_connected = true;
 break;

 default:
 break;
 }
}

void MX_USB_Weird_Test_Init()
{
	/* Link the USB Host disk I/O driver */
	if(FATFS_LinkDriver(&USBH_Driver, USBDISKPath) == 0)
	{
		/* Init Host Library */
		USBH_Init(&hUSB_Host, USBH_UserProcess, 0);

		/* Add Supported Class */
		USBH_RegisterClass(&hUSB_Host, USBH_MSC_CLASS);

		/* Start Host Process */
		USBH_Start(&hUSB_Host);
	}

//	while(!is_connected);

	FRESULT res; /* FatFs function common result code */
	uint32_t byteswritten, bytesread; /* File write/read counts */
	uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
	uint8_t rtext[100]; /* File read buffer */

	/* Register the file system object to the FatFs module */
	if(f_mount(&USBDISKFatFs, (TCHAR const*)USBDISKPath, 0) != FR_OK)
	{
		/* FatFs Initialization Error */
		Error_Handler();
	}
	else
	{
		/* Create and Open a new text file object with write access */
		if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
		{
		 /* 'STM32.TXT' file Open for write Error */
		 Error_Handler();
		}
	else
	{
		 /* Write data to the text file */
		 res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);

		 if((byteswritten == 0) || (res != FR_OK))
		 {
			/* 'STM32.TXT' file Write or EOF Error */
			Error_Handler();
		 }
	 else
	 {
		/* Close the open text file */
		f_close(&MyFile);

		/* Open the text file object with read access */
		if(f_open(&MyFile, "STM32.TXT", FA_READ) != FR_OK)
		{
		 /* 'STM32.TXT' file Open for read Error */
		 Error_Handler();
		}
		else
		{
		 /* Read data from the text file */
		 res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);

		 if((bytesread == 0) || (res != FR_OK))
		 {
			/* 'STM32.TXT' file Read or EOF Error */
			Error_Handler();
		 }
		 else
		 {
			/* Close the open text file */
			f_close(&MyFile);

			/* Compare read data with the expected data */
			if((bytesread != byteswritten))
			{
			 /* Read data is different from the expected data */
			 Error_Handler();
			}
			else
			{
			 /* Success of the demo: no error occurrence */
			 printk("Success Writing into USB file\r\n");
			}
		 }
		}
	 }
	}
	}
	/* Unlink the USB disk I/O driver */
	 FATFS_UnLinkDriver(USBDISKPath);
}

 

But I am getting a hardfault in the f_open and more specifically, the call stack looks like this:

G_Anastasopoulos_1-1719323884548.png

So the exact point that it seems to be failing is:

G_Anastasopoulos_2-1719323914794.png
So far I have edited the

 

USBH_StatusTypeDef USBH_LL_Init(USBH_HandleTypeDef *phost)
{
	/* Set the LL driver parameters */
	hhcd.Instance = USB_OTG_HS;
	hhcd.Init.Host_channels = 16;
	hhcd.Init.speed = HCD_SPEED_HIGH;
	hhcd.Init.dma_enable = DISABLE;
	hhcd.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY;
	hhcd.Init.Sof_enable = DISABLE;
	hhcd.Init.low_power_enable = DISABLE;
	hhcd.Init.use_external_vbus = ENABLE;
	HAL_HCD_Init(&hhcd);
	USBH_LL_SetTimer(phost, HAL_HCD_GetCurrentFrame(&hhcd));
 return USBH_OK;
}

 


But I have no clue what should the HAL_HCD_MspInit should look like, so I left it to what CubeMX made for me:

 

void HAL_HCD_MspInit(HCD_HandleTypeDef* hcdHandle)
{

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 if(hcdHandle->Instance==USB_OTG_HS)
 {
 /* USER CODE BEGIN USB_OTG_HS_MspInit 0 */

 /* USER CODE END USB_OTG_HS_MspInit 0 */

 /** Initializes the peripherals clock
 */
 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USBPHY;
 PeriphClkInit.UsbPhyClockSelection = RCC_USBPHYCLKSOURCE_PLL1;
 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);

 /* USB_OTG_HS clock enable */
 __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
 __HAL_RCC_USBPHYC_CLK_ENABLE();

 /* Enable VDDUSB */
 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
 {
 __HAL_RCC_PWR_CLK_ENABLE();
 HAL_PWREx_EnableVddUSB();

 /*configure VOSR register of USB*/
 HAL_PWREx_EnableUSBHSTranceiverSupply();
 __HAL_RCC_PWR_CLK_DISABLE();
 }
 else
 {
 HAL_PWREx_EnableVddUSB();

 /*configure VOSR register of USB*/
 HAL_PWREx_EnableUSBHSTranceiverSupply();
 }

 /*Configuring the SYSCFG registers OTG_HS PHY*/
 /*OTG_HS PHY enable*/
 HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE);

 /* USB_OTG_HS interrupt Init */
 HAL_NVIC_SetPriority(OTG_HS_IRQn, 5, 0);
 HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
 /* USER CODE BEGIN USB_OTG_HS_MspInit 1 */

 /* USER CODE END USB_OTG_HS_MspInit 1 */
 }
}

 

Finally, I have added the missing call to the HAL_MspInit:

void HAL_MspInit(void)
{

 /* USER CODE BEGIN MspInit 0 */

	__HAL_RCC_SYSCFG_CLK_ENABLE();

 /* USER CODE END MspInit 0 */
...
}

 

In the code I have provided above it seems that the USBH_UserProcess is never called, so I tried to remove the waiting for the boolean to be set to true as shown in the code I provided above.

Could anyone provide me with a suggestion on what to do for the STM32U5A9NJHxQ?

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    August 26, 2024