2026-05-26 9:28 AM - last edited on 2026-05-26 9:33 AM by mƎALLEm
Hello ST Community,
I am facing a USB bulk OUT transfer issue on the NUCLEO-H755ZI-Q board.
I am using an external USB3300 ULPI PHY with the STM32H755 USB OTG HS peripheral. The device enumerates successfully in High-Speed and Full-speed mode.
The USB device is configured as a vendor-defined class with:
1 Bulk OUT endpoint
1 Bulk IN endpoint
Custom VID/PID
WinUSB/libusb driver installed using Zadig on the host PC
On the host side, I am using a custom Python utility based on PyUSB/libusb to perform:
Echo-back testing - 512 bytes write and read,
Custom command write/read testing
For a basic echo-back test, I send a 512-byte pattern like:
00 01 02 03 ... up to 512 bytes
For both FS and HS modes, the echo-back works correctly. In HS mode, 512-byte OUT transfers are received by the STM32 and echoed back correctly on the IN endpoint.
The problem occurs only with some specific custom 512-byte data packets.
In the attached custom_data_tx.log, transfers work correctly up to a certain point. Starting from the 10th packet, the host-side Python utility reports a USB transfer timeout on the OUT endpoint.
Changing the host-side timeout value does not help. The same packet fails consistently every time.
I also tried enabling/disabling ZLP handling, but the behavior remains the same.
I added counters/debug checks in firmware to confirm whether the failing OUT packet reaches the STM32 application layer.
For the failing packet:
No OUT receive callback appears to be triggered
No firmware-side counter increments
It looks like the failing OUT transfer does not reach the USBX/HAL application receive path
This makes it difficult to understand whether the issue is at the host/libusb level, USB device stack level, endpoint handling level, ULPI/HS PHY level, or something payload-specific.
In wireshark it shows as USBD_STATUS_CANCELLED.
The firmware implementation is very simple at this stage.
The application thread reads data from the OUT endpoint in HAL_PCD_DataOutStageCallback() and writes the same data back on the IN endpoint for echoing.
I have attached app_usbx_device.c for reference.
I have also tried different approaches:
ThreadX + USBX implementation
HAL-based implementation
DMA enabled/disabled
ZLP enabled/disabled
Different host timeout values
The behavior is the same: normal 512-byte test patterns work, but some specific custom 512-byte packets consistently cause OUT transfer timeout.
Is there any known issue or limitation in STM32H7 USB OTG HS / USBX / ULPI handling where a specific 512-byte bulk OUT payload can fail, even though other 512-byte payloads work correctly?
I do not see anything obviously unique in the failing packet content.
I would appreciate it if someone could review the attached logs/code or try reproducing the issue using the failing packet from custom_data_tx.log.
TL;DR
HS bulk OUT endpoint receives normal 512-byte pattern, but specific 512-byte payload causes host OUT timeout and no firmware-side callback/counter is observed.
Thanks in advance.
Regards,
Pranay.