12
12
#include <zephyr/drivers/video-controls.h>
13
13
#include <zephyr/logging/log.h>
14
14
15
+ #include "video_common.h"
15
16
#include "video_ctrls.h"
16
17
#include "video_device.h"
17
18
18
19
LOG_MODULE_REGISTER (video_ov7670 , CONFIG_VIDEO_LOG_LEVEL );
19
20
20
- /* Initialization register structure */
21
- struct ov7670_reg {
22
- uint8_t reg ;
23
- uint8_t cmd ;
24
- };
25
-
26
21
struct ov7670_config {
27
22
struct i2c_dt_spec bus ;
28
23
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY (reset_gpios )
@@ -43,63 +38,7 @@ struct ov7670_data {
43
38
struct video_format fmt ;
44
39
};
45
40
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)
103
42
/* OV7670 registers */
104
43
#define OV7670_PID 0x0A
105
44
#define OV7670_COM7 0x12
@@ -209,13 +148,14 @@ static const struct video_format_cap fmts[] = {
209
148
OV7670_VIDEO_FORMAT_CAP (320 , 240 , VIDEO_PIX_FMT_YUYV ), /* QVGA */
210
149
OV7670_VIDEO_FORMAT_CAP (352 , 288 , VIDEO_PIX_FMT_YUYV ), /* CIF */
211
150
OV7670_VIDEO_FORMAT_CAP (640 , 480 , VIDEO_PIX_FMT_YUYV ), /* VGA */
212
- {0 }};
151
+ {0 }
152
+ };
213
153
214
154
/*
215
155
* This initialization table is based on the MCUX SDK driver for the OV7670.
216
156
* Note that this table assumes the camera is fed a 6MHz XCLK signal
217
157
*/
218
- static const struct ov7670_reg ov7670_init_regtbl [] = {
158
+ static const struct video_reg8 ov7670_init_regtbl [] = {
219
159
{OV7670_MVFP , 0x00 }, /* MVFP: Mirror/VFlip,Normal image */
220
160
221
161
/* configure the output timing */
@@ -369,6 +309,51 @@ static const struct ov7670_reg ov7670_init_regtbl[] = {
369
309
{0xb8 , 0x0a },
370
310
};
371
311
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
+
372
357
static int ov7670_get_caps (const struct device * dev , struct video_caps * caps )
373
358
{
374
359
caps -> format_caps = fmts ;
@@ -379,8 +364,7 @@ static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
379
364
{
380
365
const struct ov7670_config * config = dev -> config ;
381
366
struct ov7670_data * data = dev -> data ;
382
- const struct ov7670_resolution_cfg * resolution ;
383
- int ret ;
367
+ int ret = - ENOTSUP ;
384
368
uint8_t i = 0U ;
385
369
386
370
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)
397
381
398
382
/* Set output resolution */
399
383
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 ){
402
387
/* Set output format */
403
388
switch (fmts [i ].width_min ) {
404
389
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 ));
406
396
break ;
407
397
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 ));
409
400
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 ));
412
404
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 ));
415
408
break ;
416
409
}
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 );
440
410
if (ret < 0 ) {
411
+ LOG_ERR ("Resolution not set!" );
441
412
return ret ;
442
413
}
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 );
455
414
}
456
415
i ++ ;
457
416
}
458
417
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 ;
461
424
}
462
425
463
426
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)
487
450
static int ov7670_init (const struct device * dev )
488
451
{
489
452
const struct ov7670_config * config = dev -> config ;
490
- int ret , i ;
453
+ int ret ;
491
454
uint8_t pid ;
492
455
struct video_format fmt = {
493
456
.pixelformat = VIDEO_PIX_FMT_RGB565 ,
494
457
.width = 320 ,
495
458
.height = 240 ,
496
459
};
497
- const struct ov7670_reg * reg ;
498
460
499
461
if (!i2c_is_ready_dt (& config -> bus )) {
500
462
/* I2C device is not ready, return */
@@ -559,7 +521,7 @@ static int ov7670_init(const struct device *dev)
559
521
}
560
522
561
523
/* 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 );
563
525
if (ret < 0 ) {
564
526
LOG_ERR ("Could not reset camera: %d" , ret );
565
527
return ret ;
@@ -573,12 +535,10 @@ static int ov7670_init(const struct device *dev)
573
535
}
574
536
575
537
/* 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 ;
582
542
}
583
543
584
544
/* Initialize controls */
@@ -628,15 +588,17 @@ static DEVICE_API(video, ov7670_api) = {
628
588
#define OV7670_PWDN_GPIO (inst )
629
589
#endif
630
590
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
+ \
637
599
DEVICE_DT_INST_DEFINE(inst, ov7670_init, NULL, &ov7670_data_##inst, &ov7670_config_##inst, \
638
600
POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); \
639
- \
601
+ \
640
602
VIDEO_DEVICE_DEFINE(ov7670_##inst, DEVICE_DT_INST_GET(inst), NULL);
641
603
642
604
DT_INST_FOREACH_STATUS_OKAY (OV7670_INIT )
0 commit comments