/Raspberry-ili9340spi

ILI9340 SPI TFT Library & XPT2046 Touch Screen Library for Raspberry

Primary LanguageCMIT LicenseMIT

Raspberry-ili9340spi

ILI9340 SPI TFT Library for Raspberry Pi.
This may works with other boards like OrangePi/NanoPi.

You can show a chart to ILI9340/ILI9341/ILI9163C/ST7735 SPI TFT.
You can choose bmc2835 library/WiringPi library.

I tested these TFT.
1.44 inch 128x128 ST7735
1.44 inch 128x128 ILI9163C
1.8 inch 128x160 ST7735
2.2 inch 240x320 ILI9340
2.4 inch 240x320 ILI9341
2.4 inch 240x320 ILI9341

This project can be built with either:

  • Build using bcm2835 library
  • Build using Hardware SPI of the WiringPi library
  • Build using Software SPI of the WiringPi library

Wirering

TFT GPIO Header
VCC -- 3.3V *4
GND -- GND
CS -- Pin#24(SPI CS0) *2 *3
RES -- Pin#12 *1
D/C -- Pin#11 *1
MOSI -- Pin#19(SPI MOSI) *3
SCK -- Pin#23(SPI SCLK) *3
LED -- 3.3V *4
MISO -- N/C

(*1) You can change it to any pin by changing source.

(*2) You can use CS1 by specifying compilation flags.

(*3) For Software SPI, you can change it to any pin by changing source.

(*4) SPI TFTs require a lot of current.
If it is supplied from the Raspberry Pi's 3.3V pin, it may run out of current.
Use the 5V pin and the regulator to power it and it will be stable.
I used AMS1117.


Build using bcm2835 library

RPi Only, Very fast

Install bcm2835 library

wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.56.tar.gz
tar zxvf bcm2835-1.56.tar.gz
cd bcm2835-1.56
./configure
make
sudo make check
sudo make install

* This tool require 1.56 or later.
* Because this tool uses bcm2835_spi_write.

Using other GPIO

You can change GPIO to any pin by changing here.

#ifdef BCM
#include <bcm2835.h>
#define D_C 17  // BCM IO17=Pin#11
#define RES 18  // BCM IO18=Pin#12
#endif

Using SPI0

Use Pin#24 as ChipSelect.

cd $HOME   
git clone https://github.com/nopnop2002/Raspberry-ili9340spi
cd Raspberry-ili9340spi
make lib
cc -o demo demo.c fontx.c ili9340.c jpeg.a png.a -lbcm2835 -lm -DBCM
sudo ./demo

Using SPI1

Use Pin#26 as ChipSelect.

cd $HOME   
git clone https://github.com/nopnop2002/Raspberry-ili9340spi
cd Raspberry-ili9340spi
make lib
cc -o demo demo.c fontx.c ili9340.c jpeg.a png.a -lbcm2835 -lm -DBCM -DSPI1
sudo ./demo

SPI bus speed for bcm2835

By default it uses 7.8125MHz on Rpi2, 12.5MHz on RPI3.
Can be changed at compile time.

  • -DSPI_SPEED16 : 15.625MHz on Rpi2, 25MHz on RPI3.
  • -DSPI_SPEED32 : 31.25MHz on Rpi2, 50MHz on RPI3.

50MHz is an overclock.

SPI Bus speed comparison

7.8125MHz 15.625MHz 31.25MHz
ColorBarTest 245 160 107
ArrowTest 286 193 155
LineTest 595 397 294
CircleTest 558 373 282
RoundRectTest 560 371 273
DirectionTest 304 199 153
HorizontalTest 430 283 209
VerticalTest 438 290 214
FillRectTest 448 285 221
ColorTest 500 327 234
JPEGTest 1607 1076 816
PNGTest 1742 1231 974

Build using Hardware SPI of the WiringPi library

WiringPi library initializes GPIO in one of the following ways:

  • int wiringPiSetup (void);
  • int wiringPiSetupGpio (void);
  • int wiringPiSetupPhys (void);
  • int wiringPiSetupSys (void);

This project by default uses the wiringPiSetup() function to initialize GPIOs.
Then use the wiringPiSPISetup() function to initialize the SPI.
If you use it on a board other than the RPI board, you may need to change the WiringPi number.

#define D_C   0 // wPi IO00=Pin#11
#define RES   1 // wPi IO01=Pin#12

As far as I know, there are these WiringPi libraries.

  • WiringPi for OrangePi
  • WiringPi for BananaPi
  • WiringPi for NanoPi
  • WiringPi for Pine-64

If you want to initialize GPIO with wiringPiSetupGpio(), Use the -DGPIO compilation flag.
In this case, use the following GPIOs.

#define D_C  17 // BCM IO17=Pin#11
#define RES  18 // BCM IO18=Pin#12

Using SPI0

Use Pin#24 as ChipSelect.

git clone https://github.com/nopnop2002/Raspberry-ili9340spi
cd Raspberry-ili9340spi
make lib
cc -o demo demo.c fontx.c ili9340.c jpeg.a png.a -lwiringPi -lm -pthread -DWPI
sudo ./demo

Using SPI1

Use Pin#26 as ChipSelect.

git clone https://github.com/nopnop2002/Raspberry-ili9340spi
cd Raspberry-ili9340spi
make lib
cc -o demo demo.c fontx.c ili9340.c jpeg.a png.a -lwiringPi -lm -pthread -DWPI -DSPI1
sudo ./demo

Note for OrangePi
Opi have only 1 SPI.
OPi-PC has SPI0 on pin 24.
OPi-ZERO has SPI1 on pin 24.

SPI bus speed for WiringPi

By default it uses 8MHz on all Rpi.
Can be changed at compile time.

  • -DSPI_SPEED16 : 16MHz on all Rpi.
  • -DSPI_SPEED32 : 32MHz on all Rpi.

SPI Bus speed comparison

8MHz 16MHz 32MHz
ColorBarTest 208 116 93
ArrowTest 389 296 239
LineTest 1800 1637 1560
CircleTest 1630 1481 1393
RoundRectTest 1633 1490 1412
DirectionTest 461 354 315
HorizontalTest 878 723 663
VerticalTest 909 769 702
FillRectTest 454 246 148
ColorTest 558 234 159
JPEGTest 6292 5862 5640
PNGTest 6439 5989 5803

Build using Software SPI of the WiringPi library

WiringPi library initializes GPIO in one of the following ways:

  • int wiringPiSetup (void);
  • int wiringPiSetupGpio (void);
  • int wiringPiSetupPhys (void);
  • int wiringPiSetupSys (void);

This project by default uses the wiringPiSetup() function to initialize GPIOs.
Then use the wiringPiSPISetup() function to initialize the SPI.
If you use it on a board other than the RPI board, you may need to change the WiringPi number.

#define D_C   0 // wPi IO00=Pin#11
#define RES   1 // wPi IO01=Pin#12
#define MOSI 12 // wPi IO12=Pin#19
#define SCLK 14 // wPi IO14=Pin#23
#define CS   10 // wPi IO10=Pin#24

If you want to initialize GPIO with wiringPiSetupGpio(), Use the -DGPIO compilation flag.
In this case, use the following GPIOs.

#define D_C  17 // BCM IO17=Pin#11
#define RES  18 // BCM IO18=Pin#12
#define MOSI 10 // BCM IO10=Pin#19
#define SCLK 11 // BCM IO11=Pin#23
#define CS   24 // BCM IO24=Pin#24
git clone https://github.com/nopnop2002/Raspberry-ili9340spi
cd Raspberry-ili9340spi
make lib
cc -o demo demo.c fontx.c ili9340.c jpeg.a png.a -lwiringPi -lm -pthread -DWPI -DSOFT_SPI
sudo ./demo

TFT resolution and GRAM offset

TFT resolution is set to tft.conf.

If your TFT doesn't use a memory from 0th address in GRAM, It use GRAM offset which set to tft.conf.

#width=128 height=128
width=240 height=320
#width=240 height=400

#If TFT have GRAM offset
#offsetx=2
#offsety=1

ili9340-11 ili9340-12 ili9340-13 ili9340-14 ili9340-15 ili9340-16 ili9340-17 ili9340-18 ili9340-19 ili9340-20 ili9340-21

JPEG File
ili9340-JPEG
PNG File
ili9340-PNG


From left to right:
2.8" 240x320 ILI9341
2.4" 240x320 ILI9341
2.2" 240x320 ILI9340

ILI9341-A ILI9341-B ILI9341-C


From left to right:
2.2" 240x320 ILI9340
1.44" 128x128 ST7735
1.44" 128x128 ILI9163C
1.8" 128x160 ST7735

ili9163-1


XPT2046 Touch Screen

There is a TFT equipped with XPT2046.
XPT2046-3

A library of XPT2046 Touch Screen is included in this library.
I ported from here.

There is a TFT equipped with HR2046.
XPT2046 and HR2046 are very similar. But HR2046 does not work properly.
XPT2046-2

Wirering

TFT Rpi
VCC -- 3.3V
GND -- GND
CS -- Pin#24(SPI CS0)
RES -- Pin#12 (*1)
D/C -- Pin#11 (*1)
MOSI -- Pin#19(SPI MOSI) (*2)
SCK -- Pin#23(SPI SCLK) (*2)
LED -- 3.3V
MISO -- N/C
T_CLK -- Pin#23(SPI SCLK) (*2)
T_CS -- Pin#26(SPI CE1)
T_DIN -- Pin#19(SPI MOSI) (*2)
T_OUT -- Pin#21(SPI MISO) (*2)
T_IRQ -- Pin#22 (*1)

(*1) You can change any pin.

(*2) SPI is shared by TFT and XPT2046.


cc -o xpt xpt.c xpt2046.c -lbcm2835   
sudo ./xpt

If you touch screen, point will show.

Touch-11


cc -o touch touch.c fontx.c ili9340.c xpt2046.c -lbcm2835 -lm -DBCM
sudo ./touch

If you touch area, number will show.

Touch-12