2026-03-31 4:00 AM - edited 2026-03-31 4:01 AM
Hello
I have my own board with STM32G071KBT6 microcontroller. I successfully comunicate with charger by PD protocol and I receive up to 21 V (PPS). But I need above 21V. I have power bank with AVS up to 28V and USB cable with e-marker (up to 240W). How to configure the stack to receive EPR parameters? I have no TCPP IC, but I use my own protection circuit. In the trace the EPR commands isn't present. I use STM32CubeIDE 2.1.1 and STM32CubeMX 6.17.0.
Thanks a lot and best regards
2026-03-31 7:24 AM - edited 2026-03-31 12:39 PM
Hi @Jaroslaw_T
Thank you for the question.
I'm working on new knowledge base article on How to create an EPR capable USB PD Source and Sink on STM32 using TCPP ports . For demo, VBUS is kept at 5 V even for higher SPR/EPR PDOs; only the protocol is exercised (not full EPR explicit contract).
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-04-03 2:00 AM
Is any way to receive PDO and APDO greater than 21V PPS? Unfortunatelly I have in my trace messages with max APDO 21V and PDO 20V.
2026-04-06 2:09 AM
Hello @Jaroslaw_T
You need to redefine PDO to support EPR:
uint32_t PORT0_PDO_ListSRC[USBPD_MAX_NB_PDO] =
{
#ifndef _EPR_SRC
/* PDO 1 */ (0x00019096U),
#else /*_EPR_SRC*/
/* PDO 1 */
( ((PWR_A_10MA(USBPD_CORE_PDO_SRC_FIXED_MAX_CURRENT)) << USBPD_PDO_SRC_FIXED_MAX_CURRENT_Pos) |
((PWR_V_50MV(5)) << USBPD_PDO_SRC_FIXED_VOLTAGE_Pos) |
USBPD_PDO_SRC_FIXED_PEAKCURRENT_EQUAL |
#if defined(_EPR_SRC)
USBPD_PDO_SRC_FIXED_EPR_SUPPORTED |
#endif /* _EPR_SRC */
#if defined(USBPD_REV30_SUPPORT)
#if defined(_UNCHUNKED_SUPPORT)
USBPD_PDO_SRC_FIXED_UNCHUNK_SUPPORTED |
#else
USBPD_PDO_SRC_FIXED_UNCHUNK_NOT_SUPPORTED |
#endif /* _UNCHUNKED_SUPPORT */
#endif /*USBPD_REV30_SUPPORT*/
USBPD_PDO_SRC_FIXED_DRD_NOT_SUPPORTED |
#ifdef _USB_HOST
USBPD_PDO_SRC_FIXED_USBCOMM_SUPPORTED |
#else
USBPD_PDO_SRC_FIXED_USBCOMM_NOT_SUPPORTED |
#endif
USBPD_PDO_SRC_FIXED_EXT_POWER_NOT_AVAILABLE |
USBPD_PDO_SRC_FIXED_USBSUSPEND_NOT_SUPPORTED |
USBPD_PDO_SRC_FIXED_DRP_NOT_SUPPORTED |
USBPD_PDO_TYPE_FIXED
),
/* PDO 2 */(0x00000000U),
/* PDO 3 */(0x00000000U),
/* PDO 4 */(0x00000000U),
/* PDO 5 */ (0x00000000U),
/* PDO 6 */ (0x00000000U),
/* PDO 7 */ (0x00000000U)
};
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-04-06 9:22 PM - edited 2026-04-07 1:45 AM
Thank You, but I have sink device, not source.
Will the USB PD stack for STM32G0 support PD3.1 (EPR mode)? I have project with STM32G0 microcontroller because of low cost and unfortunatelly I can't use other uC.
I read that X-CUBE-TCPP supports PD3.1, but how to use it without any TCPP IC? Is it posiible any way.
2026-04-09 12:26 AM - edited 2026-04-09 12:30 AM
Now I have downloaded the MW from github.com page: https://github.com/STMicroelectronics/stm32-mw-usbpd-core/tree/main and after the files update the EPR mode seems to be working.
In my code (usbpd_dpm_user.c):
USBPD_StatusTypeDef USBPD_DPM_UserInit(void)
{
/* USER CODE BEGIN USBPD_DPM_UserInit */
DPM_Params[0].PE_SpecRevision=USBPD_SPECIFICATION_REV3;
DPM_Settings[0].PE_PD3_Support.d.Is_EPR_Supported_SNK=USBPD_TRUE;
return USBPD_OK;
/* USER CODE END USBPD_DPM_UserInit */
}In function USBPD_DPM_Notification:
switch(EventVal)
{
case USBPD_NOTIFY_POWER_EXPLICIT_CONTRACT :
{
USBPD_PE_Request_EPRModeEnter(PortNum);
}
break;In function USBPD_DPM_SNK_EvaluateCapabilities:
USBPD_SNKRDO_TypeDef rdo;
rdo.d32=0U;
if(DPM_Settings[PortNum].PE_PD3_Support.d.Is_EPR_Supported_SNK==USBPD_TRUE&&DPM_Params[PortNum].PE_SpecRevision>=USBPD_SPECIFICATION_REV3)
{
rdo.FixedVariableRDO.EPR_Capable=1U;
}
else
{
rdo.FixedVariableRDO.EPR_Capable=0U;
}
By the way - will the middleware update be officially available as an STM32Cube package update?
2026-04-09 11:17 PM - edited 2026-04-22 4:54 AM
Hello, I'm able to enter in EPR mode, as below:
CAD 2 1 USBPD_CAD_STATE_DETACHED 850
CAD 4 1 USBPD_CAD_STATE_ATTACHED_WAIT 851
CAD 123 1 USBPD_CAD_STATE_ATTACHED 852
NOTIF 123 1 USBSTACK_START 853
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 854
EVENT 123 1 EVENT_ATTACHED 855
DEBUG 123 1 ADVICE: update USBPD_DPM_UserCableDetection 856
DEBUG 123 1 ADVICE: update USBPD_DPM_SetDataInfo:2 857
DEBUG 123 1 ADVICE: update USBPD_DPM_SetDataInfo:6 858
PE 124 1 PE_SNK_STARTUP 859
PE 124 1 PE_SNK_WAIT_FOR_CAPABILITIES 860
IN 146 1 SOP PD3 s:030 H:0x71A1 (id:0, DR:DFP, PR:SRC) SRC_CAPABILITIES DATA: 2C9181282CD102002CC103002CB10400F44106003C21DCC03C21A4C1
Option: EPW DRP
[1] Fixed : 5V - 3A
[2] Fixed : 9V - 3A
[3] Fixed : 12V - 3A
[4] Fixed : 15V - 3A
[5] Fixed : 20V - 5A
[6] Programmable : [3.3V - 11V] - 3A
[7] Programmable : [3.3V - 21V] - 3A
861
OUT 146 1 SOP s:002 H:0x0081 (id:0, DR:UFP, PR:SNK) GOODCRC 862
DEBUG 147 1 Received: 28 bytes 863
DEBUG 147 1 PDO[1] = 5000 mV, 3000 mA, 15 W 864
DEBUG 147 1 PDO[2] = 9000 mV, 3000 mA, 27 W 865
DEBUG 147 1 PDO[3] = 12000 mV, 3000 mA, 36 W 866
DEBUG 148 1 PDO[4] = 15000 mV, 3000 mA, 45 W 867
DEBUG 148 1 PDO[5] = 20000 mV, 5000 mA, 100 W 868
DEBUG 148 1 APDO [6] - max voltage: 11000 mV 869
DEBUG 148 1 APDO [7] - max voltage: 21000 mV 870
PE 148 1 PE_SNK_EVALUATE_CAPABILITY 871
PE 149 1 PE_SNK_SEND_REQUEST 872
OUT 149 1 SOP PD3 REQUEST s:006 H:0x1082 (id:0, DR:UFP, PR:SNK) DATA: F4D14753
ObjectPosition:5
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
MaximumOperatingCurrent:5000mA
OperatingCurrent:5000mA 873
IN 150 1 SOP s:002 H:0x0161 (id:0, DR:DFP, PR:SRC) GOODCRC 874
PE 150 1 PE_SNK_SELECT_CAPABILITY 875
IN 152 1 SOP PD3 ACCEPT s:002 H:0x03A3 (id:1, DR:DFP, PR:SRC) 876
OUT 152 1 SOP s:002 H:0x0281 (id:1, DR:UFP, PR:SNK) GOODCRC 877
NOTIF 153 1 POWER_STATE_CHANGE 878
DEBUG 153 1 ADVICE: USBPD_DPM_Notification:90 879
NOTIF 153 1 REQUEST_ACCEPTED 880
DEBUG 153 1 ADVICE: USBPD_DPM_Notification:1 881
PE 153 1 PE_SNK_TRANSITION_SNK 882
IN 449 1 SOP PD3 PS_RDY s:002 H:0x05A6 (id:2, DR:DFP, PR:SRC) 883
OUT 449 1 SOP s:002 H:0x0481 (id:2, DR:UFP, PR:SNK) GOODCRC 884
NOTIF 450 1 POWER_STATE_CHANGE 885
DEBUG 450 1 ADVICE: USBPD_DPM_Notification:90 886
NOTIF 450 1 POWER_EXPLICIT_CONTRACT 887
PE 450 1 PE_STATE_READY 888
NOTIF 450 1 STATE_SNK_READY 889
DEBUG 450 1 ADVICE: USBPD_DPM_Notification:32 890
PE 450 1 PE_STATE_SEND_EPRMODE 891
DEBUG 450 1 ADVICE: update USBPD_DPM_GetDataInfo:30 892
OUT 450 1 SOP s:006 PD3 H:0x128A (id:1, DR:UFP, PR:SNK) EPR_MODE
EPR_MODE : 01000000
Action: 01
0x01 Enter Sink only
0x02 Enter Acknowledged Source only
0x03 Enter Succeeded Source only
0x04 Enter Failed Source only
0x05 Exit Sink or Source
Data: 00
0x00 - Unknown cause
0x01 - Cable not EPR capable
0x02 - Source failed to become VCONN source
0x03 - EPR Mode Capable bit not set in RDO
0x04 - Source unable to enter EPR Mode at this time
0x05 - EPR Mode Capable bit not set in PDO
893
IN 452 1 SOP s:002 H:0x03A1 (id:1, DR:DFP, PR:SRC) GOODCRC 894
PE 452 1 PE_STATE_WAIT_EPRMODE_ACK 895
IN 453 1 SOP s:006 PD3 H:0x17AA (id:3, DR:DFP, PR:SRC) EPR_MODE
EPR_MODE : 02000000
Action: 02
0x01 Enter Sink only
0x02 Enter Acknowledged Source only
0x03 Enter Succeeded Source only
0x04 Enter Failed Source only
0x05 Exit Sink or Source
Data: 00
0x00 - Unknown cause
0x01 - Cable not EPR capable
0x02 - Source failed to become VCONN source
0x03 - EPR Mode Capable bit not set in RDO
0x04 - Source unable to enter EPR Mode at this time
0x05 - EPR Mode Capable bit not set in PDO
896
OUT 453 1 SOP s:002 H:0x0681 (id:3, DR:UFP, PR:SNK) GOODCRC 897
DEBUG 453 1 ADVICE: update USBPD_DPM_SetDataInfo:23 898
NOTIF 453 1 NOTIFY_EPRMODE_ACK 899
DEBUG 453 1 ADVICE: USBPD_DPM_Notification:113 900
IN 469 1 SOP s:006 PD3 H:0x11AA (id:0, DR:DFP, PR:SRC) EPR_MODE
EPR_MODE : 03000000
Action: 03
0x01 Enter Sink only
0x02 Enter Acknowledged Source only
0x03 Enter Succeeded Source only
0x04 Enter Failed Source only
0x05 Exit Sink or Source
Data: 00
0x00 - Unknown cause
0x01 - Cable not EPR capable
0x02 - Source failed to become VCONN source
0x03 - EPR Mode Capable bit not set in RDO
0x04 - Source unable to enter EPR Mode at this time
0x05 - EPR Mode Capable bit not set in PDO
901
OUT 469 1 SOP s:002 H:0x0081 (id:0, DR:UFP, PR:SNK) GOODCRC 902
PE 469 1 PE_STATE_WAIT_EPRMODE_STATUS 903
DEBUG 469 1 ADVICE: update USBPD_DPM_SetDataInfo:23 904
NOTIF 469 1 NOTIFY_EPRMODE_SUCCEEDED 905
DEBUG 469 1 ADVICE: USBPD_DPM_Notification:114 906
PE 470 1 PE_SNK_WAIT_FOR_CAPABILITIES 907
IN 471 1 SOP s:030 PD3 H:0xF3B1 (id:1, DR:DFP, PR:SRC) EXT_EPR_SOURCE_CAPA EXT:CNu0Ch1CReq0DSiz32 [ CHUNK BEGIN ] DATA: 2C9181282CD102002CC103002CB10400F44106003C21DCC03C21 908
OUT 471 1 SOP s:002 H:0x0281 (id:1, DR:UFP, PR:SNK) GOODCRC 909
OUT 473 1 SOP s:006 PD3 H:0x9491 (id:2, DR:UFP, PR:SNK) EXT_EPR_SOURCE_CAPA EXT:CNu1Ch1CReq1DSiz0 DATA: 0000 910
IN 474 1 SOP s:002 H:0x05A1 (id:2, DR:DFP, PR:SRC) GOODCRC 911
IN 475 1 SOP s:014 PD3 H:0xB5B1 (id:2, DR:DFP, PR:SRC) EXT_EPR_SOURCE_CAPA EXT:CNu1Ch1CReq0DSiz36 [ CHUNK END ]
EPR SOURCE CAPA
[1] Fixed : 5V - 3A
[2] Fixed : 9V - 3A
[3] Fixed : 12V - 3A
[4] Fixed : 15V - 3A
[5] Fixed : 20V - 5A
[6] EPR : [11V - 3.3V] - 60W
[7] EPR : [21V - 3.3V] - 60W
[8] Fixed : 28V - 5A
[9] EPR : [28V - 15V] - 140W
DATA: A4C1F4C188008C9630D2 912
OUT 475 1 SOP s:002 H:0x0481 (id:2, DR:UFP, PR:SNK) GOODCRC 913
DEBUG 476 1 Received: 28 bytes 914
DEBUG 476 1 PDO[1] = 5000 mV, 3000 mA, 15 W 915
DEBUG 476 1 PDO[2] = 9000 mV, 3000 mA, 27 W 916
DEBUG 477 1 PDO[3] = 12000 mV, 3000 mA, 36 W 917
DEBUG 477 1 PDO[4] = 15000 mV, 3000 mA, 45 W 918
DEBUG 477 1 PDO[5] = 20000 mV, 5000 mA, 100 W 919
DEBUG 477 1 APDO [6] - max voltage: 11000 mV 920
DEBUG 477 1 APDO [7] - max voltage: 21000 mV 921
DEBUG 477 1 EPR - received: 4 bytes 922
DEBUG 477 1 0x0088C1F4 923
DEBUG 477 1 EPR - max voltage: 6800 mV 924
PE 477 1 PE_SNK_EVALUATE_CAPABILITY 925
PE 479 1 PE_SNK_SEND_REQUEST 926
DEBUG 479 1 ADVICE: update USBPD_DPM_GetDataInfo:29 927
OUT 479 1 SOP PD3 EPR_REQUEST s:010 H:0x2689 (id:3, DR:UFP, PR:SNK) DATA: F4D1475300000000
ObjectPosition:5
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
MaximumOperatingCurrent:5000mA
OperatingCurrent:5000mA 928
IN 481 1 SOP s:002 H:0x07A1 (id:3, DR:DFP, PR:SRC) GOODCRC 929
PE 481 1 PE_SNK_SELECT_CAPABILITY 930
IN 482 1 SOP PD3 ACCEPT s:002 H:0x07A3 (id:3, DR:DFP, PR:SRC) 931
OUT 482 1 SOP s:002 H:0x0681 (id:3, DR:UFP, PR:SNK) GOODCRC 932
NOTIF 483 1 POWER_STATE_CHANGE 933
DEBUG 483 1 ADVICE: USBPD_DPM_Notification:90 934
NOTIF 483 1 REQUEST_ACCEPTED 935
DEBUG 483 1 ADVICE: USBPD_DPM_Notification:1 936
PE 483 1 PE_SNK_TRANSITION_SNK 937
IN 777 1 SOP PD3 PS_RDY s:002 H:0x09A6 (id:4, DR:DFP, PR:SRC) 938
OUT 777 1 SOP s:002 H:0x0881 (id:4, DR:UFP, PR:SNK) GOODCRC 939
NOTIF 778 1 POWER_STATE_CHANGE 940
DEBUG 778 1 ADVICE: USBPD_DPM_Notification:90 941
NOTIF 778 1 POWER_EXPLICIT_CONTRACT 942
PE 778 1 PE_STATE_READY 943
NOTIF 778 1 STATE_SNK_READY 944
DEBUG 778 1 ADVICE: USBPD_DPM_Notification:32 945
PE 778 1 PE_STATE_SEND_EPRMODE 946
DEBUG 778 1 ADVICE: update USBPD_DPM_GetDataInfo:30 947
OUT 778 1 SOP s:006 PD3 H:0x188A (id:4, DR:UFP, PR:SNK) EPR_MODE
EPR_MODE : 01000000
Action: 01
0x01 Enter Sink only
0x02 Enter Acknowledged Source only
0x03 Enter Succeeded Source only
0x04 Enter Failed Source only
0x05 Exit Sink or Source
Data: 00
0x00 - Unknown cause
0x01 - Cable not EPR capable
0x02 - Source failed to become VCONN source
0x03 - EPR Mode Capable bit not set in RDO
0x04 - Source unable to enter EPR Mode at this time
0x05 - EPR Mode Capable bit not set in PDO
948
IN 780 1 SOP s:002 H:0x09A1 (id:4, DR:DFP, PR:SRC) GOODCRC 949
PE 780 1 PE_STATE_WAIT_EPRMODE_ACK 950
IN 1743 1 HRST 951
NOTIF 1743 1 HARDRESET_RX 952
DEBUG 1743 1 ADVICE: USBPD_DPM_Notification:30 953
PE 1743 1 PE_HARD_RESET_RECEIVED 954
PE 1743 1 PE_SNK_HARD_RESET_WAIT_VSAFE_0V 955
GUI 0 BOARD RESET BY USER 956
CAD 4 1 USBPD_CAD_STATE_ATTACHED_WAIT 957 but unfortunately I have no access to all received EPR PDOs and APDOs.
In case
case USBPD_CORE_DATATYPE_RCV_SRC_PDO_EPR:
I have only 4 bytes of data.
Case code:
case USBPD_CORE_DATATYPE_RCV_SRC_PDO_EPR:
{
uint32_t EPR_1=0;
uint32_t EPR_2=0;
uint32_t EPR_3=0;
uint32_t EPR_4=0;
uint32_t EPR=0;
DPM_USER_DEBUG_TRACE(PortNum, "EPR - received: %lu bytes", Size);
EPR_1=0;
EPR_2=0;
EPR_3=0;
EPR_4=0;
EPR=0;
EPR_1=(uint32_t)Ptr[0*4U+0U]<<0;
EPR_2=(uint32_t)Ptr[0*4U+1U]<<8;
EPR_3=(uint32_t)Ptr[0*4U+2U]<<16;
EPR_4=(uint32_t)Ptr[0*4U+3U]<<24;
EPR=EPR_1|EPR_2|EPR_3|EPR_4;
DPM_USER_DEBUG_TRACE(PortNum, "0x%08lX", EPR);
uint32_t Max_Voltage_100mV=(EPR>>17);
Max_Voltage_100mV = Max_Voltage_100mV&0b00000000000000000000000111111111;
DPM_USER_DEBUG_TRACE(PortNum, "EPR - max voltage: %lu mV", (Max_Voltage_100mV*100));
}
break;
SPR checking:
case USBPD_CORE_DATATYPE_RCV_SRC_PDO: /*!< Storage of Received Source PDO values */
{
DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
PDO_Max_Number = Size/4; //każdy PDO to 4 bajty
if(Size==0U || Size%4U != 0U)
{
DPM_USER_DEBUG_TRACE(PortNum, "Invalid size - run fixed PDO");
If_APDO = 0U;
break;
}
for(uint8_t a=0; a<PDO_Max_Number; a++)
{
PDO_1=0;
PDO_2=0;
PDO_3=0;
PDO_4=0;
PDO=0;
PDO_1=(uint32_t)Ptr[a*4U+0U]<<0;
PDO_2=(uint32_t)Ptr[a*4U+1U]<<8;
PDO_3=(uint32_t)Ptr[a*4U+2U]<<16;
PDO_4=(uint32_t)Ptr[a*4U+3U]<<24;
PDO=PDO_1|PDO_2|PDO_3|PDO_4;
//DPM_USER_DEBUG_TRACE(PortNum, "PDO[%u] = 0x%08lX", a+1, PDO);
if((PDO&0b11000000000000000000000000000000UL)!=0b11000000000000000000000000000000UL)
{
uint32_t Fallback_Voltage=0;
Fallback_Voltage=(PDO>>10);
Fallback_Voltage=Fallback_Voltage&0b00000000000000000000001111111111;
Fallback_Voltage=Fallback_Voltage*50; //napięcie w mV
Fallback_Current=PDO&0b00000000000000000000001111111111;
Fallback_Current=Fallback_Current*10; //prąd w mA
Max_Power[a+1]=Fallback_Voltage*Fallback_Current/1000000;
DPM_USER_DEBUG_TRACE(PortNum, "PDO[%u] = %lu mV, %lu mA, %lu W" , a+1, Fallback_Voltage, Fallback_Current, Max_Power[a+1]);
if(Fallback_Voltage==20000)
{
Fallback_PDO=a+1;
Fallback_Current = Fallback_Current/10;
If_APDO = 0U;
}
}
if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL)
{
uint32_t Max_Voltage_100mV=(PDO>>17);
Max_Voltage_100mV = Max_Voltage_100mV&0b00000000000000000000000111111111;
DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu mV", a+1, (Max_Voltage_100mV*100));
if(Max_Voltage_100mV>=Requested_Voltage)
{
Requested_APDO=a+1;
//If_APDO = 1U;
}
}
}
}
break;How to access to full data with all EPR PDOs and APDOs? I have no DPM_Ports.
Best regards
2026-04-10 10:01 AM
Hi @Jaroslaw_T
Sorry for not getting back to you sooner. I will clarify this part in the article. Chucking is mandatory in EPR mode in PD3.1;
Now in your case I'm suspecting your handling of extended/chunked messages; can you test with the following source example. Here is my HW setup:
For my case, to store received SRC EPR PDOs
case USBPD_CORE_DATATYPE_RCV_SRC_PDO_EPR:
if (Size <= (USBPD_MAX_NB_PDO * 4))
{
uint8_t *pdo;
DPM_Ports[PortNum].DPM_NumberOfRcvSRCEPRPDO = (Size / 4);
for (index = 0; index < (Size / 4); index++)
{
pdo = (uint8_t *)&DPM_Ports[PortNum].DPM_ListOfRcvSRCEPRPDO[index];
memcpy(pdo, Ptr + index * 4U, 4U);
}
}
break;
Can you replace your source and attach it to the Sink with the proposed setup?
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-04-19 10:06 PM - edited 2026-04-22 4:54 AM
Thank You
Unfortunately I have only setup for SINK. For my solution I have my own PCB with STM32G071KBT6 uC. Also I have no DPM_Ports. In USBPD_CORE_DATATYPE_RCV_SRC_PDO_EPR I have only 4 bytes of data.
Best regards
Jaroslaw
2026-04-20 7:23 AM
Thanks for the clarification @Jaroslaw_T .
Can you verify whether the source used advertises EPR capabilities using chunked or unchunked extended messages?
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.