Skip to content

Commit 518132a

Browse files
committed
drivers: video: ov7670 driver changes in prep for adding OV7675
drivers: video: Restructure OV760.c driver before adding OV7675 support Modifications for use of video cci helpers in video_common.h. Signed-off-by: Mike S <[email protected]>
1 parent 0e3cd5b commit 518132a

File tree

1 file changed

+90
-128
lines changed

1 file changed

+90
-128
lines changed

drivers/video/ov7670.c

Lines changed: 90 additions & 128 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,8 +364,7 @@ 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;
383-
int ret;
367+
int ret = -ENOTSUP;
384368
uint8_t i = 0U;
385369

386370
if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565 && fmt->pixelformat != VIDEO_PIX_FMT_YUYV) {
@@ -397,67 +381,46 @@ static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
397381

398382
/* Set output resolution */
399383
while (fmts[i].pixelformat) {
400-
if (fmts[i].width_min == fmt->width && fmts[i].height_min == fmt->height &&
401-
fmts[i].pixelformat == fmt->pixelformat) {
384+
if (fmts[i].width_min == fmt->width &&
385+
fmts[i].height_min == fmt->height &&
386+
fmts[i].pixelformat == fmt->pixelformat){
402387
/* Set output format */
403388
switch (fmts[i].width_min) {
404389
case 176: /* QCIF */
405-
resolution = &OV7670_RESOLUTION_QCIF;
390+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qcif,
391+
ARRAY_SIZE(ov7670_regs_qcif));
392+
break;
393+
case 352: /* QCIF */
394+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_cif,
395+
ARRAY_SIZE(ov7670_regs_cif));
406396
break;
407397
case 320: /* QVGA */
408-
resolution = &OV7670_RESOLUTION_QVGA;
398+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qvga,
399+
ARRAY_SIZE(ov7670_regs_qvga));
409400
break;
410-
case 352: /* CIF */
411-
resolution = &OV7670_RESOLUTION_CIF;
401+
case 640: /* VGA */
402+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_vga,
403+
ARRAY_SIZE(ov7670_regs_vga));
412404
break;
413-
default: /* VGA */
414-
resolution = &OV7670_RESOLUTION_VGA;
405+
default: /* QVGA */
406+
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qvga,
407+
ARRAY_SIZE(ov7670_regs_vga));
415408
break;
416409
}
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);
440410
if (ret < 0) {
411+
LOG_ERR("Resolution not set!");
441412
return ret;
442413
}
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);
455414
}
456415
i++;
457416
}
458417

459-
LOG_ERR("Unsupported format");
460-
return -ENOTSUP;
418+
if (ret < 0) {
419+
LOG_ERR("Resolution not supported!");
420+
return ret;
421+
}
422+
423+
return 0;
461424
}
462425

463426
static int ov7670_get_fmt(const struct device *dev, struct video_format *fmt)
@@ -487,14 +450,13 @@ static int ov7670_init_controls(const struct device *dev)
487450
static int ov7670_init(const struct device *dev)
488451
{
489452
const struct ov7670_config *config = dev->config;
490-
int ret, i;
453+
int ret;
491454
uint8_t pid;
492455
struct video_format fmt = {
493456
.pixelformat = VIDEO_PIX_FMT_RGB565,
494457
.width = 320,
495458
.height = 240,
496459
};
497-
const struct ov7670_reg *reg;
498460

499461
if (!i2c_is_ready_dt(&config->bus)) {
500462
/* I2C device is not ready, return */
@@ -559,7 +521,7 @@ static int ov7670_init(const struct device *dev)
559521
}
560522

561523
/* Reset camera registers */
562-
ret = i2c_reg_write_byte_dt(&config->bus, OV7670_COM7, 0x80);
524+
ret = video_write_cci_reg(&config->bus, OV7670_REG8(OV7670_COM7), 0x80);
563525
if (ret < 0) {
564526
LOG_ERR("Could not reset camera: %d", ret);
565527
return ret;
@@ -573,12 +535,10 @@ static int ov7670_init(const struct device *dev)
573535
}
574536

575537
/* 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-
}
538+
ret = video_write_cci_multiregs8(&config->bus, ov7670_init_regtbl,
539+
ARRAY_SIZE(ov7670_init_regtbl));
540+
if (ret < 0) {
541+
return ret;
582542
}
583543

584544
/* Initialize controls */
@@ -628,15 +588,17 @@ static DEVICE_API(video, ov7670_api) = {
628588
#define OV7670_PWDN_GPIO(inst)
629589
#endif
630590

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-
\
591+
#define OV7670_INIT(inst) \
592+
const struct ov7670_config ov7670_config_##inst = { \
593+
.bus = I2C_DT_SPEC_INST_GET(inst), \
594+
OV7670_RESET_GPIO(inst) \
595+
OV7670_PWDN_GPIO(inst)}; \
596+
\
597+
struct ov7670_data ov7670_data_##inst; \
598+
\
637599
DEVICE_DT_INST_DEFINE(inst, ov7670_init, NULL, &ov7670_data_##inst, &ov7670_config_##inst, \
638600
POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); \
639-
\
601+
\
640602
VIDEO_DEVICE_DEFINE(ov7670_##inst, DEVICE_DT_INST_GET(inst), NULL);
641603

642604
DT_INST_FOREACH_STATUS_OKAY(OV7670_INIT)

0 commit comments

Comments
 (0)