Complete rotation support for the Adafruit PiTFT 2.8″ capacitive touchscreen display

In my previous post, I introduced the PiTFT 2.8″ capacitive touchscreen display and showed some test code. If you played around with that, you might have noticed that with the default /boot/config.txt setting of rotate=90 the display is a landscape mode.

But you’ll also notice that the reason why we didn’t disable PyGame’s mouse pointer is so that we can see why the counter shown does not react to our touchscreen gestures as expected:

  • if you swipe to the right, the pointer moves down
  • if you swipe to the left, the pointer moves up
  • if you swipe down, the pointer moves left
  • if you swipe up, the pointer moves right

So obviously display and touchscreen use different drivers and the rotate parameter affects the former only. And if we look at Adafruit’s online guide to the PiTFT, you won’t find a suitable option for the touchscreen part. They seem to silently ignore that subject.

Now that guide was apparantly written somewhere in the summer of 2015. The Raspbian version I used for my experiments is the Jessie release from November 2015. When I was looking through /boot/overlays/README about potential other parameters for Adafruit’s pitft28c device tree overlay, I noticed that the README had not mention of it but mentioned a pitft28-capacitive overlay:

Name:   pitft28-capacitive
Info:   Adafruit PiTFT 2.8" capacitive touch screen
Load:   dtoverlay=pitft28-capacitive,=
Params: speed                    Display SPI bus speed
        rotate                   Display rotation {0,90,180,270}
        fps                      Delay between frame updates
        debug                    Debug output level {0-7}
        touch-sizex              Touchscreen size x (default 240)
        touch-sizey              Touchscreen size y (default 320)
        touch-invx               Touchscreen inverted x axis
        touch-invy               Touchscreen inverted y axis
        touch-swapxy             Touchscreen swapped x y axis

Et voila, exactly the kind of parameters we need!

At first I didn’t get that pitft28c is not the same as pitft28-capacitive, so I simply added combinations of the touch-invx, touch-invy and touch-swapxy options to the pitft28c line in /boot/config.txt and wondered why they had no effect. Then I thought about it some more and came to realize that those were actually two different files located in the /boot/overlays directory, namely pitft28c-overlay.dtb and pitft28-capacitive-overlay.dtb.

Googling for the latter lead me to the pull requests #1050: DTS for Adafruit PiTFT 2.8 capacitive touchscreen and #1192: Added overlay for Adafruit PiTFT 2.8″ capacitive touch screen which indicated that:

  • the ft6236 touchscreen driver had been accepted into the mainline Raspberry kernel in October 2015
  • a suitable overlay, namely pitft28-capacitive-overlay.dts had been merged in November 2015.

So since November 2015 basically everything required for support of the touchscreen is available in the mainline Raspberry distribution and no special Adafruit packages are necessary any longer. You will however add some configuration manually that is otherwise done by the adafruit-pitft-helper script. For the example of /boot/config.txt, we can use its results as a starting point:

[pi1]
device_tree=bcm2708-rpi-b-plus.dtb
[pi2]
device_tree=bcm2709-rpi-2-b.dtb
[all]
dtparam=spi=on
dtparam=i2c1=on
dtparam=i2c_arm=on
dtoverlay=pitft28c,rotate=90,speed=32000000,fps=20

Changing pitft28c to pitft28-capacitive here and rebooting alone will not suffice if you installed Adafruit’s raspberrypi-bootloader package. You’ll need to revert to the newest original Raspbian version. I did this by executing rpi-update.

After a reboot the touchscreen was still working, although with the new in-kernel driver, with the screen being properly rotated. However /dev/input/touchscreen was missing because a new udev rule was required. I edited /etc/udev/rules.d/95-ft6206.rules as follows:

SUBSYSTEM=="input", ATTRS{name}=="ft6236", ENV{DEVNAME}=="*event*", SYMLINK+="input/touchscreen"

Next the touchscreen was working again as I could verify with the test program from my previous post. Jay!

Of course the touchscreen still had the X and Y axes wrong. So I added the touch-swapxy option and rebooted. Now the Y asis was right but the X axis was still wrong. So I also added the touch-invx option so the line looked like this:

dtoverlay=pitft28-capacitive,rotate=90,speed=32000000,fps=20,touch-swapxy=true,touch-inx=true

…but the X axis was still wrong!

For cases as these it helps to understand device trees in more depth. This raspberrypi.org page “Device trees, overlays and parameters” gives you exactly depth. From there I deduced that parameter parsing could be nicely debugged using

vcdbg log msg

which indicated that instead of touch-invx the parameter would actually be parsed as touch-i. Dafuq?

Reading the raspberrypi.org page again indicated that /boot/config.txt lines are not allowed to have more than 79 characters or so. The trick is to spread parameters over multiple lines like this:

dtoverlay=pitft28-capacitive,rotate=90,speed=32000000,fps=20
dtoverlay=pitft28-capacitive,touch-swapxy=true,touch-invx=true

I rebooted and voila! The test program was finally working properly :)