From d2b257824429ff045144f4b5b41a4899e3ffad34 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Fri, 17 Apr 2026 19:41:00 +0800 Subject: [PATCH] refactor(examples/ppa): PPA example switch to use RGB LCD panel Also moved the RGB panel initialization code to a common component, which can be reused by other examples. --- docs/en/api-reference/peripherals/ppa.rst | 2 +- docs/zh_CN/api-reference/peripherals/ppa.rst | 2 +- examples/peripherals/.build-test-rules.yml | 4 +- .../rgb_panel_init/CMakeLists.txt | 4 + .../rgb_panel_init}/Kconfig.projbuild | 31 ++- .../rgb_panel_init/example_rgb_panel_init.c | 115 ++++++++++ .../include/example_rgb_panel_init.h | 89 ++++++++ .../lcd/rgb_panel/main/idf_component.yml | 2 + .../lcd/rgb_panel/main/rgb_lcd_example_main.c | 158 ++------------ examples/peripherals/ppa/ppa_dsi/README.md | 126 ----------- .../ppa/ppa_dsi/main/idf_component.yml | 6 - .../peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py | 11 - .../ppa/ppa_dsi/sdkconfig.defaults | 3 - .../{ppa_dsi => ppa_rgb_lcd}/CMakeLists.txt | 2 +- .../peripherals/ppa/ppa_rgb_lcd/README.md | 54 +++++ .../main/CMakeLists.txt | 4 +- .../main/Kconfig.projbuild | 13 -- .../ppa/ppa_rgb_lcd/main/idf_component.yml | 6 + .../ppa/{ppa_dsi => ppa_rgb_lcd}/main/image.c | 0 .../ppa/{ppa_dsi => ppa_rgb_lcd}/main/image.h | 0 .../{ppa_dsi => ppa_rgb_lcd}/main/image.jpg | Bin .../main/ppa_rgb_lcd_main.c} | 203 ++++++++++-------- .../ppa/ppa_rgb_lcd/pytest_ppa_rgb_lcd.py | 19 ++ .../ppa/ppa_rgb_lcd/sdkconfig.defaults | 0 .../ppa_rgb_lcd/sdkconfig.defaults.esp32p4 | 34 +++ .../ppa_rgb_lcd/sdkconfig.defaults.esp32s31 | 42 ++++ 26 files changed, 523 insertions(+), 407 deletions(-) create mode 100644 examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/CMakeLists.txt rename examples/peripherals/lcd/rgb_panel/{main => common_components/rgb_panel_init}/Kconfig.projbuild (98%) create mode 100644 examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/example_rgb_panel_init.c create mode 100644 examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/include/example_rgb_panel_init.h delete mode 100644 examples/peripherals/ppa/ppa_dsi/README.md delete mode 100644 examples/peripherals/ppa/ppa_dsi/main/idf_component.yml delete mode 100644 examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py delete mode 100644 examples/peripherals/ppa/ppa_dsi/sdkconfig.defaults rename examples/peripherals/ppa/{ppa_dsi => ppa_rgb_lcd}/CMakeLists.txt (94%) create mode 100644 examples/peripherals/ppa/ppa_rgb_lcd/README.md rename examples/peripherals/ppa/{ppa_dsi => ppa_rgb_lcd}/main/CMakeLists.txt (77%) rename examples/peripherals/ppa/{ppa_dsi => ppa_rgb_lcd}/main/Kconfig.projbuild (50%) create mode 100644 examples/peripherals/ppa/ppa_rgb_lcd/main/idf_component.yml rename examples/peripherals/ppa/{ppa_dsi => ppa_rgb_lcd}/main/image.c (100%) rename examples/peripherals/ppa/{ppa_dsi => ppa_rgb_lcd}/main/image.h (100%) rename examples/peripherals/ppa/{ppa_dsi => ppa_rgb_lcd}/main/image.jpg (100%) rename examples/peripherals/ppa/{ppa_dsi/main/ppa_dsi_main.c => ppa_rgb_lcd/main/ppa_rgb_lcd_main.c} (65%) create mode 100644 examples/peripherals/ppa/ppa_rgb_lcd/pytest_ppa_rgb_lcd.py create mode 100644 examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults create mode 100644 examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32p4 create mode 100644 examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32s31 diff --git a/docs/en/api-reference/peripherals/ppa.rst b/docs/en/api-reference/peripherals/ppa.rst index f314b2add91..6ee441c8e5e 100644 --- a/docs/en/api-reference/peripherals/ppa.rst +++ b/docs/en/api-reference/peripherals/ppa.rst @@ -175,7 +175,7 @@ The PPA operations are acted on the target block of an input picture. Therefore, Application Examples ^^^^^^^^^^^^^^^^^^^^ -* :example:`peripherals/ppa/ppa_dsi` - PPA with DSI display example. The image used in this example will be first scaled up, rotated at counter-clockwise direction and rotated back, mirrored and mirror back, and scaled down. Then the image will be blended with a whole red image with less transparency. Next the `ESP32` word will be color-keyed out. Lastly a frame will be filled around the `ESP32`. +* :example:`peripherals/ppa/ppa_rgb_lcd` - PPA with RGB LCD display example. The image used in this example will be first scaled up, rotated at counter-clockwise direction and rotated back, mirrored and mirror back, and scaled down. Then the image will be blended with a whole red image with less transparency. Next the `ESP32` word will be color-keyed out. Lastly a frame will be filled around the `ESP32`. API Reference ------------- diff --git a/docs/zh_CN/api-reference/peripherals/ppa.rst b/docs/zh_CN/api-reference/peripherals/ppa.rst index f1dc9f850bb..3ab4551c0fa 100644 --- a/docs/zh_CN/api-reference/peripherals/ppa.rst +++ b/docs/zh_CN/api-reference/peripherals/ppa.rst @@ -175,7 +175,7 @@ PPA 操作作用于输入图片的目标块。因此,完成一次 PPA 事务 应用示例 ^^^^^^^^^ -* :example:`peripherals/ppa/ppa_dsi` - 使用 DSI 显示屏的 PPA 示例。首先,该示例所使用的图像会被放大、逆时针旋转后复原、镜像后复原、缩小。其次,该图像将与一个透明度较低的全红图像叠加,`ESP32` 字样将被色键移除。最后,会在 `ESP32` 周围填充一个框。 +* :example:`peripherals/ppa/ppa_rgb_lcd` - 使用 RGB LCD 显示屏的 PPA 示例。首先,该示例所使用的图像会被放大、逆时针旋转后复原、镜像后复原、缩小。其次,该图像将与一个透明度较低的全红图像叠加,`ESP32` 字样将被色键移除。最后,会在 `ESP32` 周围填充一个框。 API 参考 -------- diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index e17c4588ca0..6b0731ad637 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -512,9 +512,9 @@ examples/peripherals/pcnt: - esp_driver_pcnt - soc -examples/peripherals/ppa/ppa_dsi: +examples/peripherals/ppa/ppa_rgb_lcd: disable: - - if: SOC_PPA_SUPPORTED != 1 or SOC_MIPI_DSI_SUPPORTED != 1 + - if: SOC_PPA_SUPPORTED != 1 or SOC_LCD_RGB_SUPPORTED != 1 depends_components: - esp_driver_dma - esp_driver_ppa diff --git a/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/CMakeLists.txt b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/CMakeLists.txt new file mode 100644 index 00000000000..d91a161dff5 --- /dev/null +++ b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_register(SRCS "example_rgb_panel_init.c" + INCLUDE_DIRS "include" + REQUIRES esp_lcd esp_driver_gpio + ) diff --git a/examples/peripherals/lcd/rgb_panel/main/Kconfig.projbuild b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/Kconfig.projbuild similarity index 98% rename from examples/peripherals/lcd/rgb_panel/main/Kconfig.projbuild rename to examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/Kconfig.projbuild index 5dc913d6da3..df821a316f3 100644 --- a/examples/peripherals/lcd/rgb_panel/main/Kconfig.projbuild +++ b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/Kconfig.projbuild @@ -1,4 +1,4 @@ -menu "Example Configuration" +menu "RGB Panel Configuration" choice EXAMPLE_LCD_BUFFER_MODE prompt "RGB LCD Buffer Mode" default EXAMPLE_USE_SINGLE_FB @@ -43,122 +43,149 @@ menu "Example Configuration" default 16 if EXAMPLE_LCD_DATA_LINES_16 default 24 if EXAMPLE_LCD_DATA_LINES_24 - menu "GPIO assignment" + menu "RGB LCD GPIO assignment" config EXAMPLE_LCD_VSYNC_GPIO int "VSYNC GPIO" help GPIO pin number for VSYNC signal. + config EXAMPLE_LCD_HSYNC_GPIO int "HSYNC GPIO" help GPIO pin number for HSYNC signal. + config EXAMPLE_LCD_DE_GPIO int "DE GPIO" help GPIO pin number for DE signal. + config EXAMPLE_LCD_PCLK_GPIO int "PCLK GPIO" help GPIO pin number for PCLK signal. + config EXAMPLE_LCD_DATA0_GPIO int "DATA0 GPIO" help GPIO pin number for data bus[0]. + config EXAMPLE_LCD_DATA1_GPIO int "DATA1 GPIO" help GPIO pin number for data bus[1]. + config EXAMPLE_LCD_DATA2_GPIO int "DATA2 GPIO" help GPIO pin number for data bus[2]. + config EXAMPLE_LCD_DATA3_GPIO int "DATA3 GPIO" help GPIO pin number for data bus[3]. + config EXAMPLE_LCD_DATA4_GPIO int "DATA4 GPIO" help GPIO pin number for data bus[4]. + config EXAMPLE_LCD_DATA5_GPIO int "DATA5 GPIO" help GPIO pin number for data bus[5]. + config EXAMPLE_LCD_DATA6_GPIO int "DATA6 GPIO" help GPIO pin number for data bus[6]. + config EXAMPLE_LCD_DATA7_GPIO int "DATA7 GPIO" help GPIO pin number for data bus[7]. + config EXAMPLE_LCD_DATA8_GPIO int "DATA8 GPIO" help GPIO pin number for data bus[8]. + config EXAMPLE_LCD_DATA9_GPIO int "DATA9 GPIO" help GPIO pin number for data bus[9]. + config EXAMPLE_LCD_DATA10_GPIO int "DATA10 GPIO" help GPIO pin number for data bus[10]. + config EXAMPLE_LCD_DATA11_GPIO int "DATA11 GPIO" help GPIO pin number for data bus[11]. + config EXAMPLE_LCD_DATA12_GPIO int "DATA12 GPIO" help GPIO pin number for data bus[12]. + config EXAMPLE_LCD_DATA13_GPIO int "DATA13 GPIO" help GPIO pin number for data bus[13]. + config EXAMPLE_LCD_DATA14_GPIO int "DATA14 GPIO" help GPIO pin number for data bus[14]. + config EXAMPLE_LCD_DATA15_GPIO int "DATA15 GPIO" help GPIO pin number for data bus[15]. + config EXAMPLE_LCD_DATA16_GPIO int "DATA16 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[16]. + config EXAMPLE_LCD_DATA17_GPIO int "DATA17 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[17]. + config EXAMPLE_LCD_DATA18_GPIO int "DATA18 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[18]. + config EXAMPLE_LCD_DATA19_GPIO int "DATA19 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[19]. + config EXAMPLE_LCD_DATA20_GPIO int "DATA20 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[20]. + config EXAMPLE_LCD_DATA21_GPIO int "DATA21 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[21]. + config EXAMPLE_LCD_DATA22_GPIO int "DATA22 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 help GPIO pin number for data bus[22]. + config EXAMPLE_LCD_DATA23_GPIO int "DATA23 GPIO" depends on EXAMPLE_LCD_DATA_LINES > 16 diff --git a/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/example_rgb_panel_init.c b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/example_rgb_panel_init.c new file mode 100644 index 00000000000..305e73180f8 --- /dev/null +++ b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/example_rgb_panel_init.c @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "example_rgb_panel_init.h" +#include "driver/gpio.h" +#include "esp_check.h" +#include "esp_lcd_panel_rgb.h" + +static const char *TAG = "rgb_panel_init"; + +static void s_fill_data_gpio_nums(gpio_num_t data_gpio_nums[ESP_LCD_RGB_BUS_WIDTH_MAX]) +{ + data_gpio_nums[0] = EXAMPLE_PIN_NUM_DATA0; + data_gpio_nums[1] = EXAMPLE_PIN_NUM_DATA1; + data_gpio_nums[2] = EXAMPLE_PIN_NUM_DATA2; + data_gpio_nums[3] = EXAMPLE_PIN_NUM_DATA3; + data_gpio_nums[4] = EXAMPLE_PIN_NUM_DATA4; + data_gpio_nums[5] = EXAMPLE_PIN_NUM_DATA5; + data_gpio_nums[6] = EXAMPLE_PIN_NUM_DATA6; + data_gpio_nums[7] = EXAMPLE_PIN_NUM_DATA7; + data_gpio_nums[8] = EXAMPLE_PIN_NUM_DATA8; + data_gpio_nums[9] = EXAMPLE_PIN_NUM_DATA9; + data_gpio_nums[10] = EXAMPLE_PIN_NUM_DATA10; + data_gpio_nums[11] = EXAMPLE_PIN_NUM_DATA11; + data_gpio_nums[12] = EXAMPLE_PIN_NUM_DATA12; + data_gpio_nums[13] = EXAMPLE_PIN_NUM_DATA13; + data_gpio_nums[14] = EXAMPLE_PIN_NUM_DATA14; + data_gpio_nums[15] = EXAMPLE_PIN_NUM_DATA15; +#if CONFIG_EXAMPLE_LCD_DATA_LINES > 16 + data_gpio_nums[16] = EXAMPLE_PIN_NUM_DATA16; + data_gpio_nums[17] = EXAMPLE_PIN_NUM_DATA17; + data_gpio_nums[18] = EXAMPLE_PIN_NUM_DATA18; + data_gpio_nums[19] = EXAMPLE_PIN_NUM_DATA19; + data_gpio_nums[20] = EXAMPLE_PIN_NUM_DATA20; + data_gpio_nums[21] = EXAMPLE_PIN_NUM_DATA21; + data_gpio_nums[22] = EXAMPLE_PIN_NUM_DATA22; + data_gpio_nums[23] = EXAMPLE_PIN_NUM_DATA23; +#endif +} + +esp_err_t example_rgb_panel_init_backlight(void) +{ +#if EXAMPLE_PIN_NUM_BK_LIGHT >= 0 + gpio_config_t bk_gpio_config = { + .mode = GPIO_MODE_OUTPUT, + .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT, + }; + ESP_RETURN_ON_ERROR(gpio_config(&bk_gpio_config), TAG, "configure backlight gpio failed"); +#endif + + return ESP_OK; +} + +void example_rgb_panel_set_backlight(bool on) +{ + if (EXAMPLE_PIN_NUM_BK_LIGHT < 0) { + return; + } + + gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, on ? EXAMPLE_LCD_BK_LIGHT_ON_LEVEL : EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL); +} + +esp_err_t example_rgb_panel_new(esp_lcd_panel_handle_t *panel_handle) +{ + ESP_RETURN_ON_FALSE(panel_handle, ESP_ERR_INVALID_ARG, TAG, "panel handle is null"); + + esp_lcd_rgb_panel_config_t panel_config = { + .data_width = CONFIG_EXAMPLE_LCD_DATA_LINES, + .dma_burst_size = 64, + .num_fbs = EXAMPLE_RGB_PANEL_NUM_FBS, +#if CONFIG_EXAMPLE_USE_BOUNCE_BUFFER + .bounce_buffer_size_px = 20 * EXAMPLE_LCD_H_RES, +#endif + .clk_src = LCD_CLK_SRC_DEFAULT, + .disp_gpio_num = EXAMPLE_PIN_NUM_DISP_EN, + .pclk_gpio_num = EXAMPLE_PIN_NUM_PCLK, + .vsync_gpio_num = EXAMPLE_PIN_NUM_VSYNC, + .hsync_gpio_num = EXAMPLE_PIN_NUM_HSYNC, + .de_gpio_num = EXAMPLE_PIN_NUM_DE, + .timings = { + .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, + .h_res = EXAMPLE_LCD_H_RES, + .v_res = EXAMPLE_LCD_V_RES, + .hsync_back_porch = EXAMPLE_LCD_HBP, + .hsync_front_porch = EXAMPLE_LCD_HFP, + .hsync_pulse_width = EXAMPLE_LCD_HSYNC, + .vsync_back_porch = EXAMPLE_LCD_VBP, + .vsync_front_porch = EXAMPLE_LCD_VFP, + .vsync_pulse_width = EXAMPLE_LCD_VSYNC, + .flags = { + .pclk_active_neg = true, + }, + }, + .flags.fb_in_psram = true, + }; + s_fill_data_gpio_nums(panel_config.data_gpio_nums); + return esp_lcd_new_rgb_panel(&panel_config, panel_handle); +} + +esp_err_t example_rgb_panel_init(esp_lcd_panel_handle_t panel_handle) +{ + ESP_RETURN_ON_FALSE(panel_handle, ESP_ERR_INVALID_ARG, TAG, "panel handle is null"); + ESP_RETURN_ON_ERROR(esp_lcd_panel_reset(panel_handle), TAG, "reset RGB panel failed"); + ESP_RETURN_ON_ERROR(esp_lcd_panel_init(panel_handle), TAG, "init RGB panel failed"); + return ESP_OK; +} + +esp_err_t example_rgb_panel_deinit(esp_lcd_panel_handle_t panel_handle) +{ + ESP_RETURN_ON_FALSE(panel_handle, ESP_ERR_INVALID_ARG, TAG, "panel handle is null"); + return esp_lcd_panel_del(panel_handle); +} diff --git a/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/include/example_rgb_panel_init.h b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/include/example_rgb_panel_init.h new file mode 100644 index 00000000000..031f1319f98 --- /dev/null +++ b/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init/include/example_rgb_panel_init.h @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "esp_lcd_panel_ops.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Refresh Rate = 18000000/(1+40+20+800)/(1+10+5+480) = 42Hz +#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (18 * 1000 * 1000) +#define EXAMPLE_LCD_H_RES 800 +#define EXAMPLE_LCD_V_RES 480 +#define EXAMPLE_LCD_HSYNC 1 +#define EXAMPLE_LCD_HBP 40 +#define EXAMPLE_LCD_HFP 20 +#define EXAMPLE_LCD_VSYNC 1 +#define EXAMPLE_LCD_VBP 10 +#define EXAMPLE_LCD_VFP 5 + +#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 1 +#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL +#define EXAMPLE_PIN_NUM_BK_LIGHT -1 +#define EXAMPLE_PIN_NUM_DISP_EN -1 + +#define EXAMPLE_PIN_NUM_HSYNC CONFIG_EXAMPLE_LCD_HSYNC_GPIO +#define EXAMPLE_PIN_NUM_VSYNC CONFIG_EXAMPLE_LCD_VSYNC_GPIO +#define EXAMPLE_PIN_NUM_DE CONFIG_EXAMPLE_LCD_DE_GPIO +#define EXAMPLE_PIN_NUM_PCLK CONFIG_EXAMPLE_LCD_PCLK_GPIO + +#define EXAMPLE_PIN_NUM_DATA0 CONFIG_EXAMPLE_LCD_DATA0_GPIO +#define EXAMPLE_PIN_NUM_DATA1 CONFIG_EXAMPLE_LCD_DATA1_GPIO +#define EXAMPLE_PIN_NUM_DATA2 CONFIG_EXAMPLE_LCD_DATA2_GPIO +#define EXAMPLE_PIN_NUM_DATA3 CONFIG_EXAMPLE_LCD_DATA3_GPIO +#define EXAMPLE_PIN_NUM_DATA4 CONFIG_EXAMPLE_LCD_DATA4_GPIO +#define EXAMPLE_PIN_NUM_DATA5 CONFIG_EXAMPLE_LCD_DATA5_GPIO +#define EXAMPLE_PIN_NUM_DATA6 CONFIG_EXAMPLE_LCD_DATA6_GPIO +#define EXAMPLE_PIN_NUM_DATA7 CONFIG_EXAMPLE_LCD_DATA7_GPIO +#define EXAMPLE_PIN_NUM_DATA8 CONFIG_EXAMPLE_LCD_DATA8_GPIO +#define EXAMPLE_PIN_NUM_DATA9 CONFIG_EXAMPLE_LCD_DATA9_GPIO +#define EXAMPLE_PIN_NUM_DATA10 CONFIG_EXAMPLE_LCD_DATA10_GPIO +#define EXAMPLE_PIN_NUM_DATA11 CONFIG_EXAMPLE_LCD_DATA11_GPIO +#define EXAMPLE_PIN_NUM_DATA12 CONFIG_EXAMPLE_LCD_DATA12_GPIO +#define EXAMPLE_PIN_NUM_DATA13 CONFIG_EXAMPLE_LCD_DATA13_GPIO +#define EXAMPLE_PIN_NUM_DATA14 CONFIG_EXAMPLE_LCD_DATA14_GPIO +#define EXAMPLE_PIN_NUM_DATA15 CONFIG_EXAMPLE_LCD_DATA15_GPIO +#if CONFIG_EXAMPLE_LCD_DATA_LINES > 16 +#define EXAMPLE_PIN_NUM_DATA16 CONFIG_EXAMPLE_LCD_DATA16_GPIO +#define EXAMPLE_PIN_NUM_DATA17 CONFIG_EXAMPLE_LCD_DATA17_GPIO +#define EXAMPLE_PIN_NUM_DATA18 CONFIG_EXAMPLE_LCD_DATA18_GPIO +#define EXAMPLE_PIN_NUM_DATA19 CONFIG_EXAMPLE_LCD_DATA19_GPIO +#define EXAMPLE_PIN_NUM_DATA20 CONFIG_EXAMPLE_LCD_DATA20_GPIO +#define EXAMPLE_PIN_NUM_DATA21 CONFIG_EXAMPLE_LCD_DATA21_GPIO +#define EXAMPLE_PIN_NUM_DATA22 CONFIG_EXAMPLE_LCD_DATA22_GPIO +#define EXAMPLE_PIN_NUM_DATA23 CONFIG_EXAMPLE_LCD_DATA23_GPIO +#endif + +#if CONFIG_EXAMPLE_USE_DOUBLE_FB +#define EXAMPLE_RGB_PANEL_NUM_FBS 2 +#else +#define EXAMPLE_RGB_PANEL_NUM_FBS 1 +#endif + +#if CONFIG_EXAMPLE_LCD_DATA_LINES_16 +#define EXAMPLE_PIXEL_SIZE 2 +#elif CONFIG_EXAMPLE_LCD_DATA_LINES_24 +#define EXAMPLE_PIXEL_SIZE 3 +#endif + +esp_err_t example_rgb_panel_init_backlight(void); +void example_rgb_panel_set_backlight(bool on); +esp_err_t example_rgb_panel_new(esp_lcd_panel_handle_t *panel_handle); +esp_err_t example_rgb_panel_init(esp_lcd_panel_handle_t panel_handle); +esp_err_t example_rgb_panel_deinit(esp_lcd_panel_handle_t panel_handle); + +#ifdef __cplusplus +} +#endif diff --git a/examples/peripherals/lcd/rgb_panel/main/idf_component.yml b/examples/peripherals/lcd/rgb_panel/main/idf_component.yml index 4ca86dce7ec..9bcf75b4fe4 100644 --- a/examples/peripherals/lcd/rgb_panel/main/idf_component.yml +++ b/examples/peripherals/lcd/rgb_panel/main/idf_component.yml @@ -1,2 +1,4 @@ dependencies: lvgl/lvgl: "9.2.0" + rgb_panel_init: + path: ${IDF_PATH}/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init diff --git a/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c b/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c index aedf4c3365f..b9d724906e5 100644 --- a/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c +++ b/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: CC0-1.0 */ @@ -12,80 +12,22 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_timer.h" +#include "example_rgb_panel_init.h" #include "esp_lcd_panel_ops.h" #include "esp_lcd_panel_rgb.h" -#include "driver/gpio.h" #include "esp_err.h" #include "esp_log.h" #include "lvgl.h" static const char *TAG = "example"; -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////// Please update the following configuration according to your LCD spec ////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Refresh Rate = 18000000/(1+40+20+800)/(1+10+5+480) = 42Hz -#define EXAMPLE_LCD_PIXEL_CLOCK_HZ (18 * 1000 * 1000) -#define EXAMPLE_LCD_H_RES 800 -#define EXAMPLE_LCD_V_RES 480 -#define EXAMPLE_LCD_HSYNC 1 -#define EXAMPLE_LCD_HBP 40 -#define EXAMPLE_LCD_HFP 20 -#define EXAMPLE_LCD_VSYNC 1 -#define EXAMPLE_LCD_VBP 10 -#define EXAMPLE_LCD_VFP 5 - -#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL 1 -#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL -#define EXAMPLE_PIN_NUM_BK_LIGHT -1 -#define EXAMPLE_PIN_NUM_DISP_EN -1 - -#define EXAMPLE_PIN_NUM_HSYNC CONFIG_EXAMPLE_LCD_HSYNC_GPIO -#define EXAMPLE_PIN_NUM_VSYNC CONFIG_EXAMPLE_LCD_VSYNC_GPIO -#define EXAMPLE_PIN_NUM_DE CONFIG_EXAMPLE_LCD_DE_GPIO -#define EXAMPLE_PIN_NUM_PCLK CONFIG_EXAMPLE_LCD_PCLK_GPIO - -#define EXAMPLE_PIN_NUM_DATA0 CONFIG_EXAMPLE_LCD_DATA0_GPIO -#define EXAMPLE_PIN_NUM_DATA1 CONFIG_EXAMPLE_LCD_DATA1_GPIO -#define EXAMPLE_PIN_NUM_DATA2 CONFIG_EXAMPLE_LCD_DATA2_GPIO -#define EXAMPLE_PIN_NUM_DATA3 CONFIG_EXAMPLE_LCD_DATA3_GPIO -#define EXAMPLE_PIN_NUM_DATA4 CONFIG_EXAMPLE_LCD_DATA4_GPIO -#define EXAMPLE_PIN_NUM_DATA5 CONFIG_EXAMPLE_LCD_DATA5_GPIO -#define EXAMPLE_PIN_NUM_DATA6 CONFIG_EXAMPLE_LCD_DATA6_GPIO -#define EXAMPLE_PIN_NUM_DATA7 CONFIG_EXAMPLE_LCD_DATA7_GPIO -#define EXAMPLE_PIN_NUM_DATA8 CONFIG_EXAMPLE_LCD_DATA8_GPIO -#define EXAMPLE_PIN_NUM_DATA9 CONFIG_EXAMPLE_LCD_DATA9_GPIO -#define EXAMPLE_PIN_NUM_DATA10 CONFIG_EXAMPLE_LCD_DATA10_GPIO -#define EXAMPLE_PIN_NUM_DATA11 CONFIG_EXAMPLE_LCD_DATA11_GPIO -#define EXAMPLE_PIN_NUM_DATA12 CONFIG_EXAMPLE_LCD_DATA12_GPIO -#define EXAMPLE_PIN_NUM_DATA13 CONFIG_EXAMPLE_LCD_DATA13_GPIO -#define EXAMPLE_PIN_NUM_DATA14 CONFIG_EXAMPLE_LCD_DATA14_GPIO -#define EXAMPLE_PIN_NUM_DATA15 CONFIG_EXAMPLE_LCD_DATA15_GPIO -#if CONFIG_EXAMPLE_LCD_DATA_LINES > 16 -#define EXAMPLE_PIN_NUM_DATA16 CONFIG_EXAMPLE_LCD_DATA16_GPIO -#define EXAMPLE_PIN_NUM_DATA17 CONFIG_EXAMPLE_LCD_DATA17_GPIO -#define EXAMPLE_PIN_NUM_DATA18 CONFIG_EXAMPLE_LCD_DATA18_GPIO -#define EXAMPLE_PIN_NUM_DATA19 CONFIG_EXAMPLE_LCD_DATA19_GPIO -#define EXAMPLE_PIN_NUM_DATA20 CONFIG_EXAMPLE_LCD_DATA20_GPIO -#define EXAMPLE_PIN_NUM_DATA21 CONFIG_EXAMPLE_LCD_DATA21_GPIO -#define EXAMPLE_PIN_NUM_DATA22 CONFIG_EXAMPLE_LCD_DATA22_GPIO -#define EXAMPLE_PIN_NUM_DATA23 CONFIG_EXAMPLE_LCD_DATA23_GPIO -#endif - -#if CONFIG_EXAMPLE_USE_DOUBLE_FB -#define EXAMPLE_LCD_NUM_FB 2 -#else -#define EXAMPLE_LCD_NUM_FB 1 -#endif // CONFIG_EXAMPLE_USE_DOUBLE_FB - +// Keep the LVGL draw format local to this example. The panel bus format is configured separately. #if CONFIG_EXAMPLE_LCD_DATA_LINES_16 -#define EXAMPLE_DATA_BUS_WIDTH 16 -#define EXAMPLE_PIXEL_SIZE 2 -#define EXAMPLE_LV_COLOR_FORMAT LV_COLOR_FORMAT_RGB565 +#define EXAMPLE_LV_COLOR_FORMAT LV_COLOR_FORMAT_RGB565 #elif CONFIG_EXAMPLE_LCD_DATA_LINES_24 -#define EXAMPLE_DATA_BUS_WIDTH 24 -#define EXAMPLE_PIXEL_SIZE 3 -#define EXAMPLE_LV_COLOR_FORMAT LV_COLOR_FORMAT_RGB888 +#define EXAMPLE_LV_COLOR_FORMAT LV_COLOR_FORMAT_RGB888 +#else +#error "Unsupported LVGL color format" #endif //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -144,97 +86,21 @@ static void example_lvgl_port_task(void *arg) } } -static void example_bsp_init_lcd_backlight(void) -{ -#if EXAMPLE_PIN_NUM_BK_LIGHT >= 0 - gpio_config_t bk_gpio_config = { - .mode = GPIO_MODE_OUTPUT, - .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT - }; - ESP_ERROR_CHECK(gpio_config(&bk_gpio_config)); -#endif -} - -static void example_bsp_set_lcd_backlight(uint32_t level) -{ -#if EXAMPLE_PIN_NUM_BK_LIGHT >= 0 - gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, level); -#endif -} - void app_main(void) { ESP_LOGI(TAG, "Turn off LCD backlight"); - example_bsp_init_lcd_backlight(); - example_bsp_set_lcd_backlight(EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL); + ESP_ERROR_CHECK(example_rgb_panel_init_backlight()); + example_rgb_panel_set_backlight(false); ESP_LOGI(TAG, "Install RGB LCD panel driver"); esp_lcd_panel_handle_t panel_handle = NULL; - esp_lcd_rgb_panel_config_t panel_config = { - .data_width = EXAMPLE_DATA_BUS_WIDTH, - .dma_burst_size = 64, - .num_fbs = EXAMPLE_LCD_NUM_FB, -#if CONFIG_EXAMPLE_USE_BOUNCE_BUFFER - .bounce_buffer_size_px = 20 * EXAMPLE_LCD_H_RES, -#endif - .clk_src = LCD_CLK_SRC_DEFAULT, - .disp_gpio_num = EXAMPLE_PIN_NUM_DISP_EN, - .pclk_gpio_num = EXAMPLE_PIN_NUM_PCLK, - .vsync_gpio_num = EXAMPLE_PIN_NUM_VSYNC, - .hsync_gpio_num = EXAMPLE_PIN_NUM_HSYNC, - .de_gpio_num = EXAMPLE_PIN_NUM_DE, - .data_gpio_nums = { - EXAMPLE_PIN_NUM_DATA0, - EXAMPLE_PIN_NUM_DATA1, - EXAMPLE_PIN_NUM_DATA2, - EXAMPLE_PIN_NUM_DATA3, - EXAMPLE_PIN_NUM_DATA4, - EXAMPLE_PIN_NUM_DATA5, - EXAMPLE_PIN_NUM_DATA6, - EXAMPLE_PIN_NUM_DATA7, - EXAMPLE_PIN_NUM_DATA8, - EXAMPLE_PIN_NUM_DATA9, - EXAMPLE_PIN_NUM_DATA10, - EXAMPLE_PIN_NUM_DATA11, - EXAMPLE_PIN_NUM_DATA12, - EXAMPLE_PIN_NUM_DATA13, - EXAMPLE_PIN_NUM_DATA14, - EXAMPLE_PIN_NUM_DATA15, -#if CONFIG_EXAMPLE_LCD_DATA_LINES > 16 - EXAMPLE_PIN_NUM_DATA16, - EXAMPLE_PIN_NUM_DATA17, - EXAMPLE_PIN_NUM_DATA18, - EXAMPLE_PIN_NUM_DATA19, - EXAMPLE_PIN_NUM_DATA20, - EXAMPLE_PIN_NUM_DATA21, - EXAMPLE_PIN_NUM_DATA22, - EXAMPLE_PIN_NUM_DATA23 -#endif - }, - .timings = { - .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, - .h_res = EXAMPLE_LCD_H_RES, - .v_res = EXAMPLE_LCD_V_RES, - .hsync_back_porch = EXAMPLE_LCD_HBP, - .hsync_front_porch = EXAMPLE_LCD_HFP, - .hsync_pulse_width = EXAMPLE_LCD_HSYNC, - .vsync_back_porch = EXAMPLE_LCD_VBP, - .vsync_front_porch = EXAMPLE_LCD_VFP, - .vsync_pulse_width = EXAMPLE_LCD_VSYNC, - .flags = { - .pclk_active_neg = true, - }, - }, - .flags.fb_in_psram = true, // allocate frame buffer in PSRAM - }; - ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle)); + ESP_ERROR_CHECK(example_rgb_panel_new(&panel_handle)); ESP_LOGI(TAG, "Initialize RGB LCD panel"); - ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); - ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); + ESP_ERROR_CHECK(example_rgb_panel_init(panel_handle)); ESP_LOGI(TAG, "Turn on LCD backlight"); - example_bsp_set_lcd_backlight(EXAMPLE_LCD_BK_LIGHT_ON_LEVEL); + example_rgb_panel_set_backlight(true); ESP_LOGI(TAG, "Initialize LVGL library"); lv_init(); diff --git a/examples/peripherals/ppa/ppa_dsi/README.md b/examples/peripherals/ppa/ppa_dsi/README.md deleted file mode 100644 index c02f404be75..00000000000 --- a/examples/peripherals/ppa/ppa_dsi/README.md +++ /dev/null @@ -1,126 +0,0 @@ -| Supported Targets | ESP32-P4 | -| ----------------- | -------- | - - -# PPA DSI example - -## Overview - -This example demonstrates how to use the esp_driver_ppa component to process a given image and display it via DSI interface. - -The example used image will be first scaled up, rotated at counter-clockwise direction and rotated back, mirrored and mirror back, and scaled down. Then the image will be blended with a whole red image with less transparency. Next the `ESP32` word will be color-keyed out. Lastly a frame will be filled around the `ESP32`. - -## Usage - -The subsections below give only absolutely necessary information. For full steps to configure ESP-IDF and use it to build and run projects, see [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started). - - -### Hardware Required - -This example requires: - -- EK79007 or ILI9881C LCD screen -- ESP32P4 devkit - -**Note:** For EK79007 you will need to connect following pins: -- 5V - 5V -- GND - GND -- RST_LCD - 3V3 - - - GND - ┌─────────────────────────────────────────────────────────┐ - │ │ - │ │ - │ │ - │ │ - │ │ - │ │ - │ │ - │ │ - ┌───────────────-─────────────┴──────────────────┐ │ - │ │ ┌──────────┴───────────┐ - │ │ DSI DATA 1P │ │ - │ ├───────────────────────────┤ │ - │ │ │ │ - │ │ DSI DATA 1N │ │ - │ ├───────────────────────────┤ │ - │ ESP32-P4 │ │ │ - │ │ DSI CLK N │ LCD Screen │ - │ ├───────────────────────────┤ │ - │ │ │ │ - │ │ DSI CLK P │ │ - │ ├───────────────────────────┤ │ - │ │ │ │ - │ │ DSI DATA 0P │ │ - │ ├───────────────────────────┤ │ - │ │ │ │ - │ │ DSI DATA 0N │ │ - │ ├───────────────────────────┤ │ - │ │ │ │ - │ │ └──────────────────────┘ - │ │ - │ │ - │ │ - │ │ - │ │ - │ │ - └────────────────────────────────────────────────┘ - - -### Set Chip Target - -First of all, your target must be supported by both: - -- **By your ESP-IDF version**: For the full list of supported targets, run: - ``` - idf.py --list-targets - ``` -- **By this example**: For the full list of supported targets, refer to the supported targets table at the top of this README. - -After you make sure that your target is supported, go to your example project directory and [set the chip target](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/idf-py.html#select-the-target-chip-set-target): - -``` -idf.py set-target -``` - -For example, to set esp32-P4 as the chip target, run: - -``` -idf.py set-target esp32p4 -``` - - -### Build and Flash - -Execute the following command to build the project, flash it to your development board, and run the monitor tool to view the serial output: - -``` -idf.py build flash monitor -``` - -This command can be reduced to `idf.py flash monitor`. - -If the above command fails, check the log on the serial monitor which usually provides information on the possible cause of the issue. - -To exit the serial monitor, use `Ctrl` + `]`. - - -## Example Output - -If you see the following console output, your example should be running correctly: - -``` -I (1555) main_task: Calling app_main() -I (1555) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c -I (1795) ppa_dsi: JPEG image decoded! Size of the decoded image is: 320px x 240px -start srm operations -start blend operations -start fill operations -I (10085) main_task: Returned from app_main() -``` - - -## Reference - -- [ESP-IDF: Pixel-Processing Accelerator](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/ppa.html) diff --git a/examples/peripherals/ppa/ppa_dsi/main/idf_component.yml b/examples/peripherals/ppa/ppa_dsi/main/idf_component.yml deleted file mode 100644 index 4345977f95f..00000000000 --- a/examples/peripherals/ppa/ppa_dsi/main/idf_component.yml +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: - idf: - version: ">=5.3.0" - dsi_init: - path: ${IDF_PATH}/examples/peripherals/camera/common_components/dsi_init - esp_jpeg: ">=1.0.2" diff --git a/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py b/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py deleted file mode 100644 index f8a55926c16..00000000000 --- a/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: CC0-1.0 -import pytest -from pytest_embedded import Dut -from pytest_embedded_idf.utils import idf_parametrize - - -@pytest.mark.generic -@idf_parametrize('target', ['esp32p4'], indirect=['target']) -def test_ppa_dsi(dut: Dut) -> None: - dut.expect_exact('Calling app_main()') diff --git a/examples/peripherals/ppa/ppa_dsi/sdkconfig.defaults b/examples/peripherals/ppa/ppa_dsi/sdkconfig.defaults deleted file mode 100644 index 73cebe337da..00000000000 --- a/examples/peripherals/ppa/ppa_dsi/sdkconfig.defaults +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_SPIRAM=y -CONFIG_IDF_EXPERIMENTAL_FEATURES=y -CONFIG_SPIRAM_SPEED_200M=y diff --git a/examples/peripherals/ppa/ppa_dsi/CMakeLists.txt b/examples/peripherals/ppa/ppa_rgb_lcd/CMakeLists.txt similarity index 94% rename from examples/peripherals/ppa/ppa_dsi/CMakeLists.txt rename to examples/peripherals/ppa/ppa_rgb_lcd/CMakeLists.txt index ccd3fbdf81f..821828f7273 100644 --- a/examples/peripherals/ppa/ppa_dsi/CMakeLists.txt +++ b/examples/peripherals/ppa/ppa_rgb_lcd/CMakeLists.txt @@ -5,4 +5,4 @@ cmake_minimum_required(VERSION 3.22) include($ENV{IDF_PATH}/tools/cmake/project.cmake) # "Trim" the build. Include the minimal set of components, main, and anything it depends on. idf_build_set_property(MINIMAL_BUILD ON) -project(ppa_dsi) +project(ppa_rgb_lcd) diff --git a/examples/peripherals/ppa/ppa_rgb_lcd/README.md b/examples/peripherals/ppa/ppa_rgb_lcd/README.md new file mode 100644 index 00000000000..a2ec7de53ee --- /dev/null +++ b/examples/peripherals/ppa/ppa_rgb_lcd/README.md @@ -0,0 +1,54 @@ +| Supported Targets | ESP32-P4 | ESP32-S31 | +| ----------------- | -------- | --------- | + +# PPA RGB LCD Example + +## Overview + +This example demonstrates how to use `esp_driver_ppa` to process an image and display the results on a generic RGB LCD panel. + +The image is scaled, rotated, mirrored, blended, and filled by PPA, then pushed to the RGB panel with `esp_lcd_panel_draw_bitmap()`. + +## Hardware Required + +* An ESP development board, which supports the RGB LCD peripheral +* A general RGB panel, supports 16/24 bit-width, with HSYNC, VSYNC and DE signal +* An USB cable for power supply and programming + +## Configure + +Run `idf.py menuconfig` and open `Example Configuration`: + +1. Set the RGB LCD timing parameters. +2. Set the RGB LCD GPIO assignments. +3. Choose whether the source image comes from the embedded JPEG or the pre-generated `RGB565` image. + +## Build and Flash + +Run `idf.py -p PORT build flash monitor` to build, flash and monitor the project. A picture with 'ESP32' word will 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 + +```text +I (1555) main_task: Calling app_main() +I (1565) ppa_rgb: Turn off LCD backlight +I (1575) ppa_rgb: Install RGB LCD panel driver +I (1605) ppa_rgb: Initialize RGB LCD panel +I (1615) ppa_rgb: Turn on LCD backlight +I (1795) ppa_rgb: JPEG image decoded! Size of the decoded image is: 320px x 240px +start srm operations +start blend operations +start fill operations +I (10085) main_task: Returned from app_main() +``` + +## Reference + +- [ESP-IDF: Pixel-Processing Accelerator](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/ppa.html) +- [ESP-IDF: RGB LCD](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/lcd/rgb_lcd.html) diff --git a/examples/peripherals/ppa/ppa_dsi/main/CMakeLists.txt b/examples/peripherals/ppa/ppa_rgb_lcd/main/CMakeLists.txt similarity index 77% rename from examples/peripherals/ppa/ppa_dsi/main/CMakeLists.txt rename to examples/peripherals/ppa/ppa_rgb_lcd/main/CMakeLists.txt index 61a29afb082..82167da14ce 100644 --- a/examples/peripherals/ppa/ppa_dsi/main/CMakeLists.txt +++ b/examples/peripherals/ppa/ppa_rgb_lcd/main/CMakeLists.txt @@ -1,4 +1,4 @@ -set(srcs "ppa_dsi_main.c") +set(srcs "ppa_rgb_lcd_main.c") if(CONFIG_EXAMPLE_SOURCE_IMAGE_FORMAT_RGB565) list(APPEND srcs "image.c") @@ -12,6 +12,6 @@ endif() idf_component_register(SRCS ${srcs} INCLUDE_DIRS "." - REQUIRES esp_mm esp_driver_ppa dsi_init + REQUIRES esp_mm esp_psram esp_driver_ppa esp_lcd EMBED_FILES ${embed_files} ) diff --git a/examples/peripherals/ppa/ppa_dsi/main/Kconfig.projbuild b/examples/peripherals/ppa/ppa_rgb_lcd/main/Kconfig.projbuild similarity index 50% rename from examples/peripherals/ppa/ppa_dsi/main/Kconfig.projbuild rename to examples/peripherals/ppa/ppa_rgb_lcd/main/Kconfig.projbuild index 2a9eb651d1e..50fa512f89a 100644 --- a/examples/peripherals/ppa/ppa_dsi/main/Kconfig.projbuild +++ b/examples/peripherals/ppa/ppa_rgb_lcd/main/Kconfig.projbuild @@ -1,17 +1,4 @@ menu "Example Configuration" - config EXAMPLE_USED_LDO_CHAN_ID - int "example used LDO channel ID" - default 3 - help - Example used LDO channel ID, you may check datasheet to know more details. - - config EXAMPLE_USED_LDO_VOLTAGE_MV - int "example used LDO voltage in mV" - default 2500 - range 0 3300 - help - Example used LDO voltage, in mV - choice EXAMPLE_SOURCE_IMAGE_FORMAT prompt "Select source image format" default EXAMPLE_SOURCE_IMAGE_FORMAT_JPEG diff --git a/examples/peripherals/ppa/ppa_rgb_lcd/main/idf_component.yml b/examples/peripherals/ppa/ppa_rgb_lcd/main/idf_component.yml new file mode 100644 index 00000000000..10787f88e8e --- /dev/null +++ b/examples/peripherals/ppa/ppa_rgb_lcd/main/idf_component.yml @@ -0,0 +1,6 @@ +dependencies: + idf: + version: ">=5.3.0" + esp_jpeg: ">=1.0.2" + rgb_panel_init: + path: ${IDF_PATH}/examples/peripherals/lcd/rgb_panel/common_components/rgb_panel_init diff --git a/examples/peripherals/ppa/ppa_dsi/main/image.c b/examples/peripherals/ppa/ppa_rgb_lcd/main/image.c similarity index 100% rename from examples/peripherals/ppa/ppa_dsi/main/image.c rename to examples/peripherals/ppa/ppa_rgb_lcd/main/image.c diff --git a/examples/peripherals/ppa/ppa_dsi/main/image.h b/examples/peripherals/ppa/ppa_rgb_lcd/main/image.h similarity index 100% rename from examples/peripherals/ppa/ppa_dsi/main/image.h rename to examples/peripherals/ppa/ppa_rgb_lcd/main/image.h diff --git a/examples/peripherals/ppa/ppa_dsi/main/image.jpg b/examples/peripherals/ppa/ppa_rgb_lcd/main/image.jpg similarity index 100% rename from examples/peripherals/ppa/ppa_dsi/main/image.jpg rename to examples/peripherals/ppa/ppa_rgb_lcd/main/image.jpg diff --git a/examples/peripherals/ppa/ppa_dsi/main/ppa_dsi_main.c b/examples/peripherals/ppa/ppa_rgb_lcd/main/ppa_rgb_lcd_main.c similarity index 65% rename from examples/peripherals/ppa/ppa_dsi/main/ppa_dsi_main.c rename to examples/peripherals/ppa/ppa_rgb_lcd/main/ppa_rgb_lcd_main.c index 04839b51a3d..aa841e70686 100644 --- a/examples/peripherals/ppa/ppa_dsi/main/ppa_dsi_main.c +++ b/examples/peripherals/ppa/ppa_rgb_lcd/main/ppa_rgb_lcd_main.c @@ -1,32 +1,37 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include -#include "esp_attr.h" -#include "esp_log.h" -#include "esp_check.h" #include "freertos/FreeRTOS.h" -#include "esp_lcd_mipi_dsi.h" -#include "esp_lcd_panel_ops.h" -#include "esp_ldo_regulator.h" #include "driver/ppa.h" -#include "example_dsi_init.h" -#include "example_dsi_init_config.h" +#include "example_rgb_panel_init.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "esp_lcd_panel_ops.h" +#include "esp_log.h" #if CONFIG_EXAMPLE_SOURCE_IMAGE_FORMAT_JPEG #include "jpeg_decoder.h" #else #include "image.h" #endif +#if CONFIG_EXAMPLE_LCD_DATA_LINES_16 +#define EXAMPLE_LCD_COLOR_FORMAT ESP_COLOR_FOURCC_RGB16 +#elif CONFIG_EXAMPLE_LCD_DATA_LINES_24 +#define EXAMPLE_LCD_COLOR_FORMAT ESP_COLOR_FOURCC_BGR24 +#else +#error "Unsupported LCD data lines" +#endif + #define EXAMPLE_IMAGE_H 240 #define EXAMPLE_IMAGE_W 320 #define EXAMPLE_BUFFER_CNT_CYCLE(buffer_cnt) (((buffer_cnt) + 1) % 2) -static const char *TAG = "ppa_dsi"; +static const char *TAG = "ppa_rgb"; #if CONFIG_EXAMPLE_SOURCE_IMAGE_FORMAT_JPEG //Reference the binary-included jpeg file @@ -78,24 +83,28 @@ esp_err_t s_get_rgb565_image(uint16_t **pixels) } #endif -void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_panel, ppa_client_handle_t ppa_srm_handle, void *clear_buf) +static void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_handle_t panel_handle, ppa_client_handle_t ppa_srm_handle, void *clear_buf) { ppa_srm_oper_config_t srm_config = { - .in.buffer = in_buf, - .in.pic_w = EXAMPLE_IMAGE_W, - .in.pic_h = EXAMPLE_IMAGE_H, - .in.block_w = EXAMPLE_IMAGE_W, - .in.block_h = EXAMPLE_IMAGE_H, - .in.block_offset_x = 0, - .in.block_offset_y = 0, - .in.srm_cm = PPA_SRM_COLOR_MODE_RGB565, - .out.buffer = out_buf[0], - .out.buffer_size = buf_size, - .out.pic_w = EXAMPLE_IMAGE_W, - .out.pic_h = EXAMPLE_IMAGE_H, - .out.block_offset_x = 0, - .out.block_offset_y = 0, - .out.srm_cm = PPA_SRM_COLOR_MODE_RGB565, + .in = { + .buffer = in_buf, + .pic_w = EXAMPLE_IMAGE_W, + .pic_h = EXAMPLE_IMAGE_H, + .block_w = EXAMPLE_IMAGE_W, + .block_h = EXAMPLE_IMAGE_H, + .block_offset_x = 0, + .block_offset_y = 0, + .srm_cm = PPA_SRM_COLOR_MODE_RGB565, + }, + .out = { + .buffer = out_buf[0], + .buffer_size = buf_size, + .pic_w = EXAMPLE_IMAGE_W, + .pic_h = EXAMPLE_IMAGE_H, + .block_offset_x = 0, + .block_offset_y = 0, + .srm_cm = (ppa_srm_color_mode_t)EXAMPLE_LCD_COLOR_FORMAT, + }, .rotation_angle = PPA_SRM_ROTATION_ANGLE_0, .scale_x = 1, .scale_y = 1, @@ -114,9 +123,10 @@ void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_hand srm_config.scale_x = mul[i]; srm_config.scale_y = mul[i]; ESP_ERROR_CHECK(ppa_do_scale_rotate_mirror(ppa_srm_handle, &srm_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W * size_mul[i], EXAMPLE_IMAGE_H * size_mul[i], out_buf[buffer_cnt])); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W * size_mul[i], EXAMPLE_IMAGE_H * size_mul[i], out_buf[buffer_cnt])); vTaskDelay(800 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W * mul[i], EXAMPLE_IMAGE_H * mul[i], clear_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W * size_mul[i], EXAMPLE_IMAGE_H * size_mul[i], clear_buf)); + srm_config.in.srm_cm = srm_config.out.srm_cm; srm_config.in.buffer = out_buf[i % 2]; srm_config.out.buffer = out_buf[1 - i % 2]; srm_config.in.pic_w = EXAMPLE_IMAGE_W * size_mul[i]; @@ -133,9 +143,9 @@ void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_hand srm_config.out.pic_w = EXAMPLE_IMAGE_H * 1.5; srm_config.out.pic_h = EXAMPLE_IMAGE_W * 1.5; ESP_ERROR_CHECK(ppa_do_scale_rotate_mirror(ppa_srm_handle, &srm_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_H * 1.5, EXAMPLE_IMAGE_W * 1.5, out_buf[buffer_cnt])); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_H * 1.5, EXAMPLE_IMAGE_W * 1.5, out_buf[buffer_cnt])); vTaskDelay(800 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_H * 1.5, EXAMPLE_IMAGE_W * 1.5, clear_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_H * 1.5, EXAMPLE_IMAGE_W * 1.5, clear_buf)); srm_config.in.buffer = out_buf[buffer_cnt]; srm_config.in.pic_w = EXAMPLE_IMAGE_H * 1.5; srm_config.in.pic_h = EXAMPLE_IMAGE_W * 1.5; @@ -149,9 +159,9 @@ void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_hand srm_config.out.pic_w = EXAMPLE_IMAGE_W * 1.5; srm_config.out.pic_h = EXAMPLE_IMAGE_H * 1.5; ESP_ERROR_CHECK(ppa_do_scale_rotate_mirror(ppa_srm_handle, &srm_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, out_buf[buffer_cnt])); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, out_buf[buffer_cnt])); vTaskDelay(800 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, clear_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, clear_buf)); srm_config.rotation_angle = PPA_SRM_ROTATION_ANGLE_0; srm_config.in.buffer = out_buf[buffer_cnt]; srm_config.in.pic_w = EXAMPLE_IMAGE_W * 1.5; @@ -166,15 +176,16 @@ void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_hand srm_config.mirror_x = 1; srm_config.mirror_y = 1; ESP_ERROR_CHECK(ppa_do_scale_rotate_mirror(ppa_srm_handle, &srm_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, out_buf[buffer_cnt])); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, out_buf[buffer_cnt])); vTaskDelay(800 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, clear_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W * 1.5, EXAMPLE_IMAGE_H * 1.5, clear_buf)); srm_config.in.buffer = out_buf[buffer_cnt]; srm_config.out.buffer = out_buf[1 - buffer_cnt]; buffer_cnt = EXAMPLE_BUFFER_CNT_CYCLE(buffer_cnt); } //back to 1x original image + srm_config.in.srm_cm = PPA_SRM_COLOR_MODE_RGB565; srm_config.in.buffer = in_buf; srm_config.in.pic_w = EXAMPLE_IMAGE_W; srm_config.in.pic_h = EXAMPLE_IMAGE_H; @@ -189,38 +200,44 @@ void s_srm_ops(void *in_buf, void **out_buf, size_t buf_size, esp_lcd_panel_hand srm_config.mirror_x = 0; srm_config.mirror_y = 0; ESP_ERROR_CHECK(ppa_do_scale_rotate_mirror(ppa_srm_handle, &srm_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf[buffer_cnt])); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf[buffer_cnt])); vTaskDelay(800 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, clear_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, clear_buf)); } -void s_blend_ops(void *bg_buf, void *fg_buf, void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_panel, ppa_client_handle_t ppa_blend_handle, void *clear_buf) +static void s_blend_ops(void *bg_buf, void *fg_buf, void *out_buf, size_t buf_size, esp_lcd_panel_handle_t panel_handle, ppa_client_handle_t ppa_blend_handle, void *clear_buf) { //this operation will blend the bg_buf with the fg_buf ppa_blend_oper_config_t blend_config = { - .in_bg.buffer = bg_buf, - .in_bg.pic_w = EXAMPLE_IMAGE_W, - .in_bg.pic_h = EXAMPLE_IMAGE_H, - .in_bg.block_w = EXAMPLE_IMAGE_W, - .in_bg.block_h = EXAMPLE_IMAGE_H, - .in_bg.block_offset_x = 0, - .in_bg.block_offset_y = 0, - .in_bg.blend_cm = PPA_SRM_COLOR_MODE_RGB565, - .in_fg.buffer = fg_buf, - .in_fg.pic_w = EXAMPLE_IMAGE_W, - .in_fg.pic_h = EXAMPLE_IMAGE_H, - .in_fg.block_w = EXAMPLE_IMAGE_W, - .in_fg.block_h = EXAMPLE_IMAGE_H, - .in_fg.block_offset_x = 0, - .in_fg.block_offset_y = 0, - .in_fg.blend_cm = PPA_BLEND_COLOR_MODE_A8, - .out.buffer = out_buf, - .out.buffer_size = buf_size, - .out.pic_w = EXAMPLE_IMAGE_W, - .out.pic_h = EXAMPLE_IMAGE_H, - .out.block_offset_x = 0, - .out.block_offset_y = 0, - .out.blend_cm = PPA_SRM_COLOR_MODE_RGB565, + .in_bg = { + .buffer = bg_buf, + .pic_w = EXAMPLE_IMAGE_W, + .pic_h = EXAMPLE_IMAGE_H, + .block_w = EXAMPLE_IMAGE_W, + .block_h = EXAMPLE_IMAGE_H, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_SRM_COLOR_MODE_RGB565, + }, + .in_fg = { + .buffer = fg_buf, + .pic_w = EXAMPLE_IMAGE_W, + .pic_h = EXAMPLE_IMAGE_H, + .block_w = EXAMPLE_IMAGE_W, + .block_h = EXAMPLE_IMAGE_H, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = PPA_BLEND_COLOR_MODE_A8, + }, + .out = { + .buffer = out_buf, + .buffer_size = buf_size, + .pic_w = EXAMPLE_IMAGE_W, + .pic_h = EXAMPLE_IMAGE_H, + .block_offset_x = 0, + .block_offset_y = 0, + .blend_cm = (ppa_blend_color_mode_t)EXAMPLE_LCD_COLOR_FORMAT, + }, .bg_alpha_update_mode = PPA_ALPHA_SCALE, .bg_alpha_scale_ratio = 0.9, .fg_alpha_update_mode = PPA_ALPHA_SCALE, @@ -235,9 +252,9 @@ void s_blend_ops(void *bg_buf, void *fg_buf, void *out_buf, size_t buf_size, esp .mode = PPA_TRANS_MODE_BLOCKING, }; ESP_ERROR_CHECK(ppa_do_blend(ppa_blend_handle, &blend_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); vTaskDelay(800 / portTICK_PERIOD_MS); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, clear_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, clear_buf)); //the `ESP32` in the bg_buf will be color-keyed out memset(fg_buf, 0xff, buf_size); @@ -256,21 +273,23 @@ void s_blend_ops(void *bg_buf, void *fg_buf, void *out_buf, size_t buf_size, esp .r = 0xfe, }; ESP_ERROR_CHECK(ppa_do_blend(ppa_blend_handle, &blend_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); vTaskDelay(800 / portTICK_PERIOD_MS); } -void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_panel, ppa_client_handle_t ppa_fill_handle) +static void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t panel_handle, ppa_client_handle_t ppa_fill_handle) { int buffer_cnt = 0; ppa_fill_oper_config_t fill_config = { - .out.buffer = out_buf, - .out.buffer_size = buf_size, - .out.pic_w = EXAMPLE_IMAGE_W, - .out.pic_h = EXAMPLE_IMAGE_H, - .out.block_offset_x = 0, - .out.block_offset_y = 20, - .out.fill_cm = PPA_FILL_COLOR_MODE_RGB565, + .out = { + .buffer = out_buf, + .buffer_size = buf_size, + .pic_w = EXAMPLE_IMAGE_W, + .pic_h = EXAMPLE_IMAGE_H, + .block_offset_x = 0, + .block_offset_y = 20, + .fill_cm = (ppa_fill_color_mode_t)EXAMPLE_LCD_COLOR_FORMAT, + }, .fill_block_w = 10, .fill_block_h = 200, .fill_argb_color = { @@ -284,7 +303,7 @@ void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_ //below ops will add a frame to the `ESP32` characters ESP_ERROR_CHECK(ppa_do_fill(ppa_fill_handle, &fill_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); buffer_cnt = EXAMPLE_BUFFER_CNT_CYCLE(buffer_cnt); fill_config.out.block_offset_x = 0; @@ -292,7 +311,7 @@ void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_ fill_config.fill_block_w = 320; fill_config.fill_block_h = 10; ESP_ERROR_CHECK(ppa_do_fill(ppa_fill_handle, &fill_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); buffer_cnt = EXAMPLE_BUFFER_CNT_CYCLE(buffer_cnt); fill_config.out.block_offset_x = 310; @@ -300,7 +319,7 @@ void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_ fill_config.fill_block_w = 10; fill_config.fill_block_h = 200; ESP_ERROR_CHECK(ppa_do_fill(ppa_fill_handle, &fill_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); buffer_cnt = EXAMPLE_BUFFER_CNT_CYCLE(buffer_cnt); fill_config.out.block_offset_x = 0; @@ -308,7 +327,7 @@ void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_ fill_config.fill_block_w = 320; fill_config.fill_block_h = 10; ESP_ERROR_CHECK(ppa_do_fill(ppa_fill_handle, &fill_config)); - ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); + ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, 0, 0, EXAMPLE_IMAGE_W, EXAMPLE_IMAGE_H, out_buf)); buffer_cnt = EXAMPLE_BUFFER_CNT_CYCLE(buffer_cnt); vTaskDelay(800 / portTICK_PERIOD_MS); } @@ -316,22 +335,20 @@ void s_fill_ops(void *out_buf, size_t buf_size, esp_lcd_panel_handle_t mipi_dpi_ void app_main(void) { uint16_t *pixels = NULL; - esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL; - esp_lcd_panel_io_handle_t mipi_dbi_io = NULL; - esp_lcd_panel_handle_t mipi_dpi_panel = NULL; + esp_lcd_panel_handle_t panel_handle = NULL; - //---------------MIPI LDO Init------------------// - esp_ldo_channel_handle_t ldo_mipi_phy = NULL; - esp_ldo_channel_config_t ldo_mipi_phy_config = { - .chan_id = CONFIG_EXAMPLE_USED_LDO_CHAN_ID, - .voltage_mv = CONFIG_EXAMPLE_USED_LDO_VOLTAGE_MV, - }; - ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy)); + ESP_LOGI(TAG, "Turn off LCD backlight"); + ESP_ERROR_CHECK(example_rgb_panel_init_backlight()); + example_rgb_panel_set_backlight(false); - //---------------DSI Init------------------// - example_dsi_resource_alloc(NULL, &mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, NULL, NULL); - example_dpi_panel_reset(mipi_dpi_panel); - example_dpi_panel_init(mipi_dpi_panel); + ESP_LOGI(TAG, "Install RGB LCD panel driver"); + ESP_ERROR_CHECK(example_rgb_panel_new(&panel_handle)); + + ESP_LOGI(TAG, "Initialize RGB LCD panel"); + ESP_ERROR_CHECK(example_rgb_panel_init(panel_handle)); + + ESP_LOGI(TAG, "Turn on LCD backlight"); + example_rgb_panel_set_backlight(true); //---------------Get Source image------------------// ESP_ERROR_CHECK(s_get_rgb565_image(&pixels)); @@ -359,7 +376,7 @@ void app_main(void) }; ESP_ERROR_CHECK(ppa_register_client(&ppa_srm_config, &ppa_srm_handle)); printf("start srm operations\n"); - s_srm_ops(pixels, (void **)out_buf, out_buf_size, mipi_dpi_panel, ppa_srm_handle, clear_buf); + s_srm_ops(pixels, (void **)out_buf, out_buf_size, panel_handle, ppa_srm_handle, clear_buf); uint8_t *fg_buf = heap_caps_calloc(out_buf_size, 1, MALLOC_CAP_DMA | MALLOC_CAP_SPIRAM); if (!fg_buf) { @@ -376,7 +393,7 @@ void app_main(void) }; ESP_ERROR_CHECK(ppa_register_client(&ppa_blend_config, &ppa_blend_handle)); printf("start blend operations\n"); - s_blend_ops(pixels, fg_buf, out_buf[0], out_buf_size, mipi_dpi_panel, ppa_blend_handle, clear_buf); + s_blend_ops(pixels, fg_buf, out_buf[0], out_buf_size, panel_handle, ppa_blend_handle, clear_buf); //---------------FILL------------------// ppa_client_handle_t ppa_fill_handle = NULL; @@ -386,7 +403,7 @@ void app_main(void) }; ESP_ERROR_CHECK(ppa_register_client(&ppa_fill_config, &ppa_fill_handle)); printf("start fill operations\n"); - s_fill_ops(out_buf[0], out_buf_size, mipi_dpi_panel, ppa_fill_handle); + s_fill_ops(out_buf[0], out_buf_size, panel_handle, ppa_fill_handle); #if CONFIG_EXAMPLE_SOURCE_IMAGE_FORMAT_JPEG free(pixels); @@ -398,5 +415,5 @@ void app_main(void) ESP_ERROR_CHECK(ppa_unregister_client(ppa_srm_handle)); ESP_ERROR_CHECK(ppa_unregister_client(ppa_blend_handle)); ESP_ERROR_CHECK(ppa_unregister_client(ppa_fill_handle)); - example_dsi_resource_destroy(mipi_dsi_bus, mipi_dbi_io, mipi_dpi_panel); + ESP_ERROR_CHECK(example_rgb_panel_deinit(panel_handle)); } diff --git a/examples/peripherals/ppa/ppa_rgb_lcd/pytest_ppa_rgb_lcd.py b/examples/peripherals/ppa/ppa_rgb_lcd/pytest_ppa_rgb_lcd.py new file mode 100644 index 00000000000..10047ea2fb8 --- /dev/null +++ b/examples/peripherals/ppa/ppa_rgb_lcd/pytest_ppa_rgb_lcd.py @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 +import pytest +from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize +from pytest_embedded_idf.utils import soc_filtered_targets + + +@pytest.mark.generic +@idf_parametrize('target', soc_filtered_targets('SOC_PPA_SUPPORTED == 1'), indirect=['target']) +def test_ppa_rgb_lcd(dut: Dut) -> None: + dut.expect_exact('Calling app_main()') + dut.expect_exact('ppa_rgb: Install RGB LCD panel driver') + dut.expect_exact('ppa_rgb: Initialize RGB LCD panel') + # ... + dut.expect_exact('start srm operations') + dut.expect_exact('start blend operations') + dut.expect_exact('start fill operations') + dut.expect_exact('Returned from app_main()') diff --git a/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults b/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults new file mode 100644 index 00000000000..e69de29bb2d diff --git a/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32p4 b/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32p4 new file mode 100644 index 00000000000..5f5cfd4f21c --- /dev/null +++ b/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32p4 @@ -0,0 +1,34 @@ +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_HEX=y +CONFIG_SPIRAM_SPEED_200M=y + +CONFIG_EXAMPLE_LCD_DATA_LINES_16=y + +# RGB565 over 16 data lines uses B[4:0], G[5:0], R[4:0] +CONFIG_EXAMPLE_LCD_VSYNC_GPIO=41 +CONFIG_EXAMPLE_LCD_HSYNC_GPIO=39 +CONFIG_EXAMPLE_LCD_DE_GPIO=43 +CONFIG_EXAMPLE_LCD_PCLK_GPIO=33 + +# B3:B7 <=> DATA0:DATA4 +CONFIG_EXAMPLE_LCD_DATA0_GPIO=40 +CONFIG_EXAMPLE_LCD_DATA1_GPIO=42 +CONFIG_EXAMPLE_LCD_DATA2_GPIO=27 +CONFIG_EXAMPLE_LCD_DATA3_GPIO=29 +CONFIG_EXAMPLE_LCD_DATA4_GPIO=31 + +# G2:G7 <=> DATA5:DATA10 +CONFIG_EXAMPLE_LCD_DATA5_GPIO=21 +CONFIG_EXAMPLE_LCD_DATA6_GPIO=23 +CONFIG_EXAMPLE_LCD_DATA7_GPIO=26 +CONFIG_EXAMPLE_LCD_DATA8_GPIO=28 +CONFIG_EXAMPLE_LCD_DATA9_GPIO=30 +CONFIG_EXAMPLE_LCD_DATA10_GPIO=32 + +# R3:R7 <=> DATA11:DATA15 +CONFIG_EXAMPLE_LCD_DATA11_GPIO=6 +CONFIG_EXAMPLE_LCD_DATA12_GPIO=0 +CONFIG_EXAMPLE_LCD_DATA13_GPIO=15 +CONFIG_EXAMPLE_LCD_DATA14_GPIO=17 +CONFIG_EXAMPLE_LCD_DATA15_GPIO=19 diff --git a/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32s31 b/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32s31 new file mode 100644 index 00000000000..1733291dd7d --- /dev/null +++ b/examples/peripherals/ppa/ppa_rgb_lcd/sdkconfig.defaults.esp32s31 @@ -0,0 +1,42 @@ +CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_250M=y + +CONFIG_EXAMPLE_LCD_DATA_LINES_24=y + +# Default GPIO assignment +CONFIG_EXAMPLE_LCD_VSYNC_GPIO=45 +CONFIG_EXAMPLE_LCD_HSYNC_GPIO=44 +CONFIG_EXAMPLE_LCD_DE_GPIO=43 +CONFIG_EXAMPLE_LCD_PCLK_GPIO=40 + +# B0:B7 <=> DATA0:DATA7 +CONFIG_EXAMPLE_LCD_DATA0_GPIO=8 +CONFIG_EXAMPLE_LCD_DATA1_GPIO=9 +CONFIG_EXAMPLE_LCD_DATA2_GPIO=10 +CONFIG_EXAMPLE_LCD_DATA3_GPIO=11 +CONFIG_EXAMPLE_LCD_DATA4_GPIO=12 +CONFIG_EXAMPLE_LCD_DATA5_GPIO=13 +CONFIG_EXAMPLE_LCD_DATA6_GPIO=14 +CONFIG_EXAMPLE_LCD_DATA7_GPIO=15 + +# G0:G7 <=> DATA8:DATA15 +CONFIG_EXAMPLE_LCD_DATA8_GPIO=16 +CONFIG_EXAMPLE_LCD_DATA9_GPIO=17 +CONFIG_EXAMPLE_LCD_DATA10_GPIO=18 +CONFIG_EXAMPLE_LCD_DATA11_GPIO=19 +CONFIG_EXAMPLE_LCD_DATA12_GPIO=33 +CONFIG_EXAMPLE_LCD_DATA13_GPIO=34 +CONFIG_EXAMPLE_LCD_DATA14_GPIO=35 +CONFIG_EXAMPLE_LCD_DATA15_GPIO=36 + +# R0:R7 <=> DATA16:DATA23 +CONFIG_EXAMPLE_LCD_DATA16_GPIO=37 +CONFIG_EXAMPLE_LCD_DATA17_GPIO=38 +CONFIG_EXAMPLE_LCD_DATA18_GPIO=39 +CONFIG_EXAMPLE_LCD_DATA19_GPIO=2 +CONFIG_EXAMPLE_LCD_DATA20_GPIO=3 +CONFIG_EXAMPLE_LCD_DATA21_GPIO=4 +CONFIG_EXAMPLE_LCD_DATA22_GPIO=5 +CONFIG_EXAMPLE_LCD_DATA23_GPIO=7