Raspberry Pi 3, PiTFT and a modern kernel (bluetooth support!)

Note 2017-02-17: Some slight changes have been made after testing this guide against raspbian 2017-01-11.

Adafruit’s PiTFT is a very neat little addition to the Raspberry Pi. It combines a 2.8″ 320×240 touchscreen (either resistive or capacitive) with 4 buttons hooked up to the Pi’s GPIO. Adafruit even sells a case topper for their standard pi case to fit the screen.

Installation and use of the screen is easily done by following the instructions. The easy install script takes care of everything and after a reboot the screen works flawlessly.

Unfortunately this will install a fairly old kernel, 4.1, which does not support certain features of the Pi 3. Bluetooth support is one of them and the WiFi driver seemsless reliable. There have been multiple forum posts requesting an updated kernel since the Pi 3 was released, but nothing has surfaced yet.

This guide sets up the screen with a standard raspbian install and gets the touchscreen to work for TSLIB by applying a small kernel patch. I’ ll primarily be using the screen with pygame, a simple and light way of getting images up on the screen. pygame relies on TSLIB for it’s touchscreen input, hence the need for the patch.

First of all, my “setup” is as follows:

Raspberry Pi 3

Adafruit 2.8″ capacitive PiTFT Plus

Adafruit Case and PiTFT case Topper

Raspbian jessie lite 2016-05-27 (and 2017-01-11)

Let’s start by everything that’s needed to get the screen to run. I’ll follow up with some more details to what’s what below.

Step by Step

These steps are based on adafruit’s instructions but without using the adafruit kernel. This will probably only work for a Pi 2 and 3.

Start by having raspbian jessie installed and running on your Pi. Make sure all the software is up to date by running
sudo apt-get update && sudo apt-get upgrade

Append the following to /boot/config.txt. If you are using the resistive version use the pitft28-resistive.dtbo overlay instead.

/boot/config.txt

1

2

3

4

dtparam=spi=on

dtparam=i2c1=on

dtparam=i2c_arm=on

dtoverlay=pitft28-capacitive,rotate=90,speed=32000000,fps=20

Adafruit’s steps to get the console to show up on boot are still valid. Modify the kernel options by appending fbcon=map:10 fbcon=font:VGA8x8 to /boot/cmdline.txt It should look something like this:

And to be sure that the module is loaded modify /etc/modules and add ft6236 to the list:

/etc/modules

1

2

3

4

5

6

# /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.

ft6236

dmesg can be used to check if everything is loading:

This shows that both fbtft and ft6236 are loaded and have created their devices.

For decent pygame support libsdl has to be downgraded, here adafruit’s steps can be followed 1:1. Create a file pinsdl.sh and paste in this code:

/home/pi/pinsdl

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#!/bin/bash

#enable wheezy package sources

echo "deb http://archive.raspbian.org/raspbian wheezy main

" > /etc/apt/sources.list.d/wheezy.list

#set stable as default package source (currently jessie)

echo "APT::Default-release \"stable\";

" > /etc/apt/apt.conf.d/10defaultRelease

#set the priority for libsdl from wheezy higher then the jessie package

echo "Package: libsdl1.2debian

Pin: release n=jessie

Pin-Priority: -10

Package: libsdl1.2debian

Pin: release n=wheezy

Pin-Priority: 900

" > /etc/apt/preferences.d/libsdl

#install

apt-get update

apt-get -y --force-yes install libsdl1.2debian/wheezy

Execute the file by issuing these commands:

Shell

1

2

sudo chmod +x pinsdl.sh

sudo ./pindsdl.sh

Your Pi is now ready to use pygame based and touchscreen input!

Detailed Reasoning

Adafruit does supply a set of patches, but the file’s datestamps indicate that the patch was created in 2013. This is even more outdated than adafruits kernel sources. and will not help patching the newer kernel. It does however give some insight in what Adafruit has modified and which modules are used.

Time to do some digging!

Display

In the adafruit kernel the module that creates the framebuffer device /dev/fb1 is called fbtft. This module also exists in the raspbian sources, so it should also support the pitft. Lets dig a little deeper! In the instructions adafruit modifies the /boot/config.txt file to add an overlay and this initializes the module with the right parameters. The exact same overlay does not exist but seems to have been renamed to pitft28-capacitive.dtbo or pitft28-resistive.dtbo. This overlay can be used and the screen works immediately, that was easy! Adafruit’s other tweaks to get the console to show work without any change too.

I think X should also work as the framebuffer device is created similar to the adafruit kernel.

Touchscreen

The touchscreen required a little more work. Adafruit’s kernel contains the module ft6x06_ts but it does not exist in the raspbian sources. However it does contain a module ft6236, might this work? Adafruit’s udev rule does create the /dev/input/touchscreen symlink and running evtest shows incoming coordinates when the screen is touched. So Succes? Unfortunately not, when running a TSLIB test it outputs “Error Message is: selected device is not a touchscreen I understand”. A bit of googling led me to a post on 0xf8 where Pieter Hollants ran into the same problems. He does a great job of identifying why TSLIB does not understand the event output: Basically, TSLIB requires a touch pressure value to function. Unfortunately he does not have a solution for the problem.

This made me dig a little more in the differences between the sources of the two modules. Turns out the ft6x06_ts does not read the actual force data from the controller but just uses a defined constant! The kernel patch implements exactly the same for the newer ft6236 module and bingo! it works!

Loose Ends

Obviously there are some loose ends because of my hardware and because I simply haven’t tried everything yet:

PWM Backlight control

GPIO Power Switch: Module rpi_power_switch does not exist.

I have not tried to get X to run, as I’ll be using Pygame/SDL for the graphics. It will probably work fine without the kernel modifications as these were only needed to get LIBTS to work.