Skip to content

Commit 461a0f8

Browse files
committed
feat(lvgl_port): Initial support for ppa rendering in lvgl
Mainly supports the following features: - color blend (simple fill) - color blend with opa - blend normal (blend with argb8888) - blend normal to color (color convert / memcpy)
1 parent c90025b commit 461a0f8

21 files changed

+1995
-22
lines changed

components/esp_lvgl_port/CMakeLists.txt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ if("usb_host_hid" IN_LIST build_components)
7777
endif()
7878

7979
# Include SIMD assembly source code for rendering, only for (9.1.0 <= LVG_version < 9.2.0) and only for esp32 and esp32s3
80-
if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS "9.2.0"))
81-
if(CONFIG_IDF_TARGET_ESP32 OR CONFIG_IDF_TARGET_ESP32S3)
80+
if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS_EQUAL "9.2.0"))
81+
if(CONFIG_IDF_TARGET_ESP32 OR CONFIG_IDF_TARGET_ESP32S3 OR CONFIG_IDF_TARGET_ESP32P4)
8282
message(VERBOSE "Compiling SIMD")
8383
if(CONFIG_IDF_TARGET_ESP32S3)
8484
file(GLOB_RECURSE ASM_SRCS ${PORT_PATH}/simd/*_esp32s3.S) # Select only esp32s3 related files
85-
else()
85+
elseif(CONFIG_IDF_TARGET_ESP32)
8686
file(GLOB_RECURSE ASM_SRCS ${PORT_PATH}/simd/*_esp32.S) # Select only esp32 related files
8787
endif()
8888
list(APPEND ADD_SRCS ${ASM_SRCS})
@@ -91,9 +91,16 @@ if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS "9.2.0"))
9191
idf_component_get_property(lvgl_lib ${lvgl_name} COMPONENT_LIB)
9292
target_include_directories(${lvgl_lib} PRIVATE "include")
9393

94+
if(CONFIG_IDF_TARGET_ESP32P4)
95+
file(GLOB_RECURSE PPA_SRCS ${PORT_PATH}/ppa/*)
96+
list(APPEND ADD_SRCS ${PPA_SRCS})
97+
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_malloc_core")
98+
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u esp_ppa_fill_for_lvgl")
99+
else()
94100
# Force link .S files
95-
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_argb8888_esp")
96-
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_rgb565_esp")
101+
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_argb8888_esp")
102+
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_rgb565_esp")
103+
endif()
97104
endif()
98105
endif()
99106

@@ -114,5 +121,9 @@ target_link_libraries(lvgl_port_lib PRIVATE
114121
${ADD_LIBS}
115122
)
116123

124+
if(CONFIG_IDF_TARGET_ESP32P4)
125+
target_link_libraries(lvgl_port_lib PRIVATE idf::esp_driver_ppa idf::esp_mm)
126+
endif()
127+
117128
# Finally, link the lvgl_port_lib its esp-idf interface library
118129
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl_port_lib)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
3+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
4+
project(mipi_dsi_panel)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
| Supported Targets | ESP32-P4 |
2+
| ----------------- | -------- |
3+
4+
# MIPI DSI LCD Panel Example
5+
6+
[esp_lcd](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/lcd/dsi_lcd.html) supports MIPI DSI interfaced LCD panel, with frame buffer(s) managed by the driver itself.
7+
8+
This example shows the general process of installing a MIPI DSI LCD driver, and displays a LVGL widget on the screen.
9+
10+
## How to use the example
11+
12+
### Hardware Required
13+
14+
* An ESP development board, which with MIPI DSI peripheral supported
15+
* A general MIPI DSI LCD panel, with 2 data lanes and 1 clock lane, this example support [ILI9881C](https://components.espressif.com/components/espressif/esp_lcd_ili9881c) and [EK79007](https://components.espressif.com/components/espressif/esp_lcd_ek79007)
16+
* An USB cable for power supply and programming
17+
18+
### Hardware Connection
19+
20+
The connection between ESP Board and the LCD is as follows:
21+
22+
```text
23+
ESP Board MIPI DSI LCD Panel
24+
+-----------------------+ +-------------------+
25+
| GND +--------------+ GND |
26+
| | | |
27+
| 3V3 +--------------+ VCC |
28+
| | | |
29+
| DSI_CLK_P +--------------+ DSI_CLK_P |
30+
| DSI_CLK_N + + DSI_CLK_N |
31+
| | | |
32+
| DSI_DAT0_P +--------------+ DSI_DAT0_P |
33+
| DAI_DAT0_N + + DAI_DAT0_N |
34+
| | | |
35+
| DSI_DAT1_P +--------------+ DSI_DAT1_P |
36+
| DSI_DAT1_N + + DSI_DAT1_N |
37+
| | | |
38+
| | | |
39+
| BK_LIGHT +--------------+ BLK |
40+
| | | |
41+
| Reset +--------------+ Reset |
42+
| | | |
43+
+-----------------------+ +-------------------+
44+
```
45+
46+
Before testing your LCD, you also need to read your LCD spec carefully, and then adjust the values like "resolution" and "blank time" in the [main](./main/mipi_dsi_lcd_example_main.c) file.
47+
48+
### Configure
49+
50+
Run `idf.py menuconfig` and go to `Example Configuration`:
51+
52+
* Choose the LCD model in `Select MIPI LCD model` according to your board.
53+
* Choose whether to `Use DMA2D to copy draw buffer to frame buffer` asynchronously. If you choose `No`, the draw buffer will be copied to the frame buffer synchronously by CPU.
54+
* Choose if you want to `Monitor Refresh Rate by GPIO`. If you choose `Yes`, then you can attach an oscilloscope or logic analyzer to the GPIO pin to monitor the Refresh Rate of the display.
55+
Please note, the actual Refresh Rate should be **double** the square wave frequency.
56+
57+
### Build and Flash
58+
59+
Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. A LVGL widget should show up on the LCD as expected.
60+
61+
The first time you run `idf.py` for the example will cost extra time as the build system needs to address the component dependencies and downloads the missing components from the ESP Component Registry into `managed_components` folder.
62+
63+
(To exit the serial monitor, type ``Ctrl-]``.)
64+
65+
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
66+
67+
### Example Output
68+
69+
```bash
70+
...
71+
I (1629) example: MIPI DSI PHY Powered on
72+
I (1629) example: Install MIPI DSI LCD control panel
73+
I (1639) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c
74+
I (1779) example: Install MIPI DSI LCD data panel
75+
I (1799) example: Initialize LVGL library
76+
I (1799) example: Allocate separate LVGL draw buffers from PSRAM
77+
I (1809) example: Use esp_timer as LVGL tick timer
78+
I (1809) example: Create LVGL task
79+
I (1809) example: Starting LVGL task
80+
I (1919) example: Display LVGL Meter Widget
81+
...
82+
```
83+
84+
## Troubleshooting
85+
86+
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
idf_component_register(SRCS "mipi_dsi_lcd_main.c"
2+
INCLUDE_DIRS ".")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
menu "Example Configuration"
2+
config EXAMPLE_AVOID_BLUE_SCREEN
3+
bool "Avoid blue screen caused for PSRAM bandwidth"
4+
default y
5+
help
6+
Enable this option, DMA2D peak will be limted, then GDMA will run normal.
7+
endmenu
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dependencies:
2+
espressif/esp32_p4_function_ev_board:
3+
version: "*"
4+
override_path: "../../../../../bsp/esp32_p4_function_ev_board"
5+
lvgl/lvgl: "~9.2.0"
6+
esp_lcd_ili9881c: "^1.0.0"
7+
esp_lcd_ek79007: "^1.0.0"
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: CC0-1.0
5+
*/
6+
7+
#include "freertos/FreeRTOS.h"
8+
#include "freertos/task.h"
9+
#include "esp_log.h"
10+
11+
#include "hal/axi_dma_ll.h"
12+
#include "hal/axi_icm_ll.h"
13+
#include "soc/mipi_dsi_bridge_struct.h"
14+
15+
#include "lv_demos.h"
16+
#include "bsp/esp-bsp.h"
17+
18+
static char *TAG = "app_main";
19+
20+
#define LOG_MEM_INFO (0)
21+
22+
static void esp_dsi_avoid_blue_screen(void)
23+
{
24+
axi_icm_ll_set_dw_gdma_qos_arbiter_prio(0, 9, 10);
25+
axi_icm_ll_set_dw_gdma_qos_arbiter_prio(1, 9, 10);
26+
axi_icm_ll_set_h264_dma_qos_arbiter_prio(1, 5, 5);
27+
axi_icm_ll_set_h264_dma_qos_arbiter_prio(0, 5, 5);
28+
axi_icm_ll_set_dma2d_qos_arbiter_prio(4, 4);
29+
axi_icm_ll_set_cache_qos_arbiter_prio(4, 4);
30+
31+
int peak_level = 5; // 4: 800MB/s, 5: 400MB, 6: 200MB
32+
axi_icm_ll_set_qos_burstiness(AXI_ICM_MASTER_DMA2D, 256);
33+
axi_icm_ll_set_qos_peak_transaction_rate(AXI_ICM_MASTER_DMA2D, peak_level, peak_level + 1);
34+
}
35+
36+
void app_main(void)
37+
{
38+
#if CONFIG_EXAMPLE_AVOID_BLUE_SCREEN
39+
esp_dsi_avoid_blue_screen();
40+
#endif
41+
42+
/* Initialize display and LVGL */
43+
bsp_display_start();
44+
45+
#if CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR
46+
ESP_LOGI(TAG, "Avoid lcd tearing effect");
47+
#if CONFIG_BSP_DISPLAY_LVGL_FULL_REFRESH
48+
ESP_LOGI(TAG, "LVGL full-refresh");
49+
#elif CONFIG_BSP_DISPLAY_LVGL_DIRECT_MODE
50+
ESP_LOGI(TAG, "LVGL direct-mode");
51+
#endif
52+
#endif
53+
54+
/* Set display brightness to 100% */
55+
bsp_display_backlight_on();
56+
57+
ESP_LOGI(TAG, "Display LVGL demo");
58+
bsp_display_lock(0);
59+
// lv_demo_widgets(); /* A widgets example */
60+
// lv_demo_music(); /* A modern, smartphone-like music player demo. */
61+
// lv_demo_stress(); /* A stress test for LVGL. */
62+
lv_demo_benchmark(); /* A demo to measure the performance of LVGL or to compare different settings. */
63+
bsp_display_unlock();
64+
65+
#if LOG_MEM_INFO
66+
static char buffer[128]; /* Make sure buffer is enough for `sprintf` */
67+
while (1) {
68+
sprintf(buffer, " Biggest / Free / Total\n"
69+
"\t SRAM : [%8d / %8d / %8d]\n"
70+
"\t PSRAM : [%8d / %8d / %8d]",
71+
heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
72+
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
73+
heap_caps_get_total_size(MALLOC_CAP_INTERNAL),
74+
heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM),
75+
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
76+
heap_caps_get_total_size(MALLOC_CAP_SPIRAM));
77+
ESP_LOGI("MEM", "%s", buffer);
78+
79+
vTaskDelay(pdMS_TO_TICKS(500));
80+
}
81+
#endif
82+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Name, Type, SubType, Offset, Size, Flags
2+
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
3+
nvs, data, nvs, 0x9000, 0x6000,
4+
phy_init, data, phy, 0xf000, 0x1000,
5+
factory, app, factory, 0x10000, 10M,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
# SPDX-License-Identifier: CC0-1.0
3+
import pytest
4+
from pytest_embedded import Dut
5+
6+
7+
@pytest.mark.esp32p4
8+
@pytest.mark.generic
9+
def test_rgb_lcd_lvgl(dut: Dut) -> None:
10+
dut.expect_exact('example: Install MIPI DSI LCD control panel')
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
#
3+
# Serial flasher config
4+
#
5+
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
6+
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
7+
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
8+
9+
#
10+
# Compiler options
11+
#
12+
CONFIG_COMPILER_OPTIMIZATION_PERF=y
13+
14+
#
15+
# Kernel
16+
#
17+
CONFIG_FREERTOS_HZ=1000
18+
19+
#
20+
# LVGL configuration
21+
#
22+
CONFIG_LV_CONF_SKIP=y
23+
24+
#
25+
# Enable built-in fonts
26+
#
27+
CONFIG_LV_FONT_MONTSERRAT_14=y
28+
CONFIG_LV_FONT_MONTSERRAT_16=y
29+
CONFIG_LV_FONT_MONTSERRAT_18=y
30+
CONFIG_LV_FONT_MONTSERRAT_22=y
31+
CONFIG_LV_FONT_MONTSERRAT_24=y
32+
CONFIG_LV_FONT_MONTSERRAT_32=y
33+
34+
#
35+
# Color Settings
36+
#
37+
CONFIG_LV_COLOR_DEPTH_24=y
38+
39+
#
40+
# Compiler Settings
41+
#
42+
CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y
43+
44+
#
45+
# Logging
46+
#
47+
CONFIG_LV_USE_LOG=n
48+
CONFIG_LV_LOG_LEVEL_ERROR=y
49+
CONFIG_LV_LOG_PRINTF=n
50+
51+
#
52+
# Display
53+
#
54+
CONFIG_BSP_LCD_DPI_BUFFER_NUMS=2
55+
CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR=y
56+
CONFIG_BSP_DISPLAY_LVGL_DIRECT_MODE=y
57+
CONFIG_BSP_LCD_COLOR_FORMAT_RGB888=y
58+
CONFIG_BSP_LCD_TYPE_1280_800=y
59+
# end of Display
60+
# end of Board Support Package(ESP32-P4)
61+
62+
#
63+
# Partition Table
64+
#
65+
CONFIG_PARTITION_TABLE_CUSTOM=y
66+
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
67+
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
68+
69+
#
70+
# Demos
71+
#
72+
CONFIG_LV_USE_DEMO_WIDGETS=y
73+
CONFIG_LV_DEMO_WIDGETS_SLIDESHOW=y
74+
CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER=y
75+
CONFIG_LV_USE_DEMO_BENCHMARK=y
76+
CONFIG_LV_USE_DEMO_RENDER=y
77+
CONFIG_LV_USE_DEMO_SCROLL=y
78+
CONFIG_LV_USE_DEMO_STRESS=y
79+
CONFIG_LV_USE_DEMO_TRANSFORM=y
80+
CONFIG_LV_USE_DEMO_MUSIC=y
81+
CONFIG_LV_DEMO_MUSIC_SQUARE=y
82+
CONFIG_LV_DEMO_MUSIC_LANDSCAPE=y
83+
CONFIG_LV_DEMO_MUSIC_ROUND=y
84+
CONFIG_LV_DEMO_MUSIC_LARGE=y
85+
CONFIG_LV_DEMO_MUSIC_AUTO_PLAY=y
86+
CONFIG_LV_USE_DEMO_FLEX_LAYOUT=y
87+
CONFIG_LV_USE_DEMO_MULTILANG=n
88+
# end of Demos
89+
# end of LVGL configuration
90+
# end of Component config
91+
92+
#
93+
# Others
94+
#
95+
CONFIG_LV_USE_OBSERVER=y
96+
CONFIG_LV_USE_SYSMON=y
97+
CONFIG_LV_USE_PERF_MONITOR=y
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
CONFIG_SPIRAM=y
2+
CONFIG_SPIRAM_MODE_HEX=y
3+
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
4+
CONFIG_SPIRAM_SPEED_200M=y
5+
CONFIG_SPIRAM_MEMTEST=n
6+
CONFIG_CACHE_L2_CACHE_LINE_128B=y
7+
8+
CONFIG_LV_COLOR_DEPTH_16=n
9+
CONFIG_BSP_LCD_COLOR_FORMAT_RGB565=n
10+
11+
#
12+
# ESP-MM: Memory Management Configurations
13+
#
14+
CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS=y
15+
CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS_MAX_LEN=0x4000
16+
# end of ESP-MM: Memory Management Configurations
17+
18+
#
19+
# Example Configuration
20+
#
21+
CONFIG_EXAMPLE_AVOID_BLUE_SCREEN=y
22+
# end of Example Configuration
23+
24+
#
25+
# Rendering Configuration
26+
#
27+
# Set custom ASM render and provide a header file with function prototypes
28+
CONFIG_LV_DRAW_SW_ASM_CUSTOM=y
29+
CONFIG_LV_DRAW_SW_ASM_CUSTOM_INCLUDE="esp_lvgl_port_lv_blend_ppa.h"
30+
31+
#
32+
# Memory Settings
33+
#
34+
CONFIG_LV_USE_CUSTOM_MALLOC=y
35+
CONFIG_LV_USE_CLIB_SPRINTF=y
36+
CONFIG_LV_USE_CLIB_STRING=y

0 commit comments

Comments
 (0)