diff --git a/components/esp_driver_isp/include/driver/isp_bf.h b/components/esp_driver_isp/include/driver/isp_bf.h index b1301301a9..2669ae3d03 100644 --- a/components/esp_driver_isp/include/driver/isp_bf.h +++ b/components/esp_driver_isp/include/driver/isp_bf.h @@ -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; /** diff --git a/components/esp_driver_isp/include/driver/isp_blc.h b/components/esp_driver_isp/include/driver/isp_blc.h index d4a9bd8120..3954e5cfb1 100644 --- a/components/esp_driver_isp/include/driver/isp_blc.h +++ b/components/esp_driver_isp/include/driver/isp_blc.h @@ -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; /** diff --git a/components/esp_driver_isp/include/driver/isp_color.h b/components/esp_driver_isp/include/driver/isp_color.h index 5549fdeab3..aaf2906eae 100644 --- a/components/esp_driver_isp/include/driver/isp_color.h +++ b/components/esp_driver_isp/include/driver/isp_color.h @@ -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; /** diff --git a/components/esp_driver_isp/include/driver/isp_sharpen.h b/components/esp_driver_isp/include/driver/isp_sharpen.h index 636454affb..01dc51873c 100644 --- a/components/esp_driver_isp/include/driver/isp_sharpen.h +++ b/components/esp_driver_isp/include/driver/isp_sharpen.h @@ -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; /** diff --git a/components/esp_driver_isp/include/driver/isp_wbg.h b/components/esp_driver_isp/include/driver/isp_wbg.h index b8add5cd50..c4545aed18 100644 --- a/components/esp_driver_isp/include/driver/isp_wbg.h +++ b/components/esp_driver_isp/include/driver/isp_wbg.h @@ -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; /** diff --git a/components/esp_driver_isp/src/isp_awb.c b/components/esp_driver_isp/src/isp_awb.c index 1332a85cef..caac82a9f7 100644 --- a/components/esp_driver_isp/src/isp_awb.c +++ b/components/esp_driver_isp/src/isp_awb.c @@ -75,47 +75,49 @@ static esp_err_t s_esp_isp_awb_config_hardware(isp_proc_handle_t isp_proc, const ESP_RETURN_ON_FALSE(isp_hal_awb_set_window_range(&isp_proc->hal, &awb_cfg->window), ESP_ERR_INVALID_ARG, TAG, "invalid window range"); + bool subwindow_is_zero = awb_cfg->subwindow.top_left.x == 0 && + awb_cfg->subwindow.top_left.y == 0 && + awb_cfg->subwindow.btm_right.x == 0 && + awb_cfg->subwindow.btm_right.y == 0; // Subwindow feature is only supported on REV >= 3.0 if (efuse_hal_chip_revision() < 300) { - bool subwindow_is_zero = awb_cfg->subwindow.top_left.x == 0 && - awb_cfg->subwindow.top_left.y == 0 && - awb_cfg->subwindow.btm_right.x == 0 && - awb_cfg->subwindow.btm_right.y == 0; if (!subwindow_is_zero) { ESP_LOGW(TAG, "Subwindow feature is not supported on REV < 3.0, subwindow will not be configured"); } } else { - // Subwindow is just checked and configured on REV >= 3.0 - isp_window_t subwindow = awb_cfg->subwindow; - ESP_RETURN_ON_FALSE( - (subwindow.top_left.x >= awb_cfg->window.top_left.x) && - (subwindow.top_left.y >= awb_cfg->window.top_left.y) && - (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && - (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), - ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" - ); + if (!subwindow_is_zero) { + // Subwindow is just checked and configured on REV >= 3.0 + isp_window_t subwindow = awb_cfg->subwindow; + ESP_RETURN_ON_FALSE( + (subwindow.top_left.x >= awb_cfg->window.top_left.x) && + (subwindow.top_left.y >= awb_cfg->window.top_left.y) && + (subwindow.btm_right.x <= awb_cfg->window.btm_right.x) && + (subwindow.btm_right.y <= awb_cfg->window.btm_right.y), + ESP_ERR_INVALID_ARG, TAG, "subwindow exceeds window range" + ); - if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || - (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { - int block_width = (int)((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM); - int block_height = (int)((subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); - ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %d x %d)", - block_width, block_height); - return ESP_ERR_INVALID_ARG; - } + if ((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM < 4 || + (subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM < 4) { + int block_width = (int)((subwindow.btm_right.x - subwindow.top_left.x + 1) / ISP_AWB_WINDOW_X_NUM); + int block_height = (int)((subwindow.btm_right.y - subwindow.top_left.y + 1) / ISP_AWB_WINDOW_Y_NUM); + ESP_LOGE(TAG, "subwindow block size is too small: width and height must be at least 4 (got %d x %d)", + block_width, block_height); + return ESP_ERR_INVALID_ARG; + } - int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; - int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; - if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { - ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ - Resolution will be floored to the nearest divisible value.", - size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); - // floor to the nearest divisible value - subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; - subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; + int size_x = subwindow.btm_right.x - subwindow.top_left.x + 1; + int size_y = subwindow.btm_right.y - subwindow.top_left.y + 1; + if ((size_x % ISP_AWB_WINDOW_X_NUM != 0) || (size_y % ISP_AWB_WINDOW_Y_NUM != 0)) { + ESP_LOGW(TAG, "subwindow size (%d x %d) is not divisible by AWB subwindow blocks grid (%d x %d). \ + Resolution will be floored to the nearest divisible value.", + size_x, size_y, ISP_AWB_WINDOW_X_NUM, ISP_AWB_WINDOW_Y_NUM); + // floor to the nearest divisible value + subwindow.btm_right.x -= size_x % ISP_AWB_WINDOW_X_NUM; + subwindow.btm_right.y -= size_y % ISP_AWB_WINDOW_Y_NUM; + } + ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), + ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); } - ESP_RETURN_ON_FALSE(isp_hal_awb_set_subwindow_range(&isp_proc->hal, &subwindow), - ESP_ERR_INVALID_ARG, TAG, "invalid subwindow range"); } isp_u32_range_t lum_range = awb_cfg->white_patch.luminance; diff --git a/components/esp_driver_isp/src/isp_bf.c b/components/esp_driver_isp/src/isp_bf.c index 1c71d0eefd..23fd164428 100644 --- a/components/esp_driver_isp/src/isp_bf.c +++ b/components/esp_driver_isp/src/isp_bf.c @@ -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; diff --git a/components/esp_driver_isp/src/isp_blc.c b/components/esp_driver_isp/src/isp_blc.c index f8faa2774b..9a9ca10445 100644 --- a/components/esp_driver_isp/src/isp_blc.c +++ b/components/esp_driver_isp/src/isp_blc.c @@ -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; diff --git a/components/esp_driver_isp/src/isp_color.c b/components/esp_driver_isp/src/isp_color.c index c3da6d5cdc..cea2d7945f 100644 --- a/components/esp_driver_isp/src/isp_color.c +++ b/components/esp_driver_isp/src/isp_color.c @@ -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; diff --git a/components/esp_driver_isp/src/isp_sharpen.c b/components/esp_driver_isp/src/isp_sharpen.c index c0dd2fc258..e0746946d0 100644 --- a/components/esp_driver_isp/src/isp_sharpen.c +++ b/components/esp_driver_isp/src/isp_sharpen.c @@ -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; diff --git a/components/esp_driver_isp/src/isp_wbg.c b/components/esp_driver_isp/src/isp_wbg.c index 96b809840c..b17d7d9ecc 100644 --- a/components/esp_driver_isp/src/isp_wbg.c +++ b/components/esp_driver_isp/src/isp_wbg.c @@ -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; } diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 253c7a2114..fce320c14a 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -1867,21 +1867,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; } @@ -1889,21 +1895,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; } @@ -1911,21 +1923,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; } @@ -1933,21 +1951,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; } @@ -1983,21 +2007,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; } @@ -2005,21 +2035,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; } @@ -2030,25 +2066,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; @@ -2060,13 +2096,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;