uploaded 6 days ago


LVGL ESP Portation

Component Registry

This component helps with using LVGL with Espressif's LCD and touch drivers. It can be used with any project with LCD display.


  • Initialization of the LVGL
    • Create task and timer
    • Handle rotating
  • Add/remove display (using esp_lcd)
  • Add/remove touch input (using esp_lcd_touch)



<div class="codehilite">
<pre><span></span><code><span class="k">const</span><span class="w"> </span><span class="n">lvgl_port_cfg_t</span><span class="w"> </span><span class="n">lvgl_cfg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ESP_LVGL_PORT_INIT_CONFIG</span><span class="p">();</span><span class="w"></span>
<span class="n">esp_err_t</span><span class="w"> </span><span class="n">err</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lvgl_port_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">lvgl_cfg</span><span class="p">);</span><span class="w"></span>

Add screen

Add an LCD screen to the LVGL. It can be called multiple times for adding multiple LCD screens.

This part is necessary only in IDF 5.0 and older:

static lv_disp_t  disp;
    / The component calls esp_lcd_panel_draw_bitmap API for send data to the screen. There must be called 
    lvgl_port_flush_ready(disp) after each transaction to display. The best way is to use on_color_trans_done 
    callback from esp_lcd IO config structure. /
    static bool notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t edata, void user_ctx)
        lv_disp_t  disp = (lv_disp_t )user_ctx;
        return false;
/* LCD IO / esp_lcd_panel_io_spi_config_t io_config = { ... .on_color_trans_done = notify_lvgl_flush_ready, .user_ctx = &disp }; esp_lcd_panel_io_handle_t io_handle = NULL; ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t) 1, &io_config, &io_handle));
LCD driver initialization */ ... esp_lcd_panel_handle_t lcd_panel_handle; esp_err_t err = esp_lcd_new_panel_st7789(io_handle, &panel_config, &lcd_panel_handle);

Main part of the code (IDF version independent):

/* Add LCD screen /
    const lvgl_port_display_cfg_t disp_cfg = {
        .io_handle = io_handle,
        .panel_handle = lcd_panel_handle,
        .buffer_size = DISP_WIDTHDISP_HEIGHT,
        .double_buffer = true,
        .hres = DISP_WIDTH,
        .vres = DISP_HEIGHT,
        .monochrome = false,
        /* Rotation values must be same as used in esp_lcd for initial settings of the screen */
        .rotation = {
            .swap_xy = false,
            .mirror_x = false,
            .mirror_y = false,
        .flags = {
            .buff_dma = true,
    disp = lvgl_port_add_disp(&disp_cfg);

Note: The screens added in this function are not removed in lvgl_port_deinit. They must be removed by lvgl_port_remove_disp before deinitialization. Otherwise, there can be memory leaks!

Add touch input

Add touch input to the LVGL. It can be called more times for adding more touch inputs.

/* Touch driver initialization /
    esp_lcd_touch_handle_t tp;
    esp_err_t err = esp_lcd_touch_new_i2c_gt911(io_handle, &tp_cfg, &tp);
Add touch input (for selected screen) */ const lvgl_port_touch_cfg_t touch_cfg = { .disp = disp_spi, .handle = tp, }; lvgl_port_add_touch(&touch_cfg);

Note: The inputs added in this function are not removed in lvgl_port_deinit. They must be removed by lvgl_port_remove_touch before deinitialization. Otherwise, there can be memory leaks!

LVGL API usage

Every LVGL calls must be protected with these lock/unlock commands:

/* Wait for the other task done the screen operation /
    lv_obj_t  screen = lv_disp_get_scr_act(disp);
    lv_obj_t  obj = lv_label_create(screen);
    / Screen operation done -> release for the other task */

Rotating screen

<div class="codehilite">
<pre><span></span><code><span class="n">lv_disp_set_rotation</span><span class="p">(</span><span class="n">disp</span><span class="p">,</span><span class="w"> </span><span class="n">LV_DISP_ROT_90</span><span class="p">);</span><span class="w"></span>

Note: During the rotating, the component call esp_lcd API.


Supports all targets

License: Apache-2.0

To add this component to your project, run: add-dependency "espressif/esp_lvgl_port^1.0.2"

or download archive


  • lvgl/lvgl ^8
  • espressif/esp_lcd_touch ^1.0
  • ESP-IDF >=4.4
  • Badge

    espressif/esp_lvgl_port version: 1.0.2