2026-05-06 2:01 PM
Hello,
I've been adapting the DRP1M1 USB-PD DRP reference design for use on a custom STM32U5A9 Board, and have run into an issue where it seems like ST's compiled USBPD library just stalls during negotiation as a SRC device.
Hardware: STM32U5A9, custom board with TCPP03-M20
Library: USBPDCORE_PD3_FULL_CM33_wc32.a
Configuration: DRP, PD3.0
## Problem
Operating as SRC, the PE state machine sends ACCEPT in response to a REQUEST but never advances to PE_SRC_TRANSITION_SUPPLY. PS_RDY is never sent and the port partner eventually triggers a hard reset.
## What We Have Verified
**Protocol layer is working correctly:**
- SOURCE_CAPABILITIES sent and GOODCRC received
- REQUEST received and GOODCRC sent
- ACCEPT sent and GOODCRC received
- All confirmed on protocol analyzer
**All DPM callbacks returning correct values:**
- USBPD_DPM_EvaluateRequest() returns USBPD_ACCEPT (verified via debugger)
- USBPD_PWR_IF_GetVBUSStatus(USBPD_PWR_VSAFE5V) returns USBPD_TRUE (VBUS at ~4.8V, threshold 4750mV)
- USBPD_DPM_SetDataInfo(USBPD_CORE_DATATYPE_RCV_REQ_PDO) storing valid RDO (0x1304b12c)
- DPM_Params[0].PE_IsConnected = 1
- DPM_Params[0].PE_Power = USBPD_POWER_DEFAULT5V (1)
- DPM_Params[0].PE_PowerRole = USBPD_PORTPOWERROLE_SRC (1)
**PE task is alive and running:**
- USBPD_PE_StateMachine_DRP() called ~13000+ times returning _timing=2ms
- PE task is not suspended, not blocked on queue
- TIM1 running correctly at 1MHz tick (PSC=159, SystemCoreClock=160MHz, APB2=DIV1)
**Callbacks never called after ACCEPT/GOODCRC:**
- USBPD_DPM_SetupNewPower() call count = 0
- USBPD_DPM_IsPowerReady() call count = 0
- USBPD_PE_TaskWakeUp() fires twice on attachment, never again after ACCEPT/GOODCRC
- TX completions (TXMSGSENT): count=3 (SOURCE_CAPABILITIES, GOODCRC for REQUEST, ACCEPT)
- RX completions (RXMSGEND): count=3 (GOODCRC for SOURCE_CAPABILITIES, REQUEST, GOODCRC for ACCEPT)
**Notification log per attach cycle (complete, never progresses beyond these 3):**
1. USBPD_NOTIFY_USBSTACK_START (104)
2. USBPD_NOTIFY_POWER_STATE_CHANGE (90)
3. USBPD_NOTIFY_SRCCAP_SENT (15)
Notifications never fired: USBPD_NOTIFY_REQUEST_ACCEPTED, USBPD_NOTIFY_CTRL_MSG_SENT, USBPD_NOTIFY_POWER_EXPLICIT_CONTRACT, USBPD_NOTIFY_AMS_INTERRUPTED
## Conclusion
The PE library sends ACCEPT at the protocol layer and increments TX completions correctly, but its internal state machine does not advance past PE_SRC_SEND_CAPABILITIES. USBPD_NOTIFY_REQUEST_ACCEPTED is never fired despite EvaluateRequest returning USBPD_ACCEPT and all observable callbacks returning correct values. The PE appears to be processing the negotiation at the protocol layer independently of its internal state machine progression.
Is there an additional callback, configuration flag, or initialization step required for the PE to transition from PE_SRC_SEND_CAPABILITIES to PE_SRC_TRANSITION_SUPPLY after receiving ACCEPT/GOODCRC?
2026-05-08 8:42 AM - edited 2026-05-15 6:30 AM
Hi @JoeMck
Can you check USBPD_DPM_TimerCounter implementation? Did you generate your project using CubeMX? Make sure USBPD_PE_Task is scheduled properly and not blocked by other tasks.
Could you please attach your trace.
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.
2026-05-18 12:57 PM
Thank you for your help.
USBPD_DPM_TimerCounter wasn't being called. I started from the G071RB DRP reference design and basically migrated that to our custom STM32U5A9 platform. Our design uses ToughGFX and a bunch of other stuff that has rendered using/regenerating-with CubeMX underneath intractable. Since adding USBPD_DPM_TimerCounter to the appropriate timebase increment function, it's now getting past where it was and is calling setupNewPower, and then IsPowerReady, although I"m still having problems with the timeliness there of.
2026-05-19 2:31 AM
Hi @JoeMck
Thank you for your feedback.
Since you are now seeing progression and only have remaining timing-related behavior to tune, I suggest we close this ticket as solved for the original issue.
If you still have issues with the remaining timeliness or power readiness behavior, please start a new discussion and include the current status.
Thanks again for confirming the fix.
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.
2026-05-19 7:17 AM
What I'm seeing now, in my debugger is that SetupNewPower is called, and then approx 400ms later IsPowerReady() is called, but NOTIFY REQUEST_ACCEPTED is still never being sent, looking at my notification log:
104 = USBSTACK_START
90 = POWER_STATE_CHANGE
15 = SRCCAP_SENT
90 = POWER_STATE_CHANGE
31 = HARDRESET_TX
105 = USBSTACK_STOP
and looking at my protocol analyzer, it appears that the hard reset is being sent 29ms after setupNewPower.
After EvaluateRequest returns USBPD_ACCEPT and SetupNewPower returns USBPD_ACCEPT, Is there an internal PE timer that drives the SRC to send a hard reset at ~29ms? And why does IsPowerReady not get called until ~400ms after SetupNewPower?
2026-05-19 10:20 AM
@JoeMck Would you attach your trace and voltage of CCx and VBUS.
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.
2026-05-19 12:26 PM
The top one is scaled to see VBUS, the bottom to see CC.