2026-03-19 2:34 AM - edited 2026-03-22 10:57 PM
Hello everybody
I'm working with USB PD sink on my own board with STM32G071KBT6 microcontroller ad development software: STM32CubeIDE 2.1.1 and STMCubeMX 6.17 (freeRTOS, without TCPP, with my own protection of VBUS and CC lines).
I want to set sink to APDO 24 V (if the charger accept it) or otherwise 20 V PDO.
Unfortunatelly if the charger, which I use, not accept APDO 24 V, it send hardreset and cut off the Vbus, so I can't use the flag to inform about the status (APDO or PDO).
Is there any way to read the PDOs from the source and on based on this choose APDO or PDO?
I have no structure DPM_Ports, and
USBPD_DPM_GetDataInfo(PortNum, USBPD_CORE_DATATYPE_RCV_SRC_PDO, buffer, &size);returns size = 0;
Best regards
Solved! Go to Solution.
2026-03-24 5:41 AM - edited 2026-03-24 5:44 AM
OK, now it is correct:
void USBPD_DPM_SetDataInfo(uint8_t PortNum, USBPD_CORE_DataInfoType_TypeDef DataId, uint8_t *Ptr, uint32_t Size)
{
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
/* Check type of information targeted by request */
switch(DataId)
{
//case USBPD_CORE_DATATYPE_RDO_POSITION: /*!< Reset the PDO position selected by the sink only */
// break;
case USBPD_CORE_DATATYPE_RCV_SRC_PDO: /*!< Storage of Received Source PDO values */
{
DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
uint8_t PDO_Number = Size/4;
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_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, PDO); //for information
if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL) //if APDO
{
uint32_t Max_Voltage_100mV=(PDO>>17);
Max_Voltage_100mV = Max_Voltage_100mV&0b00000000000000000000000111111111;
DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu * 100mV = %lu mV", a, Max_Voltage_100mV, (Max_Voltage_100mV*100));
if(Max_Voltage_100mV>=210U) //if APDO>=21V
{
If_APDO = 1U;
break;
}
}
}
}
break;
Trace:
CAD 2 1 USBPD_CAD_STATE_DETACHED 581
CAD 4 1 USBPD_CAD_STATE_ATTACHED_WAIT 582
CAD 123 1 USBPD_CAD_STATE_ATTACHED 583
NOTIF 123 1 USBSTACK_START 584
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 585
EVENT 123 1 EVENT_ATTACHED 586
DEBUG 123 1 ADVICE: update USBPD_DPM_UserCableDetection 587
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 588
DEBUG 123 1 ADVICE: update USBPD_DPM_SetDataInfo:2 589
DEBUG 124 1 ADVICE: update USBPD_DPM_SetDataInfo:6 590
PE 124 1 PE_SNK_STARTUP 591
PE 124 1 PE_SNK_WAIT_FOR_CAPABILITIES 592
IN 125 1 SOP PD3 s:026 H:0x61A1 (id:0, DR:DFP, PR:SRC) SRC_CAPABILITIES DATA: 2C9101082CD102002CC103002CB10400454106004121A4C9
Option: EPW
[1] Fixed : 5V - 3A
[2] Fixed : 9V - 3A
[3] Fixed : 12V - 3A
[4] Fixed : 15V - 3A
[5] Fixed : 20V - 3.25A
[6] Programmable : [3.3V - 21V] - 3.25A
593
OUT 125 1 SOP s:002 H:0x0041 (id:0, DR:UFP, PR:SNK) GOODCRC 594
DEBUG 126 1 Received: 24 bytes 595
DEBUG 126 1 PDO[0] = 0x0801912C 596
DEBUG 126 1 PDO[1] = 0x0002D12C 597
DEBUG 126 1 PDO[2] = 0x0003C12C 598
DEBUG 126 1 PDO[3] = 0x0004B12C 599
DEBUG 126 1 PDO[4] = 0x00064145 600
DEBUG 126 1 PDO[5] = 0xC9A42141 601
DEBUG 127 1 APDO [5] - max voltage: 210 * 100mV = 21000 mV 602
PE 127 1 PE_SNK_EVALUATE_CAPABILITY 603
PE 128 1 PE_SNK_SEND_REQUEST 604
OUT 128 1 SOP PD3 REQUEST s:006 H:0x1082 (id:0, DR:UFP, PR:SNK) DATA: 3C340863
ObjectPosition:6
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
Operating Current:3000mA
Operating Voltage:21000mV 605
IN 129 1 SOP s:002 H:0x0121 (id:0, DR:DFP, PR:SRC) GOODCRC 606
PE 129 1 PE_SNK_SELECT_CAPABILITY 607
IN 133 1 SOP PD3 ACCEPT s:002 H:0x03A3 (id:1, DR:DFP, PR:SRC) 608
OUT 133 1 SOP s:002 H:0x0241 (id:1, DR:UFP, PR:SNK) GOODCRC 609
NOTIF 134 1 POWER_STATE_CHANGE 610
DEBUG 134 1 ADVICE: USBPD_DPM_Notification:90 611
NOTIF 134 1 REQUEST_ACCEPTED 612
DEBUG 134 1 ADVICE: USBPD_DPM_Notification:1 613
PE 134 1 PE_SNK_TRANSITION_SNK 614
IN 368 1 SOP PD3 PS_RDY s:002 H:0x05A6 (id:2, DR:DFP, PR:SRC) 615
OUT 368 1 SOP s:002 H:0x0441 (id:2, DR:UFP, PR:SNK) GOODCRC 616
NOTIF 369 1 POWER_STATE_CHANGE 617
DEBUG 369 1 ADVICE: USBPD_DPM_Notification:90 618
NOTIF 369 1 POWER_EXPLICIT_CONTRACT 619
DEBUG 369 1 ADVICE: USBPD_DPM_Notification:16 620
PE 369 1 PE_STATE_READY 621
NOTIF 369 1 STATE_SNK_READY 622
DEBUG 369 1 ADVICE: USBPD_DPM_Notification:32 623
PE 369 1 PE_STATE_READY_WAIT 624
2026-03-24 5:10 AM - edited 2026-03-24 5:41 AM
OK it is possible now to switch between APDO and (if APDO is not possible) PDO.
Code:
void USBPD_DPM_SetDataInfo(uint8_t PortNum, USBPD_CORE_DataInfoType_TypeDef DataId, uint8_t *Ptr, uint32_t Size)
{
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
/* Check type of information targeted by request */
switch(DataId)
{
//case USBPD_CORE_DATATYPE_RDO_POSITION: /*!< Reset the PDO position selected by the sink only */
// break;
case USBPD_CORE_DATATYPE_RCV_SRC_PDO: /*!< Storage of Received Source PDO values */
{
DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
uint8_t PDO_Number = Size/4;
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_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, PDO); //for information
if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL) //if APDO exist
{
uint32_t Max_Voltage_20mV=(PDO>>9);
Max_Voltage_20mV = Max_Voltage_20mV&0b00000000000000000000011111111111; //masking
DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu * 20mV = %lu mV", a, Max_Voltage_20mV, (Max_Voltage_20mV*20));
if(Max_Voltage_20mV>=1050U) //if APDO>=21V
{
If_APDO = 1U;
break;
}
}
}
}
break;But the returned voltage value of APDO is not correct. Should be 1050 (21V) but is 528.
Trace:
CAD 2 1 USBPD_CAD_STATE_DETACHED 446
CAD 4 1 USBPD_CAD_STATE_ATTACHED_WAIT 447
CAD 123 1 USBPD_CAD_STATE_ATTACHED 448
NOTIF 123 1 USBSTACK_START 449
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 450
EVENT 123 1 EVENT_ATTACHED 451
DEBUG 123 1 ADVICE: update USBPD_DPM_UserCableDetection 452
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 453
DEBUG 123 1 ADVICE: update USBPD_DPM_SetDataInfo:2 454
DEBUG 124 1 ADVICE: update USBPD_DPM_SetDataInfo:6 455
PE 124 1 PE_SNK_STARTUP 456
PE 124 1 PE_SNK_WAIT_FOR_CAPABILITIES 457
IN 125 1 SOP PD3 s:026 H:0x61A1 (id:0, DR:DFP, PR:SRC) SRC_CAPABILITIES DATA: 2C9101082CD102002CC103002CB10400454106004121A4C9
Option: EPW
[1] Fixed : 5V - 3A
[2] Fixed : 9V - 3A
[3] Fixed : 12V - 3A
[4] Fixed : 15V - 3A
[5] Fixed : 20V - 3.25A
[6] Programmable : [3.3V - 21V] - 3.25A
458
OUT 125 1 SOP s:002 H:0x0041 (id:0, DR:UFP, PR:SNK) GOODCRC 459
DEBUG 126 1 Received: 24 bytes 460
DEBUG 126 1 PDO[0] = 0x0801912C 461
DEBUG 126 1 PDO[1] = 0x0002D12C 462
DEBUG 126 1 PDO[2] = 0x0003C12C 463
DEBUG 126 1 PDO[3] = 0x0004B12C 464
DEBUG 126 1 PDO[4] = 0x00064145 465
DEBUG 127 1 PDO[5] = 0xC9A42141 466
DEBUG 127 1 APDO [5] - max voltage: 528 * 20mV = 10560 mV 467
PE 127 1 PE_SNK_EVALUATE_CAPABILITY 468
PE 128 1 PE_SNK_SEND_REQUEST 469
OUT 128 1 SOP PD3 REQUEST s:006 H:0x1082 (id:0, DR:UFP, PR:SNK) DATA: 2CB10453
ObjectPosition:5
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
MaximumOperatingCurrent:3000mA
OperatingCurrent:3000mA 470
IN 129 1 SOP s:002 H:0x0121 (id:0, DR:DFP, PR:SRC) GOODCRC 471
PE 129 1 PE_SNK_SELECT_CAPABILITY 472
IN 133 1 SOP PD3 ACCEPT s:002 H:0x03A3 (id:1, DR:DFP, PR:SRC) 473
OUT 133 1 SOP s:002 H:0x0241 (id:1, DR:UFP, PR:SNK) GOODCRC 474
NOTIF 134 1 POWER_STATE_CHANGE 475
DEBUG 134 1 ADVICE: USBPD_DPM_Notification:90 476
NOTIF 134 1 REQUEST_ACCEPTED 477
DEBUG 134 1 ADVICE: USBPD_DPM_Notification:1 478
PE 134 1 PE_SNK_TRANSITION_SNK 479
IN 382 1 SOP PD3 PS_RDY s:002 H:0x05A6 (id:2, DR:DFP, PR:SRC) 480
OUT 382 1 SOP s:002 H:0x0441 (id:2, DR:UFP, PR:SNK) GOODCRC 481
NOTIF 383 1 POWER_STATE_CHANGE 482
DEBUG 383 1 ADVICE: USBPD_DPM_Notification:90 483
NOTIF 383 1 POWER_EXPLICIT_CONTRACT 484
DEBUG 383 1 ADVICE: USBPD_DPM_Notification:16 485
PE 383 1 PE_STATE_READY 486
NOTIF 383 1 STATE_SNK_READY 487
DEBUG 383 1 ADVICE: USBPD_DPM_Notification:32 488
PE 383 1 PE_STATE_READY_WAIT 489 What is wrong?
2026-03-24 5:41 AM - edited 2026-03-24 5:44 AM
OK, now it is correct:
void USBPD_DPM_SetDataInfo(uint8_t PortNum, USBPD_CORE_DataInfoType_TypeDef DataId, uint8_t *Ptr, uint32_t Size)
{
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
/* Check type of information targeted by request */
switch(DataId)
{
//case USBPD_CORE_DATATYPE_RDO_POSITION: /*!< Reset the PDO position selected by the sink only */
// break;
case USBPD_CORE_DATATYPE_RCV_SRC_PDO: /*!< Storage of Received Source PDO values */
{
DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
uint8_t PDO_Number = Size/4;
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_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, PDO); //for information
if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL) //if APDO
{
uint32_t Max_Voltage_100mV=(PDO>>17);
Max_Voltage_100mV = Max_Voltage_100mV&0b00000000000000000000000111111111;
DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu * 100mV = %lu mV", a, Max_Voltage_100mV, (Max_Voltage_100mV*100));
if(Max_Voltage_100mV>=210U) //if APDO>=21V
{
If_APDO = 1U;
break;
}
}
}
}
break;
Trace:
CAD 2 1 USBPD_CAD_STATE_DETACHED 581
CAD 4 1 USBPD_CAD_STATE_ATTACHED_WAIT 582
CAD 123 1 USBPD_CAD_STATE_ATTACHED 583
NOTIF 123 1 USBSTACK_START 584
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 585
EVENT 123 1 EVENT_ATTACHED 586
DEBUG 123 1 ADVICE: update USBPD_DPM_UserCableDetection 587
DEBUG 123 1 ADVICE: USBPD_DPM_Notification:104 588
DEBUG 123 1 ADVICE: update USBPD_DPM_SetDataInfo:2 589
DEBUG 124 1 ADVICE: update USBPD_DPM_SetDataInfo:6 590
PE 124 1 PE_SNK_STARTUP 591
PE 124 1 PE_SNK_WAIT_FOR_CAPABILITIES 592
IN 125 1 SOP PD3 s:026 H:0x61A1 (id:0, DR:DFP, PR:SRC) SRC_CAPABILITIES DATA: 2C9101082CD102002CC103002CB10400454106004121A4C9
Option: EPW
[1] Fixed : 5V - 3A
[2] Fixed : 9V - 3A
[3] Fixed : 12V - 3A
[4] Fixed : 15V - 3A
[5] Fixed : 20V - 3.25A
[6] Programmable : [3.3V - 21V] - 3.25A
593
OUT 125 1 SOP s:002 H:0x0041 (id:0, DR:UFP, PR:SNK) GOODCRC 594
DEBUG 126 1 Received: 24 bytes 595
DEBUG 126 1 PDO[0] = 0x0801912C 596
DEBUG 126 1 PDO[1] = 0x0002D12C 597
DEBUG 126 1 PDO[2] = 0x0003C12C 598
DEBUG 126 1 PDO[3] = 0x0004B12C 599
DEBUG 126 1 PDO[4] = 0x00064145 600
DEBUG 126 1 PDO[5] = 0xC9A42141 601
DEBUG 127 1 APDO [5] - max voltage: 210 * 100mV = 21000 mV 602
PE 127 1 PE_SNK_EVALUATE_CAPABILITY 603
PE 128 1 PE_SNK_SEND_REQUEST 604
OUT 128 1 SOP PD3 REQUEST s:006 H:0x1082 (id:0, DR:UFP, PR:SNK) DATA: 3C340863
ObjectPosition:6
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
Operating Current:3000mA
Operating Voltage:21000mV 605
IN 129 1 SOP s:002 H:0x0121 (id:0, DR:DFP, PR:SRC) GOODCRC 606
PE 129 1 PE_SNK_SELECT_CAPABILITY 607
IN 133 1 SOP PD3 ACCEPT s:002 H:0x03A3 (id:1, DR:DFP, PR:SRC) 608
OUT 133 1 SOP s:002 H:0x0241 (id:1, DR:UFP, PR:SNK) GOODCRC 609
NOTIF 134 1 POWER_STATE_CHANGE 610
DEBUG 134 1 ADVICE: USBPD_DPM_Notification:90 611
NOTIF 134 1 REQUEST_ACCEPTED 612
DEBUG 134 1 ADVICE: USBPD_DPM_Notification:1 613
PE 134 1 PE_SNK_TRANSITION_SNK 614
IN 368 1 SOP PD3 PS_RDY s:002 H:0x05A6 (id:2, DR:DFP, PR:SRC) 615
OUT 368 1 SOP s:002 H:0x0441 (id:2, DR:UFP, PR:SNK) GOODCRC 616
NOTIF 369 1 POWER_STATE_CHANGE 617
DEBUG 369 1 ADVICE: USBPD_DPM_Notification:90 618
NOTIF 369 1 POWER_EXPLICIT_CONTRACT 619
DEBUG 369 1 ADVICE: USBPD_DPM_Notification:16 620
PE 369 1 PE_STATE_READY 621
NOTIF 369 1 STATE_SNK_READY 622
DEBUG 369 1 ADVICE: USBPD_DPM_Notification:32 623
PE 369 1 PE_STATE_READY_WAIT 624