LCD
Where are the LCD drivers and reference examples for ESP series chips?
Please first understand the LCD development process through the ESP-IoT-Solution Programming Guide - LCD Development Guide.
For basic LCD driver examples, please refer to esp-idf/examples/peripherals/lcd.
For advanced LCD driver examples, please refer to esp-iot-solution/examples/display.
Which adapted ICs can be used by the LCD screen of ESP32 series chips?
For support of SPI, I80, RGB, MIPI-DSI, and other interfaces across ESP chip series, please refer to LCD Development Guide - Supported Interface Types. Some chips (such as ESP32-C5/C6/H2/H4) do not have a native I80 peripheral, but can drive an LCD by simulating I80 timing through the
Parliointerface inesp_lcd.For the list of LCD driver IC components officially ported by Espressif based on
esp_lcd(including I2C, SPI, QSPI, I80, MIPI-DSI, 3-wire SPI + RGB, and other interfaces), please refer to LCD Development Guide - Driver and Examples.
Common issues in application development with the ESP series chips
For common issues about the LCD screen, please refer to the LCD Application Development Notes.
Notes for Driving MIPI-DSI LCD with ESP32-P4
ESP32-P4 supports MIPI-DSI LCD with up to 2 lanes. Each supports a maximum rate of 1.5 Gbps, totaling 3 Gbps. It also supports color formats
RGB565,RGB666, andRGB888.Some MIPI-DSI LCDs, such as
ILI9881CandJD9365, are configured as 4-lane by default through hardware. However, most ICs support switching to 2-lane by modifying initialization registers. The register addresses and operations vary by IC model; please consult the LCD driver IC datasheet or the panel vendor. ESP32-P4 only supports 1-lane and 2-lane configurations.When configuring
lane_bit_rate_mbps: the maximum must not exceed 1500 Mbps; a minimum of 480 Mbps is recommended. The actual value can be calculated from resolution, refresh rate, color depth, and lane count, then determined with a 20% margin. For the calculation method, please refer to MIPI DSI LCD Detailed Guide.The MIPI-DSI driver enables the communication response mechanism (frame ACK) by default. If there is a communication anomaly between the ESP and the LCD, the ESP may freeze and trigger the watchdog. At this point, please check whether the hardware connection is correct, whether the initialization command is correct, whether the reset timing is correct, or use a logic analyzer to troubleshoot communication issues.
Driving a MIPI-DSI screen requires a stable 2.5 V power supply for the MIPI DSI PHY (obtained via an LDO). Please refer to the LDO configuration section in the corresponding example code.
Do ESP series development boards with screens support GUI development using the Arduino IDE?
The official LCD driver library for Arduino development, ESP32_Display_Panel, has been released. It can be directly downloaded on the Arduino IDE. For supported development boards, please refer to the documentation.
Several points to note:
ESP32_Display_Panel relies on arduino-esp32.
Due to the screen drift issue with the RGB interface of ESP32-S3, it is necessary to use features from ESP-IDF release/v5.1 or later to solve the problem. However, the ESP-IDF version used in arduino-esp32 v2.x.x is v4.4.x, which cannot solve this problem. Therefore, you should use arduino-esp32 v3.x.x. For detailed instructions, please refer to Document.
Given that Arduino cannot adjust various parameter configurations, such as compile optimization levels, through menuconfig like ESP-IDF, it is recommended to develop a GUI based on ESP-IDF to achieve optimal performance.
How can I improve the display frame rate of LCD screens?
For a detailed introduction to frame rates, please refer to the ESP-IoT-Solution Programming Guide - LCD Overview. Generally speaking, due to the computational performance of the ESP, the “interface frame rate” is often much higher than the “rendering frame rate”, so this issue can be described as “how to improve the rendering frame rate of the LCD”. This issue can be considered from the following three aspects:
Improve the performance of ESP. When developing with ESP-IDF, ESP can be configured through menuconfig, but it is not configured to the best performance by default. Here, taking
ESP32-S3as an example, we can increase the CPU frequency to the highest240 MHz, increase the frequency of FreeRTOS tick to 1000, and increase the bandwidth of Flash or PSRAM. In addition, we can also increase the data cache line size, set the compilation optimization level to-O2, and so on.Improve the performance of LVGL. LVGL itself can also be configured through menuconfig or the lv_conf.h file, such as setting LVGL to use the
mallocandmemcpymemory operation functions in ESP-IDF, enabling thefast memorycompilation option, etc.Optimize application design. You can make full use of CPU resources by adjusting the priority of tasks or specifying CPU cores for LVGL and other tasks, especially for ESPs with dual cores. Besides, you can also optimize the design of the GUI, such as avoiding the use of complex animations and layers with transparency overlay effects as much as possible.
Taking ESP32-S3R8 as an example, the following ESP configuration items can improve the frame rate (ESP-IDF release/v5.1):
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y[should be consistent with PSRAM]
CONFIG_SPIRAM_MODE_OCT=y
CONFIG_IDF_EXPERIMENTAL_FEATURES=yandCONFIG_SPIRAM_SPEED_120M=y[should be consistent with FLASH]
CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y
CONFIG_SPIRAM_RODATA=y
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y
CONFIG_COMPILER_OPTIMIZATION_PERF=yOn ESP32-P4, you can adjust the following configurations to increase the frame rate (applicable to ESP-IDF release/v5.4 and later; release/v6.0 is recommended):
CONFIG_CACHE_L2_CACHE_256KB=y
CONFIG_CACHE_L2_CACHE_LINE_128B=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
CONFIG_COMPILER_OPTIMIZATION_PERF=yThe following LVGL configuration items can help improve the frame rate:
LVGL v8:
CONFIG_LV_MEM_CUSTOM=y,CONFIG_LV_MEMCPY_MEMSET_STD=y,CONFIG_LV_ATTRIBUTE_FAST_MEM=yLVGL v9:
CONFIG_LV_OS_FREERTOS=y,CONFIG_LV_USE_CLIB_MALLOC=y,CONFIG_LV_USE_CLIB_STRING=y,CONFIG_LV_USE_CLIB_SPRINTF=y,CONFIG_LV_DEF_REFR_PERIOD=15If higher frame rates, better rotation performance, and improved anti-tearing behavior are required, it is recommended to use the esp_lvgl_adapter component.
Is there any example code for I2S driving I80 LCD with ESP32/ESP32-S2?
In earlier ESP-IDF versions (v4.x and before), ESP32/ESP32-S2 drove LCD via the I80 (8080) parallel interface by reusing the I2S peripheral to simulate I80 timing. Starting from ESP-IDF v5.0, this was unified to the I80 interface of the
esp_lcdcomponent (esp_lcd_new_i80_bus), which no longer depends on I2S and provides a more standardized API.To drive an I80 LCD, please refer directly to the
i80_controllerexample in LCD examples, and ESP-IDF Programming Guide - I80 LCD.
What is the recommended upper limit of LCD resolution for ESP series chips? What is the corresponding frame rate?
The resolution upper limit depends on the interface type and the application’s frame-rate requirements. It is recommended to use the maximum resolution that can achieve a smooth frame rate (typically ≥ 30 FPS) as the practical upper limit, rather than pursuing the theoretical hardware limit. For typical resolutions and corresponding frame rates on each platform (based on
esp_lvgl_adapter+ LVGL v9 Benchmark), please refer to Selection of LCD Driver Chip.
How can I enable PSRAM 120M Octal (DDR) on ESP32-S3R8?
ESP-IDF v5.1 or later versions are required.
Enable configuration items through menuconfig:
IDF_EXPERIMENTAL_FEATURES,SPIRAM_SPEED_120M,SPIRAM_MODE_OCT.The
ESP32-S3-WROOM-1-N16R16Vmodule currently does not support this feature. If enabled, the chip may freeze upon power-up and then reset.Please note it is an experimental feature still in testing and may come with the following temperature risks:
The chip may not work properly even with ECC enabled when the temperature is above 65°C.
Temperature changes may also cause program crashes when accessing PSRAM/flash. For more details, please refer to SPI Flash and External SPI RAM Configuration.
Does ESP32-S3 require an external PSRAM to use the RGB screen?
In general, yes. RGB screens require the ESP to provide at least one full-screen-sized frame buffer. However, the resolution of RGB screens is usually large, and ESP32-S3’s SRAM might not meet this requirement.
It’s not recommended to use a Quad PSRAM due to its relatively low bandwidth, as this could make the PCLK of the RGB LCD cannot be set to the required frequency.
It’s recommended to use an Octal PSRAM and set the clock to 80 MHz or above.
How can I increase the upper limit of PCLK settings on ESP32-S3 while ensuring normal RGB screen display?
Typically, the upper limit of PCLK settings is constrained by the bandwidth of the PSRAM. Therefore, you need to enhance the PSRAM bandwidth:
Use a higher frequency PSRAM clock or a wider PSRAM bus (Octal).
Reduce the PSRAM bandwidth occupied by other peripherals like Wi-Fi, flash, etc.
Decrease the Data Cache Line Size to 32 Bytes (set to 64 Bytes when using RGB Bounce Buffer mode).
Enable the Bounce Buffer mode of the RGB driver. The larger the buffer, the better the effect. For usage, please refer to the documentation. Please note that in this mode, the CPU first moves PSRAM data to SRAM, and then the GDMA transfers data to the RGB peripheral. Therefore, it is necessary to enable
CONFIG_ESP32S3_DATA_CACHE_LINE_64B=y. Otherwise, it may cause the screen to drift.Based on limited testing, for Quad PSRAM at 80 MHz, the highest PCLK setting is around 11 MHz; for Octal PSRAM at 80 MHz, the highest PCLK setting is around 22 MHz; for Octal PSRAM at 120 MHz, the highest PCLK setting is around 30 MHz.
For applications using LVGL, the task of RGB peripheral initialization can be assigned to the same core as the task of LVGL
lv_timer_handler(). This significantly increases the upper limit of PCLK settings.
Which image decoding formats are supported by LCD applications on ESP series chips?
Software JPEG decoding: ESP-IDF includes the built-in
tjpgdsoftware decoder for JPEG. For an application example, please refer to esp-idf/examples/peripherals/lcd/tjpgd.Hardware JPEG decoding: ESP32-S31 and ESP32-P4 integrate a hardware JPEG codec (
SOC_JPEG_CODEC_SUPPORTED), and support hardware-accelerated JPEG decoding through the esp_driver_jpeg component, which is significantly faster than software decoding.Via esp_lvgl_adapter + esp_lv_decoder: It is recommended to use esp_lvgl_adapter together with esp_lv_decoder, which supports the following formats:
Standard formats: JPG, PNG, QOI
Sliced formats (optimized for embedded memory): SJPG, SPNG, SQOI
Hardware acceleration (supported chips only): JPEG, PJPG
Based on LVGL built-in libraries: LVGL itself also provides decoding support for PNG, BMP, GIF, and other formats. For details, please refer to LVGL libs.
EAF animation format: An Espressif custom animation format, originally designed for screen refreshing with the esp_emote_gfx component (segmented decoding), and also adapted to LVGL. Refer to the LVGL EAF Player Example.
Why do I get drift (overall drift of the display) when ESP32-S3 is driving an RGB LCD screen?
Reasons
The PCLK setting of the RGB peripheral is too high, and the bandwidth of PSRAM or GDMA cannot be satisfied.
PSRAM and flash share a set of SPI interfaces. PSRAM is disabled during writes to flash (such as via Wi-Fi, OTA, Bluetooth LE).
Reading a large amount of flash/PSRAM data results in insufficient PSRAM bandwidth.
Solutions
Improve PSRAM and flash bandwidth. For example, use a higher frequency or larger bit width under the conditions allowed by the hardware.
Enable
CONFIG_COMPILER_OPTIMIZATION_PERF.Reduce the Data Cache Line Size to 32 Bytes (set to 64 Bytes when using the RGB
Bounce Buffermode).Enable
CONFIG_SPIRAM_FETCH_INSTRUCTIONSandCONFIG_SPIRAM_RODATA.(Not Recommended) Enable
CONFIG_LCD_RGB_RESTART_IN_VSYNCto automatically recover after screen drifting, but this cannot completely avoid the issue and may reduce the frame rate.Applications
While ensuring the screen display is normal, try to reduce the frequency of PCLK and decrease the bandwidth utilization of PSRAM.
If you need to use Wi-Fi, Bluetooth LE, and continuous flash writing operations, please adopt the
XIP on PSRAM + RGB Bounce buffermethod. Here,XIP on PSRAMis used to load the code segment and read-only segment data into PSRAM, and the flash writing operation will not disable PSRAM after it is turned on.RGB Bounce bufferis used to block the frame buffer data and transfer it from PSRAM to SRAM through the CPU, and then use GDMA to transfer data to the RGB peripheral. Compared with directly using PSRAM GDMA, it can achieve higher transmission bandwidth. The setup steps are as follows:
Make sure the ESP-IDF version is release/v5.0 or newer (released after 2022.12.12), as older versions do not support the
XIP on PSRAMfunction. (release/v4.4 supports this function through patching, but it is not recommended)Confirm whether
CONFIG_SPIRAM_FETCH_INSTRUCTIONSandCONFIG_SPIRAM_RODATAcan be enabled in the PSRAM configuration. If the read-only data segment is too large (such as a large number of images), it may cause insufficient PSRAM space. At this time, you can use the file system or make the images into a bin to load into the designated partition.Check if there is any memory (SRAM) left, and it takes about [10 × screen_width × 4] bytes.
Set
Data cache line sizeto 64 Bytes (you can setData cache sizeto 32 KB to save memory).Set
CONFIG_FREERTOS_HZto 1000.If all the above conditions are met, you can refer to the documentation to modify the RGB driver to Bounce Buffer mode. If drift still occurs after enabling, you can try to increase the buffer, but this will consume more SRAM memory.
If you still have the drift problem when dealing with Wi-Fi, you can try to turn off
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIPin PSRAM, which takes up much SRAM space.The effects of this setting include higher CPU usage, possible interrupt watchdog reset, and higher memory overhead.
Since the Bounce Buffer transfers data from PSRAM to SRAM through the CPU in GDMA interrupts, the program should avoid performing operations that disable interrupts for an extended period (such as calling
portENTER_CRITICAL()), as it can still result in screen drifting.For the drift caused by short-term operations of flash, such as before and after Wi-Fi connection, you can call
esp_lcd_rgb_panel_set_pclk()before the operation to reduce the PCLK (such as 6 MHz) and delay about 20 ms (the time for RGB to complete one frame), and then increase PCLK to the original level after the operation. This operation may cause the screen to flash blank in a short-term.If unavoidable, you can enable
CONFIG_LCD_RGB_RESTART_IN_VSYNCor use theesp_lcd_rgb_panel_restart()to reset the RGB timing to prevent permanent drifting.For guidance on how to avoid RGB screen drift issues in Arduino, please refer to the link.
Why is there vertical dislocation when I drive SPI/8080 LCD screen to display LVGL?
If you use DMA interrupt transfer, the flush-complete callback should be called after the DMA transfer finishes, not immediately after
draw_bitmap().
LVGL v8: Call
lv_disp_flush_ready()in the DMA transfer complete interrupt.LVGL v9: Call
lv_display_flush_ready()in the DMA transfer complete interrupt.
When I use ESP32-C3 to drive the LCD display through the SPI interface, is it possible to use RTC_CLK as the SPI clock, so that the LCD display can normally display static pictures in Deep-sleep mode?
Deep-sleep mode: The CPU and most peripherals are powered down, only the RTC memory is operational. For more details, please refer to the “Low Power Management” section in the ESP32-C3 Datasheet.
The SPI of ESP32-C3 only supports two clock sources, APB_CLK and XTAL_CLK, and does not support RTC_CLK. Therefore, the LCD screen cannot display static pictures in Deep-sleep mode. For details, please refer to ESP32-C3 Technical Reference Manual > Reset and Clock [PDF].
For the LCD screen driven by the SPI interface, the driver IC generally has built-in GRAM. Thus, the static pictures can be displayed normally without the ESP continuously outputting the SPI clock, but the pictures cannot be updated during this period.
Are 9-bit bus and 18-bit color depth supported if I use the ILI9488 LCD screen to test the screen example?
The ILI9488 driver chip can support 9-bit bus and 18-bit color depth. However, Espressif’s driver can only support 8-bit bus and 16-bit color depth for now.
When using ESP32-S3 to drive an RGB screen, why does it halt or reset (TG1WDT_SYS_RST) when running esp_lcd_new_rgb_panel() or esp_lcd_panel_init()?
Please check if the pins occupied by PSRAM in ESP chips or modules conflict with the RGB pins. If there is a conflict, modify the RGB pin configuration.
If using ESP32-S3R8, avoid using GPIO35, GPIO36, and GPIO37 pins.
When using ESP32-S3 to drive an RGB screen, an abnormal color inversion is observed, i.e., black turns into white, and white turns into black. How to handle this?
Please check whether the initialization register of the screen driver IC has set the invert_color function. For example, in ST7789, this can be corrected by configuring the Inversion register:
INVOFF (20h): Display Inversion Off
INVON (21h): Display Inversion On
How to handle color inaccuracies, such as missing colors, when driving an RGB screen with ESP32-S3?
It’s likely that the RGB configuration is incorrect. This problem can be troubleshot in the following ways:
Check for RGB/BGR setting errors: For example, if the screen is set to red (0xC0, 0x0, 0x0), but the screen actually displays black.
Check whether the RGB and BGR registers are set: For example, in ST7789, it can be corrected through the MADCTL (36h) register (when MADCTL (36h) = 1, it is BGR; when MADCTL (36h) = 0, it is RGB).
Check for LVGL SWAP16 setting errors: If the screen is configured to red (0xC0, 0x0, 0x0), but the screen actually displays blue, please go to menuconfig → Component config → LVGL configuration → Color settings.
If there’s missing colors in the RGB TTL screen display, it is necessary to set R, G, B displays separately, and check whether the channel with waveform and RGB data line design are compliant.
The spaces in the LVGL’s label are correctly inputted, for example “Indoor temperature 25.5℃”, but the spaces are not displayed on the screen. What could be the reason and how to troubleshoot this?
This pertains to the missing display of the LVGL label. Enable the following debug items and missing characters will be filled with squares to prevent map loss:
Component config→LVGL configuration→Font usage→Enable drawing placeholders when glyph dsc is not found
When LVGL v8 continuously loads different images stored on flash, the speed is too slow. For example, how to avoid the slow speed issue when cycling through three images on the home screen?
The reason for the slow speed is that the corresponding image caching mechanism is not turned on, so each images need to be parsed by the parser each time it is used.
Enable the corresponding image caching mechanism via the
#define LV_IMG_CACHE_DEF_SIZE 1macro, where 1 represents the number of cached images. Please note that this operation will consume more memory.
LVGL v8 fails to load PNG, JPEG images from flash. What’s the reason for a blank screen?
First, it is necessary to check the status of the remaining memory. LVGL needs to perform two steps to load images: loadpng_get_raw_size and loadpng_convert. If the memory is not enough, it will directly return error code 83.
The memory requirements should also be estimated in advance:
loadpng_get_raw_sizeneeds memory equivalent to the image size,loadpng_convertrequires memory of image length * width * 3 bytes. Enabling the image caching mechanism will cause largeimage_cache, which will simultaneously lead to memory strain.
How to convert a GIF animation into C language code?
Convert the GIF to Map option, with the Color format set to CF_RAW.
Can the screen be set to transparent when displaying GIF animations?
Yes. But GIF only has a 1 bit Alpha descriptor, so it can only be fully transparent or opaque, and there is no semi-transparency.
Which image format is better for the LVGL interface? Is there any reference?
You can refer to the table below:
Image format
Transparent support
Size
Decoding speed
PNG
Perfectly supported
Moderate
Moderate
BMP
Limited support
Large
Fastest, no decoding required
JPG
Not supported
Small
Fast
When converting images to MAP format via LVGL imageconverter, if using non-RAW formats such as
CF_TRUE_COLORfor conversion, subsequent LVGL loading will not require re-decoding, but it will occupy a larger code segment.
When using some third-party libraries such as FreeType and Lottie with LVGL, why does the screen go blank despite the program loading normally?
First, consider whether the task stack settings are incorrect:
FreeType: When using
esp_lvgl_adapter, first confirm the stack configuration: for LVGL v8, setCONFIG_ESP_MAIN_TASK_STACK_SIZEto 32768 (font initialization runs on the calling thread); for LVGL v9, setCONFIG_LV_DRAW_THREAD_STACK_SIZEto 32768 (font rendering runs on the draw thread). In addition, the following two Kconfig options can reduce resource usage:
ESP_LVGL_ADAPTER_FREETYPE_SMALL_RENDER_POOL: Reduces the FreeType render pool from 16 KB to 4 KB, and can also reduce the LVGL v9 draw thread stack requirement.
ESP_LVGL_ADAPTER_FREETYPE_MINIMAL_BUILD: Trims FreeType build modules and keeps only what is needed for common TTF/OTF paths (removes Type1/CID/BDF/PCF and other legacy drivers and compressed-stream helpers), which significantly reduces flash usage. Do not enable this if your project needs any of the trimmed formats.Reference example: lvgl_freetype_font.
Lottie: Generally, more than 30 KB of task stack needs to be allocated. Refer to lottie porting.
What are some good solutions if the internal RAM of ESP32-S3, driving an SPI screen, is insufficient to allocate space for the entire screen buffer?
Use PSRAM as a framebuffer, and then use a small SRAM buffer to transfer data to the framebuffer in multiple batches (SPI DMA can’t directly transfer PSRAM data). After completing the transfer, use the framebuffer to render directly. Compared to rendering directly with a small buffer and then sending data, this can prevent tearing and speed up rendering. For specific implementation, please refer to esp_lvgl_adapter.
How to deal with diagonal tearing on the SPI screen after the hardware is rotated 90 or 270 degrees?
It is recommended to enable the LVGL
sw_rotateflag in normal mode and use LVGL software rotation. However, please note thatsw_rotateconflicts withfull_refreshanddirect_mode, so do not use them together. For example, callingsw_rotateunderfull_refreshwill directly return without any effect.Note
sw_rotate,full_refresh, anddirect_modeare LVGL v8 APIs. Rotation in LVGL v9 works differently; please refer to LVGL v9 Rotation Notes.
Using the ESP32-S2 USB camera and I80 LCD simultaneously may result in the LCD display showing missing images or behaving abnormally. How can this be resolved?
Please refer to this code to increase the startup delay time of I2S.
How to solve the unexpected crash when operating LVGL controls through non-LVGL tasks?
LVGL APIs are not thread-safe. When operating LVGL controls from a non-LVGL task, you must protect the calls with a lock.
If you use the
esp_lvgl_adaptercomponent, use the lock APIs it provides:if (esp_lv_adapter_lock(-1) == ESP_OK) { /* LVGL API calls */ esp_lv_adapter_unlock(); }If you use the legacy
esp_lvgl_portcomponent, the corresponding APIs arelvgl_port_lock(0)andlvgl_port_unlock().
Does ESP32-S3 support RGB888?
Parallel RGB888 is not supported (ESP32-P4 supports parallel RGB888), only RGB565 is supported. Serial RGB888 output can be configured with the following settings:
esp_lcd_rgb_panel_config_t panel_conf = { ... .data_width = 8, .bits_per_pixel = 24, ... }
How can I disable the left and right swipe functionality when operating the LVGL tabview?
Please add the following code:
lv_obj_clear_flag(lv_tabview_get_content(tabview), LV_OBJ_FLAG_SCROLLABLE);.
Does LVGL support multiple indev inputs?
Yes. All input devices are managed in a linked list, supporting multiple input devices of the same and different types. For application examples, please refer to the component espressif/esp_lvgl_adapter. The component currently supports input device types such as touch, button, and knob.
Does LVGL support multi-touch?
LVGL multi-touch support varies by version:
LVGL v8: Native multi-touch is not supported; each indev can report only one touch point.
LVGL v9: Multi-pointer input is supported. Multiple touch indevs can be registered for the same display, and each touch point can control different widgets independently.
When using esp_lvgl_adapter, you can enable multi-touch mode when registering a touch device (LVGL v9 only):
esp_lv_adapter_touch_config_t touch_cfg = ESP_LV_ADAPTER_TOUCH_DEFAULT_CONFIG(disp, touch_handle); touch_cfg.multi_touch.mode = ESP_LV_ADAPTER_TOUCH_MODE_MULTI_CONTROL; touch_cfg.multi_touch.pointers = 2; /* Must be >= 2, and not exceed CONFIG_ESP_LCD_TOUCH_MAX_POINTS */ lv_indev_t *touch = esp_lv_adapter_register_touch(&touch_cfg);
Does a high CPU usage rate reported by LVGL have any impact?
The CPU usage calculated by LVGL statistics is the duration of the LVGL rendering task within 500 ms, and it does not represent the real CPU usage. Please use FreeRTOS’s vTaskGetRunTimeStats to calculate the real usage.
Can ESP32-S3 enter Light-sleep mode after enabling the RGB screen driver?
Using the esp_lcd RGB driver directly: When initializing the RGB interface, if
CONFIG_PM_ENABLEis enabled, the driver automatically holds theESP_PM_NO_LIGHT_SLEEPlock, preventing the system from entering Light-sleep mode. To enter Light-sleep, you must first callesp_lcd_panel_del()to delete the RGB panel (releasing the lock), then reinitialize after waking from sleep.Using the esp_lvgl_adapter component: This component provides two Light-sleep usage modes. The LVGL UI state (widget tree) is retained during sleep, so the UI does not need to be rebuilt.
Manual sleep: The application controls the full sleep/wake flow:
Before entering sleep, call
esp_lv_adapter_sleep_prepare()to pause the adapter and wait for the current frame refresh to complete.Call
esp_lcd_panel_del()to release display hardware resources.Call
esp_light_sleep_start()to enter Light-sleep.After waking, reinitialize the LCD hardware, then call
esp_lv_adapter_sleep_recover()to rebind the panel and resume the adapter.Automatic sleep (auto_sleep): Configure an idle timeout at initialization. The adapter automatically triggers sleep after LVGL has been idle longer than the specified time:
esp_lv_adapter_config_t cfg = ESP_LV_ADAPTER_DEFAULT_CONFIG(); cfg.auto_sleep.enable = true; cfg.auto_sleep.idle_timeout_ms = 5000; /* Auto-sleep after 5 s of idle */ /* Pause mode: the adapter releases the lock and pauses LVGL; the system enters tickless light sleep; panel sleep/backlight is handled by user callbacks */ cfg.auto_sleep.mode = ESP_LV_ADAPTER_AUTO_SLEEP_MODE_PAUSE; cfg.auto_sleep.callbacks.on_enter_sleep = panel_sleep_cb; cfg.auto_sleep.callbacks.on_exit_sleep = panel_wake_cb; /* User mode: the on_enter_sleep callback owns the full sleep_prepare → LCD deinit → light_sleep_start → LCD init → sleep_recover flow */ /* cfg.auto_sleep.mode = ESP_LV_ADAPTER_AUTO_SLEEP_MODE_USER; */ ESP_ERROR_CHECK(esp_lv_adapter_init(&cfg));In Pause mode, registered touch/button/knob inputs automatically notify the adapter to wake; custom wake sources can call
esp_lv_adapter_request_wake()oresp_lv_adapter_request_wake_from_isr().
Is it supported to drive segment LCD screens?
ESP chips can’t directly drive the segment LCD screen through the GPIO pin, because this function requires cycling between high and low voltage levels, with an AC voltage from 2.7 V to 5.0 V and typical values of 3.0 V, 3.3 V, 4.5 V, and 5.0 V. However, the chips do not support voltage range adjustment.
When driving an RGB LCD with ESP32-P4, the screen shows abnormal colors. How to troubleshoot?
ESP32-P4 has multiple VDDPST power domains. Each VDDPST controls the maximum output level of GPIOs in the corresponding region (for the GPIO-to-VDDPST mapping, please refer to the ESP32-P4 Datasheet). If the corresponding VDDPST supply is insufficient or not configured correctly, some GPIOs may have a maximum output level of 1.8 V, causing insufficient RGB interface signal levels and abnormal screen colors. Please check that the VDDPST for the GPIOs used by the RGB interface is configured to the correct voltage (typically 3.3 V).
Note also: Unlike ESP32-S3 (PCLK up to about 30 MHz), the RGB interface clock frequency on ESP32-S31 and ESP32-P4 has no such 30 MHz upper limit, so they can support higher interface frame rates and larger-resolution RGB screens.
Does ESP32-P4 support HDMI signal output?
ESP32-P4 does not support direct HDMI signal output. However, HDMI signal output can be achieved through an MIPI-DSI to HDMI bridge chip. Currently, the MIPI-DSI to HDMI chip supported by Espressif is LT8912B. For more information, refer to example code.
In LVGL applications, how to rotate the RGB or MIPI-DSI interface screen by 90 degrees/270 degrees? How to avoid tearing? How to further improve the frame rate?
It is recommended to use the esp_lvgl_adapter component. This component provides features such as high-efficiency rotation, tear prevention, frame rate enhancement, and supports LVGL v8 and v9 versions.
Refer to the example code esp_lvgl_adapter example.
Can ESP32-P4 generate MIPI-DSI signals (LP and HP) when no MIPI peripheral is connected?
Theoretically possible, but with limitations: Signals can be output during the LP (Low Power) phase; however, during the HP (High Performance) phase, because the driver enables frame ACK by default and has no timeout mechanism, when the FIFO is full it will continuously wait for ACK (BTA), causing the link to freeze. If only capturing waveform segments can satisfy your requirements, then it’s feasible. If continuous output is needed, you must modify the MIPI-DSI driver inside IDF; currently it cannot be achieved through external configuration alone.
GIF animations in EAF format play slowly on ESP32-S3/P4. How to optimize?
You can change the EAF encoding format to JPEG (set in the conversion tool), which will increase file size but decode faster;
For larger resolution screens (such as 466×466), LVGL rendering burden is heavy;
Compared with EAF + LVGL, using the esp_emote_gfx component directly for screen refreshing (segmented decoding) is more efficient. EAF was originally designed for
esp_emote_gfx, and is only additionally adapted to LVGL;AVI with JPEG-encoded frames is smoother on an LCD than GIF;
P4 revision v3.1 improves CPU frequency and PSRAM bandwidth, enabling LVGL and MP4 to stably reach 15 frames under 1080p RGB888.
ESP32-P4 drives a MIPI-DSI LCD with no image and no other error logs. How to troubleshoot?
First, check whether the SPIRAM clock rate is configured to 200 MHz or above (
CONFIG_SPIRAM_SPEED_200M=y). Driving a MIPI-DSI interface screen requires higher PSRAM bandwidth; when bandwidth is insufficient, the screen may fail to display without reporting an error.Next, check whether the DSI data pins (
DSI_DATAN0/DSI_DATAP0) and clock pins (DSI_CLKN/DSI_CLKP) are correctly connected to the panel.
ESP32-P4 drives a MIPI-DSI LCD with twisted or misaligned images. How to handle this?
This issue is generally caused by a mismatch between
lane_bit_rate_mbpsand the actualpixel_clock, or betweenlane_bit_rate_mbpsand the rate required by the panel. Recalculatelane_bit_rate_mbpsbased on resolution, refresh rate, color depth, and lane count (with about a 20% margin). For the calculation method, please refer to MIPI DSI LCD Detailed Guide. Note that on ESP32-P4,lane_bit_rate_mbpsmust not exceed 1500, and a minimum of 480 is recommended.
ESP32-P4 drives a MIPI-DSI LCD with a flashing blue screen and the message “can’t fetch data from external memory fast enough, underrun happens”. How to handle this?
This issue is caused by insufficient PSRAM bandwidth. You can try the following:
Lower
lane_bit_rate_mbpsanddpi_clock_freq_mhz(pixel clock frequency).If using the RGB888 color format, consider switching to RGB565 to reduce bandwidth demand.
Enable the following configuration items to improve PSRAM bandwidth:
CONFIG_SPIRAM_XIP_FROM_PSRAM=y
CONFIG_CACHE_L2_CACHE_256KB=y
CONFIG_CACHE_L2_CACHE_LINE_128B=y
CONFIG_COMPILER_OPTIMIZATION_PERF=y