LVGL screen shift on nvs_set

Ludos_vic
Posts: 3
Joined: Tue Apr 04, 2023 1:08 pm

LVGL screen shift on nvs_set

Postby Ludos_vic » Tue Apr 04, 2023 2:59 pm

Hi everyone,

I have strange issue using LVGL and NVS library.

I use:
ESP-IDF 5.0
LVGL 8.3.0
FreeRTOS
Board:
ESP32-S3 WROOM 1
I have a some Screens in LVGL and everithing go well (Display and Touchscreen)
but in a Screen where i save a value in NVS, with the code below, the Screen shift a bit, and
everytime I call nvs_set_ all Screens of the GUI have horizontal shifting (like scroll), only rebooting they go back to the right position

Code: Untitled.c Select all


nvs_handle_t my_handle;
esp_err_t err;
err = nvs_open("storage", NVS_READWRITE, &my_handle);
err = nvs_set_u16(my_handle, "screen_lum", val);
ESP_LOGI(TAG," NVS err:%d",err);
nvs_commit(my_handle);
nvs_close(my_handle);
Screen.png
Screen.png (13.35 KiB) Viewed 7046 times
Screen shifted.png
Screen shifted.png (107.62 KiB) Viewed 7046 times
No error returned.
I call the nvs_flash_init() on initialization phase, and reading from NVS with nvs_get_u16() doesn't cause any problems.

Anyone can give me suggestions?

Sprite
Espressif staff
Espressif staff
Posts: 10612
Joined: Thu Nov 26, 2015 4:08 am

Re: LVGL screen shift on nvs_set

Postby Sprite » Wed Apr 05, 2023 12:44 am

How do you initialize the screen?

Ludos_vic
Posts: 3
Joined: Tue Apr 04, 2023 1:08 pm

Re: LVGL screen shift on nvs_set

Postby Ludos_vic » Wed Apr 05, 2023 7:28 am

Notes:
the GUI task run on core 0, i try various StackDepth from 4000 to 120000
i call lv_tick_inc() from other task, not from timer callback, and this task run on core 1, but changing the core it's the same

Code: Untitled.c Select all


#define GUI_PERIOD				2
#define TICK_PERIOD 10
#define GUI_TASK_CORE 0
#define TICK_TASK_CORE 1
void app_main(void)
{
nvs_init();
xTaskCreatePinnedToCore(Gui_Task, "Gui_Task", 120096, NULL,10, &guiTaskHandle, GUI_TASK_CORE);
while (1) {
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

Code: Untitled.c Select all


void Gui_Task(void *arg)
{
static lv_disp_draw_buf_t disp_buf;
static lv_disp_drv_t disp_drv;

ESP_LOGI(TAG, "Create semaphores");
sem_vsync_end = xSemaphoreCreateBinary();
assert(sem_vsync_end);
sem_gui_ready = xSemaphoreCreateBinary();
assert(sem_gui_ready);

init_backlight_pwm();

ESP_LOGI(TAG, "Install RGB LCD panel driver");
esp_lcd_panel_handle_t panel_handle = NULL;
esp_lcd_rgb_panel_config_t panel_config = {
.data_width = 16, // RGB565 in parallel mode, thus 16bit in width
.psram_trans_align = 64,
.clk_src = LCD_CLK_SRC_DEFAULT,
.disp_gpio_num = PIN_NUM_DISP_EN,
.pclk_gpio_num = PIN_NUM_PCLK,
.vsync_gpio_num = PIN_NUM_VSYNC,
.hsync_gpio_num = PIN_NUM_HSYNC,
.de_gpio_num = PIN_NUM_DE,
.data_gpio_nums = {
PIN_NUM_DATA0,PIN_NUM_DATA1,PIN_NUM_DATA2,PIN_NUM_DATA3,PIN_NUM_DATA4,
PIN_NUM_DATA5,PIN_NUM_DATA6,PIN_NUM_DATA7,PIN_NUM_DATA8,PIN_NUM_DATA9,
PIN_NUM_DATA10,PIN_NUM_DATA11,PIN_NUM_DATA12,PIN_NUM_DATA13,PIN_NUM_DATA14,PIN_NUM_DATA15,
},
.timings = {
.pclk_hz = LCD_PIXEL_CLOCK_HZ,
.h_res = LCD_H_RES,
.v_res = LCD_V_RES,
.hsync_back_porch = HSYNC_BACK_PORCH,
.hsync_front_porch = HSYNC_FRONT_PORCH,
.hsync_pulse_width = HSYNC_PULSE_WIDTH,
.vsync_back_porch = VSYNC_BACK_PORCH,
.vsync_front_porch = VSYNC_FRONT_PORCH,
.vsync_pulse_width = VSYNC_PULSE_WIDTH,
.flags.pclk_active_neg = true,
},
.flags.fb_in_psram = true,
};
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle));

ESP_LOGI(TAG, "Register event callbacks");
esp_lcd_rgb_panel_event_callbacks_t cbs = {
.on_vsync = on_vsync_event,
};
ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(panel_handle, &cbs, &disp_drv));

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));

i2c_master_init();
esp_lcd_touch_config_t tp_cfg = {
.x_max =LCD_H_RES,
.y_max = LCD_V_RES,
.rst_gpio_num = TOUCH_GT911_RST,
.int_gpio_num = -1,
.flags = {
.swap_xy = 0,
.mirror_x = 0,
.mirror_y = 0,
},
};

esp_lcd_panel_io_handle_t tp_io_handle = NULL;
esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_NUM_0, &io_config, &tp_io_handle));
ESP_LOGI(TAG, "Initialize touch controller GT911");
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp));


ESP_LOGI(TAG, "Initialize LVGL library");
lv_init();
void *buf1 = NULL;
void *buf2 = NULL;
buf1 = heap_caps_malloc(LCD_H_RES * 100 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
assert(buf1);
buf2 = heap_caps_malloc(LCD_H_RES * 100 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
assert(buf2);
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, LCD_H_RES * 100);

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 = 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);

/**** Init Touchpad GT911 **********/

static lv_indev_drv_t indev_drv;
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 = tp;

lv_indev_drv_register(&indev_drv);

ui_init();

xTaskCreatePinnedToCore(Tick_Task, "Tick_Task", 4096, NULL,1, &tickTaskHandle, TICK_TASK_CORE);

while(1){
lv_timer_handler();
vTaskDelay(GUI_PERIOD);
}
}

Code: Untitled.c Select all


void nvs_init(){
esp_err_t err = nvs_flash_init();
//err = nvs_flash_init_partition("storage");
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// NVS partition was truncated and needs to be erased
// Retry nvs_flash_init
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
ESP_LOGI(TAG, "NVS Init error:%d",err);
}
ESP_ERROR_CHECK( err );/* esp_err_t*/
ESP_LOGI(TAG, "NVS Error: %d",err);
ESP_LOGI(TAG, "NVS Initialized");
}

Code: Untitled.c Select all

void Tick_Task(void *arg)
{
while(1){
lv_tick_inc(30);
vTaskDelay(TICK_PERIOD);
}
}

Sprite
Espressif staff
Espressif staff
Posts: 10612
Joined: Thu Nov 26, 2015 4:08 am

Re: LVGL screen shift on nvs_set

Postby Sprite » Fri Apr 07, 2023 12:52 am

Looks like your framebuffer and DMA somehow get de-synced somehow. Can you try adding '.bounce_buffer_size_px=LCD_H_RES*8' to your panel_config and see if that helps?

Ludos_vic
Posts: 3
Joined: Tue Apr 04, 2023 1:08 pm

Re: LVGL screen shift on nvs_set

Postby Ludos_vic » Tue Apr 11, 2023 6:52 pm

trying with .bouce_buffer_size_px = 8 * LCD_H_RES the screen drift vertical but more sporadically but your suggestion help my to find the right way...in fact it is a synchronization problem

I finally solved it with this combination:

.bounce_buffer_size_px = 20 * LCD_H_RES,

reduce the size of buffer in the PSRAM and don't use the second buffer

buf1 = heap_caps_malloc(LCD_H_RES * 100 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
assert(buf1);
/*buf2 = heap_caps_malloc(LCD_H_RES * 100 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
assert(buf2);*/
// initialize LVGL draw buffers
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, LCD_H_RES * 100);

and this in sdkconfig

CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
CONFIG_SPIRAM_RODATA=y
CONFIG_LCD_RGB_RESTART_IN_VSYNC=y

The only problem is that when the screen goes out of sync and is re-synchronized due to CONFIG_LCD_RGB_RESTART_IN_VSYNC, the Screen have a little flash, but with this combination of settings the event is very sporadic, and I think it's an acceptable solution

this link also helped me
https://espressif-docs.readthedocs-host ... s/lcd.html

TasosVL
Posts: 1
Joined: Tue Dec 09, 2025 10:01 pm

Re: LVGL screen shift on nvs_set

Postby TasosVL » Tue Dec 09, 2025 10:56 pm

Hi, i am facing the same issue but its random, maybe 1 in 10 times when writing to NVS. I am using a 480x800 panel at 14MHz with the waveshare_rgb_lcd_port library. I have tried using esp_lcd_panel_disp_off to pause the panel before writing to NVS but i am getting error that is function is not supported by this panel. Also i tried esp_lcd_rgb_panel_restart after writing to NVS but its not supported either.
When using the CONFIG_LCD_RGB_RESTART_IN_VSYNC the panel is always shifted to the right and when writing to NVS sometimes i get random lines-glitches in the screen which they never leave.
I am using double buffers with bounce buffer of 10px and LVGL full refresh.
Any suggestions?

Who is online

Users browsing this forum: Applebot, Bing [Bot], ChatGPT-User, Google [Bot] and 2 guests