I need the help for using LVGL and ESP-IDF 5
There were many difficulties for me to make it work.
However, I managed to get it to work but the driver is not correct.
Does anyone know what it could be?
What am I doing wrong?
I will post the code, board and details
It works fine on the Arduino, look at the screen and the letters. Perfect screen.
Using the TFT_eSPI library
But in ESP IDF 5 it looks bad and ugly and with the colors changed, instead of blue it becomes green. What’s wrong?
Below is the code used with esp idf 5
Main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_lcd_ili9341.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_touch_xpt2046.h"
#include "lvgl.h"
#include "lcd.h"
#include "touch.h"
#include "f_test.h"
#include "ui.h"
#include "hardware.h"
#include "sdkconfig.h"
#define TAG "Main:"
void InitBacklight(void){
gpio_set_direction(CONFIG_LCD_BACKLIGHT, GPIO_MODE_OUTPUT);
gpio_set_level(CONFIG_LCD_BACKLIGHT, 1);
}
void lvUpdateTask(void *ptr){
while (true) {
vTaskDelay(pdMS_TO_TICKS(20));
if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)){
lv_task_handler();
printf(".");
xSemaphoreGive(xGuiSemaphore);
}
}
}
void ui_event_Screen(lv_event_t *e){
lv_event_code_t event_code = lv_event_get_code(e);
// GuiData_t *gd = (GuiData_t *)lv_event_get_user_data(e);
if (event_code == LV_EVENT_CLICKED){
ESP_LOGI(TAG, "clicked");
// lv_obj_t *object = lv_event_get_target(e);
// lv_obj_add_flag(object, LV_OBJ_FLAG_HIDDEN);
}
}
void app_main(void){
static lv_disp_drv_t disp_drv;
InitBacklight();
esp_lcd_panel_handle_t display = InitDisplay(&disp_drv);
esp_lcd_touch_handle_t touchpanel = InitTouchPanel();
xGuiSemaphore = xSemaphoreCreateMutex();
InitLVGL(display, touchpanel, &disp_drv);
ui_init();
xTaskCreatePinnedToCore(&lvUpdateTask, "lv_update", 8192, NULL, 6, &g_lvgl_task_handle, 1);
}
LCD.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_lcd_ili9341.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_touch_xpt2046.h"
#include "lvgl.h"
#include "lcd.h"
#include "hardware.h"
#include "sdkconfig.h"
#define CONFIG_LCD_HRES 240
#define CONFIG_LCD_VRES 320
#define CONFIG_LCD_BUF_SIZE (CONFIG_LCD_HRES * 90)
SemaphoreHandle_t xGuiSemaphore = NULL;
TaskHandle_t g_lvgl_task_handle = NULL;
void lvgl_acquire(void);
void lvgl_release(void);
static bool lvgl_notify_flush_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx){
lv_disp_drv_t *disp_driver = (lv_disp_drv_t *)user_ctx;
lv_disp_flush_ready(disp_driver);
return false;
}
esp_lcd_panel_handle_t InitDisplay(lv_disp_drv_t *disp_drv){
esp_lcd_panel_io_handle_t lcd_io_handle = NULL;
esp_lcd_panel_handle_t lcd_panel = NULL;
esp_lcd_panel_io_spi_config_t lcd_io_config = {
.cs_gpio_num = (gpio_num_t)CONFIG_LCD_CS,
.dc_gpio_num = CONFIG_LCD_DC,
.spi_mode = 0,
.pclk_hz = CONFIG_LCD_PIXEL_CLOCK_HZ,
.trans_queue_depth = 3,
.on_color_trans_done = lvgl_notify_flush_ready,
.user_ctx = disp_drv,
.lcd_cmd_bits = CONFIG_LCD_CMD_BITS,
.lcd_param_bits = CONFIG_LCD_PARAM_BITS,
.flags = { .dc_low_on_data = 0, .octal_mode = 0, .sio_mode = 0, .lsb_first = 0, .cs_high_active = 0 } };
const spi_bus_config_t lcd_spi_buscfg = {
.mosi_io_num = CONFIG_LCD_SPI_MOSI,
.miso_io_num = CONFIG_LCD_SPI_MISO,
.sclk_io_num = CONFIG_LCD_SPI_CLK,
.quadwp_io_num = GPIO_NUM_NC,
.quadhd_io_num = GPIO_NUM_NC,
.data4_io_num = GPIO_NUM_NC,
.data5_io_num = GPIO_NUM_NC,
.data6_io_num = GPIO_NUM_NC,
.data7_io_num = GPIO_NUM_NC,
.max_transfer_sz = CONFIG_LCD_BUF_SIZE * sizeof(uint16_t),
.flags = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO | SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_GPIO_PINS,
//.intr_flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM
};
const esp_lcd_panel_dev_config_t lcd_panel_devcfg
= {
.reset_gpio_num = GPIO_NUM_NC,
.rgb_endian = LCD_RGB_ENDIAN_RGB,
//.rgb_endian = LCD_RGB_ENDIAN_BGR,
.bits_per_pixel = 16,
.flags = {
.reset_active_high = 1 },
.vendor_config = NULL
};
ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_LCD_SPI, &lcd_spi_buscfg, SPI_DMA_CH_AUTO));
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)CONFIG_LCD_SPI, &lcd_io_config, &lcd_io_handle));
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9341(lcd_io_handle, &lcd_panel_devcfg, &lcd_panel));
ESP_ERROR_CHECK(esp_lcd_panel_reset(lcd_panel));
ESP_ERROR_CHECK(esp_lcd_panel_init(lcd_panel));
esp_lcd_panel_swap_xy(lcd_panel, false);
esp_lcd_panel_mirror(lcd_panel, true, false);
ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(lcd_panel, true));
return lcd_panel;
}
void lvgl_acquire(void){
TaskHandle_t task = xTaskGetCurrentTaskHandle();
if (g_lvgl_task_handle != task){
xSemaphoreTake(xGuiSemaphore, portMAX_DELAY);
}
}
void lvgl_release(void){
TaskHandle_t task = xTaskGetCurrentTaskHandle();
if (g_lvgl_task_handle != task){
xSemaphoreGive(xGuiSemaphore);
}
}
void lcd_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) {
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)drv->user_data;
int32_t offsetx1 = area->x1;
int32_t offsetx2 = area->x2;
int32_t offsety1 = area->y1;
int32_t offsety2 = area->y2;
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
lv_disp_flush_ready(drv);
}
static void lvgl_touch_cb(lv_indev_drv_t *drv, lv_indev_data_t *data){
uint16_t touchpad_x[1] = { 0 };
uint16_t touchpad_y[1] = { 0 };
uint8_t touchpad_cnt = 0;
esp_lcd_touch_read_data((esp_lcd_touch_handle_t)drv->user_data);
bool touchpad_pressed = esp_lcd_touch_get_coordinates((esp_lcd_touch_handle_t)drv->user_data, touchpad_x, touchpad_y, NULL, &touchpad_cnt, 1);
if (touchpad_pressed && touchpad_cnt > 0){
data->point.x = touchpad_x[0];
data->point.y = touchpad_y[0];
data->state = LV_INDEV_STATE_PRESSED;
}else{
data->state = LV_INDEV_STATE_RELEASED;
}
}
void InitLVGL(esp_lcd_panel_handle_t panel_handle, esp_lcd_touch_handle_t touch_handle, lv_disp_drv_t *disp_drv){
static lv_disp_draw_buf_t disp_buf;
lv_init();
static lv_color_t buf1[CONFIG_LCD_BUF_SIZE];
static lv_color_t buf2[CONFIG_LCD_BUF_SIZE];
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, CONFIG_LCD_BUF_SIZE);
lv_disp_drv_init(disp_drv);
disp_drv->hor_res = CONFIG_LCD_HRES;
disp_drv->ver_res = CONFIG_LCD_VRES;
disp_drv->flush_cb = lcd_lvgl_flush_cb;
disp_drv->draw_buf = &disp_buf;
disp_drv->user_data = panel_handle;
lv_disp_t *disp = lv_disp_drv_register(disp_drv);
static lv_indev_drv_t indev_drv; // Input device driver (Touch)
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.disp = disp;
indev_drv.read_cb = lvgl_touch_cb;
indev_drv.user_data = touch_handle;
lv_indev_drv_register(&indev_drv);
}
Hardware.h
#pragma once
//#define CONFIG_LCD_PIXEL_CLOCK_HZ (40 * 1000 * 1000)
#define CONFIG_LCD_PIXEL_CLOCK_HZ (80000000)
#define CONFIG_LCD_CMD_BITS (8)
#define CONFIG_LCD_PARAM_BITS (8)
#define CONFIG_LCD_SPI SPI2_HOST
#define CONFIG_LCD_BACKLIGHT (gpio_num_t) GPIO_NUM_27
#define CONFIG_LCD_SPI_CLK (gpio_num_t) GPIO_NUM_14
#define CONFIG_LCD_SPI_MOSI (gpio_num_t) GPIO_NUM_13
#define CONFIG_LCD_SPI_MISO (gpio_num_t) GPIO_NUM_12
#define CONFIG_LCD_DC (gpio_num_t) GPIO_NUM_2
#define CONFIG_LCD_CS (gpio_num_t) GPIO_NUM_15
#define CONFIG_LCD_RESET (gpio_num_t) GPIO_NUM_NC /* GPIO_NUM_4 */
#define CONFIG_LCD_BUSY (gpio_num_t) GPIO_NUM_NC /* GPIO_NUM_35 */
//#define CONFIG_TOUCH_CLOCK_HZ ESP_LCD_TOUCH_SPI_CLOCK_HZ
#define CONFIG_TOUCH_CLOCK_HZ 2500000
#define CONFIG_TOUCH_SPI SPI2_HOST
// #define CONFIG_TOUCH_SPI_CLK (gpio_num_t) GPIO_NUM_25
// #define CONFIG_TOUCH_SPI_MOSI (gpio_num_t) GPIO_NUM_32
// #define CONFIG_TOUCH_SPI_MISO (gpio_num_t) GPIO_NUM_39
#define CONFIG_TOUCH_CS (gpio_num_t) GPIO_NUM_33
#define CONFIG_TOUCH_DC (gpio_num_t) GPIO_NUM_NC
#define CONFIG_TOUCH_RST (gpio_num_t) GPIO_NUM_NC
#define CONFIG_TOUCH_IRQ (gpio_num_t) GPIO_NUM_36 /* GPIO_NUM_36 */
#define TOUCH_X_RES_MIN 17
#define TOUCH_X_RES_MAX 291
#define TOUCH_Y_RES_MIN 15
#define TOUCH_Y_RES_MAX 218
where am I going wrong?
What can I change?