Skip to main content
Visitor II
November 2, 2020
Solved

STM32G431 UCPD continuous power cycling

  • November 2, 2020
  • 9 replies
  • 5309 views

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!

    This topic has been closed for replies.
    Best answer by Stefano.Patassa

    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.

    9 replies

    ST Employee
    November 3, 2020

    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

    Visitor II
    November 3, 2020

    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...

    ST Employee
    November 3, 2020

    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

    Visitor II
    November 17, 2020

    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 

    ST Employee
    November 17, 2020

    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

    Visitor II
    November 18, 2020

    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

    ST Employee
    November 18, 2020

    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

    Visitor II
    November 18, 2020

    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...

    ST Employee
    November 18, 2020

    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

    Visitor II
    November 18, 2020

    Dear Yohann,

    We are getting somewhere! By adding that line to the USBPD_DPM_TraceWakeUp function i can get a proper trace of what's going on.

    Attached the lastest trace, i have two issues:

    • both PC and wall charger are sending USBPD_CORE_DATATYPE_RCV_REQ_PDO instead of what it is used in the examples...
    • if i try to cut and paste the code from the examples, compiler is upset by not having DPM_Ports defined anywhere, in fact a search in the code does not find anything. Is it possible lastest version has different naming respect to the examples?

    One thing i noticed, i have to put back that magic line in USBPD_DPM_TraceWakeUp function everytime i regenerate code with cubemx, any workaround to this?

    Thank you very much for your help!!

    Stefano

    ST Employee
    November 19, 2020

    Dear Stefano,

    Happy to see that you are progressing in your setup.

    • Did you apply compare your application with Simple application:

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

    I remind here the expected sink power negotiation (described in UM2552 as well):

    0693W000005BuEQQA0.pngI attached the NO_RTOS application based on G4.

    DPM_Ports is defined in usbpd_dpm_user.c.

    Regards,

    Yohann

    Stefano.PatassaAuthorAnswer
    Visitor II
    November 20, 2020

    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.