From 97526e92887527b5d7516d334eacba7d162ed35c Mon Sep 17 00:00:00 2001 From: Armando Date: Tue, 17 Oct 2023 18:54:13 +0800 Subject: [PATCH 1/3] feat(isp): isp af submodule low level driver --- components/hal/CMakeLists.txt | 4 + components/hal/esp32p4/include/hal/isp_ll.h | 724 ++++++++++++++++++ .../hal/include/hal/color_space_types.h | 31 + components/hal/include/hal/isp_hal.h | 75 ++ components/hal/include/hal/isp_types.h | 62 ++ components/hal/isp_hal.c | 62 ++ .../esp32p4/include/soc/Kconfig.soc_caps.in | 16 + .../soc/esp32p4/include/soc/clk_tree_defs.h | 17 + .../soc/esp32p4/include/soc/isp_struct.h | 5 +- components/soc/esp32p4/include/soc/soc_caps.h | 6 + 10 files changed, 1000 insertions(+), 2 deletions(-) create mode 100644 components/hal/esp32p4/include/hal/isp_ll.h create mode 100644 components/hal/include/hal/color_space_types.h create mode 100644 components/hal/include/hal/isp_hal.h create mode 100644 components/hal/include/hal/isp_types.h create mode 100644 components/hal/isp_hal.c diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index eb41bb2dcd5..58698a72195 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -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() diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h new file mode 100644 index 00000000000..33499ec5c44 --- /dev/null +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -0,0 +1,724 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include +#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 diff --git a/components/hal/include/hal/color_space_types.h b/components/hal/include/hal/color_space_types.h new file mode 100644 index 00000000000..9ed088c7063 --- /dev/null +++ b/components/hal/include/hal/color_space_types.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#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 diff --git a/components/hal/include/hal/isp_hal.h b/components/hal/include/hal/isp_hal.h new file mode 100644 index 00000000000..80ea6db9de5 --- /dev/null +++ b/components/hal/include/hal/isp_hal.h @@ -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 +#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 diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h new file mode 100644 index 00000000000..65c7cb483e2 --- /dev/null +++ b/components/hal/include/hal/isp_types.h @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#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 diff --git a/components/hal/isp_hal.c b/components/hal/isp_hal.c new file mode 100644 index 00000000000..6fb72413a99 --- /dev/null +++ b/components/hal/isp_hal.c @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#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" + +/** + * 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; +} diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index e980bda57a2..a46faeba120 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -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 diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index c218ff496e3..90f56146d0b 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -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//////////////////////////////////////////////////// diff --git a/components/soc/esp32p4/include/soc/isp_struct.h b/components/soc/esp32p4/include/soc/isp_struct.h index acb3c4a465f..980103687bf 100644 --- a/components/soc/esp32p4/include/soc/isp_struct.h +++ b/components/soc/esp32p4/include/soc/isp_struct.h @@ -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"); diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 7e03ccbbb84..4a1615b5f47 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -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) From 7efcf06c5d4f1d568260e9b27467c209281862f8 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 26 Oct 2023 11:17:13 +0800 Subject: [PATCH 2/3] change(ll): update color space types, ll changes --- components/hal/esp32p4/include/hal/isp_ll.h | 228 ++++++++++-------- .../hal/include/hal/color_space_types.h | 31 --- components/hal/include/hal/color_types.h | 92 +++++++ components/hal/include/hal/isp_types.h | 26 +- .../esp32p4/include/soc/Kconfig.soc_caps.in | 2 +- components/soc/esp32p4/include/soc/soc_caps.h | 2 +- 6 files changed, 246 insertions(+), 135 deletions(-) delete mode 100644 components/hal/include/hal/color_space_types.h create mode 100644 components/hal/include/hal/color_types.h diff --git a/components/hal/esp32p4/include/hal/isp_ll.h b/components/hal/esp32p4/include/hal/isp_ll.h index 33499ec5c44..96633369b2d 100644 --- a/components/hal/esp32p4/include/hal/isp_ll.h +++ b/components/hal/esp32p4/include/hal/isp_ll.h @@ -11,7 +11,7 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/isp_types.h" -#include "hal/color_space_types.h" +#include "hal/color_types.h" #include "soc/isp_struct.h" #include "soc/hp_sys_clkrst_struct.h" #include "soc/clk_tree_defs.h" @@ -89,7 +89,7 @@ typedef enum { /** * @brief Enable the bus clock for ISP module * - * @param hw hardware instance address + * @param hw Hardware instance address * @param en enable / disable */ static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en) @@ -104,7 +104,7 @@ static inline void isp_ll_enable_module_clock(isp_dev_t *hw, bool en) /** * @brief Reset the ISP module * - * @param hw hardware instance address + * @param hw Hardware instance address */ static inline void isp_ll_reset_module_clock(isp_dev_t *hw) { @@ -119,7 +119,7 @@ static inline void isp_ll_reset_module_clock(isp_dev_t *hw) /** * @brief Select ISP clock source * - * @param hw hardware instance address + * @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) @@ -150,7 +150,7 @@ static inline void isp_ll_select_clk_source(isp_dev_t *hw, soc_periph_isp_clk_sr /** * @brief Set ISP clock div * - * @param hw hardware instance address + * @param hw Hardware instance address * @param div divider value */ static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div) @@ -168,7 +168,7 @@ static inline void isp_ll_set_clock_div(isp_dev_t *hw, uint32_t div) /** * @brief Init ISP * - * @param[in] hw + * @param[in] hw Hardware instance address */ static inline void isp_ll_init(isp_dev_t *hw) { @@ -180,7 +180,7 @@ static inline void isp_ll_init(isp_dev_t *hw) /** * @brief Enable / Disable ISP clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable) @@ -191,7 +191,7 @@ static inline void isp_ll_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable ISP * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_enable(isp_dev_t *hw, bool enable) @@ -202,7 +202,7 @@ static inline void isp_ll_enable(isp_dev_t *hw, bool enable) /** * @brief Set input data source * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -212,11 +212,11 @@ static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_so hw->cntl.isp_in_src = 0; hw->cntl.mipi_data_en = 1; break; - case ISP_INPUT_DATA_SOURCE_CAM: + case ISP_INPUT_DATA_SOURCE_DVP: hw->cntl.isp_in_src = 1; hw->cntl.mipi_data_en = 0; break; - case ISP_INPUT_DATA_SOURCE_DMA: + case ISP_INPUT_DATA_SOURCE_DWGDMA: hw->cntl.isp_in_src = 2; hw->cntl.mipi_data_en = 0; break; @@ -226,32 +226,43 @@ static inline void isp_ll_set_input_data_source(isp_dev_t *hw, isp_input_data_so } /** - * @brief Set input data format + * @brief Set input data color format * - * @param[in] hw - * @param[in] format data format, see `color_space_pixel_format_t` + * @param[in] hw Hardware instance address + * @param[in] format color format, see `color_space_pixel_format_t` + * + * @return true for valid format, false for invalid format */ -static inline void isp_ll_set_input_data_format(isp_dev_t *hw, color_space_pixel_format_t format) +static inline bool isp_ll_set_input_data_color_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); + bool valid = false; + + if (format.color_space == COLOR_SPACE_RAW) { + switch(format.pixel_format) { + case COLOR_PIXEL_RAW8: + hw->cntl.isp_data_type = 0; + valid = true; + break; + case COLOR_PIXEL_RAW10: + hw->cntl.isp_data_type = 1; + valid = true; + break; + case COLOR_PIXEL_RAW12: + hw->cntl.isp_data_type = 2; + valid = true; + break; + default: + break; + } } + + return valid; } /** * @brief Set input data horizontal pixel number * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -262,7 +273,7 @@ static inline void isp_ll_set_intput_data_h_pixel_num(isp_dev_t *hw, uint32_t pi /** * @brief Set input data vertical row number * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -271,53 +282,76 @@ static inline void isp_ll_set_intput_data_v_row_num(isp_dev_t *hw, uint32_t row_ } /** - * @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 output data color format + * + * @param[in] hw Hardware instance address + * @param[in] format color format, see `color_space_pixel_format_t` + * + * @return true for valid format, false for invalid format + */ +static inline bool isp_ll_set_output_data_color_format(isp_dev_t *hw, color_space_pixel_format_t format) +{ + bool valid = false; + + if (format.color_space == COLOR_SPACE_RAW) { + switch(format.pixel_format) { + case COLOR_PIXEL_RAW8: + hw->cntl.isp_out_type = 0; + hw->cntl.demosaic_en = 0; + hw->cntl.rgb2yuv_en = 0; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + default: + break; + } + } else if (format.color_space == COLOR_SPACE_RGB) { + switch(format.pixel_format) { + case COLOR_PIXEL_RGB888: + hw->cntl.isp_out_type = 2; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + valid = true; + break; + case COLOR_PIXEL_RGB565: + hw->cntl.isp_out_type = 4; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 1; + valid = true; + break; + default: + break; + } + } else if (format.color_space == COLOR_SPACE_YUV) { + switch(format.pixel_format) { + case COLOR_PIXEL_YUV422: + hw->cntl.isp_out_type = 1; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + case COLOR_PIXEL_YUV420: + hw->cntl.isp_out_type = 3; + hw->cntl.demosaic_en = 1; + hw->cntl.rgb2yuv_en = 1; + hw->cntl.yuv2rgb_en = 0; + valid = true; + break; + default: + break; + } } + + return valid; } /** * @brief Set if line start packet exists * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] en Enable / Disable */ static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en) @@ -328,7 +362,7 @@ static inline void isp_ll_enable_line_start_packet_exist(isp_dev_t *hw, bool en) /** * @brief Set if line end packet exists * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] en Enable / Disable */ static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) @@ -339,9 +373,11 @@ static inline void isp_ll_enable_line_end_packet_exist(isp_dev_t *hw, bool en) /** * @brief Get if demosaic is enabled * + * @param[in] hw Hardware instance address + * * @return True: enabled */ -static inline bool isp_ll_get_demosaic_en(isp_dev_t *hw) +static inline bool isp_ll_is_demosaic_enabled(isp_dev_t *hw) { return hw->cntl.demosaic_en; } @@ -349,9 +385,11 @@ static inline bool isp_ll_get_demosaic_en(isp_dev_t *hw) /** * @brief Get if rgb2yuv is enabled * + * @param[in] hw Hardware instance address + * * @return True: enabled */ -static inline bool isp_ll_get_rgb2yuv_en(isp_dev_t *hw) +static inline bool isp_ll_is_rgb2yuv_enabled(isp_dev_t *hw) { return hw->cntl.rgb2yuv_en; } @@ -373,7 +411,7 @@ static inline void isp_ll_af_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable AF * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_af_enable(isp_dev_t *hw, bool enable) @@ -395,7 +433,7 @@ static inline void isp_ll_af_enable_auto_update(isp_dev_t *hw, bool enable) /** * @brief Manual aupdate AF once * - * @param[in] hw + * @param[in] hw Hardware instance address */ static inline void isp_ll_af_manual_update(isp_dev_t *hw) { @@ -406,7 +444,7 @@ static inline void isp_ll_af_manual_update(isp_dev_t *hw) /** * @brief Set edge thresh mode * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -419,7 +457,7 @@ static inline void isp_ll_af_set_edge_thresh_mode(isp_dev_t *hw, isp_ll_af_edge_ /** * @brief Set edge threshold * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] thresh Edge threshold */ static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh) @@ -432,7 +470,7 @@ static inline void isp_ll_af_set_edge_thresh(isp_dev_t *hw, uint32_t thresh) /** * @brief Set auto edge thresh pixel num * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -445,7 +483,7 @@ static inline void isp_ll_af_set_auto_edge_thresh_pixel_num(isp_dev_t *hw, uint3 /** * @brief Set window range * - * @param[in] hw + * @param[in] hw Hardware instance address * @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 @@ -486,7 +524,7 @@ static inline void isp_ll_af_set_window_range(isp_dev_t *hw, uint32_t window_id, /** * @brief Get window sum * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] window_id Window ID * * @return Window sum @@ -508,7 +546,7 @@ static inline uint32_t isp_ll_af_get_window_sum(isp_dev_t *hw, uint32_t window_i /** * @brief Get window lum * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] window_id Window ID * * @return Window lum @@ -533,7 +571,7 @@ static inline uint32_t isp_ll_af_get_window_lum(isp_dev_t *hw, uint32_t window_i /** * @brief Set env monitor period * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -544,7 +582,7 @@ static inline void isp_ll_af_env_monitor_set_period(isp_dev_t *hw, uint32_t peri /** * @brief Set env monitor mode * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -560,7 +598,7 @@ static inline void isp_ll_af_env_monitor_set_mode(isp_dev_t *hw, isp_ll_af_env_m /** * @brief Set env monitor threshold * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] sum_thresh Threshold for definition * @param[in] lum_thresh Threshold for luminance */ @@ -575,7 +613,7 @@ static inline void isp_ll_af_env_monitor_set_thresh(isp_dev_t *hw, uint32_t sum_ /** * @brief Set env monitor ratio * - * @param[in] hw + * @param[in] hw Hardware instance address * @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) @@ -592,7 +630,7 @@ static inline void isp_ll_af_env_monitor_set_ratio(isp_dev_t *hw, uint32_t ratio /** * @brief Enable / Disable BF clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable) @@ -603,7 +641,7 @@ static inline void isp_ll_bf_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable BF * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) @@ -617,7 +655,7 @@ static inline void isp_ll_bf_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable CCM clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable) @@ -628,7 +666,7 @@ static inline void isp_ll_ccm_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable CCM * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) @@ -642,7 +680,7 @@ static inline void isp_ll_ccm_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable Color clock * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable) @@ -653,7 +691,7 @@ static inline void isp_ll_color_clk_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable Color * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] enable Enable / Disable */ static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) @@ -667,7 +705,7 @@ static inline void isp_ll_color_enable(isp_dev_t *hw, bool enable) /** * @brief Enable / Disable interrupt * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] mask INTR mask * @param[in] enable Enable / disable */ @@ -684,7 +722,7 @@ static inline void isp_ll_enable_intr(isp_dev_t *hw, uint32_t mask, bool enable) /** * @brief Get interrupt status * - * @param[in] hw + * @param[in] hw Hardware instance address * * @return Interrupt status */ @@ -697,7 +735,7 @@ static inline uint32_t isp_ll_get_intr_status(isp_dev_t *hw) /** * @brief Get interrupt raw * - * @param[in] hw + * @param[in] hw Hardware instance address * * @return Interrupt raw */ @@ -710,7 +748,7 @@ static inline uint32_t isp_ll_get_intr_raw(isp_dev_t *hw) /** * @brief Clear interrupt * - * @param[in] hw + * @param[in] hw Hardware instance address * @param[in] mask INTR mask */ __attribute__((always_inline)) diff --git a/components/hal/include/hal/color_space_types.h b/components/hal/include/hal/color_space_types.h deleted file mode 100644 index 9ed088c7063..00000000000 --- a/components/hal/include/hal/color_space_types.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include -#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 diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h new file mode 100644 index 00000000000..e213216fb5e --- /dev/null +++ b/components/hal/include/hal/color_types.h @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @background + * + * Color Space: a specific representation of colors, e.g. RGB, YUV, etc. + * Color Pixel Format: a specific pixel format of a certain color space, e.g. RGB565, YUV422, etc. + */ + +/*--------------------------------------------------------------- + Color Space +---------------------------------------------------------------*/ +/** + * @brief Color Space + */ +typedef enum { + COLOR_SPACE_RAW, ///< Color space raw + COLOR_SPACE_RGB, ///< Color space rgb + COLOR_SPACE_YUV, ///< Color space yuv + COLOR_SPACE_GRAY, ///< Color space gray +} color_space_t; + +/*--------------------------------------------------------------- + Color Space Format +---------------------------------------------------------------*/ +/** + * @brief Raw Format + */ +typedef enum { + COLOR_PIXEL_RAW8, ///< 8 bits per pixel + COLOR_PIXEL_RAW10, ///< 10 bits per pixel + COLOR_PIXEL_RAW12, ///< 12 bits per pixel +} color_pixel_raw_format_t; + +/** + * @brief RGB Format + */ +typedef enum { + COLOR_PIXEL_RGB888, ///< 24 bits, 8 bits per R/G/B value + COLOR_PIXEL_RGB565, ///< 16 bits, 5 bits per R/B value, 6 bits for G value +} color_pixel_rgb_format_t; + +/** + * @brief YUV Format + */ +typedef enum { + COLOR_PIXEL_YUV444, ///< 24 bits, 8 bits per Y/U/V value + COLOR_PIXEL_YUV422, ///< 16 bits, 8-bit Y per pixel, 8-bit U and V per two pixels + COLOR_PIXEL_YUV420, ///< 12 bits, 8-bit Y per pixel, 8-bit U and V per four pixels +} color_pixel_yuv_format_t; + +/** + * @brief Gray Format + */ +typedef enum { + COLOR_PIXEL_GRAY4, ///< 4 bits, grayscale + COLOR_PIXEL_GRAY8, ///< 8 bits, grayscale +} color_pixel_gray_format_t; + +/*--------------------------------------------------------------- + Color Space Struct Type +---------------------------------------------------------------*/ +#define COLOR_PIXEL_FORMAT_BITWIDTH 24 ///< Bitwidth of the `color_space_format_t:pixel_format` field +#define COLOR_SPACE_BITWIDTH 8 ///< Bitwidth of the `color_space_format_t:color_space` field + +/** + * @brief Color Space Info Structure + */ +typedef union { + struct { + uint32_t pixel_format: COLOR_PIXEL_FORMAT_BITWIDTH; ///< Format of a certain color space type + uint32_t color_space: COLOR_SPACE_BITWIDTH; ///< Color space type + }; + uint32_t color_type_id; ///< Unique type of a certain color pixel format +} color_space_pixel_format_t; + + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/isp_types.h b/components/hal/include/hal/isp_types.h index 65c7cb483e2..27d7e0bc129 100644 --- a/components/hal/include/hal/isp_types.h +++ b/components/hal/include/hal/isp_types.h @@ -6,9 +6,9 @@ #pragma once -#include #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" +#include "hal/color_types.h" #ifdef __cplusplus extern "C" { @@ -27,11 +27,24 @@ typedef int isp_clk_src_t; ///< Default type * @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_CSI, ///< Input data from CSI + ISP_INPUT_DATA_SOURCE_DVP, ///< Input data from DVP + ISP_INPUT_DATA_SOURCE_DWGDMA, ///< Input data from DW-GDMA } isp_input_data_source_t; +/** + * @brief ISP Color Type + */ +typedef enum { + ISP_COLOR_RAW8 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW8, ///< RAW8 + ISP_COLOR_RAW10 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW10, ///< RAW10 + ISP_COLOR_RAW12 = (COLOR_SPACE_RAW << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RAW12, ///< RAW12 + ISP_COLOR_RGB888 = (COLOR_SPACE_RGB << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RGB888, ///< RGB888 + ISP_COLOR_RGB565 = (COLOR_SPACE_RGB << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_RGB565, ///< RGB565 + ISP_COLOR_YUV422 = (COLOR_SPACE_YUV << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_YUV422, ///< YUV422 + ISP_COLOR_YUV420 = (COLOR_SPACE_YUV << COLOR_PIXEL_FORMAT_BITWIDTH) + COLOR_PIXEL_YUV420, ///< YUV420 +} isp_color_t; + /*--------------------------------------------------------------- AF ---------------------------------------------------------------*/ @@ -45,14 +58,13 @@ typedef struct { 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 + int definition[SOC_ISP_AF_WINDOW_NUMS]; ///< Definition, it refers how clear and sharp an image is + int luminance[SOC_ISP_AF_WINDOW_NUMS]; ///< Luminance, it refers how luminant an image is #endif } isp_af_result_t; diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index a46faeba120..ded76ad0fb9 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -559,7 +559,7 @@ config SOC_ISP_NUMS int default 1 -config SOC_ISP_AF_CTRLR_NUMS +config SOC_ISP_AF_CTLR_NUMS int default 1 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 4a1615b5f47..f351f934b84 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -269,7 +269,7 @@ /*-------------------------- ISP CAPS ----------------------------------------*/ #define SOC_ISP_NUMS 1U -#define SOC_ISP_AF_CTRLR_NUMS 1U +#define SOC_ISP_AF_CTLR_NUMS 1U #define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U #define SOC_ISP_AF_WINDOW_NUMS 3 From 16d8b7df41b4255cb7728d829d327334d628431a Mon Sep 17 00:00:00 2001 From: Armando Date: Mon, 30 Oct 2023 15:29:17 +0800 Subject: [PATCH 3/3] feat(color): added helper to get color space and color pixel format --- components/hal/include/hal/color_types.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/components/hal/include/hal/color_types.h b/components/hal/include/hal/color_types.h index e213216fb5e..5890da3f42a 100644 --- a/components/hal/include/hal/color_types.h +++ b/components/hal/include/hal/color_types.h @@ -72,8 +72,14 @@ typedef enum { /*--------------------------------------------------------------- Color Space Struct Type ---------------------------------------------------------------*/ -#define COLOR_PIXEL_FORMAT_BITWIDTH 24 ///< Bitwidth of the `color_space_format_t:pixel_format` field -#define COLOR_SPACE_BITWIDTH 8 ///< Bitwidth of the `color_space_format_t:color_space` field +///< Bitwidth of the `color_space_format_t:color_space` field +#define COLOR_SPACE_BITWIDTH 8 +///< Bitwidth of the `color_space_format_t:pixel_format` field +#define COLOR_PIXEL_FORMAT_BITWIDTH 24 +///< Helper to get `color_space_format_t:color_space` from its `color_space_pixel_format_t:color_type_id` +#define COLOR_SPACE_TYPE(color_type_id) (((color_type_id) >> COLOR_PIXEL_FORMAT_BITWIDTH) & ((1 << COLOR_SPACE_BITWIDTH) - 1)) +///< Helper to get `color_space_format_t:pixel_format` from its `color_space_pixel_format_t:color_type_id` +#define COLOR_PIXEL_FORMAT(color_type_id) ((color_type_id) & ((1 << COLOR_PIXEL_FORMAT_BITWIDTH) - 1)) /** * @brief Color Space Info Structure