forked from espressif/esp-idf
Merge branch 'feat/isp_lsc_feature' into 'master'
isp: lsc feature Closes IDF-11228 See merge request espressif/esp-idf!31193
This commit is contained in:
@@ -34,6 +34,10 @@ if(CONFIG_SOC_ISP_COLOR_SUPPORTED)
|
|||||||
list(APPEND srcs "src/isp_color.c")
|
list(APPEND srcs "src/isp_color.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SOC_ISP_LSC_SUPPORTED)
|
||||||
|
list(APPEND srcs "src/isp_lsc.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(NOT ${target} STREQUAL "linux")
|
if(NOT ${target} STREQUAL "linux")
|
||||||
list(APPEND requires esp_mm)
|
list(APPEND requires esp_mm)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -22,3 +22,4 @@
|
|||||||
#include "driver/isp_hist.h"
|
#include "driver/isp_hist.h"
|
||||||
#include "driver/isp_sharpen.h"
|
#include "driver/isp_sharpen.h"
|
||||||
#include "driver/isp_color.h"
|
#include "driver/isp_color.h"
|
||||||
|
#include "driver/isp_lsc.h"
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "driver/isp_types.h"
|
#include "driver/isp_types.h"
|
||||||
|
#include "hal/color_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -30,6 +31,7 @@ typedef struct {
|
|||||||
bool has_line_end_packet; ///< Enable line end packet
|
bool has_line_end_packet; ///< Enable line end packet
|
||||||
uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line
|
uint32_t h_res; ///< Input horizontal resolution, i.e. the number of pixels in a line
|
||||||
uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame
|
uint32_t v_res; ///< Input vertical resolution, i.e. the number of lines in a frame
|
||||||
|
color_raw_element_order_t bayer_order; ///< Bayer order
|
||||||
int intr_priority; ///< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3)
|
int intr_priority; ///< The interrupt priority, range 0~3, if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3)
|
||||||
} esp_isp_processor_cfg_t;
|
} esp_isp_processor_cfg_t;
|
||||||
|
|
||||||
|
91
components/esp_driver_isp/include/driver/isp_lsc.h
Normal file
91
components/esp_driver_isp/include/driver/isp_lsc.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* 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 LSC Gain array
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
isp_lsc_gain_t *gain_r; ///< Gain for R channel
|
||||||
|
isp_lsc_gain_t *gain_gr; ///< Gain for GR channel
|
||||||
|
isp_lsc_gain_t *gain_gb; ///< Gain for GB channel
|
||||||
|
isp_lsc_gain_t *gain_b; ///< Gain for B channel
|
||||||
|
} esp_isp_lsc_gain_array_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISP LSC configurations
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
esp_isp_lsc_gain_array_t *gain_array; ///< Gain array
|
||||||
|
} esp_isp_lsc_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper function to allocate gain array for LSC
|
||||||
|
*
|
||||||
|
* @param[in] proc Processor handle
|
||||||
|
* @param[in] gain_array Gain array to be allocated
|
||||||
|
* @param[out] out_array_size_per_channel Array size
|
||||||
|
*
|
||||||
|
* @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_NO_MEM Out of memory
|
||||||
|
*/
|
||||||
|
esp_err_t esp_isp_lsc_allocate_gain_array(isp_proc_handle_t isp_proc, esp_isp_lsc_gain_array_t *gain_array, size_t *out_array_size_per_channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISP LSC configuration
|
||||||
|
*
|
||||||
|
* @note After calling this API, LSC doesn't take into effect until `esp_isp_lsc_enable` is called
|
||||||
|
*
|
||||||
|
* @param[in] proc Processor handle
|
||||||
|
* @param[in] config LSC configurations
|
||||||
|
*
|
||||||
|
* @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_NOT_SUPPORTED Not supported
|
||||||
|
*/
|
||||||
|
esp_err_t esp_isp_lsc_configure(isp_proc_handle_t isp_proc, const esp_isp_lsc_config_t *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable ISP LSC 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_lsc_enable(isp_proc_handle_t isp_proc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable ISP LSC 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_lsc_disable(isp_proc_handle_t isp_proc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -64,6 +64,7 @@ typedef struct isp_processor_t {
|
|||||||
color_space_pixel_format_t out_color_format;
|
color_space_pixel_format_t out_color_format;
|
||||||
uint32_t h_res;
|
uint32_t h_res;
|
||||||
uint32_t v_res;
|
uint32_t v_res;
|
||||||
|
color_raw_element_order_t bayer_order;
|
||||||
/* sub module contexts */
|
/* sub module contexts */
|
||||||
isp_af_ctlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS];
|
isp_af_ctlr_t af_ctlr[SOC_ISP_AF_CTLR_NUMS];
|
||||||
isp_awb_ctlr_t awb_ctlr;
|
isp_awb_ctlr_t awb_ctlr;
|
||||||
@@ -73,6 +74,7 @@ typedef struct isp_processor_t {
|
|||||||
isp_fsm_t demosaic_fsm;
|
isp_fsm_t demosaic_fsm;
|
||||||
isp_fsm_t sharpen_fsm;
|
isp_fsm_t sharpen_fsm;
|
||||||
isp_fsm_t color_fsm;
|
isp_fsm_t color_fsm;
|
||||||
|
isp_fsm_t lsc_fsm;
|
||||||
esp_isp_evt_cbs_t cbs;
|
esp_isp_evt_cbs_t cbs;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
|
|
||||||
|
@@ -139,6 +139,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_
|
|||||||
isp_ll_enable_line_end_packet_exist(proc->hal.hw, proc_config->has_line_end_packet);
|
isp_ll_enable_line_end_packet_exist(proc->hal.hw, proc_config->has_line_end_packet);
|
||||||
isp_ll_set_intput_data_h_pixel_num(proc->hal.hw, proc_config->h_res);
|
isp_ll_set_intput_data_h_pixel_num(proc->hal.hw, proc_config->h_res);
|
||||||
isp_ll_set_intput_data_v_row_num(proc->hal.hw, proc_config->v_res);
|
isp_ll_set_intput_data_v_row_num(proc->hal.hw, proc_config->v_res);
|
||||||
|
isp_ll_set_bayer_mode(proc->hal.hw, proc_config->bayer_order);
|
||||||
isp_ll_yuv_set_std(proc->hal.hw, proc_config->yuv_std);
|
isp_ll_yuv_set_std(proc->hal.hw, proc_config->yuv_std);
|
||||||
if (out_color_format.color_space == COLOR_SPACE_YUV) {
|
if (out_color_format.color_space == COLOR_SPACE_YUV) {
|
||||||
isp_ll_yuv_set_range(proc->hal.hw, proc_config->yuv_range);
|
isp_ll_yuv_set_range(proc->hal.hw, proc_config->yuv_range);
|
||||||
@@ -148,6 +149,7 @@ esp_err_t esp_isp_new_processor(const esp_isp_processor_cfg_t *proc_config, isp_
|
|||||||
proc->out_color_format = out_color_format;
|
proc->out_color_format = out_color_format;
|
||||||
proc->h_res = proc_config->h_res;
|
proc->h_res = proc_config->h_res;
|
||||||
proc->v_res = proc_config->v_res;
|
proc->v_res = proc_config->v_res;
|
||||||
|
proc->bayer_order = proc_config->bayer_order;
|
||||||
|
|
||||||
*ret_proc = proc;
|
*ret_proc = proc;
|
||||||
|
|
||||||
|
110
components/esp_driver_isp/src/isp_lsc.c
Normal file
110
components/esp_driver_isp/src/isp_lsc.c
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "driver/isp_core.h"
|
||||||
|
#include "driver/isp_bf.h"
|
||||||
|
#include "driver/isp_lsc.h"
|
||||||
|
#include "esp_private/isp_private.h"
|
||||||
|
#include "hal/efuse_hal.h"
|
||||||
|
#include "soc/chip_revision.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
LSC
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
#define ISP_LSC_GET_GRIDS(res) (((res) - 1) / 2 / ISP_LL_LSC_GRID_HEIGHT + 2)
|
||||||
|
|
||||||
|
static const char *TAG = "ISP_LSC";
|
||||||
|
|
||||||
|
esp_err_t esp_isp_lsc_allocate_gain_array(isp_proc_handle_t isp_proc, esp_isp_lsc_gain_array_t *gain_array, size_t *out_array_size_per_channel)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
ESP_RETURN_ON_FALSE(isp_proc->lsc_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "lsc is enabled already");
|
||||||
|
|
||||||
|
int num_grids_x_max = ISP_LSC_GET_GRIDS(ISP_LL_HSIZE_MAX);
|
||||||
|
int num_grids_y_max = ISP_LSC_GET_GRIDS(ISP_LL_VSIZE_MAX);
|
||||||
|
int num_grids_x = ISP_LSC_GET_GRIDS(isp_proc->h_res);
|
||||||
|
int num_grids_y = ISP_LSC_GET_GRIDS(isp_proc->v_res);
|
||||||
|
ESP_LOGD(TAG, "num_grids_x_max: %d, num_grids_x: %d, num_grids_y_max: %d, num_grids_y: %d", num_grids_x_max, num_grids_y_max, num_grids_x, num_grids_y);
|
||||||
|
ESP_RETURN_ON_FALSE(num_grids_x <= num_grids_x_max && num_grids_y <= num_grids_y_max, ESP_ERR_INVALID_ARG, TAG, "invalid h_res or v_res");
|
||||||
|
|
||||||
|
gain_array->gain_r = (isp_lsc_gain_t *)heap_caps_calloc(1, num_grids_x * num_grids_y * sizeof(isp_lsc_gain_t), ISP_MEM_ALLOC_CAPS);
|
||||||
|
gain_array->gain_gr = (isp_lsc_gain_t *)heap_caps_calloc(1, num_grids_x * num_grids_y * sizeof(isp_lsc_gain_t), ISP_MEM_ALLOC_CAPS);
|
||||||
|
gain_array->gain_gb = (isp_lsc_gain_t *)heap_caps_calloc(1, num_grids_x * num_grids_y * sizeof(isp_lsc_gain_t), ISP_MEM_ALLOC_CAPS);
|
||||||
|
gain_array->gain_b = (isp_lsc_gain_t *)heap_caps_calloc(1, num_grids_x * num_grids_y * sizeof(isp_lsc_gain_t), ISP_MEM_ALLOC_CAPS);
|
||||||
|
|
||||||
|
if (!gain_array->gain_r || !gain_array->gain_gr || !gain_array->gain_gb || !gain_array->gain_b) {
|
||||||
|
ESP_LOGE(TAG, "no enough mem for gain arrays");
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "gain_array->gain_r: %p, gain_array->gain_gr: %p, gain_array->gain_gb: %p, gain_array->gain_b: %p", gain_array->gain_r, gain_array->gain_gr, gain_array->gain_gb, gain_array->gain_b);
|
||||||
|
*out_array_size_per_channel = num_grids_x * num_grids_y;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_isp_lsc_configure(isp_proc_handle_t isp_proc, const esp_isp_lsc_config_t *config)
|
||||||
|
{
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
|
unsigned chip_version = efuse_hal_chip_revision();
|
||||||
|
if (!ESP_CHIP_REV_ABOVE(chip_version, 100)) {
|
||||||
|
ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "LSC is not supported on ESP32P4 chips prior than ECO2");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
|
||||||
|
|
||||||
|
int num_grids_x_max = ISP_LSC_GET_GRIDS(ISP_LL_HSIZE_MAX);
|
||||||
|
int num_grids_y_max = ISP_LSC_GET_GRIDS(ISP_LL_VSIZE_MAX);
|
||||||
|
int num_grids_x = ISP_LSC_GET_GRIDS(isp_proc->h_res);
|
||||||
|
int num_grids_y = ISP_LSC_GET_GRIDS(isp_proc->v_res);
|
||||||
|
ESP_LOGD(TAG, "num_grids_x_max: %d, num_grids_x: %d, num_grids_y_max: %d, num_grids_y: %d", num_grids_x_max, num_grids_y_max, num_grids_x, num_grids_y);
|
||||||
|
ESP_RETURN_ON_FALSE(num_grids_x <= num_grids_x_max && num_grids_y <= num_grids_y_max, ESP_ERR_INVALID_ARG, TAG, "invalid h_res or v_res");
|
||||||
|
ESP_RETURN_ON_FALSE(config->gain_array->gain_r && config->gain_array->gain_gr && config->gain_array->gain_gb && config->gain_array->gain_b, ESP_ERR_INVALID_ARG, TAG, "null pointer to gain arrays");
|
||||||
|
|
||||||
|
isp_ll_lsc_set_xtablesize(isp_proc->hal.hw, num_grids_x);
|
||||||
|
|
||||||
|
for (int y = 0; y < num_grids_y; y++) {
|
||||||
|
for (int x = 0; x < num_grids_x; x++) {
|
||||||
|
int i = y * num_grids_x + x;
|
||||||
|
isp_ll_lut_set_wdata_r_gr(isp_proc->hal.hw, config->gain_array->gain_r[i], config->gain_array->gain_gr[i]);
|
||||||
|
isp_ll_lut_set_cmd(isp_proc->hal.hw, true, false, i, ISP_LL_LUT_LSC);
|
||||||
|
isp_ll_lut_set_wdata_gb_b(isp_proc->hal.hw, config->gain_array->gain_gb[i], config->gain_array->gain_b[i]);
|
||||||
|
isp_ll_lut_set_cmd(isp_proc->hal.hw, true, true, i, ISP_LL_LUT_LSC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_isp_lsc_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->lsc_fsm == ISP_FSM_INIT, ESP_ERR_INVALID_STATE, TAG, "lsc is enabled already");
|
||||||
|
|
||||||
|
isp_ll_lsc_clk_enable(isp_proc->hal.hw, true);
|
||||||
|
isp_ll_lsc_enable(isp_proc->hal.hw, true);
|
||||||
|
isp_proc->lsc_fsm = ISP_FSM_ENABLE;
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_isp_lsc_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->lsc_fsm == ISP_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "lsc isn't enabled yet");
|
||||||
|
|
||||||
|
isp_ll_lsc_enable(isp_proc->hal.hw, false);
|
||||||
|
isp_ll_lsc_clk_enable(isp_proc->hal.hw, false);
|
||||||
|
isp_proc->lsc_fsm = ISP_FSM_INIT;
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
@@ -24,6 +24,9 @@ extern "C" {
|
|||||||
|
|
||||||
#define ISP_LL_GET_HW(num) (((num) == 0) ? (&ISP) : NULL)
|
#define ISP_LL_GET_HW(num) (((num) == 0) ? (&ISP) : NULL)
|
||||||
|
|
||||||
|
#define ISP_LL_HSIZE_MAX 1920
|
||||||
|
#define ISP_LL_VSIZE_MAX 1080
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
Clock
|
Clock
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
@@ -81,6 +84,14 @@ extern "C" {
|
|||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
#define ISP_LL_AE_WINDOW_MAX_RANGE ((1<<12) - 1)
|
#define ISP_LL_AE_WINDOW_MAX_RANGE ((1<<12) - 1)
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
AWB
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
#define ISP_LL_AWB_WINDOW_MAX_RANGE ((1<<12) - 1)
|
||||||
|
#define ISP_LL_AWB_LUM_MAX_RANGE ((1<<10) - 1)
|
||||||
|
#define ISP_LL_AWB_RGB_RATIO_INT_BITS (2)
|
||||||
|
#define ISP_LL_AWB_RGB_RATIO_FRAC_BITS (8)
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
BF
|
BF
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
@@ -103,20 +114,10 @@ extern "C" {
|
|||||||
#define ISP_LL_COLOR_BRIGNTNESS_MAX 127
|
#define ISP_LL_COLOR_BRIGNTNESS_MAX 127
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
AWB
|
LSC
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
#define ISP_LL_AWB_WINDOW_MAX_RANGE ((1<<12) - 1)
|
#define ISP_LL_LSC_GRID_HEIGHT 32
|
||||||
#define ISP_LL_AWB_LUM_MAX_RANGE ((1<<10) - 1)
|
#define ISP_LL_LSC_GRID_WIDTH 32
|
||||||
#define ISP_LL_AWB_RGB_RATIO_INT_BITS (2)
|
|
||||||
#define ISP_LL_AWB_RGB_RATIO_FRAC_BITS (8)
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
struct {
|
|
||||||
uint32_t fraction: ISP_LL_AWB_RGB_RATIO_FRAC_BITS;
|
|
||||||
uint32_t integer: ISP_LL_AWB_RGB_RATIO_INT_BITS;
|
|
||||||
};
|
|
||||||
uint32_t val;
|
|
||||||
} isp_ll_awb_rgb_ratio_t;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
CCM
|
CCM
|
||||||
@@ -150,6 +151,22 @@ typedef enum {
|
|||||||
ISP_LL_AF_EDGE_DETECTOR_MODE_MANUAL, ///< Manual set threshold
|
ISP_LL_AF_EDGE_DETECTOR_MODE_MANUAL, ///< Manual set threshold
|
||||||
} isp_ll_af_edge_detector_mode_t;
|
} isp_ll_af_edge_detector_mode_t;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint32_t fraction: ISP_LL_AWB_RGB_RATIO_FRAC_BITS;
|
||||||
|
uint32_t integer: ISP_LL_AWB_RGB_RATIO_INT_BITS;
|
||||||
|
};
|
||||||
|
uint32_t val;
|
||||||
|
} isp_ll_awb_rgb_ratio_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISP LUT
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ISP_LL_LUT_LSC, ///< LUT for LSC
|
||||||
|
ISP_LL_LUT_DPC, ///< LUT for DPC
|
||||||
|
} isp_ll_lut_t;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
Clock
|
Clock
|
||||||
@@ -463,6 +480,17 @@ static inline bool isp_ll_is_rgb2yuv_enabled(isp_dev_t *hw)
|
|||||||
return hw->cntl.rgb2yuv_en;
|
return hw->cntl.rgb2yuv_en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set bayer mode
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] bayer_order Bayer order
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_set_bayer_mode(isp_dev_t *hw, color_raw_element_order_t bayer_order)
|
||||||
|
{
|
||||||
|
hw->frame_cfg.bayer_mode = bayer_order;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
AF
|
AF
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
@@ -1153,6 +1181,88 @@ static inline void isp_ll_ae_env_detector_set_period(isp_dev_t *hw, uint32_t per
|
|||||||
hw->ae_monitor.ae_monitor_period = period;
|
hw->ae_monitor.ae_monitor_period = period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
LSC
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief Enable / Disable LSC clock
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] enable Enable / Disable
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_lsc_clk_enable(isp_dev_t *hw, bool enable)
|
||||||
|
{
|
||||||
|
hw->clk_en.clk_lsc_force_on = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable / Disable Color
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] enable Enable / Disable
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_lsc_enable(isp_dev_t *hw, bool enable)
|
||||||
|
{
|
||||||
|
hw->cntl.lsc_en = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set xtable size
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] xtablesize xtablesize
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_lsc_set_xtablesize(isp_dev_t *hw, uint8_t xtablesize)
|
||||||
|
{
|
||||||
|
hw->lsc_tablesize.lsc_xtablesize = xtablesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
LUT
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief Select ISP LUT
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] is_write Is write or not
|
||||||
|
* @param[in] is_gb_b Is gb_b or not
|
||||||
|
* @param[in] addr LUT addr
|
||||||
|
* @param[in] lut ISP LUT
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_lut_set_cmd(isp_dev_t *hw, bool is_write, bool is_gb_b, uint32_t addr, isp_ll_lut_t lut)
|
||||||
|
{
|
||||||
|
uint32_t val = 0;
|
||||||
|
val |= is_write ? (1 << 16) : 0;
|
||||||
|
val |= is_gb_b ? 0 : (1 << 10);
|
||||||
|
val |= addr & ((1 << 10) - 1);
|
||||||
|
val |= lut << 12;
|
||||||
|
hw->lut_cmd.val = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lut gb and b gain
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] gb_gain gb gain
|
||||||
|
* @param[in] b_gain b gain
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_lut_set_wdata_gb_b(isp_dev_t *hw, isp_lsc_gain_t gb_gain, isp_lsc_gain_t b_gain)
|
||||||
|
{
|
||||||
|
hw->lut_wdata.lut_wdata = (gb_gain.val & 0x3ff) << 10 | (b_gain.val & 0x3ff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lut r and gr gain
|
||||||
|
*
|
||||||
|
* @param[in] hw Hardware instance address
|
||||||
|
* @param[in] r_gain r gain
|
||||||
|
* @param[in] gr_gain gr gain
|
||||||
|
*/
|
||||||
|
static inline void isp_ll_lut_set_wdata_r_gr(isp_dev_t *hw, isp_lsc_gain_t r_gain, isp_lsc_gain_t gr_gain)
|
||||||
|
{
|
||||||
|
hw->lut_wdata.lut_wdata = (r_gain.val & 0x3ff) << 10 | (gr_gain.val & 0x3ff);
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
INTR
|
INTR
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
|
@@ -141,6 +141,15 @@ typedef enum {
|
|||||||
/*---------------------------------------------------------------
|
/*---------------------------------------------------------------
|
||||||
Color Endian
|
Color Endian
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief RAW element order
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
COLOR_RAW_ELEMENT_ORDER_BGGR, ///< BGGR order
|
||||||
|
COLOR_RAW_ELEMENT_ORDER_GBRG, ///< GBRG order
|
||||||
|
COLOR_RAW_ELEMENT_ORDER_GRBG, ///< GRBG order
|
||||||
|
COLOR_RAW_ELEMENT_ORDER_RGGB, ///< RGGB order
|
||||||
|
} color_raw_element_order_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief RGB element order
|
* @brief RGB element order
|
||||||
|
@@ -393,6 +393,31 @@ typedef union {
|
|||||||
uint32_t val; ///< 32-bit color saturation value
|
uint32_t val; ///< 32-bit color saturation value
|
||||||
} isp_color_saturation_t;
|
} isp_color_saturation_t;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
LSC
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
#if SOC_ISP_LSC_SUPPORTED
|
||||||
|
#define ISP_LSC_GRAD_RATIO_INT_BITS SOC_ISP_LSC_GRAD_RATIO_INT_BITS
|
||||||
|
#define ISP_LSC_GRAD_RATIO_DEC_BITS SOC_ISP_LSC_GRAD_RATIO_DEC_BITS
|
||||||
|
#define ISP_LSC_GRAD_RATIO_RES_BITS SOC_ISP_LSC_GRAD_RATIO_RES_BITS
|
||||||
|
#else
|
||||||
|
#define ISP_LSC_GRAD_RATIO_INT_BITS 2
|
||||||
|
#define ISP_LSC_GRAD_RATIO_DEC_BITS 8
|
||||||
|
#define ISP_LSC_GRAD_RATIO_RES_BITS 22
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LSC gain
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint32_t decimal:8; ///< Integer part
|
||||||
|
uint32_t integer:2; ///< Decimal part
|
||||||
|
uint32_t reserved:ISP_LSC_GRAD_RATIO_RES_BITS; ///< Reserved
|
||||||
|
};
|
||||||
|
uint32_t val; ///< 32-bit gradient ratio value
|
||||||
|
} isp_lsc_gain_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -887,6 +887,10 @@ config SOC_ISP_COLOR_SUPPORTED
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_ISP_LSC_SUPPORTED
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_ISP_SHARE_CSI_BRG
|
config SOC_ISP_SHARE_CSI_BRG
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
@@ -999,6 +1003,18 @@ config SOC_ISP_HIST_INTERVAL_NUMS
|
|||||||
int
|
int
|
||||||
default 15
|
default 15
|
||||||
|
|
||||||
|
config SOC_ISP_LSC_GRAD_RATIO_INT_BITS
|
||||||
|
int
|
||||||
|
default 2
|
||||||
|
|
||||||
|
config SOC_ISP_LSC_GRAD_RATIO_DEC_BITS
|
||||||
|
int
|
||||||
|
default 8
|
||||||
|
|
||||||
|
config SOC_ISP_LSC_GRAD_RATIO_RES_BITS
|
||||||
|
int
|
||||||
|
default 22
|
||||||
|
|
||||||
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@@ -342,6 +342,7 @@
|
|||||||
#define SOC_ISP_DVP_SUPPORTED 1
|
#define SOC_ISP_DVP_SUPPORTED 1
|
||||||
#define SOC_ISP_SHARPEN_SUPPORTED 1
|
#define SOC_ISP_SHARPEN_SUPPORTED 1
|
||||||
#define SOC_ISP_COLOR_SUPPORTED 1
|
#define SOC_ISP_COLOR_SUPPORTED 1
|
||||||
|
#define SOC_ISP_LSC_SUPPORTED 1
|
||||||
#define SOC_ISP_SHARE_CSI_BRG 1
|
#define SOC_ISP_SHARE_CSI_BRG 1
|
||||||
|
|
||||||
#define SOC_ISP_NUMS 1U
|
#define SOC_ISP_NUMS 1U
|
||||||
@@ -371,6 +372,9 @@
|
|||||||
#define SOC_ISP_HIST_BLOCK_Y_NUMS 5
|
#define SOC_ISP_HIST_BLOCK_Y_NUMS 5
|
||||||
#define SOC_ISP_HIST_SEGMENT_NUMS 16
|
#define SOC_ISP_HIST_SEGMENT_NUMS 16
|
||||||
#define SOC_ISP_HIST_INTERVAL_NUMS 15
|
#define SOC_ISP_HIST_INTERVAL_NUMS 15
|
||||||
|
#define SOC_ISP_LSC_GRAD_RATIO_INT_BITS 2
|
||||||
|
#define SOC_ISP_LSC_GRAD_RATIO_DEC_BITS 8
|
||||||
|
#define SOC_ISP_LSC_GRAD_RATIO_RES_BITS 22
|
||||||
|
|
||||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||||
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
||||||
|
@@ -13,7 +13,7 @@ menu "Example DSI Configuration"
|
|||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
choice EXAMPLE_MIPI_DSI_DISP_HRES
|
choice EXAMPLE_MIPI_DSI_DISP_HRES
|
||||||
bool "Set MIPI CSI horizontal resolution"
|
bool "Set MIPI DSI horizontal resolution"
|
||||||
default EXAMPLE_MIPI_DSI_DISP_HRES_800 if EXAMPLE_LCD_PATTERN_ILI9881C
|
default EXAMPLE_MIPI_DSI_DISP_HRES_800 if EXAMPLE_LCD_PATTERN_ILI9881C
|
||||||
default EXAMPLE_MIPI_DSI_DISP_HRES_1024 if EXAMPLE_LCD_PATTERN_EK79007
|
default EXAMPLE_MIPI_DSI_DISP_HRES_1024 if EXAMPLE_LCD_PATTERN_EK79007
|
||||||
default EXAMPLE_MIPI_DSI_DISP_HRES_800
|
default EXAMPLE_MIPI_DSI_DISP_HRES_800
|
||||||
@@ -30,7 +30,7 @@ menu "Example DSI Configuration"
|
|||||||
default 1024 if EXAMPLE_MIPI_DSI_DISP_HRES_1024
|
default 1024 if EXAMPLE_MIPI_DSI_DISP_HRES_1024
|
||||||
|
|
||||||
choice EXAMPLE_MIPI_DSI_DISP_VRES
|
choice EXAMPLE_MIPI_DSI_DISP_VRES
|
||||||
bool "Set MIPI CSI vertical resolution"
|
bool "Set MIPI DSI vertical resolution"
|
||||||
default EXAMPLE_MIPI_DSI_DISP_VRES_1280 if EXAMPLE_LCD_PATTERN_ILI9881C
|
default EXAMPLE_MIPI_DSI_DISP_VRES_1280 if EXAMPLE_LCD_PATTERN_ILI9881C
|
||||||
default EXAMPLE_MIPI_DSI_DISP_VRES_600 if EXAMPLE_LCD_PATTERN_EK79007
|
default EXAMPLE_MIPI_DSI_DISP_VRES_600 if EXAMPLE_LCD_PATTERN_EK79007
|
||||||
default EXAMPLE_MIPI_DSI_DISP_VRES_1280
|
default EXAMPLE_MIPI_DSI_DISP_VRES_1280
|
||||||
|
@@ -14,6 +14,7 @@ This example demonstrates how to use the ISP (image signal processor) to work wi
|
|||||||
- ISP Demosaic feature
|
- ISP Demosaic feature
|
||||||
- ISP GAMMA feature
|
- ISP GAMMA feature
|
||||||
- ISP Color feature
|
- ISP Color feature
|
||||||
|
- ISP LSC feature
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@@ -347,6 +347,28 @@ void app_main(void)
|
|||||||
ESP_ERROR_CHECK(esp_isp_color_configure(isp_proc, &color_config));
|
ESP_ERROR_CHECK(esp_isp_color_configure(isp_proc, &color_config));
|
||||||
ESP_ERROR_CHECK(esp_isp_color_enable(isp_proc));
|
ESP_ERROR_CHECK(esp_isp_color_enable(isp_proc));
|
||||||
|
|
||||||
|
#if CONFIG_ESP32P4_REV_MIN_FULL >= 100
|
||||||
|
esp_isp_lsc_gain_array_t gain_array = {};
|
||||||
|
esp_isp_lsc_config_t lsc_config = {
|
||||||
|
.gain_array = &gain_array,
|
||||||
|
};
|
||||||
|
size_t gain_size = 0;
|
||||||
|
ESP_ERROR_CHECK(esp_isp_lsc_allocate_gain_array(isp_proc, &gain_array, &gain_size));
|
||||||
|
|
||||||
|
isp_lsc_gain_t gain_val = {
|
||||||
|
.decimal = 204,
|
||||||
|
.integer = 0,
|
||||||
|
};
|
||||||
|
for (int i = 0; i < gain_size; i++) {
|
||||||
|
gain_array.gain_r[i].val = gain_val.val;
|
||||||
|
gain_array.gain_gr[i].val = gain_val.val;
|
||||||
|
gain_array.gain_gb[i].val = gain_val.val;
|
||||||
|
gain_array.gain_b[i].val = gain_val.val;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(esp_isp_lsc_configure(isp_proc, &lsc_config));
|
||||||
|
ESP_ERROR_CHECK(esp_isp_lsc_enable(isp_proc));
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct af_task_param_t {
|
typedef struct af_task_param_t {
|
||||||
isp_proc_handle_t isp_proc;
|
isp_proc_handle_t isp_proc;
|
||||||
esp_sccb_io_handle_t dw9714_io_handle;
|
esp_sccb_io_handle_t dw9714_io_handle;
|
||||||
|
Reference in New Issue
Block a user