Looking at the circuit diagram for the touch screen interface board:
there is an LED backlight that is intended for PWM (pulse width modulation) control using the LCD_BKL line (connected to PB2/PWM0 of the Allwinner A10). This is pin 36 of the LCD connector for the Olimex LIME.
The Linux LCD driver for the A13-LCD43TS has control of this port but it doesn’t seem to do much. For my application I need to add user control of the backlight because the display will be operated in a darkened room.
Understanding the circuit
PWM control works by switching on and off the supply voltage to the LEDs (fast enough that you don’t see the flicker). When the supply is switched off the LEDs carry on working for a short time until their internal stores of charge (capacitors) have decayed and then they also switch off. So the amount of “on time” relative to the “off time” determines how much energy overall is available to drive the LEDs.
The LED backlight (VLED+ and VLED-) uses the 28V for full brightness (I actually measured 24V). It is in series with T1 so we must switch off T1 to switch off the LEDs.
This is done by raising T1’s base close to the 28v supply. We do that by switching off T2 and that allows T1’s internal base-emitter resistor circuit to pull the T1 base up to the supply rail.
T2 is switched off by raising its emitter voltage close to it’s base voltage (which is at 3.3V) using the LCD_BKL line. So, to switch off the backlight we make LCD_BKL go high. R7 in this circuit pulls LCD_BKL low to switch on the backlight at full brightness if PB2 is not configured as an output.
Software for PWM control
There are several steps needed to enable PWM output from the A10 :
- Create a kernel build environment to make a custom Debian build. This is so you can add the missing sunxi drivers that aren’t in the standard Olimex distribution package.
- Patch the disp_lcd.c kernel module to disable its control of the backlight. (The details I found relate to an older version of the driver – it is possible the patch is no longer required).
- Add pwm-sunxi.ko to the kernel modules to be built.
- Build and copy the modified LCD driver and the new PWM driver over to your system
- Update script.bin to declare the PWM ports and their default values. (If you don’t do this then pwm0 does not appear in /sys/class/pwm_sunxi/ and you need this).
123456789[pwm0_para]pwm_used = 1pwm_period = 1000pwm_duty_percent = 100[pwm1_para]pwm_used = 1pwm_period = 10000pwm_duty_percent = 100
- Load the pwm-sunxi.ko driver
Then you can experiment with the PWM backlight control.
The pwm-sunxi driver works well but can be misleading until you realise what is going on. The driver makes a number of decisions for you to keep things simple. What this means is it really helps to use an oscilloscope to see what is going on!
Anyway; what I have concluded is this…
When pwm0 is high then the backlight power is switched off -but- the voltage drop at the LEDs is not immediate and it needs time to decay to its lowest value. When pwm0 is low then full power is applied to the LEDs.
To get the best backlight dimming you need the shortest “on” time and the longest possible off time. This means you need the lowest frequency (longest duty cycle) you can program in. The driver allows any value to be programmed but only certain values makes sense, with others values giving unexpected results.
The best values I have found so far are:
Period = 790 Hz (I did get it working at 785Hz but not reliably, 800 Hz is probably a good default).
echo 790hz > /sys/class/pwm_sunxi/pwm0/period
echo 1 > /sys/class/pwm_sunxi/pwm0/duty_percent
echo 100 > /sys/class/pwm_sunxi/pwm0/duty_percent
Duty_percent = 1 to 100 for dimmest to brightest.
(Don’t mess with Duty, keep it simple and use percentage values).
The dimming is not linear. The most obvious changes are in the range 1-20 and the step from 50 to 100 does not having much impact.
A value of 1 does not cause any flickering as far as I can see.
Switching off the backlight
To switch off the LEDs completely using the pwm0:
echo 1 > /sys/class/pwm_sunxi/pwm0/duty_percent
echo 0 > /sys/class/pwm_sunxi/pwm0/run
This stops the PWM in the state pwm0 was when the command was executed. So the LEDs can be on or off! Setting duty_percent to 1 gives only a 1 in 100 chance of the backlight being lit (and very bright!) when it is stopped. I suspect there is a better way to do it.
Loading pwm-sunxi at boot time
To auto-load the module at boot time edit the /etc/modules file and the pwm-sunxi line:
# /etc/modules: kernel modules to load at boot time.
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
#For SATA Support
#Display and GPU
The command lsmod reports pwm_sunxi is loaded.
Kernel and module versions
The Debian image I’m using has kernel 3.4.90+ and the modinfo command reports the following:
author: David H. Wilkins <dwil...@conecuh.com>
vermagic: 3.4.90+ preempt mod_unload modversions ARMv7 p2v8