cancel
Showing results for 
Search instead for 
Did you mean: 

USB PD library gets stuck in loop waiting for VBus to be 0V when a USB-C charger plugged

AOhir.1603
Associate III

Hi there,

We have a custom board with STM32F030CC and PTN5110 chip as the TCPC. We are using the x-cube-usb-pd library with config USBPD_TCPM_LIB_PD3_CONFIG_1.

Initially, DRP role is selected. When we plug in a standard USB-C charger (5V 3A output) to the port, TCPC reports to present Rd role. That is, in tcpc_driver->get_cc(), it returns CC_STATUS as 0x13.

But the firmware gets stuck in USBPD_DPM_IsPowerReady(), as it waits for the VBus to be 0V but the charger is presenting 5V so it gets stuck in a loop calling USBPD_DPM_IsPowerReady() (USBPD_TCPM_VBUS_IsVsafe0V() is returning USBPD_ERROR).

The firmware currently crashes after it calls USBPD_DPM_IsPowerReady() multiple times..

Could someone please help me understand why when USBPD_DPM_IsPowerReady() is called, it is waiting for VBus to be 0V in this situation? I know that VBus is actually 5V and I thought it should check to make sure VBus is 5V but library is doing the opposite.

Is there a setting I need to configure (DPM_Setting, PDO setting etc)?

Any idea would be appreciated.

Thanks,

AOF

26 REPLIES 26
Yohann M.
ST Employee

Hello

Could you please attach in PD trace generated with CubeMonitor?

"For your information, we have a way to trace messages exchanged between our solution and the port partner thanks to trace mechanism.

Please have a look to the following thread: https://community.st.com/s/question/0D50X0000BdfSu2SQE/how-to-use-debug-trace-trace-

I advice you to switch to 'Consumer_RTOS' application. You could enable in this project the compilation switch _TRACE.

Then in using Cubemonitor-UCPD, you will be able to check what happens exactly.

The binary log (.cpd file) can be retrieved locally in your hard disk under:

C:\Users\<login>\AppData\Local\Temp\STM32CubeMonitor-UCPD\Acquisition

You could attach directly this file for analysis."

Regards,

Yohann

AOhir.1603
Associate III

Hi Yohann,

Thanks for your answer.

Just to clarify, I am using the USBPD_TCPM_LIB_PD3_CONFIG_1 configuration.

Could I still use the 'Consumer_RTOS' example by just changing the defined symbol to what I require it to be?

I will try and get the trace using CubeMonitor-UCPD from the application I have set up already as well.

Thanks,

AOF

Hi AOF,

I advise you to start from EVAL_FUSB307_DRP project and disable _DRP switch (keep only _SNK switch) and then compare to 'Consumer_RTOS' project to fix different errors, mainly:

  • copy 'usbpd_pdo_defs_Snk_1Port.h' file in this application (use to define SNK PDO)
  • Few updates in 'usbpd_dpm_user.c' and 'usbpd_pwr_if.c' linked to Souce PDO and VBUS management

Please find updated files.

Regards,

Yohann

'usbpd_dpm_user.c' and 'usbpd_pwr_if.c'  in sink only

Hi Yohann,

Thank you for the files.

I have now modified the project for 1 port and SINK only using your files.

I have made a small progress but the performance differ with differen USBC devices.

Below shows 3 different tests I have done.

Please note that all the tests were done from a fresh power cycle on the board so PTN chip should always be in a clean state.

TEST 1: Plug in a phone (Samsung A20) which seems to support USBPD negotiation and DRP role.

Please see the log in snk_1port_a20phone.cpd.txt. (please remove .txt from the file name, as the forum does not accept .cpd files)

The log contains plugging the phone then unplugging it.

I do seem to get POWER_EXPLICIT_CONTRACT and PE_STATE_READY which seems to follow what the datasheet says.

If I want to start sinking power from the phone, where do I put the code for this?

The actual control of drawing current from the USB is done in another chip (BQ chip) so I would need to call some functions to start this process.

TEST 2: Plug in a phone (Redmi Note 7) which seems to only support Sink role

Please see the log in snk_1port_miNote7phone.cpd.txt.

The log was collected plugging in the phone and unplugging the phone.

Strange thing with this test is, it did not successfully detect any alert event when I plugged in the phone.

However when unplugged the phone, it showed the alert events you see in the log.

The result was different if I had my board in Debug mode and placed a breakpoint at the end of ptn5110_tcpc_alert (equivalent of fusb307_tcpc_alert).

I would then see an alert (Valid alert = 1) when plugged the phone. If I get rid of the breakpoint after that, we get the result seen in snk_1port_miNote7phone_2.cpd.txt: it gets stuck in PE_SNK_EVALUATE_CAPABILITY and nothing more happens.

I don't understand why the alert event was not captured if I don't run it in the debug mode. Is it a timing issue? How would you fix this?

TEST 3: Plug in a standard USBC phone charger

The log for this test is snk_1port_charger.cpd.txt.

The log was collected when I plugged in the charger then disconnected.

In this case, it seems to get stuck in the PE_SNK_WAIT_FOR_CAPABILITIES. This makes sense as the charger is just constantly being a source and probably does not have the capability to negotiate USB PD protocol.

In this case, what could I do to detect this and start drawing power from it?

Also how could I make the USBPD stack gracefully get out of this situation?

Thanks,

AOF

 

Dear AOF,

Good to see your progresses !

Please find my answers to your questions:

TEST1:

In the attached log, you managed to establish a contract. in the notification 'USBPD_DPM_Notification(USBPD_NOTIFY_POWER_EXPLICIT_CONTRACT)', you could start drawing current.

TEST2:

Stack will start PD negociation after indication from TCPC as VBUS is present (normally 5V). In the logs, what it is strange is that ATTACHED event occurs after detection of VbusVolt=32768! You may have problems here if this value is not correct.

In breaking the the MCU, you may change completely the sequence and the real time. Can you have a look at the VBUS level behaviour?

TEST3:

In legacy source Type-C charger (it means no PD negociation), Stack will wait for a SRC_CAPA message in state 'PE_SNK_WAIT_FOR_CAPABILITIES'. After 500ms (tSnkWaitForCapa timer), stack will send a 1st hard reset and go back to wait for capa. After 3 hard reset, stack will enter in disabled state and a notification through ''USBPD_DPM_Notification(USBPD_NOTIFY_PE_DISABLED)'' will be sent to user.

In this case, you can start drawing power.

Unfortunately, in the release DV2.1.0, this notification does not exist. It is present in our latest stack release done for STM32G0 (DV1.3.0 for instance).

In the current FW you have, I advise you to start a timer on DPM side when you detect a CAD detection and after 1500ms, you could start drawing minimun USB current.

For your information, we plan to update X-CUBE-USBPD FW with up-to-date stack library.

Regards,

Yohann

Hi Yohann,

Thanks for your reply.

Further questions and clarifications...

TEST1:

OK great, so we can start drawing power when I get USBPD_NOTIFY_POWER_EXPLICIT_CONTRACT.

So I could do something like

case USBPD_NOTIFY_POWER_EXPLICIT_CONTRACT :
  // Exisiting code...
  if(DPM_Params[PortNum].PE_PowerRole == USBPD_PORTPOWERROLE_SNK)
  {
    // TODO: call function to trigger drawing current
  }
  break;

Question is how do I know what voltage and current to start drawing? What was negotiated and where is this stored?

From looking at the UM2063.pdf in section 5.4.1, it seems that when we get USBPD_NOTIFY_REQUEST_ACCPETED, we can extract what capability was selected? Am I correct in assuming that USBPD_SNKRDO_TypeDef rdo contains the information I'm looking for?

Example around here would be appreciated.

TEST2:

The log file snk_1port_miNote7phone_2.cpd does show what you said and I had a closer look at how VbusVolt could be 32768. This seems to be a problem when &VBUSVoltage is set to NULL. I've worked this around by always passing a variable when fusb307_tcpc_get_vbus_level is called. After this, I don't see 32768 any more.

But even after this, I still don't seem to detect the cable plugged event. Could this be specific to the phone because it's a sink only device? When it is plugged to our board, the USB_VBUS is not 5V so the phone may not activate the cable plug event ?? I thought a cable detect event should be triggered regardless..

TEST 3:

So you suggest in USBPD_DPM_UserCableDetection() function case USBPD_CAD_EVENT_ATTACHED, I could start a timer - Could I use the DPM_Ports[0].DPM_TimerAlert timer? Then I could add my logic in USBPD_DPM_UserExecute case DPM_USER_EVENT_TIMER?

OR would you recommend adding a completely new timer to detect this condition?

Also Do you have an approximate timeline for when X-CUBE-USBPD FW will be updated?

Thanks,

AOF

Hi AOF,

Here are my answers to your different questions:

TEST1:

You are right, this is the way to retrieve the information:

  • SRC capability from port partner will be transfered to user thanks to 'USBPD_DPM_SetDataInfo(USBPD_CORE_DATATYPE_RCV_SRC_PDO)' inside the structure 'DPM_ListOfRcvSRCPDO'
  • Selected PDO will be selected inside the function 'USBPD_DPM_SNK_EvaluateCapabilities' and the information will be available in the variable 'DPM_RequestDOMsg' like:
      USBPD_SNKRDO_TypeDef rdo;
      rdo.d32                                   = DPM_Ports[PortNum].DPM_RequestDOMsg;

TEST2:

This is the reason... If 2 ports are sink only, they cannot communicate together.

TEST3:

Yes you could use alert timer (used normally for PPS) or base your new timer on the same mechanism.

For the new release, we are working on it. I hope it will be available in the next weeks.

Best regards,

Yohann