Skip to main content
Visitor
October 9, 2026
Question

STM32H723 USBX Custom HID hangs in OTG_HS_IRQHandler() until FIFO configuration is added

Hi,

I would like to share a solution that may help others using USBX Custom HID on the STM32H723.

Environment

  • STM32H723
  • STM32CubeMX 6.17
  • STM32CubeH7 V1.13.0
  • USBX + ThreadX
  • USB_OTG_HS (Internal FS PHY)
  • Custom HID
  • 64-byte reports IN and OUT

Problem

The device enumerated correctly and received HID SET_REPORT requests.

A worker thread processed the received command and sent a response using:

 

ux_device_class_hid_event_set(&hid_event);

 

After the first IN report, the application appeared to hang.

The CPU spent nearly all its time inside:

 

OTG_HS_IRQHandler()

 

and ThreadX tasks no longer received meaningful runtime.

Debugging Results

The following registers were observed:

DAINT     = 0x00000002

DIEPTSIZ1 = 0x00080040

DTXFSTS1  = 0x00000000

 

This indicated that EP1-IN had a pending 64-byte transfer and the Tx FIFO remained blocked.

HAL_PCD_EP_Transmit() returned:

HAL_OK

but the transfer never completed.

 

Root Cause

CubeMX generated no FIFO configuration for the USB OTG HS peripheral.

The following functions were never called:

 

HAL_PCDEx_SetRxFiFo(...)

HAL_PCDEx_SetTxFiFo(...)

 

Solution

After HAL_PCD_Init(), add:

 

HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_HS, 0x100);

HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 0, 0x20);

HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_HS, 1, 0x40);

 

After adding the FIFO configuration:

  • HID communication works correctly
  • IN and OUT reports operate normally
  • No endless OTG_HS_IRQHandler()
  • ThreadX scheduling works as expected

Additional Notes

I also reduced:

hpcd_USB_OTG_HS.Init.dev_endpoints = 2;

because the application only uses:

  • EP0 (Control)
  • EP1 IN (64-byte HID Input Report)
  • EP1 OUT (64-byte HID Output Report)

Additionally:

hpcd_USB_OTG_HS.Init.use_dedicated_ep1 = DISABLE;

and the dedicated EP1 interrupts are not used:

OTG_HS_EP1_IN_IRQn

OTG_HS_EP1_OUT_IRQn

 

Only the global USB interrupt is required:

OTG_HS_IRQn