Skip to content

8bit parallel TFT & 4-line resistance touch screen Driver for esp-idf using i2s paralell mode

License

Notifications You must be signed in to change notification settings

nopnop2002/esp-idf-parallel-tft

Repository files navigation

esp-idf-parallel-tft

8 bit parallel TFT & 4-line resistance touch screen Driver for esp-idf.
You can use such a TFT-Shield with esp32.

TFT-Shield

Support driver

Generic Shield

  • ILI9225
  • ILI9226(Same as ILI9225)
  • ILI9320
  • ILI9325
  • ILI9341
  • ILI9342
  • ILI9481
  • ILI9486
  • ILI9488
  • SPFD5408(Same as ILI9320)
  • R61505U(Same as ILI9320)
  • R61509V
  • LGDP4532
  • ST7775(Same as ILI9225)
  • ST7781
  • ST7783(Same as ST7781)
  • ST7793(Same as R61509)
  • ST7796(Same as ILI9486)
  • HX8347A(*2)
  • HX8347D(Almost the same as HX8347A)(*2)
  • HX8347G(Same as HX8347D)(*2)
  • HX8347I(Same as HX8347D)(*2)

OPEN-SMART Products

  • OPEN-SMART ILI9225 TFT-Shield(176x220)(*5)
  • OPEN-SMART ILI9327 TFT-Shield(240x400)(*3)(*5)
  • OPEN-SMART ILI9340 TFT-Shield(240x320)(*5)
  • OPEN-SMART S6D1121 16Pin-Parallel(240x320)(*1)(*5)
  • OPEN-SMART ST7775 16Pin-Parallel(176x220 Same as ILI9225)(*1)(*5)
  • OPEN-SMART ST7783 16Pin-Parallel(240x320)(*1)(*5)
  • OPEN-SMART R61509V 16Pin-Parallel(240x400)(*1)(*5)
  • OPEN-SMART ILI9488 16Pin-Parallel(320x400 Color inversion)(*1)(*4)(*5)

(*1)
I2S parallel does not work.
I don't know why.
GPIO parallel or REGISTER I/O parallel works.
LED pins connect to GND instead of 3.3V.

(*2)
Very Slow.
Most drivers require three commands to display one Pixel.
This driver require 9 commands to display one Pixel.
For some reason, the color of 0xFFFF does not appear.

(*3)
It has a GRAM offset.
See below.

(*4)
Need RGB inverstion.

(*5)
4-line resistance touch screen available.
See below.

These are all 2.4 inch, 320x240 TFTs. TFT-SHIELD-2

3.95 inches is almost twice as large as 2.4 inches. TFT-SHIELD-3

These are OPEN-SMART 16Pin-Parallel Products. OPEN-SMART-16Pin

These are OPEN-SMART TFT-Shield Products. OPEN-SMART-Shield

Software requirements

ESP-IDF V5.0 or later.
ESP-IDF V4.4 release branch reached EOL in July 2024.

Note for ESP-IDF V5.x
ESP-IDF V5.x gives this warning, but work.

#warning "legacy adc driver is deprecated, please migrate to use esp_adc/adc_oneshot.h and esp_adc/adc_continuous.h for oneshot mode and continuous mode drivers respectively"

Installation

git clone https://github.com/nopnop2002/esp-idf-parallel-tft
cd esp-idf-parallel-tft/
idf.py set-target {esp32/esp32s2/esp32s3}
idf.py menuconfig
idf.py flash

Note for ESP32-S2
The tjpgd library is not present in ESP32-S2 ROM.
With ESP-IDF Ver5, the JPEG decode library is now provided from the IDF Component Registry, and the JPEG decode library is now available for ESP32-S2.
However, since the SRAM is small, a large image cannot be displayed.
With ESP-IDF Ver4.4, you cannot be displayed JPEG files because the IDF Component Registry cannot be used.
Due to the small SRAM capacity, there is a possibility that an error may occur when displaying PNG files.
You can avoid this error by enabling PSRAM.

Configuration

You have to set this config value with menuconfig.

  • CONFIG_DRIVER

    The information provided by sellers on Ebay or AliExpress is largely incorrect.
    You waste time if you don't choose the right driver.
    There are many variations of the 2.4 inch shield.
    You can use this to find out your driver.
    This is for Arduino UNO.
    Do not use this on the ESP32 as the GPIO on the ESP32 is not 5V tolerant.
    Never believe the seller's information.
    I'll say it again.
    Never believe the seller's information.
  • CONFIG_INTERFACE
    Most drivers work using I2S parallel.
    However, some drivers only work using GPIO parallels or REGISTER I/O parallels.
    I2S parallel is the fastest when drawing to consecutive addresses.
    However, REGISTER I/O parallel is the fastest when drawing to non-contiguous addresses.
    When using REGISTER I/O parallel, GPIO from D0 to D7 is 1 to 31.(GPIO0 is boot mode pin)
    I2S parallel is suitable for image-intensive applications.
    REGISTER I/O parallel is suitable for character-intensive applications.
    GPIO parallel is most slow.
  • CONFIG_WIDTH
  • CONFIG_HEIGHT
    Specifies the resolution of the TFT.
  • CONFIG_OFFSETX
  • CONFIG_OFFSETY
    You can specify the GRAM offset.
    You must specify Y offset = 32 for OPEN-SMART-ILI9327.
  • CONFIG_INVERSION
    For some TFTs, the BGR may be inverted.
    Specify if the colors are inverted.

config-menu

config-app1

config-app2

config-app4

Wireing

TFT ESP32 ESP32S2/S3
LDC_RST -- GPIO32 GPIO45 *1
LDC_CS -- GPIO33 GPIO42 *1
LDC_RS -- GPIO15 GPIO41 *1
LDC_WR -- GPIO4 GPIO40 *1
LDC_RD -- GPIO2 GPIO39 *1
LDC_D0 -- GPIO12 GPIO1 *1 *2
LDC_D1 -- GPIO13 GPIO2 *1 *2
LDC_D2 -- GPIO26 GPIO3 *1 *2
LDC_D3 -- GPIO25 GPIO4 *1 *2
LDC_D4 -- GPIO17 GPIO5 *1 *2
LDC_D5 -- GPIO16 GPIO6 *1 *2
LDC_D6 -- GPIO27 GPIO7 *1 *2
LDC_D7 -- GPIO14 GPIO8 *1 *2
5V -- 5V 5V *3
3.3V -- 3.3V 3.3V *3
GND -- GND GND

(*1)
You can change any GPIO using menuconfig.

config-app3

(*2)
When using REGISTER I/O parallel, GPIO from D0 to D7 is 1 to 31.(GPIO0 is boot mode pin)

(*3)
With a regulator (mostly AMS1117) is on the back, the supply voltage is 5V.
With a regulator is NOT on the back, the supply voltage is 3.3V.

Back

Note
My R61509V has a regulator on the back.
Normally, a TFT with a regulator works at 5V, but my R61509V doesn't work unless I supply both 5V and 3.3V.

Note
ESP32 development board cannot supply too much current.
It is more stable when supplied from an external power source.

All

Circuit

Graphic support

Graphic1 Graphic2 Graphic3 Graphic4 Graphic5 Graphic6 Graphic7 Graphic8

Fonts support

Font1 It's possible to text rotation and invert.
Font2 Font3 Font4 You can specify multiple fonts at the same time.
Font5

Image support

BMP file
Image1 JPEG file
Image2 PNG file
Image3

Using Wemos D1 ESP32

I bought this for $4.
WeMos-R32-11

To attach the TFT-Shield, you need to do changed some pin assignments like this.
Because GPIO34/35/36/39 are READ ONLY.
WeMos-R32-1

WeMos-R32-12

With this change, GPIO will look like this:
WeMos-R32-2

WeMos-R32-3

WeMos-R32-4

It's great because it doesn't require any wiring.
WeMos-R32-13

If you use OPEN-SMART TFT-Shield Products, you must use custom GPIO.
WeMos-R32-OpenSmart

Using TZT D1 ESP32-S3

I bought this for $5.
tzt-d1-esp32s3

You can attach the TFT-Shield without changing anything.
But I2S parallel doesn't work. I don't know why.
tzt-d1-esp32s3-Generic tzt-d1-esp32s3-Open-Smart

If you use TZT D1 ESP32-S3, you must use custom GPIO.
config-esp32s3-generic

JPEG Decoder

The ESP-IDF component includes Tiny JPEG Decompressor.
The document of Tiny JPEG Decompressor is here.
This can reduce the image to 1/2 1/4 1/8.

PNG Decoder

The ESP-IDF component includes part of the miniz library, such as mz_crc32.
But it doesn't support all of the miniz.
The document of miniz library is here.

And I ported the pngle library from here.
This can reduce the image to any size.

Font File

This project uses the following as default fonts:

  • font/ILGH16XB.FNT // 8x16Dot Gothic
  • font/ILGH24XB.FNT // 12x24Dot Gothic
  • font/ILGH32XB.FNT // 16x32Dot Gothic
  • font/ILMH16XB.FNT // 8x16Dot Mincyo
  • font/ILMH24XB.FNT // 12x24Dot Mincyo
  • font/ILMH32XB.FNT // 16x32Dot Mincyo

From 0x00 to 0x7f, the characters image of Alphanumeric are stored.
From 0x80 to 0xff, the characters image of Japanese are stored.
Changing this file will change the font.

You can add your original fonts.
The format of the font file is the FONTX format.
Your font file is put in font directory.
Your font file is uploaded to SPIFFS partition using meke flash.

Please refer this page about FONTX format.

Font File Editor(FONTX Editor)

There is a font file editor.
This can be done on Windows 10.
Developer page is here.

fontx-editor-1

Convert from BDF font to FONTX font

step1)
download fontxedit.exe.

step2)
download BDF font file from Internet.
I downloaded from here.
fontxedit.exe can ONLY import Monospaced bitmap fonts file.
Monospaced bitmap fonts can also be downloaded here.

step3)
import the BDF font file into your fontxedit.exe.
this tool can convert from BDF to FONTX.
fontx-editor-2

step4)
adjust font size.
fontx-editor-3

step5)
check font pattern.
when you have made any changes, press the apply button.
fontx-editor-4

step6)
save as .fnt file from your fontedit.exe.
fontx-editor-5

step7)
upload your font file to $HOME/esp-idf-ili9340/font directory.

step8)
add font to use

FontxFile fx32L[2];
InitFontx(fx32L,"/spiffs/LATIN32B.FNT",""); // 16x32Dot LATIN

Font file that From 0x00 to 0x7f, the characters image of Standard ASCII are stored.
AsciiCode-1

Font file that From 0x80 to 0xff, the characters image of Japanese are stored.
AsciiCode-2

Font file that From 0x80 to 0xff, the characters image of Latin are stored.
AsciiCode-3

u8g2 library contains many BDF fonts.
This was converted from emoticons21.bdf.
bdf-font-1

This was converted from Scroll-o-Sprites.bdf.
bdf-font-2

Convert from TTF font to FONTX font

step1)
Download WFONTX64.exe from here. Developer page is here.

step2)
Select ttf font.
WFONTX64-1

step3)
Enter Height, Width, FontX2 name.
Specify half of Height for Width.
Specify your favorite font name in the FontX2 name field using up to 8 characters.
WFONTX64-2

step4)
Specify the file name to save.
WFONTX64-3

step5)
Specify the font style as required.
WFONTX64-4

step6)
Press the RUN button to convert TTF fonts to FONTX format.
WFONTX64-5

step7)
upload your font file to $HOME/esp-idf-ili9340/font directory.

step8)
add font to use

    FontxFile fx16G[2];
    FontxFile fx24G[2];
    FontxFile fx32G[2];
    //InitFontx(fx16G,"/spiffs/ILGH16XB.FNT",""); // 8x16Dot Gothic
    //InitFontx(fx24G,"/spiffs/ILGH24XB.FNT",""); // 12x24Dot Gothic
    //InitFontx(fx32G,"/spiffs/ILGH32XB.FNT",""); // 16x32Dot Gothic
    InitFontx(fx16G,"/spiffs/Gigi16.FNT",""); // 8x16Dot Gigi
    InitFontx(fx24G,"/spiffs/Gigi24.FNT",""); // 12x24Dot Gigi
    InitFontx(fx32G,"/spiffs/Gigi32.FNT",""); // 16x32Dot Gigi

tft_font


4-line resistance touch screen

Some TFT has 4-line resistance touch screen.
The 4-line resistor touch screen uses 4 pins.

  • X(+):Digital Output
  • X(-):Digital Output/Analog Input
  • Y(+):Digital Output/Analog Input
  • Y(-):Digital Output

When using GPIO Parallel Interface or REGISTER Parallel Interface, you can enable 4-line resistance touch screen using menuconfig.

ESP-IDF cannot simultaneous both digital output and analog input using a single gpio.
Two GPIOs are required for simultaneous digital output and analog input.
(X-) and ESP32 are connected with two wires.
(Y+) and ESP32 are connected with two wires.

(X-) ----+---- Gpio for Digital Output(Using GPIO number)
         +---- Gpio for Analog Input(Using ADC1 Channel number)

(Y+) ----+---- Gpio for Digital Output(Using GPIO number)
         +---- Gpio for Analog Input(Using ADC1 Channel number)

Configuration for touch screen

config-touch-1

  • ADC Channel
    When reading analog values, ESP-IDF can use ADC1 and ADC2.
    This project use ADC1 to read analog value.
    ESP32 has 8 channels: GPIO32 - GPIO39.
    ESP32S2/S3 has 10 channels: GPIO01 - GPIO10.
    Refer to the ESP32 data sheet for the relationship between ADC channels and GPIOs.
    When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.
TFT ADC1 ESP32 ESP32S2/S3
LCD-WR(Y+) Channel#6 GPIO34 GPIO07
LCD-RS(X-) Channel#7 GPIO35 GPIO08
  • GPIO number
    It uses four GPIOs, but the GPIOs differ depending on the TFT model.

config-touch-2

  • Save calibration data to NVS
    Write calibration data to NVS.
    Read calibration data from NVS when starting the firmware and use it.
    If you use the same TFT, you don't need to calibrate again.
    To clear the calibration data recorded in NVS, execute the following command.
idf.py erase_flash

OPEN-SMART 16Pin-Parallel Products

X(+) X(-) Y(+) Y(-)
LCD_D6 LCD_RS LCD_WR LCD_D7

Touch0

OPEN-SMART TFT-Shield Products

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D6 LCD_RS LCD_WR LCD_D7

Touch-OpenSmart-Sheild-1

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2/S3
LCD_WR(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

4-line resistance touch screen cannot be used with the Wemos D1 ESP32.
Because the combination of GPIO and ADC does not match.

ELEGOO TFT-Shield Products

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D0 LCD_RS LCD_CS LCD_D1

Touch-Elegoo-1

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2/S3
LCD_CS(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

No additional wiring is required when using the Wemos D1 ESP32.
LCD_CS is assigned to ADC1_6 and LCD_RS is assigned to ADC1_7.

ILI9341 2.4inch TFT-Shield with Yellow Pin-header

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D0 LCD_RS LCD_CS LCD_D1

Touch-ILI9341-1

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2/S3
LCD_CS(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

No additional wiring is required when using the Wemos D1 ESP32.
LCD_CS is assigned to ADC1_6 and LCD_RS is assigned to ADC1_7.

ILI9486 3.5inch TFT-Shield

There is no marking about 4-line resistance touch screen.
But 4-line resistance touch screen available.

X(+) X(-) Y(+) Y(-)
LCD_D6 LCD_RS LCD_WR LCD_D7

Touch-ILI9486-1

When using ADC1_6(ADC1 Channel#6) and ADC1_7(ADC1 Channel#7), the following wiring is additionally required.

TFT ESP32 ESP32S2/S3
LCD_WR(Y+) ADC1_6(GPIO34) ADC1_6(GPIO07)
LCD_RS(X-) ADC1_7(GPIO35) ADC1_7(GPIO08)

4-line resistance touch screen cannot be used with the Wemos D1 ESP32.
Because the combination of GPIO and ADC does not match.

Other TFT

I don't know which pin is X(+), X(-), Y(+), Y(-).
If you find, please tell me.

Calibrating the touch screen

Keep touching the corner point.
TouchCalib-1 TouchCalib-2

Draw with touch

If there is no touch for 10 seconds, it will end.
Touch-OpenSmat-16pin Touch-OpenSmart-Shield-2 Touch-Elegoo-2 Touch-ILI9341-2 Touch-ILI9486-2

Button with touch

You can only enter up to 15 characters.
If there is no touch for 10 seconds, it will end.
Touch-Keyboard

Move with touch

If there is no touch for 10 seconds, it will end.
Touch-Move-1 Touch-Move-2

Menu with Touch

If there is no touch for 10 seconds, it will end.
Touch-Menu-1 Touch-Menu-2

Select image with touch

If there is no touch for 10 seconds, it will end.
I borrowed the icon from here.
Touch-Icon-1 Touch-Icon-2

How dose it works

https://www.sparkfun.com/datasheets/LCD/HOW%20DOES%20IT%20WORK.pdf

Application layer

LibraryLayer

Performance comparison using ILI9488(320x480)

I2S parallel is not always faster.
Depending on the application, REGISTER I/O parallel may be faster.
Compiling with the O2 option doesn't help much.
The unit of the number is the required time in milliseconds.
A smaller value indicates faster speed.

Test GPIO parallel REGISTER I/O parallel I2S parallel I2S parallel(O2)
AddressTest 820 280 40 30
FillTest 3900 2370 1620 1590
ColorBarTest 810 290 60 40
ArrowTest 860 300 160 140
LineTest 2060 860 3150 2900
CircleTest 1950 830 2840 2610
RoundRectTest 1970 820 2930 2690
RectAngleTest 2810 1340 5180 4880
TriangleTest 2960 1530 6090 5640
DirectionTest 900 330 250 230
HorizontalTest 1110 430 610 550
VerticalTest 1110 430 610 550
FillRectTest 1300 590 200 140
ColorTest 1660 650 220 180
BMPTest 7280 6500 6130 5790
JPEGTest 1210 490 170 140
PNGTest 1480 750 440 1010

graph

Performance comparison using ILI9341(240x320)

SPI used this.

Test SPI GPIO parallel REGISTER I/O parallel I2S parallel
FillTest 1620 2700 1920 1560
ColorBarTest 80 410 150 30
ArrowTest 250 450 160 140
LineTest 2770 1030 430 1570
CircleTest 2470 970 410 1410
RoundRectTest 2510 970 400 1430
RectAngleTest 5990 2000 940 4050
TriangleTest 6950 2110 990 4740
DirectionTest 420 500 190 240
HorizontalTest 1030 710 290 590
VerticalTest 1010 710 290 590
FillRectTest 170 710 340 120
ColorTest 250 850 340 150
BMPTest 7470 6880 6360 6120
JPEGTest 2530 800 350 150
PNGTest 2800 1070 610 420

Reference about I2S driver

https://github.com/espressif/esp-iot-solution/tree/master/components/bus

  • for esp32
    i2s_lcd_esp32_driver.c
  • for esp32s2
    i2s_lcd_esp32s2_driver.c
  • for esp32s3
    8080_lcd_esp32s3.c
  • Common header
    i2s_lcd_driver.h