cancel
Showing results for 
Search instead for 
Did you mean: 

Switching between USB CAD state machines

kumen
Associate

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

2 REPLIES 2
FBL
ST Employee

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.

kumen
Associate

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:

  • CAD_StateMachine_SNK
  • CAD_StateMachine_SRC
  • CAD_StateMachine_DRP

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?