Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature(lvgl_port): Initial support for ppa rendering in lvgl (BSP-563) #409

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions components/esp_lvgl_port/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ if("usb_host_hid" IN_LIST build_components)
endif()

# Include SIMD assembly source code for rendering, only for (9.1.0 <= LVG_version < 9.2.0) and only for esp32 and esp32s3
if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS "9.2.0"))
if(CONFIG_IDF_TARGET_ESP32 OR CONFIG_IDF_TARGET_ESP32S3)
if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS_EQUAL "9.2.0"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it really work with 9.2.0? we had some compatibility problems with this version. If yes, why can't support 9.2.2 too?

if(CONFIG_IDF_TARGET_ESP32 OR CONFIG_IDF_TARGET_ESP32S3 OR CONFIG_IDF_TARGET_ESP32P4)
message(VERBOSE "Compiling SIMD")
if(CONFIG_IDF_TARGET_ESP32S3)
file(GLOB_RECURSE ASM_SRCS ${PORT_PATH}/simd/*_esp32s3.S) # Select only esp32s3 related files
else()
elseif(CONFIG_IDF_TARGET_ESP32)
file(GLOB_RECURSE ASM_SRCS ${PORT_PATH}/simd/*_esp32.S) # Select only esp32 related files
endif()
list(APPEND ADD_SRCS ${ASM_SRCS})
Expand All @@ -91,9 +91,16 @@ if((lvgl_ver VERSION_GREATER_EQUAL "9.1.0") AND (lvgl_ver VERSION_LESS "9.2.0"))
idf_component_get_property(lvgl_lib ${lvgl_name} COMPONENT_LIB)
target_include_directories(${lvgl_lib} PRIVATE "include")

if(CONFIG_IDF_TARGET_ESP32P4)
file(GLOB_RECURSE PPA_SRCS ${PORT_PATH}/ppa/*)
list(APPEND ADD_SRCS ${PPA_SRCS})
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_malloc_core")
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u esp_ppa_fill_for_lvgl")
else()
# Force link .S files
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_argb8888_esp")
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_rgb565_esp")
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_argb8888_esp")
set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u lv_color_blend_to_rgb565_esp")
endif()
endif()
endif()

Expand All @@ -114,5 +121,9 @@ target_link_libraries(lvgl_port_lib PRIVATE
${ADD_LIBS}
)

if(CONFIG_IDF_TARGET_ESP32P4)
target_link_libraries(lvgl_port_lib PRIVATE idf::esp_driver_ppa idf::esp_mm)
endif()

# Finally, link the lvgl_port_lib its esp-idf interface library
target_link_libraries(${COMPONENT_LIB} INTERFACE lvgl_port_lib)
4 changes: 4 additions & 0 deletions components/esp_lvgl_port/examples/mipi_dsi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mipi_dsi_panel)
86 changes: 86 additions & 0 deletions components/esp_lvgl_port/examples/mipi_dsi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
| Supported Targets | ESP32-P4 |
| ----------------- | -------- |

# MIPI DSI LCD Panel Example

[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.

This example shows the general process of installing a MIPI DSI LCD driver, and displays a LVGL widget on the screen.

## How to use the example

### Hardware Required

* An ESP development board, which with MIPI DSI peripheral supported
* 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)
* An USB cable for power supply and programming

### Hardware Connection

The connection between ESP Board and the LCD is as follows:

```text
ESP Board MIPI DSI LCD Panel
+-----------------------+ +-------------------+
| GND +--------------+ GND |
| | | |
| 3V3 +--------------+ VCC |
| | | |
| DSI_CLK_P +--------------+ DSI_CLK_P |
| DSI_CLK_N + + DSI_CLK_N |
| | | |
| DSI_DAT0_P +--------------+ DSI_DAT0_P |
| DAI_DAT0_N + + DAI_DAT0_N |
| | | |
| DSI_DAT1_P +--------------+ DSI_DAT1_P |
| DSI_DAT1_N + + DSI_DAT1_N |
| | | |
| | | |
| BK_LIGHT +--------------+ BLK |
| | | |
| Reset +--------------+ Reset |
| | | |
+-----------------------+ +-------------------+
```

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.

### Configure

Run `idf.py menuconfig` and go to `Example Configuration`:

* Choose the LCD model in `Select MIPI LCD model` according to your board.
* 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.
* 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.
Please note, the actual Refresh Rate should be **double** the square wave frequency.

### Build and Flash

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.

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.

(To exit the serial monitor, type ``Ctrl-]``.)

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.

### Example Output

```bash
...
I (1629) example: MIPI DSI PHY Powered on
I (1629) example: Install MIPI DSI LCD control panel
I (1639) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c
I (1779) example: Install MIPI DSI LCD data panel
I (1799) example: Initialize LVGL library
I (1799) example: Allocate separate LVGL draw buffers from PSRAM
I (1809) example: Use esp_timer as LVGL tick timer
I (1809) example: Create LVGL task
I (1809) example: Starting LVGL task
I (1919) example: Display LVGL Meter Widget
...
```

## Troubleshooting

For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
idf_component_register(SRCS "mipi_dsi_lcd_main.c"
INCLUDE_DIRS ".")
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
menu "Example Configuration"
config EXAMPLE_AVOID_BLUE_SCREEN
bool "Avoid blue screen caused for PSRAM bandwidth"
default y
help
Enable this option, DMA2D peak will be limted, then GDMA will run normal.
endmenu
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencies:
espressif/esp32_p4_function_ev_board:
version: "*"
override_path: "../../../../../bsp/esp32_p4_function_ev_board"
Comment on lines +2 to +4
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For esp_lvgl_port, we try to avoid dependencies on any BSP. Can we removed it?

If not, we can place the example in different location,(not directly into esp_lvgl_port component)

lvgl/lvgl: "~9.2.0"
esp_lcd_ili9881c: "^1.0.0"
esp_lcd_ek79007: "^1.0.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

#include "hal/axi_dma_ll.h"
#include "hal/axi_icm_ll.h"
#include "soc/mipi_dsi_bridge_struct.h"

#include "lv_demos.h"
#include "bsp/esp-bsp.h"

static char *TAG = "app_main";

#define LOG_MEM_INFO (0)

static void esp_dsi_avoid_blue_screen(void)
{
axi_icm_ll_set_dw_gdma_qos_arbiter_prio(0, 9, 10);
axi_icm_ll_set_dw_gdma_qos_arbiter_prio(1, 9, 10);
axi_icm_ll_set_h264_dma_qos_arbiter_prio(1, 5, 5);
axi_icm_ll_set_h264_dma_qos_arbiter_prio(0, 5, 5);
axi_icm_ll_set_dma2d_qos_arbiter_prio(4, 4);
axi_icm_ll_set_cache_qos_arbiter_prio(4, 4);

int peak_level = 5; // 4: 800MB/s, 5: 400MB, 6: 200MB
axi_icm_ll_set_qos_burstiness(AXI_ICM_MASTER_DMA2D, 256);
axi_icm_ll_set_qos_peak_transaction_rate(AXI_ICM_MASTER_DMA2D, peak_level, peak_level + 1);
}

void app_main(void)
{
#if CONFIG_EXAMPLE_AVOID_BLUE_SCREEN && CONFIG_LV_COLOR_DEPTH_24
esp_dsi_avoid_blue_screen();
#endif

/* Initialize display and LVGL */
bsp_display_start();

#if CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR
ESP_LOGI(TAG, "Avoid lcd tearing effect");
#if CONFIG_BSP_DISPLAY_LVGL_FULL_REFRESH
ESP_LOGI(TAG, "LVGL full-refresh");
#elif CONFIG_BSP_DISPLAY_LVGL_DIRECT_MODE
ESP_LOGI(TAG, "LVGL direct-mode");
#endif
#endif

/* Set display brightness to 100% */
bsp_display_backlight_on();

ESP_LOGI(TAG, "Display LVGL demo");
bsp_display_lock(0);
// lv_demo_widgets(); /* A widgets example */
// lv_demo_music(); /* A modern, smartphone-like music player demo. */
// lv_demo_stress(); /* A stress test for LVGL. */
lv_demo_benchmark(); /* A demo to measure the performance of LVGL or to compare different settings. */
bsp_display_unlock();

#if LOG_MEM_INFO
static char buffer[128]; /* Make sure buffer is enough for `sprintf` */
while (1) {
sprintf(buffer, " Biggest / Free / Total\n"
"\t SRAM : [%8d / %8d / %8d]\n"
"\t PSRAM : [%8d / %8d / %8d]",
heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL),
heap_caps_get_free_size(MALLOC_CAP_INTERNAL),
heap_caps_get_total_size(MALLOC_CAP_INTERNAL),
heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM),
heap_caps_get_free_size(MALLOC_CAP_SPIRAM),
heap_caps_get_total_size(MALLOC_CAP_SPIRAM));
ESP_LOGI("MEM", "%s", buffer);

vTaskDelay(pdMS_TO_TICKS(500));
}
#endif
}
5 changes: 5 additions & 0 deletions components/esp_lvgl_port/examples/mipi_dsi/partitions.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 10M,
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
from pytest_embedded import Dut


@pytest.mark.esp32p4
@pytest.mark.generic
def test_rgb_lcd_lvgl(dut: Dut) -> None:
dut.expect_exact('example: Install MIPI DSI LCD control panel')
97 changes: 97 additions & 0 deletions components/esp_lvgl_port/examples/mipi_dsi/sdkconfig.defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@

#
# Serial flasher config
#
CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y

#
# Compiler options
#
CONFIG_COMPILER_OPTIMIZATION_PERF=y

#
# Kernel
#
CONFIG_FREERTOS_HZ=1000

#
# LVGL configuration
#
CONFIG_LV_CONF_SKIP=y

#
# Enable built-in fonts
#
CONFIG_LV_FONT_MONTSERRAT_14=y
CONFIG_LV_FONT_MONTSERRAT_16=y
CONFIG_LV_FONT_MONTSERRAT_18=y
CONFIG_LV_FONT_MONTSERRAT_22=y
CONFIG_LV_FONT_MONTSERRAT_24=y
CONFIG_LV_FONT_MONTSERRAT_32=y

#
# Color Settings
#
CONFIG_LV_COLOR_DEPTH_24=y

#
# Compiler Settings
#
CONFIG_LV_ATTRIBUTE_FAST_MEM_USE_IRAM=y

#
# Logging
#
CONFIG_LV_USE_LOG=n
CONFIG_LV_LOG_LEVEL_ERROR=y
CONFIG_LV_LOG_PRINTF=n

#
# Display
#
CONFIG_BSP_LCD_DPI_BUFFER_NUMS=2
CONFIG_BSP_DISPLAY_LVGL_AVOID_TEAR=y
CONFIG_BSP_DISPLAY_LVGL_DIRECT_MODE=y
CONFIG_BSP_LCD_COLOR_FORMAT_RGB888=y
CONFIG_BSP_LCD_TYPE_1280_800=y
# end of Display
# end of Board Support Package(ESP32-P4)

#
# Partition Table
#
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"

#
# Demos
#
CONFIG_LV_USE_DEMO_WIDGETS=y
CONFIG_LV_DEMO_WIDGETS_SLIDESHOW=y
CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER=y
CONFIG_LV_USE_DEMO_BENCHMARK=y
CONFIG_LV_USE_DEMO_RENDER=y
CONFIG_LV_USE_DEMO_SCROLL=y
CONFIG_LV_USE_DEMO_STRESS=y
CONFIG_LV_USE_DEMO_TRANSFORM=y
CONFIG_LV_USE_DEMO_MUSIC=y
CONFIG_LV_DEMO_MUSIC_SQUARE=y
CONFIG_LV_DEMO_MUSIC_LANDSCAPE=y
CONFIG_LV_DEMO_MUSIC_ROUND=y
CONFIG_LV_DEMO_MUSIC_LARGE=y
CONFIG_LV_DEMO_MUSIC_AUTO_PLAY=y
CONFIG_LV_USE_DEMO_FLEX_LAYOUT=y
CONFIG_LV_USE_DEMO_MULTILANG=n
# end of Demos
# end of LVGL configuration
# end of Component config

#
# Others
#
CONFIG_LV_USE_OBSERVER=y
CONFIG_LV_USE_SYSMON=y
CONFIG_LV_USE_PERF_MONITOR=y
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
CONFIG_SPIRAM=y
CONFIG_SPIRAM_MODE_HEX=y
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM_SPEED_200M=y
CONFIG_SPIRAM_MEMTEST=n
CONFIG_CACHE_L2_CACHE_LINE_128B=y

CONFIG_LV_COLOR_DEPTH_16=n
CONFIG_BSP_LCD_COLOR_FORMAT_RGB565=n

#
# ESP-MM: Memory Management Configurations
#
CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS=y
CONFIG_ESP_MM_CACHE_MSYNC_C2M_CHUNKED_OPS_MAX_LEN=0x4000
# end of ESP-MM: Memory Management Configurations

#
# Example Configuration
#
CONFIG_EXAMPLE_AVOID_BLUE_SCREEN=y
# end of Example Configuration

#
# Rendering Configuration
#
# Set custom ASM render and provide a header file with function prototypes
CONFIG_LV_DRAW_SW_ASM_CUSTOM=y
CONFIG_LV_DRAW_SW_ASM_CUSTOM_INCLUDE="esp_lvgl_port_lv_blend_ppa.h"

#
# Memory Settings
#
CONFIG_LV_USE_CUSTOM_MALLOC=y
CONFIG_LV_USE_CLIB_SPRINTF=y
CONFIG_LV_USE_CLIB_STRING=y
Loading
Loading