摄像头控制器驱动程序

[English]

简介

ESP32-P4 具有以下硬件,用于与外部摄像头传感器通信:

  • MIPI 摄像头串行接口 (CSI)

  • ISP 数字视频端口 (ISP DVP)

摄像头控制器驱动程序是为上述硬件外设而设计的。

功能概述

资源分配

安装摄像头控制器驱动程序

摄像头控制器驱动程序可以通过 CSI 外设实现,需要应用 esp_cam_ctlr_csi_config_t 指定的配置。

如果指定了 esp_cam_ctlr_csi_config_t 中的配置,就可以调用 esp_cam_new_csi_ctlr() 来分配和初始化 CSI 摄像头控制器句柄。如果函数运行正确,将返回一个 CSI 摄像头控制器句柄。请参考以下代码。

esp_cam_ctlr_csi_config_t csi_config = {
    .ctlr_id = 0,
    .h_res = MIPI_CSI_DISP_HSIZE,
    .v_res = MIPI_CSI_DISP_VSIZE_640P,
    .lane_bit_rate_mbps = MIPI_CSI_LANE_BITRATE_MBPS,
    .input_data_color_type = CAM_CTLR_COLOR_RAW8,
    .output_data_color_type = CAM_CTLR_COLOR_RGB565,
    .data_lane_num = 2,
    .byte_swap_en = false,
    .queue_items = 1,
};
esp_cam_ctlr_handle_t handle = NULL;
ESP_ERROR_CHECK(esp_cam_new_csi_ctlr(&csi_config, &handle));

摄像头控制器驱动程序可以通过 ISP 外设实现,需要应用 esp_cam_ctlr_isp_dvp_cfg_t 指定的配置。

如果指定了 esp_cam_ctlr_isp_dvp_cfg_t 中的配置,就可以调用 esp_cam_new_isp_dvp_ctlr() 来分配和初始化 ISP DVP 摄像头控制器句柄。如果函数运行正确,将返回一个 ISP DVP 摄像头控制器句柄。请参考以下代码。

在调用 esp_cam_new_isp_dvp_ctlr() 之前,还应调用 esp_isp_new_processor() 来创建 ISP 句柄。

isp_proc_handle_t isp_proc = NULL;
esp_isp_processor_cfg_t isp_config = {
    .clk_hz = 120 * 1000 * 1000,
    .input_data_source = ISP_INPUT_DATA_SOURCE_DVP,
    .input_data_color_type = ISP_COLOR_RAW8,
    .output_data_color_type = ISP_COLOR_RGB565,
    .has_line_start_packet = false,
    .has_line_end_packet = false,
    .h_res = MIPI_CSI_DISP_HSIZE,
    .v_res = MIPI_CSI_DISP_VSIZE,
};
ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));

esp_cam_ctlr_isp_dvp_cfg_t dvp_ctlr_config = {
    .data_width = 8,
    .data_io = {53, 54, 52, 0, 1, 45, 46, 47, -1, -1, -1, -1, -1, -1, -1, -1},
    .pclk_io = 21,
    .hsync_io = 5,
    .vsync_io = 23,
    .de_io = 22,
    .io_flags.vsync_invert = 1,
    .queue_items = 10,
};
ESP_ERROR_CHECK(esp_cam_new_isp_dvp_ctlr(isp_proc, &dvp_ctlr_config, &cam_handle));

卸载摄像头控制器驱动程序

如果不再需要先前安装的摄像头控制器驱动程序,建议通过调用 esp_cam_ctlr_del() 来回收资源,从而释放底层硬件。

启用和禁用摄像头控制器驱动程序

在开始摄像头控制器操作之前,首先要调用 esp_cam_ctlr_enable() 以启用摄像头控制器驱动程序。此函数:

  • 将驱动程序状态从 init 切换到 enable

ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle));

调用 esp_cam_ctlr_disable() 则会执行与上述过程相反的操作,即将驱动程序切回到 init 状态。

ESP_ERROR_CHECK(esp_cam_ctlr_disable(handle));

启动和停止摄像头控制器驱动程序

从摄像头传感器接收信号之前,首先要调用 esp_cam_ctlr_start() 以启动摄像头控制器驱动程序。此函数:

  • 将驱动程序状态从 enable 切换到 start

ESP_ERROR_CHECK(esp_cam_ctlr_start(handle));

调用 esp_cam_ctlr_stop() 则会执行与上述过程相反的操作,即将驱动程序切回到 enable 状态。

ESP_ERROR_CHECK(esp_cam_ctlr_stop(handle));

从摄像头传感器处接收信号

调用 esp_cam_ctlr_receive(),可以接收来自摄像头传感器或其他设备的信号。

ESP_ERROR_CHECK(esp_cam_ctlr_receive(handle, &my_trans, ESP_CAM_CTLR_MAX_DELAY));

注册事件回调函数

摄像头控制器驱动程序开始接收信号时,会动态生成特定事件。如果在事件发生时需要调用一些函数,请通过调用 esp_cam_ctlr_register_event_callbacks() 将这些函数挂接到中断服务程序。所有支持的事件回调函数参见 esp_cam_ctlr_evt_cbs_t

  • esp_cam_ctlr_evt_cbs_t::on_get_new_trans 可设置回调函数,当摄像头控制器驱动程序完成传输并尝试获取新的事务描述符时,该回调函数会被调用。在 s_ctlr_csi_start() 中也会调用此回调函数。如果此回调函数未能获取新的事务描述符,但设置了 bk_buffer_dis 标志,则摄像头控制器驱动程序将使用内部备份 buffer。

  • esp_cam_ctlr_evt_cbs_t::on_trans_finished 可设置回调函数,当摄像头控制器驱动程序完成传输时,该回调函数会被调用。此函数在 ISR 上下文中被调用,因此必须确保该函数不会尝试阻塞(例如,确保只从该函数中调用带有 ISR 后缀的 FreeRTOS API)。

线程安全

以下工厂函数:

由驱动程序保证线程安全。使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。

Kconfig 选项

当 cache 被禁用时,以下 Kconfig 选项会影响中断处理程序的行为:

IRAM 安全

默认情况下,当 cache 因写入或擦除 flash 等原因而被禁用时,CSI 中断将被推迟。

有以下 Kconfig 选项:

这些选项支持

  • 即使 cache 被禁用也能启用中断服务

  • 将 ISR 使用的所有函数放入 IRAM

  • 将驱动程序对象放入 DRAM(以防意外映射到 PSRAM)

启用上述 Kconfig 选项,保证 cache 被禁用时中断可以正常运行,但这会增加 IRAM 使用量。因此,当 cache 被禁用时,用户回调函数需要注意(回调函数的)代码和数据应该是 IRAM 安全或 DRAM 安全的。

应用示例

  • peripherals/camera/camera_dsi 演示了如何使用 esp_driver_cam 组件从摄像头传感器捕获信号,并通过 DSI 接口将其显示在 ILI9881C LCD 屏幕上。

API 参考

Header File

  • components/esp_driver_cam/include/esp_cam_ctlr.h

  • This header file can be included with:

    #include "esp_cam_ctlr.h"
    
  • This header file is a part of the API provided by the esp_driver_cam component. To declare that your component depends on esp_driver_cam, add the following to your CMakeLists.txt:

    REQUIRES esp_driver_cam
    

    or

    PRIV_REQUIRES esp_driver_cam
    

Functions

esp_err_t esp_cam_ctlr_enable(esp_cam_ctlr_handle_t handle)

Enable ESP CAM controller.

参数

handle -- [in] ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_start(esp_cam_ctlr_handle_t handle)

Start ESP CAM controller.

参数

handle -- [in] ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_stop(esp_cam_ctlr_handle_t handle)

Stop ESP CAM controller.

参数

handle -- [in] ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_disable(esp_cam_ctlr_handle_t handle)

Disable ESP CAM controller.

参数

handle -- [in] ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_receive(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, uint32_t timeout_ms)

Receive data to the given transaction.

参数
  • handle -- [in] ESP CAM controller handle

  • trans -- [in] ESP CAM controller transaction type

  • timeout_ms -- [in] Timeout in ms

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_del(esp_cam_ctlr_handle_t handle)

Delete ESP CAM controller handle.

参数

handle -- [in] ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_register_event_callbacks(esp_cam_ctlr_handle_t handle, const esp_cam_ctlr_evt_cbs_t *cbs, void *user_data)

Register ESP CAM controller event callbacks.

参数
  • handle -- [in] ESP CAM controller handle

  • cbs -- [in] ESP CAM controller event callbacks

  • user_data -- [in] User data

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid state

esp_err_t esp_cam_ctlr_get_frame_buffer(esp_cam_ctlr_handle_t handle, uint32_t fb_num, const void **fb0, ...)

Get ESP CAM controller internal malloced backup buffer(s) addr.

备注

Generally, data in internal buffer is ready when on_trans_finished event

参数
  • handle -- [in] ESP CAM controller handle

  • fb_num -- [in] Number of frame buffer(s) to get. This value must be the same as the number of the followed fbN parameters

  • fb0 -- [out] Address of the frame buffer 0 (first frame buffer)

  • ... -- [out] List of other frame buffers if any

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_INVALID_STATE: Invalid driver state

esp_err_t esp_cam_ctlr_get_frame_buffer_len(esp_cam_ctlr_handle_t handle, size_t *ret_fb_len)

Get ESP CAM controller internal backup buffer length.

参数
  • handle -- [in] ESP CAM controller handle

  • ret_fb_len -- [out] Optional, The size of each frame buffer, in bytes.

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: NULL ptr

  • ESP_ERR_INVALID_STATE: Invalid driver state

Header File

  • components/esp_driver_cam/include/esp_cam_ctlr_types.h

  • This header file can be included with:

    #include "esp_cam_ctlr_types.h"
    
  • This header file is a part of the API provided by the esp_driver_cam component. To declare that your component depends on esp_driver_cam, add the following to your CMakeLists.txt:

    REQUIRES esp_driver_cam
    

    or

    PRIV_REQUIRES esp_driver_cam
    

Structures

struct esp_cam_ctlr_trans_t

ESP CAM controller transaction type.

Public Members

void *buffer

Transaction buffer.

size_t buflen

Len of the transaction buffer.

size_t received_size

Received size, this received_size will be written by the driver, indicating the real received size.

struct esp_cam_ctlr_evt_cbs_t

ESP CAM controller event callbacks.

Public Members

bool (*on_get_new_trans)(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)

On get new transaction callback.

Param handle

[in] ESP CAM controller handle

Param trans

[in] New transaction

Param user_data

[in] User registered data

Return

Whether a high priority task is woken up by this function

bool (*on_trans_finished)(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)

On transaction finish callback.

Param handle

[in] ESP CAM controller handle

Param trans

[out] Finished transaction

Param user_data

[in] User registered data

Return

Whether a high priority task is woken up by this function

Macros

ESP_CAM_CTLR_MAX_DELAY

ESP CAM controller max timeout value.

Type Definitions

typedef struct esp_cam_ctlr_t *esp_cam_ctlr_handle_t

ESP CAM controller handle.

Header File

  • components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h

  • This header file can be included with:

    #include "esp_cam_ctlr_csi.h"
    
  • This header file is a part of the API provided by the esp_driver_cam component. To declare that your component depends on esp_driver_cam, add the following to your CMakeLists.txt:

    REQUIRES esp_driver_cam
    

    or

    PRIV_REQUIRES esp_driver_cam
    

Functions

esp_err_t esp_cam_new_csi_ctlr(const esp_cam_ctlr_csi_config_t *config, esp_cam_ctlr_handle_t *ret_handle)

New ESP CAM CSI controller.

参数
  • config -- [in] CSI controller configurations

  • ret_handle -- [out] Returned ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_NO_MEM: Out of memory

  • ESP_ERR_NOT_SUPPORTED: Currently not support modes or types

  • ESP_ERR_NOT_FOUND: CSI is registered already

Structures

struct esp_cam_ctlr_csi_config_t

ESP CAM CSI controller configurations.

Public Members

int ctlr_id

CSI controller ID.

mipi_csi_phy_clock_source_t clk_src

CSI phy clock source.

uint32_t h_res

Input horizontal resolution, i.e. the number of pixels in a line.

uint32_t v_res

Input vertical resolution, i.e. the number of lines in a frame.

uint8_t data_lane_num

Data lane num.

int lane_bit_rate_mbps

Lane bit rate in Mbps.

cam_ctlr_color_t input_data_color_type

Input color type.

cam_ctlr_color_t output_data_color_type

Output color type.

int queue_items

Queue items.

uint32_t byte_swap_en

Enable byte swap.

uint32_t bk_buffer_dis

Disable backup buffer.

struct esp_cam_ctlr_csi_config_t::[anonymous] [anonymous]

Boolean Flags.

Header File

  • components/esp_driver_cam/isp_dvp/include/esp_cam_ctlr_isp_dvp.h

  • This header file can be included with:

    #include "esp_cam_ctlr_isp_dvp.h"
    
  • This header file is a part of the API provided by the esp_driver_cam component. To declare that your component depends on esp_driver_cam, add the following to your CMakeLists.txt:

    REQUIRES esp_driver_cam
    

    or

    PRIV_REQUIRES esp_driver_cam
    

Functions

esp_err_t esp_cam_new_isp_dvp_ctlr(isp_proc_handle_t isp_proc, const esp_cam_ctlr_isp_dvp_cfg_t *ctlr_config, esp_cam_ctlr_handle_t *ret_handle)

New ESP CAM ISP DVP controller.

参数
  • isp_proc -- [in] Processor handle

  • ctlr_config -- [in] ISP DVP controller configurations

  • ret_handle -- [out] Returned ESP CAM controller handle

返回

  • ESP_OK

  • ESP_ERR_INVALID_ARG: Invalid argument

  • ESP_ERR_NO_MEM: Out of memory

  • ESP_ERR_NOT_SUPPORTED: Currently not support modes or types

  • ESP_ERR_NOT_FOUND: ISP DVP is registered already

Structures

struct esp_cam_ctlr_isp_dvp_cfg_t

ESP CAM ISP DVP controller configurations.

Public Members

cam_ctlr_data_width_t data_width

Number of data lines.

int data_io[ISP_DVP_DATA_SIG_NUM]

ISP DVP data-in IO numbers.

int pclk_io

ISP DVP pclk IO numbers.

int hsync_io

ISP DVP hsync IO numbers.

int vsync_io

ISP DVP vsync IO numbers.

int de_io

ISP DVP de IO numbers.

uint32_t pclk_invert

The pclk is inverted.

uint32_t hsync_invert

The hsync signal is inverted.

uint32_t vsync_invert

The vsync signal is inverted.

uint32_t de_invert

The de signal is inverted.

struct esp_cam_ctlr_isp_dvp_cfg_t::[anonymous] io_flags

ISP DVP IO flags.

int queue_items

Queue items.

uint32_t byte_swap_en

Enable byte swap.

uint32_t bk_buffer_dis

Disable backup buffer.


此文档对您有帮助吗?