mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'feature/support_isp_ccm_v5.3' into 'release/v5.3'
feat(isp_ccm): support isp color correction matrix (v5.3) See merge request espressif/esp-idf!31608
This commit is contained in:
@@ -11,6 +11,7 @@ set(requires)
|
||||
if(CONFIG_SOC_ISP_SUPPORTED)
|
||||
list(APPEND srcs "src/isp_core.c"
|
||||
"src/isp_af.c"
|
||||
"src/isp_ccm.c"
|
||||
"src/isp_awb.c")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -15,3 +15,4 @@
|
||||
#include "driver/isp_af.h"
|
||||
#include "driver/isp_awb.h"
|
||||
#include "driver/isp_bf.h"
|
||||
#include "driver/isp_ccm.h"
|
||||
|
||||
@@ -177,7 +177,7 @@ typedef struct {
|
||||
/**
|
||||
* @brief Prototype of ISP AWB event callback
|
||||
*
|
||||
* @param[in] handle ISP AWB controller handle
|
||||
* @param[in] awb_ctlr ISP AWB controller handle
|
||||
* @param[in] edata ISP AWB event data
|
||||
* @param[in] user_data User registered context, registered when in `esp_isp_awb_env_detector_register_event_callbacks()`
|
||||
*
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Color Correction Matrix configurations
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
float matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]; /*!< The color correction matrix in float, range (-4.0, 4.0) */
|
||||
bool saturation; /*!< Whether to use saturation when the float data in the matrix is out of the range,
|
||||
* For example, if one of the matrix data is 5.0,
|
||||
* When saturation is true, and final value will be limited to 4.0, and won't rise error
|
||||
* When saturation is false, `esp_isp_ccm_configure` will rise ESP_ERR_INVALID_ARG error
|
||||
*/
|
||||
} esp_isp_ccm_config_t;
|
||||
|
||||
/**
|
||||
* @brief ISP Color Correction Matrix (CCM) configuration
|
||||
*
|
||||
* @note This function is allowed to be called before or after `esp_isp_ccm_enable`,
|
||||
* but it only takes effect until `esp_isp_ccm_enable` is called
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
* @param[in] ccm_cfg CCM configurations, set NULL to de-configure the ISP CCM
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
*/
|
||||
esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config_t *ccm_cfg);
|
||||
|
||||
/**
|
||||
* @brief Enable ISP CCM function
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc);
|
||||
|
||||
/**
|
||||
* @brief Disable ISP CCM function
|
||||
*
|
||||
* @param[in] proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_ccm_disable(isp_proc_handle_t proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "driver/isp_core.h"
|
||||
#include "driver/isp_ccm.h"
|
||||
#include "esp_private/isp_private.h"
|
||||
|
||||
static const char *TAG = "ISP_CCM";
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CCM
|
||||
---------------------------------------------------------------*/
|
||||
esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config_t *ccm_cfg)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc && ccm_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
bool ret = true;
|
||||
portENTER_CRITICAL(&proc->spinlock);
|
||||
ret = isp_hal_ccm_set_matrix(&proc->hal, ccm_cfg->saturation, ccm_cfg->matrix);
|
||||
portEXIT_CRITICAL(&proc->spinlock);
|
||||
ESP_RETURN_ON_FALSE(ret, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ccm matrix contain NaN or out of range");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
portENTER_CRITICAL(&proc->spinlock);
|
||||
isp_ll_ccm_clk_enable(proc->hal.hw, true);
|
||||
isp_ll_ccm_enable(proc->hal.hw, true);
|
||||
portEXIT_CRITICAL(&proc->spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_isp_ccm_disable(isp_proc_handle_t proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||
|
||||
portENTER_CRITICAL(&proc->spinlock);
|
||||
isp_ll_ccm_enable(proc->hal.hw, false);
|
||||
isp_ll_ccm_clk_enable(proc->hal.hw, false);
|
||||
portEXIT_CRITICAL(&proc->spinlock);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -118,3 +118,38 @@ TEST_CASE("ISP AWB driver basic function", "[isp]")
|
||||
TEST_ESP_OK(esp_isp_disable(isp_proc));
|
||||
TEST_ESP_OK(esp_isp_del_processor(isp_proc));
|
||||
}
|
||||
|
||||
TEST_CASE("ISP CCM basic function", "[isp]")
|
||||
{
|
||||
esp_isp_processor_cfg_t isp_config = {
|
||||
.clk_hz = 80 * 1000 * 1000,
|
||||
.input_data_source = ISP_INPUT_DATA_SOURCE_CSI,
|
||||
.input_data_color_type = ISP_COLOR_RAW8,
|
||||
.output_data_color_type = ISP_COLOR_RGB565,
|
||||
};
|
||||
isp_proc_handle_t isp_proc = NULL;
|
||||
TEST_ESP_OK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||||
TEST_ESP_OK(esp_isp_enable(isp_proc));
|
||||
|
||||
esp_isp_ccm_config_t ccm_cfg = {
|
||||
.matrix = {
|
||||
{5.0, 0.0, 0.0},
|
||||
{0.0, 1.0, 0.0},
|
||||
{0.0, 0.0, 1.0}
|
||||
},
|
||||
.saturation = false,
|
||||
};
|
||||
// Out of range case
|
||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_ccm_configure(isp_proc, &ccm_cfg));
|
||||
// saturation case
|
||||
ccm_cfg.saturation = true;
|
||||
TEST_ESP_OK(esp_isp_ccm_configure(isp_proc, &ccm_cfg));
|
||||
TEST_ESP_OK(esp_isp_ccm_enable(isp_proc));
|
||||
// Allow to be called after enabled
|
||||
ccm_cfg.matrix[0][0] = -1.1;
|
||||
TEST_ESP_OK(esp_isp_ccm_configure(isp_proc, &ccm_cfg));
|
||||
TEST_ESP_OK(esp_isp_ccm_disable(isp_proc));
|
||||
|
||||
TEST_ESP_OK(esp_isp_disable(isp_proc));
|
||||
TEST_ESP_OK(esp_isp_del_processor(isp_proc));
|
||||
}
|
||||
|
||||
@@ -100,6 +100,22 @@ typedef union {
|
||||
uint32_t val;
|
||||
} isp_ll_awb_rgb_ratio_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CCM
|
||||
---------------------------------------------------------------*/
|
||||
#define ISP_LL_CCM_MATRIX_INT_BITS (2)
|
||||
#define ISP_LL_CCM_MATRIX_FRAC_BITS (10)
|
||||
#define ISP_LL_CCM_MATRIX_TOT_BITS (ISP_LL_CCM_MATRIX_INT_BITS + ISP_LL_CCM_MATRIX_FRAC_BITS + 1) // including one sign bit
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t fraction: ISP_LL_AWB_RGB_RATIO_FRAC_BITS;
|
||||
uint32_t integer: ISP_LL_AWB_RGB_RATIO_INT_BITS;
|
||||
uint32_t sign: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} isp_ll_ccm_gain_t;
|
||||
|
||||
/**
|
||||
* @brief Env monitor mode
|
||||
*/
|
||||
@@ -790,6 +806,25 @@ static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable)
|
||||
hw->cntl.ccm_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Color Correction Matrix
|
||||
*
|
||||
* @param[in] hw Hardware instance address
|
||||
* @param[in] fixed_point_matrix Color Correction Matrix in fixed-point format
|
||||
*/
|
||||
static inline void isp_ll_ccm_set_matrix(isp_dev_t *hw, isp_ll_ccm_gain_t fixed_point_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION])
|
||||
{
|
||||
hw->ccm_coef0.ccm_rr = fixed_point_matrix[0][0].val;
|
||||
hw->ccm_coef0.ccm_rg = fixed_point_matrix[0][1].val;
|
||||
hw->ccm_coef1.ccm_rb = fixed_point_matrix[0][2].val;
|
||||
hw->ccm_coef1.ccm_gr = fixed_point_matrix[1][0].val;
|
||||
hw->ccm_coef3.ccm_gg = fixed_point_matrix[1][1].val;
|
||||
hw->ccm_coef3.ccm_gb = fixed_point_matrix[1][2].val;
|
||||
hw->ccm_coef4.ccm_br = fixed_point_matrix[2][0].val;
|
||||
hw->ccm_coef4.ccm_bg = fixed_point_matrix[2][1].val;
|
||||
hw->ccm_coef5.ccm_bb = fixed_point_matrix[2][2].val;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Color
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
@@ -88,6 +88,21 @@ uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t m
|
||||
*/
|
||||
void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Color Correction Matrix
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Set Color Correction Matrix
|
||||
*
|
||||
* @param[in] hal Context of the HAL layer
|
||||
* @param[in] saturation Whether to enable saturation when float data overflow
|
||||
* @param[in] flt_matrix 3x3 RGB correction matrix
|
||||
* @return
|
||||
* - true Set success
|
||||
* - false Invalid argument
|
||||
*/
|
||||
bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const float flt_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AWB
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
@@ -100,6 +100,15 @@ typedef enum {
|
||||
ISP_BF_EDGE_PADDING_MODE_CUSTOM_DATA, ///< Fill BF edge padding data with custom pixel data
|
||||
} isp_bf_edge_padding_mode_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CCM
|
||||
---------------------------------------------------------------*/
|
||||
#if SOC_ISP_CCM_SUPPORTED
|
||||
#define ISP_CCM_DIMENSION SOC_ISP_CCM_DIMENSION ///< ISP Color Correction Matrix dimension
|
||||
#else
|
||||
#define ISP_CCM_DIMENSION 0 ///< Not support CCM
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AWB
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
@@ -70,6 +70,31 @@ uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t m
|
||||
|
||||
return triggered_events;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Color Correction Matrix
|
||||
---------------------------------------------------------------*/
|
||||
bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const float flt_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION])
|
||||
{
|
||||
isp_ll_ccm_gain_t fp_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION] = {};
|
||||
hal_utils_fixed_point_t fp_cfg = {
|
||||
.int_bit = ISP_LL_CCM_MATRIX_INT_BITS,
|
||||
.frac_bit = ISP_LL_CCM_MATRIX_FRAC_BITS,
|
||||
.saturation = saturation,
|
||||
};
|
||||
int err_level = saturation ? -1 : 0;
|
||||
/* Transfer the float type to fixed point */
|
||||
for (int i = 0; i < ISP_CCM_DIMENSION; i++) {
|
||||
for (int j = 0; j < ISP_CCM_DIMENSION; j++) {
|
||||
if (hal_utils_float_to_fixed_point_32b(flt_matrix[i][j], &fp_cfg, &fp_matrix[i][j].val) < err_level) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
isp_ll_ccm_set_matrix(hal->hw, fp_matrix);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AWB
|
||||
---------------------------------------------------------------*/
|
||||
|
||||
@@ -803,6 +803,10 @@ config SOC_ISP_BF_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ISP_CCM_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ISP_DVP_SUPPORTED
|
||||
bool
|
||||
default y
|
||||
@@ -835,6 +839,10 @@ config SOC_ISP_BF_TEMPLATE_Y_NUMS
|
||||
int
|
||||
default 3
|
||||
|
||||
config SOC_ISP_CCM_DIMENSION
|
||||
int
|
||||
default 3
|
||||
|
||||
config SOC_ISP_DVP_DATA_WIDTH_MAX
|
||||
int
|
||||
default 16
|
||||
|
||||
@@ -321,6 +321,7 @@
|
||||
|
||||
/*-------------------------- ISP CAPS ----------------------------------------*/
|
||||
#define SOC_ISP_BF_SUPPORTED 1
|
||||
#define SOC_ISP_CCM_SUPPORTED 1
|
||||
#define SOC_ISP_DVP_SUPPORTED 1
|
||||
|
||||
#define SOC_ISP_NUMS 1U
|
||||
@@ -330,6 +331,7 @@
|
||||
#define SOC_ISP_SHARE_CSI_BRG 1
|
||||
#define SOC_ISP_BF_TEMPLATE_X_NUMS 3
|
||||
#define SOC_ISP_BF_TEMPLATE_Y_NUMS 3
|
||||
#define SOC_ISP_CCM_DIMENSION 3
|
||||
#define SOC_ISP_DVP_DATA_WIDTH_MAX 16
|
||||
|
||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user