Cross Compile Raspberry Pi Kernel to support Tontec 3.5 Inch 480×320 LCD

Please Note

This post is no longer relevant for newer Tontec MZ61581 LCD, if your Tontec screen was purchased from 2015 onwards please download http://s3.amazonaws.com/ttbox/35screen.zip and just follow the instructions. They have included the drivers in FBTFT so it’s much easier to get your display up and running 🙂

If you want some instructions on how to cross compile your pi kernel then this blog post will hopefully still be of some use!

Introduction

My journey started when I received delivery of my shiny new pi case and LCD display / touch screen. I eagerly followed the instructions supplied by Tontec (https://s3.amazonaws.com/ttbox/35screen.zip  ) and got the LCD display working quite quickly but was disappointed with the results. The driver that they supplied technically worked but used almost all the CPU on the pi and was in effect useless.

One word of warning was that the first time I tried to use the supplied driver I had my pi over clocked to 1000 Mhz and the display would not work. A helpful person on the raspberry pi forum had had a similar problem. Switching off the over clocking fixed the issue. I can overclock my pi to 950 Mhz and the display works without issue. I suggest that you start with a pi that has not been over clocked and then step up the over clocking once you have it working.

I did some more research mostly on the raspberry pi official forums and found that this was a problem experienced by everyone that has purchased this and other similar displays. An open source frame buffer driver framework FBTFT had been created (https://github.com/notro/fbtft/wiki) by an enterprising pi user named notro. I was initially excited to see that it looked like the Tontec display uses a compatible display controller so I started trying to get the display to work using this framework. I learnt a lot on this journey using the information on the wiki but did not manage to get the display to work.

I then sent an email to Tontec asking if they had a solution and was impressed with how quickly they responded. It seems that they has been working on improving their open source driver and they were using the excellent FBTFT framework. They provided me with the following download links.

The above links are links to raspberry pi raspberry SD card images. If you want to create a pi sd card from this image then follow the instructions from the raspberry pi website http://www.raspberrypi.org/documentation/installation/installing-images/README.md.

I downloaded the the correct image for my display and happily watched my pi boot using the TFT display 🙂

By this point I had spent a lot of time reading the documentation on the FBTFT wiki and fancied teaching myself how to re-compile the raspberry pi kernel and see if I could compile my own kernel with support for the Tontec display.

I again contacted Tontec to ask for the source code that they had used to create there custom images. Again I was amazed at how quickly they responded and supplied me with the source code.

It turns out that they have modified the FBTFT source so it’s not currently possible to use the pre-build kernel and firmware that can be downloaded from the FBTFT site. I spent quite a few weeks trying before I released that they had modified the FBTFT source! I initially wanted to use loadable kernel modules that would not require the kernel to be re-compiled but so far I have not been able to get the modified FBTFT source to work as a loadable module. (A project for the future me thinks!)

I was successful in re-compiling the raspberry pi kernel and getting the display to work with the newly compiled kernel. I initially tired to compile directly on the raspberry pi but it takes 9 hours on the pi so I quickly decided to build a cross compile virtual machine and compile the kernel on that.

Below are the notes that I made teaching myself how to compile the raspberry pi kernel with the FBTFT drivers using the latest raspberian image at the time  of writing (October 2014).

I used the following sites as my reference, so I would suggest that you also take a look at these sites.

You can use the procedure below if you want to build a raspberry kernel that will allow you to see the pi boot on the TFT display. I used an Ubuntu virtual machine running on my windows laptop to cross compile the kernel.

Cross Compile the kernel

Download and install virtual box

Download Ubuntu desktop from http://www.ubuntu.com/download/desktop

Create a new virtual machine in virtual box

createVM

Make the hard disk 16GB as the default 8GB is not quite big enough for job.

Boot the virtual machine from the Ubuntu image that you downloaded.

Follow the instructions and install Ubuntu desktop. I installed with a named user of pi.

Next we need to install the virtual box additions and some other software needed for re-compiling the kernel. The terminal is found clicking the first icon in the tool bar

term button

on the desktop side bar and typing “terminal” in to the search bar.  Once the terminal is open enter the commands in the boxes below to install the virtual machine add-ons.

cd $HOME    
sudo apt-get install virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11

Once the add-ons are installed it will be helpful to allow you to copy and paste between your virtual machine and your host machine. This is configured from the devices menu and the shared clipboard sub menu located at the top of the virtual machine console window.

Next we need to install GIT

cd sudo apt-get install git

Download the pre-built bmc2708 compiler from the Raspberry Pi tools section on GitHub

git clone git://github.com/raspberrypi/tools.git --depth 1

Install gcc and other required bits

sudo apt-get install gcc-arm-linux-gnueabi make ncurses-dev

Install support for 32 bit if on Ubuntu 64 as I am as well as unrar that we will need later to unpack a rar archive

sudo apt-get install libc6-i386 lib32z1 lib32stdc++6 unrar

Set the following environment variables by adding the following lines to the .bashrc hidden file in your home directory. This file is executed when you start a bash shell and so ensures that the environment variables are set that are needed for the compilation.

export PATH=$HOME/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin:$PATH
export CCPREFIX=$HOME/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-
export MODULES_TEMP ~/modules

Close the terminal window and re-open to start a new shell with the environment variables set.

Initialise GIT and download the pi kernel source

git init 
git clone --depth 1 git://github.com/raspberrypi/linux.git

Download the modified FBTFT source from Tontec and configure it in the kernel source

wget https://s3.amazonaws.com/ttbox/mztx-fbtft.rar
unrar x mztx-fbtft.rar
mv mztx-fbtft/fbtft $HOME/linux/drivers/video/fbtft
cd $HOME/linux/drivers/video
echo "obj-y += fbtft/" >> Makefile
sed -i 's/endmenu/source "drivers\/video\/fbtft\/Kconfig"\n\nendmenu/' Kconfig
ln fbtft/fbtft.h ../../include/linux/fbtft.h
cd fbtft
make clean

Next we need to modify the bcm2708 platform file. (A modified copy can be found in $HOME/mztx-fbtft) The file is located arch/arm/mach-bcm2708/bcm2708.c relative to where you installed the kernel source. So if you followed my instructions use the following command to edit the bcm2708.c platform file.

nano $HOME/linux/arch/arm/mach-bcm2708/bcm2708.c

Add the following line to the top of the file with the other #include statements

#include <linux/fbtft.h>

Replace the following section (nano $HOME/linux/arch/arm/mach-bcm2708/bcm2708.c)

#ifdef CONFIG_BCM2708_SPIDEV
static struct spi_board_info bcm2708_spi_devices[] = {
#ifdef CONFIG_SPI_SPIDEV
 {
 .modalias = "spidev",
 .max_speed_hz = 500000,
 .bus_num = 0,
 .chip_select = 0,
 .mode = SPI_MODE_0,
 }, {
 .modalias = "spidev",
 .max_speed_hz = 500000,
 .bus_num = 0,
 .chip_select = 1,
 .mode = SPI_MODE_0,
#endif
 }

With the following if the date on the back of your display reads before 2014-10-1

#ifdef CONFIG_BCM2708_SPIDEV
static struct spi_board_info bcm2708_spi_devices[] = {
#ifdef CONFIG_SPI_SPIDEV
 {
 .modalias = "fb_ili9481",
 .max_speed_hz = 128000000,
 .mode = SPI_MODE_3,
 .platform_data = &(struct fbtft_platform_data) {
 .display = {
 .buswidth = 8,
 .backlight = 1,
 },
 .bgr = true,
 .gpios = (const struct fbtft_gpio []) {
 { "reset", 15 },
 { "dc", 25 },
 { "led", 18 },
 {},
 },
 }
 }, {
 .modalias = "spidev",
 .max_speed_hz = 500000,
 .bus_num = 0,
 .chip_select = 1,
 .mode = SPI_MODE_0,
 }
#endif
};
#endif

Or the following if the date on the back of your display reads after 2014-10-1

#ifdef CONFIG_BCM2708_SPIDEV
static struct spi_board_info bcm2708_spi_devices[] = {
#ifdef CONFIG_SPI_SPIDEV
 {
 .modalias = "fb_ili9486",
 .max_speed_hz = 128000000,
 .mode = SPI_MODE_3,
 .platform_data = &(struct fbtft_platform_data) {
 .display = {
 .buswidth = 8,
 .backlight = 1,
 },
 .bgr = true,
 .gpios = (const struct fbtft_gpio []) {
 { "reset", 15 },
 { "dc", 25 },
 { "led", 18 },
 {},
 },
 }
 }, {
 .modalias = "spidev",
 .max_speed_hz = 500000,
 .bus_num = 0,
 .chip_select = 1,
 .mode = SPI_MODE_0,
 }
#endif
};
#endif

Now it’s time to start the kernel build process. On my i7 4 core laptop giving 3 cores and half my ram (2GB) to the virtual box VM the kernel compile takes 20 to 30 mins which is a lot better than about 9 hours it takes on the pi.

cd $HOME/linux
make mrproper 

Next we need the current config from your pi that can be generated by running the following command on your pi

zcat /proc/config.gz > .config

and then the following on the build machine to copy the config file to the root of the kernel source code.

scp pi@IP_OF_PI:.config $HOME/linux 

Ensure that your configuration is up to date with the following command. Make should ask you at least to confirm Support for small TFT LCD display modules (FB_TFT) [N/m/y] (NEW)

* Restart config...
*
*
* Support for small TFT LCD display modules
*
Support for small TFT LCD display modules (FB_TFT) [N/m/y] (NEW) y
 FB driver for the ILI9481 LCD Controller (FB_TFT_ILI9481) [N/m/y/?] (NEW) y
 FB driver for the ILI9486 LCD Controller (FB_TFT_ILI9486) [N/m/y/?] (NEW) y
*
...

and most likely a few more. Answer y to the FB_TFT questions as shown above. If it asks for lots the most likely you have not copied in the kernel from the running pi.

make ARCH=arm CROSS_COMPILE=${CCPREFIX} oldconfig

now run menuconfig so that we can configure the fbtft modules

make ARCH=arm CROSS_COMPILE=${CCPREFIX} menuconfig

If menuconfiug runs the following will be displayed.

menuconfig1

Arrow down to “Device Drivers” and hit return. Arrow down to “Graphics Support”

Arrow down to “Support for small TFT LCD display modules (NEW) and it should already be selected with a star.

menuconfig2

The hit enter and check the ILI9481 and/or the ILI9486 are selected.

menuconfig3

You may also want to enable Frame buffer console rotation

Device Drivers —> Graphics support —> Console display driver support —>

[*] Framebuffer Console Rotation

Exit menuconfig opting to save the changes to the configuration file.

Now we are finally ready to build the raspberry pi kernel. The –j6 switch tells it to use more than 1 core. I have seen conflicting advice but I went for number of cores *2 so in my case I have given 3 of my 4 cores to the Ubuntu so hence why I use –j6

make ARCH=arm CROSS_COMPILE=${CCPREFIX} -j6

Now compile the modules

make ARCH=arm CROSS_COMPILE=${CCPREFIX} modules

Install the modules

make ARCH=arm CROSS_COMPILE=${CCPREFIX} INSTALL_MOD_PATH=${MODULES_TEMP} modules_install

Create a tar archive of the modules so that they can be transferred to the pi

cd $HOME/modules
tar cvf lib.tar *

Download the firmware to match you kernel source. This takes a while depending on your internet connection speed.

cd $HOME
git clone git://github.com/raspberrypi/firmware.git

Now we have everything we need to boot the new kernel on the pi. We use scp to transfer files from the build machine to the pi users home directory, then log into the pi and install the files, reboot it and cross our fingers.

scp /home/pi/linux/arch/arm/boot/Image pi@IP_OF_PI:fb_ili9486.img

or

scp /home/pi/linux/arch/arm/boot/Image pi@IP_OF_PI:fb_ili9481.img

depending on the date on your board.

Next we transfer the firmware

scp $HOME/firmware/boot/bootcode.bin pi@IP_OF_PI:
scp $HOME/firmware/boot/fixup.dat pi@IP_OF_PI:
scp $HOME/firmware/boot/start.elf pi@IP_OF_PI:

Modules

scp $HOME/modules/lib.tar pi@IP_OF_PI:

Now it’s time to log into the pi and install the kernel and firmware.

sudo mv bootcode.bin /boot
sudo mv fixup.dat /boot
sudo mv start.elf /boot

sudo mv fb_ili9481.img /boot
# or
sudo mv fb_ili9486.img /boot

Install the complied libraries

cd /
sudo tar xvf $HOME/lib.tar
cd $HOME

Update the /boot/config.txt and set the new boot kernel (fb_ili9486.img or fb_ili9481.img)

sudo nano /boot/config.txt

Add or update the configuration parameter (fb_ili9481.img or fb_ili9486.img depending on your board)

kernel=fb_ili9481.img

I found the default console font a little hard to read so followed the instructions at https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi/using-the-console to select a better console font.

My next project is to try to compile support for the touch screen component of the display, and see if I can incorporate the Tontec changes to the official  FBTFT source so that the display can be used with the pre-build images available for download on the FBTFT wiki. If any one has any ideas on how to do this please fell free to comment below.

Advertisements