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. https://www.student-circuit.com/studentzone/transient-response-of-rc-circuit/
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.