feat(isp): allow to bypass shadow register

This commit is contained in:
armando
2026-01-05 14:47:21 +08:00
parent e41ecaabf2
commit 6f7f545619
11 changed files with 114 additions and 64 deletions
@@ -24,6 +24,9 @@ typedef struct {
uint8_t denoising_level; ///< BF denoising level, from 2 to 20, the bigger the better denoising performance, but the worse detailed
uint8_t padding_line_tail_valid_start_pixel; ///< BF 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; ///< BF 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
struct {
uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary
} flags; ///< Driver behaviour flags
} esp_isp_bf_config_t;
/**
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -43,10 +43,13 @@ typedef struct {
* @brief ISP BLC configurations
*/
typedef struct {
isp_window_t window; ///< The sampling windows of BLC, only pixels within the window will be sampled
esp_isp_blc_thresh_t filter_threshold; ///< Black level threshold for each channel of the raw Bayer image
bool filter_enable; ///< Enable filter for BLC, if enabled, only pixels within the threshold will be sampled
esp_isp_blc_stretch_t stretch; ///< Stretch configurations for each channel of the raw Bayer image
isp_window_t window; ///< The sampling windows of BLC, only pixels within the window will be sampled
esp_isp_blc_thresh_t filter_threshold; ///< Black level threshold for each channel of the raw Bayer image
bool filter_enable; ///< Enable filter for BLC, if enabled, only pixels within the threshold will be sampled
esp_isp_blc_stretch_t stretch; ///< Stretch configurations for each channel of the raw Bayer image
struct {
uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary
} flags; ///< Driver behaviour flags
} esp_isp_blc_config_t;
/**
@@ -36,6 +36,9 @@ typedef struct {
* Zero (0): Maintains the original brightness, without adjusting the image's brightness.
* Positive range (1 to 127): Increases brightness, the larger the value, the brighter the image.
*/
struct {
uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary
} flags; ///< Driver behaviour flags
} esp_isp_color_config_t;
/**
@@ -27,6 +27,9 @@ typedef struct {
uint8_t sharpen_template[ISP_SHARPEN_TEMPLATE_X_NUMS][ISP_SHARPEN_TEMPLATE_Y_NUMS]; ///< Sharpen template data
uint8_t padding_line_tail_valid_start_pixel; ///< Sharpen 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; ///< Sharpen 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
struct {
uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary
} flags; ///< Driver behaviour flags
} esp_isp_sharpen_config_t;
/**
@@ -21,7 +21,9 @@ extern "C" {
* @brief ISP BLC configurations
*/
typedef struct {
//for future proof
struct {
uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary
} flags; ///< Driver behaviour flags
} esp_isp_wbg_config_t;
/**
+1 -1
View File
@@ -43,7 +43,7 @@ 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);
bool valid = isp_ll_shadow_update_bf(proc->hal.hw, config->flags.update_once_configured);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update bf shadow register");
return ESP_OK;
+1 -1
View File
@@ -58,7 +58,7 @@ 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);
bool valid = isp_ll_shadow_update_blc(isp_proc->hal.hw, config->flags.update_once_configured);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update blc shadow register");
return ESP_OK;
+1 -1
View File
@@ -43,7 +43,7 @@ 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);
bool valid = isp_ll_shadow_update_color(proc->hal.hw, config->flags.update_once_configured);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update color shadow register");
return ESP_OK;
+1 -1
View File
@@ -45,7 +45,7 @@ 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);
bool valid = isp_ll_shadow_update_sharpen(proc->hal.hw, config->flags.update_once_configured);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update sharp shadow register");
return ESP_OK;
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,11 +32,14 @@ esp_err_t esp_isp_wbg_configure(isp_proc_handle_t isp_proc, const esp_isp_wbg_co
}
#endif
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(isp_proc && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
// Configure clock control mode
isp_ll_awb_set_wb_gain_clk_ctrl_mode(isp_proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO);
bool valid = isp_ll_shadow_update_wbg(isp_proc->hal.hw, config->flags.update_once_configured);
ESP_RETURN_ON_FALSE_ISR(valid, ESP_ERR_INVALID_STATE, TAG, "failed to update wbg shadow register");
return ESP_OK;
}
@@ -61,9 +64,6 @@ 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;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1890,21 +1890,27 @@ static inline void isp_ll_shadow_set_mode(isp_dev_t *hw, isp_ll_shadow_mode_t mo
/**
* @brief Update BLC shadow register
*
* @param[in] hw Hardware instance address
* @param[in] hw Hardware instance address
* @param[in] force_update Force update
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw, bool force_update)
{
//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;
}
if (force_update) {
//don't care shadow register
hw->shadow_reg_ctrl.blc_update = 1;
} else {
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;
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.blc_update = 1;
}
return true;
}
@@ -1912,21 +1918,27 @@ static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw)
/**
* @brief Update DPC shadow register
*
* @param[in] hw Hardware instance address
* @param[in] hw Hardware instance address
* @param[in] force_update Force update
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw, bool force_update)
{
//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;
}
if (force_update) {
//don't care shadow register
hw->shadow_reg_ctrl.dpc_update = 1;
} else {
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;
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.dpc_update = 1;
}
return true;
}
@@ -1934,21 +1946,27 @@ static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw)
/**
* @brief Update BF shadow register
*
* @param[in] hw Hardware instance address
* @param[in] hw Hardware instance address
* @param[in] force_update Force update
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw, bool force_update)
{
//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;
}
if (force_update) {
//don't care shadow register
hw->shadow_reg_ctrl.bf_update = 1;
} else {
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;
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.bf_update = 1;
}
return true;
}
@@ -1956,21 +1974,27 @@ static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw)
/**
* @brief Update WBG shadow register
*
* @param[in] hw Hardware instance address
* @param[in] hw Hardware instance address
* @param[in] force_update Force update
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw, bool force_update)
{
//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;
}
if (force_update) {
//don't care shadow register
hw->shadow_reg_ctrl.wbg_update = 1;
} else {
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;
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.wbg_update = 1;
}
return true;
}
@@ -2006,21 +2030,27 @@ static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw, bool force_update)
/**
* @brief Update Sharpen shadow register
*
* @param[in] hw Hardware instance address
* @param[in] hw Hardware instance address
* @param[in] force_update Force update
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw, bool force_update)
{
//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;
}
if (force_update) {
//don't care shadow register
hw->shadow_reg_ctrl.sharp_update = 1;
} else {
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;
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.sharp_update = 1;
}
return true;
}
@@ -2028,21 +2058,27 @@ static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw)
/**
* @brief Update Color shadow register
*
* @param[in] hw Hardware instance address
* @param[in] hw Hardware instance address
* @param[in] force_update Force update
* @return
* - True if update is successful, False otherwise
*/
static inline bool isp_ll_shadow_update_color(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_color(isp_dev_t *hw, bool force_update)
{
//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;
}
if (force_update) {
//don't care shadow register
hw->shadow_reg_ctrl.color_update = 1;
} else {
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;
//self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC
hw->shadow_reg_ctrl.color_update = 1;
}
return true;
}
@@ -2053,25 +2089,25 @@ static inline void isp_ll_shadow_set_mode(isp_dev_t *hw, isp_ll_shadow_mode_t mo
//for compatibility
}
static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_blc(isp_dev_t *hw, bool force_update)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_dpc(isp_dev_t *hw, bool force_update)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_bf(isp_dev_t *hw, bool force_update)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw, bool force_update)
{
//for compatibility
return true;
@@ -2083,13 +2119,13 @@ static inline bool isp_ll_shadow_update_ccm(isp_dev_t *hw, bool force_update)
return true;
}
static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_sharpen(isp_dev_t *hw, bool force_update)
{
//for compatibility
return true;
}
static inline bool isp_ll_shadow_update_color(isp_dev_t *hw)
static inline bool isp_ll_shadow_update_color(isp_dev_t *hw, bool force_update)
{
//for compatibility
return true;