From ea7d496e58f1b60bbd976d10216cab5b8c00562b Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 23 May 2024 16:38:42 +0800 Subject: [PATCH] feat(ppa): add PPA driver support for ESP32P4 Remove L4/L8, YUV422 in PPA driver Clean up --- components/esp_driver_ppa/src/ppa_blend.c | 24 +++++++++--------- components/esp_driver_ppa/src/ppa_core.c | 4 --- components/esp_driver_ppa/src/ppa_srm.c | 15 +++-------- .../dma/include/esp_private/dma2d.h | 1 + components/hal/esp32p4/include/hal/ppa_ll.h | 25 ++++++++++--------- components/hal/include/hal/color_types.h | 12 +++------ components/hal/include/hal/ppa_types.h | 11 ++++---- docs/en/api-reference/peripherals/ppa.rst | 4 +-- 8 files changed, 40 insertions(+), 56 deletions(-) diff --git a/components/esp_driver_ppa/src/ppa_blend.c b/components/esp_driver_ppa/src/ppa_blend.c index 2ba33f9e52..e9b96ff563 100644 --- a/components/esp_driver_ppa/src/ppa_blend.c +++ b/components/esp_driver_ppa/src/ppa_blend.c @@ -155,15 +155,15 @@ bool ppa_blend_transaction_on_picked(uint32_t num_chans, const dma2d_trans_chann ppa_ll_blend_set_tx_color_mode(platform->hal.dev, blend_trans_desc->out.blend_cm); // Color keying - color_pixel_rgb888_data_t rgb888_black = RGB888_BLACK; - color_pixel_rgb888_data_t rgb888_white = RGB888_WHITE; + color_pixel_rgb888_data_t rgb888_min = {.b = 0x00, .g = 0x00, .r = 0x00}; + color_pixel_rgb888_data_t rgb888_max = {.b = 0xFF, .g = 0xFF, .r = 0xFF}; ppa_ll_blend_configure_rx_bg_ck_range(platform->hal.dev, - blend_trans_desc->bg_ck_en ? &blend_trans_desc->bg_ck_rgb_low_thres : &rgb888_white, - blend_trans_desc->bg_ck_en ? &blend_trans_desc->bg_ck_rgb_high_thres : &rgb888_black); + blend_trans_desc->bg_ck_en ? &blend_trans_desc->bg_ck_rgb_low_thres : &rgb888_max, + blend_trans_desc->bg_ck_en ? &blend_trans_desc->bg_ck_rgb_high_thres : &rgb888_min); ppa_ll_blend_configure_rx_fg_ck_range(platform->hal.dev, - blend_trans_desc->fg_ck_en ? &blend_trans_desc->fg_ck_rgb_low_thres : &rgb888_white, - blend_trans_desc->fg_ck_en ? &blend_trans_desc->fg_ck_rgb_high_thres : &rgb888_black); - ppa_ll_blend_set_ck_default_rgb(platform->hal.dev, (blend_trans_desc->bg_ck_en && blend_trans_desc->fg_ck_en) ? &blend_trans_desc->ck_rgb_default_val : &rgb888_black); + blend_trans_desc->fg_ck_en ? &blend_trans_desc->fg_ck_rgb_low_thres : &rgb888_max, + blend_trans_desc->fg_ck_en ? &blend_trans_desc->fg_ck_rgb_high_thres : &rgb888_min); + ppa_ll_blend_set_ck_default_rgb(platform->hal.dev, (blend_trans_desc->bg_ck_en && blend_trans_desc->fg_ck_en) ? &blend_trans_desc->ck_rgb_default_val : &rgb888_min); ppa_ll_blend_enable_ck_fg_bg_reverse(platform->hal.dev, blend_trans_desc->ck_reverse_bg2fg); ppa_ll_blend_start(platform->hal.dev, PPA_LL_BLEND_TRANS_MODE_BLEND); @@ -217,11 +217,11 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf ESP_RETURN_ON_FALSE(config->fg_alpha_scale_ratio > 0 && config->fg_alpha_scale_ratio < 1, ESP_ERR_INVALID_ARG, TAG, "invalid fg_alpha_scale_ratio"); new_fg_alpha_value = (uint32_t)(config->fg_alpha_scale_ratio * 256); } - if (config->in_bg.blend_cm == PPA_BLEND_COLOR_MODE_L4) { - ESP_RETURN_ON_FALSE(config->in_bg.block_w % 2 == 0 && config->in_bg.block_offset_x % 2 == 0, - ESP_ERR_INVALID_ARG, TAG, "in_bg.block_w and in_bg.block_offset_x must be even"); - } - if (config->in_fg.blend_cm == PPA_BLEND_COLOR_MODE_A4 || config->in_fg.blend_cm == PPA_BLEND_COLOR_MODE_L4) { + // if (config->in_bg.blend_cm == PPA_BLEND_COLOR_MODE_L4) { + // ESP_RETURN_ON_FALSE(config->in_bg.block_w % 2 == 0 && config->in_bg.block_offset_x % 2 == 0, + // ESP_ERR_INVALID_ARG, TAG, "in_bg.block_w and in_bg.block_offset_x must be even"); + // } + if (config->in_fg.blend_cm == PPA_BLEND_COLOR_MODE_A4) { // || config->in_fg.blend_cm == PPA_BLEND_COLOR_MODE_L4 ESP_RETURN_ON_FALSE(config->in_fg.block_w % 2 == 0 && config->in_fg.block_offset_x % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "in_fg.block_w and in_fg.block_offset_x must be even"); } diff --git a/components/esp_driver_ppa/src/ppa_core.c b/components/esp_driver_ppa/src/ppa_core.c index 646adeab20..6f309d9205 100644 --- a/components/esp_driver_ppa/src/ppa_core.c +++ b/components/esp_driver_ppa/src/ppa_core.c @@ -458,11 +458,7 @@ esp_err_t ppa_do_operation(ppa_client_handle_t ppa_client, ppa_engine_t *ppa_eng } if (mode == PPA_TRANS_MODE_BLOCKING) { - // while (1) { - // printf("ppa intr: %ld\n", PPA.int_raw.val); - // } xSemaphoreTake(trans_elm->sem, portMAX_DELAY); // Given in the ISR - // TODO: Sanity check new_trans_elm not in trans_stailq anymore? (loop takes time tho) } err: diff --git a/components/esp_driver_ppa/src/ppa_srm.c b/components/esp_driver_ppa/src/ppa_srm.c index 20b017fb23..244a18bff9 100644 --- a/components/esp_driver_ppa/src/ppa_srm.c +++ b/components/esp_driver_ppa/src/ppa_srm.c @@ -107,7 +107,7 @@ bool ppa_srm_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel }; dma2d_configure_dscr_port_mode(dma2d_tx_chan, &dma_dscr_port_mode_config); - // YUV444 and YUV422 are not supported by PPA module, need to utilize 2D-DMA color space conversion feature to do a conversion + // YUV444 is not supported by PPA module, need to utilize 2D-DMA color space conversion feature to do a conversion ppa_srm_color_mode_t ppa_in_color_mode = srm_trans_desc->in.srm_cm; if (ppa_in_color_mode == PPA_SRM_COLOR_MODE_YUV444) { ppa_in_color_mode = PPA_SRM_COLOR_MODE_RGB888; @@ -118,15 +118,6 @@ bool ppa_srm_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel dma_tx_csc.tx_csc_option = DMA2D_CSC_TX_YUV444_TO_RGB888_709; } dma2d_configure_color_space_conversion(dma2d_tx_chan, &dma_tx_csc); - } else if (ppa_in_color_mode == PPA_SRM_COLOR_MODE_YUV422) { - ppa_in_color_mode = PPA_SRM_COLOR_MODE_RGB888; - dma2d_csc_config_t dma_tx_csc = {0}; - if (srm_trans_desc->in.yuv_std == PPA_COLOR_CONV_STD_RGB_YUV_BT601) { - dma_tx_csc.tx_csc_option = DMA2D_CSC_TX_YUV422_TO_RGB888_601; - } else { - dma_tx_csc.tx_csc_option = DMA2D_CSC_TX_YUV422_TO_RGB888_709; - } - dma2d_configure_color_space_conversion(dma2d_tx_chan, &dma_tx_csc); } ppa_srm_color_mode_t ppa_out_color_mode = srm_trans_desc->out.srm_cm; @@ -193,7 +184,7 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s config->in.block_offset_x % 2 == 0 && config->in.block_offset_y % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV420 input does not support odd h/w/offset_x/offset_y"); } - // TODO: ECO2 support YUV422 + // TODO: P4 ECO2 support YUV422 // else if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV422) { // ESP_RETURN_ON_FALSE(config->in.pic_w % 2 == 0 && config->in.block_w % 2 == 0 && config->in.block_offset_x % 2 == 0, // ESP_ERR_INVALID_ARG, TAG, "YUV422 input does not support odd w/offset_x"); @@ -273,7 +264,7 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s dma_trans_desc->tx_channel_num = 1; dma_trans_desc->rx_channel_num = 1; dma_trans_desc->channel_flags = 0; - if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV422 || config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV444) { + if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV444) { dma_trans_desc->channel_flags |= DMA2D_CHANNEL_FUNCTION_FLAG_TX_CSC; } if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV444) { diff --git a/components/esp_hw_support/dma/include/esp_private/dma2d.h b/components/esp_hw_support/dma/include/esp_private/dma2d.h index 0710782048..4524ca95c6 100644 --- a/components/esp_hw_support/dma/include/esp_private/dma2d.h +++ b/components/esp_hw_support/dma/include/esp_private/dma2d.h @@ -288,6 +288,7 @@ typedef struct { * @param[in] config Configuration of 2D-DMA channel DSCR-PORT mode * @return * - ESP_OK: Configure 2D-DMA dscr-port mode successfully + * - ESP_ERR_INVALID_ARG: Configure 2D-DMA dscr-port mode failed because of invalid argument */ esp_err_t dma2d_configure_dscr_port_mode(dma2d_channel_handle_t dma2d_chan, const dma2d_dscr_port_mode_config_t *config); diff --git a/components/hal/esp32p4/include/hal/ppa_ll.h b/components/hal/esp32p4/include/hal/ppa_ll.h index f53e8fe75d..687e63c5ef 100644 --- a/components/hal/esp32p4/include/hal/ppa_ll.h +++ b/components/hal/esp32p4/include/hal/ppa_ll.h @@ -27,6 +27,7 @@ extern "C" { #define PPA_LL_SRM_SCALING_INT_MAX PPA_SR_SCAL_X_INT_V #define PPA_LL_SRM_SCALING_FRAG_MAX PPA_SR_SCAL_X_FRAG_V +// TODO: On P4 ECO2, SRM block size needs update #define PPA_LL_SRM_DEFAULT_BLOCK_SIZE 18 // 18 x 18 block size #define PPA_LL_SRM_YUV420_BLOCK_SIZE 20 // 20 x 20 block size @@ -438,12 +439,12 @@ static inline void ppa_ll_blend_set_rx_bg_color_mode(ppa_dev_t *dev, ppa_blend_c case PPA_BLEND_COLOR_MODE_RGB565: val = 2; break; - case PPA_BLEND_COLOR_MODE_L8: - val = 4; - break; - case PPA_BLEND_COLOR_MODE_L4: - val = 5; - break; + // case PPA_BLEND_COLOR_MODE_L8: + // val = 4; + // break; + // case PPA_BLEND_COLOR_MODE_L4: + // val = 5; + // break; default: // Unsupported blending rx background color mode abort(); @@ -470,12 +471,12 @@ static inline void ppa_ll_blend_set_rx_fg_color_mode(ppa_dev_t *dev, ppa_blend_c case PPA_BLEND_COLOR_MODE_RGB565: val = 2; break; - case PPA_BLEND_COLOR_MODE_L8: - val = 4; - break; - case PPA_BLEND_COLOR_MODE_L4: - val = 5; - break; + // case PPA_BLEND_COLOR_MODE_L8: + // val = 4; + // break; + // case PPA_BLEND_COLOR_MODE_L4: + // val = 5; + // break; case PPA_BLEND_COLOR_MODE_A8: val = 6; break; diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h index 25b9900590..4f2e82614c 100644 --- a/components/hal/include/hal/color_types.h +++ b/components/hal/include/hal/color_types.h @@ -171,17 +171,11 @@ typedef union { * @brief Data structure for RGB888 pixel unit */ typedef struct { - uint8_t b; /*!< B component [0, 255] */ - uint8_t g; /*!< G component [0, 255] */ - uint8_t r; /*!< R component [0, 255] */ + uint8_t b; /*!< B component [0, 255] */ + uint8_t g; /*!< G component [0, 255] */ + uint8_t r; /*!< R component [0, 255] */ } color_pixel_rgb888_data_t; -///< Color BLACK in color_pixel_rgb888_data_t -#define RGB888_BLACK {.b = 0x00, .g = 0x00, .r = 0x00} - -///< Color WHITE in color_pixel_rgb888_data_t -#define RGB888_WHITE {.b = 0xFF, .g = 0xFF, .r = 0xFF} - /** * @brief Data structure for RGB565 pixel unit */ diff --git a/components/hal/include/hal/ppa_types.h b/components/hal/include/hal/ppa_types.h index 485e4414f1..67741433c5 100644 --- a/components/hal/include/hal/ppa_types.h +++ b/components/hal/include/hal/ppa_types.h @@ -41,10 +41,11 @@ typedef enum { PPA_SRM_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA SRM color mode: RGB565 */ PPA_SRM_COLOR_MODE_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), /*!< PPA SRM color mode: YUV420 */ PPA_SRM_COLOR_MODE_YUV444 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV444), /*!< PPA SRM color mode: YUV444 (limited range only)*/ - PPA_SRM_COLOR_MODE_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), /*!< PPA SRM color mode: YUV422 (input only, limited range only) */ - // YUV444 and YUV422 not supported by PPA hardware, but seems like we can use 2D-DMA to do conversion before sending into and after coming out from the PPA module - // If in_pic is YUV444/422, then TX DMA channel could do DMA2D_CSC_TX_YUV444/422_TO_RGB888_601/709, so PPA in_color_mode is RGB888 + // YUV444 not supported by PPA hardware, but we can use 2D-DMA to do conversion before sending into and after coming out from the PPA module + // If in_pic is YUV444, then TX DMA channel could do DMA2D_CSC_TX_YUV444_TO_RGB888_601/709, so PPA in_color_mode is RGB888 // If out_pic is YUV444, then RX DMA channel could do DMA2D_CSC_RX_YUV420_TO_YUV444, so PPA out_color_mode is YUV420 + // TODO: P4 ECO2 supports YUV422 + // PPA_SRM_COLOR_MODE_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), /*!< PPA SRM color mode: YUV422 (input only, limited range only) */ } ppa_srm_color_mode_t; /** @@ -57,8 +58,8 @@ typedef enum { PPA_BLEND_COLOR_MODE_A8 = COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A8), /*!< PPA blend color mode: A8, only available on blend foreground input */ PPA_BLEND_COLOR_MODE_A4 = COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A4), /*!< PPA blend color mode: A4, only available on blend foreground input */ // TODO: Support CLUT to support L4/L8 color mode - PPA_BLEND_COLOR_MODE_L8 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L8), /*!< PPA blend color mode: L8, only available on blend inputs */ - PPA_BLEND_COLOR_MODE_L4 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L4), /*!< PPA blend color mode: L4, only available on blend inputs */ + // PPA_BLEND_COLOR_MODE_L8 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L8), /*!< PPA blend color mode: L8, only available on blend inputs */ + // PPA_BLEND_COLOR_MODE_L4 = COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L4), /*!< PPA blend color mode: L4, only available on blend inputs */ } ppa_blend_color_mode_t; /** diff --git a/docs/en/api-reference/peripherals/ppa.rst b/docs/en/api-reference/peripherals/ppa.rst index 67c2825d31..e108558839 100644 --- a/docs/en/api-reference/peripherals/ppa.rst +++ b/docs/en/api-reference/peripherals/ppa.rst @@ -114,7 +114,7 @@ Similarly, some notes to avoid confusion in configuring :cpp:type:`ppa_blend_ope .. list:: - :cpp:member:`ppa_out_pic_blk_config_t::buffer` can be the same pointer to one of the input's :cpp:member:`ppa_in_pic_blk_config_t::buffer` for a blend operation. - The blocks' width/height of FG and BG should be identical, and are the width/height values for the output block. - - If the color mode of the input picture is ``PPA_BLEND_COLOR_MODE_A4`` or ``PPA_BLEND_COLOR_MODE_L4``, then its ``block_w`` and ``block_offset_x`` fields must be even. + - If the color mode of the input picture is ``PPA_BLEND_COLOR_MODE_A4``, then its ``block_w`` and ``block_offset_x`` fields must be even. Fill ~~~~ @@ -140,7 +140,7 @@ The PPA driver has guaranteed the thread safety of calling the PPA operation API 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 of 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. +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. API Reference -------------