Files
2025-12-11 10:24:31 +08:00

73 lines
2.8 KiB
C

/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_types.h>
#include "esp_log.h"
#include "esp_check.h"
#include "freertos/FreeRTOS.h"
#include "driver/isp_core.h"
#include "driver/isp_ccm.h"
#include "esp_private/isp_private.h"
static const char *TAG = "ISP_CCM";
/*---------------------------------------------------------------
CCM
---------------------------------------------------------------*/
esp_err_t esp_isp_ccm_configure(isp_proc_handle_t proc, const esp_isp_ccm_config_t *ccm_cfg)
{
ESP_RETURN_ON_FALSE(proc && ccm_cfg, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
// Check matrix values are within valid range
float max_range = (1 << ISP_LL_CCM_MATRIX_INT_BITS);
float min_range = -(1 << ISP_LL_CCM_MATRIX_INT_BITS);
for (int i = 0; i < ISP_CCM_DIMENSION; i++) {
for (int j = 0; j < ISP_CCM_DIMENSION; j++) {
float value = ccm_cfg->matrix[i][j];
ESP_RETURN_ON_FALSE(value >= min_range && value <= max_range, ESP_ERR_INVALID_ARG, TAG,
"Matrix[%d][%d] value %f is out of range [%f, %f]", i, j, value, min_range, max_range);
}
}
bool ret = true;
bool valid = false;
esp_os_enter_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, ccm_cfg->flags.update_once_configured);
esp_os_exit_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;
}
esp_err_t esp_isp_ccm_enable(isp_proc_handle_t proc)
{
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
isp_fsm_t expected_fsm = ISP_FSM_INIT;
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&proc->ccm_fsm, &expected_fsm, ISP_FSM_ENABLE), ESP_ERR_INVALID_STATE, TAG, "ccm is enabled already");
esp_os_enter_critical(&proc->spinlock);
isp_ll_ccm_enable(proc->hal.hw, true);
esp_os_exit_critical(&proc->spinlock);
return ESP_OK;
}
esp_err_t esp_isp_ccm_disable(isp_proc_handle_t proc)
{
ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
isp_fsm_t expected_fsm = ISP_FSM_ENABLE;
ESP_RETURN_ON_FALSE(atomic_compare_exchange_strong(&proc->ccm_fsm, &expected_fsm, ISP_FSM_INIT), ESP_ERR_INVALID_STATE, TAG, "ccm isn't enabled yet");
esp_os_enter_critical(&proc->spinlock);
isp_ll_ccm_enable(proc->hal.hw, false);
esp_os_exit_critical(&proc->spinlock);
return ESP_OK;
}