mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feat/isp_dsi_example' into 'master'
example(isp): added isp af example Closes IDF-9808 See merge request espressif/esp-idf!30469
This commit is contained in:
commit
895e6d5afc
@ -121,11 +121,11 @@ examples/peripherals/i2s/i2s_recorder:
|
|||||||
|
|
||||||
examples/peripherals/isp/auto_focus:
|
examples/peripherals/isp/auto_focus:
|
||||||
disable:
|
disable:
|
||||||
- if: INCLUDE_DEFAULT == 1
|
- if: SOC_MIPI_CSI_SUPPORTED != 1 or SOC_MIPI_DSI_SUPPORTED != 1 or SOC_ISP_SUPPORTED != 1
|
||||||
temporary: true
|
|
||||||
reason: disable build temporarily # TODO: IDF-8895
|
|
||||||
depends_components:
|
depends_components:
|
||||||
- esp_driver_isp
|
- esp_driver_isp
|
||||||
|
- esp_driver_cam
|
||||||
|
- esp_lcd
|
||||||
|
|
||||||
examples/peripherals/jpeg/jpeg_decode:
|
examples/peripherals/jpeg/jpeg_decode:
|
||||||
disable:
|
disable:
|
||||||
|
@ -17,7 +17,7 @@ The subsections below give only absolutely necessary information. For full steps
|
|||||||
|
|
||||||
This example requires:
|
This example requires:
|
||||||
|
|
||||||
- OV5647 camera sensor with VCM (Voice Coil Motor). The VCM used in this example is DW9714.
|
- OV5647 camera sensor
|
||||||
- ILI9881C LCD screen
|
- ILI9881C LCD screen
|
||||||
- ESP32P4 devkit
|
- ESP32P4 devkit
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
idf_component_register(SRCS "camera_dsi_main.c" "example_dsi_init.c"
|
idf_component_register(SRCS "camera_dsi_main.c"
|
||||||
INCLUDE_DIRS "."
|
INCLUDE_DIRS "."
|
||||||
REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c esp_lcd
|
REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c esp_lcd dsi_init
|
||||||
)
|
)
|
||||||
|
@ -12,8 +12,20 @@ menu "Example Configuration"
|
|||||||
help
|
help
|
||||||
Example used LDO voltage, in mV
|
Example used LDO voltage, in mV
|
||||||
|
|
||||||
choice EXAMPLE_MIPI_CSI_VRES
|
choice EXAMPLE_MIPI_CSI_DISP_HRES
|
||||||
bool "Set MIPI CSI verticol resolution"
|
bool "Set MIPI CSI horizontal resolution"
|
||||||
|
default EXAMPLE_MIPI_CSI_HRES_800
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_HRES_800
|
||||||
|
bool "800"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_DISP_HRES
|
||||||
|
int
|
||||||
|
default 800 if EXAMPLE_MIPI_CSI_HRES_800
|
||||||
|
|
||||||
|
choice EXAMPLE_MIPI_CSI_DISP_VRES
|
||||||
|
bool "Set MIPI CSI vertical resolution"
|
||||||
default EXAMPLE_MIPI_CSI_VRES_640
|
default EXAMPLE_MIPI_CSI_VRES_640
|
||||||
|
|
||||||
config EXAMPLE_MIPI_CSI_VRES_640
|
config EXAMPLE_MIPI_CSI_VRES_640
|
||||||
@ -22,4 +34,8 @@ menu "Example Configuration"
|
|||||||
bool "1280"
|
bool "1280"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_DISP_VRES
|
||||||
|
int
|
||||||
|
default 640 if EXAMPLE_MIPI_CSI_VRES_640
|
||||||
|
default 1280 if EXAMPLE_MIPI_CSI_VRES_1280
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -55,9 +55,9 @@ void app_main(void)
|
|||||||
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer);
|
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer);
|
||||||
|
|
||||||
//---------------Necessary variable config------------------//
|
//---------------Necessary variable config------------------//
|
||||||
frame_buffer_size = EXAMPLE_MIPI_CSI_DISP_HSIZE * EXAMPLE_MIPI_DSI_IMAGE_VSIZE * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
|
frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * EXAMPLE_MIPI_DSI_IMAGE_VSIZE * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
|
||||||
|
|
||||||
ESP_LOGD(TAG, "EXAMPLE_MIPI_CSI_DISP_HSIZE: %d, EXAMPLE_MIPI_DSI_IMAGE_VSIZE: %d, bits per pixel: %d", EXAMPLE_MIPI_CSI_DISP_HSIZE, EXAMPLE_MIPI_DSI_IMAGE_VSIZE, 8);
|
ESP_LOGD(TAG, "CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES: %d, EXAMPLE_MIPI_DSI_IMAGE_VSIZE: %d, bits per pixel: %d", CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, EXAMPLE_MIPI_DSI_IMAGE_VSIZE, 8);
|
||||||
ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size);
|
ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size);
|
||||||
ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer);
|
ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer);
|
||||||
|
|
||||||
@ -89,12 +89,8 @@ void app_main(void)
|
|||||||
//---------------CSI Init------------------//
|
//---------------CSI Init------------------//
|
||||||
esp_cam_ctlr_csi_config_t csi_config = {
|
esp_cam_ctlr_csi_config_t csi_config = {
|
||||||
.ctlr_id = 0,
|
.ctlr_id = 0,
|
||||||
.h_res = EXAMPLE_MIPI_CSI_DISP_HSIZE,
|
.h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES,
|
||||||
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
|
.v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES,
|
||||||
.v_res = EXAMPLE_MIPI_CSI_DISP_VSIZE_640P,
|
|
||||||
#else
|
|
||||||
.v_res = EXAMPLE_MIPI_CSI_DISP_VSIZE_1280P,
|
|
||||||
#endif
|
|
||||||
.lane_bit_rate_mbps = EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS,
|
.lane_bit_rate_mbps = EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS,
|
||||||
.input_data_color_type = MIPI_CSI_COLOR_RAW8,
|
.input_data_color_type = MIPI_CSI_COLOR_RAW8,
|
||||||
.output_data_color_type = MIPI_CSI_COLOR_RGB565,
|
.output_data_color_type = MIPI_CSI_COLOR_RGB565,
|
||||||
@ -129,12 +125,8 @@ void app_main(void)
|
|||||||
.output_data_color_type = ISP_COLOR_RGB565,
|
.output_data_color_type = ISP_COLOR_RGB565,
|
||||||
.has_line_start_packet = false,
|
.has_line_start_packet = false,
|
||||||
.has_line_end_packet = false,
|
.has_line_end_packet = false,
|
||||||
.h_res = EXAMPLE_MIPI_CSI_DISP_HSIZE,
|
.h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES,
|
||||||
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
|
.v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES,
|
||||||
.v_res = EXAMPLE_MIPI_CSI_DISP_VSIZE_640P,
|
|
||||||
#else
|
|
||||||
.v_res = EXAMPLE_MIPI_CSI_DISP_VSIZE_1280P,
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));
|
ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||||||
ESP_ERROR_CHECK(esp_isp_enable(isp_proc));
|
ESP_ERROR_CHECK(esp_isp_enable(isp_proc));
|
||||||
@ -174,7 +166,6 @@ void app_main(void)
|
|||||||
|
|
||||||
esp_cam_sensor_format_t *cam_cur_fmt = NULL;
|
esp_cam_sensor_format_t *cam_cur_fmt = NULL;
|
||||||
for (int i = 0; i < cam_fmt_array.count; i++) {
|
for (int i = 0; i < cam_fmt_array.count; i++) {
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
|
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
|
||||||
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) {
|
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) {
|
||||||
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
|
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
|
||||||
|
@ -12,24 +12,11 @@ extern "C" {
|
|||||||
|
|
||||||
#define EXAMPLE_RGB565_BITS_PER_PIXEL 16
|
#define EXAMPLE_RGB565_BITS_PER_PIXEL 16
|
||||||
#define EXAMPLE_MIPI_SCCB_FREQ (100000)
|
#define EXAMPLE_MIPI_SCCB_FREQ (100000)
|
||||||
#define EXAMPLE_MIPI_SCCB_SCL_IO (34)
|
#define EXAMPLE_MIPI_SCCB_SCL_IO (8)
|
||||||
#define EXAMPLE_MIPI_SCCB_SDA_IO (31)
|
#define EXAMPLE_MIPI_SCCB_SDA_IO (7)
|
||||||
#define EXAMPLE_MIPI_CSI_DISP_HSIZE 800
|
|
||||||
#define EXAMPLE_MIPI_CSI_DISP_VSIZE_640P 640
|
|
||||||
#define EXAMPLE_MIPI_CSI_DISP_VSIZE_1280P 1280
|
|
||||||
#define EXAMPLE_MIPI_CSI_640P 1
|
|
||||||
#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000)
|
#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000)
|
||||||
#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4
|
#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4
|
||||||
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_HSIZE 800
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_VSIZE 1280
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_HSYNC 40
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_HBP 140
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_HFP 40
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_VSYNC 4
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_VBP 16
|
|
||||||
#define EXAMPLE_MIPI_DSI_IMAGE_VFP 16
|
|
||||||
|
|
||||||
#define EXAMPLE_OV5647_DEV_ADDR 0x36
|
#define EXAMPLE_OV5647_DEV_ADDR 0x36
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,5 @@ dependencies:
|
|||||||
espressif/esp_lcd_ili9881c: "*"
|
espressif/esp_lcd_ili9881c: "*"
|
||||||
idf:
|
idf:
|
||||||
version: ">=5.3.0"
|
version: ">=5.3.0"
|
||||||
|
dsi_init:
|
||||||
|
path: ${IDF_PATH}/examples/peripherals/camera/components/dsi_init
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "example_dsi_init.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES esp_lcd
|
||||||
|
)
|
@ -6,14 +6,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_heap_caps.h"
|
|
||||||
#include "esp_lcd_mipi_dsi.h"
|
#include "esp_lcd_mipi_dsi.h"
|
||||||
#include "esp_lcd_panel_ops.h"
|
#include "esp_lcd_panel_ops.h"
|
||||||
#include "esp_lcd_ili9881c.h"
|
#include "esp_lcd_ili9881c.h"
|
||||||
#include "esp_ldo_regulator.h"
|
|
||||||
#include "esp_cache.h"
|
|
||||||
#include "example_dsi_init.h"
|
#include "example_dsi_init.h"
|
||||||
#include "example_config.h"
|
|
||||||
|
|
||||||
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer)
|
void example_dsi_resource_alloc(esp_lcd_panel_handle_t *ili9881c_ctrl_panel, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer)
|
||||||
{
|
{
|
@ -10,6 +10,15 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_HSIZE 800
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_VSIZE 1280
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_HSYNC 40
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_HBP 140
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_HFP 40
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_VSYNC 4
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_VBP 16
|
||||||
|
#define EXAMPLE_MIPI_DSI_IMAGE_VFP 16
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief DSI init function
|
* @brief DSI init function
|
||||||
*
|
*
|
@ -0,0 +1,4 @@
|
|||||||
|
dependencies:
|
||||||
|
espressif/esp_lcd_ili9881c: "^0.2.0"
|
||||||
|
idf:
|
||||||
|
version: ">=5.3.0"
|
6
examples/peripherals/isp/auto_focus/CMakeLists.txt
Normal file
6
examples/peripherals/isp/auto_focus/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||||
|
# in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(isp_af_dsi)
|
141
examples/peripherals/isp/auto_focus/README.md
Normal file
141
examples/peripherals/isp/auto_focus/README.md
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
| Supported Targets | ESP32-P4 |
|
||||||
|
| ----------------- | -------- |
|
||||||
|
|
||||||
|
|
||||||
|
# Camera display via DSI example
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This example demonstrates how to use the ISP (image signal processor) to work with esp_driver_cam component. This example will capture camera sensor signals via CSI interface and display it via DSI interface. This example also enables the ISP AF (auto-focus) feature.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The subsections below give only absolutely necessary information. For full steps to configure ESP-IDF and use it to build and run projects, see [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started).
|
||||||
|
|
||||||
|
|
||||||
|
### Hardware Required
|
||||||
|
|
||||||
|
This example requires:
|
||||||
|
|
||||||
|
- OV5647 camera sensor with VCM (Voice Coil Motor). The VCM used in this example is DW9714.
|
||||||
|
- ILI9881C LCD screen
|
||||||
|
- ESP32P4 devkit
|
||||||
|
|
||||||
|
|
||||||
|
GND GND
|
||||||
|
┌────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ┌───────────────┴─────────────┴──────────────────┐ │
|
||||||
|
│ │ │ ┌──────────┴───────────┐
|
||||||
|
│ │ │ DSI DATA 1P │ │
|
||||||
|
│ │ ├───────────────────────────┤ │
|
||||||
|
┌───────────┴─────────┐ CSI DATA 1P │ │ │ │
|
||||||
|
│ ├──────────────────────┤ │ DSI DATA 1N │ │
|
||||||
|
│ │ │ ├───────────────────────────┤ │
|
||||||
|
│ │ CSI DATA 1N │ ESP32-P4 │ │ │
|
||||||
|
│ OV5647 ├──────────────────────┤ │ DSI CLK N │ ILI9881C │
|
||||||
|
│ │ │ ├───────────────────────────┤ │
|
||||||
|
│ │ CSI CLK N │ │ │ │
|
||||||
|
│ ├──────────────────────┤ │ DSI CLK P │ │
|
||||||
|
│ │ │ ├───────────────────────────┤ │
|
||||||
|
│ │ CSI CLK P │ │ │ │
|
||||||
|
│ ├──────────────────────┤ │ DSI DATA 0P │ │
|
||||||
|
│ │ │ ├───────────────────────────┤ │
|
||||||
|
│ │ CSI DATA 0P │ │ │ │
|
||||||
|
│ ├──────────────────────┤ │ DSI DATA 0N │ │
|
||||||
|
│ │ │ ├───────────────────────────┤ │
|
||||||
|
│ │ CSI DATA 0N │ │ │ │
|
||||||
|
│ ├──────────────────────┤ │ └──────────────────────┘
|
||||||
|
│ │ │ │
|
||||||
|
└───────┬──┬──────────┘ │ │
|
||||||
|
│ │ I2C SCL │ │
|
||||||
|
│ └─────────────────────────────────┤ │
|
||||||
|
│ I2C SDA │ │
|
||||||
|
└────────────────────────────────────┤ │
|
||||||
|
└────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
|
||||||
|
### Set Chip Target
|
||||||
|
|
||||||
|
First of all, your target must be supported by both:
|
||||||
|
|
||||||
|
- **By your ESP-IDF version**: For the full list of supported targets, run:
|
||||||
|
```
|
||||||
|
idf.py --list-targets
|
||||||
|
```
|
||||||
|
- **By this example**: For the full list of supported targets, refer to the supported targets table at the top of this README.
|
||||||
|
|
||||||
|
After you make sure that your target is supported, go to your example project directory and [set the chip target](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/tools/idf-py.html#select-the-target-chip-set-target):
|
||||||
|
|
||||||
|
```
|
||||||
|
idf.py set-target <target>
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, to set esp32-P4 as the chip target, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
idf.py set-target esp32p4
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Configure the Project
|
||||||
|
|
||||||
|
For information about Kconfig options, see [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) > _Name of relevant section(s)_.
|
||||||
|
|
||||||
|
To conveniently check or modify Kconfig options for this example in a project configuration menu, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
idf.py menuconfig
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
Set CONFIG_CAMERA_OV5647 to y
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Build and Flash
|
||||||
|
|
||||||
|
Execute the following command to build the project, flash it to your development board, and run the monitor tool to view the serial output:
|
||||||
|
|
||||||
|
```
|
||||||
|
idf.py build flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
This command can be reduced to `idf.py flash monitor`.
|
||||||
|
|
||||||
|
If the above command fails, check the log on the serial monitor which usually provides information on the possible cause of the issue.
|
||||||
|
|
||||||
|
To exit the serial monitor, use `Ctrl` + `]`.
|
||||||
|
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
If you see the following console output, your example should be running correctly:
|
||||||
|
|
||||||
|
```
|
||||||
|
I (1085) main_task: Calling app_main()
|
||||||
|
I (1095) ili9881c: ID1: 0x98, ID2: 0x81, ID3: 0x5c
|
||||||
|
I (1125) gpio: GPIO[31]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||||
|
I (1125) gpio: GPIO[34]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0
|
||||||
|
I (1295) ov5647: Detected Camera sensor PID=0x5647 with index 0
|
||||||
|
I (1305) cam_dsi: fmt[0].name:MIPI_2lane_24Minput_RAW8_800x1280_50fps
|
||||||
|
I (1305) cam_dsi: fmt[1].name:MIPI_2lane_24Minput_RAW8_800x640_50fps
|
||||||
|
I (1315) cam_dsi: fmt[2].name:MIPI_2lane_24Minput_RAW8_800x800_50fps
|
||||||
|
I (1355) cam_dsi: Format in use:MIPI_2lane_24Minput_RAW8_800x640_50fps
|
||||||
|
```
|
||||||
|
|
||||||
|
You will also see the screen auto-focus when the screen image changes.
|
||||||
|
|
||||||
|
## Reference
|
||||||
|
|
||||||
|
- Link to the ESP-IDF camera controller driver API reference, [ESP-IDF: Camera Controller Driver](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/camera_driver.html)
|
||||||
|
- Link to the ESP-IDF ISP driver API reference, [ESP-IDF: Image Signal Processor](https://docs.espressif.com/projects/esp-idf/en/latest/esp32p4/api-reference/peripherals/isp.html)
|
||||||
|
- [ESP-IDF Getting Started](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html#get-started)
|
||||||
|
- [Project Configuration](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/kconfig.html) (Kconfig Options)
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -33,8 +33,9 @@ typedef struct {
|
|||||||
* @brief Sensor driver API to set sensor focus value
|
* @brief Sensor driver API to set sensor focus value
|
||||||
*
|
*
|
||||||
* @param[in] focus_val Camera sensor focus value
|
* @param[in] focus_val Camera sensor focus value
|
||||||
|
* @param[in] arg User arg
|
||||||
*/
|
*/
|
||||||
esp_err_t (*af_sensor_set_focus)(int focus_val);
|
esp_err_t (*af_sensor_set_focus)(int focus_val, void *arg);
|
||||||
|
|
||||||
} isp_af_sa_scheme_sensor_drv_t;
|
} isp_af_sa_scheme_sensor_drv_t;
|
||||||
|
|
||||||
@ -72,13 +73,14 @@ esp_err_t isp_af_delete_sa_scheme(isp_af_scheme_handle_t scheme);
|
|||||||
* @param[in] scheme AF scheme handle
|
* @param[in] scheme AF scheme handle
|
||||||
* @param[in] sensor_drv Sensor driver, see `isp_af_sa_scheme_sensor_drv_t`
|
* @param[in] sensor_drv Sensor driver, see `isp_af_sa_scheme_sensor_drv_t`
|
||||||
* @param[in] info Sensor info
|
* @param[in] info Sensor info
|
||||||
|
* @param[in] arg User arg
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK On success
|
* - ESP_OK On success
|
||||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||||
* - ESP_ERR_INVALID_STATE Invalid state
|
* - ESP_ERR_INVALID_STATE Invalid state
|
||||||
*/
|
*/
|
||||||
esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info);
|
esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info, void *arg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -29,6 +29,7 @@ typedef struct {
|
|||||||
|
|
||||||
isp_af_sa_scheme_sensor_info_t sensor_info;
|
isp_af_sa_scheme_sensor_info_t sensor_info;
|
||||||
isp_af_sa_scheme_sensor_drv_t sensor_drv;
|
isp_af_sa_scheme_sensor_drv_t sensor_drv;
|
||||||
|
void *arg;
|
||||||
} af_scheme_context_t;
|
} af_scheme_context_t;
|
||||||
|
|
||||||
/* ------------------------ Interface Functions --------------------------- */
|
/* ------------------------ Interface Functions --------------------------- */
|
||||||
@ -78,7 +79,7 @@ esp_err_t isp_af_delete_sa_scheme(isp_af_scheme_handle_t scheme)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info)
|
esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme, const isp_af_sa_scheme_sensor_drv_t *sensor_drv, const isp_af_sa_scheme_sensor_info_t *info, void *arg)
|
||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(scheme, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer");
|
ESP_RETURN_ON_FALSE(scheme, ESP_ERR_INVALID_ARG, TAG, "invalid arg: null pointer");
|
||||||
ESP_RETURN_ON_FALSE(scheme->ctx, ESP_ERR_INVALID_STATE, TAG, "no scheme created yet");
|
ESP_RETURN_ON_FALSE(scheme->ctx, ESP_ERR_INVALID_STATE, TAG, "no scheme created yet");
|
||||||
@ -86,6 +87,7 @@ esp_err_t isp_af_sa_scheme_register_sensor_driver(isp_af_scheme_handle_t scheme,
|
|||||||
af_scheme_context_t *ctx = scheme->ctx;
|
af_scheme_context_t *ctx = scheme->ctx;
|
||||||
ctx->sensor_drv.af_sensor_set_focus = sensor_drv->af_sensor_set_focus;
|
ctx->sensor_drv.af_sensor_set_focus = sensor_drv->af_sensor_set_focus;
|
||||||
ctx->sensor_info.focus_val_max = info->focus_val_max;
|
ctx->sensor_info.focus_val_max = info->focus_val_max;
|
||||||
|
ctx->arg = arg;
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -117,7 +119,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu
|
|||||||
|
|
||||||
isp_af_result_t result = {};
|
isp_af_result_t result = {};
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(0), TAG, "sensor set focus val fail");
|
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(0, ctx->arg), TAG, "sensor set focus val fail");
|
||||||
|
|
||||||
ESP_LOGV(TAG, "//----------- af start ----------//");
|
ESP_LOGV(TAG, "//----------- af start ----------//");
|
||||||
|
|
||||||
@ -128,7 +130,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu
|
|||||||
|
|
||||||
for (int x = 0; x <= ctx->first_approx_cycles; x++) {
|
for (int x = 0; x <= ctx->first_approx_cycles; x++) {
|
||||||
af_current = af_current_base + x * ctx->first_step_val;
|
af_current = af_current_base + x * ctx->first_step_val;
|
||||||
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current), TAG, "sensor set focus val fail");
|
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current, ctx->arg), TAG, "sensor set focus val fail");
|
||||||
ESP_RETURN_ON_ERROR(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result), TAG, "get AF result fail");
|
ESP_RETURN_ON_ERROR(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result), TAG, "get AF result fail");
|
||||||
af_sum = result.definition[0] + result.definition[1] + result.definition[2];
|
af_sum = result.definition[0] + result.definition[1] + result.definition[2];
|
||||||
if (af_sum > af_sum_max) {
|
if (af_sum > af_sum_max) {
|
||||||
@ -154,7 +156,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu
|
|||||||
af_current = 0;
|
af_current = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current), TAG, "sensor set focus val fail");
|
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current, ctx->arg), TAG, "sensor set focus val fail");
|
||||||
ESP_RETURN_ON_ERROR(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result), TAG, "get AF result fail");
|
ESP_RETURN_ON_ERROR(esp_isp_af_controller_get_oneshot_result(ctx->af_ctlr, &result), TAG, "get AF result fail");
|
||||||
af_sum = result.definition[0] + result.definition[1] + result.definition[2];
|
af_sum = result.definition[0] + result.definition[1] + result.definition[2];
|
||||||
if (af_sum > af_sum_max) {
|
if (af_sum > af_sum_max) {
|
||||||
@ -167,7 +169,7 @@ static esp_err_t s_af_process(void *arg, int *out_definition_thresh, int *out_lu
|
|||||||
// af done
|
// af done
|
||||||
ESP_LOGV(TAG, "//----------- af done ----------//");
|
ESP_LOGV(TAG, "//----------- af done ----------//");
|
||||||
ESP_LOGV(TAG, "af_sum_max: %d, af_current_best: %d.%d", af_sum_max, (int)af_current_best, (int)((int)(af_current_best * 1000) % 1000));
|
ESP_LOGV(TAG, "af_sum_max: %d, af_current_best: %d.%d", af_sum_max, (int)af_current_best, (int)((int)(af_current_best * 1000) % 1000));
|
||||||
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current_best), TAG, "sensor set focus val fail");
|
ESP_RETURN_ON_ERROR(ctx->sensor_drv.af_sensor_set_focus(af_current_best, ctx->arg), TAG, "sensor set focus val fail");
|
||||||
|
|
||||||
// update env threshold
|
// update env threshold
|
||||||
ESP_LOGV(TAG, "//------- update env threshold -------//");
|
ESP_LOGV(TAG, "//------- update env threshold -------//");
|
||||||
|
4
examples/peripherals/isp/auto_focus/main/CMakeLists.txt
Normal file
4
examples/peripherals/isp/auto_focus/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "isp_af_dsi_main.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES esp_mm esp_driver_isp esp_driver_cam esp_driver_i2c esp_lcd dsi_init
|
||||||
|
)
|
41
examples/peripherals/isp/auto_focus/main/Kconfig.projbuild
Normal file
41
examples/peripherals/isp/auto_focus/main/Kconfig.projbuild
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
menu "Example Configuration"
|
||||||
|
config EXAMPLE_USED_LDO_CHAN_ID
|
||||||
|
int "example used LDO channel ID"
|
||||||
|
default 3
|
||||||
|
help
|
||||||
|
Example used LDO channel ID, you may check datasheet to know more details.
|
||||||
|
|
||||||
|
config EXAMPLE_USED_LDO_VOLTAGE_MV
|
||||||
|
int "example used LDO voltage in mV"
|
||||||
|
default 2500
|
||||||
|
range 0 3300
|
||||||
|
help
|
||||||
|
Example used LDO voltage, in mV
|
||||||
|
|
||||||
|
choice EXAMPLE_MIPI_CSI_DISP_HRES
|
||||||
|
bool "Set MIPI CSI horizontal resolution"
|
||||||
|
default EXAMPLE_MIPI_CSI_HRES_800
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_HRES_800
|
||||||
|
bool "800"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_DISP_HRES
|
||||||
|
int
|
||||||
|
default 800 if EXAMPLE_MIPI_CSI_HRES_800
|
||||||
|
|
||||||
|
choice EXAMPLE_MIPI_CSI_DISP_VRES
|
||||||
|
bool "Set MIPI CSI vertical resolution"
|
||||||
|
default EXAMPLE_MIPI_CSI_VRES_640
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_VRES_640
|
||||||
|
bool "640"
|
||||||
|
config EXAMPLE_MIPI_CSI_VRES_1280
|
||||||
|
bool "1280"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config EXAMPLE_MIPI_CSI_DISP_VRES
|
||||||
|
int
|
||||||
|
default 640 if EXAMPLE_MIPI_CSI_VRES_640
|
||||||
|
default 1280 if EXAMPLE_MIPI_CSI_VRES_1280
|
||||||
|
endmenu
|
24
examples/peripherals/isp/auto_focus/main/example_config.h
Normal file
24
examples/peripherals/isp/auto_focus/main/example_config.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define EXAMPLE_RGB565_BITS_PER_PIXEL 16
|
||||||
|
#define EXAMPLE_MIPI_SCCB_FREQ (100000)
|
||||||
|
#define EXAMPLE_MIPI_SCCB_SCL_IO (8)
|
||||||
|
#define EXAMPLE_MIPI_SCCB_SDA_IO (7)
|
||||||
|
#define EXAMPLE_MIPI_IDI_CLOCK_RATE (50000000)
|
||||||
|
#define EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS 200 //line_rate = pclk * 4
|
||||||
|
|
||||||
|
#define EXAMPLE_OV5647_DEV_ADDR 0x36
|
||||||
|
#define EXAMPLE_DW9714_DEV_ADDR 0xC
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,9 @@
|
|||||||
|
dependencies:
|
||||||
|
espressif/esp_cam_sensor: "^0.2.2"
|
||||||
|
espressif/esp_lcd_ili9881c: "*"
|
||||||
|
idf:
|
||||||
|
version: ">=5.3.0"
|
||||||
|
isp_af_schemes:
|
||||||
|
path: ${IDF_PATH}/examples/peripherals/isp/auto_focus/components/isp_af_schemes
|
||||||
|
dsi_init:
|
||||||
|
path: ${IDF_PATH}/examples/peripherals/camera/components/dsi_init
|
357
examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c
Normal file
357
examples/peripherals/isp/auto_focus/main/isp_af_dsi_main.c
Normal file
@ -0,0 +1,357 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "esp_lcd_mipi_dsi.h"
|
||||||
|
#include "esp_lcd_panel_ops.h"
|
||||||
|
#include "esp_lcd_ili9881c.h"
|
||||||
|
#include "esp_ldo_regulator.h"
|
||||||
|
#include "esp_cache.h"
|
||||||
|
#include "driver/i2c_master.h"
|
||||||
|
#include "driver/isp.h"
|
||||||
|
#include "isp_af_scheme_sa.h"
|
||||||
|
#include "esp_cam_ctlr_csi.h"
|
||||||
|
#include "esp_cam_ctlr.h"
|
||||||
|
#include "esp_sccb_intf.h"
|
||||||
|
#include "esp_sccb_i2c.h"
|
||||||
|
#include "esp_cam_sensor.h"
|
||||||
|
#include "ov5647.h"
|
||||||
|
#include "example_dsi_init.h"
|
||||||
|
#include "example_config.h"
|
||||||
|
|
||||||
|
static const char *TAG = "isp_dsi";
|
||||||
|
|
||||||
|
static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data);
|
||||||
|
static bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data);
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint16_t s : 4;
|
||||||
|
uint16_t d : 10;
|
||||||
|
uint16_t flag : 1;
|
||||||
|
uint16_t pd : 1;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
uint16_t byte2 : 8;
|
||||||
|
uint16_t byte1 : 8;
|
||||||
|
};
|
||||||
|
uint16_t val;
|
||||||
|
} dw9714_reg_t;
|
||||||
|
|
||||||
|
static bool IRAM_ATTR s_env_change_cb(isp_af_ctrlr_t af_ctrlr, const esp_isp_af_env_detector_evt_data_t *edata, void *user_data)
|
||||||
|
{
|
||||||
|
BaseType_t mustYield = pdFALSE;
|
||||||
|
TaskHandle_t task_handle = (TaskHandle_t)user_data;
|
||||||
|
vTaskNotifyGiveFromISR(task_handle, &mustYield);
|
||||||
|
|
||||||
|
return (mustYield == pdTRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t s_sensor_set_focus_val(int focus_val, void *arg)
|
||||||
|
{
|
||||||
|
esp_sccb_io_handle_t dw9714_io_handle = arg;
|
||||||
|
|
||||||
|
dw9714_reg_t reg = {0};
|
||||||
|
reg.d = (uint16_t)((focus_val / 120.0) * 1023.0);
|
||||||
|
|
||||||
|
uint8_t data[2] = {0};
|
||||||
|
data[0] = reg.byte1;
|
||||||
|
data[1] = reg.byte2;
|
||||||
|
|
||||||
|
uint16_t reg_addr = (data[0] << 8) + (data[1]);
|
||||||
|
uint8_t reg_val = 0;
|
||||||
|
|
||||||
|
esp_err_t ret = esp_sccb_transmit_reg_a16v8(dw9714_io_handle, reg_addr, reg_val);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
printf("dw9714 esp_sccb_transmit_reg_a16v8 failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void af_task(void *arg)
|
||||||
|
{
|
||||||
|
TaskHandle_t task_handle = xTaskGetCurrentTaskHandle();
|
||||||
|
|
||||||
|
typedef struct af_task_param_t {
|
||||||
|
isp_proc_handle_t isp_proc;
|
||||||
|
esp_sccb_io_handle_t dw9714_io_handle;
|
||||||
|
} af_task_param_t;
|
||||||
|
|
||||||
|
af_task_param_t af_task_param = *(af_task_param_t *)arg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AF window, windows for ISP hardware to record the
|
||||||
|
* - lunimance
|
||||||
|
* - definition
|
||||||
|
* of the current windows
|
||||||
|
*/
|
||||||
|
esp_isp_af_config_t af_config = {
|
||||||
|
.window = {
|
||||||
|
[0] = {
|
||||||
|
.top_left_x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) - 100,
|
||||||
|
.bottom_right_x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) + 99,
|
||||||
|
.top_left_y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) - 100,
|
||||||
|
.bottom_right_y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) + 99,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.top_left_x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) - 100,
|
||||||
|
.bottom_right_x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) + 99,
|
||||||
|
.top_left_y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) - 100,
|
||||||
|
.bottom_right_y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) + 99,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
.top_left_x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) - 100,
|
||||||
|
.bottom_right_x = (CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES / 2) + 99,
|
||||||
|
.top_left_y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) - 100,
|
||||||
|
.bottom_right_y = (CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES / 2) + 99,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.edge_thresh = 128,
|
||||||
|
};
|
||||||
|
|
||||||
|
isp_af_ctrlr_t af_ctrlr = NULL;
|
||||||
|
ESP_ERROR_CHECK(esp_isp_new_af_controller(af_task_param.isp_proc, &af_config, &af_ctrlr));
|
||||||
|
|
||||||
|
esp_isp_af_env_config_t env_config = {
|
||||||
|
.interval = 10,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_isp_af_controller_set_env_detector(af_ctrlr, &env_config));
|
||||||
|
|
||||||
|
esp_isp_af_env_detector_evt_cbs_t cbs = {
|
||||||
|
.on_env_change = s_env_change_cb,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_isp_af_env_detector_register_event_callbacks(af_ctrlr, &cbs, task_handle));
|
||||||
|
|
||||||
|
isp_af_sa_scheme_config_t af_scheme_config = {
|
||||||
|
.first_step_val = 12,
|
||||||
|
.first_approx_cycles = 10,
|
||||||
|
.second_step_val = 2,
|
||||||
|
.second_approx_cycles = 10,
|
||||||
|
};
|
||||||
|
isp_af_scheme_handle_t af_scheme = NULL;
|
||||||
|
ESP_ERROR_CHECK(isp_af_create_sa_scheme(af_ctrlr, &af_scheme_config, &af_scheme));
|
||||||
|
|
||||||
|
isp_af_sa_scheme_sensor_drv_t sensor_driver = {
|
||||||
|
.af_sensor_set_focus = s_sensor_set_focus_val,
|
||||||
|
};
|
||||||
|
isp_af_sa_scheme_sensor_info_t sensor_info = {
|
||||||
|
.focus_val_max = 120,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(isp_af_sa_scheme_register_sensor_driver(af_scheme, &sensor_driver, &sensor_info, af_task_param.dw9714_io_handle));
|
||||||
|
|
||||||
|
int definition_thresh = 0;
|
||||||
|
int luminance_thresh = 0;
|
||||||
|
ESP_ERROR_CHECK(esp_isp_af_controller_enable(af_ctrlr));
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
ESP_ERROR_CHECK(isp_af_process(af_scheme, &definition_thresh, &luminance_thresh));
|
||||||
|
ESP_ERROR_CHECK(esp_isp_af_controller_set_env_detector_threshold(af_ctrlr, definition_thresh, luminance_thresh));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_FAIL;
|
||||||
|
esp_lcd_panel_handle_t ili9881c_ctrl_panel = NULL;
|
||||||
|
esp_lcd_panel_handle_t mipi_dpi_panel = NULL;
|
||||||
|
void *frame_buffer = NULL;
|
||||||
|
size_t frame_buffer_size = 0;
|
||||||
|
|
||||||
|
//mipi ldo
|
||||||
|
esp_ldo_channel_handle_t ldo_mipi_phy = NULL;
|
||||||
|
esp_ldo_channel_config_t ldo_mipi_phy_config = {
|
||||||
|
.chan_id = CONFIG_EXAMPLE_USED_LDO_CHAN_ID,
|
||||||
|
.voltage_mv = CONFIG_EXAMPLE_USED_LDO_VOLTAGE_MV,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @background
|
||||||
|
* Sensor use RAW8
|
||||||
|
* ISP convert to RGB565
|
||||||
|
*/
|
||||||
|
//---------------DSI Init------------------//
|
||||||
|
example_dsi_resource_alloc(&ili9881c_ctrl_panel, &mipi_dpi_panel, &frame_buffer);
|
||||||
|
|
||||||
|
//---------------Necessary variable config------------------//
|
||||||
|
frame_buffer_size = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES * EXAMPLE_MIPI_DSI_IMAGE_VSIZE * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES: %d, EXAMPLE_MIPI_DSI_IMAGE_VSIZE: %d, bits per pixel: %d", CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES, EXAMPLE_MIPI_DSI_IMAGE_VSIZE, 8);
|
||||||
|
ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size);
|
||||||
|
ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer);
|
||||||
|
|
||||||
|
esp_cam_ctlr_trans_t new_trans = {
|
||||||
|
.buffer = frame_buffer,
|
||||||
|
.buflen = frame_buffer_size,
|
||||||
|
};
|
||||||
|
|
||||||
|
//---------------I2C Init------------------//
|
||||||
|
i2c_master_bus_config_t i2c_bus_conf = {
|
||||||
|
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||||
|
.sda_io_num = EXAMPLE_MIPI_SCCB_SDA_IO,
|
||||||
|
.scl_io_num = EXAMPLE_MIPI_SCCB_SCL_IO,
|
||||||
|
.i2c_port = I2C_NUM_0,
|
||||||
|
.flags.enable_internal_pullup = true,
|
||||||
|
};
|
||||||
|
i2c_master_bus_handle_t bus_handle = NULL;
|
||||||
|
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_conf, &bus_handle));
|
||||||
|
|
||||||
|
//---------------SCCB Init------------------//
|
||||||
|
esp_sccb_io_handle_t ov5647_io_handle = NULL;
|
||||||
|
sccb_i2c_config_t i2c_config = {
|
||||||
|
.scl_speed_hz = EXAMPLE_MIPI_SCCB_FREQ,
|
||||||
|
.device_address = EXAMPLE_OV5647_DEV_ADDR,
|
||||||
|
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &ov5647_io_handle));
|
||||||
|
|
||||||
|
esp_sccb_io_handle_t dw9714_io_handle = NULL;
|
||||||
|
i2c_config.device_address = EXAMPLE_DW9714_DEV_ADDR;
|
||||||
|
ESP_ERROR_CHECK(sccb_new_i2c_io(bus_handle, &i2c_config, &dw9714_io_handle));
|
||||||
|
|
||||||
|
//---------------CSI Init------------------//
|
||||||
|
esp_cam_ctlr_csi_config_t csi_config = {
|
||||||
|
.ctlr_id = 0,
|
||||||
|
.h_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES,
|
||||||
|
.v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES,
|
||||||
|
.lane_bit_rate_mbps = EXAMPLE_MIPI_CSI_LANE_BITRATE_MBPS,
|
||||||
|
.input_data_color_type = MIPI_CSI_COLOR_RAW8,
|
||||||
|
.output_data_color_type = MIPI_CSI_COLOR_RGB565,
|
||||||
|
.data_lane_num = 2,
|
||||||
|
.byte_swap_en = false,
|
||||||
|
.queue_items = 1,
|
||||||
|
};
|
||||||
|
esp_cam_ctlr_handle_t handle = NULL;
|
||||||
|
ret = esp_cam_new_csi_ctlr(&csi_config, &handle);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "csi init fail[%d]", ret);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_cam_ctlr_evt_cbs_t cbs = {
|
||||||
|
.on_get_new_trans = s_camera_get_new_vb,
|
||||||
|
.on_trans_finished = s_camera_get_finished_trans,
|
||||||
|
};
|
||||||
|
if (esp_cam_ctlr_register_event_callbacks(handle, &cbs, &new_trans) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "ops register fail");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(esp_cam_ctlr_enable(handle));
|
||||||
|
//---------------ISP Init------------------//
|
||||||
|
isp_proc_handle_t isp_proc = NULL;
|
||||||
|
esp_isp_processor_cfg_t isp_config = {
|
||||||
|
.clk_hz = 80 * 1000 * 1000,
|
||||||
|
.input_data_source = ISP_INPUT_DATA_SOURCE_CSI,
|
||||||
|
.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 = CONFIG_EXAMPLE_MIPI_CSI_DISP_HRES,
|
||||||
|
.v_res = CONFIG_EXAMPLE_MIPI_CSI_DISP_VRES,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(esp_isp_new_processor(&isp_config, &isp_proc));
|
||||||
|
ESP_ERROR_CHECK(esp_isp_enable(isp_proc));
|
||||||
|
|
||||||
|
typedef struct af_task_param_t {
|
||||||
|
isp_proc_handle_t isp_proc;
|
||||||
|
esp_sccb_io_handle_t dw9714_io_handle;
|
||||||
|
} af_task_param_t;
|
||||||
|
|
||||||
|
af_task_param_t af_task_param = {
|
||||||
|
.isp_proc = isp_proc,
|
||||||
|
.dw9714_io_handle = dw9714_io_handle,
|
||||||
|
};
|
||||||
|
xTaskCreatePinnedToCore(af_task, "af_task", 8192, &af_task_param, 5, NULL, 0);
|
||||||
|
|
||||||
|
//---------------DSI Panel Init------------------//
|
||||||
|
example_dsi_ili9881c_panel_init(ili9881c_ctrl_panel);
|
||||||
|
|
||||||
|
//init to all white
|
||||||
|
memset(frame_buffer, 0xFF, frame_buffer_size);
|
||||||
|
esp_cache_msync((void *)frame_buffer, frame_buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||||
|
|
||||||
|
if (esp_cam_ctlr_start(handle) != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Driver start fail");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_cam_sensor_config_t cam_config = {
|
||||||
|
.sccb_handle = ov5647_io_handle,
|
||||||
|
.reset_pin = -1,
|
||||||
|
.pwdn_pin = -1,
|
||||||
|
.xclk_pin = -1,
|
||||||
|
.sensor_port = ESP_CAM_SENSOR_MIPI_CSI,
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_cam_sensor_device_t *cam = ov5647_detect(&cam_config);
|
||||||
|
if (!cam) {
|
||||||
|
ESP_LOGE(TAG, "failed to detect 5647");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_cam_sensor_format_array_t cam_fmt_array = {0};
|
||||||
|
esp_cam_sensor_query_format(cam, &cam_fmt_array);
|
||||||
|
const esp_cam_sensor_format_t *parray = cam_fmt_array.format_array;
|
||||||
|
for (int i = 0; i < cam_fmt_array.count; i++) {
|
||||||
|
ESP_LOGI(TAG, "fmt[%d].name:%s", i, parray[i].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_cam_sensor_format_t *cam_cur_fmt = NULL;
|
||||||
|
for (int i = 0; i < cam_fmt_array.count; i++) {
|
||||||
|
#if CONFIG_EXAMPLE_MIPI_CSI_VRES_640
|
||||||
|
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x640_50fps")) {
|
||||||
|
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (!strcmp(parray[i].name, "MIPI_2lane_24Minput_RAW8_800x1280_50fps")) {
|
||||||
|
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Format set fail");
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Format in use:%s", cam_cur_fmt->name);
|
||||||
|
}
|
||||||
|
int enable_flag = 1;
|
||||||
|
// Set sensor output stream
|
||||||
|
ret = esp_cam_sensor_ioctl(cam, ESP_CAM_SENSOR_IOC_S_STREAM, &enable_flag);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Start stream fail");
|
||||||
|
}
|
||||||
|
|
||||||
|
example_dpi_panel_init(mipi_dpi_panel);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
ESP_ERROR_CHECK(esp_cam_ctlr_receive(handle, &new_trans, ESP_CAM_CTLR_MAX_DELAY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool s_camera_get_new_vb(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)
|
||||||
|
{
|
||||||
|
esp_cam_ctlr_trans_t new_trans = *(esp_cam_ctlr_trans_t *)user_data;
|
||||||
|
trans->buffer = new_trans.buffer;
|
||||||
|
trans->buflen = new_trans.buflen;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool s_camera_get_finished_trans(esp_cam_ctlr_handle_t handle, esp_cam_ctlr_trans_t *trans, void *user_data)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
4
examples/peripherals/isp/auto_focus/sdkconfig.defaults
Normal file
4
examples/peripherals/isp/auto_focus/sdkconfig.defaults
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_SPIRAM=y
|
||||||
|
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
|
||||||
|
CONFIG_SPIRAM_SPEED_200M=y
|
||||||
|
CONFIG_CAMERA_OV5647=y
|
Loading…
Reference in New Issue
Block a user