forked from espressif/esp-idf
feat(csi): added csi bridge share control code
This commit is contained in:
committed by
Armando (Dou Yiwen)
parent
251239d59d
commit
8f097a4629
@@ -45,6 +45,10 @@ if(NOT BOOTLOADER_BUILD)
|
|||||||
list(APPEND srcs "adc_share_hw_ctrl.c")
|
list(APPEND srcs "adc_share_hw_ctrl.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SOC_ISP_SHARE_CSI_BRG)
|
||||||
|
list(APPEND srcs "mipi_csi_share_hw_ctrl.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CONFIG_SOC_PM_SUPPORT_CPU_PD)
|
if(CONFIG_SOC_PM_SUPPORT_CPU_PD)
|
||||||
list(APPEND srcs "sleep_cpu.c")
|
list(APPEND srcs "sleep_cpu.c")
|
||||||
endif()
|
endif()
|
||||||
|
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MIPI_CSI_BRG_USER_CSI, ///< Used by CSI Host
|
||||||
|
MIPI_CSI_BRG_USER_ISP_DVP, ///< Used by ISP DVP
|
||||||
|
MIPI_CSI_BRG_USER_SHARE, ///< Don't care user, share the usage with other users
|
||||||
|
} mipi_csi_brg_user_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Claim MIPI CSI Bridge peripheral
|
||||||
|
*
|
||||||
|
* @param[in] user CSI Bridge user
|
||||||
|
* @param[out] out_id ID of the CSI Bridge
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_NOT_FOUND No free CSI Bridge
|
||||||
|
*/
|
||||||
|
esp_err_t mipi_csi_brg_claim(mipi_csi_brg_user_t user, int *out_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declaim MIPI CSI Bridge peripheral
|
||||||
|
*
|
||||||
|
* @param[in] id ID of the CSI Bridge
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK
|
||||||
|
* - ESP_ERR_INVALID_STATE CSI Bridge isn't claimed yet
|
||||||
|
*/
|
||||||
|
esp_err_t mipi_csi_brg_declaim(int id);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
88
components/esp_hw_support/mipi_csi_share_hw_ctrl.c
Normal file
88
components/esp_hw_support/mipi_csi_share_hw_ctrl.c
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "esp_private/periph_ctrl.h"
|
||||||
|
#include "esp_private/mipi_csi_share_hw_ctrl.h"
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "hal/mipi_csi_ll.h"
|
||||||
|
|
||||||
|
#define MIPI_CSI_BRG_USER_NO_USER 99
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
mipi_csi_brg_user_t user[MIPI_CSI_BRG_LL_BRG_NUMS];
|
||||||
|
int ref_cnt[MIPI_CSI_BRG_LL_BRG_NUMS];
|
||||||
|
portMUX_TYPE spinlock;
|
||||||
|
} csi_brg_share_ctx_t;
|
||||||
|
|
||||||
|
static csi_brg_share_ctx_t s_ctx = {
|
||||||
|
.user[0 ...(MIPI_CSI_BRG_LL_BRG_NUMS - 1)] = MIPI_CSI_BRG_USER_NO_USER,
|
||||||
|
.ref_cnt[0 ...(MIPI_CSI_BRG_LL_BRG_NUMS - 1)] = 0,
|
||||||
|
.spinlock = portMUX_INITIALIZER_UNLOCKED,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *TAG = "CSI_SHARE";
|
||||||
|
|
||||||
|
esp_err_t mipi_csi_brg_claim(mipi_csi_brg_user_t user, int *out_id)
|
||||||
|
{
|
||||||
|
bool found = true;
|
||||||
|
portENTER_CRITICAL(&s_ctx.spinlock);
|
||||||
|
for (int i = 0; i < MIPI_CSI_BRG_LL_BRG_NUMS; i ++) {
|
||||||
|
bool user_is_shared = (s_ctx.user[i] == MIPI_CSI_BRG_USER_SHARE);
|
||||||
|
bool to_share = (user == MIPI_CSI_BRG_USER_SHARE);
|
||||||
|
bool duplicate_user = (s_ctx.user[i] == user);
|
||||||
|
|
||||||
|
if (s_ctx.ref_cnt[i] == 0) {
|
||||||
|
PERIPH_RCC_ATOMIC() {
|
||||||
|
mipi_csi_ll_enable_brg_module_clock(i, true);
|
||||||
|
mipi_csi_ll_reset_brg_module_clock(i);
|
||||||
|
}
|
||||||
|
s_ctx.user[i] = user;
|
||||||
|
} else {
|
||||||
|
if (!user_is_shared && !to_share && !duplicate_user) {
|
||||||
|
found = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user_is_shared) {
|
||||||
|
s_ctx.user[i] = user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
s_ctx.ref_cnt[i]++;
|
||||||
|
*out_id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL(&s_ctx.spinlock);
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return ESP_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t mipi_csi_brg_declaim(int id)
|
||||||
|
{
|
||||||
|
portENTER_CRITICAL(&s_ctx.spinlock);
|
||||||
|
|
||||||
|
s_ctx.ref_cnt[id]--;
|
||||||
|
if (s_ctx.ref_cnt[id] < 0) {
|
||||||
|
portEXIT_CRITICAL(&s_ctx.spinlock);
|
||||||
|
ESP_LOGE(TAG, "%s called, but s_ctx.ref_cnt[%d] == 0", __func__, id);
|
||||||
|
return ESP_ERR_INVALID_STATE;
|
||||||
|
} else if (s_ctx.ref_cnt[id] == 0) {
|
||||||
|
PERIPH_RCC_ATOMIC() {
|
||||||
|
mipi_csi_ll_enable_brg_module_clock(id, false);
|
||||||
|
}
|
||||||
|
s_ctx.user[id] = MIPI_CSI_BRG_USER_NO_USER;
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL(&s_ctx.spinlock);
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
70
components/hal/esp32p4/include/hal/mipi_csi_brg_ll.h
Normal file
70
components/hal/esp32p4/include/hal/mipi_csi_brg_ll.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "hal/misc.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "hal/hal_utils.h"
|
||||||
|
#include "soc/mipi_csi_bridge_struct.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MIPI_CSI_BRG_LL_BRG_NUMS 1
|
||||||
|
#define MIPI_CSI_BRG_LL_GET_HW(id) (((id) == 0) ? &MIPI_CSI_BRIDGE : NULL)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the CSI bridge
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the CSI bridge controller register base address
|
||||||
|
* @param en True to enable, false to disable
|
||||||
|
*/
|
||||||
|
static inline void mipi_csi_brg_ll_enable(csi_brg_dev_t *dev, bool en)
|
||||||
|
{
|
||||||
|
dev->csi_en.csi_brg_en = en;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the number of 64-bit words in one dma burst transfer
|
||||||
|
*
|
||||||
|
* @note valid only when csi_bridge is the flow controller
|
||||||
|
*
|
||||||
|
* @param dev Pointer to the CSI bridge controller register base address
|
||||||
|
* @param burst_len Number of 64-bit words in one dma burst transfer
|
||||||
|
*/
|
||||||
|
static inline void mipi_csi_brg_ll_set_burst_len(csi_brg_dev_t *dev, uint32_t burst_len)
|
||||||
|
{
|
||||||
|
dev->dma_req_cfg.dma_burst_len = burst_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set horizontal pixel number
|
||||||
|
*
|
||||||
|
* @param[in] dev Pointer to the CSI bridge controller register base address
|
||||||
|
* @param[in] pixel_num number of pixels
|
||||||
|
*/
|
||||||
|
static inline void mipi_csi_brg_ll_set_intput_data_h_pixel_num(csi_brg_dev_t *dev, uint32_t pixel_num)
|
||||||
|
{
|
||||||
|
dev->frame_cfg.hadr_num = pixel_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set vertical row number
|
||||||
|
*
|
||||||
|
* @param[in] dev Pointer to the CSI bridge controller register base address
|
||||||
|
* @param[in] row_num number of rows
|
||||||
|
*/
|
||||||
|
static inline void mipi_csi_brg_ll_set_intput_data_v_row_num(csi_brg_dev_t *dev, uint32_t row_num)
|
||||||
|
{
|
||||||
|
dev->frame_cfg.vadr_num = row_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
55
components/hal/esp32p4/include/hal/mipi_csi_ll.h
Normal file
55
components/hal/esp32p4/include/hal/mipi_csi_ll.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "hal/misc.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "hal/hal_utils.h"
|
||||||
|
#include "hal/mipi_csi_brg_ll.h"
|
||||||
|
#include "soc/hp_sys_clkrst_struct.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------
|
||||||
|
CSI Bridge
|
||||||
|
---------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* @brief Enable the bus clock for CSI Bridge module
|
||||||
|
*
|
||||||
|
* @param csi_bridge_id CSI Bridge ID
|
||||||
|
* @param en enable / disable
|
||||||
|
*/
|
||||||
|
static inline void mipi_csi_ll_enable_brg_module_clock(int csi_bridge_id, bool en)
|
||||||
|
{
|
||||||
|
HP_SYS_CLKRST.soc_clk_ctrl1.reg_csi_brg_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_brg_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_enable_brg_module_clock(__VA_ARGS__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the CSI Bridge module
|
||||||
|
*
|
||||||
|
* @param csi_bridge_id CSI Bridge ID
|
||||||
|
*/
|
||||||
|
static inline void mipi_csi_ll_reset_brg_module_clock(int csi_bridge_id)
|
||||||
|
{
|
||||||
|
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_csi_brg = 1;
|
||||||
|
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_csi_brg = 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_brg_module_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; mipi_csi_ll_reset_brg_module_clock(__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@@ -615,6 +615,10 @@ config SOC_ISP_AF_WINDOW_NUMS
|
|||||||
int
|
int
|
||||||
default 3
|
default 3
|
||||||
|
|
||||||
|
config SOC_ISP_SHARE_CSI_BRG
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@@ -343,7 +343,7 @@ typedef union {
|
|||||||
} csi_brg_host_ctrl_reg_t;
|
} csi_brg_host_ctrl_reg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct csi_brg_dev_t {
|
||||||
volatile csi_brg_clk_en_reg_t clk_en;
|
volatile csi_brg_clk_en_reg_t clk_en;
|
||||||
volatile csi_brg_csi_en_reg_t csi_en;
|
volatile csi_brg_csi_en_reg_t csi_en;
|
||||||
volatile csi_brg_dma_req_cfg_reg_t dma_req_cfg;
|
volatile csi_brg_dma_req_cfg_reg_t dma_req_cfg;
|
||||||
@@ -361,6 +361,7 @@ typedef struct {
|
|||||||
volatile csi_brg_host_ctrl_reg_t host_ctrl;
|
volatile csi_brg_host_ctrl_reg_t host_ctrl;
|
||||||
} csi_brg_dev_t;
|
} csi_brg_dev_t;
|
||||||
|
|
||||||
|
extern csi_brg_dev_t MIPI_CSI_BRIDGE;
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
_Static_assert(sizeof(csi_brg_dev_t) == 0x44, "Invalid size of csi_brg_dev_t structure");
|
_Static_assert(sizeof(csi_brg_dev_t) == 0x44, "Invalid size of csi_brg_dev_t structure");
|
||||||
|
@@ -1815,7 +1815,7 @@ typedef union {
|
|||||||
} csi_host_phy_stopstate_reg_t;
|
} csi_host_phy_stopstate_reg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct csi_host_dev_t {
|
||||||
volatile csi_host_version_reg_t version;
|
volatile csi_host_version_reg_t version;
|
||||||
volatile csi_host_n_lanes_reg_t n_lanes;
|
volatile csi_host_n_lanes_reg_t n_lanes;
|
||||||
volatile csi_host_csi2_resetn_reg_t csi2_resetn;
|
volatile csi_host_csi2_resetn_reg_t csi2_resetn;
|
||||||
@@ -1872,6 +1872,7 @@ typedef struct {
|
|||||||
volatile csi_host_scrambling_seed2_reg_t scrambling_seed2;
|
volatile csi_host_scrambling_seed2_reg_t scrambling_seed2;
|
||||||
} csi_host_dev_t;
|
} csi_host_dev_t;
|
||||||
|
|
||||||
|
extern csi_host_dev_t MIPI_CSI_HOST;
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
_Static_assert(sizeof(csi_host_dev_t) == 0x30c, "Invalid size of csi_host_dev_t structure");
|
_Static_assert(sizeof(csi_host_dev_t) == 0x30c, "Invalid size of csi_host_dev_t structure");
|
||||||
|
@@ -275,6 +275,7 @@
|
|||||||
#define SOC_ISP_AF_CTLR_NUMS 1U
|
#define SOC_ISP_AF_CTLR_NUMS 1U
|
||||||
#define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U
|
#define SOC_ISP_AF_ENV_DETECTOR_NUMS 1U
|
||||||
#define SOC_ISP_AF_WINDOW_NUMS 3
|
#define SOC_ISP_AF_WINDOW_NUMS 3
|
||||||
|
#define SOC_ISP_SHARE_CSI_BRG 1
|
||||||
|
|
||||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||||
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
||||||
|
Reference in New Issue
Block a user