2025-10-30 2:45 PM - edited 2025-10-30 2:46 PM
Hi community,
Before I start discussing my specific issue, I would like to know if dual USB host operation is allowed on STM32H7 MCUs. The H7 MCU has both FS and HS USB cores, and I want to configure both FS and HS as USB hosts, not using the OTG feature. The HS USB core will also run in full-speed host mode without an external PHY, with each host having its own USB port. Are there any potential issues with this configuration?
I encountered unexpected behavior during project development: USB FS MSC class functionalities were affected when devices were plugged into the USB HS port.
Here is my USB class setup:
The USB FS core is registered with two classes — MSC class and a custom printer class.
The USB HS core is registered with a HID class.
All classes worked individually.
If no device is plugged into the USB HS port, the USB FS port works normally. It prints correctly when connected to a thermal receipt printer and creates text file reports using FATFS when connected to a flash drive.
However, after I plugged a barcode scanner or any other device (another flash drive or SD card adapter) into the USB HS port, the USB FS core started experiencing issues with MSC class operations. It seemed like the USB host controller stayed busy and eventually timed out. Specifically:
USBH_MSC_RdWrProcess flagged a busy status and eventually returned a timeout error.
Luckily, the printer class still worked on the USB FS port.
I also checked the USB HS port HID class operations after this issue occurred. The barcode scanner still worked. It appears that, so far, the issue only affects MSC class operations on the USB FS side.
After unplugging devices from both HS and FS ports and reattaching a flash drive to the USB FS port, text file writing function worked normally again.
I also tried changing the interrupt priorities for both USB cores (FS = 6, HS = 7), but this had no effect. No DMA is being used. I checked the USB driver code, and it does not appear that FS and HS share the same static/global buffers.
I hope someone has some insight into this issue. Thank you!
2025-10-31 4:32 AM - edited 2025-10-31 4:34 AM
In hardware, the two OTG USB devices are entirely independent from each other, and so are their respective integrated FS PHYs.
That leaves us with software.
While you haven't stated which sort of software did you use, I suspect, it's Cube-based. Besides potential bugs there, you may experience also bandwidth issues (you mention timeouts). It also sounds like you are using some sort of an RTOS, which adds to complexity and potential points of failure.
Sorry for such a vague statement, but I am afraid at this point you are at your own. Cube is open source, so you can debug it yourself, although this is not going to be simple.
JW
2025-10-31 6:28 AM - edited 2025-10-31 6:39 AM
Yes, I used the STM32CubeMX to generated the USB source codes. The firmware package is STM32 Cube FW_H7 V1.12.1.
FreeRTOS is used in this project, and the system contains several tasks — the main GUI task for TouchGFX and a task for UART communication. Initially, I had a single USB task that handled both the USB FS and HS state machines in a loop. Later, I created two separate tasks, one for each USB host, but the issue still persisted. When this issue occurs, the system is not performing any intensive work besides exporting data to the USB drive. The barcode scanner is simply connected but not actively scanning.
We also have a peripheral board powered by another identical H7 MCU, which uses two USB ports: the USB FS is configured as a host, and the USB HS is configured as a device. The USB FS port is registered with the MSC class, and the USB HS port is registered with the CDC class. There are no issues with this setup.
2025-10-31 6:57 AM - edited 2025-10-31 6:59 AM
Hello @AL,
Could you please first provide the exact reference of the STM32H7 MCU used so that I can assist you properly?
Best regards,
2025-10-31 7:05 AM
The MCU model is STM32H743BITx.
2025-10-31 7:47 AM
Yes, dual USB host operation is supported on the STM32H743BITx MCU. However, your issue seems related to managing two classes simultaneously on a single USB core. Which classe are you using to handle this in mode Host ?
Also, are you using any RTOS to manage the two USB hosts concurrently?
2025-10-31 8:02 AM
Hi @AL
Here is an example: DualCore_Standalone
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.
2025-10-31 8:21 AM
So, you were telling me that USB_OTG_FS and USB_OTG_HS are controlled by a single USB core in the STM32H743BITx MCU? I thought there were two separate USB cores internally.
I configured both FS and HS in host-only mode, with one physical USB port for each host.
The FS port is registered with MSC and a custom printer USB class, while the HS port is registered with the HID class. They all work individually.
However, if I plug a device like barcode scanner into the USB HS port without doing any active work, and then try to write some text to a flash drive attached to the FS port, data export stops working on FS port. If the FS port is connected to a printer instead, the printer class seems to work. I think this is because it transfers much less data through the Bulk OUT endpoint.
After the issue occurred, I also checked the barcode scanner functionality, and it was still correctly sending barcode data to my system.
2025-10-31 8:38 AM - edited 2025-10-31 8:41 AM
So, you were telling me that USB_OTG_FS and USB_OTG_HS are controlled by a single USB core in the STM32H743BITx MCU? I thought there were two separate USB cores internally.
No, The STM32H743BITx MCU has two separate USB cores internally:
Each core operates independently and can be configured separately.
- USB_OTG_FS (Full-Speed core)
- USB_OTG_HS (High-Speed core)
you can refer to the USB_HOST_DualClass_Standalone in section Appli available in the STM32CubeH7RS firmware package.
Also, please feel free to share part of your application configuration so I can assist you further.
2025-10-31 9:15 AM
Thank you for your help.
My dual classes on the USB FS core seem to be working fine. I have no problem switching between a flash drive (MSC class) and a printer device (Printer class) on the USB FS port.
This issue only occurs when other devices are attached to the USB HS port. It seems that the USB HS core affects the FS core internally somehow—maybe due to hardware or software interactions—but I’m not sure at the moment.
USBH_HandleTypeDef hUSBHost_HS;
ApplicationTypeDef Appli_state = APPLICATION_IDLE;
USBH_HandleTypeDef hUSBHost_FS;
ApplicationTypeDef Appli_state_FS = APPLICATION_IDLE;
static void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id);
static void USBH_UserProcess_FS(USBH_HandleTypeDef *phost, uint8_t id);
void MX_USB_HOST_Init(void)
{
  if (USBH_Init(&hUSBHost_HS, USBH_UserProcess, HOST_HS) != USBH_OK)
  {
    Error_Handler();
  }
  if (USBH_RegisterClass(&hUSBHost_HS, USBH_HID_CLASS) != USBH_OK)
  {
    Error_Handler();
  }
  if (USBH_Start(&hUSBHost_HS) != USBH_OK)
  {
    Error_Handler();
  }
}
void MX_USB_HOST_FS_Init(void)
{
    /* Init MSC Host Library on FS */
    if( USBH_Init(&hUSBHost_FS, USBH_UserProcess_FS, HOST_FS) != USBH_OK)
    {
        Error_Handler();
    }
    /* Register MSC Class */
    if( USBH_RegisterClass(&hUSBHost_FS, USBH_MSC_CLASS) != USBH_OK)
    {
        Error_Handler();
    }
    if( USBH_RegisterClass(&hUSBHost_FS, USBH_PRINTER_CLASS) != USBH_OK)
    {
        Error_Handler();
    }
    /* Start Host Process */
    if( USBH_Start(&hUSBHost_FS) != USBH_OK)
    {
        Error_Handler();
    }
}
void MX_USB_HOST_Process(void)
{
  /* USB Host Background task */
  USBH_Process(&hUSBHost_HS);
}
void MX_USB_HOST_FS_Process(void)
{
  /* USB Host FS Background task */
  USBH_Process(&hUSBHost_FS);
}
void StartUSBHostTask(void const * argument)
{
	MX_USB_HOST_Init(); //for HID
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
	MX_USB_HOST_Process();
  }
}
void StartUSB_FSHostTask(void const * argument)
{
	MX_USB_HOST_FS_Init();
  /* Infinite loop */
  for(;;)
  {
	osDelay(1);
	MX_USB_HOST_FS_Process();
  }
}
static void USBH_UserProcess_FS(USBH_HandleTypeDef *phost, uint8_t id)
{
	switch (id)
	{
		case HOST_USER_SELECT_CONFIGURATION:
			break;
		case HOST_USER_DISCONNECTION:
			Appli_state_FS = APPLICATION_DISCONNECT;
			f_mount(NULL, USBHPath, 0);        // Unmount
			FATFS_FixedUnLinkDriverEx(1);      // Unlink
			break;
		case HOST_USER_CLASS_ACTIVE:
			Appli_state_FS = APPLICATION_READY;
			if(USBH_GetActiveClass(phost) == USB_MSC_CLASS)
			{
				FATFS_FixedLinkDriver(&USBH_Driver, USBHPath, 1);
				f_mount(&USBHFatFS, USBHPath, 1);
			}
			break;
		case HOST_USER_CONNECTION:
			Appli_state_FS = APPLICATION_START;
			break;
		default:
			break;
	}
}
static void USBH_UserProcess  (USBH_HandleTypeDef *phost, uint8_t id)
{
  /* USER CODE BEGIN CALL_BACK_1 */
  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;
  break;
  case HOST_USER_CONNECTION:
  Appli_state = APPLICATION_START;
  break;
  default:
  break;
  }
  /* USER CODE END CALL_BACK_1 */
}
