cancel
Showing results for 
Search instead for 
Did you mean: 

STMH747 and STM32CubeIDE: how to use USB HOST?

HTD
Senior III

UPDATE

Today, as the first thing in the morning I run my USB test that didn't work the last 3 days. Out of the blue it started to... kind of work. The device (USB disk) is detected as mass storage device, so the USB host enters the HOST_CLASS state, then after trying to mount the FS i get HardFault called.

My understanding of it is it must be hardware fault then, it must have been from the start. To be more specific - the micro USB plug of my OTG cable. Judging by the look of it (it looks fugly), it must be it. I ordered a better OTG adapter, one piece, without a cable, a branded one, Hama. I will perform all tests again when the hardware arrives.

Several lessons learned here. First - I need more peripherals to test, one is not enough. First hardware errors like connections must be ruled out. Then - I figured out how to test the USB host properly. It's all in usb_host.c file, the USBH_UserProcess() function. APPLICATION_START and APPLICATION_READY states must be entered. The first state is entered when the host detects anything connected to it, the second one is entered when it recognizes that it's in fact a mass storage (or any other compatible) class device. Then the fatfs operation is simple.

BTW, for what I've checked, it makes no apparent difference where the MX_USB_HOST_Init() is called. It works when called from main(), it works when called from TouchGFX task. It probably affects the blocking behavior, but it's not the issue here. It seems like the host's state machine works properly either way.

To the administrators: please remove my recent posts on USB problems. If I have further problems - I have a fully functional test project on GitHub that can be run to reproduce issues, with branches for both Internal FS and External Phy USB3320C-EZK chip. In the next question I will post all details with the link to the example.

--

Original question:

I was able to configure USB_OTG_HS and FATFS for USB disk.

However, when I try to mount my USB disk, f_mount() returns error, because the host is in state different from HOST_CLASS.

I tried to wait with USBH_Delay(100) and see what happens with hUSB_Host.gState over time.

First it's HOST_DEV_WAIT_FOR_ATTACHMENT, then HOST_DEV_ATTACHED, then HOST_ENUMERATION and it stays that way.

I found the USBH_ReEnumerate() function, I called it when the gState changed to HOST_ENUMERATION and... I finally got HOST_IDLE that stayed.

Knowing that f_open() will at some point expect the state HOST_CLASS there's no way it can succeed.

So I'm surely missing something here. I figured out that the state changes to HOST_ENUMERATION each time USB disk is connected. But waiting for it in a loop seems like a lame idea, there must be a kind of event, some way to attach my code when it happens. Then, something else, I don't know what must be done before f_mount() can be called, but what?

Where can I find a documentation of how to do it properly? I had no such problems with SD card, it just works. It also can detect connection, however, when I call f_open() it just works. I assume I need to add some code to the usb_host.c file, but to be able to do so I need a documentation. Any clue.

OK, I figured out the first part:

In the usb_host.c file there's USBH_UserProcess() function with some available states. HOST_USER_CONNECTION state is entered when the USB disk is connected. The host state is HOST_DEV_ATTACHED. Of course f_open() fails.

I read the blog post http://evenlund.blogspot.com/2016/10/usb-storage-with-stm32f4-discovery-and_58.html .

It seems like the guy gets HOST_USER_CLASS_ACTIVE state somehow, but I can't do it. I get only HOST_USER_CONNECTION and this is it.

Here's my USBH_UserProcess():

static void USBH_UserProcess  (USBH_HandleTypeDef *phost, uint8_t id)
{
  /* USER CODE BEGIN CALL_BACK_1 */
  FRESULT fr;
  switch(id)
  {
  case HOST_USER_SELECT_CONFIGURATION:
  break;
 
  case HOST_USER_DISCONNECTION:
  Appli_state = APPLICATION_DISCONNECT;
  break;
 
  case HOST_USER_CLASS_ACTIVE:
  Appli_state = APPLICATION_READY;
  fr = f_mount(&USBHFatFS, (TCHAR*)USBHPath, (BYTE)0x1);
  break;
 
  case HOST_USER_CONNECTION:
  Appli_state = APPLICATION_START;
  break;
 
  default:
  break;
  }
  /* USER CODE END CALL_BACK_1 */
}

f_mount() is never called.

BTW, where should I call MX_USB_HOST_Init() ? When placed in main.c like this:

/* USER CODE BEGIN Header_TouchGFX_Task */
/**
  * @brief  Function implementing the TouchGFXTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_TouchGFX_Task */
__weak void TouchGFX_Task(void *argument)
{
  /* init code for USB_HOST */
  MX_USB_HOST_Init();
  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END 5 */
}

...it's never called.

I tried to call MX_USB_HOST_Init() from a new RTOS thread. Still, same result, I get CONNECTION, but no CLASS_ACTIVE.

Same result with calling MX_USB_HOST_Init() from any other place. So it's probably a dead end. I've checked that USBH_Get_DevDesc() doesn't complete successfully. I got lost debugging it.

I've run of ideas.

2 REPLIES 2
Muhammed Güler
Senior II

Did you check the enable polarity of the USB Power switch IC? I had a similar problem for this reason.

Pavel A.
Evangelist III

Before integration with TouchGFX and RTOS, please get a no-RTOS USB MSC example working first.

This will validate your hardware and test that your USB drive format is compatible with the fatfs software.

Enable debug prints in the ST USBH library to trace enumeration process.

Use some another, better quality & supported USBH library.