2024-10-21 03:18 AM - last edited on 2024-12-06 06:02 AM by Andrew Neil
Hi, what is the correct way to switch between CAD state machines? For example, between DRP to SNK and vice versa.
Motivation: When the battery is bellow the defined SOC, switch from the DRP state machine to the SNK only and stop toggling between SRC and SNK.
Switch can be done by executing for example:
// To SNK
CAD_HW_Handles[PortNum].CAD_PtrStateMachine = &CAD_StateMachine_SNK;
// To DRP
CAD_HW_Handles[PortNum].CAD_PtrStateMachine = &CAD_StateMachine_DRP;
But what is the best place for the code to change the state machine and in what CAD state?
Hard reset? Error recovery? or simply in disconnected state?
Thanks for any advice
2024-12-06 01:25 AM
Hi @kumen
DRP is not a state machine. DRP (Dual Role Port) is a capability that allows a device to switch between power roles being a source (SRC) and a sink (SNK). To implement this capability, it in the stack you need to add predefined symbol _DRP.
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.
2024-12-06 02:57 AM
Thank you for reply.
To be more specific, I'm looking to this file: https://github.com/STMicroelectronics/stm32-mw-usbpd-device-g0/blob/main/src/usbpd_cad_hw_if.c
There are defined three CAD state machines:
And one main CAD state machine: "CAD_StateMachine" which call one of the above three ones:
/* Call the state machine corresponding to the port SNK or SRC or DRP */
_timing = _handle->CAD_PtrStateMachine(PortNum, pEvent, pCCXX);
To add ability to switch between used state machines, I added new function:
enum cad_state_machine{
e_cad_sm_snk,
e_cad_sm_src,
e_cad_sm_drp
};
USBPD_StatusTypeDef CAD_state_machine_switch(uint8_t PortNum, enum cad_state_machine machine)
{
switch(machine)
{
#if defined(_SNK)
case e_cad_sm_snk:
CAD_HW_Handles[PortNum].CAD_PtrStateMachine = &CAD_StateMachine_SNK;
#if defined(_TRACE)
USBPD_TRACE_Add(USBPD_TRACE_DEBUG, PortNum, 0,
(uint8_t *)"CAD State Machine switched to : CAD_StateMachine_SNK", 52);
#endif /* _TRACE */
return USBPD_OK;
break;
#endif
#if defined(_SRC)
case e_cad_sm_src:
CAD_HW_Handles[PortNum].CAD_PtrStateMachine = &CAD_StateMachine_SRC;
#if defined(_TRACE)
USBPD_TRACE_Add(USBPD_TRACE_DEBUG, PortNum, 0,
(uint8_t *)"CAD State Machine switched to : CAD_StateMachine_SRC", 52);
#endif /* _TRACE */
return USBPD_OK;
break;
#endif
#if defined(_DRP)
case e_cad_sm_drp:
CAD_HW_Handles[PortNum].CAD_PtrStateMachine = &CAD_StateMachine_DRP;
#if defined(_TRACE)
USBPD_TRACE_Add(USBPD_TRACE_DEBUG, PortNum, 0,
(uint8_t *)"CAD State Machine switched to : CAD_StateMachine_DRP", 52);
#endif /* _TRACE */
return USBPD_OK;
break;
#endif
default:
return USBPD_NOTSUPPORTED;
break;
}
}
Question is: Can I can call this function anytime and anywhere when cable is disconnected (DPM_Params[0].PE_IsConnected == USBPD_FALSE) or there is any other rule?
2025-01-03 04:06 PM
When CAD state machines are switched, for example, from DRP to SNK, should the Policy engine state machine be switched too? From USBPD_PE_StateMachine_DRP to USBPD_PE_StateMachine_SNK?
Or USBPD_PE_StateMachine_DRP should be called in all cases of CAD state machines?
In practice it should not be a problem to choose the corresponding PE state machine in the PE task according to the currently used CAD state machine, but the PE task is started after cable attachment, and I don't see any reason to use any other PE state machine than USBPD_PE_StateMachine_DRP. Are my assumptions correct?