The purpose of this Post is to share it with colleagues and also for myself.
Sometimes I even go back to the forum to see something I did and forgot.
The project below is the fully functional code of the Elecrow 5" RGB 24Bits Display
Working with LVGL and Squareline Studio.
This manufacter use Display Driver ILI6122 e ILI5960
This full code:
5Inch_LVGL_Ok.zip (74.7 KB)
And
Partial code:
#include <Arduino_GFX_Library.h>
#include <lvgl.h>
#include "ui.h"
//Função de start do Barramento do Display (Verificar pinos junto com o projeto de Hardware) e parametros do display:
Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
40 /* DE */, 41 /* VSYNC */, 39 /* HSYNC */, 0 /* PCLK */,
45 /* R0 */, 48 /* R1 */, 47 /* R2 */, 21 /* R3 */, 14 /* R4 */,
5 /* G0 */, 6 /* G1 */, 7 /* G2 */, 15 /* G3 */, 16 /* G4 */, 4 /* G5 */,
8 /* B0 */, 3 /* B1 */, 46 /* B2 */, 9 /* B3 */, 1 /* B4 */,
0 /* hsync_polarity */, 210 /* hsync_front_porch */, 4 /* hsync_pulse_width */, 43 /* hsync_back_porch */,
0 /* vsync_polarity */, 22 /* vsync_front_porch */, 4 /* vsync_pulse_width */, 12 /* vsync_back_porch */,
0 /* pclk_active_neg */, 16000000 /* prefer_speed */);
Arduino_RGB_Display *gfx = new Arduino_RGB_Display(800 /* width */, 480 /* height */, rgbpanel);
#include "touch.h"
//Variaveis do LVGL
#define TFT_BL 2
//#define GFX_BL DF_GFX_BL // default backlight pin, you may replace DF_GFX_BL to actual backlight pin
static uint32_t screenWidth = 800;
static uint32_t screenHeight = 480;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *disp_draw_buf;
static lv_disp_drv_t disp_drv;
//Calibração Touch
uint16_t touchCalibration_x0 = 300, touchCalibration_x1 = 3600, touchCalibration_y0 = 300, touchCalibration_y1 = 3600;
uint8_t touchCalibration_rotate = 1, touchCalibration_invert_x = 2, touchCalibration_invert_y = 0;
void setup(){
Serial.begin(115200);
f_SetupDisplay();
ui_init();
}
void loop(){
lv_timer_handler();
}
f_SetupDisplay():
void f_SetupDisplay(){
gfx->begin();
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
lv_init();
touch_init();
screenWidth = gfx->width();
screenHeight = gfx->height();
disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * screenHeight / 4, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * screenHeight / 10);
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&indev_drv);
}
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p){
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
#if (LV_COLOR_16_SWAP != 0)
gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif
lv_disp_flush_ready(disp);
}
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data){
if (touch_has_signal()){
if (touch_touched()){
data->state = LV_INDEV_STATE_PR;
data->point.x = touch_last_x;
data->point.y = touch_last_y;
}else if (touch_released()){
data->state = LV_INDEV_STATE_REL;
}
}
else{
data->state = LV_INDEV_STATE_REL;
}
}
and Touch.h
/*******************************************************************************
* Touch libraries:
* FT6X36: https://github.com/strange-v/FT6X36.git
* GT911: https://github.com/TAMCTec/gt911-arduino.git
* XPT2046: https://github.com/PaulStoffregen/XPT2046_Touchscreen.git
******************************************************************************/
/* uncomment for FT6X36 */
// #define TOUCH_FT6X36
// #define TOUCH_FT6X36_SCL 38//19
// #define TOUCH_FT6X36_SDA 37//18
// #define TOUCH_FT6X36_INT 4//39
// #define TOUCH_SWAP_XY
// #define TOUCH_MAP_X1 800
// #define TOUCH_MAP_X2 0
// #define TOUCH_MAP_Y1 0
// #define TOUCH_MAP_Y2 480
/* uncomment for GT911 */
#define TOUCH_GT911
#define TOUCH_GT911_SCL 20//20
#define TOUCH_GT911_SDA 19//19
#define TOUCH_GT911_INT 10//-1
#define TOUCH_GT911_RST 11
//38
#define TOUCH_GT911_ROTATION ROTATION_NORMAL
#define TOUCH_MAP_X1 800//480
#define TOUCH_MAP_X2 0
#define TOUCH_MAP_Y1 480//272
#define TOUCH_MAP_Y2 0
/* uncomment for XPT2046 */
// #define TOUCH_XPT2046
// #define TOUCH_XPT2046_SCK 12
// #define TOUCH_XPT2046_MISO 13
// #define TOUCH_XPT2046_MOSI 11
// #define TOUCH_XPT2046_CS 38
// #define TOUCH_XPT2046_INT 36
// #define TOUCH_XPT2046_ROTATION 0
// #define TOUCH_MAP_X1 4000
// #define TOUCH_MAP_X2 100
// #define TOUCH_MAP_Y1 100
// #define TOUCH_MAP_Y2 4000
int touch_last_x = 0, touch_last_y = 0;
#if defined(TOUCH_FT6X36)
#include <Wire.h>
#include <FT6X36.h>
FT6X36 ts(&Wire, TOUCH_FT6X36_INT);
bool touch_touched_flag = true, touch_released_flag = true;
#elif defined(TOUCH_GT911)
#include <Wire.h>
#include <TAMC_GT911.h>
TAMC_GT911 ts = TAMC_GT911(TOUCH_GT911_SDA, TOUCH_GT911_SCL, TOUCH_GT911_INT, TOUCH_GT911_RST, max(TOUCH_MAP_X1, TOUCH_MAP_X2), max(TOUCH_MAP_Y1, TOUCH_MAP_Y2));
#elif defined(TOUCH_XPT2046)
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
XPT2046_Touchscreen ts(TOUCH_XPT2046_CS, TOUCH_XPT2046_INT);
#endif
#if defined(TOUCH_FT6X36)
void touch(TPoint p, TEvent e)
{
if (e != TEvent::Tap && e != TEvent::DragStart && e != TEvent::DragMove && e != TEvent::DragEnd)
{
return;
}
// translation logic depends on screen rotation
#if defined(TOUCH_SWAP_XY)
touch_last_x = map(p.y, TOUCH_MAP_X1, TOUCH_MAP_X2, 0, gfx->width());
touch_last_y = map(p.x, TOUCH_MAP_Y1, TOUCH_MAP_Y2, 0, gfx->height());
#else
touch_last_x = map(p.x, TOUCH_MAP_X1, TOUCH_MAP_X2, 0, gfx->width());
touch_last_y = map(p.y, TOUCH_MAP_Y1, TOUCH_MAP_Y2, 0, gfx->height());
#endif
switch (e)
{
case TEvent::Tap:
Serial.println("Tap");
touch_touched_flag = true;
touch_released_flag = true;
break;
case TEvent::DragStart:
Serial.println("DragStart");
touch_touched_flag = true;
break;
case TEvent::DragMove:
Serial.println("DragMove");
touch_touched_flag = true;
break;
case TEvent::DragEnd:
Serial.println("DragEnd");
touch_released_flag = true;
break;
default:
Serial.println("UNKNOWN");
break;
}
}
#endif
void touch_init()
{
#if defined(TOUCH_FT6X36)
Wire.begin(TOUCH_FT6X36_SDA, TOUCH_FT6X36_SCL);
ts.begin();
ts.registerTouchHandler(touch);
#elif defined(TOUCH_GT911)
Wire.begin(TOUCH_GT911_SDA, TOUCH_GT911_SCL);
ts.begin();
ts.setRotation(TOUCH_GT911_ROTATION);
#elif defined(TOUCH_XPT2046)
SPI.begin(TOUCH_XPT2046_SCK, TOUCH_XPT2046_MISO, TOUCH_XPT2046_MOSI, TOUCH_XPT2046_CS);
ts.begin();
ts.setRotation(TOUCH_XPT2046_ROTATION);
#endif
}
bool touch_has_signal()
{
#if defined(TOUCH_FT6X36)
ts.loop();
return touch_touched_flag || touch_released_flag;
#elif defined(TOUCH_GT911)
return true;
#elif defined(TOUCH_XPT2046)
return ts.tirqTouched();
#else
return false;
#endif
}
bool touch_touched()
{
#if defined(TOUCH_FT6X36)
if (touch_touched_flag)
{
touch_touched_flag = false;
return true;
}
else
{
return false;
}
#elif defined(TOUCH_GT911)
ts.read();
if (ts.isTouched)
{
#if defined(TOUCH_SWAP_XY)
touch_last_x = map(ts.points[0].y, TOUCH_MAP_X1, TOUCH_MAP_X2, 0, gfx->width() - 1);
touch_last_y = map(ts.points[0].x, TOUCH_MAP_Y1, TOUCH_MAP_Y2, 0, gfx->height() - 1);
#else
touch_last_x = map(ts.points[0].x, TOUCH_MAP_X1, TOUCH_MAP_X2, 0, gfx->width() - 1);
touch_last_y = map(ts.points[0].y, TOUCH_MAP_Y1, TOUCH_MAP_Y2, 0, gfx->height() - 1);
#endif
return true;
}
else
{
return false;
}
#elif defined(TOUCH_XPT2046)
if (ts.touched())
{
TS_Point p = ts.getPoint();
#if defined(TOUCH_SWAP_XY)
touch_last_x = map(p.y, TOUCH_MAP_X1, TOUCH_MAP_X2, 0, gfx->width() - 1);
touch_last_y = map(p.x, TOUCH_MAP_Y1, TOUCH_MAP_Y2, 0, gfx->height() - 1);
#else
touch_last_x = map(p.x, TOUCH_MAP_X1, TOUCH_MAP_X2, 0, gfx->width() - 1);
touch_last_y = map(p.y, TOUCH_MAP_Y1, TOUCH_MAP_Y2, 0, gfx->height() - 1);
#endif
return true;
}
else
{
return false;
}
#else
return false;
#endif
}
bool touch_released()
{
#if defined(TOUCH_FT6X36)
if (touch_released_flag)
{
touch_released_flag = false;
return true;
}
else
{
return false;
}
#elif defined(TOUCH_GT911)
return true;
#elif defined(TOUCH_XPT2046)
return true;
#else
return false;
#endif
}
The heart of the code is here:
This code is what makes the RGB display work, you need to know exactly the parameters of the display used. According to the manufacturer.
This part is the standard LVGL code.
Most often used with TFT