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

  1. nvs_handle_t my_handle;
  2. esp_err_t err;
  3. err = nvs_open("storage", NVS_READWRITE, &my_handle);
  4. err = nvs_set_u16(my_handle, "screen_lum", val);
  5. ESP_LOGI(TAG," NVS err:%d",err);
  6. nvs_commit(my_handle);
  7. nvs_close(my_handle);
Screen.png
Screen.png (13.35 KiB) Viewed 3126 times
Screen shifted.png
Screen shifted.png (107.62 KiB) Viewed 3126 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?

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: LVGL screen shift on nvs_set

Postby ESP_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
  1. #define GUI_PERIOD              2
  2. #define TICK_PERIOD             10
  3. #define GUI_TASK_CORE                         0
  4. #define TICK_TASK_CORE          1
  5. void app_main(void)
  6. {
  7.     nvs_init();
  8.     xTaskCreatePinnedToCore(Gui_Task, "Gui_Task", 120096, NULL,10, &guiTaskHandle, GUI_TASK_CORE);
  9.     while (1) {
  10.         vTaskDelay(pdMS_TO_TICKS(1000));
  11.     }
  12. }
  1. void Gui_Task(void *arg)
  2. {
  3.     static lv_disp_draw_buf_t disp_buf;
  4.     static lv_disp_drv_t disp_drv;      
  5.  
  6.     ESP_LOGI(TAG, "Create semaphores");
  7.     sem_vsync_end = xSemaphoreCreateBinary();
  8.     assert(sem_vsync_end);
  9.     sem_gui_ready = xSemaphoreCreateBinary();
  10.     assert(sem_gui_ready);
  11.  
  12.     init_backlight_pwm();
  13.  
  14.     ESP_LOGI(TAG, "Install RGB LCD panel driver");
  15.     esp_lcd_panel_handle_t panel_handle = NULL;
  16.     esp_lcd_rgb_panel_config_t panel_config = {
  17.         .data_width = 16, // RGB565 in parallel mode, thus 16bit in width
  18.         .psram_trans_align = 64,
  19.         .clk_src = LCD_CLK_SRC_DEFAULT,
  20.         .disp_gpio_num = PIN_NUM_DISP_EN,
  21.         .pclk_gpio_num = PIN_NUM_PCLK,
  22.         .vsync_gpio_num = PIN_NUM_VSYNC,
  23.         .hsync_gpio_num = PIN_NUM_HSYNC,
  24.         .de_gpio_num = PIN_NUM_DE,
  25.         .data_gpio_nums = {
  26.             PIN_NUM_DATA0,PIN_NUM_DATA1,PIN_NUM_DATA2,PIN_NUM_DATA3,PIN_NUM_DATA4,
  27.             PIN_NUM_DATA5,PIN_NUM_DATA6,PIN_NUM_DATA7,PIN_NUM_DATA8,PIN_NUM_DATA9,
  28.             PIN_NUM_DATA10,PIN_NUM_DATA11,PIN_NUM_DATA12,PIN_NUM_DATA13,PIN_NUM_DATA14,PIN_NUM_DATA15,
  29.         },
  30.         .timings = {
  31.             .pclk_hz = LCD_PIXEL_CLOCK_HZ,
  32.             .h_res = LCD_H_RES,
  33.             .v_res = LCD_V_RES,
  34.             .hsync_back_porch = HSYNC_BACK_PORCH,
  35.             .hsync_front_porch = HSYNC_FRONT_PORCH,
  36.             .hsync_pulse_width = HSYNC_PULSE_WIDTH,
  37.             .vsync_back_porch = VSYNC_BACK_PORCH,
  38.             .vsync_front_porch = VSYNC_FRONT_PORCH,
  39.             .vsync_pulse_width = VSYNC_PULSE_WIDTH,
  40.             .flags.pclk_active_neg = true,
  41.         },
  42.         .flags.fb_in_psram = true,
  43.     };
  44.     ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle));
  45.  
  46.     ESP_LOGI(TAG, "Register event callbacks");
  47.     esp_lcd_rgb_panel_event_callbacks_t cbs = {
  48.         .on_vsync = on_vsync_event,
  49.     };
  50.     ESP_ERROR_CHECK(esp_lcd_rgb_panel_register_event_callbacks(panel_handle, &cbs, &disp_drv));
  51.  
  52.     ESP_LOGI(TAG, "Initialize RGB LCD panel");
  53.     ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
  54.     ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
  55.  
  56.     i2c_master_init();
  57.     esp_lcd_touch_config_t tp_cfg = {
  58.         .x_max =LCD_H_RES,
  59.         .y_max = LCD_V_RES,
  60.         .rst_gpio_num = TOUCH_GT911_RST,
  61.         .int_gpio_num = -1,
  62.         .flags = {
  63.             .swap_xy = 0,
  64.             .mirror_x = 0,
  65.             .mirror_y = 0,
  66.         },
  67.     };
  68.  
  69.     esp_lcd_panel_io_handle_t tp_io_handle = NULL;
  70.     esp_lcd_panel_io_i2c_config_t io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
  71.     ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_NUM_0, &io_config, &tp_io_handle));
  72.     ESP_LOGI(TAG, "Initialize touch controller GT911");
  73.     ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp));
  74.  
  75.  
  76.     ESP_LOGI(TAG, "Initialize LVGL library");
  77.     lv_init();
  78.     void *buf1 = NULL;
  79.     void *buf2 = NULL;
  80.     buf1 = heap_caps_malloc(LCD_H_RES * 100 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
  81.     assert(buf1);
  82.     buf2 = heap_caps_malloc(LCD_H_RES * 100 * sizeof(lv_color_t), MALLOC_CAP_SPIRAM);
  83.     assert(buf2);
  84.     lv_disp_draw_buf_init(&disp_buf, buf1, buf2, LCD_H_RES * 100);
  85.  
  86.     ESP_LOGI(TAG, "Register display driver to LVGL");
  87.     lv_disp_drv_init(&disp_drv);
  88.     disp_drv.hor_res = LCD_H_RES;
  89.     disp_drv.ver_res = LCD_V_RES;
  90.     disp_drv.flush_cb = lvgl_flush_cb;
  91.     disp_drv.draw_buf = &disp_buf;
  92.     disp_drv.user_data = panel_handle;
  93.     lv_disp_t *disp = lv_disp_drv_register(&disp_drv);  
  94.  
  95.     /****   Init Touchpad GT911   **********/
  96.  
  97.     static lv_indev_drv_t indev_drv;    
  98.     lv_indev_drv_init(&indev_drv);
  99.     indev_drv.type = LV_INDEV_TYPE_POINTER;
  100.     indev_drv.disp = disp;
  101.     indev_drv.read_cb = lvgl_touch_cb;
  102.     indev_drv.user_data = tp;
  103.  
  104.     lv_indev_drv_register(&indev_drv);    
  105.  
  106.     ui_init();
  107.    
  108.     xTaskCreatePinnedToCore(Tick_Task, "Tick_Task", 4096, NULL,1, &tickTaskHandle, TICK_TASK_CORE);
  109.  
  110.     while(1){        
  111.         lv_timer_handler();
  112.         vTaskDelay(GUI_PERIOD);        
  113.     }
  114. }
  1. void nvs_init(){
  2.     esp_err_t err = nvs_flash_init();
  3.     //err = nvs_flash_init_partition("storage");
  4.     if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
  5.         // NVS partition was truncated and needs to be erased
  6.         // Retry nvs_flash_init
  7.         ESP_ERROR_CHECK(nvs_flash_erase());
  8.         err = nvs_flash_init();
  9.         ESP_LOGI(TAG, "NVS Init error:%d",err);
  10.     }
  11.     ESP_ERROR_CHECK( err );/* esp_err_t*/
  12.     ESP_LOGI(TAG, "NVS Error: %d",err);
  13.     ESP_LOGI(TAG, "NVS Initialized");
  14. }
  1. void Tick_Task(void *arg)
  2. {
  3.     while(1){
  4.         lv_tick_inc(30);
  5.         vTaskDelay(TICK_PERIOD);
  6.     }
  7. }

ESP_Sprite
Posts: 9746
Joined: Thu Nov 26, 2015 4:08 am

Re: LVGL screen shift on nvs_set

Postby ESP_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

Who is online

Users browsing this forum: No registered users and 105 guests