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?