Hi,
I’ve got problem with display anything on display and got stuck totally. I’m trying to run display on esp32 with lvgl 8.3.4 and lvgl_esp32_drivers from master branch but after initialization I get only flickering white/black screen with no image (its looks like the white screen is flickering with display refreshrate). I did not have any errors.
Description
What MCU/Processor/Board and compiler are you using?
esp32 wrover with espidf 4.4.3
What do you want to achieve?
Proper display initialization
What have you tried so far?
Code to reproduce
display.c
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_freertos_hooks.h"
#include "freertos/event_groups.h"
#include "display.h"
#include "../lvgl_tft/disp_driver.h"
#include "../lvgl_helpers.h"
#include "sdkconfig.h"
static struct display_ctx disp_ctx =
{
.backlight = NULL,
.disp = NULL,
.indev = NULL,
.is_valid = false
};
static lv_disp_draw_buf_t draw_buf;
static lv_disp_drv_t disp_drv;
static lv_color_t buf_1[320 * 10];
disp_backlight_config_t backlight_config;
disp_backlight_h backlight_h = NULL;
static lv_indev_drv_t indev_drv;
lv_indev_t* indev = NULL;
lv_disp_t* disp = NULL;
static const char *TAG = "Display";
void display_task(void* param)
{
ESP_LOGI(TAG, "Display task created");
for(;;)
{
lv_task_handler();
vTaskDelay(10 / portTICK_RATE_MS);
}
}
void IRAM_ATTR lv_tick_task(void)
{
lv_tick_inc(portTICK_RATE_MS);
}
lv_disp_t* init_display()
{
lv_init();
lvgl_driver_init();
lv_disp_draw_buf_init(&draw_buf, buf_1, NULL, LV_HOR_RES*10);
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = LV_HOR_RES;
disp_drv.ver_res = LV_VER_RES;
disp_drv.draw_buf = &draw_buf;
disp_drv.flush_cb = disp_driver_flush;
disp = lv_disp_drv_register(&disp_drv);
if(disp == NULL)
{
ESP_LOGE(TAG, "CANNOT LOAD DISPLAY DRIVER");
disp_ctx.is_valid = false;
return NULL;
}
esp_register_freertos_tick_hook(lv_tick_task);
lv_tick_inc(portTICK_RATE_MS);
xTaskCreate(display_task, "DisplayTask", 4096, NULL, 1, NULL);
disp_ctx.is_valid = true;
ESP_LOGI(TAG, "Display created");
return disp;
}
disp_backlight_h* init_backlight()
{
ESP_LOGI(TAG, "Initializing backlight");
backlight_config.gpio_num = CONFIG_LV_DISP_PIN_BCKL;
backlight_config.pwm_control = true;
backlight_config.channel_idx = 0;
backlight_config.timer_idx = 0;
backlight_h = disp_backlight_new(&backlight_config);
if(backlight_h == NULL)
{
ESP_LOGE(TAG, "Cannot init baclight");
disp_ctx.is_valid = false;
return NULL;
}
ESP_LOGI(TAG, "Backlight initialized");
disp_ctx.is_valid = true;
return &backlight_h;
}
void set_backlight(int percentage)
{
disp_backlight_set(backlight_h, percentage);
}
lv_indev_t* init_indev()
{
ESP_LOGI(TAG, "Creating indev");
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = touch_driver_read;
indev = lv_indev_drv_register(&indev_drv);
if(indev == NULL)
{
ESP_LOGE(TAG, "Cannot register indev driver");
disp_ctx.is_valid = false;
return NULL;
}
ESP_LOGI(TAG, "Indev created");
disp_ctx.is_valid = true;
return indev;
}
display_ctx* create_display_ctx()
{
ESP_LOGI(TAG, "Creating display context");
disp_ctx.disp = init_display();
disp_ctx.backlight = init_backlight();
disp_ctx.indev = init_indev();
if(!disp_ctx.is_valid || disp_ctx.disp == NULL ||
disp_ctx.backlight == NULL || disp_ctx.indev == NULL)
{
ESP_LOGE(TAG, "Cannot create display context");
return NULL;
}
ESP_LOGI(TAG, "Display context created");
return &disp_ctx;
}
esp_err_t dispose(display_ctx** ctx)
{
ESP_LOGI(TAG, "Disposing ");
*ctx = NULL;
disp_ctx.is_valid = false;
disp_ctx.disp = NULL;
disp_ctx.indev = NULL;
disp_ctx.backlight = NULL;
disp_backlight_delete(backlight_h);
lv_indev_delete(indev);
lv_disp_remove(disp);
disp = NULL;
indev = NULL;
return ESP_OK;
}
display.h
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
#include "esp_log.h"
#include "esp_err.h"
#include "lvgl.h"
#include "esp_lcd_backlight.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct display_ctx
{
bool is_valid; // should be allways checked and modified
lv_disp_t* disp;
lv_indev_t* indev;
disp_backlight_h* backlight;
} display_ctx;
// Creating display context is recommended for create diaplay
display_ctx* create_display_ctx();
lv_disp_t* init_display();
lv_indev_t* init_indev();
disp_backlight_h* init_backlight();
void set_backlight(int percentage);
esp_err_t dispose(display_ctx** ctx);
#ifdef __cplusplus
}
#endif
#endif
Logs from serial port:
I (4640) Display: Creating display context
I (4640) lvgl_helpers: Display buffer size: 0
I (4650) lvgl_helpers: Initializing SPI master for display
I (4660) lvgl_helpers: Configuring SPI host SPI2_HOST
I (4660) lvgl_helpers: MISO pin: -1, MOSI pin: 23, SCLK pin: 18, IO2/WP pin: -1, IO3/HD pin: -1
I (4670) lvgl_helpers: Max transfer size: 0 (bytes)
I (4680) lvgl_helpers: Initializing SPI bus…
I (4680) disp_spi: Adding SPI device
I (4690) disp_spi: Clock speed: 40000000Hz, mode: 0, CS pin: 5
I (4890) ILI9341: Initialization.
I (5090) ILI9341: Display orientation: LANDSCAPE
I (5090) ILI9341: 0x36 command value: 0x28
I (5090) disp_backlight: Setting LCD backlight: 100%
I (5090) lvgl_helpers: Initializing SPI master for touch
I (5100) lvgl_helpers: Configuring SPI host SPI3_HOST
I (5100) lvgl_helpers: MISO pin: 12, MOSI pin: 13, SCLK pin: 14, IO2/WP pin: -1, IO3/HD pin: -1
I (5110) lvgl_helpers: Max transfer size: 0 (bytes)
I (5120) lvgl_helpers: Initializing SPI bus…
I (5120) XPT2046: XPT2046 Initialization
I (5130) gpio: GPIO[26]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (5140) Display: Display task created
I (5140) Display: Display created
I (5150) Display: Initializing backlight
I (5150) Display: Backlight initialized
I (5150) Display: Creating indev
I (5160) Display: Indev created
I (5160) Display: Display context created
I (5170) disp_backlight: Setting LCD backlight: 100%
Can somebody tell me where I did mistake?