cancel
Showing results for 
Search instead for 
Did you mean: 

USB PD SINK - automatic APDO/PDO

Jaroslaw_T
Associate III

Hello everybody

I'm working with USB PD sink on my own board with STM32G071KBT6 microcontroller ad development software: STM32CubeIDE 2.1.1 and STMCubeMX 6.17 (freeRTOS, without TCPP, with my own protection of VBUS and CC lines).

I want to set sink to APDO 24 V (if the charger accept it) or otherwise 20 V PDO.

Unfortunatelly if the charger, which I use, not accept APDO 24 V, it send hardreset and cut off the Vbus, so I can't use the flag to inform about the status (APDO or PDO).

Is there any way to read the PDOs from the source and on based on this choose APDO or PDO?

I have no structure DPM_Ports, and 

USBPD_DPM_GetDataInfo(PortNum, USBPD_CORE_DATATYPE_RCV_SRC_PDO, buffer, &size);

returns size = 0;

Best regards

1 ACCEPTED SOLUTION

Accepted Solutions

OK, now it is correct:

 

void USBPD_DPM_SetDataInfo(uint8_t PortNum, USBPD_CORE_DataInfoType_TypeDef DataId, uint8_t *Ptr, uint32_t Size)
{
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
  /* Check type of information targeted by request */
  switch(DataId)
  {
  //case USBPD_CORE_DATATYPE_RDO_POSITION:      /*!< Reset the PDO position selected by the sink only */
    // break;
  case USBPD_CORE_DATATYPE_RCV_SRC_PDO:       /*!< Storage of Received Source PDO values        */
  {
	  DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
	  uint8_t PDO_Number = Size/4;
	  if(Size==0U || Size%4U != 0U)
	  {
		  DPM_USER_DEBUG_TRACE(PortNum, "Invalid size - run fixed PDO");
		  If_APDO = 0U;
		  break;
	  }
	  for(uint8_t a=0; a<PDO_Number; a++)
	  {
		  PDO_1=0;
		  PDO_2=0;
		  PDO_3=0;
		  PDO_4=0;
		  PDO=0;
		  PDO_1=(uint32_t)Ptr[a*4U+0U]<<0;
		  PDO_2=(uint32_t)Ptr[a*4U+1U]<<8;
		  PDO_3=(uint32_t)Ptr[a*4U+2U]<<16;
		  PDO_4=(uint32_t)Ptr[a*4U+3U]<<24;
		  PDO=PDO_1|PDO_2|PDO_3|PDO_4;
		  DPM_USER_DEBUG_TRACE(PortNum, "PDO[%u] = 0x%08lX", a, PDO); //for information
		  if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL) //if APDO
		  {
			  uint32_t Max_Voltage_100mV=(PDO>>17);
			  Max_Voltage_100mV =  Max_Voltage_100mV&0b00000000000000000000000111111111;
			  DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu * 100mV = %lu mV", a, Max_Voltage_100mV, (Max_Voltage_100mV*100));
			  if(Max_Voltage_100mV>=210U) //if APDO>=21V
			  {
				  If_APDO = 1U;
				  break;
			  }
		  }
	  }
  }
     break;

 

Trace:

 

CAD	2	1	USBPD_CAD_STATE_DETACHED	581	
CAD	4	1	USBPD_CAD_STATE_ATTACHED_WAIT	582	
CAD	123	1	USBPD_CAD_STATE_ATTACHED	583	
NOTIF	123	1	USBSTACK_START	584	
DEBUG	123	1	ADVICE: USBPD_DPM_Notification:104	585	
EVENT	123	1	EVENT_ATTACHED	586	
DEBUG	123	1	ADVICE: update USBPD_DPM_UserCableDetection	587	
DEBUG	123	1	ADVICE: USBPD_DPM_Notification:104	588	
DEBUG	123	1	ADVICE: update USBPD_DPM_SetDataInfo:2	589	
DEBUG	124	1	ADVICE: update USBPD_DPM_SetDataInfo:6	590	
PE	124	1	PE_SNK_STARTUP	591	
PE	124	1	PE_SNK_WAIT_FOR_CAPABILITIES	592	
IN	125	1	SOP	 PD3	s:026	    H:0x61A1    	(id:0, DR:DFP, PR:SRC) 	SRC_CAPABILITIES	DATA: 2C9101082CD102002CC103002CB10400454106004121A4C9	
Option: 	EPW	
 [1] Fixed : 5V - 3A
 [2] Fixed : 9V - 3A
 [3] Fixed : 12V - 3A
 [4] Fixed : 15V - 3A
 [5] Fixed : 20V - 3.25A
 [6] Programmable : [3.3V - 21V] - 3.25A
	593	
OUT	125	1	SOP	s:002	    H:0x0041     (id:0, DR:UFP, PR:SNK) 	GOODCRC	594	
DEBUG	126	1	Received: 24 bytes	595	
DEBUG	126	1	PDO[0] = 0x0801912C	596	
DEBUG	126	1	PDO[1] = 0x0002D12C	597	
DEBUG	126	1	PDO[2] = 0x0003C12C	598	
DEBUG	126	1	PDO[3] = 0x0004B12C	599	
DEBUG	126	1	PDO[4] = 0x00064145	600	
DEBUG	126	1	PDO[5] = 0xC9A42141	601	
DEBUG	127	1	APDO [5] - max voltage: 210 * 100mV = 21000 mV	602	
PE	127	1	PE_SNK_EVALUATE_CAPABILITY	603	
PE	128	1	PE_SNK_SEND_REQUEST	604	
OUT	128	1	SOP	 PD3	REQUEST	s:006	    H:0x1082    	(id:0, DR:UFP, PR:SNK)  DATA: 3C340863
ObjectPosition:6
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
Operating Current:3000mA
Operating Voltage:21000mV	605	
IN	129	1	SOP	s:002	    H:0x0121     (id:0, DR:DFP, PR:SRC) 	GOODCRC	606	
PE	129	1	PE_SNK_SELECT_CAPABILITY	607	
IN	133	1	SOP	 PD3	ACCEPT	s:002	    H:0x03A3     (id:1, DR:DFP, PR:SRC) 	608	
OUT	133	1	SOP	s:002	    H:0x0241     (id:1, DR:UFP, PR:SNK) 	GOODCRC	609	
NOTIF	134	1	POWER_STATE_CHANGE	610	
DEBUG	134	1	ADVICE: USBPD_DPM_Notification:90	611	
NOTIF	134	1	REQUEST_ACCEPTED	612	
DEBUG	134	1	ADVICE: USBPD_DPM_Notification:1	613	
PE	134	1	PE_SNK_TRANSITION_SNK	614	
IN	368	1	SOP	 PD3	PS_RDY	s:002	    H:0x05A6     (id:2, DR:DFP, PR:SRC) 	615	
OUT	368	1	SOP	s:002	    H:0x0441     (id:2, DR:UFP, PR:SNK) 	GOODCRC	616	
NOTIF	369	1	POWER_STATE_CHANGE	617	
DEBUG	369	1	ADVICE: USBPD_DPM_Notification:90	618	
NOTIF	369	1	POWER_EXPLICIT_CONTRACT	619	
DEBUG	369	1	ADVICE: USBPD_DPM_Notification:16	620	
PE	369	1	PE_STATE_READY	621	
NOTIF	369	1	STATE_SNK_READY	622	
DEBUG	369	1	ADVICE: USBPD_DPM_Notification:32	623	
PE	369	1	PE_STATE_READY_WAIT	624	

View solution in original post

2 REPLIES 2
Jaroslaw_T
Associate III

OK it is possible now to switch between APDO and (if APDO is not possible) PDO.

Code:

void USBPD_DPM_SetDataInfo(uint8_t PortNum, USBPD_CORE_DataInfoType_TypeDef DataId, uint8_t *Ptr, uint32_t Size)
{
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
  /* Check type of information targeted by request */
  switch(DataId)
  {
  //case USBPD_CORE_DATATYPE_RDO_POSITION:      /*!< Reset the PDO position selected by the sink only */
    // break;
  case USBPD_CORE_DATATYPE_RCV_SRC_PDO:       /*!< Storage of Received Source PDO values        */
  {
	  DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
	  uint8_t PDO_Number = Size/4;
	  if(Size==0U || Size%4U != 0U)
	  {
		  DPM_USER_DEBUG_TRACE(PortNum, "Invalid size - run fixed PDO");
		  If_APDO = 0U;
		  break;
	  }
	  for(uint8_t a=0; a<PDO_Number; a++)
	  {
		  PDO_1=0;
		  PDO_2=0;
		  PDO_3=0;
		  PDO_4=0;
		  PDO=0;
		  PDO_1=(uint32_t)Ptr[a*4U+0U]<<0;
		  PDO_2=(uint32_t)Ptr[a*4U+1U]<<8;
		  PDO_3=(uint32_t)Ptr[a*4U+2U]<<16;
		  PDO_4=(uint32_t)Ptr[a*4U+3U]<<24;
		  PDO=PDO_1|PDO_2|PDO_3|PDO_4;
		  DPM_USER_DEBUG_TRACE(PortNum, "PDO[%u] = 0x%08lX", a, PDO); //for information
		  if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL) //if APDO exist
		  {
			  uint32_t Max_Voltage_20mV=(PDO>>9);
			  Max_Voltage_20mV =  Max_Voltage_20mV&0b00000000000000000000011111111111; //masking
			  DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu * 20mV = %lu mV", a, Max_Voltage_20mV, (Max_Voltage_20mV*20));
			  if(Max_Voltage_20mV>=1050U) //if APDO>=21V
			  {
				  If_APDO = 1U;
				  break;
			  }
		  }
	  }
  }
     break;

But the returned voltage value of APDO is not correct. Should be 1050 (21V) but is 528.

Trace:

CAD	2	1	USBPD_CAD_STATE_DETACHED	446	
CAD	4	1	USBPD_CAD_STATE_ATTACHED_WAIT	447	
CAD	123	1	USBPD_CAD_STATE_ATTACHED	448	
NOTIF	123	1	USBSTACK_START	449	
DEBUG	123	1	ADVICE: USBPD_DPM_Notification:104	450	
EVENT	123	1	EVENT_ATTACHED	451	
DEBUG	123	1	ADVICE: update USBPD_DPM_UserCableDetection	452	
DEBUG	123	1	ADVICE: USBPD_DPM_Notification:104	453	
DEBUG	123	1	ADVICE: update USBPD_DPM_SetDataInfo:2	454	
DEBUG	124	1	ADVICE: update USBPD_DPM_SetDataInfo:6	455	
PE	124	1	PE_SNK_STARTUP	456	
PE	124	1	PE_SNK_WAIT_FOR_CAPABILITIES	457	
IN	125	1	SOP	 PD3	s:026	    H:0x61A1    	(id:0, DR:DFP, PR:SRC) 	SRC_CAPABILITIES	DATA: 2C9101082CD102002CC103002CB10400454106004121A4C9	
Option: 	EPW	
 [1] Fixed : 5V - 3A
 [2] Fixed : 9V - 3A
 [3] Fixed : 12V - 3A
 [4] Fixed : 15V - 3A
 [5] Fixed : 20V - 3.25A
 [6] Programmable : [3.3V - 21V] - 3.25A
	458	
OUT	125	1	SOP	s:002	    H:0x0041     (id:0, DR:UFP, PR:SNK) 	GOODCRC	459	
DEBUG	126	1	Received: 24 bytes	460	
DEBUG	126	1	PDO[0] = 0x0801912C	461	
DEBUG	126	1	PDO[1] = 0x0002D12C	462	
DEBUG	126	1	PDO[2] = 0x0003C12C	463	
DEBUG	126	1	PDO[3] = 0x0004B12C	464	
DEBUG	126	1	PDO[4] = 0x00064145	465	
DEBUG	127	1	PDO[5] = 0xC9A42141	466	
DEBUG	127	1	APDO [5] - max voltage: 528 * 20mV = 10560 mV	467	
PE	127	1	PE_SNK_EVALUATE_CAPABILITY	468	
PE	128	1	PE_SNK_SEND_REQUEST	469	
OUT	128	1	SOP	 PD3	REQUEST	s:006	    H:0x1082    	(id:0, DR:UFP, PR:SNK)  DATA: 2CB10453
ObjectPosition:5
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
MaximumOperatingCurrent:3000mA
OperatingCurrent:3000mA	470	
IN	129	1	SOP	s:002	    H:0x0121     (id:0, DR:DFP, PR:SRC) 	GOODCRC	471	
PE	129	1	PE_SNK_SELECT_CAPABILITY	472	
IN	133	1	SOP	 PD3	ACCEPT	s:002	    H:0x03A3     (id:1, DR:DFP, PR:SRC) 	473	
OUT	133	1	SOP	s:002	    H:0x0241     (id:1, DR:UFP, PR:SNK) 	GOODCRC	474	
NOTIF	134	1	POWER_STATE_CHANGE	475	
DEBUG	134	1	ADVICE: USBPD_DPM_Notification:90	476	
NOTIF	134	1	REQUEST_ACCEPTED	477	
DEBUG	134	1	ADVICE: USBPD_DPM_Notification:1	478	
PE	134	1	PE_SNK_TRANSITION_SNK	479	
IN	382	1	SOP	 PD3	PS_RDY	s:002	    H:0x05A6     (id:2, DR:DFP, PR:SRC) 	480	
OUT	382	1	SOP	s:002	    H:0x0441     (id:2, DR:UFP, PR:SNK) 	GOODCRC	481	
NOTIF	383	1	POWER_STATE_CHANGE	482	
DEBUG	383	1	ADVICE: USBPD_DPM_Notification:90	483	
NOTIF	383	1	POWER_EXPLICIT_CONTRACT	484	
DEBUG	383	1	ADVICE: USBPD_DPM_Notification:16	485	
PE	383	1	PE_STATE_READY	486	
NOTIF	383	1	STATE_SNK_READY	487	
DEBUG	383	1	ADVICE: USBPD_DPM_Notification:32	488	
PE	383	1	PE_STATE_READY_WAIT	489	

What is wrong?

OK, now it is correct:

 

void USBPD_DPM_SetDataInfo(uint8_t PortNum, USBPD_CORE_DataInfoType_TypeDef DataId, uint8_t *Ptr, uint32_t Size)
{
/* USER CODE BEGIN USBPD_DPM_SetDataInfo */
  /* Check type of information targeted by request */
  switch(DataId)
  {
  //case USBPD_CORE_DATATYPE_RDO_POSITION:      /*!< Reset the PDO position selected by the sink only */
    // break;
  case USBPD_CORE_DATATYPE_RCV_SRC_PDO:       /*!< Storage of Received Source PDO values        */
  {
	  DPM_USER_DEBUG_TRACE(PortNum, "Received: %lu bytes", Size);
	  uint8_t PDO_Number = Size/4;
	  if(Size==0U || Size%4U != 0U)
	  {
		  DPM_USER_DEBUG_TRACE(PortNum, "Invalid size - run fixed PDO");
		  If_APDO = 0U;
		  break;
	  }
	  for(uint8_t a=0; a<PDO_Number; a++)
	  {
		  PDO_1=0;
		  PDO_2=0;
		  PDO_3=0;
		  PDO_4=0;
		  PDO=0;
		  PDO_1=(uint32_t)Ptr[a*4U+0U]<<0;
		  PDO_2=(uint32_t)Ptr[a*4U+1U]<<8;
		  PDO_3=(uint32_t)Ptr[a*4U+2U]<<16;
		  PDO_4=(uint32_t)Ptr[a*4U+3U]<<24;
		  PDO=PDO_1|PDO_2|PDO_3|PDO_4;
		  DPM_USER_DEBUG_TRACE(PortNum, "PDO[%u] = 0x%08lX", a, PDO); //for information
		  if((PDO&0b11000000000000000000000000000000UL)==0b11000000000000000000000000000000UL) //if APDO
		  {
			  uint32_t Max_Voltage_100mV=(PDO>>17);
			  Max_Voltage_100mV =  Max_Voltage_100mV&0b00000000000000000000000111111111;
			  DPM_USER_DEBUG_TRACE(PortNum, "APDO [%u] - max voltage: %lu * 100mV = %lu mV", a, Max_Voltage_100mV, (Max_Voltage_100mV*100));
			  if(Max_Voltage_100mV>=210U) //if APDO>=21V
			  {
				  If_APDO = 1U;
				  break;
			  }
		  }
	  }
  }
     break;

 

Trace:

 

CAD	2	1	USBPD_CAD_STATE_DETACHED	581	
CAD	4	1	USBPD_CAD_STATE_ATTACHED_WAIT	582	
CAD	123	1	USBPD_CAD_STATE_ATTACHED	583	
NOTIF	123	1	USBSTACK_START	584	
DEBUG	123	1	ADVICE: USBPD_DPM_Notification:104	585	
EVENT	123	1	EVENT_ATTACHED	586	
DEBUG	123	1	ADVICE: update USBPD_DPM_UserCableDetection	587	
DEBUG	123	1	ADVICE: USBPD_DPM_Notification:104	588	
DEBUG	123	1	ADVICE: update USBPD_DPM_SetDataInfo:2	589	
DEBUG	124	1	ADVICE: update USBPD_DPM_SetDataInfo:6	590	
PE	124	1	PE_SNK_STARTUP	591	
PE	124	1	PE_SNK_WAIT_FOR_CAPABILITIES	592	
IN	125	1	SOP	 PD3	s:026	    H:0x61A1    	(id:0, DR:DFP, PR:SRC) 	SRC_CAPABILITIES	DATA: 2C9101082CD102002CC103002CB10400454106004121A4C9	
Option: 	EPW	
 [1] Fixed : 5V - 3A
 [2] Fixed : 9V - 3A
 [3] Fixed : 12V - 3A
 [4] Fixed : 15V - 3A
 [5] Fixed : 20V - 3.25A
 [6] Programmable : [3.3V - 21V] - 3.25A
	593	
OUT	125	1	SOP	s:002	    H:0x0041     (id:0, DR:UFP, PR:SNK) 	GOODCRC	594	
DEBUG	126	1	Received: 24 bytes	595	
DEBUG	126	1	PDO[0] = 0x0801912C	596	
DEBUG	126	1	PDO[1] = 0x0002D12C	597	
DEBUG	126	1	PDO[2] = 0x0003C12C	598	
DEBUG	126	1	PDO[3] = 0x0004B12C	599	
DEBUG	126	1	PDO[4] = 0x00064145	600	
DEBUG	126	1	PDO[5] = 0xC9A42141	601	
DEBUG	127	1	APDO [5] - max voltage: 210 * 100mV = 21000 mV	602	
PE	127	1	PE_SNK_EVALUATE_CAPABILITY	603	
PE	128	1	PE_SNK_SEND_REQUEST	604	
OUT	128	1	SOP	 PD3	REQUEST	s:006	    H:0x1082    	(id:0, DR:UFP, PR:SNK)  DATA: 3C340863
ObjectPosition:6
GiveBack:0
CapabilityMismatch:0
USBCommunicationCapable:1
NoUSBSuspend:1
UnchunkedExtendedMessagesSupported:0
Operating Current:3000mA
Operating Voltage:21000mV	605	
IN	129	1	SOP	s:002	    H:0x0121     (id:0, DR:DFP, PR:SRC) 	GOODCRC	606	
PE	129	1	PE_SNK_SELECT_CAPABILITY	607	
IN	133	1	SOP	 PD3	ACCEPT	s:002	    H:0x03A3     (id:1, DR:DFP, PR:SRC) 	608	
OUT	133	1	SOP	s:002	    H:0x0241     (id:1, DR:UFP, PR:SNK) 	GOODCRC	609	
NOTIF	134	1	POWER_STATE_CHANGE	610	
DEBUG	134	1	ADVICE: USBPD_DPM_Notification:90	611	
NOTIF	134	1	REQUEST_ACCEPTED	612	
DEBUG	134	1	ADVICE: USBPD_DPM_Notification:1	613	
PE	134	1	PE_SNK_TRANSITION_SNK	614	
IN	368	1	SOP	 PD3	PS_RDY	s:002	    H:0x05A6     (id:2, DR:DFP, PR:SRC) 	615	
OUT	368	1	SOP	s:002	    H:0x0441     (id:2, DR:UFP, PR:SNK) 	GOODCRC	616	
NOTIF	369	1	POWER_STATE_CHANGE	617	
DEBUG	369	1	ADVICE: USBPD_DPM_Notification:90	618	
NOTIF	369	1	POWER_EXPLICIT_CONTRACT	619	
DEBUG	369	1	ADVICE: USBPD_DPM_Notification:16	620	
PE	369	1	PE_STATE_READY	621	
NOTIF	369	1	STATE_SNK_READY	622	
DEBUG	369	1	ADVICE: USBPD_DPM_Notification:32	623	
PE	369	1	PE_STATE_READY_WAIT	624