Merge branch 'feature/support_isp_ae' into 'master'

feat(isp): Support ISP Auto Exposure (AE)

Closes IDF-9592, IDF-10193, and IDF-10580

See merge request espressif/esp-idf!31671
This commit is contained in:
Gao Xu
2024-08-01 16:21:34 +08:00
21 changed files with 1208 additions and 128 deletions
+148 -26
View File
@@ -41,8 +41,8 @@ extern "C" {
#define ISP_LL_EVENT_MIPI_HNUM_UNMATCH (1<<5)
#define ISP_LL_EVENT_DPC_CHECK_DONE (1<<6)
#define ISP_LL_EVENT_GAMMA_XCOORD_ERR (1<<7)
#define ISP_LL_EVENT_AE_MONITOR (1<<8)
#define ISP_LL_EVENT_AE_FRAME_DONE (1<<9)
#define ISP_LL_EVENT_AE_ENV (1<<8)
#define ISP_LL_EVENT_AE_FDONE (1<<9)
#define ISP_LL_EVENT_AF_FDONE (1<<10)
#define ISP_LL_EVENT_AF_ENV (1<<11)
#define ISP_LL_EVENT_AWB_FDONE (1<<12)
@@ -65,6 +65,7 @@ extern "C" {
#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF)
#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV)
#define ISP_LL_EVENT_AE_MASK (ISP_LL_EVENT_AE_FDONE | ISP_LL_EVENT_AE_ENV)
#define ISP_LL_EVENT_AWB_MASK (ISP_LL_EVENT_AWB_FDONE)
/*---------------------------------------------------------------
@@ -72,6 +73,11 @@ extern "C" {
---------------------------------------------------------------*/
#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1)
/*---------------------------------------------------------------
AE
---------------------------------------------------------------*/
#define ISP_LL_AE_WINDOW_MAX_RANGE ((1<<12) - 1)
/*---------------------------------------------------------------
BF
---------------------------------------------------------------*/
@@ -117,20 +123,20 @@ typedef union {
} isp_ll_ccm_gain_t;
/**
* @brief Env monitor mode
* @brief Env detector mode
*/
typedef enum {
ISP_LL_AF_ENV_MONITOR_MODE_ABS, ///< Use absolute val for threshold
ISP_LL_AF_ENV_MONITOR_MODE_RATIO, ///< Use ratio val for threshold
} isp_ll_af_env_monitor_mode_t;
ISP_LL_AF_ENV_DETECTOR_MODE_ABS, ///< Use absolute val for threshold
ISP_LL_AF_ENV_DETECTOR_MODE_RATIO, ///< Use ratio val for threshold
} isp_ll_af_env_detector_mode_t;
/**
* @brief Edge monitor mode
* @brief Edge detector mode
*/
typedef enum {
ISP_LL_AF_EDGE_MONITOR_MODE_AUTO, ///< Auto set threshold
ISP_LL_AF_EDGE_MONITOR_MODE_MANUAL, ///< Manual set threshold
} isp_ll_af_edge_monitor_mode_t;
ISP_LL_AF_EDGE_DETECTOR_MODE_AUTO, ///< Auto set threshold
ISP_LL_AF_EDGE_DETECTOR_MODE_MANUAL, ///< Manual set threshold
} isp_ll_af_edge_detector_mode_t;
/*---------------------------------------------------------------
@@ -496,11 +502,11 @@ static inline void isp_ll_af_manual_update(isp_dev_t *hw)
* @brief Set edge thresh mode
*
* @param[in] hw Hardware instance address
* @param[in] mode See `isp_ll_af_edge_monitor_mode_t`
* @param[in] mode See `isp_ll_af_edge_detector_mode_t`
*/
static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_monitor_mode_t mode)
static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_detector_mode_t mode)
{
if (mode == ISP_LL_AF_EDGE_MONITOR_MODE_AUTO) {
if (mode == ISP_LL_AF_EDGE_DETECTOR_MODE_AUTO) {
hw->af_threshold.af_threshold = 0;
}
}
@@ -622,43 +628,43 @@ static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_i
}
/*---------------------------------------------
AF Env Monitor
AF Env detector
----------------------------------------------*/
/**
* @brief Set env monitor period
* @brief Set env detector period
*
* @param[in] hw Hardware instance address
* @param[in] period period of the env monitor, in frames
* @param[in] period period of the env detector, in frames
*/
static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t period)
static inline void isp_ll_af_env_detector_set_period(isp_dev_t *hw, uint32_t period)
{
hw->af_ctrl0.af_env_period = period;
}
/**
* @brief Set env monitor mode
* @brief Set env detector mode
*
* @param[in] hw Hardware instance address
* @param[in] mode See `isp_ll_af_env_monitor_mode_t`
* @param[in] mode See `isp_ll_af_env_detector_mode_t`
*/
static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_monitor_mode_t mode)
static inline void isp_ll_af_env_detector_set_mode(isp_dev_t *hw, isp_ll_af_env_detector_mode_t mode)
{
if (mode == ISP_LL_AF_ENV_MONITOR_MODE_RATIO) {
if (mode == ISP_LL_AF_ENV_DETECTOR_MODE_RATIO) {
hw->af_env_user_th_sum.af_env_user_threshold_sum = 0x0;
hw->af_env_user_th_lum.af_env_user_threshold_lum = 0x0;
}
//nothing to do to if using abs mode, it'll be enabled after `isp_ll_af_env_monitor_set_thresh()`
//nothing to do to if using abs mode, it'll be enabled after `isp_ll_af_env_detector_set_thresh()`
}
/**
* @brief Set env monitor threshold
* @brief Set env detector threshold
*
* @param[in] hw Hardware instance address
* @param[in] sum_thresh Threshold for definition
* @param[in] lum_thresh Threshold for luminance
*/
static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_thresh, uint32_t lum_thresh)
static inline void isp_ll_af_env_detector_set_thresh(isp_dev_t *hw, uint32_t sum_thresh, uint32_t lum_thresh)
{
HAL_ASSERT(sum_thresh != 0 || lum_thresh != 0);
@@ -667,12 +673,12 @@ static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_
}
/**
* @brief Set env monitor ratio
* @brief Set env detector ratio
*
* @param[in] hw Hardware instance address
* @param[in] ratio_val Threshold for ratio
*/
static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio_val)
static inline void isp_ll_af_env_detector_set_ratio(isp_dev_t *hw, uint32_t ratio_val)
{
HAL_ASSERT(hw->af_env_user_th_sum.af_env_user_threshold_sum == 0 &&
hw->af_env_user_th_lum.af_env_user_threshold_lum == 0);
@@ -974,6 +980,122 @@ static inline void isp_ll_cam_enable(isp_dev_t *hw, bool enable)
hw->cam_cntl.cam_en = 0;
}
}
/*---------------------------------------------------------------
AE
---------------------------------------------------------------*/
/**
* @brief Enable / Disable AE clock
*
* @param[in] hw Hardware instance address
* @param[in] enable Enable / Disable
*/
static inline void isp_ll_ae_clk_enable(isp_dev_t *hw, bool enable)
{
hw->clk_en.clk_ae_force_on = enable;
}
/**
* @brief Enable / Disable AE
*
* @param[in] hw Hardware instance address
* @param[in] enable Enable / Disable
*/
static inline void isp_ll_ae_enable(isp_dev_t *hw, bool enable)
{
hw->cntl.ae_en = enable;
}
/**
* @brief Manual aupdate AF once
*
* @param[in] hw Hardware instance address
*/
static inline void isp_ll_ae_manual_update(isp_dev_t *hw)
{
hw->ae_ctrl.ae_update = 1;
}
/**
* @brief Select AE input data source
*
* @param[in] hw Hardware instance address
* @param[in] sample_point 0: AE input data after demosaic, 1: AE input data after gamma
*/
static inline void isp_ll_ae_set_sample_point(isp_dev_t *hw, isp_ae_sample_point_t sample_point)
{
hw->ae_ctrl.ae_select = sample_point;
}
/**
* @brief Set AE window range
*
* @param[in] hw Hardware instance address
* @param[in] x_start Top left pixel x axis value
* @param[in] x_bsize Block size on x axis
* @param[in] y_start Top left pixel y axis value
* @param[in] y_bsize Block size on y axis
*/
static inline void isp_ll_ae_set_window_range(isp_dev_t *hw, int x_start, int x_bsize, int y_start, int y_bsize)
{
hw->ae_bx.ae_x_start = x_start;
hw->ae_bx.ae_x_bsize = x_bsize;
hw->ae_by.ae_y_start = y_start;
hw->ae_by.ae_y_bsize = y_bsize;
}
/**
* @brief Get block mean luminance
*
* @param[in] hw Hardware instance address
* @param[in] block_id
*
* @return Mean luminance
*/
static inline int isp_ll_ae_get_block_mean_lum(isp_dev_t *hw, int block_id)
{
HAL_ASSERT(block_id >=0 && block_id < (SOC_ISP_AE_BLOCK_X_NUMS * SOC_ISP_AE_BLOCK_Y_NUMS));
return hw->ae_block_mean[block_id / 4].ae_b_mean[3 - (block_id % 4)];
}
/**
* @brief AE set the pixel number of each subwin, and set the reciprocal of each subwin_pixnum, 20bit fraction
*
* @param[in] hw Hardware instance address
* @param[in] subwin_pixnum Pixel number
*/
static inline void isp_ll_ae_set_subwin_pixnum_recip(isp_dev_t *hw, int subwin_pixnum)
{
hw->ae_winpixnum.ae_subwin_pixnum = subwin_pixnum;
int subwin_recip = (1 << 20) / subwin_pixnum;
hw->ae_win_reciprocal.ae_subwin_recip = subwin_recip;
}
/**
* @brief Set AE env detector threshold
*
* @param[in] hw Hardware instance address
* @param[in] low_thresh Lower lum threshold
* @param[in] high_thresh Higher lum threshold
*/
static inline void isp_ll_ae_env_detector_set_thresh(isp_dev_t *hw, uint32_t low_thresh, uint32_t high_thresh)
{
hw->ae_monitor.ae_monitor_tl = low_thresh;
hw->ae_monitor.ae_monitor_th = high_thresh;
}
/**
* @brief Set AE env detector period
*
* @param[in] hw Hardware instance address
* @param[in] period period of the AE env detector, in frames
*/
static inline void isp_ll_ae_env_detector_set_period(isp_dev_t *hw, uint32_t period)
{
hw->ae_monitor.ae_monitor_period = period;
}
/*---------------------------------------------------------------
INTR
---------------------------------------------------------------*/
+18 -7
View File
@@ -64,7 +64,18 @@ void isp_hal_init(isp_hal_context_t *hal, int isp_id);
* @param[in] window_id Window ID
* @param[in] window Window info, see `isp_window_t`
*/
void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_window_t *window);
void isp_hal_af_window_config(isp_hal_context_t *hal, int window_id, const isp_window_t *window);
/*---------------------------------------------------------------
AE
---------------------------------------------------------------*/
/**
* @brief Configure AE window
*
* @param[in] hal Context of the HAL layer
* @param[in] window Window info, see `isp_window_t`
*/
void isp_hal_ae_window_config(isp_hal_context_t *hal, const isp_window_t *window);
/*---------------------------------------------------------------
INTR
@@ -75,7 +86,7 @@ void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const
* @param[in] hal Context of the HAL layer
* @param[in] mask HW event mask
*/
uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask);
uint32_t isp_hal_check_clear_intr_event(isp_hal_context_t *hal, uint32_t mask);
/*---------------------------------------------------------------
BF
@@ -101,7 +112,7 @@ void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config);
* - 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]);
bool isp_hal_ccm_set_matrix(isp_hal_context_t *hal, bool saturation, const float flt_matrix[ISP_CCM_DIMENSION][ISP_CCM_DIMENSION]);
/*---------------------------------------------------------------
AWB
@@ -115,7 +126,7 @@ bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const
* - true Set success
* - false Invalid arg
*/
bool isp_hal_awb_set_window_range(const isp_hal_context_t *hal, const isp_window_t *win);
bool isp_hal_awb_set_window_range(isp_hal_context_t *hal, const isp_window_t *win);
/**
* @brief Set the luminance range of the white patch
@@ -127,7 +138,7 @@ bool isp_hal_awb_set_window_range(const isp_hal_context_t *hal, const isp_window
* - true Set success
* - false Invalid arg
*/
bool isp_hal_awb_set_luminance_range(const isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max);
bool isp_hal_awb_set_luminance_range(isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max);
/**
* @brief Set the R/G ratio of the white patch
@@ -138,7 +149,7 @@ bool isp_hal_awb_set_luminance_range(const isp_hal_context_t *hal, uint32_t lum_
* - true Set success
* - false Invalid arg
*/
bool isp_hal_awb_set_rg_ratio_range(const isp_hal_context_t *hal, float rg_min, float rg_max);
bool isp_hal_awb_set_rg_ratio_range(isp_hal_context_t *hal, float rg_min, float rg_max);
/**
* @brief Set the B/R ratio of the white patch
@@ -149,7 +160,7 @@ bool isp_hal_awb_set_rg_ratio_range(const isp_hal_context_t *hal, float rg_min,
* - true Set success
* - false Invalid arg
*/
bool isp_hal_awb_set_bg_ratio_range(const isp_hal_context_t *hal, float bg_min, float bg_max);
bool isp_hal_awb_set_bg_ratio_range(isp_hal_context_t *hal, float bg_min, float bg_max);
#ifdef __cplusplus
}
+20
View File
@@ -122,6 +122,26 @@ typedef enum {
ISP_AWB_SAMPLE_POINT_AFTER_CCM, ///< Sample AWB data after CCM (Color Correction Matrix)
} isp_awb_sample_point_t;
/*---------------------------------------------------------------
AE
---------------------------------------------------------------*/
#if (SOC_ISP_AE_BLOCK_X_NUMS && SOC_ISP_AE_BLOCK_Y_NUMS)
#define ISP_AE_BLOCK_X_NUM SOC_ISP_AE_BLOCK_X_NUMS // The AF window number for sampling
#define ISP_AE_BLOCK_Y_NUM SOC_ISP_AE_BLOCK_Y_NUMS // The AF window number for sampling
#else
#define ISP_AE_BLOCK_X_NUM 0
#define ISP_AE_BLOCK_Y_NUM 0
#endif
/**
* @brief ISP AE input data source
*
*/
typedef enum {
ISP_AE_SAMPLE_POINT_AFTER_DEMOSAIC, ///< AE input data after demosaic
ISP_AE_SAMPLE_POINT_AFTER_GAMMA, ///< AE input data after gamma
} isp_ae_sample_point_t;
#ifdef __cplusplus
}
+25 -7
View File
@@ -29,7 +29,7 @@ void isp_hal_init(isp_hal_context_t *hal, int isp_id)
/*---------------------------------------------------------------
AF
---------------------------------------------------------------*/
void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_window_t *window)
void isp_hal_af_window_config(isp_hal_context_t *hal, int window_id, const isp_window_t *window)
{
isp_ll_af_set_window_range(hal->hw, window_id, window->top_left.x, window->top_left.y, window->btm_right.x, window->btm_right.y);
}
@@ -57,10 +57,28 @@ void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config)
isp_ll_bf_set_template(hal->hw, default_template);
}
}
/*---------------------------------------------------------------
AE
---------------------------------------------------------------*/
void isp_hal_ae_window_config(isp_hal_context_t *hal, const isp_window_t *window)
{
uint32_t ae_x_start = window->top_left.x;
uint32_t ae_x_bsize = (window->btm_right.x - window-> top_left.x) / SOC_ISP_AE_BLOCK_X_NUMS;
uint32_t ae_y_start = window->top_left.y;
uint32_t ae_y_bsize = (window->btm_right.y - window->top_left.y) / SOC_ISP_AE_BLOCK_Y_NUMS;
isp_ll_ae_set_window_range(hal->hw, ae_x_start, ae_x_bsize, ae_y_start, ae_y_bsize);
int ae_subwin_pixnum = ae_x_bsize * ae_y_bsize;
isp_ll_ae_set_subwin_pixnum_recip(hal->hw, ae_subwin_pixnum);
}
/*---------------------------------------------------------------
INTR, put in iram
---------------------------------------------------------------*/
uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask)
uint32_t isp_hal_check_clear_intr_event(isp_hal_context_t *hal, uint32_t mask)
{
uint32_t triggered_events = isp_ll_get_intr_status(hal->hw) & mask;
@@ -74,7 +92,7 @@ uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t m
/*---------------------------------------------------------------
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])
bool isp_hal_ccm_set_matrix(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 = {
@@ -98,7 +116,7 @@ bool isp_hal_ccm_set_matrix(const isp_hal_context_t *hal, bool saturation, const
/*---------------------------------------------------------------
AWB
---------------------------------------------------------------*/
bool isp_hal_awb_set_window_range(const isp_hal_context_t *hal, const isp_window_t *win)
bool isp_hal_awb_set_window_range(isp_hal_context_t *hal, const isp_window_t *win)
{
if (win->top_left.x > win->btm_right.x ||
win->top_left.y > win->btm_right.y ||
@@ -111,7 +129,7 @@ bool isp_hal_awb_set_window_range(const isp_hal_context_t *hal, const isp_window
return true;
}
bool isp_hal_awb_set_luminance_range(const isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max)
bool isp_hal_awb_set_luminance_range(isp_hal_context_t *hal, uint32_t lum_min, uint32_t lum_max)
{
if (lum_min > lum_max || lum_max > ISP_LL_AWB_LUM_MAX_RANGE) {
return false;
@@ -120,7 +138,7 @@ bool isp_hal_awb_set_luminance_range(const isp_hal_context_t *hal, uint32_t lum_
return true;
}
bool isp_hal_awb_set_rg_ratio_range(const isp_hal_context_t *hal, float rg_min, float rg_max)
bool isp_hal_awb_set_rg_ratio_range(isp_hal_context_t *hal, float rg_min, float rg_max)
{
// Convert to fixed point
isp_ll_awb_rgb_ratio_t fp_rg_min = {};
@@ -142,7 +160,7 @@ bool isp_hal_awb_set_rg_ratio_range(const isp_hal_context_t *hal, float rg_min,
return true;
}
bool isp_hal_awb_set_bg_ratio_range(const isp_hal_context_t *hal, float bg_min, float bg_max)
bool isp_hal_awb_set_bg_ratio_range(isp_hal_context_t *hal, float bg_min, float bg_max)
{
// Convert to fixed point
isp_ll_awb_rgb_ratio_t fp_bg_min = {};