mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(isp): isp af submodule low level driver
This commit is contained in:
parent
7c21207bd3
commit
97526e9288
@ -83,6 +83,10 @@ if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "i2c_hal.c" "i2c_hal_iram.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ISP_SUPPORTED)
|
||||
list(APPEND srcs "isp_hal.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_RMT_SUPPORTED)
|
||||
list(APPEND srcs "rmt_hal.c")
|
||||
endif()
|
||||
|
724
components/hal/esp32p4/include/hal/isp_ll.h
Normal file
724
components/hal/esp32p4/include/hal/isp_ll.h
Normal file
@ -0,0 +1,724 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "esp_attr.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/isp_types.h"
|
||||
#include "hal/color_space_types.h"
|
||||
#include "soc/isp_struct.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define ISP_LL_GET_HW(num) (((num) == 0) ? (&ISP) : NULL)
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
INTR
|
||||
---------------------------------------------------------------*/
|
||||
#define ISP_LL_EVENT_DATA_TYPE_ERR (1<<0)
|
||||
#define ISP_LL_EVENT_ASYNC_FIFO_OVF (1<<1)
|
||||
#define ISP_LL_EVENT_BUF_FULL (1<<2)
|
||||
#define ISP_LL_EVENT_HVNUM_SETTING_ERR (1<<3)
|
||||
#define ISP_LL_EVENT_DATA_TYPE_SETTING_ERR (1<<4)
|
||||
#define ISP_LL_EVENT_MIPI_HNUM_UNMATCH (1<<5)
|
||||
#define ISP_LL_EVENT_DPC_CHECK_DONE (1<<6)
|
||||
#define ISP_LL_EVENT_GAMMA_XCOORD_ERR (1<<7)
|
||||
#define ISP_LL_EVENT_AE_MONITOR (1<<8)
|
||||
#define ISP_LL_EVENT_AE_FRAME_DONE (1<<9)
|
||||
#define ISP_LL_EVENT_AF_FDONE (1<<10)
|
||||
#define ISP_LL_EVENT_AF_ENV (1<<11)
|
||||
#define ISP_LL_EVENT_AWB_FDONE (1<<12)
|
||||
#define ISP_LL_EVENT_HIST_FDONE (1<<13)
|
||||
#define ISP_LL_EVENT_FRAME (1<<14)
|
||||
#define ISP_LL_EVENT_BLC_FRAME (1<<15)
|
||||
#define ISP_LL_EVENT_LSC_FRAME (1<<16)
|
||||
#define ISP_LL_EVENT_DPC_FRAME (1<<17)
|
||||
#define ISP_LL_EVENT_BF_FRAME (1<<18)
|
||||
#define ISP_LL_EVENT_DEMOSAIC_FRAME (1<<19)
|
||||
#define ISP_LL_EVENT_MEDIAN_FRAME (1<<20)
|
||||
#define ISP_LL_EVENT_CCM_FRAME (1<<21)
|
||||
#define ISP_LL_EVENT_GAMMA_FRAME (1<<22)
|
||||
#define ISP_LL_EVENT_RGB2YUV_FRAME (1<<23)
|
||||
#define ISP_LL_EVENT_SHARP_FRAME (1<<24)
|
||||
#define ISP_LL_EVENT_COLOR_FRAME (1<<25)
|
||||
#define ISP_LL_EVENT_YUV2RGB_FRAME (1<<26)
|
||||
#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)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AF
|
||||
---------------------------------------------------------------*/
|
||||
#define ISP_LL_AF_WINDOW_MAX_RANGE ((1<<12) - 1)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Env monitor mode
|
||||
*/
|
||||
typedef enum {
|
||||
ISP_LL_AF_ENV_MONITOR_MODE_ABS, ///< Use absolute val for threshold
|
||||
ISP_LL_AF_ENV_MONITOR_MODE_RATIO, ///< Use ratio val for threshold
|
||||
} isp_ll_af_env_monitor_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Edge monitor mode
|
||||
*/
|
||||
typedef enum {
|
||||
ISP_LL_AF_EDGE_MONITOR_MODE_AUTO, ///< Auto set threshold
|
||||
ISP_LL_AF_EDGE_MONITOR_MODE_MANUAL, ///< Manual set threshold
|
||||
} isp_ll_af_edge_monitor_mode_t;
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Clock
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable the bus clock for ISP module
|
||||
*
|
||||
* @param hw hardware instance address
|
||||
* @param en enable / disable
|
||||
*/
|
||||
static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_isp_clk_en = en;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define isp_ll_enable_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_enable_module_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Reset the ISP module
|
||||
*
|
||||
* @param hw hardware instance address
|
||||
*/
|
||||
static inline void isp_ll_reset_module_clock(isp_dev_t *hw)
|
||||
{
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_isp = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_isp = 0;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define isp_ll_reset_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_reset_module_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Select ISP clock source
|
||||
*
|
||||
* @param hw hardware instance address
|
||||
* @param clk_src clock source, see valid sources in type `soc_periph_isp_clk_src_t`
|
||||
*/
|
||||
static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_src_t clk_src)
|
||||
{
|
||||
uint32_t clk_val = 0;
|
||||
switch (clk_src) {
|
||||
case ISP_CLK_SRC_XTAL:
|
||||
clk_val = 0;
|
||||
break;
|
||||
case ISP_CLK_SRC_PLL160:
|
||||
clk_val = 1;
|
||||
break;
|
||||
case ISP_CLK_SRC_PLL240:
|
||||
clk_val = 2;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
HP_SYS_CLKRST.peri_clk_ctrl25.reg_isp_clk_src_sel = clk_val;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define isp_ll_select_clk_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_select_clk_source(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Set ISP clock div
|
||||
*
|
||||
* @param hw hardware instance address
|
||||
* @param div divider value
|
||||
*/
|
||||
static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div)
|
||||
{
|
||||
HP_SYS_CLKRST.peri_clk_ctrl26.reg_isp_clk_div_num = div;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define isp_ll_set_clock_div(...) (void)__DECLARE_RCC_ATOMIC_ENV; isp_ll_set_clock_div(__VA_ARGS__)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Misc
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Init ISP
|
||||
*
|
||||
* @param[in] hw
|
||||
*/
|
||||
static inline void isp_ll_init(isp_dev_t *hw)
|
||||
{
|
||||
hw->cntl.val = 0;
|
||||
hw->int_clr.val = ISP_LL_EVENT_ALL_MASK;
|
||||
hw->int_ena.val = ~ISP_LL_EVENT_ALL_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable ISP clock
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->clk_en.clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable ISP
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->cntl.isp_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set input data source
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] source input data source, see `isp_input_data_source_t`
|
||||
*/
|
||||
static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_source_t source)
|
||||
{
|
||||
switch (source) {
|
||||
case ISP_INPUT_DATA_SOURCE_CSI:
|
||||
hw->cntl.isp_in_src = 0;
|
||||
hw->cntl.mipi_data_en = 1;
|
||||
break;
|
||||
case ISP_INPUT_DATA_SOURCE_CAM:
|
||||
hw->cntl.isp_in_src = 1;
|
||||
hw->cntl.mipi_data_en = 0;
|
||||
break;
|
||||
case ISP_INPUT_DATA_SOURCE_DMA:
|
||||
hw->cntl.isp_in_src = 2;
|
||||
hw->cntl.mipi_data_en = 0;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set input data format
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] format data format, see `color_space_pixel_format_t`
|
||||
*/
|
||||
static inline void isp_ll_set_input_data_format(isp_dev_t *hw, color_space_pixel_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case COLOR_SPACE_RAW8:
|
||||
hw->cntl.isp_data_type = 0;
|
||||
break;
|
||||
case COLOR_SPACE_RAW10:
|
||||
hw->cntl.isp_data_type = 1;
|
||||
break;
|
||||
case COLOR_SPACE_RAW12:
|
||||
hw->cntl.isp_data_type = 2;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set input data horizontal pixel number
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] pixel_num number of pixels
|
||||
*/
|
||||
static inline void isp_ll_set_intput_data_h_pixel_num(isp_dev_t *hw, uint32_t pixel_num)
|
||||
{
|
||||
hw->frame_cfg.hadr_num = pixel_num - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set input data vertical row number
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] row_num number of rows
|
||||
*/
|
||||
static inline void isp_ll_set_intput_data_v_row_num(isp_dev_t *hw, uint32_t row_num)
|
||||
{
|
||||
hw->frame_cfg.vadr_num = row_num - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set output data format
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] format data format, see `color_space_pixel_format_t`
|
||||
*/
|
||||
static inline void isp_ll_set_output_data_format(isp_dev_t *hw, color_space_pixel_format_t format)
|
||||
{
|
||||
switch (format) {
|
||||
case COLOR_SPACE_RAW8:
|
||||
hw->cntl.isp_out_type = 0;
|
||||
hw->cntl.demosaic_en = 0;
|
||||
hw->cntl.rgb2yuv_en = 0;
|
||||
hw->cntl.yuv2rgb_en = 0;
|
||||
break;
|
||||
case COLOR_SPACE_YUV422:
|
||||
hw->cntl.isp_out_type = 1;
|
||||
hw->cntl.demosaic_en = 1;
|
||||
hw->cntl.rgb2yuv_en = 1;
|
||||
hw->cntl.yuv2rgb_en = 0;
|
||||
break;
|
||||
case COLOR_SPACE_RGB888:
|
||||
hw->cntl.isp_out_type = 2;
|
||||
hw->cntl.demosaic_en = 1;
|
||||
hw->cntl.rgb2yuv_en = 1;
|
||||
hw->cntl.yuv2rgb_en = 1;
|
||||
break;
|
||||
case COLOR_SPACE_YUV420:
|
||||
hw->cntl.isp_out_type = 3;
|
||||
hw->cntl.demosaic_en = 1;
|
||||
hw->cntl.rgb2yuv_en = 1;
|
||||
hw->cntl.yuv2rgb_en = 0;
|
||||
break;
|
||||
case COLOR_SPACE_RGB565:
|
||||
hw->cntl.isp_out_type = 4;
|
||||
hw->cntl.demosaic_en = 1;
|
||||
hw->cntl.rgb2yuv_en = 1;
|
||||
hw->cntl.yuv2rgb_en = 1;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set if line start packet exists
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] en Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en)
|
||||
{
|
||||
hw->frame_cfg.hsync_start_exist = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set if line end packet exists
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] en Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en)
|
||||
{
|
||||
hw->frame_cfg.hsync_end_exist = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get if demosaic is enabled
|
||||
*
|
||||
* @return True: enabled
|
||||
*/
|
||||
static inline bool isp_ll_get_demosaic_en(isp_dev_t *hw)
|
||||
{
|
||||
return hw->cntl.demosaic_en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get if rgb2yuv is enabled
|
||||
*
|
||||
* @return True: enabled
|
||||
*/
|
||||
static inline bool isp_ll_get_rgb2yuv_en(isp_dev_t *hw)
|
||||
{
|
||||
return hw->cntl.rgb2yuv_en;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AF
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable / Disable AF clock
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_af_clk_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->clk_en.clk_af_force_on = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable AF
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_af_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->cntl.af_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable auto aupdate AF
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_af_enable_auto_update(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->af_ctrl0.af_auto_update = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Manual aupdate AF once
|
||||
*
|
||||
* @param[in] hw
|
||||
*/
|
||||
static inline void isp_ll_af_manual_update(isp_dev_t *hw)
|
||||
{
|
||||
//self clear
|
||||
hw->af_ctrl0.af_manual_update = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set edge thresh mode
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] mode See `isp_ll_af_edge_monitor_mode_t`
|
||||
*/
|
||||
static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_monitor_mode_t mode)
|
||||
{
|
||||
if (mode == ISP_LL_AF_EDGE_MONITOR_MODE_AUTO) {
|
||||
hw->af_threshold.af_threshold = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set edge threshold
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] thresh Edge threshold
|
||||
*/
|
||||
static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh)
|
||||
{
|
||||
HAL_ASSERT(thresh != 0);
|
||||
|
||||
hw->af_threshold.af_threshold = thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set auto edge thresh pixel num
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] pixel_num Pixel numbers
|
||||
*/
|
||||
static inline void isp_ll_af_set_auto_edge_thresh_pixel_num(isp_dev_t *hw, uint32_t pixel_num)
|
||||
{
|
||||
HAL_ASSERT(hw->af_threshold.af_threshold == 0);
|
||||
|
||||
hw->af_ctrl1.af_thpixnum = pixel_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set window range
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] window_id Window ID
|
||||
* @param[in] top_left_x Top left pixel x axis value
|
||||
* @param[in] top_left_y Top left pixel y axis value
|
||||
* @param[in] bottom_right_x Bottom right pixel x axis value
|
||||
* @param[in] bottom_right_y Bottom right pixel y axis value
|
||||
*/
|
||||
static inline void isp_ll_af_set_window_range(isp_dev_t *hw, uint32_t window_id, uint32_t top_left_x, uint32_t top_left_y, uint32_t bottom_right_x, uint32_t bottom_right_y)
|
||||
{
|
||||
HAL_ASSERT(top_left_x < ISP_LL_AF_WINDOW_MAX_RANGE &&
|
||||
top_left_y < ISP_LL_AF_WINDOW_MAX_RANGE &&
|
||||
bottom_right_x < ISP_LL_AF_WINDOW_MAX_RANGE &&
|
||||
bottom_right_y < ISP_LL_AF_WINDOW_MAX_RANGE);
|
||||
|
||||
switch (window_id) {
|
||||
case 0:
|
||||
hw->af_hscale_a.af_lpoint_a = top_left_x;
|
||||
hw->af_vscale_a.af_tpoint_a = top_left_y;
|
||||
hw->af_hscale_a.af_rpoint_a = bottom_right_x;
|
||||
hw->af_vscale_a.af_bpoint_a = bottom_right_y;
|
||||
break;
|
||||
case 1:
|
||||
hw->af_hscale_b.af_lpoint_b = top_left_x;
|
||||
hw->af_vscale_b.af_tpoint_b = top_left_y;
|
||||
hw->af_hscale_b.af_rpoint_b = bottom_right_x;
|
||||
hw->af_vscale_b.af_bpoint_b = bottom_right_y;
|
||||
break;
|
||||
case 2:
|
||||
hw->af_hscale_c.af_lpoint_c = top_left_x;
|
||||
hw->af_vscale_c.af_tpoint_c = top_left_y;
|
||||
hw->af_hscale_c.af_rpoint_c = bottom_right_x;
|
||||
hw->af_vscale_c.af_bpoint_c = bottom_right_y;
|
||||
break;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get window sum
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] window_id Window ID
|
||||
*
|
||||
* @return Window sum
|
||||
*/
|
||||
static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_id)
|
||||
{
|
||||
switch (window_id) {
|
||||
case 0:
|
||||
return hw->af_sum_a.af_suma;
|
||||
case 1:
|
||||
return hw->af_sum_b.af_sumb;
|
||||
case 2:
|
||||
return hw->af_sum_c.af_sumc;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get window lum
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] window_id Window ID
|
||||
*
|
||||
* @return Window lum
|
||||
*/
|
||||
static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_id)
|
||||
{
|
||||
switch (window_id) {
|
||||
case 0:
|
||||
return hw->af_lum_a.af_luma;
|
||||
case 1:
|
||||
return hw->af_lum_b.af_lumb;
|
||||
case 2:
|
||||
return hw->af_lum_c.af_lumc;
|
||||
default:
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------
|
||||
AF Env Monitor
|
||||
----------------------------------------------*/
|
||||
/**
|
||||
* @brief Set env monitor period
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] period period of the env monitor, in frames
|
||||
*/
|
||||
static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t period)
|
||||
{
|
||||
hw->af_ctrl0.af_env_period = period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set env monitor mode
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] mode See `isp_ll_af_env_monitor_mode_t`
|
||||
*/
|
||||
static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_monitor_mode_t mode)
|
||||
{
|
||||
if (mode == ISP_LL_AF_ENV_MONITOR_MODE_RATIO) {
|
||||
hw->af_env_user_th_sum.af_env_user_threshold_sum = 0x0;
|
||||
hw->af_env_user_th_lum.af_env_user_threshold_lum = 0x0;
|
||||
}
|
||||
|
||||
//nothing to do to if using abs mode, it'll be enabled after `isp_ll_af_env_monitor_set_thresh()`
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set env monitor threshold
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] sum_thresh Threshold for definition
|
||||
* @param[in] lum_thresh Threshold for luminance
|
||||
*/
|
||||
static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_thresh, uint32_t lum_thresh)
|
||||
{
|
||||
HAL_ASSERT(sum_thresh != 0 || lum_thresh != 0);
|
||||
|
||||
hw->af_env_user_th_sum.af_env_user_threshold_sum = sum_thresh;
|
||||
hw->af_env_user_th_lum.af_env_user_threshold_lum = lum_thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set env monitor ratio
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] ratio_val Threshold for ratio
|
||||
*/
|
||||
static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio_val)
|
||||
{
|
||||
HAL_ASSERT(hw->af_env_user_th_sum.af_env_user_threshold_sum == 0 &&
|
||||
hw->af_env_user_th_lum.af_env_user_threshold_lum == 0);
|
||||
|
||||
hw->af_ctrl0.af_env_threshold = ratio_val;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
BF
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable / Disable BF clock
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->clk_en.clk_bf_force_on = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable BF
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->cntl.bf_en = enable;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CCM
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable / Disable CCM clock
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->clk_en.clk_ccm_force_on = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable CCM
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->cntl.ccm_en = enable;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Color
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable / Disable Color clock
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->clk_en.clk_color_force_on = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable / Disable Color
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] enable Enable / Disable
|
||||
*/
|
||||
static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->cntl.color_en = enable;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
INTR
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable / Disable interrupt
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] mask INTR mask
|
||||
* @param[in] enable Enable / disable
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void isp_ll_enable_intr(isp_dev_t *hw, uint32_t mask, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
hw->int_ena.val |= mask;
|
||||
} else {
|
||||
hw->int_ena.val &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt status
|
||||
*
|
||||
* @param[in] hw
|
||||
*
|
||||
* @return Interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t isp_ll_get_intr_status(isp_dev_t *hw)
|
||||
{
|
||||
return hw->int_st.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt raw
|
||||
*
|
||||
* @param[in] hw
|
||||
*
|
||||
* @return Interrupt raw
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t isp_ll_get_intr_raw(isp_dev_t *hw)
|
||||
{
|
||||
return hw->int_raw.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt
|
||||
*
|
||||
* @param[in] hw
|
||||
* @param[in] mask INTR mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void isp_ll_clear_intr(isp_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->int_clr.val = mask;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
31
components/hal/include/hal/color_space_types.h
Normal file
31
components/hal/include/hal/color_space_types.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enumeration of pixel color space format
|
||||
*/
|
||||
typedef enum {
|
||||
COLOR_SPACE_RAW8, /*!< 8 bits per pixel */
|
||||
COLOR_SPACE_RAW10, /*!< 10 bits per pixel */
|
||||
COLOR_SPACE_RAW12, /*!< 12 bits per pixel */
|
||||
COLOR_SPACE_RGB888, /*!< 24 bits, 8 bits per R/G/B value */
|
||||
COLOR_SPACE_RGB565, /*!< 16 bits, 5 bits per R/B value, 6 bits for G value */
|
||||
COLOR_SPACE_YUV422, /*!< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels */
|
||||
COLOR_SPACE_YUV420, /*!< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels */
|
||||
} color_space_pixel_format_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
75
components/hal/include/hal/isp_hal.h
Normal file
75
components/hal/include/hal/isp_hal.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hal/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Context that should be maintained by both the driver and the HAL
|
||||
*/
|
||||
typedef struct {
|
||||
void *hw; ///< Beginning address of the ISP registers
|
||||
} isp_hal_context_t;
|
||||
|
||||
/**
|
||||
* @brief Init the ISP hal and set the ISP to the default configuration.
|
||||
*
|
||||
* @note This function should be called first before other hal layer function is called.
|
||||
*
|
||||
* @param[in] hal Context of the HAL layer
|
||||
* @param[in] isp_id ISP ID
|
||||
*/
|
||||
void isp_hal_init(isp_hal_context_t *hal, int isp_id);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AF
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Configure AF window
|
||||
*
|
||||
* @param[in] hal Context of the HAL layer
|
||||
* @param[in] window_id Window ID
|
||||
* @param[in] window Window info, see `isp_af_window_t`
|
||||
*/
|
||||
void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_af_window_t *window);
|
||||
|
||||
/**
|
||||
* @brief Get AF oneshot result
|
||||
*
|
||||
* @param[in] hal Context of the HAL layer
|
||||
* @param[out] out_res AF result
|
||||
*/
|
||||
void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res);
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
INTR
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Clear ISP HW intr event
|
||||
*
|
||||
* @param[in] hal Context of the HAL layer
|
||||
* @param[in] mask HW event mask
|
||||
*/
|
||||
uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
62
components/hal/include/hal/isp_types.h
Normal file
62
components/hal/include/hal/isp_types.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
Misc
|
||||
---------------------------------------------------------------*/
|
||||
#if SOC_ISP_SUPPORTED
|
||||
typedef soc_periph_isp_clk_src_t isp_clk_src_t; ///< Clock source type of ISP
|
||||
#else
|
||||
typedef int isp_clk_src_t; ///< Default type
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ISP Input Source
|
||||
*/
|
||||
typedef enum {
|
||||
ISP_INPUT_DATA_SOURCE_CSI, ///< Input data from CSI
|
||||
ISP_INPUT_DATA_SOURCE_CAM, ///< Input data from CAM
|
||||
ISP_INPUT_DATA_SOURCE_DWDMA, ///< Input data from DW-DMA
|
||||
} isp_input_data_source_t;
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AF
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ISP AF window
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t top_left_x; ///< Top left x axis value
|
||||
uint32_t top_left_y; ///< Top left y axis value
|
||||
uint32_t bottom_right_x; ///< Bottom right x axis value
|
||||
uint32_t bottom_right_y; ///< Bottom right y axis value
|
||||
} isp_af_window_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief ISP AF result
|
||||
*/
|
||||
typedef struct {
|
||||
#if SOC_ISP_SUPPORTED
|
||||
uint32_t definition[SOC_ISP_AF_WINDOW_NUMS]; ///< Definition
|
||||
uint32_t luminance[SOC_ISP_AF_WINDOW_NUMS]; ///< Luminance
|
||||
#endif
|
||||
} isp_af_result_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
62
components/hal/isp_hal.c
Normal file
62
components/hal/isp_hal.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sys/param.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"
|
||||
|
||||
/**
|
||||
* ISP HAL layer
|
||||
*/
|
||||
void isp_hal_init(isp_hal_context_t *hal, int isp_id)
|
||||
{
|
||||
//ISP hardware instance
|
||||
hal->hw = ISP_LL_GET_HW(isp_id);
|
||||
isp_ll_init(hal->hw);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
AF
|
||||
---------------------------------------------------------------*/
|
||||
void isp_hal_af_window_config(const isp_hal_context_t *hal, int window_id, const isp_af_window_t *window)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void isp_hal_af_get_oneshot_result(const isp_hal_context_t *hal, isp_af_result_t *out_res)
|
||||
{
|
||||
isp_ll_clear_intr(hal->hw, ISP_LL_EVENT_AF_FDONE);
|
||||
isp_ll_af_manual_update(hal->hw);
|
||||
|
||||
while (!(isp_ll_get_intr_raw(hal->hw) & ISP_LL_EVENT_AF_FDONE)) {
|
||||
;
|
||||
}
|
||||
|
||||
for (int i = 0; i < SOC_ISP_AF_WINDOW_NUMS; i++) {
|
||||
out_res->definition[i] = isp_ll_af_get_window_sum(hal->hw, i);
|
||||
out_res->luminance[i] = isp_ll_af_get_window_lum(hal->hw, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
INTR, put in iram
|
||||
---------------------------------------------------------------*/
|
||||
uint32_t isp_hal_check_clear_intr_event(const isp_hal_context_t *hal, uint32_t mask)
|
||||
{
|
||||
uint32_t triggered_events = isp_ll_get_intr_status(hal->hw) & mask;
|
||||
|
||||
if (triggered_events) {
|
||||
isp_ll_clear_intr(hal->hw, triggered_events);
|
||||
}
|
||||
|
||||
return triggered_events;
|
||||
}
|
@ -555,6 +555,22 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_ISP_NUMS
|
||||
int
|
||||
default 1
|
||||
|
||||
config SOC_ISP_AF_CTRLR_NUMS
|
||||
int
|
||||
default 1
|
||||
|
||||
config SOC_ISP_AF_ENV_DETECTOR_NUMS
|
||||
int
|
||||
default 1
|
||||
|
||||
config SOC_ISP_AF_WINDOW_NUMS
|
||||
int
|
||||
default 3
|
||||
|
||||
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||
bool
|
||||
default y
|
||||
|
@ -443,6 +443,23 @@ typedef enum {
|
||||
FLASH_CLK_SRC_SPLL = SOC_MOD_CLK_SPLL, /*!< Select SOC_MOD_CLK_SPLL as FLASH source clock */
|
||||
} soc_periph_flash_clk_src_t;
|
||||
|
||||
/////////////////////////////////////////////////ISP////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Array initializer for all supported clock sources of ISP
|
||||
*/
|
||||
#define SOC_ISP_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_PLL_F240M}
|
||||
|
||||
/**
|
||||
* @brief Type of ISP clock source.
|
||||
*/
|
||||
typedef enum {
|
||||
ISP_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select SOC_MOD_CLK_PLL_F160M as ISP source clock */
|
||||
ISP_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select SOC_MOD_CLK_XTAL as ISP source clock */
|
||||
ISP_CLK_SRC_PLL160 = SOC_MOD_CLK_PLL_F160M, /*!< Select SOC_MOD_CLK_PLL_F160M as ISP source clock */
|
||||
ISP_CLK_SRC_PLL240 = SOC_MOD_CLK_PLL_F240M, /*!< Select SOC_MOD_CLK_PLL_F240M as ISP source clock */
|
||||
} soc_periph_isp_clk_src_t;
|
||||
|
||||
//////////////////////////////////////////////////SDM//////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////GPIO Glitch Filter////////////////////////////////////////////////////
|
||||
|
@ -247,11 +247,11 @@ typedef union {
|
||||
*/
|
||||
uint32_t bayer_mode:2;
|
||||
/** hsync_start_exist : R/W; bitpos: [29]; default: 1;
|
||||
* this bit configures the line end packet exist or not. 0: not exist, 1: exist
|
||||
* this bit configures the line end start exist or not. 0: not exist, 1: exist
|
||||
*/
|
||||
uint32_t hsync_start_exist:1;
|
||||
/** hsync_end_exist : R/W; bitpos: [30]; default: 1;
|
||||
* this bit configures the line start packet exist or not. 0: not exist, 1: exist
|
||||
* this bit configures the line end packet exist or not. 0: not exist, 1: exist
|
||||
*/
|
||||
uint32_t hsync_end_exist:1;
|
||||
uint32_t reserved_31:1;
|
||||
@ -3857,6 +3857,7 @@ typedef struct {
|
||||
volatile isp_rdn_eco_high_reg_t rdn_eco_high;
|
||||
} isp_dev_t;
|
||||
|
||||
extern isp_dev_t ISP;
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(isp_dev_t) == 0x244, "Invalid size of isp_dev_t structure");
|
||||
|
@ -267,6 +267,12 @@
|
||||
#define SOC_I2S_PDM_MAX_RX_LINES (4) // On I2S0
|
||||
#define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */
|
||||
|
||||
/*-------------------------- ISP CAPS ----------------------------------------*/
|
||||
#define SOC_ISP_NUMS 1U
|
||||
#define SOC_ISP_AF_CTRLR_NUMS 1U
|
||||
#define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U
|
||||
#define SOC_ISP_AF_WINDOW_NUMS 3
|
||||
|
||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
||||
#define SOC_LEDC_SUPPORT_XTAL_CLOCK (1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user