cancel
Showing results for 
Search instead for 
Did you mean: 

Switching between USB CAD state machines

kumen
Associate II

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

3 REPLIES 3
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 II

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?

 

kumen
Associate II

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?