I recently bought a number of 5″ Touch Screen LCDs for the Raspberry Pi 2 from eBay. They were cheap knock-offs of a more popular brand name product, with little documentation, and broken English (hey their English is an order or two of magnitude better than my Chinese though) where there was some. The LCD displays use a chip called a XPT2046. This is a “compatible” (or read knock off) of the ADS7846 chip found in many touch screen devices. The drivers are compatible, thankfully, so we can enable them without too much pain.
As it turns out, if you’re using a recent version of Raspbian (i.e. version 7 with a kernel version north of 4.1.7 in my case), you can actually enable these units very easily. There are, however, some serious “gotchas” that you can stumble around for hours without finding a solution.
The first thing to keep in mind is that the native resolution of the LCD is NOT full HDMI, so if you try to put it through the LCD you’ll get something like:
As it turns out, this is not broken hardware at all, but just a configuration issue. Since the native resolution of these panels is 800×480, trying to push 1080p through it doesn’t really work very well. It can keep up for a portion of the dot clock cycle (the visible portions), but not the whole thing. This is easily corrected by editing the config.txt file.
In the case of the Windows 10 IoT (Internet of Things) distribution OR Raspbian 7, simply edit the configuration file in the EFI partition to reflect the below:
hdmi_cvt 800 480 60 6 0 0 0
Getting the touch screen working on Raspbian 7 is pretty easy, as well. Windows 10 IoT doesn’t currently have a driver (stay tuned here, I may be writing one if time allows).
Just add the below additional lines to the configuration file (in /boot/config.txt when Raspbian is running):
This tells the Linux kernel (at least as of version 4.1 and later), to use the ads7846 driver over the SPI bus to read touch screen coordinates. The penirq=25 line tells the driver to use GPIO pin 25 as the interrupt for a touch screen event. The penirq_pull=2 tells the driver to turn the pullup resistor on for the SPI bus, and xohms=150 tells the driver to use a baseline of 150 ohms (not the default 400) as the resistance for the resistive touch screen input. It’s also important to note that the default speed is way too fast for the XPT2046 chip (around 2 MHz, it can handle 1MHz on a good day), so we set it to 10000 (1 MHz).
The next part will require a small amount of ingenuity on your part. You’ll need to get the file “5inch_HDMI_LCD.tar.gz” from somewhere. If you search with Google, you should be able to find it easily enough. With this file, you can extract the archive file “xinput-calibrator_0.7.5-1_armhf.deb”. Install it with “dpkg -i xinput-calibrator_0.7.5-1_armhf.deb“.
This installs the graphical touch screen calibration tool for the 5″ LCD. Since we want to provide at least a baseline calibration, we add a directory at /etc/X11/xorg.conf.d and create a file named 99-calibration in that directory. The contents (as an example) would be:
MatchProduct “ADS7846 Touchscreen”
Option “Calibration” “129 3955 191 3946”
If you want to calibrate your display manually, you can simply log into the Raspberry Pi 2 on the console and issue the normal startx command. Then SSH into the Raspberry Pi 2, and run the command “DISPLAY=:0 xinput_calibrator”. You should get a screen that tells you to press the stylus to the crosshair. Once you’ve hit all four crosshairs, you are presented with a chunk of text that looks strikingly like the above 99-calibration file contents. Replace the /etc/X11/xorg.conf.d/99-calibration file’s contents with the output of the xinput_calibrator command and you should be in good shape.
Here’s what it looks like when things are happy-happy joy-joy:
A side note: The Windows 10 IoT distribution is rapidly becoming one of my favorite platforms to develop quick one-off applications on an Internet and GPIO enabled platform. It would be wonderful to have a Windows 10 IoT driver for the cheap XPT2046 based touch-screen controllers. I’m planning on writing a driver for this purpose if time permits (those who know me are laughing right now), so check back occasionally.
Hope this helps those of you who were facing the same issues I was. Feel free to comment or correct me on things if I made a mistake. 🙂