megi's PinePhone Development Log RSS


2022–10–08: Pinephone UART HW Issue

A few months ago I discovered a HW issue with Pinephone UART (the one that is used for serial console access). I discovered this when trying to use PP UART for a personal HW project, to communicate with some circuit on my Pinephone Breadboard (former keyboard).

The issue manifests as weird signal corruption of Pinephone UART signals when there's a low → high transition on RX line (say when you type something into a serial console, which causes activity on the RX line), which looks like this (zoomed in to a rising edge of RX signal):

Now those are repeated drops from 3.3V down to almost 2V for some weird reasons. It should be a nice square flat signal, not this mess. Also RX is being actively driven high during the L->H transition, it's not some open drain bus like I2C, so there must be something strongly pulling the RX line low on the phone side, for this to happen.

So I hooked up both signals to the scope, and saw even larger effect on the TX line (magenta):

Now that's quite something. :) Both signals are being corrupted, even when there's no activity on the TX line from the Phone side. So I tried to capture a few more instances of this issue, and managed to capture the interference during the time when TX line was driven low by the Phone:

So I disconnected the RX signal completely (so that it was floating), and this resulted in some cross-talk from TX to RX, but otherwise TX signal was completely clean:

At this point it was clear that the issue related to L->H changes on RX, and it started looking like the multiplexer that is used to switch the headphone jack receptacle between UART and audio modes via a kill-switch was somehow involved. Perhaps the mux was being temporarily switched to audio outputs. This would explain why RX input would be able to overdrive the TX output of the PIC chip on the breadboard and pull it down almost to 2V. It would also explain the simultaneous TX signal corruption. Headphone amplifier would be able to cause that.

The schematic around the multiplexer looks like this:

The multiplexer is siwtched to UART when the IN1/IN2 inputs are low (< 1V). Some signal must be getting to IN1/IN2 from RX/HP_L when RX is transiting from L->H. There's no other way to flip the mux to audio.

So the question is, how? First, IN1/IN2 are pulled low quite weakly with just a 47 kOhm resistor when SW1-F (headphone kill switch) is turned off, so it does not take much current to drive this input over 1V. Just 20 uA would do it.

Second, the switching of the mux to audio mode is short and temporary, so that suggests some capacitor being involved. We can even guesstimate the capacity from the timings on the scope captures. The first switch to audio lasts for 300 ns. The L->H transition is 0->3.3V. The switching threshold on IN1/IN2 is 0.5–1V, so the capacitor would have to charge from 0V to 2.3V in 300ns over a 47 kOhm resistor connected to 3.3 V, so about to 69% of the maximum voltage. What capacitance it has? :)

See eg.

Charging to 69% of the max voltage takes about τ long. τ = RC so, C = τ / R = 300e-9 / 47e3 = ~6 pF. That's not much. So where could this be? Then I noticed that jack plugin detection is done by shorting HP_DET1 signal to HP_L via some mechanism in the receptacle, and that means that HP_L/RX → HP_DET1 → Q801 → R816 → IN1/IN2 now becomes a plausible path for the interfering signal. Q801 purpose seems to be to disconnect the plug-in detection when headphones are kill switched (I guess so that UART RX signal would not be connected to audio codec's plug-in detection input pin, which would lead to misdetection of RX activity for headpones plug-in). The problem though is that MOSFET transistors have significant parasitive capacitances between their leads. These are well specified in their datasheets. And guess what?

The parasitic capacitances for SSM3K35MFV are in the ballpark of what we guesstimated. So we have found the culprit at last. :)

H->L transitions when coupled to IN1/2 do not cause any problems, because they just further push the voltage on IN1/2 down below 0V and thus do not switch the MUX direction.

So to sum it up: Q801 is acting like a 9pF capacitor between its source and gate leads which passes signal from HP_L/RX to multiplexor switching input and thus causes it to switch to audio mode repeatedly for about 1.7us before it settles back to UART mode each time there is L->H transition on UART RX.

The mess lasts 1.7us, so the maximum usable baudrate on pinephone is around 115200 baud.

The repeated switching back and forth between audio/UART during those 1.7us is being caused by a sort of a positive loop, where a swith back to UART causes change in voltage from 2V → 3.3V which is again coupled to the IN1/IN2 and causes it to cross the switching threshold for audio mode again. This happens several times and we're lucky that it eventually stops and does not cause indefinite oscillation.

In the end, Pinephone's UART is reliable only in half-duplex at 115200. Any other use may result in corrupted transmission or reception of data.

If you make sure RX signal is always high, you may be able to use UART TX at high baudrates.

If there's TX and RX activity at the same time, even if RX timing is reasonably slow for RX to not be sampled by the receiver during those 1.7us of interference, concurrently happening TX communication will be affected, and may be corrupted when the TX output is sampled by the receiver during the ongoing interference.

Funny how one FET's parasitical capacitance can degrade uart from easily reaching 3 Mbaud to being cripled to 115.2k and half-duplex.

It's not usually an issue for a typical serial console use, because that's sort of half duplex. You type a character, the phone receives it and then echoes it back. This is a sequential process so TX and RX transmission is not happening at the same time. Of course, that's not a guarantee.

I tried to connect Pinephone to PIC for full-duplex communication over UART, and that doesn't work reliably at all for all the above reasons.

HW workaround

Unsoldering R816 would allow PP to use much higher baud rates, because it disconnects the parasitic signal.

Pinephone Pro

Pinephone Pro does not have this issue, because it doesn't try to gate the HP_DET signal via a FET connected to mux control signals.

HP_DET is be connected directly to UART RX on the jack receptacle, so UART RX signal changes will be misdetected as headphone plugin/plugout events.

To mitigate this, Pinephone Pro is using a simple first order low pass filter with cutoff frequency of 1.6kHz. With high enough baudrate and not too much bytes that consist of mostly 0 being transmited at once, this misdetection of plug-in should not happen all that often in UART mode.