diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c index c96f459eb79..420c6029234 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,8 @@ #include "esp_cam_ctlr_csi_internal.h" #include "hal/mipi_csi_ll.h" #include "hal/color_hal.h" +#include "hal/efuse_hal.h" +#include "soc/chip_revision.h" #include "esp_private/periph_ctrl.h" #include "esp_private/mipi_csi_share_hw_ctrl.h" #include "esp_private/esp_cache_private.h" @@ -53,6 +55,7 @@ static esp_err_t s_csi_ctlr_disable(esp_cam_ctlr_handle_t ctlr); static esp_err_t s_ctlr_csi_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms); static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32_t buf_caps); static esp_err_t s_csi_ctlr_format_conversion(esp_cam_ctlr_t *handle, const cam_ctlr_format_conv_config_t *config); +static bool s_is_color_format_conversion_supported(cam_ctlr_color_t color_format); static esp_err_t s_csi_claim_controller(csi_controller_t *controller) { @@ -100,6 +103,8 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_ esp_err_t ret = ESP_FAIL; ESP_RETURN_ON_FALSE(config && ret_handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); ESP_RETURN_ON_FALSE(config->data_lane_num <= MIPI_CSI_HOST_LL_LANE_NUM_MAX, ESP_ERR_INVALID_ARG, TAG, "lane num should be equal or smaller than %d", MIPI_CSI_HOST_LL_LANE_NUM_MAX); + ESP_RETURN_ON_FALSE(config->input_data_color_type != 0, ESP_ERR_INVALID_ARG, TAG, "input_data_color_type must be specified"); + ESP_RETURN_ON_FALSE(config->output_data_color_type != 0, ESP_ERR_INVALID_ARG, TAG, "output_data_color_type must be specified"); csi_controller_t *ctlr = heap_caps_calloc(1, sizeof(csi_controller_t), CSI_MEM_ALLOC_CAPS); ESP_RETURN_ON_FALSE(ctlr, ESP_ERR_NO_MEM, TAG, "no mem for csi controller context"); @@ -136,19 +141,17 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_ ESP_LOGD(TAG, "ctlr->v_res: 0d %"PRId32, ctlr->v_res); //in color type - color_space_pixel_format_t in_color_format = { - .color_type_id = config->input_data_color_type, - }; - int in_bits_per_pixel = color_hal_pixel_format_get_bit_depth(in_color_format); - ctlr->in_color_format = in_color_format; + int in_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(config->input_data_color_type); + ESP_GOTO_ON_FALSE(in_bits_per_pixel != 0, ESP_ERR_INVALID_ARG, err, TAG, "unsupported input color format"); + ctlr->in_color_format = config->input_data_color_type; ctlr->in_bpp = in_bits_per_pixel; ESP_LOGD(TAG, "ctlr->in_bpp: 0d %d", ctlr->in_bpp); //out color type - color_space_pixel_format_t out_color_format = { - .color_type_id = config->output_data_color_type, - }; - int out_bits_per_pixel = color_hal_pixel_format_get_bit_depth(out_color_format); + int out_bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(config->output_data_color_type); + + ESP_GOTO_ON_FALSE(out_bits_per_pixel != 0, ESP_ERR_INVALID_ARG, err, TAG, "unsupported output color format"); + ctlr->out_color_format = config->output_data_color_type; ctlr->out_bpp = out_bits_per_pixel; ESP_LOGD(TAG, "ctlr->out_bpp: 0d %d", ctlr->out_bpp); @@ -216,6 +219,12 @@ esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_ ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "cam_csi_ctlr", &ctlr->pm_lock), err, TAG, "failed to create pm lock"); #endif //CONFIG_PM_ENABLE + cam_ctlr_format_conv_config_t format_conv_config = { + .src_format = config->input_data_color_type, + .dst_format = config->output_data_color_type, + }; + ESP_GOTO_ON_ERROR(s_csi_ctlr_format_conversion(&(ctlr->base), &format_conv_config), err, TAG, "failed to configure format conversion"); + ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; ctlr->csi_fsm = CSI_FSM_INIT; ctlr->base.del = s_ctlr_del; @@ -571,9 +580,44 @@ static void *s_csi_ctlr_alloc_buffer(esp_cam_ctlr_t *handle, size_t size, uint32 return buffer; } +static bool s_is_color_format_conversion_supported(cam_ctlr_color_t color_format) +{ + return (color_format == CAM_CTLR_COLOR_RGB888 || + color_format == CAM_CTLR_COLOR_RGB565 || + color_format == CAM_CTLR_COLOR_YUV420 || + color_format == CAM_CTLR_COLOR_YUV422_YVYU || + color_format == CAM_CTLR_COLOR_YUV422_YUYV || + color_format == CAM_CTLR_COLOR_YUV422_UYVY || + color_format == CAM_CTLR_COLOR_YUV422_VYUY); +} + static esp_err_t s_csi_ctlr_format_conversion(esp_cam_ctlr_t *handle, const cam_ctlr_format_conv_config_t *config) { - ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); - // CSI controller doesn't support format conversion yet - return ESP_ERR_NOT_SUPPORTED; + ESP_RETURN_ON_FALSE(handle && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + csi_controller_t *ctlr = __containerof(handle, csi_controller_t, base); + + if (config->src_format == config->dst_format) { + mipi_csi_brg_ll_set_color_mode_bypass(ctlr->hal.bridge_dev, true); + return ESP_OK; + } else { +#if CONFIG_IDF_TARGET_ESP32P4 + //If ESP32P4 chip version is less than v3.0, not support color format conversion + unsigned chip_version = efuse_hal_chip_revision(); + if (!ESP_CHIP_REV_ABOVE(chip_version, 300)) { + return ESP_ERR_NOT_SUPPORTED; + } +#endif + + if (!s_is_color_format_conversion_supported(config->src_format) || !s_is_color_format_conversion_supported(config->dst_format)) { + return ESP_ERR_NOT_SUPPORTED; + } else { + mipi_csi_brg_ll_set_input_color_format(ctlr->hal.bridge_dev, config->src_format); + mipi_csi_brg_ll_set_output_color_format(ctlr->hal.bridge_dev, config->dst_format); + mipi_csi_brg_ll_set_color_mode_bypass(ctlr->hal.bridge_dev, false); + mipi_csi_brg_ll_enable_color_conversion(ctlr->hal.bridge_dev, true); + } + ctlr->in_color_format = config->src_format; + ctlr->out_color_format = config->dst_format; + return ESP_OK; + } } diff --git a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h index 0baf6d55960..7c15c81f82c 100644 --- a/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h +++ b/components/esp_driver_cam/csi/src/esp_cam_ctlr_csi_internal.h @@ -50,8 +50,8 @@ struct csi_controller_t { mipi_csi_hal_context_t hal; //hal context csi_fsm_t csi_fsm; //driver fsm portMUX_TYPE spinlock; //spinlock - color_space_pixel_format_t in_color_format; //input color format - color_space_pixel_format_t out_color_format; //output color format + cam_ctlr_color_t in_color_format; //input color format + cam_ctlr_color_t out_color_format; //output color format uint32_t h_res; //input horizontal resolution uint32_t v_res; //input vertical resolution int in_bpp; //input data type, bit per pixel diff --git a/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h b/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h index 54cf67de2c9..1fddb238ee7 100644 --- a/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h +++ b/components/esp_driver_cam/dvp/include/esp_cam_ctlr_dvp.h @@ -40,6 +40,10 @@ typedef struct esp_cam_ctlr_dvp_config { uint32_t h_res; /*!< Input horizontal resolution, i.e. the number of pixels in a line */ uint32_t v_res; /*!< Input vertical resolution, i.e. the number of lines in a frame */ cam_ctlr_color_t input_data_color_type; /*!< Input pixel format */ + cam_ctlr_color_t output_data_color_type; /*!< Output pixel format */ + color_conv_std_rgb_yuv_t conv_std; /*!< Conversion standard */ + color_range_t input_range; /*!< Input color range */ + color_range_t output_range; /*!< Output color range */ uint32_t cam_data_width; /*!< Byte width, 8, 16 or 24 bit, default to 8 */ struct { uint32_t bit_swap_en : 1; /*!< Enable bit swap */ diff --git a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c index e95348ff740..5e2567a79ee 100644 --- a/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c +++ b/components/esp_driver_cam/dvp/src/esp_cam_ctlr_dvp_cam.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -266,10 +266,7 @@ static esp_err_t esp_cam_ctlr_dvp_cam_get_frame_size(const esp_cam_ctlr_dvp_conf if (config->pic_format_jpeg) { *p_size = config->h_res * config->v_res; } else { - color_space_pixel_format_t pixel_format = { - .color_type_id = config->input_data_color_type - }; - uint32_t depth = color_hal_pixel_format_get_bit_depth(pixel_format); + uint32_t depth = color_hal_pixel_format_fourcc_get_bit_depth(config->input_data_color_type); if (!depth) { return ESP_ERR_INVALID_ARG; } @@ -809,6 +806,9 @@ esp_err_t esp_cam_ctlr_dvp_format_conversion(esp_cam_ctlr_handle_t cam_handle, esp_cam_ctlr_dvp_cam_t *ctlr = (esp_cam_ctlr_dvp_cam_t *)cam_handle; ESP_LOGD(TAG, "Configure format conversion: %d -> %d", config->src_format, config->dst_format); + if (config->src_format == config->dst_format) { + return ESP_OK; + } #if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 if (config->src_format == CAM_CTLR_COLOR_YUV420) { @@ -906,6 +906,16 @@ esp_err_t esp_cam_new_dvp_ctlr(const esp_cam_ctlr_dvp_config_t *config, esp_cam_ cam_hal_init(&ctlr->hal, &cam_hal_config); + cam_ctlr_format_conv_config_t format_conv_config = { + .src_format = config->input_data_color_type, + .dst_format = config->output_data_color_type, + .conv_std = config->conv_std, + .data_width = config->cam_data_width == 0 ? 8 : config->cam_data_width, + .input_range = config->input_range, + .output_range = config->output_range, + }; + ESP_GOTO_ON_ERROR(esp_cam_ctlr_dvp_format_conversion(&(ctlr->base), &format_conv_config), fail5, TAG, "failed to configure format conversion"); + ctlr->ctlr_id = config->ctlr_id; ctlr->fb_size_in_bytes = fb_size_in_bytes; ctlr->dvp_fsm = ESP_CAM_CTLR_DVP_CAM_FSM_INIT; diff --git a/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c b/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c index 28a995d1b1f..b671037ce7d 100644 --- a/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c +++ b/components/esp_driver_cam/test_apps/csi/main/test_csi_driver.c @@ -16,7 +16,7 @@ TEST_CASE("TEST CSI driver allocation", "[csi]") .h_res = 800, .v_res = 640, .lane_bit_rate_mbps = 200, - .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .input_data_color_type = CAM_CTLR_COLOR_RGB565, .output_data_color_type = CAM_CTLR_COLOR_RGB565, .data_lane_num = 2, .byte_swap_en = false, @@ -42,7 +42,7 @@ TEST_CASE("TEST CSI driver no backup buffer usage", "[csi]") .h_res = 800, .v_res = 640, .lane_bit_rate_mbps = 200, - .input_data_color_type = CAM_CTLR_COLOR_RAW8, + .input_data_color_type = CAM_CTLR_COLOR_RGB565, .output_data_color_type = CAM_CTLR_COLOR_RGB565, .data_lane_num = 2, .byte_swap_en = false, diff --git a/components/esp_driver_cam/test_apps/csi/main/test_csi_ov5647.c b/components/esp_driver_cam/test_apps/csi/main/test_csi_ov5647.c index 23ef8ce6fc1..b2e6027ba40 100644 --- a/components/esp_driver_cam/test_apps/csi/main/test_csi_ov5647.c +++ b/components/esp_driver_cam/test_apps/csi/main/test_csi_ov5647.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -97,7 +97,7 @@ TEST_CASE("TEST esp_cam on ov5647", "[csi][camera][ov5647]") .v_res = TEST_MIPI_CSI_DISP_VRES, .lane_bit_rate_mbps = TEST_MIPI_CSI_LANE_BITRATE_MBPS, .input_data_color_type = CAM_CTLR_COLOR_RAW8, - .output_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RAW8, .data_lane_num = 2, .byte_swap_en = false, .queue_items = 1, diff --git a/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c b/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c index 123297574c6..682e9ffd6c5 100644 --- a/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c +++ b/components/esp_driver_cam/test_apps/dvp/main/test_dvp_driver.c @@ -18,6 +18,7 @@ TEST_CASE("TEST DVP driver allocation", "[DVP]") .h_res = 800, .v_res = 640, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 64, .byte_swap_en = false, .pin_dont_init = true, @@ -70,6 +71,7 @@ TEST_CASE("TEST DVP driver no backup buffer usage", "[DVP]") .h_res = 800, .v_res = 640, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 64, .byte_swap_en = false, .bk_buffer_dis = true, @@ -97,6 +99,7 @@ TEST_CASE("TEST DVP driver intern/extern init", "[DVP]") .h_res = 800, .v_res = 640, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 64, .byte_swap_en = false, .external_xtal = true, @@ -129,6 +132,7 @@ TEST_CASE("TEST DVP driver intern/extern generate xclk", "[DVP]") .h_res = 800, .v_res = 640, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 64, .byte_swap_en = false, .external_xtal = true, diff --git a/components/esp_driver_cam/test_apps/dvp/main/test_dvp_s3eye.c b/components/esp_driver_cam/test_apps/dvp/main/test_dvp_s3eye.c index c5f3f69e010..d86a0325bae 100644 --- a/components/esp_driver_cam/test_apps/dvp/main/test_dvp_s3eye.c +++ b/components/esp_driver_cam/test_apps/dvp/main/test_dvp_s3eye.c @@ -88,6 +88,7 @@ TEST_CASE("TEST DVP camera on esp32s3_eye", "[dvp][camera][esp32s3_eye]") .h_res = TEST_DVP_CAM_H_RES, .v_res = TEST_DVP_CAM_V_RES, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 64, .pin = &pin_cfg, .bk_buffer_dis = 1, diff --git a/components/esp_hal_cam/cam_hal.c b/components/esp_hal_cam/cam_hal.c index fc70f89171e..582d1dd3522 100644 --- a/components/esp_hal_cam/cam_hal.c +++ b/components/esp_hal_cam/cam_hal.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include #include "hal/cam_ll.h" #include "hal/cam_hal.h" #include "hal/color_types.h" @@ -158,25 +159,8 @@ void cam_hal_color_format_convert(cam_hal_context_t *hal, cam_ll_enable_rgb_yuv_convert(hal->hw, false); - // Extract color space from source and destination formats - color_space_t src_space = COLOR_SPACE_TYPE(cfg->src_format); - color_space_t dst_space = COLOR_SPACE_TYPE(cfg->dst_format); - - // Configure conversion based on color space types - if (src_space == COLOR_SPACE_YUV && dst_space == COLOR_SPACE_RGB) { - // YUV to RGB conversion - color_pixel_yuv_format_t yuv_format = COLOR_PIXEL_FORMAT(cfg->src_format); - cam_ll_set_convert_mode_yuv_to_rgb(hal->hw, yuv_format); - } else if (src_space == COLOR_SPACE_RGB && dst_space == COLOR_SPACE_YUV) { - // RGB to YUV conversion - color_pixel_yuv_format_t yuv_format = COLOR_PIXEL_FORMAT(cfg->dst_format); - cam_ll_set_convert_mode_rgb_to_yuv(hal->hw, yuv_format); - } else if (src_space == COLOR_SPACE_YUV && dst_space == COLOR_SPACE_YUV) { - // YUV to YUV conversion - color_pixel_yuv_format_t src_yuv_format = COLOR_PIXEL_FORMAT(cfg->src_format); - color_pixel_yuv_format_t dst_yuv_format = COLOR_PIXEL_FORMAT(cfg->dst_format); - cam_ll_set_convert_mode_yuv_to_yuv(hal->hw, src_yuv_format, dst_yuv_format); - } + // Configure conversion mode based on source and destination formats + cam_ll_set_convert_mode(hal->hw, cfg->src_format, cfg->dst_format); // Common configuration for all conversion types cam_ll_set_yuv_convert_std(hal->hw, cfg->conv_std); diff --git a/components/esp_hal_cam/esp32p4/include/hal/cam_ll.h b/components/esp_hal_cam/esp32p4/include/hal/cam_ll.h index 826977bcbbc..7a42801cd76 100644 --- a/components/esp_hal_cam/esp32p4/include/hal/cam_ll.h +++ b/components/esp_hal_cam/esp32p4/include/hal/cam_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -302,91 +302,40 @@ static inline void cam_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, color_conv_std } /** - * @brief Set the converter mode: RGB565 to YUV + * @brief Set converter mode * * @param dev CAM register base address - * @param yuv_sample YUV sample mode + * @param src_fourcc Source format FourCC + * @param dst_fourcc Destination format FourCC */ -static inline void cam_ll_set_convert_mode_rgb_to_yuv(lcd_cam_dev_t *dev, color_pixel_yuv_format_t yuv_sample) +static inline void cam_ll_set_convert_mode(lcd_cam_dev_t *dev, uint32_t src_fourcc, uint32_t dst_fourcc) { - dev->cam_rgb_yuv.cam_conv_trans_mode = 1; - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; - switch (yuv_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; - break; - default: - abort(); - } -} + bool src_is_yuv = (src_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY || + src_fourcc == ESP_COLOR_FOURCC_YVYU || + src_fourcc == ESP_COLOR_FOURCC_YUYV || + src_fourcc == ESP_COLOR_FOURCC_UYVY || + src_fourcc == ESP_COLOR_FOURCC_VYUY || + src_fourcc == ESP_COLOR_FOURCC_YUV); + bool dst_is_yuv = (dst_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY || + dst_fourcc == ESP_COLOR_FOURCC_YVYU || + dst_fourcc == ESP_COLOR_FOURCC_YUYV || + dst_fourcc == ESP_COLOR_FOURCC_UYVY || + dst_fourcc == ESP_COLOR_FOURCC_VYUY || + dst_fourcc == ESP_COLOR_FOURCC_YUV); -/** - * @brief Set the converter mode: YUV to RGB565 - * - * @param dev CAM register base address - * @param yuv_sample YUV sample mode - */ -static inline void cam_ll_set_convert_mode_yuv_to_rgb(lcd_cam_dev_t *dev, color_pixel_yuv_format_t yuv_sample) -{ - dev->cam_rgb_yuv.cam_conv_trans_mode = 0; - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; - switch (yuv_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; - break; - default: - abort(); - } -} - -/** - * @brief Set the converter mode: YUV to YUV - * - * @param dev CAM register base address - * @param src_sample Source YUV sample mode - * @param dst_sample Destination YUV sample mode - */ -static inline void cam_ll_set_convert_mode_yuv_to_yuv(lcd_cam_dev_t *dev, color_pixel_yuv_format_t src_sample, color_pixel_yuv_format_t dst_sample) -{ - HAL_ASSERT(src_sample != dst_sample); - dev->cam_rgb_yuv.cam_conv_trans_mode = 1; - switch (src_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; - break; - default: - abort(); - } - switch (dst_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 2; - break; - default: - abort(); + if (src_is_yuv && dst_is_yuv) { + HAL_ASSERT(src_fourcc != dst_fourcc); + dev->cam_rgb_yuv.cam_conv_trans_mode = 1; + dev->cam_rgb_yuv.cam_conv_yuv_mode = (src_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = (dst_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; + } else if (src_is_yuv) { + dev->cam_rgb_yuv.cam_conv_trans_mode = 0; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; + dev->cam_rgb_yuv.cam_conv_yuv_mode = (src_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; + } else if (dst_is_yuv) { + dev->cam_rgb_yuv.cam_conv_trans_mode = 1; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; + dev->cam_rgb_yuv.cam_conv_yuv_mode = (dst_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; } } diff --git a/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_brg_ll.h b/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_brg_ll.h index 5ce3feec202..dd19cc6a92a 100644 --- a/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_brg_ll.h +++ b/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_brg_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,8 @@ #include "hal/assert.h" #include "hal/hal_utils.h" #include "hal/mipi_csi_types.h" +#include "hal/color_types.h" +#include "hal/cam_ctlr_types.h" #include "soc/mipi_csi_bridge_struct.h" #ifdef __cplusplus diff --git a/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_ll.h b/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_ll.h index a491767f2e2..6d3612023a5 100644 --- a/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_ll.h +++ b/components/esp_hal_cam/esp32p4/include/hal/mipi_csi_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ #include "hal/mipi_csi_brg_ll.h" #include "hal/mipi_csi_phy_ll.h" #include "hal/mipi_csi_host_ll.h" +#include "hal/config.h" #include "soc/hp_sys_clkrst_struct.h" #ifdef __cplusplus @@ -155,6 +156,141 @@ static inline void mipi_csi_ll_reset_host_clock(int group_id) mipi_csi_ll_reset_host_clock(__VA_ARGS__); \ } while(0) +#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + +/** + * @brief Set RGB element order for input color data + * + * @param dev Pointer to the CSI bridge controller register base address + * @param rgb_format RGB element order: 0=RGB, 1=BGR, 2=RBG, 3=BRG, 4=GRB, 5=GBR + * + */ +static inline void mipi_csi_brg_ll_set_input_rgb_format(csi_brg_dev_t *dev, uint32_t rgb_format) +{ + dev->host_cm_ctrl.csi_host_cm_rx_rgb_format = rgb_format; +} + +/** + * @brief Set the color format for the input color data + * + * @param dev Pointer to the CSI bridge controller register base address + * @param color_format Camera controller color format + */ +static inline void mipi_csi_brg_ll_set_input_color_format(csi_brg_dev_t *dev, cam_ctlr_color_t color_format) +{ + // Set format type + if (color_format == CAM_CTLR_COLOR_RGB888) { + dev->host_cm_ctrl.csi_host_cm_rx = 0; + mipi_csi_brg_ll_set_input_rgb_format(dev, 0); // Default: RGB order + } else if (color_format == CAM_CTLR_COLOR_RGB565) { + dev->host_cm_ctrl.csi_host_cm_rx = 1; + mipi_csi_brg_ll_set_input_rgb_format(dev, 0); // Default: RGB order + } else if (color_format == CAM_CTLR_COLOR_YUV420) { + dev->host_cm_ctrl.csi_host_cm_rx = 3; + } else if (color_format == CAM_CTLR_COLOR_YUV422_YVYU || + color_format == CAM_CTLR_COLOR_YUV422_YUYV || + color_format == CAM_CTLR_COLOR_YUV422_UYVY || + color_format == CAM_CTLR_COLOR_YUV422_VYUY) { + dev->host_cm_ctrl.csi_host_cm_rx = 2; + // Set YUV422 packing order: YVYU=0, YUYV=1, VYUY=2, UYVY=3 + if (color_format == CAM_CTLR_COLOR_YUV422_YVYU) { + dev->host_cm_ctrl.csi_host_cm_rx_yuv422_format = 0; + } else if (color_format == CAM_CTLR_COLOR_YUV422_YUYV) { + dev->host_cm_ctrl.csi_host_cm_rx_yuv422_format = 1; + } else if (color_format == CAM_CTLR_COLOR_YUV422_VYUY) { + dev->host_cm_ctrl.csi_host_cm_rx_yuv422_format = 2; + } else if (color_format == CAM_CTLR_COLOR_YUV422_UYVY) { + dev->host_cm_ctrl.csi_host_cm_rx_yuv422_format = 3; + } + } else { + HAL_ASSERT(false && "Unsupported input color format"); + } +} + +/** + * @brief Enable or disable color mode conversion output + * + * @param dev Pointer to the CSI bridge controller register base address + * @param en true to enable, false to disable + * + */ +static inline void mipi_csi_brg_ll_enable_color_conversion(csi_brg_dev_t *dev, bool en) +{ + dev->host_cm_ctrl.csi_host_cm_en = en; +} + +/** + * @brief Enable or disable color mode conversion bypass + * + * @param dev Pointer to the CSI bridge controller regihost_cm_ctrlster base address + * @param bypass true to bypass (input directly to output), false to enable conversion + * + */ +static inline void mipi_csi_brg_ll_set_color_mode_bypass(csi_brg_dev_t *dev, bool bypass) +{ + dev->host_cm_ctrl.csi_host_cm_bypass = bypass; +} + +/** + * @brief Set the color format for the output color data + * + * @param dev Pointer to the CSI bridge controller register base address + * @param color_format Camera controller color format + */ +static inline void mipi_csi_brg_ll_set_output_color_format(csi_brg_dev_t *dev, cam_ctlr_color_t color_format) +{ + if (color_format == CAM_CTLR_COLOR_RGB888) { + dev->host_cm_ctrl.csi_host_cm_tx = 0; + } else if (color_format == CAM_CTLR_COLOR_RGB565) { + dev->host_cm_ctrl.csi_host_cm_tx = 1; + } else if (color_format == CAM_CTLR_COLOR_YUV420) { + dev->host_cm_ctrl.csi_host_cm_tx = 3; + } else if (color_format == CAM_CTLR_COLOR_YUV422_YVYU || + color_format == CAM_CTLR_COLOR_YUV422_YUYV || + color_format == CAM_CTLR_COLOR_YUV422_UYVY || + color_format == CAM_CTLR_COLOR_YUV422_VYUY) { + dev->host_cm_ctrl.csi_host_cm_tx = 2; + } else { + HAL_ASSERT(false && "Unsupported output color format"); + } +} +#else +static inline void mipi_csi_brg_ll_set_input_rgb_format(csi_brg_dev_t *dev, uint32_t rgb_format) +{ + //for compatibility + (void)dev; + (void)rgb_format; +} + +static inline void mipi_csi_brg_ll_set_input_color_format(csi_brg_dev_t *dev, cam_ctlr_color_t color_format) +{ + //for compatibility + (void)dev; + (void)color_format; +} + +static inline void mipi_csi_brg_ll_enable_color_conversion(csi_brg_dev_t *dev, bool en) +{ + //for compatibility + (void)dev; + (void)en; +} + +static inline void mipi_csi_brg_ll_set_color_mode_bypass(csi_brg_dev_t *dev, bool bypass) +{ + //for compatibility + (void)dev; + (void)bypass; +} + +static inline void mipi_csi_brg_ll_set_output_color_format(csi_brg_dev_t *dev, cam_ctlr_color_t color_format) +{ + //for compatibility + (void)dev; + (void)color_format; +} +#endif // HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 + #ifdef __cplusplus } #endif diff --git a/components/esp_hal_cam/esp32s3/include/hal/cam_ll.h b/components/esp_hal_cam/esp32s3/include/hal/cam_ll.h index b52b34eab08..2b58c45f76f 100644 --- a/components/esp_hal_cam/esp32s3/include/hal/cam_ll.h +++ b/components/esp_hal_cam/esp32s3/include/hal/cam_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -265,91 +265,40 @@ static inline void cam_ll_set_yuv_convert_std(lcd_cam_dev_t *dev, color_conv_std } /** - * @brief Set the converter mode: RGB565 to YUV + * @brief Set converter mode * * @param dev CAM register base address - * @param yuv_sample YUV sample mode + * @param src_fourcc Source format FourCC + * @param dst_fourcc Destination format FourCC */ -static inline void cam_ll_set_convert_mode_rgb_to_yuv(lcd_cam_dev_t *dev, color_pixel_yuv_format_t yuv_sample) +static inline void cam_ll_set_convert_mode(lcd_cam_dev_t *dev, uint32_t src_fourcc, uint32_t dst_fourcc) { - dev->cam_rgb_yuv.cam_conv_trans_mode = 1; - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; - switch (yuv_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; - break; - default: - abort(); - } -} + bool src_is_yuv = (src_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY || + src_fourcc == ESP_COLOR_FOURCC_YVYU || + src_fourcc == ESP_COLOR_FOURCC_YUYV || + src_fourcc == ESP_COLOR_FOURCC_UYVY || + src_fourcc == ESP_COLOR_FOURCC_VYUY || + src_fourcc == ESP_COLOR_FOURCC_YUV); + bool dst_is_yuv = (dst_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY || + dst_fourcc == ESP_COLOR_FOURCC_YVYU || + dst_fourcc == ESP_COLOR_FOURCC_YUYV || + dst_fourcc == ESP_COLOR_FOURCC_UYVY || + dst_fourcc == ESP_COLOR_FOURCC_VYUY || + dst_fourcc == ESP_COLOR_FOURCC_YUV); -/** - * @brief Set the converter mode: YUV to RGB565 - * - * @param dev CAM register base address - * @param yuv_sample YUV sample mode - */ -static inline void cam_ll_set_convert_mode_yuv_to_rgb(lcd_cam_dev_t *dev, color_pixel_yuv_format_t yuv_sample) -{ - dev->cam_rgb_yuv.cam_conv_trans_mode = 0; - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; - switch (yuv_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; - break; - default: - abort(); - } -} - -/** - * @brief Set the converter mode: YUV to YUV - * - * @param dev CAM register base address - * @param src_sample Source YUV sample mode - * @param dst_sample Destination YUV sample mode - */ -static inline void cam_ll_set_convert_mode_yuv_to_yuv(lcd_cam_dev_t *dev, color_pixel_yuv_format_t src_sample, color_pixel_yuv_format_t dst_sample) -{ - HAL_ASSERT(src_sample != dst_sample); - dev->cam_rgb_yuv.cam_conv_trans_mode = 1; - switch (src_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv_mode = 2; - break; - default: - abort(); - } - switch (dst_sample) { - case COLOR_PIXEL_YUV422: - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 0; - break; - case COLOR_PIXEL_YUV420: - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 1; - break; - case COLOR_PIXEL_YUV411: - dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 2; - break; - default: - abort(); + if (src_is_yuv && dst_is_yuv) { + HAL_ASSERT(src_fourcc != dst_fourcc); + dev->cam_rgb_yuv.cam_conv_trans_mode = 1; + dev->cam_rgb_yuv.cam_conv_yuv_mode = (src_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = (dst_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; + } else if (src_is_yuv) { + dev->cam_rgb_yuv.cam_conv_trans_mode = 0; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; + dev->cam_rgb_yuv.cam_conv_yuv_mode = (src_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; + } else if (dst_is_yuv) { + dev->cam_rgb_yuv.cam_conv_trans_mode = 1; + dev->cam_rgb_yuv.cam_conv_yuv2yuv_mode = 3; + dev->cam_rgb_yuv.cam_conv_yuv_mode = (dst_fourcc == ESP_COLOR_FOURCC_OUYY_EVYY) ? 1 : 0; } } diff --git a/components/esp_hal_cam/include/hal/cam_ctlr_types.h b/components/esp_hal_cam/include/hal/cam_ctlr_types.h index 7b0001e9792..a23d50575b2 100644 --- a/components/esp_hal_cam/include/hal/cam_ctlr_types.h +++ b/components/esp_hal_cam/include/hal/cam_ctlr_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,19 +14,20 @@ extern "C" { #endif /** - * @brief Camera Controller Color Type + * @brief Camera Controller Color Type, in FourCC format */ typedef enum { - CAM_CTLR_COLOR_RAW8 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW8), ///< RAW8 - CAM_CTLR_COLOR_RAW10 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW10), ///< RAW10 - CAM_CTLR_COLOR_RAW12 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW12), ///< RAW12 - CAM_CTLR_COLOR_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), ///< RGB565 - CAM_CTLR_COLOR_RGB666 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666), ///< RGB666 - CAM_CTLR_COLOR_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), ///< RGB888 - CAM_CTLR_COLOR_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), ///< YUV420 - CAM_CTLR_COLOR_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), ///< YUV422 - CAM_CTLR_COLOR_GRAY4 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY4), ///< GRAY4 - CAM_CTLR_COLOR_GRAY8 = COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8), ///< GRAY8 + CAM_CTLR_COLOR_RAW8 = ESP_COLOR_FOURCC_RAW8, ///< RAW8 + CAM_CTLR_COLOR_RAW10 = ESP_COLOR_FOURCC_RAW10, ///< RAW10 + CAM_CTLR_COLOR_RAW12 = ESP_COLOR_FOURCC_RAW12, ///< RAW12 + CAM_CTLR_COLOR_RGB565 = ESP_COLOR_FOURCC_RGB16, ///< RGB565 + CAM_CTLR_COLOR_RGB888 = ESP_COLOR_FOURCC_RGB24, ///< RGB888 + CAM_CTLR_COLOR_YUV420 = ESP_COLOR_FOURCC_OUYY_EVYY, ///< YUV420 + CAM_CTLR_COLOR_YUV422_YVYU = ESP_COLOR_FOURCC_YVYU, ///< YUV422, YVYU + CAM_CTLR_COLOR_YUV422_YUYV = ESP_COLOR_FOURCC_YUYV, ///< YUV422, YUYV + CAM_CTLR_COLOR_YUV422_UYVY = ESP_COLOR_FOURCC_UYVY, ///< YUV422, UYVY + CAM_CTLR_COLOR_YUV422_VYUY = ESP_COLOR_FOURCC_VYUY, ///< YUV422, VYUY + CAM_CTLR_COLOR_GRAY8 = ESP_COLOR_FOURCC_GREY, ///< GREY8 } cam_ctlr_color_t; /** diff --git a/components/hal/color_hal.c b/components/hal/color_hal.c index b556f8da488..693a8d535d9 100644 --- a/components/hal/color_hal.c +++ b/components/hal/color_hal.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -8,41 +8,6 @@ #include "hal/color_hal.h" #include "hal/assert.h" -uint32_t color_hal_pixel_format_get_bit_depth(color_space_pixel_format_t format) -{ - switch (format.color_type_id) { - case COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY4): - case COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A4): - case COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L4): - return 4; - case COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW8): - case COLOR_TYPE_ID(COLOR_SPACE_GRAY, COLOR_PIXEL_GRAY8): - case COLOR_TYPE_ID(COLOR_SPACE_ALPHA, COLOR_PIXEL_A8): - case COLOR_TYPE_ID(COLOR_SPACE_CLUT, COLOR_PIXEL_L8): - return 8; - case COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW10): - return 10; - case COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW12): - case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420): - case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV411): - return 12; - case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565): - case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422): - return 16; - case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666): - return 18; - case COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888): - case COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV444): - return 24; - case COLOR_TYPE_ID(COLOR_SPACE_ARGB, COLOR_PIXEL_ARGB8888): - return 32; - default: - // Unknown color space pixel format, unknown bit depth - HAL_ASSERT(false); - return 0; - } -} - uint32_t color_hal_pixel_format_fourcc_get_bit_depth(esp_color_fourcc_t four_character_code) { switch (four_character_code) { @@ -62,8 +27,10 @@ uint32_t color_hal_pixel_format_fourcc_get_bit_depth(esp_color_fourcc_t four_cha case ESP_COLOR_FOURCC_YVYU: case ESP_COLOR_FOURCC_VYUY: case ESP_COLOR_FOURCC_RGB16: + case ESP_COLOR_FOURCC_RGB16_BE: return 16; case ESP_COLOR_FOURCC_BGR24: + case ESP_COLOR_FOURCC_RGB24: case ESP_COLOR_FOURCC_YUV: return 24; case ESP_COLOR_FOURCC_BGRA32: diff --git a/components/hal/include/hal/color_hal.h b/components/hal/include/hal/color_hal.h index 6502781a882..1344bf66848 100644 --- a/components/hal/include/hal/color_hal.h +++ b/components/hal/include/hal/color_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,16 +13,6 @@ extern "C" { #endif -/** - * @brief Get the bit depth (bits/pixel) of each color space pixel format - * - * @param color_type_id Value constructed in color_space_pixel_format_t struct - * - * @return Number of bits per pixel - */ -uint32_t color_hal_pixel_format_get_bit_depth(color_space_pixel_format_t color_type_id); - - /** * @brief Get the bit depth (bits/pixel) of each color space pixel format * diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h index c52fca8d75d..a17dc7af3a9 100644 --- a/components/hal/include/hal/color_types.h +++ b/components/hal/include/hal/color_types.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,6 +44,16 @@ typedef uint32_t esp_color_fourcc_t; */ #define ESP_COLOR_FOURCC_BGR24 ESP_COLOR_FOURCC('B', 'G', 'R', '3') /* 24 bpp BGR-8-8-8 */ +/** + * RGB24 (RGB888) + * Memory Layout: + * | bit7 - bit0 | + * Byte 2: | B7 - B0 | + * Byte 1: | G7 - G0 | + * Byte 0: | R7 - R0 | + */ +#define ESP_COLOR_FOURCC_RGB24 ESP_COLOR_FOURCC('R', 'G', 'B', '3') /* 24 bpp RGB-8-8-8 */ + /** * RGB565 * Memory Layout: @@ -53,6 +63,15 @@ typedef uint32_t esp_color_fourcc_t; */ #define ESP_COLOR_FOURCC_RGB16 ESP_COLOR_FOURCC('R', 'G', 'B', 'L') /* 16 bpp RGB-5-6-5, little endian */ +/** + * RGB565 (Big Endian) + * Memory Layout: + * | bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 | + * Byte 1: | G2 G1 G0 | B4 B3 B2 B1 B0 | + * Byte 0: | R4 R3 R2 R1 R0 | G5 G4 G3 | + */ +#define ESP_COLOR_FOURCC_RGB16_BE ESP_COLOR_FOURCC('R', 'G', 'B', 'E') /* 16 bpp RGB-5-6-5, big endian */ + /** * Grey8 * Memory Layout: @@ -286,113 +305,6 @@ typedef enum { COLOR_COMPONENT_INVALID, /*!< Invalid color component */ } color_component_t; -///< The following values are deprecated, please use the FOURCC values instead, IDF-14284 - -/*--------------------------------------------------------------- - Color Space ----------------------------------------------------------------*/ -/** - * @brief Color Space - * - * @note Save enum 0 for special purpose - */ -typedef enum { - COLOR_SPACE_RAW = 1, ///< Color space raw - COLOR_SPACE_RGB, ///< Color space rgb - COLOR_SPACE_YUV, ///< Color space yuv - COLOR_SPACE_GRAY, ///< Color space gray - COLOR_SPACE_ARGB, ///< Color space argb - COLOR_SPACE_ALPHA, ///< Color space alpha (A) - COLOR_SPACE_CLUT, ///< Color look-up table (L) -} color_space_t; - -/*--------------------------------------------------------------- - Color Pixel Format ----------------------------------------------------------------*/ -/** - * @brief Raw Format - */ -typedef enum { - COLOR_PIXEL_RAW8, ///< 8 bits per pixel - COLOR_PIXEL_RAW10, ///< 10 bits per pixel - COLOR_PIXEL_RAW12, ///< 12 bits per pixel -} color_pixel_raw_format_t; - -/** - * @brief RGB Format - */ -typedef enum { - COLOR_PIXEL_RGB888, ///< 24 bits, 8 bits per R/G/B value - COLOR_PIXEL_RGB666, ///< 18 bits, 6 bits per R/G/B value - COLOR_PIXEL_RGB565, ///< 16 bits, 5 bits per R/B value, 6 bits for G value -} color_pixel_rgb_format_t; - -/** - * @brief YUV Format - */ -typedef enum { - COLOR_PIXEL_YUV444, ///< 24 bits, 8 bits per Y/U/V value - 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_yuv_format_t; - -/** - * @brief Gray Format - */ -typedef enum { - COLOR_PIXEL_GRAY4, ///< 4 bits, grayscale - COLOR_PIXEL_GRAY8, ///< 8 bits, grayscale -} color_pixel_gray_format_t; - -/** - * @brief ARGB Format - */ -typedef enum { - COLOR_PIXEL_ARGB8888, ///< 32 bits, 8 bits per A(alpha)/R/G/B value -} color_pixel_argb_format_t; - -/** - * @brief Alpha(A) Format - */ -typedef enum { - COLOR_PIXEL_A4, ///< 4 bits, opacity only - COLOR_PIXEL_A8, ///< 8 bits, opacity only -} color_pixel_alpha_format_t; - -/** - * @brief CLUT(L) Format - */ -typedef enum { - COLOR_PIXEL_L4, ///< 4 bits, color look-up table - COLOR_PIXEL_L8, ///< 8 bits, color look-up table -} color_pixel_clut_format_t; - -/*--------------------------------------------------------------- - Color Space Pixel Struct Type ----------------------------------------------------------------*/ -///< Bitwidth of the `color_space_pixel_format_t::color_space` field -#define COLOR_SPACE_BITWIDTH 8 -///< Bitwidth of the `color_space_pixel_format_t::pixel_format` field -#define COLOR_PIXEL_FORMAT_BITWIDTH 24 -///< Helper to get the color_space from a unique color type ID -#define COLOR_SPACE_TYPE(color_type_id) (((color_type_id) >> COLOR_PIXEL_FORMAT_BITWIDTH) & ((1 << COLOR_SPACE_BITWIDTH) - 1)) -///< Helper to get the pixel_format from a unique color type ID -#define COLOR_PIXEL_FORMAT(color_type_id) ((color_type_id) & ((1 << COLOR_PIXEL_FORMAT_BITWIDTH) - 1)) -///< Make a unique ID of a color based on the value of color space and pixel format -#define COLOR_TYPE_ID(color_space, pixel_format) (((color_space) << COLOR_PIXEL_FORMAT_BITWIDTH) | (pixel_format)) - -/** - * @brief Color Space Info Structure - */ -typedef union { - struct { - uint32_t pixel_format: COLOR_PIXEL_FORMAT_BITWIDTH; ///< Format of a certain color space type - uint32_t color_space: COLOR_SPACE_BITWIDTH; ///< Color space type - }; - uint32_t color_type_id; ///< Unique type of a certain color pixel format -} color_space_pixel_format_t; - #ifdef __cplusplus } #endif diff --git a/docs/en/api-reference/peripherals/camera_driver.rst b/docs/en/api-reference/peripherals/camera_driver.rst index b99df7ec68f..0784ecad238 100644 --- a/docs/en/api-reference/peripherals/camera_driver.rst +++ b/docs/en/api-reference/peripherals/camera_driver.rst @@ -184,6 +184,7 @@ You can implement the camera controller driver using one of the following method .h_res = CONFIG_EXAMPLE_CAM_HRES, .v_res = CONFIG_EXAMPLE_CAM_VRES, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 128, .pin = &pin_cfg, .bk_buffer_dis = 1, diff --git a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst index 1daa1f046d8..65a7634469d 100644 --- a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst @@ -278,6 +278,27 @@ LCD - The NT35510 LCD device driver has been moved out of ESP-IDF and is now hosted in the `ESP Component Registry `__. If your project uses the NT35510 driver, you can add it to your project by running ``idf.py add-dependency "espressif/esp_lcd_nt35510"``. - The ``use_dma2d`` member in the :cpp:type:`esp_lcd_dpi_panel_config_t` has been removed. Please use the :func:`esp_lcd_dpi_panel_enable_dma2d` function to enable DMA2D for the DPI panel. When not using DMA2D, the binary file size can be reduced by around 10KB. +Color Types +----------- + +The following types in the ``components/hal/include/hal/color_types.h`` header file have been removed. Please use FourCC format (:cpp:type:`esp_color_fourcc_t`) instead: + +- :cpp:type:`color_space_t` - The color space enumeration type has been removed. Please use FourCC format to specify color space and pixel format. +- :cpp:type:`color_space_pixel_format_t` - The color space pixel format union has been removed. Please use :cpp:type:`esp_color_fourcc_t` type and corresponding FourCC macro definitions to specify pixel format. + +Migration example: + +.. code-block:: c + + /* Old */ + color_space_pixel_format_t format = { + .color_space = COLOR_SPACE_RGB, + .pixel_format = COLOR_PIXEL_RGB565 + }; + + /* New */ + esp_color_fourcc_t format = ESP_COLOR_FOURCC_RGB565; + SPI --- diff --git a/docs/zh_CN/api-reference/peripherals/camera_driver.rst b/docs/zh_CN/api-reference/peripherals/camera_driver.rst index f695b11538a..38a9212cead 100644 --- a/docs/zh_CN/api-reference/peripherals/camera_driver.rst +++ b/docs/zh_CN/api-reference/peripherals/camera_driver.rst @@ -184,6 +184,7 @@ .h_res = CONFIG_EXAMPLE_CAM_HRES, .v_res = CONFIG_EXAMPLE_CAM_VRES, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 128, .pin = &pin_cfg, .bk_buffer_dis = 1, diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst index 6b376eada5d..16168129987 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst @@ -278,6 +278,27 @@ LCD - NT35510 LCD 设备驱动已经从 ESP-IDF 中移动到外部仓库,并且托管在了 `ESP Component Registry `__ 上。如果你的项目使用到了 NT35510 驱动,你可以通过运行 ``idf.py add-dependency "espressif/esp_lcd_nt35510"`` 将它添加到你的项目中。 - :cpp:type:`esp_lcd_dpi_panel_config_t` 结构体中的 ``use_dma2d`` 成员已被移除。请使用 :func:`esp_lcd_dpi_panel_enable_dma2d` 函数来启用 DMA2D 功能。当不使用 DMA2D 时,可以减小 10KB 左右的二进制文件大小。 +颜色类型 (Color Types) +---------------------- + +位于 ``components/hal/include/hal/color_types.h`` 头文件中的以下类型已被移除,请使用 FourCC 格式(:cpp:type:`esp_color_fourcc_t`)替代: + +- :cpp:type:`color_space_t` - 颜色空间枚举类型已被移除。请使用 FourCC 格式来指定颜色空间和像素格式。 +- :cpp:type:`color_space_pixel_format_t` - 颜色空间像素格式联合体已被移除。请使用 :cpp:type:`esp_color_fourcc_t` 类型和相应的 FourCC 宏定义来指定像素格式。 + +迁移示例: + +.. code-block:: c + + /* 旧版 */ + color_space_pixel_format_t format = { + .color_space = COLOR_SPACE_RGB, + .pixel_format = COLOR_PIXEL_RGB565 + }; + + /* 新版 */ + esp_color_fourcc_t format = ESP_COLOR_FOURCC_RGB565; + SPI --- diff --git a/examples/peripherals/camera/dvp_dsi/main/dvp_dsi_main.c b/examples/peripherals/camera/dvp_dsi/main/dvp_dsi_main.c index 0bf5d203cce..f2bbce28956 100644 --- a/examples/peripherals/camera/dvp_dsi/main/dvp_dsi_main.c +++ b/examples/peripherals/camera/dvp_dsi/main/dvp_dsi_main.c @@ -92,6 +92,7 @@ void app_main(void) .h_res = CONFIG_EXAMPLE_CAM_HRES, .v_res = CONFIG_EXAMPLE_CAM_VRES, .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, .dma_burst_size = 128, .pin = &pin_cfg, .bk_buffer_dis = 1, diff --git a/examples/peripherals/camera/dvp_spi_lcd/main/dvp_spi_lcd_main.c b/examples/peripherals/camera/dvp_spi_lcd/main/dvp_spi_lcd_main.c index 655e46a16de..7270992ae84 100644 --- a/examples/peripherals/camera/dvp_spi_lcd/main/dvp_spi_lcd_main.c +++ b/examples/peripherals/camera/dvp_spi_lcd/main/dvp_spi_lcd_main.c @@ -1,11 +1,12 @@ /* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include +#include "hal/cam_ctlr_types.h" #include "sdkconfig.h" #include "esp_attr.h" #include "esp_log.h" @@ -147,10 +148,15 @@ void app_main(void) .h_res = CONFIG_EXAMPLE_CAM_HRES, .v_res = CONFIG_EXAMPLE_CAM_VRES, #if CONFIG_EXAMPLE_CAM_INPUT_FORMAT_YUV422 - .input_data_color_type = CAM_CTLR_COLOR_YUV422, + .input_data_color_type = CAM_CTLR_COLOR_YUV422_UYVY, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, #else .input_data_color_type = CAM_CTLR_COLOR_RGB565, + .output_data_color_type = CAM_CTLR_COLOR_RGB565, #endif + .conv_std = COLOR_CONV_STD_RGB_YUV_BT601, + .input_range = COLOR_RANGE_LIMIT, + .output_range = COLOR_RANGE_LIMIT, .dma_burst_size = 64, .pin = &pin_cfg, .bk_buffer_dis = 1, @@ -208,8 +214,8 @@ void app_main(void) ESP_LOGI(TAG, "Configure format conversion: YUV422 -> RGB565"); // Configure format conversion const cam_ctlr_format_conv_config_t conv_cfg = { - .src_format = CAM_CTLR_COLOR_YUV422, // Source format: YUV422 - .dst_format = CAM_CTLR_COLOR_RGB565, // Destination format: RGB565 + .src_format = CAM_CTLR_COLOR_YUV422_UYVY, // Source format: YUV422 + .dst_format = CAM_CTLR_COLOR_RGB565, // Destination format: RGB565 .conv_std = COLOR_CONV_STD_RGB_YUV_BT601, .data_width = 8, .input_range = COLOR_RANGE_LIMIT,