Skip to content

Commit

Permalink
Merge branch 'feat/ppa_example' into 'master'
Browse files Browse the repository at this point in the history
ppa: added ppa dsi example

Closes IDF-10077

See merge request espressif/esp-idf!31703
  • Loading branch information
Icarus113 committed Jul 16, 2024
2 parents 42bcb84 + 3c7a833 commit f5d9cbe
Show file tree
Hide file tree
Showing 17 changed files with 902 additions and 11 deletions.
5 changes: 5 additions & 0 deletions docs/en/api-reference/peripherals/ppa.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ Performance Overview

The PPA operations are acted on the target block of an input picture. Therefore, the time it takes to complete a PPA transaction is proportional to the amount of the data in the block. The size of the entire picture has no influence on the performance. More importantly, the PPA performance highly relies on the PSRAM bandwidth if the pictures are located in the PSRAM section. When there are quite a few peripherals reading and writing to the PSRAM at the same time, the performance of PPA operation will be greatly reduced.

Application Examples
^^^^^^^^^^^^^^^^^^^^

* PPA with DSI display example: :example:`peripherals/ppa/ppa_dsi`. This 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`.

API Reference
-------------

Expand Down
7 changes: 7 additions & 0 deletions examples/peripherals/.build-test-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,13 @@ examples/peripherals/pcnt:
depends_components:
- esp_driver_pcnt

examples/peripherals/ppa/ppa_dsi:
disable:
- if: SOC_PPA_SUPPORTED != 1 or SOC_MIPI_DSI_SUPPORTED != 1
depends_components:
- esp_driver_ppa
- esp_lcd

examples/peripherals/rmt:
disable:
- if: SOC_RMT_SUPPORTED != 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,35 @@
#include "esp_log.h"
#include "esp_lcd_mipi_dsi.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_ili9881c.h"
#include "example_dsi_init.h"
#include "example_dsi_init_config.h"

void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer)
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer)
{
esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
esp_lcd_panel_io_handle_t mipi_dbi_io = NULL;

//---------------DSI resource allocation------------------//
esp_lcd_dsi_bus_config_t bus_config = {
.bus_id = 0,
.num_data_lanes = 2,
.phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT,
.lane_bit_rate_mbps = 1000, // 1000 Mbps
};
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus));
ESP_ERROR_CHECK(esp_lcd_new_dsi_bus(&bus_config, mipi_dsi_bus));

esp_lcd_dbi_io_config_t dbi_config = {
.virtual_channel = 0,
.lcd_cmd_bits = 8,
.lcd_param_bits = 8,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &mipi_dbi_io));
ESP_ERROR_CHECK(esp_lcd_new_panel_io_dbi(*mipi_dsi_bus, &dbi_config, mipi_dbi_io));

esp_lcd_panel_dev_config_t lcd_dev_config = {
.bits_per_pixel = 16,
.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
.reset_gpio_num = -1,
};
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(mipi_dbi_io, &lcd_dev_config, ili9881c_ctrl_panel));
ESP_ERROR_CHECK(esp_lcd_new_panel_ili9881c(*mipi_dbi_io, &lcd_dev_config, ili9881c_ctrl_panel));

esp_lcd_dpi_panel_config_t dpi_config = {
.dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT,
Expand All @@ -56,7 +54,7 @@ void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp
.vsync_front_porch = EXAMPLE_MIPI_DSI_IMAGE_VFP,
},
};
ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(mipi_dsi_bus, &dpi_config, mipi_dpi_panel));
ESP_ERROR_CHECK(esp_lcd_new_panel_dpi(*mipi_dsi_bus, &dpi_config, mipi_dpi_panel));
ESP_ERROR_CHECK(esp_lcd_dpi_panel_get_frame_buffer(*mipi_dpi_panel, 1, frame_buffer));
}

Expand All @@ -74,3 +72,11 @@ void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel)
//---------------DPI Panel Init------------------//
ESP_ERROR_CHECK(esp_lcd_panel_init(mipi_dpi_panel));
}

void example_dsi_resource_destroy(esp_lcd_panel_handle_t ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t mipi_dsi_bus, esp_lcd_panel_io_handle_t mipi_dbi_io, esp_lcd_panel_handle_t mipi_dpi_panel)
{
ESP_ERROR_CHECK(esp_lcd_panel_del(mipi_dpi_panel));
ESP_ERROR_CHECK(esp_lcd_panel_del(ili9881c_ctrl_panel));
ESP_ERROR_CHECK(esp_lcd_panel_io_del(mipi_dbi_io));
ESP_ERROR_CHECK(esp_lcd_del_dsi_bus(mipi_dsi_bus));
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ extern "C" {
* @brief DSI init function
*
* @param[out] ili9881c_ctrl_panel ILI9881C panel handle
* @param[out] mipi_dsi_bus MIPI DSI bus handle
* @param[out] mipi_dbi_io MIPI DBI io handle
* @param[out] mipi_dpi_panel MIPI DPI panel handle
* @param[out] frame_buffer frame buffer
*/
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer);
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer);

/**
* @brief DSI ILI9881C panel init function
Expand All @@ -37,6 +39,16 @@ void example_dsi_ili9881c_panel_init(esp_lcd_panel_handle_t ili9881c_ctrl_panel)
*/
void example_dpi_panel_init(esp_lcd_panel_handle_t mipi_dpi_panel);

/**
* @brief Destroy DSI related resources
*
* @param[in] ili9881c_ctrl_panel ILI9881C panel handle
* @param[in] mipi_dsi_bus MIPI DSI bus handle
* @param[in] mipi_dbi_io MIPI DBI io handle
* @param[in] mipi_dpi_panel MIPI DPI panel handle
*/
void example_dsi_resource_destroy(esp_lcd_panel_handle_t ili9881c_ctrl_panel, esp_lcd_dsi_bus_handle_t mipi_dsi_bus, esp_lcd_panel_io_handle_t mipi_dbi_io, esp_lcd_panel_handle_t mipi_dpi_panel);

#ifdef __cplusplus
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ct
void app_main(void)
{
esp_err_t ret = ESP_FAIL;
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 ili9881c_ctrl_panel = NULL;
esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
void *frame_buffer = NULL;
Expand All @@ -53,7 +55,7 @@ void app_main(void)
* ISP convert to RGB565
*/
//---------------DSI Init------------------//
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer);
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer);

//---------------Necessary variable config------------------//
frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
Expand Down
4 changes: 3 additions & 1 deletion examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ static void af_task(void *arg)
void app_main(void)
{
esp_err_t ret = ESP_FAIL;
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 ili9881c_ctrl_panel = NULL;
esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
void *frame_buffer = NULL;
Expand All @@ -195,7 +197,7 @@ void app_main(void)
* ISP convert to RGB565
*/
//---------------DSI Init------------------//
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer);
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer);

//---------------Necessary variable config------------------//
frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
Expand Down
6 changes: 6 additions & 0 deletions examples/peripherals/ppa/ppa_dsi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(ppa_dsi)
123 changes: 123 additions & 0 deletions examples/peripherals/ppa/ppa_dsi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
| 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:

- ILI9881C LCD screen
- ESP32P4 devkit


GND
┌─────────────────────────────────────────────────────────┐
│ │
│ │
│ │
│ │
│ │
│ │
│ │
│ │
┌───────────────-─────────────┴──────────────────┐ │
│ │ ┌──────────┴───────────┐
│ │ DSI DATA 1P │ │
│ ├───────────────────────────┤ │
│ │ │ │
│ │ DSI DATA 1N │ │
│ ├───────────────────────────┤ │
│ ESP32-P4 │ │ │
│ │ DSI CLK N │ ILI9881C │
│ ├───────────────────────────┤ │
│ │ │ │
│ │ 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 <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

- Link to the ESP-IDF feature's API reference, for example [ESP-IDF: Pixel-Processing Accelerator](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ppa.html)
- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started)
- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options)
17 changes: 17 additions & 0 deletions examples/peripherals/ppa/ppa_dsi/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
set(srcs "ppa_dsi_main.c")

if(CONFIG_EXAMPLE_SOURCE_IMAGE_FORMAT_RGB565)
list(APPEND srcs "image.c")
endif()

set(embed_files)

if(CONFIG_EXAMPLE_SOURCE_IMAGE_FORMAT_JPEG)
list(APPEND embed_files "image.jpg")
endif()

idf_component_register(SRCS ${srcs}
INCLUDE_DIRS "."
REQUIRES esp_mm esp_driver_ppa dsi_init
EMBED_FILES ${embed_files}
)
28 changes: 28 additions & 0 deletions examples/peripherals/ppa/ppa_dsi/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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
help
Select the source image format

config EXAMPLE_SOURCE_IMAGE_FORMAT_JPEG
bool "JPEG"

config EXAMPLE_SOURCE_IMAGE_FORMAT_RGB565
bool "RGB565"
endchoice

endmenu
7 changes: 7 additions & 0 deletions examples/peripherals/ppa/ppa_dsi/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
dependencies:
espressif/esp_lcd_ili9881c: "*"
idf:
version: ">=5.3.0"
dsi_init:
path: ${IDF_PATH}/examples/peripherals/camera/camera_dsi/components/dsi_init
esp_jpeg: ">=1.0.2"
Loading

0 comments on commit f5d9cbe

Please sign in to comment.