Merge branch 'feat/isp_shadow_reg' into 'master'

isp: added shadow reg settings

Closes IDF-13937

See merge request espressif/esp-idf!42698
This commit is contained in:
Armando (Dou Yiwen)
2025-11-07 07:34:21 +00:00
10 changed files with 248 additions and 2 deletions
+3
View File
@@ -43,6 +43,9 @@ esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t
isp_hal_bf_config(&(proc->hal), NULL);
}
bool valid = isp_ll_shadow_update_bf(proc->hal.hw);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update bf shadow register");
return ESP_OK;
}
+3
View File
@@ -58,6 +58,9 @@ esp_err_t esp_isp_blc_configure(isp_proc_handle_t isp_proc, const esp_isp_blc_co
// Configure stretch enable for each channel
isp_ll_blc_enable_stretch(isp_proc->hal.hw, config->stretch.top_left_chan_stretch_en, config->stretch.top_right_chan_stretch_en, config->stretch.bottom_left_chan_stretch_en, config->stretch.bottom_right_chan_stretch_en);
bool valid = isp_ll_shadow_update_blc(isp_proc->hal.hw);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update blc shadow register");
return ESP_OK;
}
+3
View File
@@ -33,11 +33,14 @@ esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config
}
bool ret = true;
bool valid = false;
portENTER_CRITICAL(&proc->spinlock);
isp_ll_ccm_set_clk_ctrl_mode(proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO);
ret = isp_hal_ccm_set_matrix(&proc->hal, ccm_cfg->saturation, ccm_cfg->matrix);
valid = isp_ll_shadow_update_ccm(proc->hal.hw);
portEXIT_CRITICAL(&proc->spinlock);
ESP_RETURN_ON_FALSE(ret, ESP_ERR_INVALID_ARG, TAG, "invalid argument: ccm matrix contain NaN or out of range");
ESP_RETURN_ON_FALSE(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update ccm shadow register");
return ESP_OK;
}
@@ -43,6 +43,9 @@ esp_err_t esp_isp_color_configure(isp_proc_handle_t proc, const esp_isp_color_co
isp_hal_color_config(&(proc->hal), NULL);
}
bool valid = isp_ll_shadow_update_color(proc->hal.hw);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update color shadow register");
return ESP_OK;
}
+2
View File
@@ -178,6 +178,8 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_
isp_ll_set_byte_swap(proc->hal.hw, true);
}
isp_ll_shadow_set_mode(proc->hal.hw, ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
proc->in_color_format = in_color_format;
proc->out_color_format = out_color_format;
proc->h_res = proc_config->h_res;
@@ -45,6 +45,9 @@ esp_err_t esp_isp_sharpen_configure(isp_proc_handle_t proc, const esp_isp_sharpe
isp_hal_sharpen_config(&(proc->hal), NULL);
}
bool valid = isp_ll_shadow_update_sharpen(proc->hal.hw);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update sharp shadow register");
return ESP_OK;
}
+3
View File
@@ -61,6 +61,9 @@ esp_err_t esp_isp_wbg_set_wb_gain(isp_proc_handle_t isp_proc, isp_wbg_gain_t gai
// Set WBG gain
isp_ll_awb_set_wb_gain(isp_proc->hal.hw, gain);
bool valid = isp_ll_shadow_update_wbg(isp_proc->hal.hw);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update wbg shadow register");
return ESP_OK;
}
+226
View File
@@ -197,6 +197,14 @@ typedef enum {
ISP_LL_PIPELINE_CLK_CTRL_ALWAYS_ON, ///< Always on
} isp_ll_pipeline_clk_ctrl_t;
/**
* @brief Shadow mode
*/
typedef enum {
ISP_SHADOW_MODE_DISABLE,
ISP_SHADOW_MODE_UPDATE_EVERY_VSYNC,
ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC,
} isp_ll_shadow_mode_t;
/*---------------------------------------------------------------
Clock
@@ -1852,6 +1860,224 @@ static inline void isp_ll_demosaic_set_padding_line_tail_valid_end_pixel(isp_dev
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->demosaic_matrix_ctrl, demosaic_tail_pixen_pulse_th, end_pixel);
}
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
/*---------------------------------------------------------------
Shadow
---------------------------------------------------------------*/
/**
* @brief Shadow mode
*
* @param[in] hw Hardware instance address
* @param[in] mode 'isp_ll_shadow_mode_t`
*/
static inline void isp_ll_shadow_set_mode(isp_dev_t *hw, isp_ll_shadow_mode_t mode)
{
hw->shadow_reg_ctrl.shadow_update_sel = mode;
}
/**
* @brief Update BLC shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.blc_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.blc_update = 1;
return true;
}
/**
* @brief Update DPC shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.dpc_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.dpc_update = 1;
return true;
}
/**
* @brief Update BF shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.bf_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.bf_update = 1;
return true;
}
/**
* @brief Update WBG shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.wbg_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.wbg_update = 1;
return true;
}
/**
* @brief Update CCM shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.ccm_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.ccm_update = 1;
return true;
}
/**
* @brief Update Sharpen shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.sharp_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.sharp_update = 1;
return true;
}
/**
* @brief Update Color shadow register
*
* @param[in] hw Hardware instance address
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_color(isp_dev_t *hw)
{
//only valid when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
HAL_ASSERT(hw->shadow_reg_ctrl.shadow_update_sel == ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC);
if (hw->shadow_reg_ctrl.color_update == 1) {
return false;
}
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.color_update = 1;
return true;
}
#else
static inline void isp_ll_shadow_set_mode(isp_dev_t *hw, isp_ll_shadow_mode_t mode)
{
//for compatibility
}
static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_color(isp_dev_t *hw)
{
//for compatibility
return true;
}
#endif
/*---------------------------------------------------------------
Sharpen
---------------------------------------------------------------*/
+1 -1
View File
@@ -724,7 +724,7 @@ Calling :cpp:func:`esp_isp_demosaic_configure` to configure Demosaic function, y
...
};
ESP_ERROR_CHECK(esp_isp_demosaic_configure(isp_proc, &sharpen_config));
ESP_ERROR_CHECK(esp_isp_demosaic_configure(isp_proc, &demosaic_config));
ESP_ERROR_CHECK(esp_isp_demosaic_enable(isp_proc));
After calling :cpp:func:`esp_isp_demosaic_configure`, you need to enable the ISP Demosaic controller, by calling :cpp:func:`esp_isp_demosaic_enable`. This function:
+1 -1
View File
@@ -724,7 +724,7 @@ ISP 去马赛克控制器
...
};
ESP_ERROR_CHECK(esp_isp_demosaic_configure(isp_proc, &sharpen_config));
ESP_ERROR_CHECK(esp_isp_demosaic_configure(isp_proc, &demosaic_config));
ESP_ERROR_CHECK(esp_isp_demosaic_enable(isp_proc));
调用 :cpp:func:`esp_isp_demosaic_configure` 后,需要通过调用 :cpp:func:`esp_isp_demosaic_enable` 来启用 ISP 去马赛克控制器。此函数: