Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9f99b1b

Browse files
authored
Merge pull request espressif#132 from espressif/ov5640
Add support for OV5640
2 parents a4f6d92 + ae32d52 commit 9f99b1b

File tree

20 files changed

+2185
-235
lines changed

20 files changed

+2185
-235
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ set(COMPONENT_SRCS
66
driver/xclk.c
77
sensors/ov2640.c
88
sensors/ov3660.c
9+
sensors/ov5640.c
910
sensors/ov7725.c
1011
conversions/yuv.c
1112
conversions/to_jpg.cpp

Kconfig

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,28 @@ config OV2640_SUPPORT
55
default y
66
help
77
Enable this option if you want to use the OV2640.
8-
Disable this option to safe memory.
8+
Disable this option to save memory.
99

1010
config OV7725_SUPPORT
1111
bool "OV7725 Support"
1212
default n
1313
help
1414
Enable this option if you want to use the OV7725.
15-
Disable this option to safe memory.
15+
Disable this option to save memory.
1616

1717
config OV3660_SUPPORT
1818
bool "OV3660 Support"
1919
default y
2020
help
2121
Enable this option if you want to use the OV3360.
22-
Disable this option to safe memory.
22+
Disable this option to save memory.
23+
24+
config OV5640_SUPPORT
25+
bool "OV5640 Support"
26+
default y
27+
help
28+
Enable this option if you want to use the OV5640.
29+
Disable this option to save memory.
2330

2431
config SCCB_HARDWARE_I2C
2532
bool "Use hardware I2C for SCCB"

conversions/esp_jpg_decode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "esp_jpg_decode.h"
1515

1616
#include "esp_system.h"
17-
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
17+
#if ESP_IDF_VERSION_MAJOR >= 4 // IDF 4+
1818
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
1919
#include "esp32/rom/tjpgd.h"
2020
#else

conversions/to_jpg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "yuv.h"
2323

2424
#include "esp_system.h"
25-
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
25+
#if ESP_IDF_VERSION_MAJOR >= 4 // IDF 4+
2626
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
2727
#include "esp32/spiram.h"
2828
#else

driver/camera.c

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@
4545
#if CONFIG_OV3660_SUPPORT
4646
#include "ov3660.h"
4747
#endif
48+
#if CONFIG_OV5640_SUPPORT
49+
#include "ov5640.h"
50+
#endif
4851

4952
typedef enum {
5053
CAMERA_NONE = 0,
5154
CAMERA_UNKNOWN = 1,
5255
CAMERA_OV7725 = 7725,
5356
CAMERA_OV2640 = 2640,
5457
CAMERA_OV3660 = 3660,
58+
CAMERA_OV5640 = 5640,
5559
} camera_model_t;
5660

5761
#define REG_PID 0x0A
@@ -80,6 +84,7 @@ typedef struct camera_fb_s {
8084
size_t width;
8185
size_t height;
8286
pixformat_t format;
87+
struct timeval timestamp;
8388
size_t size;
8489
uint8_t ref;
8590
uint8_t bad;
@@ -546,6 +551,7 @@ static void IRAM_ATTR signal_dma_buf_received(bool* need_yield)
546551
}
547552
//ESP_EARLY_LOGW(TAG, "qsf:%d", s_state->dma_received_count);
548553
//ets_printf("qsf:%d\n", s_state->dma_received_count);
554+
//ets_printf("qovf\n");
549555
}
550556
*need_yield = (ret == pdTRUE && higher_priority_task_woken == pdTRUE);
551557
}
@@ -577,6 +583,7 @@ static void IRAM_ATTR vsync_isr(void* arg)
577583
if(s_state->dma_filtered_count > 1 || s_state->fb->bad || s_state->config.fb_count > 1) {
578584
i2s_stop(&need_yield);
579585
}
586+
//ets_printf("vs\n");
580587
}
581588
if(s_state->config.fb_count > 1 || s_state->dma_filtered_count < 2) {
582589
I2S0.conf.rx_start = 0;
@@ -669,6 +676,7 @@ static void IRAM_ATTR dma_finish_frame()
669676
if(s_state->config.fb_count == 1) {
670677
i2s_start_bus();
671678
}
679+
//ets_printf("bad\n");
672680
} else {
673681
s_state->fb->len = s_state->dma_filtered_count * buf_len;
674682
if(s_state->fb->len) {
@@ -695,6 +703,8 @@ static void IRAM_ATTR dma_finish_frame()
695703
} else if(s_state->config.fb_count == 1){
696704
//frame was empty?
697705
i2s_start_bus();
706+
} else {
707+
//ets_printf("empty\n");
698708
}
699709
}
700710
} else if(s_state->fb->len) {
@@ -728,15 +738,19 @@ static void IRAM_ATTR dma_filter_buffer(size_t buf_idx)
728738
if(s_state->sensor.pixformat == PIXFORMAT_JPEG) {
729739
uint32_t sig = *((uint32_t *)s_state->fb->buf) & 0xFFFFFF;
730740
if(sig != 0xffd8ff) {
731-
//ets_printf("bad header\n");
741+
ets_printf("bh 0x%08x\n", sig);
732742
s_state->fb->bad = 1;
733743
return;
734744
}
735745
}
736746
//set the frame properties
737-
s_state->fb->width = resolution[s_state->sensor.status.framesize][0];
738-
s_state->fb->height = resolution[s_state->sensor.status.framesize][1];
747+
s_state->fb->width = resolution[s_state->sensor.status.framesize].width;
748+
s_state->fb->height = resolution[s_state->sensor.status.framesize].height;
739749
s_state->fb->format = s_state->sensor.pixformat;
750+
751+
uint64_t us = (uint64_t)esp_timer_get_time();
752+
s_state->fb->timestamp.tv_sec = us / 1000000UL;
753+
s_state->fb->timestamp.tv_usec = us % 1000000UL;
740754
}
741755
s_state->dma_filtered_count++;
742756
}
@@ -972,13 +986,6 @@ esp_err_t camera_probe(const camera_config_t* config, camera_model_t* out_camera
972986
vTaskDelay(10 / portTICK_PERIOD_MS);
973987
gpio_set_level(config->pin_reset, 1);
974988
vTaskDelay(10 / portTICK_PERIOD_MS);
975-
#if (CONFIG_OV2640_SUPPORT && !CONFIG_OV3660_SUPPORT)
976-
} else {
977-
//reset OV2640
978-
SCCB_Write(0x30, 0xFF, 0x01);//bank sensor
979-
SCCB_Write(0x30, 0x12, 0x80);//reset
980-
vTaskDelay(10 / portTICK_PERIOD_MS);
981-
#endif
982989
}
983990

984991
ESP_LOGD(TAG, "Searching for camera address");
@@ -989,15 +996,13 @@ esp_err_t camera_probe(const camera_config_t* config, camera_model_t* out_camera
989996
camera_disable_out_clock();
990997
return ESP_ERR_CAMERA_NOT_DETECTED;
991998
}
992-
s_state->sensor.slv_addr = slv_addr;
993-
s_state->sensor.xclk_freq_hz = config->xclk_freq_hz;
994-
995-
//s_state->sensor.slv_addr = 0x30;
996-
ESP_LOGD(TAG, "Detected camera at address=0x%02x", s_state->sensor.slv_addr);
999+
1000+
//slv_addr = 0x30;
1001+
ESP_LOGD(TAG, "Detected camera at address=0x%02x", slv_addr);
9971002
sensor_id_t* id = &s_state->sensor.id;
9981003

999-
#if (CONFIG_OV2640_SUPPORT)
1000-
if (s_state->sensor.slv_addr == 0x30) {
1004+
#if CONFIG_OV2640_SUPPORT
1005+
if (slv_addr == 0x30) {
10011006
ESP_LOGD(TAG, "Resetting OV2640");
10021007
//camera might be OV2640. try to reset it
10031008
SCCB_Write(0x30, 0xFF, 0x01);//bank sensor
@@ -1007,7 +1012,10 @@ esp_err_t camera_probe(const camera_config_t* config, camera_model_t* out_camera
10071012
}
10081013
#endif
10091014

1010-
#if CONFIG_OV3660_SUPPORT
1015+
s_state->sensor.slv_addr = slv_addr;
1016+
s_state->sensor.xclk_freq_hz = config->xclk_freq_hz;
1017+
1018+
#if (CONFIG_OV3660_SUPPORT || CONFIG_OV5640_SUPPORT)
10111019
if(s_state->sensor.slv_addr == 0x3c){
10121020
id->PID = SCCB_Read16(s_state->sensor.slv_addr, REG16_CHIDH);
10131021
id->VER = SCCB_Read16(s_state->sensor.slv_addr, REG16_CHIDL);
@@ -1022,7 +1030,8 @@ esp_err_t camera_probe(const camera_config_t* config, camera_model_t* out_camera
10221030
vTaskDelay(10 / portTICK_PERIOD_MS);
10231031
ESP_LOGD(TAG, "Camera PID=0x%02x VER=0x%02x MIDL=0x%02x MIDH=0x%02x",
10241032
id->PID, id->VER, id->MIDH, id->MIDL);
1025-
#if CONFIG_OV3660_SUPPORT
1033+
1034+
#if (CONFIG_OV3660_SUPPORT || CONFIG_OV5640_SUPPORT)
10261035
}
10271036
#endif
10281037

@@ -1045,6 +1054,12 @@ esp_err_t camera_probe(const camera_config_t* config, camera_model_t* out_camera
10451054
*out_camera_model = CAMERA_OV3660;
10461055
ov3660_init(&s_state->sensor);
10471056
break;
1057+
#endif
1058+
#if CONFIG_OV5640_SUPPORT
1059+
case OV5640_PID:
1060+
*out_camera_model = CAMERA_OV5640;
1061+
ov5640_init(&s_state->sensor);
1062+
break;
10481063
#endif
10491064
default:
10501065
id->PID = 0;
@@ -1072,12 +1087,46 @@ esp_err_t camera_init(const camera_config_t* config)
10721087
esp_err_t err = ESP_OK;
10731088
framesize_t frame_size = (framesize_t) config->frame_size;
10741089
pixformat_t pix_format = (pixformat_t) config->pixel_format;
1075-
s_state->width = resolution[frame_size][0];
1076-
s_state->height = resolution[frame_size][1];
1090+
1091+
switch (s_state->sensor.id.PID) {
1092+
#if CONFIG_OV2640_SUPPORT
1093+
case OV2640_PID:
1094+
if (frame_size > FRAMESIZE_UXGA) {
1095+
frame_size = FRAMESIZE_UXGA;
1096+
}
1097+
break;
1098+
#endif
1099+
#if CONFIG_OV7725_SUPPORT
1100+
case OV7725_PID:
1101+
if (frame_size > FRAMESIZE_VGA) {
1102+
frame_size = FRAMESIZE_VGA;
1103+
}
1104+
break;
1105+
#endif
1106+
#if CONFIG_OV3660_SUPPORT
1107+
case OV3660_PID:
1108+
if (frame_size > FRAMESIZE_QXGA) {
1109+
frame_size = FRAMESIZE_QXGA;
1110+
}
1111+
break;
1112+
#endif
1113+
#if CONFIG_OV5640_SUPPORT
1114+
case OV5640_PID:
1115+
if (frame_size > FRAMESIZE_QSXGA) {
1116+
frame_size = FRAMESIZE_QSXGA;
1117+
}
1118+
break;
1119+
#endif
1120+
default:
1121+
return ESP_ERR_CAMERA_NOT_SUPPORTED;
1122+
}
1123+
1124+
s_state->width = resolution[frame_size].width;
1125+
s_state->height = resolution[frame_size].height;
10771126

10781127
if (pix_format == PIXFORMAT_GRAYSCALE) {
10791128
s_state->fb_size = s_state->width * s_state->height;
1080-
if (s_state->sensor.id.PID == OV3660_PID) {
1129+
if (s_state->sensor.id.PID == OV3660_PID || s_state->sensor.id.PID == OV5640_PID) {
10811130
if (is_hs_mode()) {
10821131
s_state->sampling_mode = SM_0A00_0B00;
10831132
s_state->dma_filter = &dma_filter_yuyv_highspeed;
@@ -1120,8 +1169,8 @@ esp_err_t camera_init(const camera_config_t* config)
11201169
s_state->in_bytes_per_pixel = 2; // camera sends RGB565
11211170
s_state->fb_bytes_per_pixel = 3; // frame buffer stores RGB888
11221171
} else if (pix_format == PIXFORMAT_JPEG) {
1123-
if (s_state->sensor.id.PID != OV2640_PID && s_state->sensor.id.PID != OV3660_PID) {
1124-
ESP_LOGE(TAG, "JPEG format is only supported for ov2640 and ov3660");
1172+
if (s_state->sensor.id.PID != OV2640_PID && s_state->sensor.id.PID != OV3660_PID && s_state->sensor.id.PID != OV5640_PID) {
1173+
ESP_LOGE(TAG, "JPEG format is only supported for ov2640, ov3660 and ov5640");
11251174
err = ESP_ERR_NOT_SUPPORTED;
11261175
goto fail;
11271176
}
@@ -1268,6 +1317,8 @@ esp_err_t esp_camera_init(const camera_config_t* config)
12681317
ESP_LOGD(TAG, "Detected OV2640 camera");
12691318
} else if (camera_model == CAMERA_OV3660) {
12701319
ESP_LOGD(TAG, "Detected OV3660 camera");
1320+
} else if (camera_model == CAMERA_OV5640) {
1321+
ESP_LOGD(TAG, "Detected OV5640 camera");
12711322
} else {
12721323
ESP_LOGE(TAG, "Camera not supported");
12731324
err = ESP_ERR_CAMERA_NOT_SUPPORTED;

driver/include/esp_camera.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ typedef struct {
115115
size_t width; /*!< Width of the buffer in pixels */
116116
size_t height; /*!< Height of the buffer in pixels */
117117
pixformat_t format; /*!< Format of the pixel data */
118+
struct timeval timestamp; /*!< Timestamp since boot of the first DMA buffer of the frame */
118119
} camera_fb_t;
119120

120121
#define ESP_ERR_CAMERA_BASE 0x20000

0 commit comments

Comments
 (0)