mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 10:00:57 +02:00
update camera driver document
This commit is contained in:
@@ -6,225 +6,279 @@ Camera Controller Driver
|
||||
Introduction
|
||||
------------
|
||||
|
||||
{IDF_TARGET_NAME} has the following hardware that is intended for communication with external camera sensor:
|
||||
{IDF_TARGET_NAME} has the following hardware designed for communication with external camera sensors:
|
||||
|
||||
.. list::
|
||||
|
||||
: SOC_MIPI_CSI_SUPPORTED : - MIPI Camera Serial Interface (MIPI CSI)
|
||||
: SOC_ISP_DVP_SUPPORTED : - Digital Video Port through ISP module (ISP DVP)
|
||||
: SOC_LCDCAM_CAM_SUPPORTED : - Digital Video Port through LCD_CAM module(LCD_CAM DVP)
|
||||
|
||||
The camera controller driver is designed for this hardware peripheral.
|
||||
:SOC_MIPI_CSI_SUPPORTED: - MIPI Camera Serial Interface (MIPI CSI)
|
||||
:SOC_ISP_DVP_SUPPORTED: - Digital Video Port via ISP module (ISP DVP)
|
||||
:SOC_LCDCAM_CAM_SUPPORTED: - Digital Video Port via LCD_CAM module (LCD_CAM DVP)
|
||||
|
||||
The camera controller driver provides an interface for these hardware peripherals.
|
||||
|
||||
Functional Overview
|
||||
-------------------
|
||||
|
||||
.. list::
|
||||
|
||||
- :ref:`cam-resource-allocation` - covers how to allocate camera controller instances with properly set of configurations. It also covers how to recycle the resources when they are no longer needed.
|
||||
- :ref:`cam-enable-disable` - covers how to enable and disable a camera controller.
|
||||
- :ref:`cam-start-stop` - covers how to start and stop a camera controller.
|
||||
- :ref:`cam-receive`- covers how to receive camera signal from a sensor or something else.
|
||||
- :ref:`cam-callback`- covers how to hook user specific code to camera controller driver event callback function.
|
||||
- :ref:`cam-thread-safety` - lists which APIs are guaranteed to be thread safe by the driver.
|
||||
- :ref:`cam-kconfig-options` - lists the supported Kconfig options that can bring different effects to the driver.
|
||||
- :ref:`cam-iram-safe` - describes tips on how to make the CSI interrupt and control functions work better along with a disabled cache.
|
||||
- :ref:`cam-resource-allocation` – Describes how to allocate and configure camera controller instances, and how to release resources when no longer needed.
|
||||
- :ref:`cam-enable-disable` – Explains how to enable and disable a camera controller.
|
||||
- :ref:`cam-start-stop` – Details how to start and stop a camera controller.
|
||||
- :ref:`cam-receive` – Explains how to receive signals from a camera sensor.
|
||||
- :ref:`cam-callback` – Describes how to register user-defined event callback functions.
|
||||
- :ref:`cam-thread-safety` – Lists APIs that are thread-safe.
|
||||
- :ref:`cam-kconfig-options` – Lists supported Kconfig options that affect driver behavior.
|
||||
- :ref:`cam-iram-safe` – Provides guidance on making CSI interrupt and control functions work reliably when the cache is disabled.
|
||||
|
||||
.. _cam-resource-allocation:
|
||||
|
||||
Resource Allocation
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Install Camera Controller Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Install the Camera Controller Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Camera controller driver can be implemented in one of following ways:
|
||||
You can implement the camera controller driver using one of the following methods:
|
||||
|
||||
.. list::
|
||||
|
||||
: SOC_MIPI_CSI_SUPPORTED : - :cpp:func:`esp_cam_new_csi_ctlr`
|
||||
: SOC_ISP_DVP_SUPPORTED : - :cpp:func:`esp_cam_new_isp_dvp_ctlr`
|
||||
: SOC_LCDCAM_CAM_SUPPORTED : - :cpp:func:`esp_cam_new_lcd_cam_ctlr`
|
||||
:SOC_MIPI_CSI_SUPPORTED: - :cpp:func:`esp_cam_new_csi_ctlr`
|
||||
:SOC_ISP_DVP_SUPPORTED: - :cpp:func:`esp_cam_new_isp_dvp_ctlr`
|
||||
:SOC_LCDCAM_CAM_SUPPORTED: - :cpp:func:`esp_cam_new_lcd_cam_ctlr`
|
||||
|
||||
.. only:: SOC_MIPI_CSI_SUPPORTED
|
||||
|
||||
A camera controller driver can be implemented by the CSI peripheral, which requires the configuration that specified by :cpp:type:`esp_cam_ctlr_csi_config_t`.
|
||||
You can implement a camera controller driver using the CSI peripheral. This requires configuration via :cpp:type:`esp_cam_ctlr_csi_config_t`.
|
||||
|
||||
If the configurations in :cpp:type:`esp_cam_ctlr_csi_config_t` is specified, users can call :cpp:func:`esp_cam_new_csi_ctlr` to allocate and initialize a CSI camera controller handle. This function will return an CSI camera controller handle if it runs correctly. You can take following code as reference.
|
||||
After specifying :cpp:type:`esp_cam_ctlr_csi_config_t`, call :cpp:func:`esp_cam_new_csi_ctlr` to allocate and initialize a CSI camera controller handle. If successful, this function returns a CSI camera controller handle. See the example below.
|
||||
|
||||
.. code:: c
|
||||
|
||||
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));
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
#include "esp_cam_ctlr_csi.h"
|
||||
|
||||
The CSI in {IDF_TARGET_NAME} requires stable 2.5V power supply. Please refer to the schematic diagram to ensure that the power supply pins are connected to 2.5V power before using the MIPI CSI driver.
|
||||
void app_main(void)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
The CSI peripheral in {IDF_TARGET_NAME} requires a stable 2.5 V power supply. Refer to the schematic diagram to ensure the power supply pins are connected to 2.5 V before using the MIPI CSI driver.
|
||||
|
||||
.. only:: SOC_GP_LDO_SUPPORTED
|
||||
|
||||
In {IDF_TARGET_NAME}, the CSI can be powered by the internal adjustable LDO. Please connect the LDO channel output pin to the CSI power supply pin. Then, before initializing the CSI driver, use the API provided in :doc:`/api-reference/peripherals/ldo_regulator` to configure the LDO to output 2.5 V voltage.
|
||||
In {IDF_TARGET_NAME}, you can power the CSI using the internal adjustable LDO. Connect the LDO channel output pin to the CSI power supply pin. Before initializing the CSI driver, use the API in :doc:`/api-reference/peripherals/ldo_regulator` to configure the LDO to output 2.5 V.
|
||||
|
||||
.. only:: SOC_ISP_DVP_SUPPORTED
|
||||
|
||||
A camera controller driver can be implemented by the ISP DVP peripheral, which requires the configuration that specified by :cpp:type:`esp_cam_ctlr_isp_dvp_cfg_t`.
|
||||
You can implement a camera controller driver using the ISP DVP peripheral. This requires configuration via :cpp:type:`esp_cam_ctlr_isp_dvp_cfg_t`.
|
||||
|
||||
If the configurations in :cpp:type:`esp_cam_ctlr_isp_dvp_cfg_t` is specified, users can call :cpp:func:`esp_cam_new_isp_dvp_ctlr` to allocate and initialize a ISP DVP camera controller handle. This function will return an ISP DVP camera controller handle if it runs correctly. You can take following code as reference.
|
||||
After specifying :cpp:type:`esp_cam_ctlr_isp_dvp_cfg_t`, call :cpp:func:`esp_cam_new_isp_dvp_ctlr` to allocate and initialize an ISP DVP camera controller handle. If successful, this function returns an ISP DVP camera controller handle. See the example below.
|
||||
|
||||
Before calling :cpp:func:`esp_cam_new_isp_dvp_ctlr`, you should also call :cpp:func:`esp_isp_new_processor` to create an ISP handle.
|
||||
Before calling :cpp:func:`esp_cam_new_isp_dvp_ctlr`, create an ISP handle using :cpp:func:`esp_isp_new_processor`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
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));
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_isp_dvp.h"
|
||||
#include "driver/isp.h"
|
||||
|
||||
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));
|
||||
#define MIPI_CSI_DISP_HSIZE 800 // example value, replace with actual resolution
|
||||
#define MIPI_CSI_DISP_VSIZE 600 // example value, replace with actual resolution
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
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_handle_t cam_handle = NULL;
|
||||
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));
|
||||
}
|
||||
|
||||
.. only:: SOC_LCDCAM_CAM_SUPPORTED
|
||||
|
||||
A camera controller driver can be implemented by the DVP port of LCD_CAM, which requires the configuration that specified by :cpp:type:`esp_cam_ctlr_dvp_config_t`.
|
||||
You can implement a camera controller driver using the DVP port of LCD_CAM. This requires configuration via :cpp:type:`esp_cam_ctlr_dvp_config_t`.
|
||||
|
||||
:cpp:member:`esp_cam_ctlr_dvp_config_t::exexternal_xtal`: set this to use externally generated xclk, otherwise the camera driver will generate it internally.
|
||||
:cpp:member:`esp_cam_ctlr_dvp_config_t::exexternal_xtal`: Set this to use an externally generated xclk. Otherwise, the camera driver generates it internally.
|
||||
|
||||
If :cpp:type:`esp_cam_ctlr_lcd_cam_cfg_t` is specified, users can call :cpp:func:`esp_cam_new_lcd_cam_ctlr` to allocate and initialize a DVP camera controller handle. This function will return an DVP camera controller handle if it runs correctly. You can take following code as reference.
|
||||
After specifying :cpp:type:`esp_cam_ctlr_lcd_cam_cfg_t`, call :cpp:func:`esp_cam_new_lcd_cam_ctlr` to allocate and initialize a DVP camera controller handle. If successful, this function returns a DVP camera controller handle. See the example below.
|
||||
|
||||
After calling :cpp:func:`esp_cam_new_dvp_ctlr`, you should allocate a camera buffer that meets the alignment constraints, or call :cpp:func:`esp_cam_ctlr_alloc_buffer` to automatically allocate.
|
||||
After calling :cpp:func:`esp_cam_new_dvp_ctlr`, allocate a camera buffer that meets alignment constraints, or call :cpp:func:`esp_cam_ctlr_alloc_buffer` to allocate automatically.
|
||||
|
||||
You can call :cpp:func:`esp_cam_ctlr_format_conversion` to configure format conversion. The driver supports the following conversion types:
|
||||
To configure format conversion, call :cpp:func:`esp_cam_ctlr_format_conversion`. The driver supports the following conversion types:
|
||||
|
||||
* YUV to RGB conversion
|
||||
* RGB to YUV conversion
|
||||
* YUV to YUV conversion
|
||||
* YUV to RGB
|
||||
* RGB to YUV
|
||||
* YUV to YUV
|
||||
|
||||
Color range support:
|
||||
Supported color ranges:
|
||||
* Full range: 0-255 for both RGB and YUV
|
||||
* Limited range: RGB 16-240, YUV Y:16-240, U-V:16-235
|
||||
|
||||
.. code:: c
|
||||
|
||||
esp_cam_ctlr_handle_t cam_handle = NULL;
|
||||
esp_cam_ctlr_dvp_pin_config_t pin_cfg = {
|
||||
.data_width = EXAMPLE_DVP_CAM_DATA_WIDTH,
|
||||
.data_io = {
|
||||
EXAMPLE_DVP_CAM_D0_IO,
|
||||
EXAMPLE_DVP_CAM_D1_IO,
|
||||
EXAMPLE_DVP_CAM_D2_IO,
|
||||
EXAMPLE_DVP_CAM_D3_IO,
|
||||
EXAMPLE_DVP_CAM_D4_IO,
|
||||
EXAMPLE_DVP_CAM_D5_IO,
|
||||
EXAMPLE_DVP_CAM_D6_IO,
|
||||
EXAMPLE_DVP_CAM_D7_IO,
|
||||
},
|
||||
.vsync_io = EXAMPLE_DVP_CAM_VSYNC_IO,
|
||||
.de_io = EXAMPLE_DVP_CAM_DE_IO,
|
||||
.pclk_io = EXAMPLE_DVP_CAM_PCLK_IO,
|
||||
.xclk_io = EXAMPLE_DVP_CAM_XCLK_IO, // Set XCLK pin to generate XCLK signal
|
||||
};
|
||||
esp_cam_ctlr_dvp_config_t dvp_config = {
|
||||
.ctlr_id = 0,
|
||||
.clk_src = CAM_CLK_SRC_DEFAULT,
|
||||
.h_res = CONFIG_EXAMPLE_CAM_HRES,
|
||||
.v_res = CONFIG_EXAMPLE_CAM_VRES,
|
||||
.input_data_color_type = CAM_CTLR_COLOR_RGB565,
|
||||
.dma_burst_size = 128,
|
||||
.pin = &pin_cfg,
|
||||
.bk_buffer_dis = 1,
|
||||
.xclk_freq = EXAMPLE_DVP_CAM_XCLK_FREQ_HZ,
|
||||
};
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
#include "esp_cam_ctlr_isp_dvp.h"
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t cam_handle = NULL;
|
||||
|
||||
const cam_ctlr_format_conv_config_t conv_cfg = {
|
||||
.src_format = CAM_CTLR_COLOR_YUV422, // Source format: YUV422
|
||||
.dst_format = CAM_CTLR_COLOR_RGB565, // Destination format: RGB565
|
||||
.conv_std = COLOR_CONV_STD_RGB_YUV_BT601,
|
||||
.data_width = 8,
|
||||
.input_range = COLOR_RANGE_LIMIT,
|
||||
.output_range = COLOR_RANGE_LIMIT,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_format_conversion(cam_handle, &conv_cfg));
|
||||
esp_cam_ctlr_dvp_pin_config_t pin_cfg = {
|
||||
.data_width = EXAMPLE_DVP_CAM_DATA_WIDTH,
|
||||
.data_io = {
|
||||
EXAMPLE_DVP_CAM_D0_IO,
|
||||
EXAMPLE_DVP_CAM_D1_IO,
|
||||
EXAMPLE_DVP_CAM_D2_IO,
|
||||
EXAMPLE_DVP_CAM_D3_IO,
|
||||
EXAMPLE_DVP_CAM_D4_IO,
|
||||
EXAMPLE_DVP_CAM_D5_IO,
|
||||
EXAMPLE_DVP_CAM_D6_IO,
|
||||
EXAMPLE_DVP_CAM_D7_IO,
|
||||
},
|
||||
.vsync_io = EXAMPLE_DVP_CAM_VSYNC_IO,
|
||||
.de_io = EXAMPLE_DVP_CAM_DE_IO,
|
||||
.pclk_io = EXAMPLE_DVP_CAM_PCLK_IO,
|
||||
.xclk_io = EXAMPLE_DVP_CAM_XCLK_IO, // Set XCLK pin to generate XCLK signal
|
||||
};
|
||||
|
||||
Uninstall Camera Controller Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
esp_cam_ctlr_dvp_config_t dvp_config = {
|
||||
.ctlr_id = 0,
|
||||
.clk_src = CAM_CLK_SRC_DEFAULT,
|
||||
.h_res = CONFIG_EXAMPLE_CAM_HRES,
|
||||
.v_res = CONFIG_EXAMPLE_CAM_VRES,
|
||||
.input_data_color_type = CAM_CTLR_COLOR_RGB565,
|
||||
.dma_burst_size = 128,
|
||||
.pin = &pin_cfg,
|
||||
.bk_buffer_dis = 1,
|
||||
.xclk_freq = EXAMPLE_DVP_CAM_XCLK_FREQ_HZ,
|
||||
};
|
||||
|
||||
If a previously installed camera controller driver is no longer needed, it's recommended to recycle the resource by calling :cpp:func:`esp_cam_ctlr_del`, so that to release the underlying hardware.
|
||||
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
||||
}
|
||||
|
||||
Uninstall the Camera Controller Driver
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To release resources for a camera controller driver that is no longer needed, call :cpp:func:`esp_cam_ctlr_del`. This releases the underlying hardware.
|
||||
|
||||
.. _cam-enable-disable:
|
||||
|
||||
Enable and Disable Camera Controller Driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Enable and Disable the Camera Controller Driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before starting camera controller operation, you need to enable the camera controller driver first, by calling :cpp:func:`esp_cam_ctlr_enable`. This function:
|
||||
|
||||
* Switches the driver state from **init** to **enable**.
|
||||
Before operating the camera controller, enable the driver by calling :cpp:func:`esp_cam_ctlr_enable`. This switches the driver state from **init** to **enable**.
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle));
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
Calling :cpp:func:`esp_cam_ctlr_disable` does the opposite, that is, put the driver back to the **init** state.
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle));
|
||||
}
|
||||
|
||||
To disable the driver and return to the **init** state, call :cpp:func:`esp_cam_ctlr_disable`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_disable(handle));
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_disable(handle));
|
||||
}
|
||||
|
||||
.. _cam-start-stop:
|
||||
|
||||
Start and Stop Camera Controller Driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Start and Stop the Camera Controller Driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Before receiving camera signal from camera sensor, you need to start the camera controller driver first, by calling :cpp:func:`esp_cam_ctlr_start`. This function:
|
||||
|
||||
* Switches the driver state from **enable** to **start**.
|
||||
Before receiving signals from a camera sensor, start the driver by calling :cpp:func:`esp_cam_ctlr_start`. This switches the driver state from **enable** to **start**.
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_start(handle));
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
Calling :cpp:func:`esp_cam_ctlr_stop` does the opposite, that is, put the driver back to the **enable** state.
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle = NULL;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_start(handle));
|
||||
ESP_LOGI("CAM", "Camera controller started successfully");
|
||||
}
|
||||
|
||||
To stop the driver and return to the **enable** state, call :cpp:func:`esp_cam_ctlr_stop`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_stop(handle));
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle = NULL;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_stop(handle));
|
||||
}
|
||||
|
||||
.. _cam-receive:
|
||||
|
||||
Receive from a Camera Sensor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Receive Data from a Camera Sensor
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Now you can call :cpp:func:`esp_cam_ctlr_receive` to receive from a camera sensor or something else.
|
||||
To receive data from a camera sensor, call :cpp:func:`esp_cam_ctlr_receive`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_receive(handle, &my_trans, ESP_CAM_CTLR_MAX_DELAY));
|
||||
|
||||
.. _cam-callback:
|
||||
@@ -232,18 +286,18 @@ Now you can call :cpp:func:`esp_cam_ctlr_receive` to receive from a camera senso
|
||||
Register Event Callbacks
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After the camera controller driver starts receiving, it can generate a specific event dynamically. If you have some functions that should be called when the event happens, please hook your function to the interrupt service routine by calling :cpp:func:`esp_cam_ctlr_register_event_callbacks`. All supported event callbacks are listed in :cpp:type:`esp_cam_ctlr_evt_cbs_t`:
|
||||
After the camera controller driver starts receiving data, it can generate events dynamically. To execute user-defined functions when events occur, register your callback function using :cpp:func:`esp_cam_ctlr_register_event_callbacks`. Supported event callbacks are listed in :cpp:type:`esp_cam_ctlr_evt_cbs_t`:
|
||||
|
||||
- :cpp:member:`esp_cam_ctlr_evt_cbs_t::on_get_new_trans` sets a callback function which will be called after the camera controller driver finishes previous transaction, and tries to get a new transaction descriptor. It will also be called when in :cpp:func:`s_ctlr_csi_start`. If this callback does not get a new transaction descriptor, the camera controller driver will use the internal backup buffer if ``bk_buffer_dis`` flag is set.
|
||||
- :cpp:member:`esp_cam_ctlr_evt_cbs_t::on_get_new_trans` – Called after the driver finishes a transaction and attempts to get a new transaction descriptor. Also called in :cpp:func:`s_ctlr_csi_start`. If this callback does not provide a new transaction descriptor, the driver uses the internal backup buffer if the ``bk_buffer_dis`` flag is set.
|
||||
|
||||
- :cpp:member:`esp_cam_ctlr_evt_cbs_t::on_trans_finished` sets a callback function when the camera controller driver finishes a transaction. As this function is called within the ISR context, you must ensure that the function does not attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function).
|
||||
- :cpp:member:`esp_cam_ctlr_evt_cbs_t::on_trans_finished` – Called when the driver finishes a transaction. This function runs in the ISR context. Ensure that it does not block (for example, only use FreeRTOS APIs with the ``ISR`` suffix).
|
||||
|
||||
.. _cam-thread-safety:
|
||||
|
||||
Thread Safety
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The factory functions:
|
||||
The following factory functions are thread-safe and can be called from different RTOS tasks without additional locking:
|
||||
|
||||
.. list::
|
||||
|
||||
@@ -251,47 +305,43 @@ The factory functions:
|
||||
:SOC_ISP_DVP_SUPPORTED: - :cpp:func:`esp_cam_new_isp_dvp_ctlr`
|
||||
- :cpp:func:`esp_cam_ctlr_del`
|
||||
|
||||
are guaranteed to be thread safe by the driver, which means, they can be called from different RTOS tasks without protection by extra locks.
|
||||
|
||||
.. _cam-kconfig-options:
|
||||
|
||||
Kconfig Options
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The following Kconfig options affect the behavior of the interrupt handler when cache is disabled:
|
||||
The following Kconfig options affect interrupt handler behavior when the cache is disabled:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_MIPI_CSI_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_MIPI_CSI_ISR_CACHE_SAFE`, see :ref:`cam-thread-safety` for more details.
|
||||
:SOC_ISP_DVP_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_ISP_DVP_ISR_CACHE_SAFE`, see :ref:`cam-thread-safety` for more details.
|
||||
:SOC_MIPI_CSI_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_MIPI_CSI_ISR_CACHE_SAFE`, see :ref:`cam-thread-safety` for details.
|
||||
:SOC_ISP_DVP_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_ISP_DVP_ISR_CACHE_SAFE`, see :ref:`cam-thread-safety` for details.
|
||||
|
||||
.. _cam-iram-safe:
|
||||
|
||||
IRAM Safe
|
||||
^^^^^^^^^
|
||||
IRAM Safety
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
By default, the CSI interrupt will be deferred when the cache is disabled because of writing or erasing the flash.
|
||||
By default, CSI interrupts are delayed when the cache is disabled during flash write or erase operations. They are handled after the cache is enabled again.
|
||||
|
||||
There are Kconfig options
|
||||
The following Kconfig options:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_MIPI_CSI_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_MIPI_CSI_ISR_CACHE_SAFE`
|
||||
:SOC_ISP_DVP_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_ISP_DVP_ISR_CACHE_SAFE`
|
||||
|
||||
that
|
||||
- Enable the interrupt being serviced even when the cache is disabled.
|
||||
- Place all functions used by the ISR into IRAM.
|
||||
- Place driver object into DRAM (to avoid mapping to PSRAM).
|
||||
|
||||
- Enables the interrupt being serviced even when the cache is disabled
|
||||
- Places all functions that used by the ISR into IRAM
|
||||
- Places driver object into DRAM (in case it is mapped to PSRAM by accident)
|
||||
|
||||
This allows the interrupt to run while the cache is disabled, but comes at the cost of increased IRAM consumption. So user callbacks need to notice that the code and data inside (the callback) should be IRAM-safe or DRAM-safe, when cache is disabled.
|
||||
This allows interrupts to run while the cache is disabled, but increases IRAM usage. Ensure that user callbacks and related code/data are IRAM-safe or DRAM-safe when the cache is disabled.
|
||||
|
||||
Application Examples
|
||||
--------------------
|
||||
|
||||
* :example:`peripherals/camera/mipi_isp_dsi` demonstrates how to use the ``esp_driver_cam`` component to capture signals from a MIPI CSI camera sensor via the ISP module and display it on a LCD screen via a DSI interface.
|
||||
* :example:`peripherals/camera/dvp_isp_dsi` demonstrates how to use the ``esp_driver_cam`` component to capture signals from a DVP camera sensor via the ISP module and display it on a LCD screen via a DSI interface.
|
||||
* :example:`peripherals/camera/mipi_isp_dsi` – Demonstrates how to use the ``esp_driver_cam`` component to capture signals from a MIPI CSI camera sensor via the ISP module and display them on an LCD screen via a DSI interface.
|
||||
* :example:`peripherals/camera/dvp_isp_dsi` – Demonstrates how to use the ``esp_driver_cam`` component to capture signals from a DVP camera sensor via the ISP module and display them on an LCD screen via a DSI interface.
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
@@ -10,13 +10,12 @@
|
||||
|
||||
.. list::
|
||||
|
||||
: SOC_MIPI_CSI_SUPPORTED : - MIPI 摄像头串行接口 (MIPI CSI)
|
||||
: SOC_ISP_DVP_SUPPORTED : - ISP的DVP端口 (ISP DVP)
|
||||
: SOC_LCDCAM_CAM_SUPPORTED : - LCD_CAM的DVP端口 (LCD_CAM DVP)
|
||||
:SOC_MIPI_CSI_SUPPORTED: - MIPI 摄像头串行接口 (MIPI CSI)
|
||||
:SOC_ISP_DVP_SUPPORTED: - ISP的DVP端口 (ISP DVP)
|
||||
:SOC_LCDCAM_CAM_SUPPORTED: - LCD_CAM的DVP端口 (LCD_CAM DVP)
|
||||
|
||||
摄像头控制器驱动程序是为上述硬件外设而设计的。
|
||||
|
||||
|
||||
功能概述
|
||||
------------
|
||||
|
||||
@@ -43,9 +42,9 @@
|
||||
|
||||
.. list::
|
||||
|
||||
: SOC_MIPI_CSI_SUPPORTED : - :cpp:func:`esp_cam_new_csi_ctlr`
|
||||
: SOC_ISP_DVP_SUPPORTED : - :cpp:func:`esp_cam_new_isp_dvp_ctlr`
|
||||
: SOC_LCDCAM_CAM_SUPPORTED : - :cpp:func:`esp_cam_new_lcd_cam_ctlr`
|
||||
:SOC_MIPI_CSI_SUPPORTED: - :cpp:func:`esp_cam_new_csi_ctlr`
|
||||
:SOC_ISP_DVP_SUPPORTED: - :cpp:func:`esp_cam_new_isp_dvp_ctlr`
|
||||
:SOC_LCDCAM_CAM_SUPPORTED: - :cpp:func:`esp_cam_new_lcd_cam_ctlr`
|
||||
|
||||
.. only:: SOC_MIPI_CSI_SUPPORTED
|
||||
|
||||
@@ -55,21 +54,29 @@
|
||||
|
||||
.. code:: c
|
||||
|
||||
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));
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
#include "esp_cam_ctlr_csi.h"
|
||||
|
||||
{IDF_TARGET_NAME} 中的 CSI 控制器需要稳定的 2.5V 电源供电,请查阅原理图,确保在使用 MIPI CSI 驱动之前,已将其供电管脚连接至 2.5V 电源。
|
||||
void app_main(void)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
{IDF_TARGET_NAME} 中的 CSI 控制器需要稳定的 2.5 V 电源供电,请查阅原理图,确保在使用 MIPI CSI 驱动之前,已将其供电管脚连接至 2.5 V 电源。
|
||||
|
||||
.. only:: SOC_GP_LDO_SUPPORTED
|
||||
|
||||
@@ -85,30 +92,42 @@
|
||||
|
||||
.. code:: c
|
||||
|
||||
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));
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_isp_dvp.h"
|
||||
#include "driver/isp.h"
|
||||
|
||||
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));
|
||||
#define MIPI_CSI_DISP_HSIZE 800 // example value, replace with actual resolution
|
||||
#define MIPI_CSI_DISP_VSIZE 600 // example value, replace with actual resolution
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
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_handle_t cam_handle = NULL;
|
||||
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));
|
||||
}
|
||||
|
||||
.. only:: SOC_LCDCAM_CAM_SUPPORTED
|
||||
|
||||
@@ -132,47 +151,47 @@
|
||||
|
||||
.. code:: c
|
||||
|
||||
esp_cam_ctlr_handle_t cam_handle = NULL;
|
||||
esp_cam_ctlr_dvp_pin_config_t pin_cfg = {
|
||||
.data_width = EXAMPLE_DVP_CAM_DATA_WIDTH,
|
||||
.data_io = {
|
||||
EXAMPLE_DVP_CAM_D0_IO,
|
||||
EXAMPLE_DVP_CAM_D1_IO,
|
||||
EXAMPLE_DVP_CAM_D2_IO,
|
||||
EXAMPLE_DVP_CAM_D3_IO,
|
||||
EXAMPLE_DVP_CAM_D4_IO,
|
||||
EXAMPLE_DVP_CAM_D5_IO,
|
||||
EXAMPLE_DVP_CAM_D6_IO,
|
||||
EXAMPLE_DVP_CAM_D7_IO,
|
||||
},
|
||||
.vsync_io = EXAMPLE_DVP_CAM_VSYNC_IO,
|
||||
.de_io = EXAMPLE_DVP_CAM_DE_IO,
|
||||
.pclk_io = EXAMPLE_DVP_CAM_PCLK_IO,
|
||||
.xclk_io = EXAMPLE_DVP_CAM_XCLK_IO, // Set XCLK pin to generate XCLK signal
|
||||
};
|
||||
esp_cam_ctlr_dvp_config_t dvp_config = {
|
||||
.ctlr_id = 0,
|
||||
.clk_src = CAM_CLK_SRC_DEFAULT,
|
||||
.h_res = CONFIG_EXAMPLE_CAM_HRES,
|
||||
.v_res = CONFIG_EXAMPLE_CAM_VRES,
|
||||
.input_data_color_type = CAM_CTLR_COLOR_RGB565,
|
||||
.dma_burst_size = 128,
|
||||
.pin = &pin_cfg,
|
||||
.bk_buffer_dis = 1,
|
||||
.xclk_freq = EXAMPLE_DVP_CAM_XCLK_FREQ_HZ,
|
||||
};
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
#include "esp_cam_ctlr_isp_dvp.h"
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t cam_handle = NULL;
|
||||
|
||||
const cam_ctlr_format_conv_config_t conv_cfg = {
|
||||
.src_format = CAM_CTLR_COLOR_YUV422, // 源格式:YUV422
|
||||
.dst_format = CAM_CTLR_COLOR_RGB565, // 目标格式:RGB565
|
||||
.conv_std = COLOR_CONV_STD_RGB_YUV_BT601,
|
||||
.data_width = 8,
|
||||
.input_range = COLOR_RANGE_LIMIT,
|
||||
.output_range = COLOR_RANGE_LIMIT,
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_format_conversion(cam_handle, &conv_cfg));
|
||||
esp_cam_ctlr_dvp_pin_config_t pin_cfg = {
|
||||
.data_width = EXAMPLE_DVP_CAM_DATA_WIDTH,
|
||||
.data_io = {
|
||||
EXAMPLE_DVP_CAM_D0_IO,
|
||||
EXAMPLE_DVP_CAM_D1_IO,
|
||||
EXAMPLE_DVP_CAM_D2_IO,
|
||||
EXAMPLE_DVP_CAM_D3_IO,
|
||||
EXAMPLE_DVP_CAM_D4_IO,
|
||||
EXAMPLE_DVP_CAM_D5_IO,
|
||||
EXAMPLE_DVP_CAM_D6_IO,
|
||||
EXAMPLE_DVP_CAM_D7_IO,
|
||||
},
|
||||
.vsync_io = EXAMPLE_DVP_CAM_VSYNC_IO,
|
||||
.de_io = EXAMPLE_DVP_CAM_DE_IO,
|
||||
.pclk_io = EXAMPLE_DVP_CAM_PCLK_IO,
|
||||
.xclk_io = EXAMPLE_DVP_CAM_XCLK_IO, // Set XCLK pin to generate XCLK signal
|
||||
};
|
||||
|
||||
esp_cam_ctlr_dvp_config_t dvp_config = {
|
||||
.ctlr_id = 0,
|
||||
.clk_src = CAM_CLK_SRC_DEFAULT,
|
||||
.h_res = CONFIG_EXAMPLE_CAM_HRES,
|
||||
.v_res = CONFIG_EXAMPLE_CAM_VRES,
|
||||
.input_data_color_type = CAM_CTLR_COLOR_RGB565,
|
||||
.dma_burst_size = 128,
|
||||
.pin = &pin_cfg,
|
||||
.bk_buffer_dis = 1,
|
||||
.xclk_freq = EXAMPLE_DVP_CAM_XCLK_FREQ_HZ,
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_new_dvp_ctlr(&dvp_config, &cam_handle));
|
||||
}
|
||||
|
||||
卸载摄像头控制器驱动程序
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -184,38 +203,68 @@
|
||||
启用和禁用摄像头控制器驱动程序
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
在开始摄像头控制器操作之前,首先要调用 :cpp:func:`esp_cam_ctlr_enable` 以启用摄像头控制器驱动程序。此函数:
|
||||
|
||||
* 将驱动程序状态从 **init** 切换到 **enable**。
|
||||
在开始摄像头控制器操作之前,首先要调用 :cpp:func:`esp_cam_ctlr_enable` 以启用摄像头控制器驱动程序。此函数将驱动程序状态从 **init** 切换到 **enable**。
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle));
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle));
|
||||
}
|
||||
|
||||
调用 :cpp:func:`esp_cam_ctlr_disable` 则会执行与上述过程相反的操作,即将驱动程序切回到 **init** 状态。
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_disable(handle));
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_disable(handle));
|
||||
}
|
||||
|
||||
.. _cam-start-stop:
|
||||
|
||||
启动和停止摄像头控制器驱动程序
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
从摄像头传感器接收信号之前,首先要调用 :cpp:func:`esp_cam_ctlr_start` 以启动摄像头控制器驱动程序。此函数:
|
||||
|
||||
* 将驱动程序状态从 **enable** 切换到 **start**。
|
||||
从摄像头传感器接收信号之前,首先要调用 :cpp:func:`esp_cam_ctlr_start` 以启动摄像头控制器驱动程序。此函数将驱动程序状态从 **enable** 切换到 **start**。
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_start(handle));
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle = NULL;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_start(handle));
|
||||
ESP_LOGI("CAM", "Camera controller started successfully");
|
||||
}
|
||||
|
||||
调用 :cpp:func:`esp_cam_ctlr_stop` 则会执行与上述过程相反的操作,即将驱动程序切回到 **enable** 状态。
|
||||
|
||||
.. code:: c
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_stop(handle));
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_cam_ctlr_handle_t handle = NULL;
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_stop(handle));
|
||||
}
|
||||
|
||||
.. _cam-receive:
|
||||
|
||||
@@ -226,6 +275,10 @@
|
||||
|
||||
.. code:: c
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_cam_ctlr.h"
|
||||
#include "esp_cam_ctlr_types.h"
|
||||
|
||||
ESP_ERROR_CHECK(esp_cam_ctlr_receive(handle, &my_trans, ESP_CAM_CTLR_MAX_DELAY));
|
||||
|
||||
.. _cam-callback:
|
||||
@@ -244,7 +297,7 @@
|
||||
线程安全
|
||||
^^^^^^^^
|
||||
|
||||
以下工厂函数:
|
||||
以下工厂函数由驱动程序保证线程安全。使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。
|
||||
|
||||
.. list::
|
||||
|
||||
@@ -252,8 +305,6 @@
|
||||
:SOC_ISP_DVP_SUPPORTED: - :cpp:func:`esp_cam_new_isp_dvp_ctlr`
|
||||
- :cpp:func:`esp_cam_ctlr_del`
|
||||
|
||||
由驱动程序保证线程安全。使用时,可以直接从不同的 RTOS 任务中调用此类函数,无需额外锁保护。
|
||||
|
||||
.. _cam-kconfig-options:
|
||||
|
||||
Kconfig 选项
|
||||
@@ -271,17 +322,15 @@ Kconfig 选项
|
||||
IRAM 安全
|
||||
^^^^^^^^^
|
||||
|
||||
默认情况下,当 cache 因写入或擦除 flash 等原因而被禁用时,CSI 中断将被推迟。
|
||||
默认情况下,当 cache 因写入或擦除 flash 等原因而被禁用时,CSI 中断将被推迟。这些中断会在 cache 重新启用后再被处理。
|
||||
|
||||
有以下 Kconfig 选项:
|
||||
以下 Kconfig 选项支持:
|
||||
|
||||
.. list::
|
||||
|
||||
:SOC_MIPI_CSI_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_MIPI_CSI_ISR_CACHE_SAFE`
|
||||
:SOC_ISP_DVP_SUPPORTED: - :ref:`CONFIG_CAM_CTLR_ISP_DVP_ISR_CACHE_SAFE`
|
||||
|
||||
这些选项支持
|
||||
|
||||
- 即使 cache 被禁用也能启用中断服务
|
||||
- 将 ISR 使用的所有函数放入 IRAM
|
||||
- 将驱动程序对象放入 DRAM(以防意外映射到 PSRAM)
|
||||
|
Reference in New Issue
Block a user