Ramblings of an aging IT geek
← Ramblings of an aging IT geek
hardware

what my laptop charger and my phone were arguing about

Putting a USB-C cable in line with a power meter and a logic analyser to watch the Power Delivery negotiation, and finding out why one charger ran a device at 5V when it should have been giving it 9V.

A soldering iron and a tangle of USB-C breakout boards on a bench

I have a drawer full of USB-C chargers and a nagging suspicion that half of them are lying to me. One in particular: a perfectly reputable 45W brick that, paired with one particular device, would only ever deliver a trickle. The device charged, eventually, the way a tap charges a bath when someone has left it barely cracked. Other chargers ran the same device at full pelt. So the question was not "is the charger broken", because it ran my laptop fine. The question was "what are these two specifically saying to each other, and where does it go wrong".

USB Power Delivery is the part of USB-C that decides how much power flows. The headline numbers, 5V, 9V, 15V, 20V, are not what you get by plugging in. They are what you get after a negotiation that happens over the CC line in the cable, in a little packet protocol that most of us never see because it works. The source advertises a list of things it can do. The sink picks one. They shake hands. Power flows at the agreed voltage. When it works you get fast charging and never think about it. When it doesn't you get a bath filling one drip at a time and no error message anywhere, because as far as both devices are concerned, nothing is wrong. They agreed on 5V. They are both delighted.

Getting eyes on the CC line

You cannot debug a conversation you cannot hear. The first job was to get the negotiation onto a screen. I have a cheap USB-C power meter, the sort that sits in line and shows volts and amps on a little display, which tells you the outcome but not the argument. For the argument you need to tap the CC line itself.

I made a passthrough: a USB-C breakout board on each end, the high-current lines (VBUS, GND, the data pairs) wired straight through, and the two CC lines brought out to header pins so I could hang a logic analyser off them. PD on CC runs at 300kHz BMC encoding, which a cheap analyser will happily capture even if it can't decode it for you. Decoding is the fun part and there is open tooling for it now, but honestly half the value is just seeing that packets are happening at all.

A breakout board with CC lines jumpered out to a logic analyser

With the analyser hooked up and the good charger plugged in, I could see the shape of it: the source sends Source Capabilities, a list of Power Data Objects, each one a voltage and a current it's willing to provide. The sink answers with a Request picking object number N. The source sends Accept, then PS_RDY when the new voltage is stable, and at that point VBUS climbs from the default 5V up to whatever was agreed. Watch the power meter and the logic analyser together and you can see the handshake finish a beat before the voltage steps up. It is genuinely satisfying.

Where the trickle came from

So I swapped in the misbehaving charger and watched the same sequence. The source sent its capabilities. The sink sent its request. And then… the negotiation restarted. Soft reset, capabilities again, request again, reset again. Round and round. Every few hundred milliseconds the two of them would start the conversation, get most of the way through, and one side would give up and bin it. When a PD negotiation never completes cleanly, the spec says you fall back to plain old USB default power: 5V at a modest current. Which is exactly the trickle I was seeing. Not a fault. A fallback, firing over and over, behaving exactly as designed for a handshake that never lands.

The why turned out to be marginal signalling on the CC line. This charger's CC drive was weak, the device's CC input was a touch fussy, and the cable I happened to be using had enough resistance on that line to tip the pair over the edge. None of the three was out of spec on its own. Together they produced a CC waveform that the sink rejected often enough that the handshake never survived. Swap any one of the three, a different cable, a different charger, a different device, and the margin came back and PD completed first time. It was the specific combination that failed, which is why it had been so maddening: every component worked perfectly with every other component except this one trio.

# the good case, roughly
Source Capabilities  -> sink
Request (PDO #3, 9V) -> source
Accept               -> sink
PS_RDY               -> sink   # VBUS steps 5V -> 9V here

# the bad case
Source Capabilities  -> sink
Request (PDO #3, 9V) -> source
Soft Reset           # ...and back to the top, forever

I did not heroically fix the charger. You don't really repair a marginal CC driver on a sealed brick, and I'm not sure I'd trust the result if I did. What I did was stop using that cable with that charger, and write a sticker. But I came away understanding the thing properly for the first time, which is the actual prize. "Fast charging not working" had always felt like a vibe, a thing that either happened or didn't. Now it is a conversation I can listen in on, with a clear failure mode: when PD can't complete, you get 5V, no warning, and a device that charges like it's sulking.

The wider lesson is one I keep relearning with anything that negotiates: the failure mode of a negotiation is rarely a clean error. It is a quiet fallback to the lowest common denominator that still technically works. DNS does it, TLS cipher selection does it, and USB-C does it on a 300kHz line nobody looks at. If something is slow rather than broken, suspect a negotiation that's settling for less, and go and watch the handshake before you trust anyone's spec sheet.