diff --git a/components/esp_driver_isp/include/driver/isp_ccm.h b/components/esp_driver_isp/include/driver/isp_ccm.h index 1560782894..f779ff3cb7 100644 --- a/components/esp_driver_isp/include/driver/isp_ccm.h +++ b/components/esp_driver_isp/include/driver/isp_ccm.h @@ -26,6 +26,9 @@ typedef struct { * When saturation is true, and final value will be limited to 4.0, and won't rise error * When saturation is false, `esp_isp_ccm_configure` will rise ESP_ERR_INVALID_ARG error */ + 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_ccm_config_t; /** diff --git a/components/esp_driver_isp/src/isp_ccm.c b/components/esp_driver_isp/src/isp_ccm.c index 4168a1ad52..cb688dc7f3 100644 --- a/components/esp_driver_isp/src/isp_ccm.c +++ b/components/esp_driver_isp/src/isp_ccm.c @@ -26,7 +26,7 @@ esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config 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); + valid = isp_ll_shadow_update_ccm(proc->hal.hw, ccm_cfg->flags.update_once_configured); 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"); diff --git a/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c b/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c index d14f6033a2..e73b45fb4e 100644 --- a/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c +++ b/components/esp_driver_isp/test_apps/isp/main/test_isp_driver.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -210,15 +210,20 @@ TEST_CASE("ISP CCM basic function", "[isp]") esp_isp_ccm_config_t ccm_cfg = { .matrix = { - {5.0, 0.0, 0.0}, + {16.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0} }, .saturation = false, + .flags = { + .update_once_configured = true, + }, }; // Out of range case TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_ccm_configure(isp_proc, &ccm_cfg)); + // saturation case + ccm_cfg.matrix[0][0] = 5.0; ccm_cfg.saturation = true; TEST_ESP_OK(esp_isp_ccm_configure(isp_proc, &ccm_cfg)); TEST_ESP_OK(esp_isp_ccm_enable(isp_proc)); diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index d5abfc435d..4a1715d335 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -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 */ @@ -1965,21 +1965,27 @@ static inline bool isp_ll_shadow_update_wbg(isp_dev_t *hw) /** * @brief Update CCM 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_ccm(isp_dev_t *hw) +static inline bool isp_ll_shadow_update_ccm(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.ccm_update == 1) { - return false; - } + if (force_update) { + //don't care shadow register + hw->shadow_reg_ctrl.ccm_update = 1; + } else { + 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; + //self clear when ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC + hw->shadow_reg_ctrl.ccm_update = 1; + } return true; }