feat(isp): added isp demosaic driver

This commit is contained in:
Armando 2024-08-27 16:53:36 +08:00
parent 079df0282a
commit 02b2f9a4c4
13 changed files with 338 additions and 6 deletions

View File

@ -22,6 +22,10 @@ if(CONFIG_SOC_ISP_BF_SUPPORTED)
list(APPEND srcs "src/isp_bf.c")
endif()
if(CONFIG_SOC_ISP_DEMOSAIC_SUPPORTED)
list(APPEND srcs "src/isp_demosaic.c")
endif()
if(CONFIG_SOC_ISP_SHARPEN_SUPPORTED)
list(APPEND srcs "src/isp_sharpen.c")
endif()

View File

@ -17,5 +17,7 @@
#include "driver/isp_awb.h"
#include "driver/isp_bf.h"
#include "driver/isp_ccm.h"
#include "driver/isp_sharpen.h"
#include "driver/isp_demosaic.h"
#include "driver/isp_gamma.h"
#include "driver/isp_hist.h"
#include "driver/isp_sharpen.h"

View File

@ -0,0 +1,72 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "driver/isp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief ISP Demosaic configurations
*/
typedef struct {
isp_demosaic_grad_ratio_t grad_ratio; /**< Demosaic gradient ratio,
- gradient_x * grad_ratio < gradient_y, use interpolation results in X direction
- gradient_y * grad_ratio < gradient_x, use interpolation results in Y direction
- else use the average results between X and Y
*/
isp_demosaic_edge_padding_mode_t padding_mode; ///< Demosaic edge padding mode
uint8_t padding_data; ///< Demosaic edge padding pixel data
uint8_t padding_line_tail_valid_start_pixel; ///< Demosaic edge padding line tail valid start pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid
uint8_t padding_line_tail_valid_end_pixel; ///< Demosaic edge padding line tail valid end pixel, padding data will only be valid between the valid start pixel and the valid end pixel. Set both the start and end pixel to 0 to make all padding pixel valid
} esp_isp_demosaic_config_t;
/**
* @brief ISP Demosaic configuration
*
* @note After calling this API, Demosaic doesn't take into effect until `esp_isp_demosaic_enable` is called
*
* @param[in] proc Processor handle
* @param[in] config Demosaic configurations, set NULL to de-configure the ISP Demosaic
*
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
*/
esp_err_t esp_isp_demosaic_configure(isp_proc_handle_t proc, const esp_isp_demosaic_config_t *config);
/**
* @brief Enable ISP Demosaic function
*
* @param[in] proc Processor handle
*
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
* - ESP_ERR_INVALID_STATE Driver state is invalid.
*/
esp_err_t esp_isp_demosaic_enable(isp_proc_handle_t proc);
/**
* @brief Disable ISP Demosaic function
*
* @param[in] proc Processor handle
*
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
* - ESP_ERR_INVALID_STATE Driver state is invalid.
*/
esp_err_t esp_isp_demosaic_disable(isp_proc_handle_t proc);
#ifdef __cplusplus
}
#endif

View File

@ -18,7 +18,7 @@ extern "C" {
* @brief ISP Sharpen configurations
*/
typedef struct {
isp_sharpen_h_freq_coeff h_freq_coeff; ///< High freq pixel sharpeness coeff
isp_sharpen_h_freq_coeff_t h_freq_coeff; ///< High freq pixel sharpeness coeff
isp_sharpen_m_freq_coeff m_freq_coeff; ///< Medium freq pixel sharpeness coeff
uint8_t h_thresh; ///< High threshold, pixel value higher than this threshold will be multiplied by `h_freq_coeff`
uint8_t l_thresh; ///< Low threshold, pixel value higher than this threshold but lower than `h_thresh` will be multiplied by `m_freq_coeff`. Pixel value lower than this threshold will be set to 0

View File

@ -70,6 +70,7 @@ typedef struct isp_processor_t {
isp_ae_ctlr_t ae_ctlr;
isp_hist_ctlr_t hist_ctlr;
isp_fsm_t bf_fsm;
isp_fsm_t demosaic_fsm;
isp_fsm_t sharpen_fsm;
esp_isp_evt_cbs_t cbs;
void *user_data;

View File

@ -3,6 +3,7 @@ archive: libesp_driver_isp.a
entries:
if ISP_CTRL_FUNC_IN_IRAM = y:
isp_sharpen: esp_isp_sharpen_configure (noflash)
isp_demosaic: esp_isp_demosaic_configure (noflash)
isp_gamma: esp_isp_gamma_configure (noflash)
isp_gamma: esp_isp_gamma_fill_curve_points (noflash)
@ -11,3 +12,4 @@ archive: libhal.a
entries:
if ISP_CTRL_FUNC_IN_IRAM = y:
isp_hal: isp_hal_sharpen_config (noflash)
isp_hal: isp_hal_demosaic_config (noflash)

View File

@ -0,0 +1,66 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_types.h>
#include <sys/lock.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_check.h"
#include "freertos/FreeRTOS.h"
#include "driver/isp_core.h"
#include "driver/isp_demosaic.h"
#include "soc/isp_periph.h"
#include "esp_private/isp_private.h"
static const char *TAG = "ISP_DEMOSAIC";
/*---------------------------------------------------------------
Demosaic
---------------------------------------------------------------*/
esp_err_t esp_isp_demosaic_configure(isp_proc_handle_t proc, const esp_isp_demosaic_config_t *config)
{
ESP_RETURN_ON_FALSE_ISR(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
if (config) {
bool valid_padding_setting = (!config->padding_line_tail_valid_end_pixel && !config->padding_line_tail_valid_start_pixel) || (config->padding_line_tail_valid_end_pixel > config->padding_line_tail_valid_start_pixel);
ESP_RETURN_ON_FALSE_ISR(valid_padding_setting, ESP_ERR_INVALID_ARG, TAG, "wrong padding line tail valid pixel setting");
isp_hal_demosaic_cfg_t demosaic_hal_cfg = {
.grad_ratio = config->grad_ratio,
.padding_mode = config->padding_mode,
.padding_data = config->padding_data,
.padding_line_tail_valid_start_pixel = config->padding_line_tail_valid_start_pixel,
.padding_line_tail_valid_end_pixel = config->padding_line_tail_valid_end_pixel,
};
isp_hal_demosaic_config(&(proc->hal), &demosaic_hal_cfg);
} else {
isp_hal_demosaic_config(&(proc->hal), NULL);
}
return ESP_OK;
}
esp_err_t esp_isp_demosaic_enable(isp_proc_handle_t proc)
{
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(proc->demosaic_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "demosaic is enabled already");
isp_ll_demosaic_enable(proc->hal.hw, true);
proc->demosaic_fsm = ISP_FSM_ENABLE;
return ESP_OK;
}
esp_err_t esp_isp_demosaic_disable(isp_proc_handle_t proc)
{
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(proc->demosaic_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "demosaic isn't enabled yet");
isp_ll_demosaic_enable(proc->hal.hw, false);
proc->demosaic_fsm = ISP_FSM_INIT;
return ESP_OK;
}

View File

@ -1327,6 +1327,91 @@ static inline uint32_t isp_ll_awb_get_accumulated_b_value(isp_dev_t *hw)
return hw->awb0_acc_b.awb0_acc_b;
}
/*---------------------------------------------------------------
Demosaic
---------------------------------------------------------------*/
/**
* @brief Enable / Disable demosaic clock
*
* @param[in] hw Hardware instance address
* @param[in] enable Enable / Disable
*/
static inline void isp_ll_demosaic_clk_enable(isp_dev_t *hw, bool enable)
{
hw->clk_en.clk_demosaic_force_on = enable;
}
/**
* @brief Enable / Disable demosaic
*
* @param[in] hw Hardware instance address
* @param[in] enable Enable / Disable
*/
static inline void isp_ll_demosaic_enable(isp_dev_t *hw, bool enable)
{
hw->cntl.demosaic_en = enable;
}
/**
* @brief Set demosaic low thresh
*
* @param[in] hw Hardware instance address
* @param[in] thresh Thresh
*/
__attribute__((always_inline))
static inline void isp_ll_demosaic_set_grad_ratio(isp_dev_t *hw, isp_demosaic_grad_ratio_t grad_ratio)
{
hw->demosaic_grad_ratio.demosaic_grad_ratio = grad_ratio.val;
}
/**
* @brief Set ISP demosaic padding mode
*
* @param[in] hw Hardware instance address
* @param[in] padding_mode padding mode
*/
__attribute__((always_inline))
static inline void isp_ll_demosaic_set_padding_mode(isp_dev_t *hw, isp_demosaic_edge_padding_mode_t padding_mode)
{
hw->demosaic_matrix_ctrl.demosaic_padding_mode = padding_mode;
}
/**
* @brief Set ISP demosaic padding data
*
* @param[in] hw Hardware instance address
* @param[in] padding_data padding data
*/
__attribute__((always_inline))
static inline void isp_ll_demosaic_set_padding_data(isp_dev_t *hw, uint32_t padding_data)
{
hw->demosaic_matrix_ctrl.demosaic_padding_data = padding_data;
}
/**
* @brief Set ISP demosaic tail start pulse pixel
*
* @param[in] hw Hardware instance address
* @param[in] start_pixel start pixel value
*/
__attribute__((always_inline))
static inline void isp_ll_demosaic_set_padding_line_tail_valid_start_pixel(isp_dev_t *hw, uint32_t start_pixel)
{
hw->demosaic_matrix_ctrl.demosaic_tail_pixen_pulse_tl = start_pixel;
}
/**
* @brief Set ISP demosaic tail pulse end pixel
*
* @param[in] hw Hardware instance address
* @param[in] end_pixel end pixel value
*/
__attribute__((always_inline))
static inline void isp_ll_demosaic_set_padding_line_tail_valid_end_pixel(isp_dev_t *hw, uint32_t end_pixel)
{
hw->demosaic_matrix_ctrl.demosaic_tail_pixen_pulse_th = end_pixel;
}
/*---------------------------------------------------------------
Sharpen
---------------------------------------------------------------*/
@ -1396,7 +1481,7 @@ static inline void isp_ll_sharp_set_medium_freq_coeff(isp_dev_t *hw, isp_sharpen
* @param[in] coeff coeff
*/
__attribute__((always_inline))
static inline void isp_ll_sharp_set_high_freq_coeff(isp_dev_t *hw, isp_sharpen_h_freq_coeff coeff)
static inline void isp_ll_sharp_set_high_freq_coeff(isp_dev_t *hw, isp_sharpen_h_freq_coeff_t coeff)
{
//val higher than `sharp_threshold_high` will be multiplied by `sharp_amount_high`
hw->sharp_ctrl0.sharp_amount_high = coeff.val;

View File

@ -33,11 +33,26 @@ typedef struct {
uint8_t padding_line_tail_valid_end_pixel; ///< BF edge padding line tail valid end pixel
} isp_hal_bf_cfg_t;
/**
* @brief Demosaic configurations
*/
typedef struct {
isp_demosaic_grad_ratio_t grad_ratio; /**< Demosaic gradient ratio,
- gradient_x * grad_ratio < gradient_y, use interpolation results in X direction
- gradient_y * grad_ratio < gradient_x, use interpolation results in Y direction
- else use the average results between X and Y
*/
isp_demosaic_edge_padding_mode_t padding_mode; ///< Sharpen edge padding mode
uint8_t padding_data; ///< Sharpen edge padding pixel data
uint8_t padding_line_tail_valid_start_pixel; ///< Sharpen edge padding line tail valid start pixel
uint8_t padding_line_tail_valid_end_pixel; ///< Sharpen edge padding line tail valid end pixel
} isp_hal_demosaic_cfg_t;
/**
* @brief Sharpen configurations
*/
typedef struct {
isp_sharpen_h_freq_coeff h_freq_coeff; ///< High freq pixel sharpeness coeff
isp_sharpen_h_freq_coeff_t h_freq_coeff; ///< High freq pixel sharpeness coeff
isp_sharpen_m_freq_coeff m_freq_coeff; ///< Medium freq pixel sharpeness coeff
uint8_t h_thresh; ///< High threshold, pixel value higher than this threshold will be multiplied by `h_freq_coeff`
uint8_t l_thresh; ///< Low threshold, pixel value higher than this threshold but lower than `h_thresh` will be multiplied by `m_freq_coeff`. Pixel value lower than this threshold will be set to 0
@ -166,6 +181,17 @@ void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config);
*/
bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const float flt_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]);
/*---------------------------------------------------------------
Demosaic
---------------------------------------------------------------*/
/**
* @brief Configure ISP Demosaic
*
* @param[in] hal Context of the HAL layer
* @param[in] config Demosaic config, set NULL to de-config the ISP Demosaic
*/
void isp_hal_demosaic_config(isp_hal_context_t *hal, isp_hal_demosaic_cfg_t *config);
/*---------------------------------------------------------------
INTR
---------------------------------------------------------------*/

View File

@ -161,6 +161,39 @@ typedef enum {
#define ISP_CCM_DIMENSION 0 ///< Not support CCM
#endif
/*---------------------------------------------------------------
Demosaic
---------------------------------------------------------------*/
#if SOC_ISP_DEMOSAIC_SUPPORTED
#define ISP_DEMOSAIC_GRAD_RATIO_INT_BITS SOC_ISP_DEMOSAIC_GRAD_RATIO_INT_BITS
#define ISP_DEMOSAIC_GRAD_RATIO_DEC_BITS SOC_ISP_DEMOSAIC_GRAD_RATIO_DEC_BITS
#define ISP_DEMOSAIC_GRAD_RATIO_RES_BITS SOC_ISP_DEMOSAIC_GRAD_RATIO_RES_BITS
#else
#define ISP_DEMOSAIC_GRAD_RATIO_INT_BITS 8
#define ISP_DEMOSAIC_GRAD_RATIO_DEC_BITS 8
#define ISP_DEMOSAIC_GRAD_RATIO_RES_BITS 16
#endif
/**
* @brief Gradient ratio
*/
typedef union {
struct {
uint32_t decimal:ISP_DEMOSAIC_GRAD_RATIO_DEC_BITS; ///< Integer part
uint32_t integer:ISP_DEMOSAIC_GRAD_RATIO_INT_BITS; ///< Decimal part
uint32_t reserved:ISP_DEMOSAIC_GRAD_RATIO_RES_BITS; ///< Reserved
};
uint32_t val; ///< 32-bit gradient ratio value
} isp_demosaic_grad_ratio_t;
/**
* @brief ISP Demosaic edge padding mode
*/
typedef enum {
ISP_DEMOSAIC_EDGE_PADDING_MODE_SRND_DATA, ///< Fill Demosaic edge padding data with surrounding pixel data
ISP_DEMOSAIC_EDGE_PADDING_MODE_CUSTOM_DATA, ///< Fill Demosaic edge padding data with custom pixel data
} isp_demosaic_edge_padding_mode_t;
/*---------------------------------------------------------------
DVP
---------------------------------------------------------------*/
@ -203,7 +236,7 @@ typedef union {
uint32_t reserved:ISP_SHARPEN_H_FREQ_COEF_RES_BITS; ///< Reserved
};
uint32_t val; ///< 32-bit high freq pixel sharpeness coeff register value
} isp_sharpen_h_freq_coeff;
} isp_sharpen_h_freq_coeff_t;
/**
* @brief Medium freq pixel sharpeness coeff

View File

@ -168,6 +168,27 @@ bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const
return true;
}
/*---------------------------------------------------------------
Demosaic
---------------------------------------------------------------*/
void isp_hal_demosaic_config(isp_hal_context_t *hal, isp_hal_demosaic_cfg_t *config)
{
if (config) {
isp_ll_demosaic_set_grad_ratio(hal->hw, config->grad_ratio);
isp_ll_demosaic_set_padding_mode(hal->hw, config->padding_mode);
isp_ll_demosaic_set_padding_data(hal->hw, config->padding_data);
isp_ll_demosaic_set_padding_line_tail_valid_start_pixel(hal->hw, config->padding_line_tail_valid_start_pixel);
isp_ll_demosaic_set_padding_line_tail_valid_end_pixel(hal->hw, config->padding_line_tail_valid_end_pixel);
} else {
isp_demosaic_grad_ratio_t grad_ratio = {};
isp_ll_demosaic_set_grad_ratio(hal->hw, grad_ratio);
isp_ll_demosaic_set_padding_mode(hal->hw, 0);
isp_ll_demosaic_set_padding_data(hal->hw, 0);
isp_ll_demosaic_set_padding_line_tail_valid_start_pixel(hal->hw, 0);
isp_ll_demosaic_set_padding_line_tail_valid_end_pixel(hal->hw, 0);
}
}
/*---------------------------------------------------------------
Histogram
---------------------------------------------------------------*/
@ -202,7 +223,7 @@ void isp_hal_sharpen_config(isp_hal_context_t *hal, isp_hal_sharpen_cfg_t *confi
isp_ll_sharp_set_low_thresh(hal->hw, 0);
isp_ll_sharp_set_high_thresh(hal->hw, 0);
isp_sharpen_m_freq_coeff m_freq = {};
isp_sharpen_h_freq_coeff h_freq = {};
isp_sharpen_h_freq_coeff_t h_freq = {};
isp_ll_sharp_set_medium_freq_coeff(hal->hw, m_freq);
isp_ll_sharp_set_high_freq_coeff(hal->hw, h_freq);
isp_ll_sharp_set_padding_mode(hal->hw, 0);

View File

@ -839,6 +839,10 @@ config SOC_ISP_CCM_SUPPORTED
bool
default y
config SOC_ISP_DEMOSAIC_SUPPORTED
bool
default y
config SOC_ISP_DVP_SUPPORTED
bool
default y
@ -891,6 +895,18 @@ config SOC_ISP_CCM_DIMENSION
int
default 3
config SOC_ISP_DEMOSAIC_GRAD_RATIO_INT_BITS
int
default 2
config SOC_ISP_DEMOSAIC_GRAD_RATIO_DEC_BITS
int
default 4
config SOC_ISP_DEMOSAIC_GRAD_RATIO_RES_BITS
int
default 26
config SOC_ISP_DVP_DATA_WIDTH_MAX
int
default 16

View File

@ -334,6 +334,7 @@
/*-------------------------- ISP CAPS ----------------------------------------*/
#define SOC_ISP_BF_SUPPORTED 1
#define SOC_ISP_CCM_SUPPORTED 1
#define SOC_ISP_DEMOSAIC_SUPPORTED 1
#define SOC_ISP_DVP_SUPPORTED 1
#define SOC_ISP_SHARPEN_SUPPORTED 1
#define SOC_ISP_SHARE_CSI_BRG 1
@ -348,6 +349,9 @@
#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_DEMOSAIC_GRAD_RATIO_INT_BITS 2
#define SOC_ISP_DEMOSAIC_GRAD_RATIO_DEC_BITS 4
#define SOC_ISP_DEMOSAIC_GRAD_RATIO_RES_BITS 26
#define SOC_ISP_DVP_DATA_WIDTH_MAX 16
#define SOC_ISP_SHARPEN_TEMPLATE_X_NUMS 3
#define SOC_ISP_SHARPEN_TEMPLATE_Y_NUMS 3