Skip to content

Commit 974b001

Browse files
committed
drivers: video: ov7670 driver changes in prep for adding OV7675
drivers: video: Restructure OV760.c driver before adding OV7675 support Modification list to commit made in reverse order: - Resolve comments from 10/4 - Resolve conversations dtd 9/27 - Updated to restore com10 original setting 9/27 - update to fix sonar issues 9/26/25 - New issue identified by Sonar fixed - 12:40 PM, 9/25. - Updated for revisions requested by reviewers (9/25). - Updated ov7670.c in prep for incorporation of OV7675. See previous PR. Signed-off-by: Michael Smorto <[email protected]>
1 parent 0e3cd5b commit 974b001

File tree

1 file changed

+98
-129
lines changed

1 file changed

+98
-129
lines changed

drivers/video/ov7670.c

Lines changed: 98 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,12 @@
1212
#include <zephyr/drivers/video-controls.h>
1313
#include <zephyr/logging/log.h>
1414

15+
#include "video_common.h"
1516
#include "video_ctrls.h"
1617
#include "video_device.h"
1718

1819
LOG_MODULE_REGISTER(video_ov7670, CONFIG_VIDEO_LOG_LEVEL);
1920

20-
/* Initialization register structure */
21-
struct ov7670_reg {
22-
uint8_t reg;
23-
uint8_t cmd;
24-
};
25-
2621
struct ov7670_config {
2722
struct i2c_dt_spec bus;
2823
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
@@ -43,63 +38,7 @@ struct ov7670_data {
4338
struct video_format fmt;
4439
};
4540

46-
struct ov7670_resolution_cfg {
47-
uint8_t com7;
48-
uint8_t com3;
49-
uint8_t com14;
50-
uint8_t scaling_xsc;
51-
uint8_t scaling_ysc;
52-
uint8_t dcwctr;
53-
uint8_t pclk_div;
54-
uint8_t pclk_delay;
55-
};
56-
57-
/* Resolution settings for camera, based on those present in MCUX SDK */
58-
const struct ov7670_resolution_cfg OV7670_RESOLUTION_QCIF = {
59-
.com7 = 0x2c,
60-
.com3 = 0x00,
61-
.com14 = 0x11,
62-
.scaling_xsc = 0x3a,
63-
.scaling_ysc = 0x35,
64-
.dcwctr = 0x11,
65-
.pclk_div = 0xf1,
66-
.pclk_delay = 0x52
67-
};
68-
69-
const struct ov7670_resolution_cfg OV7670_RESOLUTION_QVGA = {
70-
.com7 = 0x14,
71-
.com3 = 0x04,
72-
.com14 = 0x19,
73-
.scaling_xsc = 0x3a,
74-
.scaling_ysc = 0x35,
75-
.dcwctr = 0x11,
76-
.pclk_div = 0xf1,
77-
.pclk_delay = 0x02
78-
};
79-
80-
const struct ov7670_resolution_cfg OV7670_RESOLUTION_CIF = {
81-
.com7 = 0x24,
82-
.com3 = 0x08,
83-
.com14 = 0x11,
84-
.scaling_xsc = 0x3a,
85-
.scaling_ysc = 0x35,
86-
.dcwctr = 0x11,
87-
.pclk_div = 0xf1,
88-
.pclk_delay = 0x02
89-
};
90-
91-
const struct ov7670_resolution_cfg OV7670_RESOLUTION_VGA = {
92-
.com7 = 0x04,
93-
.com3 = 0x00,
94-
.com14 = 0x00,
95-
.scaling_xsc = 0x3a,
96-
.scaling_ysc = 0x35,
97-
.dcwctr = 0x11,
98-
.pclk_div = 0xf0,
99-
.pclk_delay = 0x02
100-
};
101-
102-
41+
#define OV7670_REG8(addr) ((addr) | VIDEO_REG_ADDR8_DATA8)
10342
/* OV7670 registers */
10443
#define OV7670_PID 0x0A
10544
#define OV7670_COM7 0x12
@@ -209,13 +148,14 @@ static const struct video_format_cap fmts[] = {
209148
OV7670_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_YUYV), /* QVGA */
210149
OV7670_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_YUYV), /* CIF */
211150
OV7670_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_YUYV), /* VGA */
212-
{0}};
151+
{0}
152+
};
213153

214154
/*
215155
* This initialization table is based on the MCUX SDK driver for the OV7670.
216156
* Note that this table assumes the camera is fed a 6MHz XCLK signal
217157
*/
218-
static const struct ov7670_reg ov7670_init_regtbl[] = {
158+
static const struct video_reg8 ov7670_init_regtbl[] = {
219159
{OV7670_MVFP, 0x00}, /* MVFP: Mirror/VFlip,Normal image */
220160

221161
/* configure the output timing */
@@ -369,6 +309,51 @@ static const struct ov7670_reg ov7670_init_regtbl[] = {
369309
{0xb8, 0x0a},
370310
};
371311

312+
/* Resolution settings for camera, based on those present in MCUX SDK */
313+
static const struct video_reg8 ov7670_regs_qcif[] = {
314+
{OV7670_COM7, 0x2c},
315+
{OV7670_COM3, 0x00},
316+
{OV7670_COM14, 0x11},
317+
{OV7670_SCALING_XSC, 0x3a},
318+
{OV7670_SCALING_YSC, 0x35},
319+
{OV7670_SCALING_DCWCTR, 0x11},
320+
{OV7670_SCALING_PCLK_DIV, 0xf1},
321+
{OV7670_SCALING_PCLK_DELAY, 0x52},
322+
};
323+
324+
static const struct video_reg8 ov7670_regs_qvga[] = {
325+
{OV7670_COM7, 0x14},
326+
{OV7670_COM3, 0x04},
327+
{OV7670_COM14, 0x19},
328+
{OV7670_SCALING_XSC, 0x3a},
329+
{OV7670_SCALING_YSC, 0x35},
330+
{OV7670_SCALING_DCWCTR, 0x11},
331+
{OV7670_SCALING_PCLK_DIV, 0xf1},
332+
{OV7670_SCALING_PCLK_DELAY, 0x02},
333+
};
334+
335+
static const struct video_reg8 ov7670_regs_cif[] = {
336+
{OV7670_COM7, 0x24},
337+
{OV7670_COM3, 0x08},
338+
{OV7670_COM14, 0x11},
339+
{OV7670_SCALING_XSC, 0x3a},
340+
{OV7670_SCALING_YSC, 0x35},
341+
{OV7670_SCALING_DCWCTR, 0x11},
342+
{OV7670_SCALING_PCLK_DIV, 0xf1},
343+
{OV7670_SCALING_PCLK_DELAY, 0x02},
344+
};
345+
346+
static const struct video_reg8 ov7670_regs_vga[] = {
347+
{OV7670_COM7, 0x04},
348+
{OV7670_COM3, 0x00},
349+
{OV7670_COM14, 0x00},
350+
{OV7670_SCALING_XSC, 0x3a},
351+
{OV7670_SCALING_YSC, 0x35},
352+
{OV7670_SCALING_DCWCTR, 0x11},
353+
{OV7670_SCALING_PCLK_DIV, 0xf0},
354+
{OV7670_SCALING_PCLK_DELAY, 0x02},
355+
};
356+
372357
static int ov7670_get_caps(const struct device *dev, struct video_caps *caps)
373358
{
374359
caps->format_caps = fmts;
@@ -379,7 +364,6 @@ static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
379364
{
380365
const struct ov7670_config *config = dev->config;
381366
struct ov7670_data *data = dev->data;
382-
const struct ov7670_resolution_cfg *resolution;
383367
int ret;
384368
uint8_t i = 0U;
385369

@@ -396,68 +380,49 @@ static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
396380
memcpy(&data->fmt, fmt, sizeof(data->fmt));
397381

398382
/* Set output resolution */
383+
ret = -ENOTSUP;
384+
i = 0;
399385
while (fmts[i].pixelformat) {
400-
if (fmts[i].width_min == fmt->width && fmts[i].height_min == fmt->height &&
401-
fmts[i].pixelformat == fmt->pixelformat) {
386+
if (fmts[i].width_min == fmt->width &&
387+
fmts[i].height_min == fmt->height &&
388+
fmts[i].pixelformat == fmt->pixelformat){
402389
/* Set output format */
403390
switch (fmts[i].width_min) {
404391
case 176: /* QCIF */
405-
resolution = &OV7670_RESOLUTION_QCIF;
392+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qcif,
393+
ARRAY_SIZE(ov7670_regs_qcif));
394+
break;
395+
case 352: /* QCIF */
396+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_cif,
397+
ARRAY_SIZE(ov7670_regs_cif));
406398
break;
407399
case 320: /* QVGA */
408-
resolution = &OV7670_RESOLUTION_QVGA;
400+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qvga,
401+
ARRAY_SIZE(ov7670_regs_qvga));
409402
break;
410-
case 352: /* CIF */
411-
resolution = &OV7670_RESOLUTION_CIF;
403+
case 640: /* VGA */
404+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_vga,
405+
ARRAY_SIZE(ov7670_regs_vga));
412406
break;
413-
default: /* VGA */
414-
resolution = &OV7670_RESOLUTION_VGA;
407+
default: /* QVGA */
408+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qvga,
409+
ARRAY_SIZE(ov7670_regs_vga));
415410
break;
416411
}
417-
/* Program resolution bytes settings */
418-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_COM7,
419-
resolution->com7);
420-
if (ret < 0) {
421-
return ret;
422-
}
423-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_COM3,
424-
resolution->com3);
425-
if (ret < 0) {
426-
return ret;
427-
}
428-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_COM14,
429-
resolution->com14);
430-
if (ret < 0) {
431-
return ret;
432-
}
433-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_SCALING_XSC,
434-
resolution->scaling_xsc);
435-
if (ret < 0) {
436-
return ret;
437-
}
438-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_SCALING_YSC,
439-
resolution->scaling_ysc);
440412
if (ret < 0) {
413+
LOG_ERR("Resolution not set!");
441414
return ret;
442415
}
443-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_SCALING_DCWCTR,
444-
resolution->dcwctr);
445-
if (ret < 0) {
446-
return ret;
447-
}
448-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_SCALING_PCLK_DIV,
449-
resolution->pclk_div);
450-
if (ret < 0) {
451-
return ret;
452-
}
453-
return i2c_reg_write_byte_dt(&config->bus, OV7670_SCALING_PCLK_DELAY,
454-
resolution->pclk_delay);
455416
}
456417
i++;
457418
}
458419

459-
LOG_ERR("Unsupported format");
460-
return -ENOTSUP;
420+
if (ret < 0) {
421+
LOG_ERR("Resolution supported!");
422+
return ret;
423+
}
424+
425+
return 0;
461426
}
462427

463428
static int ov7670_get_fmt(const struct device *dev, struct video_format *fmt)
@@ -487,14 +452,13 @@ static int ov7670_init_controls(const struct device *dev)
487452
static int ov7670_init(const struct device *dev)
488453
{
489454
const struct ov7670_config *config = dev->config;
490-
int ret, i;
455+
int ret;
491456
uint8_t pid;
492457
struct video_format fmt = {
493458
.pixelformat = VIDEO_PIX_FMT_RGB565,
494459
.width = 320,
495460
.height = 240,
496461
};
497-
const struct ov7670_reg *reg;
498462

499463
if (!i2c_is_ready_dt(&config->bus)) {
500464
/* I2C device is not ready, return */
@@ -559,7 +523,7 @@ static int ov7670_init(const struct device *dev)
559523
}
560524

561525
/* Reset camera registers */
562-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_COM7, 0x80);
526+
ret = video_write_cci_reg(&config->bus, OV7670_REG8(OV7670_COM7), 0x80);
563527
if (ret < 0) {
564528
LOG_ERR("Could not reset camera: %d", ret);
565529
return ret;
@@ -573,12 +537,10 @@ static int ov7670_init(const struct device *dev)
573537
}
574538

575539
/* Write initialization values to OV7670 */
576-
for (i = 0; i < ARRAY_SIZE(ov7670_init_regtbl); i++) {
577-
reg = &ov7670_init_regtbl[i];
578-
ret = i2c_reg_write_byte_dt(&config->bus, reg->reg, reg->cmd);
579-
if (ret < 0) {
580-
return ret;
581-
}
540+
ret = video_write_cci_multiregs8(&config->bus, ov7670_init_regtbl,
541+
ARRAY_SIZE(ov7670_init_regtbl));
542+
if (ret < 0) {
543+
return ret;
582544
}
583545

584546
/* Initialize controls */
@@ -628,15 +590,22 @@ static DEVICE_API(video, ov7670_api) = {
628590
#define OV7670_PWDN_GPIO(inst)
629591
#endif
630592

631-
#define OV7670_INIT(inst) \
632-
const struct ov7670_config ov7670_config_##inst = {.bus = I2C_DT_SPEC_INST_GET(inst), \
633-
OV7670_RESET_GPIO(inst) \
634-
OV7670_PWDN_GPIO(inst)}; \
635-
struct ov7670_data ov7670_data_##inst; \
636-
\
637-
DEVICE_DT_INST_DEFINE(inst, ov7670_init, NULL, &ov7670_data_##inst, &ov7670_config_##inst, \
638-
POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); \
639-
\
593+
#define OV7670_INIT(inst) \
594+
const struct ov7670_config ov7670_config_##inst = { \
595+
.bus = I2C_DT_SPEC_INST_GET(inst), \
596+
OV7670_RESET_GPIO(inst) \
597+
OV7670_PWDN_GPIO(inst)}; \
598+
\
599+
static struct ov7670_data ov7670_data_##inst; \
600+
\
601+
DEVICE_DT_INST_DEFINE(inst, \
602+
ov7670_init, \
603+
NULL, \
604+
&ov7670_data_##inst, \
605+
&ov7670_config_##inst, \
606+
POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \
607+
&ov7670_api); \
608+
\
640609
VIDEO_DEVICE_DEFINE(ov7670_##inst, DEVICE_DT_INST_GET(inst), NULL);
641610

642611
DT_INST_FOREACH_STATUS_OKAY(OV7670_INIT)

0 commit comments

Comments
 (0)