Momentum beats perfection - keep moving, keep improving.
(Note: This is work in progress.) A general-purpose boilerplate for bringing up MIPI DSI LCDs (with optional touch) on the ESP32‑P4. This repo aims to give developers a clean, extensible starting point: select a board, select a panel, build, and get pixels on the screen with LVGL.
Modular, trim-to-fit panel support: choose your LCD and keep builds lean by removing unused drivers in lcd_config/.
- Minimal, vendor-neutral scaffolding for MIPI DSI on ESP32‑P4
- Clean separation of hardware init, display config, and UI logic (LVGL 9)
- Pluggable panel drivers and touch controllers
- Menuconfig-driven board selection and automatic sdkconfig overlays per vendor
- Prerequisites
- ESP-IDF v5.5.3+ or v6.0 (P4 + MIPI DSI capable toolchain, tested with v5.5.3 and v6.0)
- Python and Git installed
Note for ESP-IDF v6.0 Users: This project includes modified components in the
components/directory to ensure compatibility with ESP-IDF v6.0's new color/display API. These will be automatically used during build. The patches use conditional compilation to maintain backward compatibility with ESP-IDF v5.5.3+. Seecomponents/README.mdfor details.
-
Configure
- Select your board in menuconfig under: Project Configuration → Hardware Vendor/Board
- Select your LCD panel: Project Configuration → Display → Panel
- No options will be added later
-
Build and flash
- idf.py set-target esp32p4
- idf.py menuconfig
- idf.py -p PORT flash monitor
Note: Board selection applies an sdkconfig overlay from boards/sdkconfig.defaults.<vendor> to set sane SPI flash options and other defaults.
main/hw_config/Board-level setup (I2C, LDO, MIPI DSI PHY power, etc.)lcd_config/Panel selection and LVGL display/touch wiring
components/Local component overrides (ESP-IDF v6.0 compatibility patches)managed_components/Third-party components (esp_lvgl_port, LCD panels, touch, etc.)boards/sdkconfig overlays applied per selected vendor/boardproject_include.cmakeLogic to append the overlay based on Kconfig symbol
- ESP32-P4 chip revision support: Configured to support all chip revisions (v1.0 and above) for maximum hardware compatibility
- Partition table: 10MB factory app partition, 5MB SPIFFS storage (optimized for larger binaries)
- LVGL demos: Only widgets demo enabled by default to reduce binary size (other demos can be enabled in menuconfig)
- LVGL 9 via
espressif__esp_lvgl_port - MIPI DSI panel bring-up path: create DSI bus → DBI IO → wrap DPI panel → register display with LVGL
- I2C v2 API for touch and aux devices
The following ESP32-P4 development boards are supported and can be selected in menuconfig:
| Vendor | Board Name | Flash | URL | Status |
|---|---|---|---|---|
| Espressif | ESP32-P4 Function EV Board | 16MB | espressif.com | ✅ Works |
| Olimex | ESP32-P4-DevKit | 16MB | olimex.com | ✅ Works |
| DFRobot | FireBeetle 2 ESP32-P4 | 16MB | dfrobot.com | ✅ Works |
| Waveshare | ESP32-P4-Module-DEV-KIT | 16MB | waveshare.com | ✅ Works |
| Guition | JC-ESP32P4-M3 DEV Board | 16MB | surenoo.com | ✅ Works |
All boards use the same general I2C and DSI PHY configuration. Board-specific settings (flash mode, frequency) are applied automatically via sdkconfig overlays in boards/.
Planned to be added incrementally as part-time development progresses.
| Vendor | Model | Resolution (WxH)* | Interface | Touch | Status |
|---|---|---|---|---|---|
| BuyDisplay | 5" IPS TFT ER-TFT050-10 | 720x1280 | DSI (2-lanes) | GT911 | ✅ Works |
| DFRobot | 5" DSI (SKU: DFR0550-V2) | 800x480 | DSI (1-lane) | FT5x06 | ✅ Works |
| Luckfox | 5" DSI (SKU: 28560) | 800x480 | DSI (1-lane) | FT5x06 | ✅ Works |
| RaspberyPi | RPi 7" Touch Display V1 | 800x480 | DSI (1-lane) | FT5x06 | ✅ Works |
| RaspberyPi | RPi 5" Touch Display V2 | 720x1280 | DSI (2-lanes) | GT911 | ✅ Works |
| RaspberyPi | RPi 7" Touch Display V2 | 720x1280 | DSI (2-lanes) | GT911 | ✅ Works |
| Waveshare | ESP32-P4-WIFI6-Touch-LCD-3.4C | 800x800 | DSI (2-lanes) | GT911 | ✅ Works |
| Amelin | 7" 1024x600 LCD T D | 1024x600 | DSI (2-lanes) | GT911 | In progress |
| SeeedStudio | TBD | — | DSI | — | Planned |
*Default Resolution. Display orientation can be changed in the firmware.
Contributions and test reports are welcome.
The simplest way to use this repo as a foundation for your own ESP32-P4 project:
- Copy or fork this repository and keep only the panel driver(s) you need under
main/lcd_config/and the board overlay underboards/that matches your hardware. - Replace
main/main.cwith your own application code. The display and touch are initialised beforeapp_mainreaches your UI code, so you only need to calllv_timer_handler()in your main loop (or rely on the LVGL port task that theesp_lvgl_portcomponent starts automatically). - Add your own components alongside the existing ones — the
CMakeLists.txtandidf_component.ymlfollow standard ESP-IDF component conventions, so drop your component folder intocomponents/or list it inidf_component.ymlas a managed dependency.
The ESP32-P4 includes a Pixel-Processing Accelerator (PPA) that can offload fill, copy, rotate, and scale operations from the CPU. LVGL 9 can use this through its custom draw callback mechanism:
- Enable
Espressif's PPA acceleratorinsdkconfig(via menuconfig: Component config → LVGL configuration → Rendering configuration → Use Espressif's PPA accelerator). - The
esp_lvgl_portcomponent wires the PPA renderer automatically when the Kconfig symbol is set — no extra code is required inmain.c. - If the option is not visible, make sure you are on LVGL ≥ 9.2 and ESP-IDF ≥ v5.5.3 (both are already required by this repo).
Enabling PPA typically makes list scrolling and screen transitions noticeably faster because blending and fill operations run in hardware while the CPU is free.
- Tomasz Witke: added support for Waveshare ESP32-P4-WIFI6-Touch-LCD-3.4C.
During bring-up across multiple DSI panels, configuration changes can occasionally leave the panel in an unresponsive state. If you flash the ESP32‑P4 with different DSI settings while the same panel remains connected, the panel might not reflect the new configuration. In that case:
-
Switching ESP-IDF versions: If you're switching between ESP-IDF v5.5.3 and v6.0 (or vice versa), you must perform a clean build to avoid compatibility issues. Delete the following before rebuilding:
# Clean all cached build artifacts and configuration rm -rf build/ rm -f sdkconfig rm -f dependencies.lock # Then reconfigure and rebuild idf.py reconfigure idf.py build
This ensures cached build artifacts, component dependencies, and configuration files from the previous IDF version don't interfere with the new build.
-
Fully power-cycle the system (board and display) to clear any latched state in the panel or bridge.
-
If the display shows scrambled frames, review the
LCD_MIPI_DSI_LANE_BITRATE_MBPSsetting and lower it as needed. A typical stable range is 600–1500 Mbps. -
If the touch controller doesn't initialize or the LCD (e.g., RPi 7") doesn't power up, reduce the I2C bus speed. Some panels don't tolerate higher rates. For example, the Luckfox 5" touch only initialized reliably at ≤100 kHz.
-
ESP-IDF v6.0 + picolibc linker error: If you see
can't link soft-float modules with single-float modulesduring linking, this is a known toolchain issue (esp-15.2.0_20251204) where the picolibc fallbacklibc.awas compiled with double-float extensions while the ESP32-P4 target uses single-float ABI only. Workaround: switch to newlib viamenuconfig → Component config → C Library → Newlib(thesdkconfig.defaultsin this repo defaults to newlib to avoid this).
Below are a few photos from the project setup and output. Images are stored under pictures/.
See LICENSE for details.








