cancel
Showing results for 
Search instead for 
Did you mean: 

How to use USB, FatFS and FreeRTOS with the STM32U5A9NJHxQ

G_Anastasopoulos
Associate II

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?

0 REPLIES 0