mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
feat(csi): added csi driver
This commit is contained in:
committed by
Armando (Dou Yiwen)
parent
4c190c56e6
commit
f918079e8e
@@ -177,6 +177,10 @@ if(NOT BOOTLOADER_BUILD)
|
||||
list(APPEND srcs "mipi_dsi_hal.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_MIPI_CSI_SUPPORTED)
|
||||
list(APPEND srcs "mipi_csi_hal.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ECC_SUPPORTED)
|
||||
list(APPEND srcs "ecc_hal.c")
|
||||
endif()
|
||||
|
||||
@@ -377,7 +377,7 @@ static inline void dw_gdma_ll_channel_set_trans_block_size(dw_gdma_dev_t *dev, u
|
||||
__attribute__((always_inline))
|
||||
static inline void dw_gdma_ll_channel_set_src_master_port(dw_gdma_dev_t *dev, uint8_t channel, intptr_t mem_addr)
|
||||
{
|
||||
if (mem_addr == MIPI_CSI_MEM_BASE) {
|
||||
if (mem_addr == MIPI_CSI_BRG_MEM_BASE) {
|
||||
dev->ch[channel].ctl0.sms = DW_GDMA_LL_MASTER_PORT_MIPI_CSI;
|
||||
} else {
|
||||
dev->ch[channel].ctl0.sms = DW_GDMA_LL_MASTER_PORT_MEMORY;
|
||||
@@ -394,7 +394,7 @@ static inline void dw_gdma_ll_channel_set_src_master_port(dw_gdma_dev_t *dev, ui
|
||||
__attribute__((always_inline))
|
||||
static inline void dw_gdma_ll_channel_set_dst_master_port(dw_gdma_dev_t *dev, uint8_t channel, intptr_t mem_addr)
|
||||
{
|
||||
if (mem_addr == MIPI_DSI_MEM_BASE) {
|
||||
if (mem_addr == MIPI_DSI_BRG_MEM_BASE) {
|
||||
dev->ch[channel].ctl0.dms = DW_GDMA_LL_MASTER_PORT_MIPI_DSI;
|
||||
} else {
|
||||
dev->ch[channel].ctl0.dms = DW_GDMA_LL_MASTER_PORT_MEMORY;
|
||||
@@ -986,7 +986,7 @@ static inline void dw_gdma_ll_lli_set_dst_trans_width(dw_gdma_link_list_item_t *
|
||||
__attribute__((always_inline))
|
||||
static inline void dw_gdma_ll_lli_set_src_master_port(dw_gdma_link_list_item_t *lli, intptr_t mem_addr)
|
||||
{
|
||||
if (mem_addr == MIPI_CSI_MEM_BASE) {
|
||||
if (mem_addr == MIPI_CSI_BRG_MEM_BASE) {
|
||||
lli->ctrl_lo.sms = DW_GDMA_LL_MASTER_PORT_MIPI_CSI;
|
||||
} else {
|
||||
lli->ctrl_lo.sms = DW_GDMA_LL_MASTER_PORT_MEMORY;
|
||||
@@ -1002,7 +1002,7 @@ static inline void dw_gdma_ll_lli_set_src_master_port(dw_gdma_link_list_item_t *
|
||||
__attribute__((always_inline))
|
||||
static inline void dw_gdma_ll_lli_set_dst_master_port(dw_gdma_link_list_item_t *lli, intptr_t mem_addr)
|
||||
{
|
||||
if (mem_addr == MIPI_DSI_MEM_BASE) {
|
||||
if (mem_addr == MIPI_DSI_BRG_MEM_BASE) {
|
||||
lli->ctrl_lo.dms = DW_GDMA_LL_MASTER_PORT_MIPI_DSI;
|
||||
} else {
|
||||
lli->ctrl_lo.dms = DW_GDMA_LL_MASTER_PORT_MEMORY;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "hal/mipi_csi_types.h"
|
||||
#include "soc/mipi_csi_bridge_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -65,6 +66,74 @@ static inline void mipi_csi_brg_ll_set_intput_data_v_row_num(csi_brg_dev_t *dev,
|
||||
dev->frame_cfg.vadr_num = row_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the buffer almost full threshold for the MIPI CSI bridge
|
||||
*
|
||||
* @param dev Pointer to the CSI bridge controller register base address
|
||||
* @param afull_thrd full threshold
|
||||
*/
|
||||
static inline void mipi_csi_brg_ll_set_flow_ctl_buf_afull_thrd(csi_brg_dev_t *dev, size_t afull_thrd)
|
||||
{
|
||||
dev->buf_flow_ctl.csi_buf_afull_thrd = afull_thrd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the frame data whether contain hsync
|
||||
*
|
||||
* @param dev Pointer to the CSI bridge controller register base address
|
||||
* @param en 0: frame data doesn't contain hsync. 1: frame data contains hsync.
|
||||
*/
|
||||
static inline void mipi_csi_brg_ll_enable_has_hsync(csi_brg_dev_t *dev, bool en)
|
||||
{
|
||||
dev->frame_cfg.has_hsync_e = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the min value of data type used for pixel filter.
|
||||
*
|
||||
* @param dev Pointer to the CSI bridge controller register base address
|
||||
* @param type_min The min data type allowed by bridge's pixel filter.
|
||||
* The data type specifie the format and the content of the payload data.
|
||||
*/
|
||||
static inline void mipi_csi_brg_ll_set_data_type_min(csi_brg_dev_t *dev, uint16_t type_min)
|
||||
{
|
||||
dev->data_type_cfg.data_type_min = type_min;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the the max value of data type used for pixel filter.
|
||||
*
|
||||
* @param dev Pointer to the CSI bridge controller register base address
|
||||
* @param type_max The max data type allowed by bridge's pixel filter.
|
||||
* The data type specifie the format and the content of the payload data.
|
||||
*/
|
||||
static inline void mipi_csi_brg_ll_set_data_type_max(csi_brg_dev_t *dev, uint16_t type_max)
|
||||
{
|
||||
dev->data_type_cfg.data_type_max = type_max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the DMA interval configuration.
|
||||
*
|
||||
* @param dev Pointer to the CSI bridge controller register base address
|
||||
* @param interval 16'b1: 1 cycle. 16'b11: 2 cycle. ... ... 16'hFFFF: 16 cycle.
|
||||
*/
|
||||
static inline void mipi_csi_brg_ll_set_dma_req_interval(csi_brg_dev_t *dev, uint16_t interval)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->dma_req_interval, dma_req_interval, interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the data endianness order in bytes
|
||||
*
|
||||
* @param dev Pointer to the CSI bridge controller register base address
|
||||
* @param byte_swap_en byte swap enable or not
|
||||
*/
|
||||
static inline void mipi_csi_brg_ll_set_byte_endian(csi_brg_dev_t *dev, bool byte_swap_en)
|
||||
{
|
||||
dev->endian_mode.byte_endian_order = byte_swap_en;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/mipi_csi_host_struct.h"
|
||||
#include "hal/mipi_csi_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MIPI_CSI_HOST_LL_GET_HW(num) (((num) == 0) ? (&MIPI_CSI_HOST) : NULL)
|
||||
|
||||
#define MIPI_CSI_HOST_LL_LANE_NUM_MAX 2
|
||||
|
||||
/**
|
||||
* @brief Enable CSI host reset output
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void mipi_csi_host_ll_enable_reset_output(csi_host_dev_t *dev, bool en)
|
||||
{
|
||||
dev->csi2_resetn.csi2_resetn = !en; // host reset output, active low
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the MIPI CSI lane num
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param lanes_num Number of MIPI CSI lanes
|
||||
*/
|
||||
static inline void mipi_csi_host_ll_set_active_lanes_num(csi_host_dev_t *dev, int lanes_num)
|
||||
{
|
||||
dev->n_lanes.n_lanes = lanes_num - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the CSI virtual channel extension
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void mipi_csi_host_ll_enable_virtual_channel_extension(csi_host_dev_t *dev, bool en)
|
||||
{
|
||||
dev->vc_extension.vcx = !en; // 0 is enable
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the data de-scrambling on the controller side
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void mipi_csi_host_ll_enable_scrambling(csi_host_dev_t *dev, bool en)
|
||||
{
|
||||
dev->scrambling.scramble_enable = en;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -10,13 +10,18 @@
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "hal/mipi_csi_types.h"
|
||||
#include "hal/mipi_csi_brg_ll.h"
|
||||
#include "hal/mipi_csi_phy_ll.h"
|
||||
#include "hal/mipi_csi_host_ll.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MIPI_CSI_LL_HOST_CTLR_NUMS 1
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CSI Bridge
|
||||
---------------------------------------------------------------*/
|
||||
@@ -50,6 +55,88 @@ static inline void mipi_csi_ll_reset_brg_module_clock(int csi_bridge_id)
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define mipi_csi_ll_reset_brg_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_reset_brg_module_clock(__VA_ARGS__)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CSI PHY
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Set the clock source for the MIPI CSI D-PHY
|
||||
*
|
||||
* @param group_id Group ID
|
||||
* @param source Clock source
|
||||
*/
|
||||
static inline void mipi_csi_ll_set_phy_clock_source(int group_id, mipi_csi_phy_clock_source_t source)
|
||||
{
|
||||
(void)group_id;
|
||||
switch (source) {
|
||||
case MIPI_CSI_PHY_CLK_SRC_PLL_F20M:
|
||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_clk_src_sel = 0;
|
||||
break;
|
||||
case MIPI_CSI_PHY_CLK_SRC_RC_FAST:
|
||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_clk_src_sel = 1;
|
||||
break;
|
||||
case MIPI_CSI_PHY_CLK_SRC_PLL_F25M:
|
||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_clk_src_sel = 2;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 mipi_csi_ll_set_phy_clock_source(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_set_phy_clock_source(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Enable MIPI CSI PHY configuration clock
|
||||
*
|
||||
* @param group_id Group ID
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void mipi_csi_ll_enable_phy_config_clock(int group_id, bool en)
|
||||
{
|
||||
(void)group_id;
|
||||
HP_SYS_CLKRST.peri_clk_ctrl03.reg_mipi_csi_dphy_cfg_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 mipi_csi_ll_enable_phy_config_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_enable_phy_config_clock(__VA_ARGS__)
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
CSI Host
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enable the bus clock for MIPI CSI host
|
||||
*
|
||||
* @param group_id Group ID
|
||||
* @param en true to enable, false to disable
|
||||
*/
|
||||
static inline void mipi_csi_ll_enable_host_bus_clock(int group_id, bool en)
|
||||
{
|
||||
(void)group_id;
|
||||
HP_SYS_CLKRST.soc_clk_ctrl1.reg_csi_host_sys_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 mipi_csi_ll_enable_host_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_enable_host_bus_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Reset the MIPI CSI host CLK
|
||||
*
|
||||
* @param group_id Group ID
|
||||
*/
|
||||
static inline void mipi_csi_ll_reset_host_clock(int group_id)
|
||||
{
|
||||
(void)group_id;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_csi_host = 1;
|
||||
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_csi_host = 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 mipi_csi_ll_reset_host_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_reset_host_clock(__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/mipi_csi_host_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Control the internal interface (clock and pins) between the CSI Host and the d-PHY
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param clock_level Level of the clock
|
||||
* @param clear Whether to clear the pins of the PHY
|
||||
*/
|
||||
static inline void mipi_csi_phy_ll_write_clock(csi_host_dev_t *dev, uint32_t clock_level, bool clear)
|
||||
{
|
||||
dev->phy_test_ctrl0.val = clock_level << 1 | clear;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the PHY register via test interface
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param reg_addr Address of the PHY register
|
||||
*/
|
||||
static inline void mipi_csi_phy_ll_write_reg_addr(csi_host_dev_t *dev, uint8_t reg_addr)
|
||||
{
|
||||
dev->phy_test_ctrl1.val = (1 << 16) | (reg_addr & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the PHY register value via test interface
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param reg_val Value to write to the PHY register
|
||||
*/
|
||||
static inline void mipi_csi_phy_ll_write_reg_val(csi_host_dev_t *dev, uint8_t reg_val)
|
||||
{
|
||||
dev->phy_test_ctrl1.val = reg_val & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable dphy shutdown input
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void mipi_csi_phy_ll_enable_shutdown_input(csi_host_dev_t *dev, bool en)
|
||||
{
|
||||
dev->phy_shutdownz.phy_shutdownz = !en; // shutdown input, active low
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable dphy reset output
|
||||
*
|
||||
* @param dev Pointer to the CSI Host controller register base address
|
||||
* @param en True to enable, False to disable
|
||||
*/
|
||||
static inline void mipi_csi_phy_ll_enable_reset_output(csi_host_dev_t *dev, bool en)
|
||||
{
|
||||
dev->dphy_rstz.dphy_rstz = !en; // phy reset output, active low
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "hal/mipi_csi_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief MIPI CSI SOC layer representation of the host controller
|
||||
*/
|
||||
typedef struct csi_host_dev_t *mipi_csi_host_soc_handle_t;
|
||||
|
||||
/**
|
||||
* @brief MIPI CSI SOC layer representation of the bridge controller
|
||||
*/
|
||||
typedef struct csi_brg_dev_t *mipi_csi_bridge_soc_handle_t;
|
||||
|
||||
/**
|
||||
* @brief MIPI CSI HAL driver context
|
||||
*/
|
||||
typedef struct {
|
||||
mipi_csi_host_soc_handle_t host_dev;
|
||||
mipi_csi_bridge_soc_handle_t bridge_dev;
|
||||
} mipi_csi_hal_context_t;
|
||||
|
||||
/**
|
||||
* @brief MIPI CSI HAL driver configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t lanes_num; ///< Lane num
|
||||
uint32_t frame_width; ///< Frame width
|
||||
uint32_t frame_height; ///< Frame height
|
||||
uint32_t in_bpp; ///< In bits per pixel
|
||||
uint32_t out_bpp; ///< Out bits per pixel
|
||||
bool byte_swap_en; ///< Enable byte swap
|
||||
int clk_freq_hz; ///< Clock frequency in hz
|
||||
} mipi_csi_hal_config_t;
|
||||
|
||||
/**
|
||||
* @brief MIPI CSI HAL layer initialization
|
||||
*
|
||||
* @param hal Pointer to the HAL driver context
|
||||
* @param config Pointer to the HAL configuration
|
||||
*/
|
||||
void mipi_csi_hal_init(mipi_csi_hal_context_t *hal, const mipi_csi_hal_config_t *config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_assert.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/color_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_MIPI_CSI_SUPPORTED
|
||||
/**
|
||||
* @brief MIPI CSI PHY clock source
|
||||
*/
|
||||
typedef soc_periph_mipi_csi_phy_clk_src_t mipi_csi_phy_clock_source_t;
|
||||
#else
|
||||
typedef int mipi_csi_phy_clock_source_t;
|
||||
#endif // SOC_MIPI_CSI_SUPPORTED
|
||||
|
||||
/**
|
||||
* @brief MIPI CSI Color Type
|
||||
*/
|
||||
typedef enum {
|
||||
MIPI_CSI_COLOR_RAW8 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW8), ///< RAW8
|
||||
MIPI_CSI_COLOR_RAW10 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW10), ///< RAW10
|
||||
MIPI_CSI_COLOR_RAW12 = COLOR_TYPE_ID(COLOR_SPACE_RAW, COLOR_PIXEL_RAW12), ///< RAW12
|
||||
MIPI_CSI_COLOR_RGB565 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB565), ///< RGB565
|
||||
MIPI_CSI_COLOR_RGB666 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB666), ///< RGB666
|
||||
MIPI_CSI_COLOR_RGB888 = COLOR_TYPE_ID(COLOR_SPACE_RGB, COLOR_PIXEL_RGB888), ///< RGB888
|
||||
MIPI_CSI_COLOR_YUV420 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV420), ///< YUV420
|
||||
MIPI_CSI_COLOR_YUV422 = COLOR_TYPE_ID(COLOR_SPACE_YUV, COLOR_PIXEL_YUV422), ///< YUV422
|
||||
} mipi_csi_color_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/log.h"
|
||||
#include "hal/mipi_csi_hal.h"
|
||||
#include "hal/mipi_csi_ll.h"
|
||||
#include "soc/mipi_csi_periph.h"
|
||||
|
||||
void s_mipi_csi_hal_phy_write_register(mipi_csi_hal_context_t *hal, uint8_t reg_addr, uint8_t reg_val)
|
||||
{
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 0, false);
|
||||
mipi_csi_phy_ll_write_reg_addr(hal->host_dev, reg_addr);
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 1, false);
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 0, false);
|
||||
mipi_csi_phy_ll_write_reg_val(hal->host_dev, reg_val);
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 1, false);
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 0, false);
|
||||
}
|
||||
|
||||
void mipi_csi_hal_init(mipi_csi_hal_context_t *hal, const mipi_csi_hal_config_t *config)
|
||||
{
|
||||
hal->bridge_dev = MIPI_CSI_BRG_LL_GET_HW(0);
|
||||
hal->host_dev = MIPI_CSI_HOST_LL_GET_HW(0);
|
||||
int csi_lane_rate = config->clk_freq_hz;
|
||||
|
||||
// reset PHY
|
||||
mipi_csi_phy_ll_enable_shutdown_input(hal->host_dev, true);
|
||||
mipi_csi_phy_ll_enable_reset_output(hal->host_dev, true);
|
||||
mipi_csi_host_ll_enable_reset_output(hal->host_dev, true);
|
||||
//reset reg addr to default value
|
||||
mipi_csi_phy_ll_write_reg_addr(hal->host_dev, 0x0);
|
||||
//reset reg val to default value
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 0, 1);
|
||||
mipi_csi_phy_ll_write_clock(hal->host_dev, 0, 0);
|
||||
|
||||
uint8_t hs_freq_sel = 0;
|
||||
for (size_t i = 0; i < num_of_soc_mipi_csi_phy_pll_ranges; i++) {
|
||||
if ((csi_lane_rate / 1000000) >= soc_mipi_csi_phy_pll_ranges[i].start_mbps &&
|
||||
(csi_lane_rate / 1000000) <= soc_mipi_csi_phy_pll_ranges[i].end_mbps) {
|
||||
hs_freq_sel = soc_mipi_csi_phy_pll_ranges[i].hs_freq_range_sel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
s_mipi_csi_hal_phy_write_register(hal, 0x44, hs_freq_sel << 1);
|
||||
HAL_LOGD("csi_hal", "CSI-DPHY lane_rate: %d Hz, hs_freq: 0x%x, lane_num: 0x%x", csi_lane_rate, hs_freq_sel, config->lanes_num);
|
||||
mipi_csi_phy_ll_enable_shutdown_input(hal->host_dev, false);
|
||||
mipi_csi_phy_ll_enable_reset_output(hal->host_dev, false);
|
||||
mipi_csi_host_ll_enable_reset_output(hal->host_dev, false);
|
||||
|
||||
// Configure the host controller.
|
||||
// Configure the number of active lanes.
|
||||
mipi_csi_host_ll_set_active_lanes_num(hal->host_dev, config->lanes_num);
|
||||
/**
|
||||
* We ignore the virtual channel and virtual channel extension info, there is only one virtual channel.
|
||||
* VC is by default there, VCX needs enable or disable.
|
||||
* So we disable VCX here.
|
||||
*/
|
||||
mipi_csi_host_ll_enable_virtual_channel_extension(hal->host_dev, false);
|
||||
// Set Scrambler.
|
||||
mipi_csi_host_ll_enable_scrambling(hal->host_dev, false);
|
||||
|
||||
//CSI bridge
|
||||
//TODO: IDF-9126, make csi bridge updates into `mipi_csi_share_hw_ctrl.c` and share with ISP
|
||||
mipi_csi_brg_ll_set_intput_data_h_pixel_num(hal->bridge_dev, config->frame_height);
|
||||
mipi_csi_brg_ll_set_intput_data_v_row_num(hal->bridge_dev, config->frame_width);
|
||||
mipi_csi_brg_ll_set_flow_ctl_buf_afull_thrd(hal->bridge_dev, 960);
|
||||
mipi_csi_brg_ll_set_data_type_min(hal->bridge_dev, 0x12);
|
||||
mipi_csi_brg_ll_set_data_type_max(hal->bridge_dev, 0x2f);
|
||||
mipi_csi_brg_ll_set_byte_endian(hal->bridge_dev, config->byte_swap_en);
|
||||
}
|
||||
Reference in New Issue
Block a user