This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TPS65987D: Power role swap not always working

Part Number: TPS65987D
Other Parts Discussed in Thread: TUSB8041, TUSB321, TPS2500

Hi,

The past months we've been working on the development of an USB Type C Docking Station to connect multiple devices to a Phone, with the possibility of connecting a charger to the system.

A Brief functionality:

  • A phone is connected to the first PD controller (TPS65987DDH) bij an USB Type C connector. This controller is in Power Sink mode when no charger is connected to the system; i.e. it powers the hub and the connected devices. The controller is always in UFP mode.
  • The data lines of the phone port are connected to a hub (TUSB8041)
  • Two USB Type C connectors are available to connect devices (e.g. camera, flash drive, mouse, keyboard, etc) to the hub. Both are powered from the 5V supply, 500mA max. (TUSB321 with TPS2500).
  • Another PD controller is present on the board (TPS65987DDH) to connect a charger (USB Type C) to the system. When the charger is connected is must power the system and the phone goes into charging mode.
  • The phone will always be connected to the board.
  • No battery is present on the board. One of both PD controllers will start in Dead Battery mode
  • PP_HV1 and PP_HV2 are in dual link (both PD) and connected to an internal 5V supply rail. A SMPS makes 1V1 and 3V3 for internal use.
  • A connection from Phone PD to Charger PD is present on GPIO1 with a pulldown resistor and a RC filter (1k/100nF).

Configurations Phone PD (Advanced mode):

  • Boots in BP_WaitFor3V3_Internal; so when the Board_3V3 is stable, the PD controller loads its configuration from flash
  • PP Switches as Sink or Source
  • Power Duo Mode
  • GPIO1 configured as input: Load App Config 1
  • Load App Config 1 triggers CMD on rising edge: DBfg (clear dead battery flag) => so the flag clears when the charger is in Sink mode
  • Load App Config 1 triggers CMD on rising edge: SWSr (swap to source)
  • Load App Config 1 triggers CMD on rising edge: SWSk (swap to sink)
  • Process & Initiate Swap to Source is enabled
  • 1 Transmit Source capability is configured
  • 1 Transmit Sink capability is configured

Configurations Charger PD (Advanced mode):

  • Boots in BP_NoWait; so it always tries to load its config from flash
  • PP Switches as Sink only
  • Power duo mode
  • GPIO1 is output: Sink Arbitration output
  • Process & Initiate Swap to Sink is enabled
  • 1 Transmit Sink capability is configured

The device is used with the board permanently attached to the phone. The charger is only connected when charging the phone, not in operation. Most of the time it works as expected, but sometimes the Phone-PD becomes unresponsive. Only a hard reset of the phone, or an disconnect/connect can resolve the issue.

Using the debugging tools, I discovered that the state the Phone-PD is in when it is unresponsive is: COMMON_STATE_ATTACHWAIT_SNK.

Another issue: sometimes the Phone-PD is reponsive, but it is in PEState_Sink_Ready, or PEState_Legacy. In this case the phone can power the board, but it is not charging when the charger is connected. It looks like both PD controllers are in Sink mode (PP1_RCP in the charger is true).

When the device is working, the Phone-PD is in PEState_Source_Ready and PRState_Source_SinkTxOk.

When I hard reboot the phone (without changing anything on our device), the Phone-PD continues and negotiates a PDO with the phone.

Already tried:

  • Using simple mode configurations
  • Use Sink Arbitration Input on Phone-PD
  • Use both - app config, Sink Arbitration input - on same input from Charger-PD
  • Tried Virtual device configurations for Sink and Source in Phone-PD
  • A lot of configurations regarding Port configuration and control
  • Faster / slower slew rates
  • Other phones

Unfortunately this also doesn't solve the issue.

Am I missing a things? Does anybody has a clue?

Kind regards,
Matthijs

  • Hi Matthijs,

    It's good that you are able to use the tool to debug the trace.

    It looks like the Phone PD is in The ATTACHWAIT_SNK and is either waiting for host source VBUS or VCONN for a VPD, see attached state diagram.

    Can you capture the PD log, CC lines and VBUS when it is unresponsive and also your project files?

    Regards,

    Peter

  • Hi Peter,

    Thanks for your quick reply!

    Attached you'll find the project files for both, Charger and Phone: Project files.zip

    The 'PD State Machine Trace' from the Phone PD controller:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 INT 0x50 = PATCH_LOADED
    Port 0 PD 0x1 = PEState_CableTypeDetect
    Port 0 Type-C 0x66 = COMMON_STATE_UNATTACHED_SNK
    Port 1 PD 0x1 = PEState_CableTypeDetect
    Port 1 Type-C 0x0 = SRC_STATE_DISABLED
    Port 0 Type-C 0x65 = COMMON_STATE_ATTACHWAIT_SNK
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Another good thing to mention is that there's no MCU on the device. So unfortunately we are very limited in sending 4CC commands to the PD controllers in operation mode.

    This afternoon I'll be able to capture the PD communication (CC, VBus, etc.) between the phone and the phone-PD with a USB PD Analyzer. I will post it when I have it.

    Kind regards,
    Matthijs

  • Hi Peter,

    I have been able to capture a trace on the USB lines:

    Zoomed in on the last part (where the phone doesn't respond anymore):

    And the legend (hope it is readable):

    Also a screenshot of the corresponding packages on the PD trace:

     Line 818 through 821 are the last packets sent by the phone. After that moment, it doesn't respond anymore.

    Kind regards,
    Matthijs

  • Hi Matthijs,

    Thanks for the data, but can I get the PD trace itself instead of jpeg and also can you dump the PD State machine to a file?

    If Phone PD is a source when charger is connected, it's strange that VBUS is not present and PD is in ATTACHWAIT_SINK state.

    Have you tried by removing the initiate swap to source on the Phone PD side?

    Can you capture GPIO1, PPHV on phone_PD, CC lines and VBUS together when it fails?

    Also why there is an INT for patch loaded in the State Machine?

    Can you provide the sequence of events when this happens?

    Is this correct?

    • Dock is powered with phone connected; Phone_PD is sink
    • then Charger is connected on the charger PD port
    • Do you see a PR_SWAP in the log?
    • etc.

    Regards,

    Peter

  • Hi Peter,

    I'm a colleague of Matthijs.
    In absence of Matthijs I picked up testing and investigation on this issue.

    I measured the timing of GPIO 1 signals power and CC signalling with a logic analyzer to see what the exact sequence is together with the PD analyzer. What I found is that PD communication stops completely after GPIO 1 from the charger goes high. Is somehow lost the capture at the moment, but I can describe it from memory.

    When functioning normally we have:
    Phone powerd docking station (Sink), no charger connected.
    Charger gets connected
    Charger PD controller signals Sink Arbitration (goes high)

    Phone side PD controller issues Source capabilities
    Phopne issues Request to PD controller
    Phone PD accepts
    Phone PD issues PS_RDY signal

    Somewhere in this sequence the VBUS on the phone goes to VSafe (disconnects/stops sinking)
    Then the VBUS is switched on again being sourced.

    The difference between the succesfull scenario and failing scenario is that there is no PD communication at all between the Phone and our PD controller after SInk arbitration is signalled.

    Additionally what I noticed is that when reconnecting the phone a Hard Reset is sent, but neither side becomes responsive anymore.
    After that I restarted the phone, which then got stuck in an infinite streamof PR_SWAP requests from our side.

    This lead me to the idea of changing this Swap request behavior to the normal command which should usually issue the start of a source mode operation according to the USB PD specification. so I changed the command to Send Source Capabilities as opposed to that when sink arbitration goes high. This now seems to operate reliable now! The Phone always repsonds with a request when it receives the Source capabilities.

    I have been testing with this new config on several prototypes also using different phones.
    Since this had high priority I did not make good new captures. I would need to use the old config for that if you would still like to see them. Thanks for the help so far!

    PS I was wondering which document the State diagram you have sent comes from?

    Kind Regards,
    Dave

  • Hi Dave,

    The GPIO supposedly change the phone PD role to Source thru its APP_Config and when it's wait in sink, it shows it's not loading correctly. That's why I want to see this IO behavior.

    I looked at the Charger pjt file and I see there's no GPIO event associated with SINK_ARB_INPUT which per the device host interface document, this event works in conjunction with SINK_ARB_OUTPUT. When the input side is not driven, this pin could be floating internally which might be the reason sometimes it works and sometimes it doesn't. Can you assign a GPIO for this SINK_ARB_INPUT event and drive it low sink this is always going to be a sink PD? 

    The state diagram is from USB type-C spec release 2.0 August 2019 page 168.

    Regards,

    Peter

  • Hi Peter,

    We use the Sink Arbitration Output on the Charger PD, this controller is always in Sink indeed.

    We have used the Sink Arbitration Input on the Phone side PD controller initially using an internal or external pull-down and it seemed to work.
    However this also did not work reliable, the problem we found is that the Phone PD controller rejected the Swap, also when we issue the swap manually using I2C. We found it was rejected because the dead battery flag was active in most cases, which is basically unavoidable in our situation.

    This is why we changed it to first issues a clear Dead Battery Flag command using the APP IO Config and successively with a Swap to Source command.
    Since we have only one IO available which connects the 2 PD controllers on this PCB we tried to resolve the issues this way. Additionally we also tried using both Sink Arbitration Input and APP IO Config with the Dead Battery Clear command by using an additional wire patch on the PCB which was also not working reliably.

    Regarding the section you show, we have read it, but we could not find the MultiPortSinkNonOverlapTime in the configuration tool. Altough in practice it does seem to be long enough with the default value if we look at our measurements: do you know if this register is not available for this controller or if it is missing in the tool?

    Kind Regards,
    Dave

  • Hi Dave,

    Why the SINK_ARB_INPUT is on the phone PD?  This should be on the Charger PD where you have set GPIO1 to be the SINK_ARB_OUTPUT. Can you try setting a GPIO in the charger PD for SINK_ARB_INPUT?

    In your pjt file, multiport sink is not supported so it's irrelevant.

    Regards,

    Peter

  • Hi Peter,

    Maybe there is some misunderstanding about the role of the ports in our setup so let's try to make this clear first.
    What we call the Charger PD controller is the PD controller connected to a USB-C port which can only act as a Sink to our PCB.
    What we call the Phone PD controller controls the more complex port, which implements the power role swap functionality it connects to the phone using an USB-C cable.
    The reason why we put the Charger as output as this PD controller initiaties the power role swap when it detects insertion or removal of the Charger connector and Supply. And mainly the insertion event as at removal, power is lost in our PCB and the Phone PD controller will reset and negotiate with the connected phone for Power on restart.

    What we see is that the Charger initiaties the Arbitration sequence when a charger get's connected by raising the Sink arbitration GPIO signal. Since the Phone PD controller has no way of knowing that a charger is connected, so it is unable to initiate the Arbitration.

    I hope this clarifies our setup?

    Kind Regards,
    Dave

  • Hi Dave,

    In order to use the SINK_ARB_OUTPUT event, you need to have an SINK_ARB_INPUT event associated with it. That's the work in conjunction means in the TRM snapshot I attached previously. I don't see a GPIO assigned to this SINK_ARB_INPUT event in this Charge PD project file. I know your configuration, but the requirement to use this output event is to have the input event on the same PD configuration. You can keep the settings in Phone PD, but in charger PD assign a GPIO for the SINK_ARB_INPUT event and set it to low and try again. Hope it's clear.

    Regards,

    Peter