cancel
Showing results for 
Search instead for 
Did you mean: 

How to use USB, FatFS and FreeRTOS with the STM32U5A9NJHxQ

G_Anastasopoulos
Associate III

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?

1 REPLY 1
FBL
ST Employee

Hi @G_Anastasopoulos 

Did you take a look at this repo STMicroelectronics/stm32u5-classic-coremw-apps: Provide a set of applications for STM32U5xx series based on the STM32 Classic Core Middleware libraries. (github.com)

You may need to dig deeper in debugging the HardFault.

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.