cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G431 UCPD continuous power cycling

Stefano.Patassa
Associate II

Hi,

I'm developing an USB-C sink, using dead battery feature.

I have respective CCx pins connected to DBCCx pins and the source can successfully power the sink.

However, when the UCPD code starts running, the source disconects the 5V, effectively resulting in an endless power cycle.

I have powered the board externally and connected trough the STM32G0 Discovery in spy mode to have some trace capability. Attached you'll find the trace dump.

I'm using lastest version of the libraries, followed the AN5418 to the letter... I can confirm the vbus sensing is correctly working.

I have tried as a source both a pc and an usb-c wall charger. Same behaviour...

The same occours also if i disconnect the DBCCx pins and use an external power supply for the 3.3v...

Anybody has some ideas why this is happening?

Any help will be immensely appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions
Stefano.Patassa
Associate II

Hello Yohann,

IT WORKS!

Thank you very much for your help, it was invaluable.

The main improvement was getting the trace work, after that was easy to understand there was some of my code holding up the execution of the USBC code for too long for it to correctly reply to the SRC.

Thank you again

PS: Please consider adding DPM_Sleep_time[USBPD_PORT_COUNT + OFFSET_CAD] = 0; to CubeMX generated code because this is the only annoying thing to add it again each time i rebuild the code from CubeMX.

View solution in original post

12 REPLIES 12
Yohann M.
ST Employee

Dear @Stefano.Patassa​ ,

Your log shows clearly that the SRC capability has well been sent to the sink device (and ack with goodCRC) but this one did not send any request message. After a while, it trigs a hard reset on SRC side which will reset the VBUS.

Could you please provide us an internal PD trace (.cpd) as described in the following wiki page?

https://wiki.st.com/stm32mcu/wiki/USB_Power_Delivery_overview#Specific_tools

To use it, you have to connect a TX UART pin to VCP port available on ST Link for instance.

Regards,

Yohann

Stefano.Patassa
Associate II

Dear Yohann,

thank you very much for the fast reply.

Unfortunately in my board i do not have any hardware uart tx pins available. The only thing i can do is to use USB VCP, but i think there will be some coding involved to attach it to the trace system...

What can i add is that the stack calls USBPD_DPM_SetDataInfo only once and the only message passed is USBPD_CORE_DATATYPE_RDO_POSITION.

Without USBPD_CORE_DATATYPE_RCV_SRC_PDO and without USBPD_DPM_SNK_EvaluateCapabilities being called I have no idea where and how i can request the source to provide any PDO...

Yohann M.
ST Employee

Do you generate the application through CubeMX? if you use USB VCP, you may have a UART connected to it.

Then in cubeMx, you have to enable TRACER_EMB is selecting the correct UART.

One more point, you could refer to applications we delivered to our FW package:

  • Simple application:

https://github.com/STMicroelectronics/STM32CubeG4/tree/master/Projects/STM32G474E-EVAL/Applications/USB-PD/USB-PD_Consumer_1port

  • complete application in a demonstration:

https://github.com/STMicroelectronics/STM32CubeG4/tree/master/Projects/STM32G474E-EVAL/Demonstrations/Modules/ucpd

Stefano.Patassa
Associate II

Dear Yohann,

I've managed to connect a serial port to my board and attached you'll find a screenshot of the trace.

After USBPD_CAD_STATE_ATTACHED_WAIT it is stuck and nothing is detected anymore. If i restart the code i get the EXCEPTION DETECTED message in the trace....

I really do not understand what's going on... Am I missing something?

0693W000005BeO5QAK.png0693W000005BeOAQA0.png 

Yohann M.
ST Employee

Dear Stefano,

CAD is waiting for VBUS setting correctly to 5V to move to ATTACHED state:

static uint32_t ManageStateAttachedWait_SNK(uint8_t PortNum, USBPD_CAD_EVENT *pEvent, CCxPin_TypeDef *pCCXX)
{
  CAD_HW_HandleTypeDef *_handle = &CAD_HW_Handles[PortNum];
  uint32_t _timing = CAD_DEFAULT_TIME;
 
  uint32_t CAD_tDebounce = HAL_GetTick() - _handle->CAD_tDebounce_start;
  CAD_Check_HW_SNK(PortNum);
  if (_handle->CurrentHWcondition == HW_Attachment)
  {
    if (CAD_tDebounce > CAD_TCCDEBOUCE_THRESHOLD)
    {
      if (USBPD_TRUE == USBPD_PWR_IF_GetVBUSStatus(PortNum, USBPD_PWR_VSAFE5V)) /* Check if Vbus is on */
      {
        HW_SignalAttachement(PortNum, _handle->cc);
        _handle->cstate = USBPD_CAD_STATE_ATTACHED;

This VBUS value is measured thanks to USBPD_PWR_IF_GetVBUSStatus -> HW_IF_PWR_GetVoltage -> BSP_USBPD_PWR_VBUSGetVoltage.

Normally, you have to configure correctly the ADC to measure this VBUS voltage.

Can you have a look at it?

As described in the wiki, could you please provide for the next time directly the .cpd file? (under c:\Users\%username%\AppData\Local\Temp\STM32CubeMonitor-UCPD\Acquisition\)

A next tip is you could easily add your own debug traces in your code. For instance, you could send to tracer the measure VBUS value like:

    char str[20];
    sprintf(str, "V:%5d", _vbus_value);
    POWER_IF_TRACE(PortNum, (uint8_t *)str, strlen(str));
 
with
 
#define POWER_IF_TRACE(_PORT_,_MSG_,_SIZE_) USBPD_TRACE_Add(USBPD_TRACE_DEBUG,_PORT_,0,(uint8_t *)_MSG_, _SIZE_);

Regards

Yohann

Stefano.Patassa
Associate II

Hello Yohann,

i have the ADC working and correctly measuring the vbus.

I've added your code in the BSP_USBPD_PWR_VBUSGetVoltage. The function gets called and str buffer is filled correctly but there is nothing on the trace tool!

Here is my code:

__weak int32_t BSP_USBPD_PWR_VBUSGetVoltage(uint32_t Instance, uint32_t *pVoltage){
	int32_t ret;
	if ((Instance >= USBPD_PWR_INSTANCES_NBR) || (NULL == pVoltage)) {
		ret = BSP_ERROR_WRONG_PARAM;
	} else {
		//ret = BSP_ERROR_FEATURE_NOT_SUPPORTED;
		ret = BSP_ERROR_NONE;
		PWR_DEBUG_TRACE(Instance, "HELP: Update BSP_USBPD_PWR_VBUSGetVoltage");
		*pVoltage = (uint32_t) (GetADCChannel(ADC_VBUS_SENSE) * 1000);
		char str[20];
		sprintf(str, "V:%5d", (int16_t) *pVoltage);
		POWER_IF_TRACE(Instance, (uint8_t* )str, strlen(str));
	}
	return ret;
}

Attacched also the .cpd file, hope it can help

Thank you

Hello Stefano,

Fine to see that you applied my recommendations but what it is quite strange is that I cannot see the debug trace "POWER_IF_TRACE(Instance, (uint8_t* )str, strlen(str));" into the cpd file. Can you please check it?

I can see that you use directly the value of ADC but I would expect having a value measured after the divider voltage as done in our EVAL_G4 application:

__weak int32_t BSP_USBPD_PWR_VBUSGetVoltage(uint32_t Instance, uint32_t *pVoltage)
{
  /* USER CODE BEGIN BSP_USBPD_PWR_VBUSGetVoltage */
 
  /* Check if instance is valid       */
  int32_t ret = BSP_ERROR_NONE;
 
  if ((Instance >= USBPD_PWR_INSTANCES_NBR) || (NULL == pVoltage))
  {
    ret = BSP_ERROR_WRONG_PARAM;
  }
  else
  {
    uint32_t voltage;
 
    voltage = __LL_ADC_CALC_DATA_TO_VOLTAGE(VDDA_APPLI,  ((uint32_t)LL_ADC_REG_ReadConversionData12(VSENSE_ADC_INSTANCE)), LL_ADC_RESOLUTION_12B); /* mV */
 
    /* STM32G474E_EVAL board is used */
    /* Value is multiplied by 7.030 according to board measurements.
       Theorically, it should have been 7.613 (Divider R323/R244 (49.9K/330K) for VSENSE */
    voltage *= 7030U;
    voltage /= 1000U;
 
    *pVoltage = voltage;
  }
  return ret;

Our CAD driver expects VBUS values defined in mV:

#define USBPD_PWR_HIGH_VBUS_THRESHOLD     (2800U)

Regards,

Yohann

Stefano.Patassa
Associate II

Hi Yohann, thanks for the fast reply.

The VBUS value is in mV, my function returns a float with the real voltage on that channel, i can see in the str variable "V:05203" or something like that.

I've dig deeper in the code, for some reason in the function USBPD_DPM_Run i have very odd values for DPM_Sleep_time, see attached screenshot.

That's maybe the reason why the trace and the usbc stuff hangs at some point?

Obiviously still no idea why that happens...

Hi

You may highlight an issue with NO RTOS configuration generated with CubeMX6.0.x.

We fixed it in the latest CubeMX version v6.1.0 available on ST.com.

Anyway, can you check if you have the following code in your uspbd_dpm_core.c:

/**
  * @brief  WakeUp PE task
  * @param  PortNum port number
  * @retval None
  */
static void USBPD_PE_TaskWakeUp(uint8_t PortNum)
{
  DPM_Sleep_time[PortNum] = 0;
}
 
/**
  * @brief  WakeUp CAD task
  * @retval None
  */
static void USBPD_DPM_CADTaskWakeUp(void)
{
  DPM_Sleep_time[USBPD_PORT_COUNT] = 0;
}
 
/**
  * @brief  WakeUp TRACE task
  * @retval None
  */
void USBPD_DPM_TraceWakeUp(void)
{
  DPM_Sleep_time[USBPD_PORT_COUNT + OFFSET_CAD] = 0;
}
(...)
static void DPM_ManageAttachedState(uint8_t PortNum, USBPD_CAD_EVENT State, CCxPin_TypeDef Cc)
{
#ifdef _VCONN_SUPPORT
  if (CC1 == Cc)
  {
    DPM_Params[PortNum].VconnCCIs = CC2;
  }
  if (CC2 == Cc)
  {
    DPM_Params[PortNum].VconnCCIs = CC1;
  }
#endif /* _VCONN_SUPPORT */
  DPM_Params[PortNum].ActiveCCIs = Cc;
  (void)USBPD_PE_IsCableConnected(PortNum, 1);
 
  USBPD_DPM_UserCableDetection(PortNum, State);
 
  DPM_Sleep_time[PortNum] = 0U;
}

I attached directly the file for checking...

Yohann