mirror of
https://github.com/espressif/esp-idf.git
synced 2026-06-11 11:42:39 +02:00
feat(isp_ccm): support isp color correction matrix
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"
|
||||
|
||||
@@ -178,7 +178,7 @@ typedef struct {
|
||||
/**
|
||||
* @brief Prototype of ISP AF Env detector event callback
|
||||
*
|
||||
* @param[in] af_ctrlr ISP AF controller handle
|
||||
* @param[in] af_ctrlr ISP AF controller handle
|
||||
* @param[in] edata ISP AF Env detector event data
|
||||
* @param[in] user_data User registered context, registered when in `esp_isp_af_env_detector_register_event_callbacks()`
|
||||
*
|
||||
|
||||
@@ -164,7 +164,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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user