feat(isp): added isp bf driver

This commit is contained in:
Armando 2024-05-21 10:21:49 +08:00
parent cd7c5a8bf5
commit 6e3efc7b9f
14 changed files with 336 additions and 7 deletions

View File

@ -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

View File

@ -13,3 +13,4 @@
#include "driver/isp_core.h"
#include "driver/isp_af.h"
#include "driver/isp_bf.h"

View File

@ -0,0 +1,70 @@
/*
* SPDX-FileCopyrightText: 2024 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 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

View File

@ -0,0 +1,74 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <esp_types.h>
#include <sys/lock.h>
#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;
}

View File

@ -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"

View File

@ -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

View File

@ -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
---------------------------------------------------------------*/

View File

@ -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
}

View File

@ -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

View File

@ -5,12 +5,14 @@
*/
#include <sys/param.h>
#include <string.h>
#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
---------------------------------------------------------------*/

View File

@ -751,6 +751,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
@ -767,6 +771,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

View File

@ -312,10 +312,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)

View File

@ -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

View File

@ -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;