2024-06-25 06:02 AM - edited 2024-06-25 07:43 AM
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:
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:
So the exact point that it seems to be failing is:
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?