2026-03-17 6:10 AM - last edited on 2026-03-18 1:38 AM by Gyessine
Hello everybody
I'm building the device with power delivery sink function. I need the 21V (PPS). I done the configuration with STM32CubeMX and wrote some code in STM32CubeIDE. Unfortunately, after about 14 s of estabilishing connection, the source send hardware reset. What is the problem? In the attached file is the trase from STM32CubeMonitor-UCPD. I use STM32CubeIDE v. 2.1.1 and STM32CubeMX v. 6.17.0.
void USBPD_DPM_SNK_EvaluateCapabilities(uint8_t PortNum, uint32_t *PtrRequestData, USBPD_CORE_PDO_Type_TypeDef *PtrPowerObjectType)
{
/* USER CODE BEGIN USBPD_DPM_SNK_EvaluateCapabilities */
//DPM_USER_DEBUG_TRACE(PortNum, "ADVICE: update USBPD_DPM_SNK_EvaluateCapabilities");
USBPD_SNKRDO_TypeDef rdo;
rdo.d32=0U;
rdo.ProgRDO.ObjectPosition=6U;
rdo.ProgRDO.OutputVoltageIn20mV=1050U; //21V
rdo.ProgRDO.OperatingCurrentIn50mAunits=60U; //3A
rdo.ProgRDO.NoUSBSuspend=USBPD_ENABLE;
rdo.ProgRDO.USBCommunicationsCapable=USBPD_ENABLE;
*PtrPowerObjectType=USBPD_CORE_PDO_TYPE_APDO;
*PtrRequestData=rdo.d32;
/* USER CODE END USBPD_DPM_SNK_EvaluateCapabilities */
}
Best regards
Solved! Go to Solution.
2026-03-18 2:52 AM
I solved this problem (with AI help ;) )
In file main.c I added the tas, which periodically send request, as below:
void StartPeriodTask1(void const * argument)
{
/* USER CODE BEGIN StartPeriodTask1 */
/* Infinite loop */
for(;;)
{
USBPD_PE_Send_Request(USBPD_PORT_0, PDO_Parameters, APDO_Position);
osDelay(12000);
}
/* USER CODE END StartPeriodTask1 */
}
In main.h:
extern uint32_t PDO_Parameters;
extern uint8_t APDO_Position;
And in usbpd_dpm_user.c:
uint8_t If_APDO=1U;
uint32_t PDO_Parameters=0U;
uint8_t APDO_Position=0U;And:
void USBPD_DPM_SNK_EvaluateCapabilities(uint8_t PortNum, uint32_t *PtrRequestData, USBPD_CORE_PDO_Type_TypeDef *PtrPowerObjectType)
{
/* USER CODE BEGIN USBPD_DPM_SNK_EvaluateCapabilities */
//DPM_USER_DEBUG_TRACE(PortNum, "ADVICE: update USBPD_DPM_SNK_EvaluateCapabilities");
USBPD_SNKRDO_TypeDef rdo;
if(If_APDO==1)
{
rdo.d32=0U;
rdo.ProgRDO.ObjectPosition=6U;
rdo.ProgRDO.OutputVoltageIn20mV=1050U; //24V
rdo.ProgRDO.OperatingCurrentIn50mAunits=60U; //3A
rdo.ProgRDO.NoUSBSuspend=USBPD_ENABLE;
rdo.ProgRDO.USBCommunicationsCapable=USBPD_ENABLE;
*PtrPowerObjectType=USBPD_CORE_PDO_TYPE_APDO;
*PtrRequestData=rdo.d32;
PDO_Parameters=rdo.d32;
APDO_Position=rdo.ProgRDO.ObjectPosition;
}
else
{
rdo.d32=0U;
rdo.FixedVariableRDO.ObjectPosition=5U;
rdo.FixedVariableRDO.MaxOperatingCurrent10mAunits=300U;
rdo.FixedVariableRDO.OperatingCurrentIn10mAunits=300U;
rdo.FixedVariableRDO.USBCommunicationsCapable=USBPD_ENABLE;
rdo.FixedVariableRDO.NoUSBSuspend=USBPD_ENABLE;
rdo.FixedVariableRDO.CapabilityMismatch=USBPD_DISABLE;
*PtrPowerObjectType=USBPD_CORE_PDO_TYPE_FIXED;
*PtrRequestData=rdo.d32;
}
/* USER CODE END USBPD_DPM_SNK_EvaluateCapabilities */
}
Maybe it will help someone :)
2026-03-18 2:52 AM
I solved this problem (with AI help ;) )
In file main.c I added the tas, which periodically send request, as below:
void StartPeriodTask1(void const * argument)
{
/* USER CODE BEGIN StartPeriodTask1 */
/* Infinite loop */
for(;;)
{
USBPD_PE_Send_Request(USBPD_PORT_0, PDO_Parameters, APDO_Position);
osDelay(12000);
}
/* USER CODE END StartPeriodTask1 */
}
In main.h:
extern uint32_t PDO_Parameters;
extern uint8_t APDO_Position;
And in usbpd_dpm_user.c:
uint8_t If_APDO=1U;
uint32_t PDO_Parameters=0U;
uint8_t APDO_Position=0U;And:
void USBPD_DPM_SNK_EvaluateCapabilities(uint8_t PortNum, uint32_t *PtrRequestData, USBPD_CORE_PDO_Type_TypeDef *PtrPowerObjectType)
{
/* USER CODE BEGIN USBPD_DPM_SNK_EvaluateCapabilities */
//DPM_USER_DEBUG_TRACE(PortNum, "ADVICE: update USBPD_DPM_SNK_EvaluateCapabilities");
USBPD_SNKRDO_TypeDef rdo;
if(If_APDO==1)
{
rdo.d32=0U;
rdo.ProgRDO.ObjectPosition=6U;
rdo.ProgRDO.OutputVoltageIn20mV=1050U; //24V
rdo.ProgRDO.OperatingCurrentIn50mAunits=60U; //3A
rdo.ProgRDO.NoUSBSuspend=USBPD_ENABLE;
rdo.ProgRDO.USBCommunicationsCapable=USBPD_ENABLE;
*PtrPowerObjectType=USBPD_CORE_PDO_TYPE_APDO;
*PtrRequestData=rdo.d32;
PDO_Parameters=rdo.d32;
APDO_Position=rdo.ProgRDO.ObjectPosition;
}
else
{
rdo.d32=0U;
rdo.FixedVariableRDO.ObjectPosition=5U;
rdo.FixedVariableRDO.MaxOperatingCurrent10mAunits=300U;
rdo.FixedVariableRDO.OperatingCurrentIn10mAunits=300U;
rdo.FixedVariableRDO.USBCommunicationsCapable=USBPD_ENABLE;
rdo.FixedVariableRDO.NoUSBSuspend=USBPD_ENABLE;
rdo.FixedVariableRDO.CapabilityMismatch=USBPD_DISABLE;
*PtrPowerObjectType=USBPD_CORE_PDO_TYPE_FIXED;
*PtrRequestData=rdo.d32;
}
/* USER CODE END USBPD_DPM_SNK_EvaluateCapabilities */
}
Maybe it will help someone :)
2026-03-18 4:45 AM - edited 2026-03-18 4:46 AM
Hi @Jaroslaw_T,
Thanks for sharing your findings and workaround, this is very valuable for others.
Calling USBPD_PE_Send_Request() from your own task bypass the PD policy engine and lead to requests to be sent out of sequence. In general, it’s better to let the PD stack drive the protocol and decide when to send requests, using USBPD_DPM_SNK_EvaluateCapabilities() to build the RDO when the core asks for it.
Your solution will definitely help others avoid the same pitfall.
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.