Merge branch 'feature/add_sc030iot_dvp_cam_support' into 'master'

feat(isp_dvp): add SC030IOT camera support to dvp_isp_dsi example

See merge request espressif/esp-idf!38521
This commit is contained in:
Song Ruo Jing
2025-04-23 18:36:35 +08:00
12 changed files with 103 additions and 39 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -28,9 +28,9 @@ typedef struct {
int de_io; ///< ISP DVP de IO numbers
struct {
uint32_t pclk_invert: 1; ///< The pclk is inverted
uint32_t hsync_invert: 1; ///< The hsync signal is inverted
uint32_t vsync_invert: 1; ///< The vsync signal is inverted
uint32_t de_invert: 1; ///< The de signal is inverted
uint32_t hsync_invert: 1; ///< The hsync signal is inverted (i.e. active low)
uint32_t vsync_invert: 1; ///< The vsync signal is inverted (i.e. active high)
uint32_t de_invert: 1; ///< The de signal is inverted (i.e. active low)
} io_flags; ///< ISP DVP IO flags
int queue_items; ///< Queue items
struct {

View File

@ -45,4 +45,11 @@ menu "Example DSI Configuration"
int
default 600 if EXAMPLE_MIPI_DSI_DISP_VRES_600
default 1280 if EXAMPLE_MIPI_DSI_DISP_VRES_1280
config EXAMPLE_MIPI_DSI_DISP_USE_DMA2D
bool "Use DMA2D to copy data to frame buffer"
default n
help
Enable this option, DMA2D will be used to copy data to the target frame buffer.
This can save some CPU time and improve the performance.
endmenu

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -13,6 +13,7 @@
#include "esp_lcd_ek79007.h"
#include "example_dsi_init.h"
#include "example_dsi_init_config.h"
#include "sdkconfig.h"
void example_dsi_resource_alloc(esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_panel_io_handle_t *mipi_dbi_io, esp_lcd_panel_handle_t *mipi_dpi_panel, void **frame_buffer)
{
@ -47,6 +48,9 @@ void example_dsi_resource_alloc(esp_lcd_dsi_bus_handle_t *mipi_dsi_bus, esp_lcd_
.vsync_pulse_width = EXAMPLE_MIPI_DSI_IMAGE_VSYNC,
.vsync_front_porch = EXAMPLE_MIPI_DSI_IMAGE_VFP,
},
#if CONFIG_EXAMPLE_MIPI_DSI_DISP_USE_DMA2D
.flags.use_dma2d = true,
#endif
};
#if CONFIG_EXAMPLE_LCD_PATTERN_ILI9881C

View File

@ -81,6 +81,10 @@ void example_sensor_init(example_sensor_config_t *sensor_config, i2c_master_bus_
cam_cur_fmt = (esp_cam_sensor_format_t *) & (parray[i]);
}
}
if (!cam_cur_fmt) {
ESP_LOGE(TAG, "Unsupported format");
ESP_ERROR_CHECK(ESP_ERR_INVALID_ARG);
}
ret = esp_cam_sensor_set_format(cam, (const esp_cam_sensor_format_t *) cam_cur_fmt);
if (ret != ESP_OK) {

View File

@ -15,7 +15,7 @@ The subsections below give only absolutely necessary information. For full steps
### Hardware Required
- OV2640 camera sensor, or other camera sensors with DVP port that can output raw format color data
- OV2640 / SC030IOT camera sensor, or other camera sensors with DVP port that can output raw format color data
- EK79007 or ILI9881C LCD screen
- ESP32P4 devkit
@ -106,7 +106,7 @@ Set CONFIG_CAMERA_OV2640 to y
Remember to select the LCD screen model and set corresponding correct horizontal/vertical resolution in ``menuconfig`` > ``Example DSI Configuration``.
Available options for the camera sensor output horizontal/vertical resolution can be seen in ``menuconfig`` > ``Example Configuration``. Note that the horizontal resolution for the camera should be the same as the LCD screen horizontal resolution.
Available options for the camera sensor output horizontal/vertical resolution can be seen in ``menuconfig`` > ``Example Configuration``.
### Build and Flash

View File

@ -18,40 +18,48 @@ menu "Example Configuration"
choice EXAMPLE_CAM_HRES
bool "Set camera horizontal resolution"
default EXAMPLE_CAM_HRES_1024 if EXAMPLE_MIPI_DSI_DISP_HRES_1024
default EXAMPLE_CAM_HRES_800 if EXAMPLE_MIPI_DSI_DISP_HRES_800
default EXAMPLE_CAM_HRES_640
config EXAMPLE_CAM_HRES_1024
depends on EXAMPLE_MIPI_DSI_DISP_HRES_1024
depends on EXAMPLE_MIPI_DSI_DISP_HRES >= 1024
bool "1024"
config EXAMPLE_CAM_HRES_800
depends on EXAMPLE_MIPI_DSI_DISP_HRES_800
depends on EXAMPLE_MIPI_DSI_DISP_HRES >= 800
bool "800"
config EXAMPLE_CAM_HRES_640
depends on EXAMPLE_MIPI_DSI_DISP_HRES >= 640
bool "640"
endchoice
config EXAMPLE_CAM_HRES
int
default 1024 if EXAMPLE_CAM_HRES_1024
default 800 if EXAMPLE_CAM_HRES_800
default 640 if EXAMPLE_CAM_HRES_640
choice EXAMPLE_CAM_VRES
bool "Set camera vertical resolution"
default EXAMPLE_CAM_VRES_600 if EXAMPLE_MIPI_DSI_DISP_VRES_600
default EXAMPLE_CAM_VRES_640 if EXAMPLE_MIPI_DSI_DISP_VRES_1280
default EXAMPLE_CAM_VRES_600 if EXAMPLE_CAM_HRES_1024
default EXAMPLE_CAM_VRES_640 if EXAMPLE_CAM_HRES_800
default EXAMPLE_CAM_VRES_480 if EXAMPLE_CAM_HRES_640
config EXAMPLE_CAM_VRES_480
depends on EXAMPLE_MIPI_DSI_DISP_VRES >= 480
bool "480"
config EXAMPLE_CAM_VRES_600
depends on EXAMPLE_MIPI_DSI_DISP_VRES_600
depends on EXAMPLE_MIPI_DSI_DISP_VRES >= 600
bool "600"
config EXAMPLE_CAM_VRES_640
depends on EXAMPLE_MIPI_DSI_DISP_VRES_1280
depends on EXAMPLE_MIPI_DSI_DISP_VRES >= 640
bool "640"
config EXAMPLE_CAM_VRES_800
depends on EXAMPLE_MIPI_DSI_DISP_VRES_1280
depends on EXAMPLE_MIPI_DSI_DISP_VRES >= 800
bool "800"
endchoice
config EXAMPLE_CAM_VRES
int
default 480 if EXAMPLE_CAM_VRES_480
default 600 if EXAMPLE_CAM_VRES_600
default 640 if EXAMPLE_CAM_VRES_640
default 800 if EXAMPLE_CAM_VRES_800

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -26,6 +26,11 @@
static const char *TAG = "dvp_isp_dsi";
typedef struct {
esp_lcd_panel_handle_t panel_hdl;
void *cam_buf;
} display_update_param_t;
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);
@ -54,6 +59,13 @@ static void s_ledc_generate_dvp_xclk(void)
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
static bool example_display_update_ready(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx)
{
display_update_param_t *param = (display_update_param_t *)user_ctx;
esp_lcd_panel_draw_bitmap(param->panel_hdl, 0, 0, CONFIG_EXAMPLE_CAM_HRES, CONFIG_EXAMPLE_CAM_VRES, param->cam_buf);
return false;
}
void app_main(void)
{
esp_err_t ret = ESP_FAIL;
@ -80,15 +92,21 @@ void app_main(void)
example_dsi_resource_alloc(&mipi_dsi_bus, &mipi_dbi_io, &mipi_dpi_panel, &frame_buffer);
//---------------Necessary variable config------------------//
frame_buffer_size = CONFIG_EXAMPLE_CAM_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
frame_buffer_size = CONFIG_EXAMPLE_MIPI_DSI_DISP_HRES * CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
ESP_LOGD(TAG, "CONFIG_EXAMPLE_CAM_HRES: %d, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES: %d, bits per pixel: %d", CONFIG_EXAMPLE_CAM_HRES, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES, EXAMPLE_RGB565_BITS_PER_PIXEL);
ESP_LOGD(TAG, "CONFIG_EXAMPLE_MIPI_DSI_DISP_HRES: %d, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES: %d, bits per pixel: %d", CONFIG_EXAMPLE_MIPI_DSI_DISP_HRES, CONFIG_EXAMPLE_MIPI_DSI_DISP_VRES, EXAMPLE_RGB565_BITS_PER_PIXEL);
ESP_LOGD(TAG, "frame_buffer_size: %zu", frame_buffer_size);
ESP_LOGD(TAG, "frame_buffer: %p", frame_buffer);
size_t cam_buffer_size = CONFIG_EXAMPLE_CAM_HRES * CONFIG_EXAMPLE_CAM_VRES * EXAMPLE_RGB565_BITS_PER_PIXEL / 8;
void *cam_buffer = heap_caps_calloc(1, cam_buffer_size, MALLOC_CAP_DMA | MALLOC_CAP_SPIRAM);
if (!cam_buffer) {
ESP_LOGE(TAG, "no mem for cam_buffer");
return;
}
esp_cam_ctlr_trans_t cam_trans = {
.buffer = frame_buffer,
.buflen = frame_buffer_size,
.buffer = cam_buffer,
.buflen = cam_buffer_size,
};
//--------Camera Sensor and SCCB Init-----------//
@ -137,7 +155,7 @@ void app_main(void)
.hsync_io = EXAMPLE_ISP_DVP_CAM_HSYNC_IO,
.vsync_io = EXAMPLE_ISP_DVP_CAM_VSYNC_IO,
.de_io = EXAMPLE_ISP_DVP_CAM_DE_IO,
.io_flags.vsync_invert = 1,
.io_flags.vsync_invert = 1, // active high
.queue_items = 10,
};
ret = esp_cam_new_isp_dvp_ctlr(isp_proc, &dvp_config, &cam_handle);
@ -171,6 +189,17 @@ void app_main(void)
return;
}
// Register DPI panel event callback for display update ready notification
display_update_param_t display_update_param = {
.panel_hdl = mipi_dpi_panel,
.cam_buf = cam_buffer,
};
esp_lcd_dpi_panel_event_callbacks_t dpi_cbs = {
.on_color_trans_done = example_display_update_ready,
};
ESP_ERROR_CHECK(esp_lcd_dpi_panel_register_event_callbacks(mipi_dpi_panel, &dpi_cbs, &display_update_param));
esp_lcd_panel_draw_bitmap(mipi_dpi_panel, 0, 0, CONFIG_EXAMPLE_CAM_HRES, CONFIG_EXAMPLE_CAM_VRES, cam_buffer);
while (1) {
ESP_ERROR_CHECK(esp_cam_ctlr_receive(cam_handle, &cam_trans, ESP_CAM_CTLR_MAX_DELAY));
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -20,36 +20,46 @@ extern "C" {
#define EXAMPLE_ISP_DVP_CAM_XCLK_FREQ_HZ (20000000)
#define EXAMPLE_ISP_DVP_CAM_DATA_WIDTH (8)
#define EXAMPLE_ISP_DVP_CAM_D0_IO (8)
#define EXAMPLE_ISP_DVP_CAM_D1_IO (9)
#define EXAMPLE_ISP_DVP_CAM_D2_IO (10)
#define EXAMPLE_ISP_DVP_CAM_D3_IO (4)
#define EXAMPLE_ISP_DVP_CAM_D4_IO (5)
#define EXAMPLE_ISP_DVP_CAM_D0_IO (53)
#define EXAMPLE_ISP_DVP_CAM_D1_IO (54)
#define EXAMPLE_ISP_DVP_CAM_D2_IO (26)
#define EXAMPLE_ISP_DVP_CAM_D3_IO (1)
#define EXAMPLE_ISP_DVP_CAM_D4_IO (0)
#define EXAMPLE_ISP_DVP_CAM_D5_IO (45)
#define EXAMPLE_ISP_DVP_CAM_D6_IO (46)
#define EXAMPLE_ISP_DVP_CAM_D7_IO (47)
#define EXAMPLE_ISP_DVP_CAM_XCLK_IO (20)
#define EXAMPLE_ISP_DVP_CAM_PCLK_IO (21)
#define EXAMPLE_ISP_DVP_CAM_DE_IO (2)
#define EXAMPLE_ISP_DVP_CAM_DE_IO (22)
#define EXAMPLE_ISP_DVP_CAM_VSYNC_IO (23)
#define EXAMPLE_ISP_DVP_CAM_HSYNC_IO (-1)
#if CONFIG_EXAMPLE_CAM_HRES_800
#if CONFIG_EXAMPLE_CAM_HRES_640
#if CONFIG_EXAMPLE_CAM_VRES_480
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_640x480_26fps" // sc030iot
#endif
#elif CONFIG_EXAMPLE_CAM_HRES_800
#if CONFIG_EXAMPLE_CAM_VRES_640
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_800x640_15fps"
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_800x640_15fps" // ov2640
#elif CONFIG_EXAMPLE_CAM_VRES_800
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_800x800_15fps"
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_800x800_15fps" // ov2640
#endif
#elif CONFIG_EXAMPLE_CAM_HRES_1024
#if CONFIG_EXAMPLE_CAM_VRES_600
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_1024x600_15fps"
#define EXAMPLE_CAM_FORMAT "DVP_8bit_20Minput_RAW8_1024x600_15fps" // ov2640
#endif
#endif
#ifndef EXAMPLE_CAM_FORMAT
#error "Unsupported camera format! Please adjust EXAMPLE_CAM_HRES and EXAMPLE_CAM_VRES in menuconfig"
#endif
#ifdef __cplusplus
}
#endif

View File

@ -1,4 +1,3 @@
CONFIG_SPIRAM=y
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM_SPEED_200M=y
CONFIG_CAMERA_OV2640=y
CONFIG_CAMERA_SC030IOT=y
CONFIG_EXAMPLE_MIPI_DSI_DISP_USE_DMA2D=y

View File

@ -0,0 +1,3 @@
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_200M=y

View File

@ -1,5 +1,2 @@
CONFIG_SPIRAM=y
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM_SPEED_200M=y
CONFIG_CAMERA_SC2336=y
CONFIG_CAMERA_OV5647=y

View File

@ -0,0 +1,3 @@
CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_200M=y