view doc/LCD-backlight-driver @ 167:8ffcd88d40c3

eeproms: fc-jtag gives way to jtagbuf
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 31 Jul 2023 00:34:38 +0000
parents b1b027efce8e
children
line wrap: on
line source

I, Mother Mychaela, have a deep desire to build my own GSM cellphone handset
that would serve as a published-source replacement for my current Pirelli
DP-L10, which is laden with unwanted and undocumented extra non-GSM components
and for which there are no schematics.  I already know what kind of display I
wish to use in my dream FreeCalypso Libre Dumbphone: a 2.0" 176x220 pixel TFT
color LCD, strictly transmissive, requiring a backlight - same principal class
of LCD as in the Pirelli DP-L10, but stepping up in size from Pirelli's 128x128
to 176x220 pixels.  There are many vendors who make suitable LCD modules, and
there are two specific candidate modules already in use at FreeCalypso HQ as
part of various prototype rigs.

The backlight is implemented in exactly the same way on all candidate 2.0"
176x220 pixel TFT LCD modules I have looked at: it consists of 3 white LEDs,
joined together either at the anode or at the cathode, with the opposite
terminal brought out separately for each of the 3 LEDs, supporting an
arrangement where the 3 LEDs are driven in parallel rather than in series.
Each of the 3 LEDs needs to have about 15 mA flowing through it for maximum
display brightness; lower LED currents will produce lower display brightness,
but going significantly above 15 mA would be bad - too much current would burn
out the LEDs.

Exactly how should this backlight be driven in our FreeCalypso Libre Dumbphone
design?  In this article I am going to look at some obvious and less obvious
ways to drive backlight LEDs, and then present my own novel way (novel in that
I haven't seen it used in any existing design or seen it recommended anywhere)
which has already been implemented on our current Luna development platform.

The trivial way: VBAT and series resistors
==========================================

The most trivial way to drive a backlight LED or a parallel group of such LEDs
in a mobile phone whose ultimate power source is a single-cell Li-ion battery
would be to put a current limiting resistor in series with each LED, and then
connect each LED+resistor set between VBAT and GND, i.e., across battery
terminals.  (Of course a transistor would also need to be inserted somewhere to
act as on/off switch, turning the backlight on only when it is needed.)

With this trivial arrangement the value of the series resistors (one in series
with each LED) would need to be calculated as follows:

R = (VBAT_max - Vled) / Iled_max

where VBAT_max is the maximum allowed battery voltage (4.2 V for typical Li-ion
batteries), Vled is the voltage drop across a backlight LED, and Iled_max is the
maximum current that should ever flow through each individual LED.

The big problem with this trivial LED driver approach is that the display
backlight will glow at its maximum brightness only when the battery is at its
peak charge, and will dim as the battery discharges.  Why so?  The series
resistor value would need to be set per the equation above in order to avoid
damage to the backlight LEDs (the current through each LED must not exceed
Iled_max at the highest battery voltage), but then as the battery discharges,
the voltage across each LED series resistor will decline (VBAT - Vled, with
Vled assumed to be constant), and the current through the resistor (and thus
through the LED as well) will decline proportionally.

How do LCD backlights in mainstream commercial phones behave in this regard?
I have a disassembled Pirelli DP-L10 phone (bare motherboard with the LCD and
the keypad still attached) which I have hacked up to be powered by a lab bench
power supply instead of the usual battery, and I did an experiment with it: I
powered up this Pirelli motherboard with my bench supply, running Pirelli's
original firmware, I got it into a state where both LCD and keypad backlights
are on (press any keypad button to turn them back on when the fw turns them off
by timeout), I turned the voltage knob on the power supply up and down, and I
observed the brightness of both LCD and keypad backlights.

Observation: Pirelli's keypad backlight does get noticeably brighter or dimmer
as VBAT goes up and down, indicating that they do use the trivial driver circuit
for this one (from fw perspective, Pirelli's keypad backlight is driven or at
least controlled with Iota LED-B), but the LCD brightness stays exactly the same
as VBAT ranges from the 4.2 V Li-ion maximum to the low-battery emergency
shut-off voltage (about 2.8 V) at which the Iota VRPC block involuntarily shuts
down the entire Calypso subsystem.

It is not clear exactly how Pirelli's LCD backlight driver circuit is
implemented.  There is a component on their motherboard near the LCD connector
marked as A3-90E - it might be the LED driver - and there is another little
component next to it that looks like an inductor, suggesting some kind of boost
converter.  There is no documentation for Pirelli's Giantplus GPM526A0 LCD
module, but it seems to have just two wires for the backlight, suggesting that
the two backlight LEDs (this LCD module has 2 backlight LEDs rather than 3) may
be wired in series (not parallel), in which case a boost converter would be
absolutely required.

Boost to 5V, then fixed series resistors
========================================

The available schematics for Motorola C139 and C155 phones depict an LCD
backlight driver circuit that seemed bizarre to me at first: they take VBAT,
boost it up to constant 5V with a step-up charge pump (RT9361A on C139
schematics, REG710NA-5 on C155 schematics), and feed that 5V to their LCD
module, which presumably expects fixed 5V backlight power and internally
contains a fixed resistor in series with each LED.

This approach certainly accomplishes the goal of constant LCD backlight
brightness irrespective of battery state of charge, but it does so at a huge
cost in terms of efficiency.  Both RT9361A and REG710NA-5 are step-up charge
pumps, and they work by doubling the current draw.  If we were to use the same
arrangement for our LCD backlight (3 LEDs, each needing 15 mA), then for 45 mA
of current flowing through the LEDs, 90 mA will be drawn from the battery.
These are not "smart" boost converters that draw less input current as their
input voltage goes up (for same I*V power), instead the input current is an
almost constant 2x the output current, thus the overall efficiency gets very
poor at higher battery voltages.

I strongly dislike this approach for its wastefulness, hence I sought another
way.

My novel 3.5V LDO approach
==========================

Datasheets for the LCD modules I am working with specify the drop voltage across
each of the 3 backlight LEDs as 3.2V.  The table of battery voltage thresholds
(mapping VBAT to battery state of charge percentages) inside Pirelli's firmware
(located and extracted via thorough reverse eng) has these mappings at the lower
end:

3719	20
3688	15
3663	10
3539	5
3370	0

These numbers make it clear that a battery voltage around 3.5 to 3.6 V means
that the battery is near empty; combining this "low battery" number with the
datsheet-stated LED drop voltage of 3.2 V gave me this idea: what if we feed
VBAT to a 3.5V LDO regulator and use this LDO output as the backlight power
source, with the LED series resistor values computed for 3.5 V supply?  This
approach would produce constant LCD brightness for the wide VBAT range from
just above 3.5 V (the LDO regulator's dropout is very low) to 4.2 V or above,
without doubling the current draw (for 45 mA flowing through the LEDs,
approximately the same 45 mA will be drawn from the battery), with the only
anticipated penalty being a possible sharp drop-off in LCD brightness when the
battery gets critically low.

When I was designing my FC Luna UI development platform (an LCD add-on to the
existing historical third-party Caramel board), I sought to test this idea
empirically.  But before actually building this Luna LCD board, I fortunately
had the foresight to measure the actual voltage drop across the backlight LEDs,
rather than blindly rely on the datasheet spec of 3.2 V.  Back in 2018 I had
tested my chosen LCD modules in a standalone environment without Calypso: I had
them switched into 8-bit microprocessor bus interface mode (IM0 pin strapping)
and I drove them with an FT2232D adapter using FTDI's MCU host bus emulation
mode.  I still have the two hardware setups (LCD modules from two different
vendors) I had put together back then; the backlight power source in these
setups is USB 5V, with 110 or 120 ohm LED series resistors.  I took the one
setup on which the point between each LED cathode and the connected series
resistor is easily accessible for probing, and I measured the voltage at that
point, to see how the overall 5V gets split between the drop across the LED and
the drop across the resistor.

The answer was somewhat unexpected: the voltage drop across each LED turned out
to be somewhere around 2.9 V, as opposed to the 3.2 V datasheet number.  This
difference in the LED forward drop voltage does highlight one major weakness of
my close-to-Vled LDO approach: by setting the backlight fixed voltage so close
to the expected forward drop voltage of the actual LEDs, I am making my circuit
extremely sensitive to slight variations in that forward drop voltage.  If I
had populated LED series resistors on my Luna LCD board based on the 3.2 V
assumption (assuming 300 mV drop across each resistor), then the current flowing
through the LEDs would be double of my design intent (with Vled = 2.9 V, the
voltage drop across each resistor becomes 600 mV), possibly burning out the
LEDs!  In contrast, a circuit in which each LED+resistor set is driven with a
much higher voltage (meaning a larger voltage drop across the resistor and a
larger resistor value) is much less sensitive to variations in Vled, producing
much less resulting variation in Iled.

I ended up building my Luna LCD board with my 3.5V LDO backlight LED driver
circuit intact, but I populated 38.3 ohm series resistors instead of my
originally intended 20 ohm value.  The resulting circuit works well in practice:
the LDO puts out a very precise 3.5 V for any higher VBAT input, the LCD
backlight is bright and visually pleasing, the measured voltage drop across the
resistors with the backlight on is right about 600 mV, meaning that the 2.9 V
LED forward drop voltage hasn't changed, and the current flowing through each
LED is in the desired 15-16 mA target range.  The LDO regulator's enable input
also conveniently serves as the backlight on/off control, driven by Calypso
GPIO 9 in the complete Luna setup.  (Calypso MCSI is used only in modem configs,
not in handset configs, thus MCSI pins become GPIOs in the latter, available for
functions like LCD backlight control.)

I then set out to test what happens when the VBAT input to my Luna LCD backlight
driver falls below 3.5 V.  At lower voltages the LDO regulator becomes
essentially a pass-through, with the low battery voltage applied almost directly
to each LED+resistor set.  The current flowing through the LEDs falls
accordingly, but the question to be answered was what happens to the visual
readability of the LCD.  The answer turned out to be very positive: I set my
VBAT-generating lab bench power supply as low as 2.8 V (the emergency shut-off
voltage for Iota VRPC), and while the display naturally gets very dimmed, it is
still readable!  This finding tells us that my 3.5V LDO approach does not
present the problem I was afraid of (the display going totally dark in
critically low battery scenarios when the rest of the phone still has some life
left), and the only remaining concern with this approach is the extremely high
sensitivity to variations in LED forward drop voltage.

Where to go from here
=====================

If I ever get as far as actually building my desired FreeCalypso dream phone,
what LCD backlight driver circuit should I use?  Should I keep the 3.5V LDO
circuit that appears to work OK in our current Luna setup, or would I be heading
into trouble with LED forward drop voltage variations?  I *really* dislike the
wastefulness of the seemingly-mainstream approach (boost converter to a higher
voltage, then series resistors based on that higher voltage), but I don't know
of any better alternative.  If someone with better EE knowledge can suggest a
non-wasteful approach that would eliminate or at least reduce Vled sensitivity,
it would be great, otherwise I will have to stick with my current approach and
hope for the best.

I also desire to add PWM control to this LCD backlight, so that the 45 mA
brightness will be the available maximum, rather than required at all times.
The plan I have in mind is to insert a transistor between the cathode joining
point (where either the 3 LED cathodes or the 3 resistors connected to these
cathodes join) and GND, controlled by Calypso PWL output.  Unfortunately this
approach would be difficult to prototype in our current Luna environment
because Calypso LT/PWL output is not easily accessible on the Caramel board: it
does come out of the core module, but it goes to an on-board transistor for an
on-board indicator LED, and does not go to any header pins or test points.