From cc48efc6ec509c1189f94808a9b2288ba744ce29 Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 21 May 2024 10:21:49 +0800 Subject: [PATCH] feat(isp): added isp bf driver --- components/esp_driver_isp/CMakeLists.txt | 4 + .../esp_driver_isp/include/driver/isp.h | 1 + .../esp_driver_isp/include/driver/isp_bf.h | 70 +++++++++++++++ components/esp_driver_isp/src/isp_bf.c | 74 ++++++++++++++++ components/esp_driver_isp/src/isp_core.c | 1 + components/esp_driver_isp/src/isp_internal.h | 3 +- components/hal/esp32p4/include/hal/isp_ll.h | 86 ++++++++++++++++++- components/hal/include/hal/isp_hal.h | 26 +++++- components/hal/include/hal/isp_types.h | 19 ++++ components/hal/isp_hal.c | 26 +++++- .../esp32p4/include/soc/Kconfig.soc_caps.in | 12 +++ components/soc/esp32p4/include/soc/soc_caps.h | 4 + examples/peripherals/isp/auto_focus/README.md | 2 +- .../isp/auto_focus/main/isp_af_dsi_main.c | 15 ++++ 14 files changed, 336 insertions(+), 7 deletions(-) create mode 100644 components/esp_driver_isp/include/driver/isp_bf.h create mode 100644 components/esp_driver_isp/src/isp_bf.c diff --git a/components/esp_driver_isp/CMakeLists.txt b/components/esp_driver_isp/CMakeLists.txt index 1ac8cc1ab7..ac99867c00 100644 --- a/components/esp_driver_isp/CMakeLists.txt +++ b/components/esp_driver_isp/CMakeLists.txt @@ -7,6 +7,10 @@ if(CONFIG_SOC_ISP_SUPPORTED) "src/isp_af.c") endif() +if(CONFIG_SOC_ISP_BF_SUPPORTED) + list(APPEND srcs "src/isp_bf.c") +endif() + idf_component_register(SRCS ${srcs} INCLUDE_DIRS ${public_include} PRIV_REQUIRES esp_driver_gpio diff --git a/components/esp_driver_isp/include/driver/isp.h b/components/esp_driver_isp/include/driver/isp.h index 5909bf0fac..50674cb7b2 100644 --- a/components/esp_driver_isp/include/driver/isp.h +++ b/components/esp_driver_isp/include/driver/isp.h @@ -13,3 +13,4 @@ #include "driver/isp_core.h" #include "driver/isp_af.h" +#include "driver/isp_bf.h" diff --git a/components/esp_driver_isp/include/driver/isp_bf.h b/components/esp_driver_isp/include/driver/isp_bf.h new file mode 100644 index 0000000000..b1301301a9 --- /dev/null +++ b/components/esp_driver_isp/include/driver/isp_bf.h @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" +#include "driver/isp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief ISP BF configurations + */ +typedef struct { + isp_bf_edge_padding_mode_t padding_mode; ///< BF edge padding mode + uint8_t padding_data; ///< BF edge padding pixel data + uint8_t bf_template[ISP_BF_TEMPLATE_X_NUMS][ISP_BF_TEMPLATE_Y_NUMS]; ///< BF template data + 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 +} esp_isp_bf_config_t; + +/** + * @brief ISP BF configuration + * + * @note After calling this API, BF doesn't take into effect until `esp_isp_bf_enable` is called + * + * @param[in] proc Processor handle + * @param[in] config BF configurations, set NULL to de-configure the ISP BF + * + * @return + * - ESP_OK On success + * - ESP_ERR_INVALID_STATE Not allowed to be called under current state + * - ESP_ERR_INVALID_ARG If the combination of arguments is invalid + */ +esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t *config); + +/** + * @brief Enable ISP BF function + * + * @param[in] 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_bf_enable(isp_proc_handle_t proc); + +/** + * @brief Disable ISP BF function + * + * @param[in] 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_bf_disable(isp_proc_handle_t proc); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_isp/src/isp_bf.c b/components/esp_driver_isp/src/isp_bf.c new file mode 100644 index 0000000000..00bf4d1902 --- /dev/null +++ b/components/esp_driver_isp/src/isp_bf.c @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_log.h" +#include "esp_check.h" +#include "esp_heap_caps.h" +#include "freertos/FreeRTOS.h" +#include "esp_clk_tree.h" +#include "driver/isp_core.h" +#include "driver/isp_bf.h" +#include "esp_private/periph_ctrl.h" +#include "esp_private/mipi_csi_share_hw_ctrl.h" +#include "hal/hal_utils.h" +#include "soc/mipi_csi_bridge_struct.h" +#include "soc/isp_periph.h" +#include "isp_internal.h" + +static const char *TAG = "ISP_BF"; + +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +esp_err_t esp_isp_bf_configure(isp_proc_handle_t proc, const esp_isp_bf_config_t *config) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "bf is enabled already"); + + if (config) { + bool valid_padding_setting = (!config->padding_line_tail_valid_end_pixel && !config->padding_line_tail_valid_start_pixel) || (config->padding_line_tail_valid_end_pixel > config->padding_line_tail_valid_start_pixel); + ESP_RETURN_ON_FALSE(valid_padding_setting, ESP_ERR_INVALID_ARG, TAG, "wrong padding line tail valid pixel setting"); + + isp_hal_bf_cfg_t bf_hal_cfg = { + .denoising_level = config->denoising_level, + .padding_mode = config->padding_mode, + .padding_data = config->padding_data, + .padding_line_tail_valid_start_pixel = config->padding_line_tail_valid_start_pixel, + .padding_line_tail_valid_end_pixel = config->padding_line_tail_valid_end_pixel, + }; + memcpy(bf_hal_cfg.bf_template, config->bf_template, ISP_BF_TEMPLATE_X_NUMS * ISP_BF_TEMPLATE_X_NUMS * sizeof(uint8_t)); + isp_hal_bf_config(&(proc->hal), &bf_hal_cfg); + } else { + isp_hal_bf_config(&(proc->hal), NULL); + } + + return ESP_OK; +} + +esp_err_t esp_isp_bf_enable(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "bf is enabled already"); + + isp_ll_bf_enable(proc->hal.hw, true); + proc->bf_fsm = ISP_FSM_ENABLE; + + return ESP_OK; +} + +esp_err_t esp_isp_bf_disable(isp_proc_handle_t proc) +{ + ESP_RETURN_ON_FALSE(proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer"); + ESP_RETURN_ON_FALSE(proc->bf_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "bf isn't enabled yet"); + + isp_ll_bf_enable(proc->hal.hw, false); + proc->bf_fsm = ISP_FSM_INIT; + + return ESP_OK; +} diff --git a/components/esp_driver_isp/src/isp_core.c b/components/esp_driver_isp/src/isp_core.c index 773ca18e5b..b34057f9ab 100644 --- a/components/esp_driver_isp/src/isp_core.c +++ b/components/esp_driver_isp/src/isp_core.c @@ -13,6 +13,7 @@ #include "freertos/FreeRTOS.h" #include "esp_clk_tree.h" #include "driver/isp_core.h" +#include "driver/isp_bf.h" #include "esp_private/periph_ctrl.h" #include "esp_private/mipi_csi_share_hw_ctrl.h" #include "hal/hal_utils.h" diff --git a/components/esp_driver_isp/src/isp_internal.h b/components/esp_driver_isp/src/isp_internal.h index 1ad011c409..3d38838677 100644 --- a/components/esp_driver_isp/src/isp_internal.h +++ b/components/esp_driver_isp/src/isp_internal.h @@ -57,7 +57,8 @@ typedef struct isp_processor_t { portMUX_TYPE spinlock; /* sub module contexts */ - isp_af_ctrlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS]; + isp_af_ctrlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS]; + isp_fsm_t bf_fsm; } isp_processor_t; #ifdef __cplusplus diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index ee837995ec..c91c8efb25 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -63,14 +63,18 @@ extern "C" { #define ISP_LL_EVENT_TAIL_IDI_FRAME (1<<27) #define ISP_LL_EVENT_HEADER_IDI_FRAME (1<<28) -#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF) -#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV) +#define ISP_LL_EVENT_ALL_MASK (0x1FFFFFFF) +#define ISP_LL_EVENT_AF_MASK (ISP_LL_EVENT_AF_FDONE | ISP_LL_EVENT_AF_ENV) /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ -#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1) +#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1) +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +#define ISP_LL_BF_DEFAULT_TEMPLATE_VAL 15 /** * @brief Env monitor mode @@ -661,6 +665,82 @@ static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) hw->cntl.bf_en = enable; } +/** + * @brief Set ISP BF sigma value + * + * @param[in] hw Hardware instance address + * @param[in] sigmal_val sigma value + */ +static inline void isp_ll_bf_set_sigma(isp_dev_t *hw, uint32_t sigma_val) +{ + hw->bf_sigma.sigma = sigma_val; +} + +/** + * @brief Set ISP BF padding mode + * + * @param[in] hw Hardware instance address + * @param[in] padding_mode padding mode + */ +static inline void isp_ll_bf_set_padding_mode(isp_dev_t *hw, isp_bf_edge_padding_mode_t padding_mode) +{ + hw->bf_matrix_ctrl.bf_padding_mode = padding_mode; +} + +/** + * @brief Set ISP BF padding data + * + * @param[in] hw Hardware instance address + * @param[in] padding_data padding data + */ +static inline void isp_ll_bf_set_padding_data(isp_dev_t *hw, uint32_t padding_data) +{ + hw->bf_matrix_ctrl.bf_padding_data = padding_data; +} + +/** + * @brief Set ISP BF tail pixen pulse tl + * + * @param[in] hw Hardware instance address + * @param[in] start_pixel start pixel value + */ +static inline void isp_ll_bf_set_padding_line_tail_valid_start_pixel(isp_dev_t *hw, uint32_t start_pixel) +{ + hw->bf_matrix_ctrl.bf_tail_pixen_pulse_tl = start_pixel; +} + +/** + * @brief Set ISP BF tail pixen pulse th + * + * @param[in] hw Hardware instance address + * @param[in] end_pixel end pixel value + */ +static inline void isp_ll_bf_set_padding_line_tail_valid_end_pixel(isp_dev_t *hw, uint32_t end_pixel) +{ + hw->bf_matrix_ctrl.bf_tail_pixen_pulse_th = end_pixel; +} + +/** + * @brief Set ISP BF template + * + * @param[in] hw Hardware instance address + * @param[in] template_arr 2-d array for the template + */ +static inline void isp_ll_bf_set_template(isp_dev_t *hw, uint8_t template_arr[SOC_ISP_BF_TEMPLATE_X_NUMS][SOC_ISP_BF_TEMPLATE_Y_NUMS]) +{ + int cnt = 0; + for (int i = 0; i < SOC_ISP_BF_TEMPLATE_X_NUMS; i++) { + for (int j = 0; j < SOC_ISP_BF_TEMPLATE_Y_NUMS; j++) { + if (i == 2 && j == 2) { + break; + } + hw->bf_gau0.val = (hw->bf_gau0.val & ~(0xf << (28 - cnt * 4))) | ((template_arr[i][j] & 0xf) << (28 - cnt * 4)); + cnt++; + } + } + + hw->bf_gau1.gau_template22 = template_arr[2][2]; +} /*--------------------------------------------------------------- CCM ---------------------------------------------------------------*/ diff --git a/components/hal/include/hal/isp_hal.h b/components/hal/include/hal/isp_hal.h index 2a113ddb3f..9aacd179d8 100644 --- a/components/hal/include/hal/isp_hal.h +++ b/components/hal/include/hal/isp_hal.h @@ -19,12 +19,26 @@ extern "C" { #endif +/** + * @brief BF configurations + */ +typedef struct { + isp_bf_edge_padding_mode_t padding_mode; ///< BF edge padding mode + uint8_t padding_data; ///< BF edge padding pixel data + uint8_t bf_template[ISP_BF_TEMPLATE_X_NUMS][ISP_BF_TEMPLATE_Y_NUMS]; ///< BF template data + 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 + uint8_t padding_line_tail_valid_end_pixel; ///< BF edge padding line tail valid end pixel +} isp_hal_bf_cfg_t; /** - * Context that should be maintained by both the driver and the HAL + * @brief Context that should be maintained by both the driver and the HAL */ typedef struct { void *hw; ///< Beginning address of the ISP registers + + /* BF */ + isp_hal_bf_cfg_t bf_cfg; ///< BF configurations } isp_hal_context_t; /** @@ -61,6 +75,16 @@ void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const */ uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask); +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +/** + * @brief Configure ISP BF registers + * + * @param[in] hal Context of the HAL layer + * @param[in] config BF config, set NULL to de-config the ISP BF + */ +void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config); #ifdef __cplusplus } diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h index 8a2fb0fc76..0d5bc4be3f 100644 --- a/components/hal/include/hal/isp_types.h +++ b/components/hal/include/hal/isp_types.h @@ -72,6 +72,25 @@ typedef struct { int luminance[ISP_AF_WINDOW_NUM]; ///< Luminance, it refers how luminant an image is } isp_af_result_t; +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +#if SOC_ISP_BF_SUPPORTED +#define ISP_BF_TEMPLATE_X_NUMS SOC_ISP_BF_TEMPLATE_X_NUMS // BF template x field nums +#define ISP_BF_TEMPLATE_Y_NUMS SOC_ISP_BF_TEMPLATE_Y_NUMS // BF template y field nums +#else +#define ISP_BF_TEMPLATE_X_NUMS 0 +#define ISP_BF_TEMPLATE_Y_NUMS 0 +#endif + +/** + * @brief ISP BF edge padding mode + */ +typedef enum { + ISP_BF_EDGE_PADDING_MODE_SRND_DATA, ///< Fill BF edge padding data with surrounding pixel data + ISP_BF_EDGE_PADDING_MODE_CUSTOM_DATA, ///< Fill BF edge padding data with custom pixel data +} isp_bf_edge_padding_mode_t; + #ifdef __cplusplus } #endif diff --git a/components/hal/isp_hal.c b/components/hal/isp_hal.c index d897c07080..3bb3890693 100644 --- a/components/hal/isp_hal.c +++ b/components/hal/isp_hal.c @@ -5,12 +5,14 @@ */ #include +#include #include "sdkconfig.h" #include "soc/soc_caps.h" #include "hal/assert.h" #include "hal/log.h" #include "hal/isp_hal.h" #include "hal/isp_ll.h" +#include "hal/isp_types.h" /** * ISP HAL layer @@ -22,7 +24,6 @@ void isp_hal_init(isp_hal_context_t *hal, int isp_id) isp_ll_init(hal->hw); } - /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ @@ -31,6 +32,29 @@ void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_ll_af_set_window_range(hal->hw, window_id, window->top_left_x, window->top_left_y, window->bottom_right_x, window->bottom_right_y); } +/*--------------------------------------------------------------- + BF +---------------------------------------------------------------*/ +void isp_hal_bf_config(isp_hal_context_t *hal, isp_hal_bf_cfg_t *config) +{ + if (config) { + isp_ll_bf_set_sigma(hal->hw, config->denoising_level); + isp_ll_bf_set_padding_mode(hal->hw, config->padding_mode); + isp_ll_bf_set_padding_data(hal->hw, config->padding_data); + isp_ll_bf_set_padding_line_tail_valid_start_pixel(hal->hw, config->padding_line_tail_valid_start_pixel); + isp_ll_bf_set_padding_line_tail_valid_end_pixel(hal->hw, config->padding_line_tail_valid_end_pixel); + isp_ll_bf_set_template(hal->hw, config->bf_template); + } else { + isp_ll_bf_set_sigma(hal->hw, 0); + isp_ll_bf_set_padding_mode(hal->hw, 0); + isp_ll_bf_set_padding_data(hal->hw, 0); + isp_ll_bf_set_padding_line_tail_valid_start_pixel(hal->hw, 0); + isp_ll_bf_set_padding_line_tail_valid_end_pixel(hal->hw, 0); + uint8_t default_template[SOC_ISP_BF_TEMPLATE_X_NUMS][SOC_ISP_BF_TEMPLATE_Y_NUMS] = {}; + memset(default_template, SOC_ISP_BF_TEMPLATE_X_NUMS, sizeof(default_template)); + isp_ll_bf_set_template(hal->hw, default_template); + } +} /*--------------------------------------------------------------- INTR, put in iram ---------------------------------------------------------------*/ diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index c8822246f2..76fe088d5a 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -727,6 +727,10 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH bool default y +config SOC_ISP_BF_SUPPORTED + bool + default y + config SOC_ISP_NUMS int default 1 @@ -743,6 +747,14 @@ config SOC_ISP_SHARE_CSI_BRG bool default y +config SOC_ISP_BF_TEMPLATE_X_NUMS + int + default 3 + +config SOC_ISP_BF_TEMPLATE_Y_NUMS + int + default 3 + config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 8d3fece9ed..298b881697 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -304,10 +304,14 @@ #define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */ /*-------------------------- ISP CAPS ----------------------------------------*/ +#define SOC_ISP_BF_SUPPORTED 1 + #define SOC_ISP_NUMS 1U #define SOC_ISP_AF_CTLR_NUMS 1U #define SOC_ISP_AF_WINDOW_NUMS 3 #define SOC_ISP_SHARE_CSI_BRG 1 +#define SOC_ISP_BF_TEMPLATE_X_NUMS 3 +#define SOC_ISP_BF_TEMPLATE_Y_NUMS 3 /*-------------------------- LEDC CAPS ---------------------------------------*/ #define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1) diff --git a/examples/peripherals/isp/auto_focus/README.md b/examples/peripherals/isp/auto_focus/README.md index a38446fd9e..3e3ba628b4 100644 --- a/examples/peripherals/isp/auto_focus/README.md +++ b/examples/peripherals/isp/auto_focus/README.md @@ -6,7 +6,7 @@ ## Overview -This example demonstrates how to use the ISP (image signal processor) to work with esp_driver_cam component. This example will capture camera sensor signals via CSI interface and display it via DSI interface. This example also enables the ISP AF (auto-focus) feature. +This example demonstrates how to use the ISP (image signal processor) to work with esp_driver_cam component. This example will capture camera sensor signals via CSI interface and display it via DSI interface. This example also enables the ISP AF (auto-focus) feature and ISP BF (bayer denoise) feature. ## Usage diff --git a/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c b/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c index 6cca1612bc..4ff9f323ef 100644 --- a/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c +++ b/examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c @@ -16,6 +16,7 @@ #include "esp_cache.h" #include "driver/i2c_master.h" #include "driver/isp.h" +#include "driver/isp_bf.h" #include "isp_af_scheme_sa.h" #include "esp_cam_ctlr_csi.h" #include "esp_cam_ctlr.h" @@ -263,6 +264,20 @@ void app_main(void) ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc)); ESP_ERROR_CHECK(esp_isp_enable(isp_proc)); + esp_isp_bf_config_t bf_config = { + .denoising_level = 5, + .padding_mode = ISP_BF_EDGE_PADDING_MODE_SRND_DATA, + .bf_template = { + {1, 2, 1}, + {2, 4, 2}, + {1, 2, 1}, + }, + .padding_line_tail_valid_start_pixel = 0, + .padding_line_tail_valid_end_pixel = 0, + }; + ESP_ERROR_CHECK(esp_isp_bf_configure(isp_proc, &bf_config)); + ESP_ERROR_CHECK(esp_isp_bf_enable(isp_proc)); + typedef struct af_task_param_t { isp_proc_handle_t isp_proc; esp_sccb_io_handle_t dw9714_io_handle;