cancel
Showing results for 
Search instead for 
Did you mean: 

USB_WritePacket stuck in infinite loop

Strongato
Visitor

 

Hello ST Team,

I developed a custom USB DFU HOST class on an STM32F446ZE. I soldered a USB-C cable directly to the D+/D-, 5V and GND pins.

The Problem: The stack works correctly for transfers up to 128 bytes. However, when I set phost->Control.setup.b.wLength.w > 128 (e.g., 192 bytes) and call USBH_CtlReq, the code enters an infinite loop inside USB_WritePacket.

I have traced the execution line-by-line, monitoring the HCTSIZ register values: size (Transfer Size) and cnt (Packet Count).

Below is the detailed trace comparing a working 128-byte transfer vs. a failing 192-byte transfer.

1. Successful Scenario: Transferring 128 Bytes

Initial State: size = 128, cnt = 2.

Loop Iteration 1:

  • i=15: USBx_DFIFO written. Register updates: size = 64, cnt = 2.

  • i=31: USBx_DFIFO written. Register updates: size = 64, cnt = 1.

Loop Iteration 2:

  • Initial State: size = 128, cnt = 2.

  • i=15: USBx_DFIFO written. Register updates: size = 64, cnt = 1.

  • i=31: USBx_DFIFO written. Register updates: size = 64, cnt = 0.

  • Result: Transfer Complete (Success).


2. Failing Scenario: Transferring 192 Bytes

Initial State: size = 192, cnt = 3.

Loop Iteration 1:

  • i=15: USBx_DFIFO written. Register updates: size = 128, cnt = 3.

  • i=31: USBx_DFIFO written. Register updates: size = 64, cnt = 2.

  • i=47: USBx_DFIFO written. Register updates: size = 64, cnt = 1.

Loop Iteration 2 (Anomaly Begins):

  • Initial State: size = 128, cnt = 2

  • i=15: USBx_DFIFO written. Register updates: size = 128, cnt = 2.

  • i=31: USBx_DFIFO written. Register updates: size = 64, cnt = 1.

  • i=47: USBx_DFIFO written. Register updates: size = 64, cnt = 1.

    •  cnt value didn't change in last transfer?

Loop Iteration 3 (Corruption & Infinite Loop):

  • Transfer initialized with: size = 128, cnt = 3

    •  cnt value set to 3 again?

  • i=15: USBx_DFIFO written. Register updates: size = 128, cnt = 3.

  • i=31: USBx_DFIFO written. Register updates: size = 64, cnt = 3.

    • cnt value is now stuck at 3.

  • i=47: USBx_DFIFO written. Register updates: size = 64, cnt = 3.


Comparison with STM32G0: I ported this exact USB DFU Host class to an STM32G0C1CEU6, and the transfers work perfectly there with no issues. My application code remained identical. The only major difference is the hardware architecture (F4 uses FIFO vs G0 uses PMA) and the low-level drivers.

This is my first post so if I missed something or any additional data is needed, I'm happy to provide it.

 

0 REPLIES 0