In my last posts I showed how to integrate Watterott’s MI0283QT-2 and the newer -9 displays as a frame buffer device in Raspberry Pi’s Linux kernel. Now I will focus on adding support for the touch controller found on the display boards.
The touch controller is an ADS7846 chip that already has a device driver in the Linux kernel. User dronus has patched the vanilla driver to make it work with the MI0283QT displays and the Raspberry Pi.
Fine, we already have everything in place now to give it a try!
Hardware
First, we need to add two additional wires in our hardware setup to connect the touch controller (see old wiring in last post) with the RPi:
Signal Raspi Display Comment T_IRQ GPIO25 13 Interrupt line from ADS7846 T_CS SPI0_CE0_NÂ 11 SPI chip select 0
Software
I assume you already have a patched Linux kernel with the tft driver patches applied. Here is quick list with the next steps:
- (Manually) apply dronus small patch to your kernel tree. This adds the necessary modifications of the ADS driver.
- Note: I had to replace the invert_x with the invert_y entry in the ADS configuration to match the display orientation we use in the frame buffer driver
- Your SPI config for the display now should look like this (for the newer *-9 display): linux/file arch/arm/mach-bcm2708/bcm2708.c
static struct ads7846_platform_data ads7846_config = { .x_max = 0x0fff, .y_max = 0x0fff, .x_plate_ohms = 180, .pressure_max = 255, .debounce_max = 10, .debounce_tol = 3, .debounce_rep = 1, .gpio_pendown = 25, .keep_vref_on = 1, .swap_xy = true, .invert_y = true }; static struct spi_board_info bcm2708_spi_devices[] = { { // ads7846 touchscreen on chipsel=0 device .modalias = "ads7846", .bus_num = 0, .chip_select = 0, .max_speed_hz = 500000, .irq = GPIO_IRQ_START+25, .platform_data = &ads7846_config, .mode = SPI_MODE_0 }, { // display on chipsel=1 device .modalias = "ili9341fb", .max_speed_hz = 16000000, .bus_num = 0, .chip_select = 1, .mode = SPI_MODE_0, .platform_data = &(struct fbtft_platform_data) { .gpios = (const struct fbtft_gpio []) { { "reset", 23 }, { "led", 24 }, {}, }, .fps = 10 } } };
- I use GPIO 25 for the touch IRQ (mainly because wiring was easier this way 🙂 and had to change the relevant entries. dronus used GPIO 17 instead.
- I reduced the SPI rate of the display to 16 MHz and the frame rate to 10 fps. This proved to be more stable with activated touch controller.
- The older -2 display works similarly. You only have to exchange the second block with the one of the r61505u driver. See old post for details
- Open the configuration of the kernel and select the ADS driver:
> make menuconfig Select "Device Drivers -> Input Device Support -> [*] Touchscreens -> [*] ADS7846..."
- Make sure to include the ADS driver directly into the kernel and NOT in a module
- Ok, thats it! (Re-)compile kernel and install it on your RPi…
Test
After a reboot your system shows a new input device in /dev/input/*. If no other USB mouse or keyboard is connected then the devices found there are all created by the touch controller.
You can use the evtest utility to check the touch operation (Install with ‘apt-get install evtest’ first!):
> evtest /dev/input/event0
When you tap on the display you will see the incoming events. Note the x and y coordinates mapping if you tap on different corners of the display.
Now with the basic operation tested you can start X11 on your display (see last post) and use your fingers or a stylus to navigate the mouse cursor!
Open Topic
While touch operation with this driver is rock solid and works very precisely I have found one little nuisance: I can’t move the X11 cursor into the border regions of the display 🙁 Approx 5 mm at the border of the visibile display area my touch movements are not recognized anymore and I can’t move the pointer there… I am not sure if this is a limitation of the display, of the ADS driver or the parameter set for the driver… If you find a workaround for this then please post a comment!
[Update: 21.4.2013] Pre-compiled Kernel
A pre-compiled Raspbian Wheezy Kernel 3.6.11+ with both ili9341 display and ads7846 touch driver (i.e. supporting all devices on the MI0283QT-9 board) is available for download here:
Thanks, lallafa! I got it to work using my MI…-2.
Still there are two problems:
While booting I get spammed by the following error (although it seems negligible):
r61505ufb spi0.1: fbtft_update_display: dirty_lines_start=239 is larger than dirty_lines_end=0. Shouldn't happen, will do full display update
When using another kernel (with lcd support, but w/o touch), these errors still appear, but very less frequently. It seems that notro experienced something similar, but didn’t have time to look into it.
The second and annoying problem is:
When dragging around on the display with my finger or stylus, the display gets all glitchy.
Do you experience the same two problems?
I also got the warnings about invalid update requests and ignored them for now 🙂
I observed them always during start up but then during normal operation they did not occur anymore.
Maybe it has something to do with scrolling the screen contents as that is done regularly during startup?
I had distortions, garbled screen contents or even a blank white display if the SPI display clock or framerate was too high compared to the low ADS rate.
As a consequence I reduced both display SPI and fps.
With 16 MHz the -9 display seems to work without problems.
I am trying to get this to work with the -9 display. The display without the touchscreen works fine.
evtest shows the events when I tap the display. But when I start an application on fb1 (for example the x-server), the display gets white and stays that way as soon as I touch it. I can’t access it anymore with for example fbi.
Any ideas what that might be?
I am trying to get touch working with the -9 display. Without touch everything works fine (for example fbi). Touch itself seems to work too (evtest shows some events when I touch it). But if I try to use them together (for example on X) the display gets white and freezes as soon as I touch it. After that I have to reboot to access it again (with fbi). Also the “dirty_lines” error does not disapear after boot if I enable console on the display.
Any ideas?
I found a solution to the boot time messages:
Since the error messages can be neglected, you can disable displaying them by adding “quiet” to the kernel parameters (‘/boot/cmdline.txt’). For me they get fixed when after the “kernel variables” line, but this makes the boot process a little bit more appealing.
The problem with the glitchy display while touching/dragging still persists. The datasheet for the ADS7846 says, the touch panel allows “up to [a] 125kHz clock rate”. Still, using values like this and below for the settings (bcm2708.c), I could not get any better results.
Seems like more investigation is required. Hopefully I’m not alone. 🙂
@Julian:
I did not experience this, but have you tried compiling the driver directly into the kernel? Have you tried reading ‘dmesg’? Maybe, if keyboard controls don’t know anymore, SSH is still an option?
One thing I forgot:
You can calibrate the touch display with xinput_calibrator, but have to compile it yourself, since it’s not available in the RPi repo. Should be no problem though, you just need autoconf and some other packages, which I don’t remember.
This made it possible to touch even outer corners of the touch panel, though not the outermost ones.
Hi lallafa,
tried to get the Display working recently with your advice in article: Watterott MI0283QT-9A Display for the Rasbperry Pi
There you added a small zip file with a ready to go kernel. Is it possible to provide such a zip for the touch functionality as well?
Thanks,
CK
@CK: sure, no big deal… I updated the blog post with the link to the kernel archive
@lallafa:
I just reread your first reply, stating “With 16 MHz the -9 display seems to work without problems.”.
Would you be so kind and see if it works with the exact same wiring/touch driver with the -2A if you find the time?
This would really help me as I am slowly running out of ideas what to do.