Merge branch 'feat/isp_crop_driver_v6.0' into 'release/v6.0'

feat(isp): support Crop driver on p4 rev3 (v6.0)

See merge request espressif/esp-idf!43445
This commit is contained in:
morris
2025-11-20 10:16:01 +08:00
27 changed files with 827 additions and 55 deletions
+4
View File
@@ -46,6 +46,10 @@ if(CONFIG_SOC_ISP_WBG_SUPPORTED)
list(APPEND srcs "src/isp_wbg.c")
endif()
if(CONFIG_SOC_ISP_CROP_SUPPORTED)
list(APPEND srcs "src/isp_crop.c")
endif()
if(NOT ${target} STREQUAL "linux")
list(APPEND requires esp_mm)
endif()
@@ -25,3 +25,4 @@
#include "driver/isp_lsc.h"
#include "driver/isp_sharpen.h"
#include "driver/isp_wbg.h"
#include "driver/isp_crop.h"
@@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "driver/isp_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief ISP crop configurations
*/
typedef struct {
isp_window_t window; /*!< Crop window coordinates */
} esp_isp_crop_config_t;
/**
* @brief ISP Crop configuration
*
* @note After calling this API, crop doesn't take into effect until `esp_isp_crop_enable` is called
*
* @param[in] isp_proc Processor handle
* @param[in] config Crop configurations, set NULL to de-configure the ISP Crop
*
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
*/
esp_err_t esp_isp_crop_configure(isp_proc_handle_t isp_proc, const esp_isp_crop_config_t *config);
/**
* @brief Enable ISP crop function
*
* @param[in] isp_proc Processor handle
*
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
* - ESP_ERR_INVALID_STATE Driver state is invalid.
*/
esp_err_t esp_isp_crop_enable(isp_proc_handle_t isp_proc);
/**
* @brief Disable ISP crop function
*
* @param[in] isp_proc Processor handle
*
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
* - ESP_ERR_INVALID_STATE Driver state is invalid.
*/
esp_err_t esp_isp_crop_disable(isp_proc_handle_t isp_proc);
#ifdef __cplusplus
}
#endif
@@ -85,6 +85,7 @@ typedef struct isp_processor_t {
ISP_ATOMIC_TYPE(isp_fsm_t) blc_fsm;
ISP_ATOMIC_TYPE(isp_fsm_t) ccm_fsm;
ISP_ATOMIC_TYPE(isp_fsm_t) color_fsm;
ISP_ATOMIC_TYPE(isp_fsm_t) crop_fsm;
ISP_ATOMIC_TYPE(isp_fsm_t) demosaic_fsm;
ISP_ATOMIC_TYPE(isp_fsm_t) gamma_fsm;
ISP_ATOMIC_TYPE(isp_fsm_t) lsc_fsm;
+80
View File
@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include "sdkconfig.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/isp_core.h"
#include "driver/isp_crop.h"
#include "esp_private/isp_private.h"
#include "hal/efuse_hal.h"
#include "soc/chip_revision.h"
/*---------------------------------------------------------------
Crop
---------------------------------------------------------------*/
#define IS_EVEN(x) ((x) % 2 == 0)
#define IS_ODD(x) ((x) % 2 != 0)
static const char *TAG = "ISP_CROP";
esp_err_t esp_isp_crop_configure(isp_proc_handle_t isp_proc, const esp_isp_crop_config_t *config)
{
#if CONFIG_IDF_TARGET_ESP32P4
unsigned chip_version = efuse_hal_chip_revision();
if (!ESP_CHIP_REV_ABOVE(chip_version, 300)) {
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "Crop is not supported on ESP32P4 chips prior than v3.0");
}
#endif
uint32_t x_start = config->window.top_left.x;
uint32_t x_end = config->window.btm_right.x;
uint32_t y_start = config->window.top_left.y;
uint32_t y_end = config->window.btm_right.y;
ESP_RETURN_ON_FALSE(isp_proc && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(isp_proc->crop_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "crop is enabled already");
ESP_RETURN_ON_FALSE(x_start < x_end, ESP_ERR_INVALID_ARG, TAG, "invalid window x coordinates");
ESP_RETURN_ON_FALSE(y_start < y_end, ESP_ERR_INVALID_ARG, TAG, "invalid window y coordinates");
ESP_RETURN_ON_FALSE(x_end <= isp_proc->h_res, ESP_ERR_INVALID_ARG, TAG, "window exceeds horizontal resolution");
ESP_RETURN_ON_FALSE(y_end <= isp_proc->v_res, ESP_ERR_INVALID_ARG, TAG, "window exceeds vertical resolution");
// Check the validity of x/y coordinates
ESP_RETURN_ON_FALSE(IS_EVEN(x_start), ESP_ERR_INVALID_ARG, TAG, "x_start must be even");
ESP_RETURN_ON_FALSE(IS_ODD(x_end), ESP_ERR_INVALID_ARG, TAG, "x_end must be odd");
ESP_RETURN_ON_FALSE(IS_EVEN(y_start), ESP_ERR_INVALID_ARG, TAG, "y_start must be even");
ESP_RETURN_ON_FALSE(IS_ODD(y_end), ESP_ERR_INVALID_ARG, TAG, "y_end must be odd");
isp_ll_crop_set_clk_ctrl_mode(isp_proc->hal.hw, ISP_LL_PIPELINE_CLK_CTRL_AUTO);
isp_ll_crop_set_window(isp_proc->hal.hw, x_start, x_end, y_start, y_end);
return ESP_OK;
}
esp_err_t esp_isp_crop_enable(isp_proc_handle_t isp_proc)
{
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(isp_proc->crop_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "crop is enabled already");
isp_ll_crop_enable(isp_proc->hal.hw, true);
isp_proc->crop_fsm = ISP_FSM_ENABLE;
ESP_LOGD(TAG, "Crop enabled");
return ESP_OK;
}
esp_err_t esp_isp_crop_disable(isp_proc_handle_t isp_proc)
{
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
ESP_RETURN_ON_FALSE(isp_proc->crop_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "crop isn't enabled yet");
isp_ll_crop_enable(isp_proc->hal.hw, false);
isp_proc->crop_fsm = ISP_FSM_INIT;
ESP_LOGD(TAG, "Crop disabled");
return ESP_OK;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
+143
View File
@@ -72,7 +72,11 @@ extern "C" {
#define ISP_LL_EVENT_WBG_FRAME (1<<30)
#define ISP_LL_EVENT_CROP_ERR (1<<31)
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
#define ISP_LL_EVENT_ALL_MASK (0xFFFFFFFF)
#else
#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF)
#endif
#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV)
#define ISP_LL_EVENT_AE_MASK (ISP_LL_EVENT_AE_FDONE | ISP_LL_EVENT_AE_ENV)
#define ISP_LL_EVENT_AWB_MASK (ISP_LL_EVENT_AWB_FDONE | ISP_LL_EVENT_WBG_FRAME)
@@ -206,6 +210,23 @@ typedef enum {
ISP_SHADOW_MODE_UPDATE_ONLY_NEXT_VSYNC,
} isp_ll_shadow_mode_t;
/*---------------------------------------------------------------
Crop
---------------------------------------------------------------*/
/**
* @brief ISP crop error types
*/
typedef enum {
ISP_LL_CROP_ERR_X_MISMATCH = (1 << 0), /*!< X end coordinate exceeds image size */
ISP_LL_CROP_ERR_Y_MISMATCH = (1 << 1), /*!< Y end coordinate exceeds image size */
ISP_LL_CROP_ERR_X_END_EVEN = (1 << 2), /*!< X end coordinate is even (should be odd) */
ISP_LL_CROP_ERR_Y_END_EVEN = (1 << 3), /*!< Y end coordinate is even (should be odd) */
ISP_LL_CROP_ERR_X_START_ODD = (1 << 4), /*!< X start coordinate is odd (should be even) */
ISP_LL_CROP_ERR_Y_START_ODD = (1 << 5), /*!< Y start coordinate is odd (should be even) */
} isp_ll_crop_error_t;
/*---------------------------------------------------------------
Clock
---------------------------------------------------------------*/
@@ -2473,6 +2494,128 @@ static inline void isp_ll_hist_set_rgb_coefficient(isp_dev_t *hw, const isp_hist
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_b, rgb_coeff->coeff_b.decimal);
}
/*---------------------------------------------------------------
CROP
---------------------------------------------------------------*/
#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
/**
* @brief Set crop clock control mode
*
* @param[in] hw Hardware instance address
* @param[in] mode 'isp_ll_pipeline_clk_ctrl_t`
*/
static inline void isp_ll_crop_set_clk_ctrl_mode(isp_dev_t *hw, isp_ll_pipeline_clk_ctrl_t mode)
{
hw->clk_en.clk_crop_force_on = mode;
}
/**
* @brief Enable/Disable ISP crop
*
* @param[in] hw Hardware instance address
* @param[in] en enable / disable
*/
static inline void isp_ll_crop_enable(isp_dev_t *hw, bool enable)
{
hw->cntl.crop_en = enable;
}
/**
* @brief Set ISP crop window coordinates
*
* @param[in] hw Hardware instance address
* @param[in] x_start Crop start x coordinate (0 to image_width-1)
* @param[in] x_end Crop end x coordinate (x_start+1 to image_width-1)
* @param[in] y_start Crop start y coordinate (0 to image_height-1)
* @param[in] y_end Crop end y coordinate (y_start+1 to image_height-1)
*/
static inline void isp_ll_crop_set_window(isp_dev_t *hw,
uint32_t x_start, uint32_t x_end,
uint32_t y_start, uint32_t y_end)
{
hw->crop_x_capture.crop_x_start = x_start;
hw->crop_x_capture.crop_x_end = x_end;
hw->crop_y_capture.crop_y_start = y_start;
hw->crop_y_capture.crop_y_end = y_end;
}
/**
* @brief Get crop window coordinates
*
* @param[in] hw Hardware instance address
* @param[out] x_start Crop start x coordinate (0 to image_width-1)
* @param[out] x_end Crop end x coordinate (x_start+1 to image_width-1)
* @param[out] y_start Crop start y coordinate (0 to image_height-1)
* @param[out] y_end Crop end y coordinate (y_start+1 to image_height-1)
*/
static inline void isp_ll_crop_get_window(isp_dev_t *hw,
uint32_t *x_start, uint32_t *x_end,
uint32_t *y_start, uint32_t *y_end)
{
*x_start = hw->crop_x_capture.crop_x_start;
*x_end = hw->crop_x_capture.crop_x_end;
*y_start = hw->crop_y_capture.crop_y_start;
*y_end = hw->crop_y_capture.crop_y_end;
}
/**
* @brief Get crop error status
*
* @param[in] hw Hardware instance address
* @param[out] error_bits Error status bits
*/
static inline void isp_ll_crop_get_error_status(isp_dev_t *hw, uint32_t *error_bits)
{
*error_bits = hw->crop_err_st.val & 0x3F; // Retrieve lower 6 bits
}
/**
* @brief Clear crop error
*
* @param[in] hw Hardware instance address
*/
static inline void isp_ll_crop_clear_error(isp_dev_t *hw)
{
hw->crop_ctrl.crop_sft_rst = 1;
}
#else
static inline void isp_ll_crop_set_clk_ctrl_mode(isp_dev_t *hw, isp_ll_pipeline_clk_ctrl_t mode)
{
// for compatibility
}
static inline void isp_ll_crop_enable(isp_dev_t *hw, bool enable)
{
// for compatibility
}
static inline void isp_ll_crop_set_window(isp_dev_t *hw,
uint32_t x_start, uint32_t x_end,
uint32_t y_start, uint32_t y_end)
{
// for compatibility
}
static inline void isp_ll_crop_get_window(isp_dev_t *hw,
uint32_t *x_start, uint32_t *x_end,
uint32_t *y_start, uint32_t *y_end)
{
// for compatibility
}
static inline void isp_ll_crop_get_error_status(isp_dev_t *hw, uint32_t *error_bits)
{
// for compatibility
}
static inline void isp_ll_crop_clear_error(isp_dev_t *hw)
{
// for compatibility
}
#endif //#if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300
#ifdef __cplusplus
}
#endif
@@ -907,6 +907,10 @@ config SOC_ISP_COLOR_SUPPORTED
bool
default y
config SOC_ISP_CROP_SUPPORTED
bool
default y
config SOC_ISP_DEMOSAIC_SUPPORTED
bool
default y
@@ -351,6 +351,7 @@
#define SOC_ISP_BLC_SUPPORTED 1
#define SOC_ISP_CCM_SUPPORTED 1
#define SOC_ISP_COLOR_SUPPORTED 1
#define SOC_ISP_CROP_SUPPORTED 1
#define SOC_ISP_DEMOSAIC_SUPPORTED 1
#define SOC_ISP_DVP_SUPPORTED 1
#define SOC_ISP_LSC_SUPPORTED 1