Skip to content

Commit

Permalink
Merge branch 'feat/isp_demosaic' into 'master'
Browse files Browse the repository at this point in the history
isp: demosaic

Closes IDF-10519

See merge request espressif/esp-idf!33111
  • Loading branch information
Icarus113 committed Aug 29, 2024
2 parents 7c47596 + 87d8a51 commit d7b701b
Show file tree
Hide file tree
Showing 16 changed files with 409 additions and 31 deletions.
4 changes: 4 additions & 0 deletions components/esp_driver_isp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 3 additions & 1 deletion components/esp_driver_isp/include/driver/isp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
72 changes: 72 additions & 0 deletions components/esp_driver_isp/include/driver/isp_demosaic.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion components/esp_driver_isp/include/driver/isp_sharpen.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions components/esp_driver_isp/linker.lf
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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)
66 changes: 66 additions & 0 deletions components/esp_driver_isp/src/isp_demosaic.c
Original file line number Diff line number Diff line change
@@ -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;
}
87 changes: 86 additions & 1 deletion components/hal/esp32p4/include/hal/isp_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------------------------------------------------------*/
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 27 additions & 1 deletion components/hal/include/hal/isp_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
---------------------------------------------------------------*/
Expand Down
35 changes: 34 additions & 1 deletion components/hal/include/hal/isp_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------------------------------------------------------*/
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit d7b701b

Please sign in to comment.