display glitching on lv_task_handler() call issue
Posted: Tue Feb 06, 2024 9:30 pm
hello. There is problem eith my code
board ESP32S3 with PSRAM
lvgl 8.3.11
esp-idf 6.1.11
when i call lv_label_set_text(), on update lv_task_handler() glitch the screen
if i call lv_task_handler() once, screen is ok.
Looks like i call lv_task_handler() in wrongway but i havent found any examples, please help
here is code
board ESP32S3 with PSRAM
lvgl 8.3.11
esp-idf 6.1.11
when i call lv_label_set_text(), on update lv_task_handler() glitch the screen
if i call lv_task_handler() once, screen is ok.
Looks like i call lv_task_handler() in wrongway but i havent found any examples, please help
here is code
Code: Select all
//main.cpp
#include "freertos/FreeRTOS.h"
#include <freertos/task.h>
#include <lvgl.h>
#include "lcd.h"
#include "esp_timer.h"
#include "esp_freertos_hooks.h"
#include <ctime>
static time_t now;
static char strftime_buf[64];
static struct tm timeinfo;
static lv_obj_t *label;
extern "C" void inline tickhook(void){
lv_tick_inc(10);
}
extern "C" void inline lv_flusher(void)
{
lv_task_handler();
}
extern "C" void current_time(void){
time(&now);
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
lv_label_set_text( label, strftime_buf);
};
extern "C" void app_main() {
LCDInit();
esp_register_freertos_tick_hook(reinterpret_cast<esp_freertos_tick_cb_t>(reinterpret_cast<esp_err_t>(tickhook)));
label = lv_label_create( lv_scr_act() );
lv_label_set_text( label, "Hello world");
lv_obj_align( label, LV_ALIGN_CENTER, 0, 0 );
esp_timer_handle_t periodic_timer1;
const esp_timer_create_args_t periodic_timer_args1 = {
.callback = reinterpret_cast<esp_timer_cb_t>(&lv_flusher),
.name = "lv_flusher"
};
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args1, &periodic_timer1));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer1, 5000));
while (true){
vTaskDelay(100);
current_time();
}
}
//lcd.cpp
#include "lcd.h"
#include "esp_log.h"
#include "esp_err.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_rgb.h"
#include "driver/gpio.h"
#include "esp_heap_caps.h"
#include "lvgl.h"
#define TAG "display"
//#include "driver/spi_master.h"
//#include "driver/i2c.h"
//
//static SemaphoreHandle_t xGuiSemaphore = NULL;
//static TaskHandle_t g_lvgl_task_handle;
static void lcd_lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map)
{
auto panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
int offsetx1 = area->x1;
int offsetx2 = area->x2;
int offsety1 = area->y1;
int offsety2 = area->y2;
esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
lv_disp_flush_ready(drv);
}
esp_err_t LCDInit(void)
{
static lv_disp_draw_buf_t disp_buf; // contains internal graphic buffer(s) called draw buffer(s)
static lv_disp_drv_t disp_drv; // contains callback functions
static esp_lcd_panel_handle_t panel_handle = nullptr;
gpio_config_t bk_gpio_config = {
.pin_bit_mask = 1ULL << LCD_PIN_BK_LIGHT,
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
esp_lcd_rgb_panel_config_t panel_config = {
.clk_src = LCD_CLK_SRC_DEFAULT, // PLL_F160M
.timings = {
.pclk_hz = LCD_PIXEL_CLOCK_HZ,
.h_res = LCD_H_RES,
.v_res = LCD_V_RES,
.hsync_pulse_width = 4,
.hsync_back_porch = 8,
.hsync_front_porch = 8,
.vsync_pulse_width = 4,
.vsync_back_porch = 8,
.vsync_front_porch = 8,
.flags{
.hsync_idle_low = false,
.vsync_idle_low = false,
.de_idle_high = false,
.pclk_active_neg = true,
.pclk_idle_high = false
}
},
.data_width = 16,
.bits_per_pixel = 0,
.num_fbs = 2,
.bounce_buffer_size_px = 0, //4 * LCD_H_RES,
.sram_trans_align = 0,
.psram_trans_align = 64,
.hsync_gpio_num = LCD_PIN_HSYNC,
.vsync_gpio_num = LCD_PIN_VSYNC,
.de_gpio_num = LCD_PIN_DE,
.pclk_gpio_num = LCD_PIN_PCLK,
.disp_gpio_num = LCD_PIN_DISP_EN,
.data_gpio_nums = {
LCD_PIN_DATA0,
LCD_PIN_DATA1,
LCD_PIN_DATA2,
LCD_PIN_DATA3,
LCD_PIN_DATA4,
LCD_PIN_DATA5,
LCD_PIN_DATA6,
LCD_PIN_DATA7,
LCD_PIN_DATA8,
LCD_PIN_DATA9,
LCD_PIN_DATA10,
LCD_PIN_DATA11,
LCD_PIN_DATA12,
LCD_PIN_DATA13,
LCD_PIN_DATA14,
LCD_PIN_DATA15
},
.flags
{
.disp_active_low = 0,
.refresh_on_demand = 0,
.fb_in_psram = true,
.double_fb = true,
.no_fb = 0,
.bb_invalidate_cache = 0
}
};
ESP_LOGI(TAG, "Turn on LCD backlight");
ESP_ERROR_CHECK(gpio_config(&bk_gpio_config));
ESP_ERROR_CHECK(gpio_set_level(LCD_PIN_BK_LIGHT, 1));
ESP_LOGI(TAG, "Install RGB LCD panel driver");
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle));
#if SYNC
esp_lcd_rgb_panel_event_callbacks_t cbs = {
.on_vsync = example_on_vsync_event,
};
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(panel_handle, &cbs, &disp_drv));
#endif
ESP_LOGI(TAG, "Initialize RGB LCD panel");
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
ESP_LOGI(TAG, "Initialize LVGL library");
lv_init();
ESP_LOGI(TAG, "Allocate separate LVGL draw buffers from PSRAM");
void *buf1 = heap_caps_malloc(LCD_H_RES * LCD_V_RES, MALLOC_CAP_SPIRAM);
assert(buf1);
void *buf2 = heap_caps_malloc(LCD_H_RES * LCD_V_RES, MALLOC_CAP_SPIRAM);
assert(buf2);
//LCD_H_RES * 100 * sizeof(lv_color_t)
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, LCD_H_RES * LCD_V_RES);
ESP_LOGI(TAG, "Register display driver to LVGL");
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = LCD_H_RES;
disp_drv.ver_res = LCD_V_RES;
disp_drv.flush_cb = lcd_lvgl_flush_cb;
disp_drv.draw_buf = &disp_buf;
disp_drv.user_data = panel_handle;
lv_disp_drv_register(&disp_drv);
return ESP_OK;
}