From d5c0ab7ad2cffe46d09747d500c71a77db7e11ef Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Sat, 22 Nov 2025 17:00:40 +0800 Subject: [PATCH] refactor(ppa): avoid the use of yuv422_pack_order field in PPA driver --- .../esp_driver_ppa/include/driver/ppa.h | 1 - components/esp_driver_ppa/src/ppa_blend.c | 7 +- components/esp_driver_ppa/src/ppa_fill.c | 2 +- components/esp_driver_ppa/src/ppa_priv.h | 4 + components/esp_driver_ppa/src/ppa_srm.c | 9 +- .../esp_driver_ppa/test_apps/main/test_ppa.c | 4 +- components/hal/color_hal.c | 4 + components/hal/esp32p4/include/hal/ppa_ll.h | 184 +++++++++++------- components/hal/include/hal/color_types.h | 5 + components/hal/include/hal/ppa_types.h | 12 +- .../esp32p4/register/hw_ver3/soc/ppa_reg.h | 4 +- .../esp32p4/register/hw_ver3/soc/ppa_struct.h | 4 +- 12 files changed, 144 insertions(+), 96 deletions(-) diff --git a/components/esp_driver_ppa/include/driver/ppa.h b/components/esp_driver_ppa/include/driver/ppa.h index 9f019a45576..5a3917d88d0 100644 --- a/components/esp_driver_ppa/include/driver/ppa.h +++ b/components/esp_driver_ppa/include/driver/ppa.h @@ -127,7 +127,6 @@ typedef struct { }; ppa_color_range_t yuv_range; /*!< When the color mode is any YUV color space, this field is to describe its color range */ ppa_color_conv_std_rgb_yuv_t yuv_std; /*!< When the color mode is any YUV color space, this field is to describe its YUV<->RGB conversion standard */ - color_yuv422_pack_order_t yuv422_pack_order; /*!< When the color mode is YUV422, this field is to describe its data pack order */ } ppa_in_pic_blk_config_t; /** diff --git a/components/esp_driver_ppa/src/ppa_blend.c b/components/esp_driver_ppa/src/ppa_blend.c index 81211958332..0037e480837 100644 --- a/components/esp_driver_ppa/src/ppa_blend.c +++ b/components/esp_driver_ppa/src/ppa_blend.c @@ -144,9 +144,6 @@ bool ppa_blend_transaction_on_picked(uint32_t num_chans, const dma2d_trans_chann ppa_ll_blend_set_rx_bg_yuv_range(platform->hal.dev, blend_trans_desc->in_bg.yuv_range); ppa_ll_blend_set_rx_bg_yuv2rgb_std(platform->hal.dev, blend_trans_desc->in_bg.yuv_std); } - if ((uint32_t)blend_trans_desc->in_bg.blend_cm == PPA_BLEND_COLOR_MODE_YUV422) { - ppa_ll_blend_set_rx_bg_yuv422_pack_order(platform->hal.dev, blend_trans_desc->in_bg.yuv422_pack_order); - } ppa_ll_blend_enable_rx_bg_byte_swap(platform->hal.dev, blend_trans_desc->bg_byte_swap); ppa_ll_blend_enable_rx_bg_rgb_swap(platform->hal.dev, blend_trans_desc->bg_rgb_swap); ppa_ll_blend_configure_rx_bg_alpha(platform->hal.dev, blend_trans_desc->bg_alpha_update_mode, blend_trans_desc->bg_alpha_value); @@ -201,7 +198,7 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf config->in_bg.block_h % 2 == 0 && config->in_bg.block_w % 2 == 0 && config->in_bg.block_offset_x % 2 == 0 && config->in_bg.block_offset_y % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV420 input does not support odd h/w/offset_x/offset_y"); - } else if (config->in_bg.blend_cm == PPA_BLEND_COLOR_MODE_YUV422) { + } else if (PPA_IS_CM_YUV422(config->in_bg.blend_cm)) { ESP_RETURN_ON_FALSE(config->in_bg.pic_w % 2 == 0 && config->in_bg.block_w % 2 == 0 && config->in_bg.block_offset_x % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV422 input does not support odd w/offset_x"); } @@ -218,7 +215,7 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf ESP_RETURN_ON_FALSE(config->out.pic_h % 2 == 0 && config->out.pic_w % 2 == 0 && config->out.block_offset_x % 2 == 0 && config->out.block_offset_y % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV420 output does not support odd h/w/offset_x/offset_y"); - } else if (config->out.blend_cm == PPA_BLEND_COLOR_MODE_YUV422) { + } else if (PPA_IS_CM_YUV422(config->out.blend_cm)) { ESP_RETURN_ON_FALSE(config->out.pic_w % 2 == 0 && config->out.block_offset_x % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV422 output does not support odd w/offset_x"); } diff --git a/components/esp_driver_ppa/src/ppa_fill.c b/components/esp_driver_ppa/src/ppa_fill.c index bb92a5274d8..a810c669515 100644 --- a/components/esp_driver_ppa/src/ppa_fill.c +++ b/components/esp_driver_ppa/src/ppa_fill.c @@ -104,7 +104,7 @@ esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config // config->out.block_offset_x % 2 == 0 && config->out.block_offset_y % 2 == 0, // ESP_ERR_INVALID_ARG, TAG, "YUV420 output does not support odd h/w/offset_x/offset_y"); // } else - if (config->out.fill_cm == PPA_FILL_COLOR_MODE_YUV422) { + if (config->out.fill_cm == PPA_FILL_COLOR_MODE_YUV422_UYVY) { ESP_RETURN_ON_FALSE(config->out.pic_w % 2 == 0 && config->out.block_offset_x % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV422 output does not support odd w/offset_x"); } diff --git a/components/esp_driver_ppa/src/ppa_priv.h b/components/esp_driver_ppa/src/ppa_priv.h index e6c054a73c4..d3f03a3b03e 100644 --- a/components/esp_driver_ppa/src/ppa_priv.h +++ b/components/esp_driver_ppa/src/ppa_priv.h @@ -34,6 +34,10 @@ extern "C" { ESP_RETURN_ON_FALSE(COLOR_SPACE_TYPE(color_type_id) == COLOR_SPACE_ARGB || COLOR_SPACE_TYPE(color_type_id) == COLOR_SPACE_RGB, \ ESP_ERR_INVALID_ARG, TAG, str "_cm does not support rgb_swap"); +#define PPA_IS_CM_YUV422(color_type_id) \ + (color_type_id == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_UYVY422) || color_type_id == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_VYUY422) || \ + color_type_id == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUYV422) || color_type_id == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YVYU422)) + #define PPA_ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) #define PPA_ALIGN_DOWN(num, align) ((num) & ~((align) - 1)) diff --git a/components/esp_driver_ppa/src/ppa_srm.c b/components/esp_driver_ppa/src/ppa_srm.c index 027ee41c61e..5e3f2b76ce5 100644 --- a/components/esp_driver_ppa/src/ppa_srm.c +++ b/components/esp_driver_ppa/src/ppa_srm.c @@ -147,9 +147,6 @@ bool ppa_srm_transaction_on_picked(uint32_t num_chans, const dma2d_trans_channel ppa_ll_srm_set_rx_yuv_range(platform->hal.dev, srm_trans_desc->in.yuv_range); ppa_ll_srm_set_rx_yuv2rgb_std(platform->hal.dev, srm_trans_desc->in.yuv_std); } - if ((uint32_t)ppa_in_color_mode == COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422)) { - ppa_ll_srm_set_rx_yuv422_pack_order(platform->hal.dev, srm_trans_desc->in.yuv422_pack_order); - } ppa_ll_srm_enable_rx_byte_swap(platform->hal.dev, srm_trans_desc->byte_swap); ppa_ll_srm_enable_rx_rgb_swap(platform->hal.dev, srm_trans_desc->rgb_swap); ppa_ll_srm_configure_rx_alpha(platform->hal.dev, srm_trans_desc->alpha_update_mode, srm_trans_desc->alpha_value); @@ -190,7 +187,7 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s config->in.block_h % 2 == 0 && config->in.block_w % 2 == 0 && 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"); - } else if (config->in.srm_cm == PPA_SRM_COLOR_MODE_YUV422) { + } else if (PPA_IS_CM_YUV422(config->in.srm_cm)) { 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"); } @@ -198,7 +195,7 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s ESP_RETURN_ON_FALSE(config->out.pic_h % 2 == 0 && config->out.pic_w % 2 == 0 && config->out.block_offset_x % 2 == 0 && config->out.block_offset_y % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV420 output does not support odd h/w/offset_x/offset_y"); - } else if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV422) { + } else if (PPA_IS_CM_YUV422(config->out.srm_cm)) { ESP_RETURN_ON_FALSE(config->out.pic_w % 2 == 0 && config->out.block_offset_x % 2 == 0, ESP_ERR_INVALID_ARG, TAG, "YUV422 output does not support odd w/offset_x"); } @@ -277,7 +274,7 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV420) { srm_trans_desc->scale_x_frag = srm_trans_desc->scale_x_frag & ~1; srm_trans_desc->scale_y_frag = srm_trans_desc->scale_y_frag & ~1; - } else if (config->out.srm_cm == PPA_SRM_COLOR_MODE_YUV422) { + } else if (PPA_IS_CM_YUV422(config->out.srm_cm)) { srm_trans_desc->scale_x_frag = srm_trans_desc->scale_x_frag & ~1; } srm_trans_desc->alpha_value = new_alpha_value; diff --git a/components/esp_driver_ppa/test_apps/main/test_ppa.c b/components/esp_driver_ppa/test_apps/main/test_ppa.c index 5b8dce8b5f3..011add8c2e9 100644 --- a/components/esp_driver_ppa/test_apps/main/test_ppa.c +++ b/components/esp_driver_ppa/test_apps/main/test_ppa.c @@ -562,10 +562,10 @@ TEST_CASE("ppa_fill_basic_data_correctness_check", "[PPA]") #if !(CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP32P4_SELECTS_REV_LESS_V3) // Test a yuv color fill - oper_config.out.fill_cm = PPA_FILL_COLOR_MODE_YUV422; // output YUV422 is with YVYU packed order + oper_config.out.fill_cm = PPA_FILL_COLOR_MODE_YUV422_UYVY; // output YUV422 is with UYVY packed order const color_macroblock_yuv_data_t fill_yuv_color = {.y = 0xFF, .u = 0x55, .v = 0xAA}; oper_config.fill_yuv_color = fill_yuv_color; - out_pixel_format.color_type_id = PPA_FILL_COLOR_MODE_YUV422; + out_pixel_format.color_type_id = PPA_FILL_COLOR_MODE_YUV422_UYVY; out_pixel_depth = color_hal_pixel_format_get_bit_depth(out_pixel_format); // bits TEST_ESP_OK(ppa_do_fill(ppa_client_handle, &oper_config)); diff --git a/components/hal/color_hal.c b/components/hal/color_hal.c index c26b3db6a65..63278599948 100644 --- a/components/hal/color_hal.c +++ b/components/hal/color_hal.c @@ -28,6 +28,10 @@ uint32_t color_hal_pixel_format_get_bit_depth(color_space_pixel_format_t format) return 12; case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565): case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422): + case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_UYVY422): + case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_VYUY422): + case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUYV422): + case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YVYU422): return 16; case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666): return 18; diff --git a/components/hal/esp32p4/include/hal/ppa_ll.h b/components/hal/esp32p4/include/hal/ppa_ll.h index d20cf73ad42..a0e7323397f 100644 --- a/components/hal/esp32p4/include/hal/ppa_ll.h +++ b/components/hal/esp32p4/include/hal/ppa_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -199,6 +199,38 @@ static inline void ppa_ll_srm_start(ppa_dev_t *dev) dev->sr_scal_rotate.scal_rotate_start = 1; } +/** + * @brief Set PPA SRM input side YUV422 data format packing order + * + * @param dev Peripheral instance address + * @param color_mode One of the values in ppa_srm_color_mode_t + */ +static inline void ppa_ll_srm_set_rx_yuv422_pack_order(ppa_dev_t *dev, ppa_srm_color_mode_t color_mode) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + switch (color_mode) { + case PPA_SRM_COLOR_MODE_YUV422_YVYU: + dev->sr_color_mode.yuv422_rx_byte_order = 3; + break; + case PPA_SRM_COLOR_MODE_YUV422_YUYV: + dev->sr_color_mode.yuv422_rx_byte_order = 2; + break; + case PPA_SRM_COLOR_MODE_YUV422_VYUY: + dev->sr_color_mode.yuv422_rx_byte_order = 1; + break; + case PPA_SRM_COLOR_MODE_YUV422_UYVY: + dev->sr_color_mode.yuv422_rx_byte_order = 0; + break; + default: + // Unsupported YUV422 pack order + abort(); + } +#else + // YUV422 not supported by PPA SRM hardware before P4 ECO5 + abort(); +#endif +} + /** * @brief Check if the given color mode is supported by PPA SRM engine * @@ -214,7 +246,10 @@ static inline bool ppa_ll_srm_is_color_mode_supported(ppa_srm_color_mode_t color case PPA_SRM_COLOR_MODE_YUV420: case PPA_SRM_COLOR_MODE_YUV444: // YUV444 not supported by PPA hardware, but can be converted by 2D-DMA before/after PPA #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 - case PPA_SRM_COLOR_MODE_YUV422: + case PPA_SRM_COLOR_MODE_YUV422_UYVY: + case PPA_SRM_COLOR_MODE_YUV422_VYUY: + case PPA_SRM_COLOR_MODE_YUV422_YUYV: + case PPA_SRM_COLOR_MODE_YUV422_YVYU: case PPA_SRM_COLOR_MODE_GRAY8: #endif return true; @@ -232,6 +267,7 @@ static inline bool ppa_ll_srm_is_color_mode_supported(ppa_srm_color_mode_t color static inline void ppa_ll_srm_set_rx_color_mode(ppa_dev_t *dev, ppa_srm_color_mode_t color_mode) { uint32_t val = 0; + bool is_yuv422 __attribute__ ((unused)) = false; switch (color_mode) { case PPA_SRM_COLOR_MODE_ARGB8888: val = 0; @@ -246,8 +282,12 @@ static inline void ppa_ll_srm_set_rx_color_mode(ppa_dev_t *dev, ppa_srm_color_mo val = 8; break; #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 - case PPA_SRM_COLOR_MODE_YUV422: + case PPA_SRM_COLOR_MODE_YUV422_UYVY: + case PPA_SRM_COLOR_MODE_YUV422_VYUY: + case PPA_SRM_COLOR_MODE_YUV422_YUYV: + case PPA_SRM_COLOR_MODE_YUV422_YVYU: val = 9; + is_yuv422 = true; break; case PPA_SRM_COLOR_MODE_GRAY8: val = 12; @@ -258,6 +298,13 @@ static inline void ppa_ll_srm_set_rx_color_mode(ppa_dev_t *dev, ppa_srm_color_mo abort(); } dev->sr_color_mode.sr_rx_cm = val; + +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + // set YUV422 packing order + if (is_yuv422) { + ppa_ll_srm_set_rx_yuv422_pack_order(dev, color_mode); + } +#endif } /** @@ -283,7 +330,7 @@ static inline void ppa_ll_srm_set_tx_color_mode(ppa_dev_t *dev, ppa_srm_color_mo val = 8; break; #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 - case PPA_SRM_COLOR_MODE_YUV422: + case PPA_SRM_COLOR_MODE_YUV422_UYVY: val = 9; break; case PPA_SRM_COLOR_MODE_GRAY8: @@ -381,38 +428,6 @@ static inline void ppa_ll_srm_set_tx_yuv_range(ppa_dev_t *dev, ppa_color_range_t } } -/** - * @brief Set PPA SRM input side YUV422 data format packing order - * - * @param dev Peripheral instance address - * @param pack_order One of the pack order options in color_yuv422_pack_order_t - */ -static inline void ppa_ll_srm_set_rx_yuv422_pack_order(ppa_dev_t *dev, color_yuv422_pack_order_t pack_order) -{ -#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 - switch (pack_order) { - case COLOR_YUV422_PACK_ORDER_YVYU: - dev->sr_color_mode.yuv422_rx_byte_order = 0; - break; - case COLOR_YUV422_PACK_ORDER_YUYV: - dev->sr_color_mode.yuv422_rx_byte_order = 1; - break; - case COLOR_YUV422_PACK_ORDER_VYUY: - dev->sr_color_mode.yuv422_rx_byte_order = 2; - break; - case COLOR_YUV422_PACK_ORDER_UYVY: - dev->sr_color_mode.yuv422_rx_byte_order = 3; - break; - default: - // Unsupported YUV422 pack order - abort(); - } -#else - // YUV422 not supported by PPA SRM hardware before P4 ECO5 - abort(); -#endif -} - /** * @brief Enable PPA SRM input data swap in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) * @@ -537,7 +552,10 @@ static inline void ppa_ll_srm_get_dma_dscr_port_mode_block_size(ppa_dev_t *dev, *block_h = 20; *block_v = 18; break; - case PPA_SRM_COLOR_MODE_YUV422: + case PPA_SRM_COLOR_MODE_YUV422_UYVY: + case PPA_SRM_COLOR_MODE_YUV422_VYUY: + case PPA_SRM_COLOR_MODE_YUV422_YUYV: + case PPA_SRM_COLOR_MODE_YUV422_YVYU: *block_h = 20; *block_v = 20; break; @@ -561,7 +579,10 @@ static inline void ppa_ll_srm_get_dma_dscr_port_mode_block_size(ppa_dev_t *dev, *block_h = 36; *block_v = 34; break; - case PPA_SRM_COLOR_MODE_YUV422: + case PPA_SRM_COLOR_MODE_YUV422_UYVY: + case PPA_SRM_COLOR_MODE_YUV422_VYUY: + case PPA_SRM_COLOR_MODE_YUV422_YUYV: + case PPA_SRM_COLOR_MODE_YUV422_YVYU: *block_h = 36; *block_v = 36; break; @@ -628,6 +649,38 @@ static inline void ppa_ll_blend_start(ppa_dev_t *dev, ppa_ll_blend_trans_mode_t dev->blend_trans_mode.blend_trans_mode_update = 1; } +/** + * @brief Set PPA blending source image background YUV422 data format packing order + * + * @param dev Peripheral instance address + * @param color_mode One of the values in ppa_blend_color_mode_t + */ +static inline void ppa_ll_blend_set_rx_bg_yuv422_pack_order(ppa_dev_t *dev, ppa_blend_color_mode_t color_mode) +{ +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + switch (color_mode) { + case PPA_BLEND_COLOR_MODE_YUV422_YVYU: + dev->blend_color_mode.blend0_rx_yuv422_byte_order = 3; + break; + case PPA_BLEND_COLOR_MODE_YUV422_YUYV: + dev->blend_color_mode.blend0_rx_yuv422_byte_order = 2; + break; + case PPA_BLEND_COLOR_MODE_YUV422_VYUY: + dev->blend_color_mode.blend0_rx_yuv422_byte_order = 1; + break; + case PPA_BLEND_COLOR_MODE_YUV422_UYVY: + dev->blend_color_mode.blend0_rx_yuv422_byte_order = 0; + break; + default: + // Unsupported YUV422 pack order + abort(); + } +#else + // YUV422 not supported by PPA blending hardware before P4 ECO5 + abort(); +#endif +} + /** * @brief Check if the given color mode is supported by PPA blending engine * @@ -646,7 +699,10 @@ static inline bool ppa_ll_blend_is_color_mode_supported(ppa_blend_color_mode_t c // case PPA_BLEND_COLOR_MODE_L4: #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 case PPA_BLEND_COLOR_MODE_YUV420: - case PPA_BLEND_COLOR_MODE_YUV422: + case PPA_BLEND_COLOR_MODE_YUV422_UYVY: + case PPA_BLEND_COLOR_MODE_YUV422_VYUY: + case PPA_BLEND_COLOR_MODE_YUV422_YUYV: + case PPA_BLEND_COLOR_MODE_YUV422_YVYU: case PPA_BLEND_COLOR_MODE_GRAY8: #endif return true; @@ -664,6 +720,7 @@ static inline bool ppa_ll_blend_is_color_mode_supported(ppa_blend_color_mode_t c static inline void ppa_ll_blend_set_rx_bg_color_mode(ppa_dev_t *dev, ppa_blend_color_mode_t color_mode) { uint32_t val = 0; + bool is_yuv422 __attribute__ ((unused)) = false; switch (color_mode) { case PPA_BLEND_COLOR_MODE_ARGB8888: val = 0; @@ -684,8 +741,12 @@ static inline void ppa_ll_blend_set_rx_bg_color_mode(ppa_dev_t *dev, ppa_blend_c case PPA_BLEND_COLOR_MODE_YUV420: val = 8; break; - case PPA_BLEND_COLOR_MODE_YUV422: + case PPA_BLEND_COLOR_MODE_YUV422_UYVY: + case PPA_BLEND_COLOR_MODE_YUV422_VYUY: + case PPA_BLEND_COLOR_MODE_YUV422_YUYV: + case PPA_BLEND_COLOR_MODE_YUV422_YVYU: val = 9; + is_yuv422 = true; break; case PPA_BLEND_COLOR_MODE_GRAY8: val = 12; @@ -696,6 +757,13 @@ static inline void ppa_ll_blend_set_rx_bg_color_mode(ppa_dev_t *dev, ppa_blend_c abort(); } dev->blend_color_mode.blend0_rx_cm = val; + +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + // set YUV422 packing order + if (is_yuv422) { + ppa_ll_blend_set_rx_bg_yuv422_pack_order(dev, color_mode); + } +#endif } /** @@ -759,7 +827,7 @@ static inline void ppa_ll_blend_set_tx_color_mode(ppa_dev_t *dev, ppa_blend_colo case PPA_BLEND_COLOR_MODE_YUV420: val = 8; break; - case PPA_BLEND_COLOR_MODE_YUV422: + case PPA_BLEND_COLOR_MODE_YUV422_UYVY: val = 9; break; case PPA_BLEND_COLOR_MODE_GRAY8: @@ -877,38 +945,6 @@ static inline void ppa_ll_blend_set_tx_yuv_range(ppa_dev_t *dev, ppa_color_range #endif } -/** - * @brief Set PPA blending source image background YUV422 data format packing order - * - * @param dev Peripheral instance address - * @param pack_order One of the pack order options in color_yuv422_pack_order_t - */ -static inline void ppa_ll_blend_set_rx_bg_yuv422_pack_order(ppa_dev_t *dev, color_yuv422_pack_order_t pack_order) -{ -#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 - switch (pack_order) { - case COLOR_YUV422_PACK_ORDER_YVYU: - dev->blend_color_mode.blend0_rx_yuv422_byte_order = 0; - break; - case COLOR_YUV422_PACK_ORDER_YUYV: - dev->blend_color_mode.blend0_rx_yuv422_byte_order = 1; - break; - case COLOR_YUV422_PACK_ORDER_VYUY: - dev->blend_color_mode.blend0_rx_yuv422_byte_order = 2; - break; - case COLOR_YUV422_PACK_ORDER_UYVY: - dev->blend_color_mode.blend0_rx_yuv422_byte_order = 3; - break; - default: - // Unsupported YUV422 pack order - abort(); - } -#else - // YUV422 not supported by PPA blending hardware before P4 ECO5 - abort(); -#endif -} - /** * @brief Enable PPA blending input background data wrap in RGB (e.g. ARGB becomes BGRA, RGB becomes BGR) * @@ -1052,7 +1088,7 @@ static inline void ppa_ll_blend_configure_filling_block(ppa_dev_t *dev, ppa_fill case PPA_FILL_COLOR_MODE_GRAY8: fill_color_data = *(uint32_t *)data; break; - case PPA_FILL_COLOR_MODE_YUV422: { + case PPA_FILL_COLOR_MODE_YUV422_UYVY: { color_macroblock_yuv_data_t *yuv_data = (color_macroblock_yuv_data_t *)data; fill_color_data = ((yuv_data->y) << 24) | ((yuv_data->v) << 16) | ((yuv_data->y) << 8) | (yuv_data->u); break; diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h index b222db3abf2..cb8cef6786b 100644 --- a/components/hal/include/hal/color_types.h +++ b/components/hal/include/hal/color_types.h @@ -59,6 +59,11 @@ typedef enum { COLOR_PIXEL_YUV422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels COLOR_PIXEL_YUV420, ///< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels COLOR_PIXEL_YUV411, ///< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels + + COLOR_PIXEL_UYVY422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels w/ (lowest byte) U0-Y0-V0-Y1 (highest byte) pack order + COLOR_PIXEL_VYUY422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels w/ (lowest byte) V0-Y0-U0-Y1 (highest byte) pack order + COLOR_PIXEL_YUYV422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels w/ (lowest byte) Y0-U0-Y1-V0 (highest byte) pack order + COLOR_PIXEL_YVYU422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels w/ (lowest byte) Y0-V0-Y1-U0 (highest byte) pack order } color_pixel_yuv_format_t; /** diff --git a/components/hal/include/hal/ppa_types.h b/components/hal/include/hal/ppa_types.h index dd967e42180..6f993222550 100644 --- a/components/hal/include/hal/ppa_types.h +++ b/components/hal/include/hal/ppa_types.h @@ -44,7 +44,10 @@ typedef enum { // 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 - PPA_SRM_COLOR_MODE_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), /*!< PPA SRM color mode: YUV422 (input data pack order all supported, but output data format is fixed to YVYU) */ + PPA_SRM_COLOR_MODE_YUV422_UYVY = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_UYVY422), /*!< PPA SRM color mode: YUV422 */ + PPA_SRM_COLOR_MODE_YUV422_VYUY = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_VYUY422), /*!< PPA SRM color mode: YUV422, only available on input */ + PPA_SRM_COLOR_MODE_YUV422_YUYV = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUYV422), /*!< PPA SRM color mode: YUV422, only available on input */ + PPA_SRM_COLOR_MODE_YUV422_YVYU = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YVYU422), /*!< PPA SRM color mode: YUV422, only available on input */ PPA_SRM_COLOR_MODE_GRAY8 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8), /*!< PPA SRM color mode: GRAY8 */ } ppa_srm_color_mode_t; @@ -58,7 +61,10 @@ 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 */ PPA_BLEND_COLOR_MODE_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), /*!< PPA blend color mode: YUV420, only available on blend background input or on output */ - PPA_BLEND_COLOR_MODE_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), /*!< PPA blend color mode: YUV422, only available on blend background input (all pack order supported) or on output (fixed to YVYU) */ + PPA_BLEND_COLOR_MODE_YUV422_UYVY = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_UYVY422), /*!< PPA blend color mode: YUV422, only available on blend background input or on output */ + PPA_BLEND_COLOR_MODE_YUV422_VYUY = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_VYUY422), /*!< PPA blend color mode: YUV422, only available on blend background input */ + PPA_BLEND_COLOR_MODE_YUV422_YUYV = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUYV422), /*!< PPA blend color mode: YUV422, only available on blend background input */ + PPA_BLEND_COLOR_MODE_YUV422_YVYU = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YVYU422), /*!< PPA blend color mode: YUV422, only available on blend background input */ PPA_BLEND_COLOR_MODE_GRAY8 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8), /*!< PPA blend color mode: GRAY8, only available on blend background input or on output */ // 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 input */ @@ -73,7 +79,7 @@ typedef enum { PPA_FILL_COLOR_MODE_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), /*!< PPA fill color mode: RGB888 */ PPA_FILL_COLOR_MODE_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), /*!< PPA fill color mode: RGB565 */ // PPA_FILL_COLOR_MODE_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), /*!< PPA fill color mode: YUV420 */ // Non-typical YUV420, U and V components have to be the same value - PPA_FILL_COLOR_MODE_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), /*!< PPA fill color mode: YUV422 (w/ YVYU pack order) */ + PPA_FILL_COLOR_MODE_YUV422_UYVY = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_UYVY422), /*!< PPA fill color mode: YUV422 (w/ UYVY pack order) */ PPA_FILL_COLOR_MODE_GRAY8 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8), /*!< PPA fill color mode: GRAY8 */ } ppa_fill_color_mode_t; diff --git a/components/soc/esp32p4/register/hw_ver3/soc/ppa_reg.h b/components/soc/esp32p4/register/hw_ver3/soc/ppa_reg.h index baa0dbb88d1..a1ae216013e 100644 --- a/components/soc/esp32p4/register/hw_ver3/soc/ppa_reg.h +++ b/components/soc/esp32p4/register/hw_ver3/soc/ppa_reg.h @@ -287,7 +287,7 @@ extern "C" { #define PPA_RGB2YUV_PROTOCOL_V 0x00000001U #define PPA_RGB2YUV_PROTOCOL_S 11 /** PPA_YUV422_RX_BYTE_ORDER : R/W; bitpos: [13:12]; default: 0; - * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY + * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY (high addr -> low addr) */ #define PPA_YUV422_RX_BYTE_ORDER 0x00000003U #define PPA_YUV422_RX_BYTE_ORDER_M (PPA_YUV422_RX_BYTE_ORDER_V << PPA_YUV422_RX_BYTE_ORDER_S) @@ -351,7 +351,7 @@ extern "C" { #define PPA_BLEND_TX_RGB2YUV_PROTOCOL_V 0x00000001U #define PPA_BLEND_TX_RGB2YUV_PROTOCOL_S 15 /** PPA_BLEND0_RX_YUV422_BYTE_ORDER : R/W; bitpos: [17:16]; default: 0; - * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY + * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY (high addr -> low addr) */ #define PPA_BLEND0_RX_YUV422_BYTE_ORDER 0x00000003U #define PPA_BLEND0_RX_YUV422_BYTE_ORDER_M (PPA_BLEND0_RX_YUV422_BYTE_ORDER_V << PPA_BLEND0_RX_YUV422_BYTE_ORDER_S) diff --git a/components/soc/esp32p4/register/hw_ver3/soc/ppa_struct.h b/components/soc/esp32p4/register/hw_ver3/soc/ppa_struct.h index 855a9df1e9a..b65bff4e4b9 100644 --- a/components/soc/esp32p4/register/hw_ver3/soc/ppa_struct.h +++ b/components/soc/esp32p4/register/hw_ver3/soc/ppa_struct.h @@ -116,7 +116,7 @@ typedef union { */ uint32_t rgb2yuv_protocol:1; /** yuv422_rx_byte_order : R/W; bitpos: [13:12]; default: 0; - * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY + * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY (high addr -> low addr) */ uint32_t yuv422_rx_byte_order:2; uint32_t reserved_14:18; @@ -161,7 +161,7 @@ typedef union { */ uint32_t blend_tx_rgb2yuv_protocol:1; /** blend0_rx_yuv422_byte_order : R/W; bitpos: [17:16]; default: 0; - * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY + * YUV422 input byte order when reg_sr_rx_cm is 4'd9. 0: YVYU, 1:YUYV, 2: VYUY, 3: UYVY (high addr -> low addr) */ uint32_t blend0_rx_yuv422_byte_order:2; uint32_t reserved_18:14;