1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017, 2020, 2023 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_video_common.h"
10 #include "fsl_camera.h"
11 #include "fsl_camera_device.h"
12 #include "fsl_ov7670.h"
13 
14 /*******************************************************************************
15  * Definitions
16  ******************************************************************************/
17 #define OV7670_SCCB_ADDR 0x21U
18 
19 #define OV7670_WriteReg(handle, reg, val)                            \
20     SCCB_WriteReg(OV7670_SCCB_ADDR, kSCCB_RegAddr8Bit, (reg), (val), \
21                   ((ov7670_resource_t *)((handle)->resource))->i2cSendFunc)
22 
23 #define OV7670_ReadReg(handle, reg, val)                            \
24     SCCB_ReadReg(OV7670_SCCB_ADDR, kSCCB_RegAddr8Bit, (reg), (val), \
25                  ((ov7670_resource_t *)((handle)->resource))->i2cReceiveFunc)
26 
27 #define OV7670_ModifyReg(handle, reg, clrMask, val)                              \
28     SCCB_ModifyReg(OV7670_SCCB_ADDR, kSCCB_RegAddr8Bit, (reg), (clrMask), (val), \
29                    ((ov7670_resource_t *)((handle)->resource))->i2cReceiveFunc,  \
30                    ((ov7670_resource_t *)((handle)->resource))->i2cSendFunc)
31 
32 /*******************************************************************************
33  * Prototypes
34  ******************************************************************************/
35 status_t OV7670_Init(camera_device_handle_t *handle, const camera_config_t *config);
36 
37 status_t OV7670_Deinit(camera_device_handle_t *handle);
38 
39 status_t OV7670_Control(camera_device_handle_t *handle, camera_device_cmd_t cmd, int32_t arg);
40 
41 status_t OV7670_Start(camera_device_handle_t *handle);
42 
43 status_t OV7670_Stop(camera_device_handle_t *handle);
44 
45 status_t OV7670_InitExt(camera_device_handle_t *handle, const camera_config_t *config, const void *specialConfig);
46 /*******************************************************************************
47  * Variables
48  ******************************************************************************/
49 /*! @brief OV7670 resolution options                                          */
50 ov7670_window_start_point_t OV7670_WINDOW_START_POINT_VGA_DEFAULT   = {140, 16};
51 ov7670_window_start_point_t OV7670_WINDOW_START_POINT_QVGA_DEFAULT  = {272, 16};
52 ov7670_window_start_point_t OV7670_WINDOW_START_POINT_QQVGA_DEFAULT = {140, 16};
53 ov7670_window_start_point_t OV7670_WINDOW_START_POINT_CIF_DEFAULT   = {140, 16};
54 ov7670_window_start_point_t OV7670_WINDOW_START_POINT_QCIF_DEFAULT  = {140, 16};
55 ov7670_window_start_point_t OV7670_WINDOW_START_POINT_QQCIF_DEFAULT = {140, 16};
56 
57 /*! @brief Night mode initialization structure data                           */
58 ov7670_output_format_config_t OV7670_FORMAT_RawBayerRGB       = {0x01, 0x00, 0x00};
59 ov7670_output_format_config_t OV7670_FORMAT_ProcessedBayerRGB = {0x05, 0x00, 0x00};
60 ov7670_output_format_config_t OV7670_FORMAT_YUV422            = {0x00, 0x00, 0x00};
61 ov7670_output_format_config_t OV7670_FORMAT_GRB422            = {0x04, 0x00, 0x00};
62 ov7670_output_format_config_t OV7670_FORMAT_RGB565            = {0x04, 0xd0, 0x00};
63 ov7670_output_format_config_t OV7670_FORMAT_RGB555            = {0x04, 0xf0, 0x00};
64 ov7670_output_format_config_t OV7670_FORMAT_xRGB444           = {0x04, 0xd0, 0x2};
65 ov7670_output_format_config_t OV7670_FORMAT_RGBx444           = {0x04, 0xd0, 0x3};
66 
67 /*! @brief resolution initialization structure data                           */
68 ov7670_resolution_config_t OV7670_RESOLUTION_VGA = {0x00, 0x00, 0x00, 0x3a, 0x35, 0x11, 0xf0, 0x02};   /*!< 640 x 480 */
69 ov7670_resolution_config_t OV7670_RESOLUTION_QVGA_ORIGINAL = {0x10, 0x00, 0x00, 0x3a,
70                                                               0x35, 0x11, 0xf0, 0x02};                 /*!< 320 x 240 */
71 ov7670_resolution_config_t OV7670_RESOLUTION_QVGA  = {0x10, 0x04, 0x19, 0x3a, 0x35, 0x11, 0xf1, 0x02}; /*!< 320 x 240 */
72 ov7670_resolution_config_t OV7670_RESOLUTION_QQVGA = {0x10, 0x04, 0x1A, 0x3a, 0x35, 0x22, 0xf2, 0x02}; /*!< 160 x 120 */
73 
74 ov7670_resolution_config_t OV7670_RESOLUTION_CIF = {0x20, 0x08, 0x11, 0x3a, 0x35, 0x11, 0xf1, 0x02};   /*!< 352 x 288 */
75 ov7670_resolution_config_t OV7670_RESOLUTION_QCIF_ORIGINAL = {0x21, 0x08, 0x11, 0x3a,
76                                                               0x35, 0x11, 0xf1, 0x02};                 /*!< 176 x 144 */
77 ov7670_resolution_config_t OV7670_RESOLUTION_QCIF  = {0x28, 0x00, 0x11, 0x3a, 0x35, 0x11, 0xf1, 0x02}; /*!< 176 x 144 */
78 ov7670_resolution_config_t OV7670_RESOLUTION_QQCIF = {0x28, 0x0c, 0x12, 0x3a, 0x35, 0x22, 0xf2, 0x02}; /*!< 88 x 72 */
79 
80 /*! @brief Special effects configuration initialization structure data       */
81 ov7670_windowing_config_t OV7670_WINDOW_VGA   = {0x36, 0x13, 0x01, 0x0a, 0x02, 0x7a};
82 ov7670_windowing_config_t OV7670_WINDOW_QVGA  = {0x80, 0x15, 0x03, 0x00, 0x03, 0x7b};
83 ov7670_windowing_config_t OV7670_WINDOW_QQVGA = {0x64, 0x16, 0x04, 0x0a, 0x03, 0x7b};
84 ov7670_windowing_config_t OV7670_WINDOW_CIF   = {0x12, 0x15, 0x0b, 0x0a, 0x03, 0x7b};
85 ov7670_windowing_config_t OV7670_WINDOW_QCIF  = {0x80, 0x39, 0x03, 0x0a, 0x03, 0x7b};
86 ov7670_windowing_config_t OV7670_WINDOW_QQCIF = {0x64, 0x3a, 0x03, 0x06, 0x03, 0x7b};
87 
88 /*! @brief Frame rate initialization structure data                           */
89 ov7670_frame_rate_config_t OV7670_30FPS_26MHZ_XCLK = {0x80, 0x0a, 0x00, 0x00, 0x2b, 0x00};
90 ov7670_frame_rate_config_t OV7670_25FPS_26MHZ_XCLK = {0x80, 0x0a, 0x00, 0x00, 0x99, 0x00};
91 ov7670_frame_rate_config_t OV7670_15FPS_26MHZ_XCLK = {0x00, 0x0a, 0x00, 0x00, 0x2b, 0x00};
92 ov7670_frame_rate_config_t OV7670_14FPS_26MHZ_XCLK = {0x00, 0x0a, 0x00, 0x00, 0x46, 0x00};
93 
94 ov7670_frame_rate_config_t OV7670_30FPS_24MHZ_XCLK = {0x80, 0x0a, 0x00, 0x00, 0x00, 0x00};
95 ov7670_frame_rate_config_t OV7670_25FPS_24MHZ_XCLK = {0x80, 0x0a, 0x00, 0x00, 0x66, 0x00};
96 ov7670_frame_rate_config_t OV7670_15FPS_24MHZ_XCLK = {0x00, 0x0a, 0x00, 0x00, 0x00, 0x00};
97 ov7670_frame_rate_config_t OV7670_14FPS_24MHZ_XCLK = {0x00, 0x0a, 0x00, 0x00, 0x1a, 0x00};
98 
99 ov7670_frame_rate_config_t OV7670_30FPS_13MHZ_XCLK = {0x00, 0x4a, 0x00, 0x00, 0x2b, 0x00};
100 ov7670_frame_rate_config_t OV7670_25FPS_13MHZ_XCLK = {0x00, 0x4a, 0x00, 0x00, 0x99, 0x00};
101 ov7670_frame_rate_config_t OV7670_15FPS_13MHZ_XCLK = {0x01, 0x4a, 0x00, 0x00, 0x2b, 0x00};
102 ov7670_frame_rate_config_t OV7670_14FPS_13MHZ_XCLK = {0x01, 0x4a, 0x00, 0x00, 0x46, 0x00};
103 
104 ov7670_frame_rate_config_t OV7670_30FPS_12MHZ_XCLK = {0x00, 0x4a, 0x00, 0x00, 0x2b, 0x00};
105 ov7670_frame_rate_config_t OV7670_25FPS_12MHZ_XCLK = {0x00, 0x4a, 0x00, 0x00, 0x66, 0x00};
106 ov7670_frame_rate_config_t OV7670_15FPS_12MHZ_XCLK = {0x01, 0x4a, 0x00, 0x00, 0x2b, 0x00};
107 ov7670_frame_rate_config_t OV7670_14FPS_12MHZ_XCLK = {0x01, 0x4a, 0x00, 0x00, 0x46, 0x00};
108 
109 /*! @brief Night mode initialization structure data                           */
110 ov7670_night_mode_config_t OV7670_NIGHT_MODE_DISABLED       = {0x00};
111 ov7670_night_mode_config_t OV7670_NIGHT_MODE_AUTO_FR_DIVBY2 = {0xa0};
112 ov7670_night_mode_config_t OV7670_NIGHT_MODE_AUTO_FR_DIVBY4 = {0xc0};
113 ov7670_night_mode_config_t OV7670_NIGHT_MODE_AUTO_FR_DIVBY8 = {0xe0};
114 
115 /*! @brief Banding filter initialization structure data                       */
116 ov7670_filter_config_t OV7670_FILTER_DISABLED                          = {0x00, 0x98, 0x7f, 0x02, 0x03, 0x02};
117 ov7670_filter_config_t OV7670_FILTER_30FPS_60HZ                        = {0x20, 0x98, 0x7f, 0x02, 0x03, 0x02};
118 ov7670_filter_config_t OV7670_FILTER_15FPS_60HZ                        = {0x20, 0x4c, 0x3f, 0x05, 0x07, 0x02};
119 ov7670_filter_config_t OV7670_FILTER_25FPS_50HZ                        = {0x20, 0x98, 0x7f, 0x03, 0x03, 0x0a};
120 ov7670_filter_config_t OV7670_FILTER_14FPS_50HZ                        = {0x20, 0x4c, 0x3f, 0x06, 0x07, 0x0a};
121 ov7670_filter_config_t OV7670_FILTER_30FPS_60HZ_AUTO_LIGHT_FREQ_DETECT = {0x20, 0x98, 0x7f, 0x02, 0x03, 0x12};
122 ov7670_filter_config_t OV7670_FILTER_15FPS_60HZ_AUTO_LIGHT_FREQ_DETECT = {0x20, 0x4c, 0x3f, 0x05, 0x07, 0x12};
123 ov7670_filter_config_t OV7670_FILTER_25FPS_50HZ_AUTO_LIGHT_FREQ_DETECT = {0x20, 0x98, 0x7f, 0x03, 0x03, 0x1a};
124 ov7670_filter_config_t OV7670_FILTER_14FPS_50HZ_AUTO_LIGHT_FREQ_DETECT = {0x20, 0x4c, 0x3f, 0x06, 0x07, 0x1a};
125 
126 /*! @brief White balance initialization structure data                        */
127 ov7670_white_balance_config_t OV7670_WHITE_BALANCE_DEFAULT  = {0x02, 0x9a, 0xc0, 0x55, 0x02, 0x14,
128                                                                0xf0, 0x45, 0x61, 0x51, 0x79, 0x08};
129 ov7670_white_balance_config_t OV7670_WHITE_BALANCE_DISABLED = {0x00, 0x9a, 0xc0, 0x55, 0x02, 0x14,
130                                                                0xf0, 0x45, 0x61, 0x51, 0x79, 0x00};
131 ov7670_white_balance_config_t OV7670_WHITE_BALANCE_SIMPLE   = {0x02, 0x9f, 0x10, 0x55, 0x02, 0x14,
132                                                                0xf0, 0x45, 0x61, 0x51, 0x79, 0x08};
133 
134 /*! @brief Light mode configuration initialization structure data             */
135 ov7670_light_mode_config_t OV7670_LIGHT_MODE_DISABLED = {0x05, 0x0a, 0x08, 0x00, 0x08};
136 ov7670_light_mode_config_t OV7670_LIGHT_MODE_AUTO     = {0xc5, 0x3a, 0x08, 0x00, 0x08};
137 ov7670_light_mode_config_t OV7670_LIGHT_MODE_SUNNY    = {0xc5, 0x6a, 0x5a, 0x00, 0x5c};
138 ov7670_light_mode_config_t OV7670_LIGHT_MODE_CLOUDY   = {0xc5, 0x0a, 0x58, 0x00, 0x60};
139 ov7670_light_mode_config_t OV7670_LIGHT_MODE_OFFICE   = {0xc5, 0x2a, 0x84, 0x00, 0x4c};
140 ov7670_light_mode_config_t OV7670_LIGHT_MODE_HOME     = {0xc5, 0x1a, 0x96, 0x00, 0x40};
141 
142 /*! @brief Color saturation configuration initialization structure data       */
143 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_4PLUS   = {0xc0, 0xc0, 0x00, 0x33, 0x8d, 0xc0, 0x9e, 0x02};
144 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_3PLUS   = {0x99, 0x99, 0x00, 0x28, 0x71, 0x99, 0x9e, 0x02};
145 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_2PLUS   = {0xc0, 0xc0, 0x00, 0x33, 0x8d, 0xc0, 0x9e, 0x00};
146 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_1PLUS   = {0x99, 0x99, 0x00, 0x28, 0x71, 0x99, 0x9e, 0x00};
147 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_0       = {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80, 0x9e, 0x00};
148 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_DEFAULT = {0x40, 0x34, 0x0c, 0x17, 0x29, 0x40, 0x1e, 0x00};
149 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_1MINUS  = {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66, 0x9e, 0x00};
150 ov7670_color_saturation_config_t OV7670_COLOR_SATURATION_2MINUS  = {0x40, 0x40, 0x00, 0x11, 0x2f, 0x40, 0x9e, 0x00};
151 
152 /*! @brief Special effects configuration initialization structure data       */
153 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_ANTIQUE     = {0x18, 0, 255};
154 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_SEPHIA      = {0x18, 16, 146};
155 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_BLUISH      = {0x18, 240, 146};
156 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_GREENISH    = {0x18, 0, 30};
157 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_REDISH      = {0x18, 90, 240};
158 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_BW          = {0x18, 110, 110};
159 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_NEGATIVE    = {0x28, 0x80, 0x80};
160 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_BW_NEGATIVE = {0x38, 110, 110};
161 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_NORMAL      = {0x0c, 0x80, 0x80};
162 ov7670_special_effect_config_t OV7670_SPECIAL_EFFECT_DISABLED    = {0x08, 0x80, 0x80};
163 
164 /*! @brief Special effects configuration initialization structure data       */
165 ov7670_gamma_curve_slope_config_t OV7670_GAMMA_CURVE_SLOPE_DEFAULT = {0x24, 0x04, 0x07, 0x10, 0x28, 0x36, 0x44, 0x52,
166                                                                       0x60, 0x6c, 0x78, 0x8c, 0x9e, 0xbb, 0xd2, 0xe5};
167 ov7670_gamma_curve_slope_config_t OV7670_GAMMA_CURVE_SLOPE1        = {0x20, 0x10, 0x1e, 0x35, 0x5a, 0x69, 0x76, 0x80,
168                                                                       0x88, 0x8f, 0x96, 0xa3, 0xaf, 0xc4, 0xd7, 0xe8};
169 
170 const camera_device_operations_t ov7670_ops = {
171     .init     = OV7670_Init,
172     .deinit   = OV7670_Deinit,
173     .start    = OV7670_Start,
174     .stop     = OV7670_Stop,
175     .control  = OV7670_Control,
176     .init_ext = OV7670_InitExt,
177 };
178 /*******************************************************************************
179  * Code
180  ******************************************************************************/
181 
OV7670_DelayMs(uint32_t ms)182 static void OV7670_DelayMs(uint32_t ms)
183 {
184     VIDEO_DelayMs(ms);
185 }
186 
OV7670_CameraInit(camera_device_handle_t * handle,const ov7670_config_t * config)187 status_t OV7670_CameraInit(camera_device_handle_t *handle, const ov7670_config_t *config)
188 {
189     uint8_t u8TempVal0, u8TempVal1;
190 
191     /* Reset Device */
192     (void)OV7670_WriteReg(handle, OV7670_COM7_REG, 0x80);
193     /* wait for a least 1ms */
194     OV7670_DelayMs(5); /* 5ms */
195     /* Read product ID nuumber MSB */
196     if (OV7670_ReadReg(handle, OV7670_PID_REG, &u8TempVal0) != kStatus_Success)
197     {
198         return kStatus_Fail;
199     }
200     /* Read product ID nuumber MSB */
201     if (OV7670_ReadReg(handle, OV7670_VER_REG, &u8TempVal1) != kStatus_Success)
202     {
203         return kStatus_Fail;
204     }
205     if ((u8TempVal0 != OV7670_PID_NUM) && (u8TempVal1 != OV7670_VER_NUM))
206     {
207         return kStatus_Fail;
208     }
209 
210     /* NULL pointer means default setting. */
211     if (config == NULL)
212     {
213         /* Reset Device */
214         (void)OV7670_WriteReg(handle, OV7670_COM7_REG, 0x80);
215         /* wait for a bit */
216         OV7670_DelayMs(5); /* 5ms */
217     }
218     else
219     {
220         (void)OV7670_Configure(handle, config);
221     }
222     /* MVFP */
223     if (OV7670_ReadReg(handle, OV7670_MVFP_REG, &u8TempVal1) != kStatus_Success)
224     {
225         return kStatus_Fail;
226     }
227     if (0U == (u8TempVal1 & OV7670_MVFP_MIRROR_MASK))
228     {
229         u8TempVal1 |= OV7670_MVFP_MIRROR_MASK;
230         (void)OV7670_WriteReg(handle, OV7670_MVFP_REG, u8TempVal1);
231     }
232     return kStatus_Success;
233 }
234 
OV7670_ContrastAdjustment(camera_device_handle_t * handle,uint8_t val)235 status_t OV7670_ContrastAdjustment(camera_device_handle_t *handle, uint8_t val)
236 {
237     status_t status = kStatus_Success;
238 
239     status = OV7670_WriteReg(handle, OV7670_CONTRAS_CENTER_REG, 0x80);
240     status = OV7670_ModifyReg(handle, OV7670_MTXS_REG, 0x80, 0x00);
241     status = OV7670_WriteReg(handle, OV7670_CONTRAS_REG, val);
242     return status;
243 }
244 
OV7670_BrightnessAdjustment(camera_device_handle_t * handle,uint8_t val)245 status_t OV7670_BrightnessAdjustment(camera_device_handle_t *handle, uint8_t val)
246 {
247     status_t status = kStatus_Success;
248 
249     status = OV7670_WriteReg(handle, OV7670_BRIGHT_REG, val);
250 
251     return status;
252 }
253 
OV7670_Configure(camera_device_handle_t * handle,const ov7670_config_t * config)254 status_t OV7670_Configure(camera_device_handle_t *handle, const ov7670_config_t *config)
255 {
256     status_t status = kStatus_Success;
257 
258     ov7670_windowing_config_t *windowConfig;
259     (void)OV7670_OutputFormat(handle, config->outputFormat);
260     (void)OV7670_Resolution(handle, config->resolution);
261 
262     switch ((video_resolution_t)config->resolution)
263     {
264         case kVIDEO_ResolutionVGA:
265             windowConfig = (ov7670_windowing_config_t *)&OV7670_WINDOW_VGA;
266             break;
267         case kVIDEO_ResolutionQVGA:
268             windowConfig = (ov7670_windowing_config_t *)&OV7670_WINDOW_QVGA;
269             break;
270         case kVIDEO_ResolutionQQVGA:
271             windowConfig = (ov7670_windowing_config_t *)&OV7670_WINDOW_QQVGA;
272             break;
273         case kVIDEO_ResolutionCIF:
274             windowConfig = (ov7670_windowing_config_t *)&OV7670_WINDOW_CIF;
275             break;
276         case kVIDEO_ResolutionQCIF:
277             windowConfig = (ov7670_windowing_config_t *)&OV7670_WINDOW_QCIF;
278             break;
279         case kVIDEO_ResolutionQQCIF:
280             windowConfig = (ov7670_windowing_config_t *)&OV7670_WINDOW_QQCIF;
281             break;
282         default:
283             status = kStatus_Fail; /* not supported resolution */
284             break;
285     }
286 
287     if (kStatus_Success != status)
288     {
289         return status;
290     }
291 
292     (void)OV7670_SetWindow(handle, windowConfig);
293     (void)OV7670_FrameRateAdjustment(handle, config->frameRate);
294 
295     /* configure Hsync/Vsync for EZH */
296     (void)OV7670_WriteReg(handle, OV7670_COM10_REG, 0x20); /* no PCLK toggle during Hblank, mandatory! */
297 
298     if (config->advancedConfig == NULL)
299     {
300         (void)OV7670_BandingFilterSelection(handle, (ov7670_filter_config_t *)&OV7670_FILTER_25FPS_50HZ);
301         (void)OV7670_NightMode(handle, (ov7670_night_mode_config_t *)&OV7670_NIGHT_MODE_DISABLED);
302         (void)OV7670_WhiteBalance(handle, (ov7670_white_balance_config_t *)&OV7670_WHITE_BALANCE_SIMPLE);
303         (void)OV7670_LightMode(handle, (ov7670_light_mode_config_t *)&OV7670_LIGHT_MODE_DISABLED);
304         (void)OV7670_ColorSaturation(handle, (ov7670_color_saturation_config_t *)&OV7670_COLOR_SATURATION_2PLUS);
305         (void)OV7670_SpecialEffects(handle, (ov7670_special_effect_config_t *)&OV7670_SPECIAL_EFFECT_DISABLED);
306         (void)OV7670_GammaCurveSlope(handle, (ov7670_gamma_curve_slope_config_t *)&OV7670_GAMMA_CURVE_SLOPE_DEFAULT);
307     }
308     else
309     {
310         (void)OV7670_BandingFilterSelection(handle, config->advancedConfig->filter);
311         (void)OV7670_NightMode(handle, config->advancedConfig->nightMode);
312         (void)OV7670_WhiteBalance(handle, config->advancedConfig->whiteBalance);
313         (void)OV7670_LightMode(handle, config->advancedConfig->lightMode);
314         (void)OV7670_ColorSaturation(handle, config->advancedConfig->colorSaturation);
315         (void)OV7670_SpecialEffects(handle, config->advancedConfig->specialEffect);
316         (void)OV7670_GammaCurveSlope(handle, config->advancedConfig->gammaCurveSlope);
317     }
318 
319     (void)OV7670_ContrastAdjustment(handle, config->contrast);
320     (void)OV7670_BrightnessAdjustment(handle, config->brightness);
321     (void)OV7670_WriteReg(handle, 0xb0, 0x84); /*!< because of colors */
322     (void)OV7670_WriteReg(handle, 0xff, 0xff);
323 
324     return kStatus_Success;
325 }
326 
OV7670_OutputFormat(camera_device_handle_t * handle,const ov7670_output_format_config_t * outputFormatConfig)327 status_t OV7670_OutputFormat(camera_device_handle_t *handle, const ov7670_output_format_config_t *outputFormatConfig)
328 {
329     (void)OV7670_ModifyReg(handle, OV7670_COM7_REG, 0x05, outputFormatConfig->com7);
330     (void)OV7670_ModifyReg(handle, OV7670_RGB444_REG, 0x03, outputFormatConfig->rgb444);
331     (void)OV7670_ModifyReg(handle, OV7670_COM15_REG, 0x30, outputFormatConfig->com15);
332 
333     return kStatus_Success;
334 }
335 
OV7670_Resolution(camera_device_handle_t * handle,uint32_t resolution)336 status_t OV7670_Resolution(camera_device_handle_t *handle, uint32_t resolution)
337 {
338     status_t status = kStatus_Success;
339 
340     ov7670_resolution_config_t *resolution_config;
341     switch ((video_resolution_t)resolution)
342     {
343         case kVIDEO_ResolutionVGA:
344             resolution_config = (ov7670_resolution_config_t *)&OV7670_RESOLUTION_VGA;
345             break;
346         case kVIDEO_ResolutionQVGA:
347             resolution_config = (ov7670_resolution_config_t *)&OV7670_RESOLUTION_QVGA;
348             break;
349         case kVIDEO_ResolutionQQVGA:
350             resolution_config = (ov7670_resolution_config_t *)&OV7670_RESOLUTION_QQVGA;
351             break;
352         case kVIDEO_ResolutionCIF:
353             resolution_config = (ov7670_resolution_config_t *)&OV7670_RESOLUTION_CIF;
354             break;
355         case kVIDEO_ResolutionQCIF:
356             resolution_config = (ov7670_resolution_config_t *)&OV7670_RESOLUTION_QCIF;
357             break;
358         case kVIDEO_ResolutionQQCIF:
359             resolution_config = (ov7670_resolution_config_t *)&OV7670_RESOLUTION_QQCIF;
360             break;
361         default:
362             status = kStatus_Fail; /*!< not supported resolution */
363             break;
364     }
365 
366     if (kStatus_Success != status)
367     {
368         return status;
369     }
370 
371     (void)OV7670_ModifyReg(handle, OV7670_COM7_REG, 0x38, resolution_config->com7);
372     (void)OV7670_ModifyReg(handle, OV7670_COM3_REG, 0x0c, resolution_config->com3);
373     (void)OV7670_WriteReg(handle, OV7670_COM14_REG, resolution_config->com14);
374     (void)OV7670_WriteReg(handle, OV7670_SCALING_XSC_REG, resolution_config->scalingXsc);
375     (void)OV7670_WriteReg(handle, OV7670_SCALING_YSC_REG, resolution_config->scalingYsc);
376     (void)OV7670_ModifyReg(handle, OV7670_SCALING_DCWCTR_REG, 0x33, resolution_config->scalingDcwctr);
377     (void)OV7670_WriteReg(handle, OV7670_SCALING_PCLK_DIV_REG, resolution_config->scalingPclkDiv);
378     (void)OV7670_WriteReg(handle, OV7670_SCALING_PCLK_DELAY_REG, resolution_config->scalingPclkDelay);
379 
380     /* Autotomatically set output window after resolution change                */
381     (void)OV7670_ModifyReg(handle, OV7670_TSLB_REG, 0x01, 0x01);
382 
383     return kStatus_Success;
384 }
385 
OV7670_SetWindow(camera_device_handle_t * handle,const ov7670_windowing_config_t * windowingConfig)386 status_t OV7670_SetWindow(camera_device_handle_t *handle, const ov7670_windowing_config_t *windowingConfig)
387 {
388     (void)OV7670_ModifyReg(handle, OV7670_TSLB_REG, 0x01, 0x00);
389 
390     (void)OV7670_WriteReg(handle, OV7670_HREF_REG, windowingConfig->href);
391     (void)OV7670_WriteReg(handle, OV7670_HSTART_REG, windowingConfig->hstart);
392     (void)OV7670_WriteReg(handle, OV7670_HSTOP_REG, windowingConfig->hstop);
393     (void)OV7670_WriteReg(handle, OV7670_VREF_REG, windowingConfig->vref);
394     (void)OV7670_WriteReg(handle, OV7670_VSTART_REG, windowingConfig->vstart);
395     (void)OV7670_WriteReg(handle, OV7670_VSTOP_REG, windowingConfig->vstop);
396 
397     return kStatus_Success;
398 }
399 
OV7670_FrameRateAdjustment(camera_device_handle_t * handle,const ov7670_frame_rate_config_t * frameRateConfig)400 status_t OV7670_FrameRateAdjustment(camera_device_handle_t *handle, const ov7670_frame_rate_config_t *frameRateConfig)
401 {
402     (void)OV7670_WriteReg(handle, OV7670_CLKRC_REG, frameRateConfig->clkrc);
403     OV7670_DelayMs(2);
404     (void)OV7670_WriteReg(handle, OV7670_DBLV_REG, frameRateConfig->dblv);
405     OV7670_DelayMs(2);
406     (void)OV7670_WriteReg(handle, OV7670_EXHCH_REG, frameRateConfig->exhch);
407     OV7670_DelayMs(2);
408     (void)OV7670_WriteReg(handle, OV7670_EXHCL_REG, frameRateConfig->exhcl);
409     OV7670_DelayMs(2);
410     (void)OV7670_WriteReg(handle, OV7670_DM_LNL_REG, frameRateConfig->dm_lnl);
411     OV7670_DelayMs(2);
412     (void)OV7670_WriteReg(handle, OV7670_DM_LNH_REG, frameRateConfig->dm_lnh);
413     OV7670_DelayMs(2);
414 
415     return kStatus_Success;
416 }
417 
OV7670_NightMode(camera_device_handle_t * handle,const ov7670_night_mode_config_t * nightModeConfig)418 status_t OV7670_NightMode(camera_device_handle_t *handle, const ov7670_night_mode_config_t *nightModeConfig)
419 {
420     (void)OV7670_ModifyReg(handle, OV7670_COM11_REG, 0xe0, nightModeConfig->com11);
421 
422     OV7670_DelayMs(2);
423 
424     return kStatus_Success;
425 }
426 
OV7670_BandingFilterSelection(camera_device_handle_t * handle,const ov7670_filter_config_t * filterConfig)427 status_t OV7670_BandingFilterSelection(camera_device_handle_t *handle, const ov7670_filter_config_t *filterConfig)
428 {
429     (void)OV7670_WriteReg(handle, OV7670_BD50ST_REG, filterConfig->bd50st);      /*!< 50Hz banding filter */
430     (void)OV7670_WriteReg(handle, OV7670_BD60ST_REG, filterConfig->bd60st);      /*!< 60Hz banding filter */
431     (void)OV7670_WriteReg(handle, OV7670_BD50MAX_REG, filterConfig->bd50max);    /*!< x step for 50hz */
432     (void)OV7670_WriteReg(handle, OV7670_BD60MAX_REG, filterConfig->bd60max);    /*!< y step for 60hz */
433     (void)OV7670_ModifyReg(handle, OV7670_COM11_REG, 0x1a, filterConfig->com11); /*!< Automatic Detect banding filter */
434     (void)OV7670_ModifyReg(handle, OV7670_COM8_REG, 0x20, filterConfig->com8);   /*!< banding filter enable */
435 
436     return kStatus_Success;
437 }
438 
OV7670_WhiteBalance(camera_device_handle_t * handle,const ov7670_white_balance_config_t * whiteBalanceConfig)439 status_t OV7670_WhiteBalance(camera_device_handle_t *handle, const ov7670_white_balance_config_t *whiteBalanceConfig)
440 {
441     (void)OV7670_ModifyReg(handle, OV7670_COM8_REG, 0x02, whiteBalanceConfig->com8); /*!< AWB on/off  */
442     (void)OV7670_WriteReg(handle, OV7670_AWBCTR0_REG, whiteBalanceConfig->awbctr0);
443     (void)OV7670_WriteReg(handle, OV7670_AWBCTR1_REG, whiteBalanceConfig->awbctr1);
444     (void)OV7670_WriteReg(handle, OV7670_AWBCTR2_REG, whiteBalanceConfig->awbctr2);
445     (void)OV7670_WriteReg(handle, OV7670_AWBCTR3_REG, whiteBalanceConfig->awbctr3);
446     (void)OV7670_WriteReg(handle, OV7670_AWBC1_REG, whiteBalanceConfig->awbc1);
447     (void)OV7670_WriteReg(handle, OV7670_AWBC2_REG, whiteBalanceConfig->awbc2);
448     (void)OV7670_WriteReg(handle, OV7670_AWBC3_REG, whiteBalanceConfig->awbc3);
449     (void)OV7670_WriteReg(handle, OV7670_AWBC4_REG, whiteBalanceConfig->awbc4);
450     (void)OV7670_WriteReg(handle, OV7670_AWBC5_REG, whiteBalanceConfig->awbc5);
451     (void)OV7670_WriteReg(handle, OV7670_AWBC6_REG, whiteBalanceConfig->awbc6);
452     (void)OV7670_WriteReg(handle, 0x59, 0x91);
453     (void)OV7670_WriteReg(handle, 0x5a, 0x94);
454     (void)OV7670_WriteReg(handle, 0x5b, 0xaa);
455     (void)OV7670_WriteReg(handle, 0x5c, 0x71);
456     (void)OV7670_WriteReg(handle, 0x5d, 0x8d);
457     (void)OV7670_WriteReg(handle, 0x5e, 0x0f);
458     (void)OV7670_WriteReg(handle, 0x5f, 0xf0);
459     (void)OV7670_WriteReg(handle, 0x60, 0xf0);
460     (void)OV7670_WriteReg(handle, 0x61, 0xf0);
461     (void)OV7670_ModifyReg(handle, OV7670_COM16_REG, 0x08, whiteBalanceConfig->com16); /*!< AWB gain on */
462 
463     return kStatus_Success;
464 }
465 
OV7670_LightMode(camera_device_handle_t * handle,const ov7670_light_mode_config_t * lightModeConfig)466 status_t OV7670_LightMode(camera_device_handle_t *handle, const ov7670_light_mode_config_t *lightModeConfig)
467 {
468     (void)OV7670_ModifyReg(handle, OV7670_COM8_REG, 0xc5, lightModeConfig->com8);
469     (void)OV7670_ModifyReg(handle, OV7670_COM9_REG, 0x7a, lightModeConfig->com9);
470     (void)OV7670_WriteReg(handle, OV7670_RED_REG, lightModeConfig->red);
471     (void)OV7670_WriteReg(handle, OV7670_GGAIN_REG, lightModeConfig->green);
472     (void)OV7670_WriteReg(handle, OV7670_BLUE_REG, lightModeConfig->blue);
473     (void)OV7670_WriteReg(handle, OV7670_GAIN_REG, 0x00);
474     OV7670_DelayMs(2);
475 
476     /*!< Exposure value */
477     (void)OV7670_WriteReg(handle, OV7670_AECH_REG, 0x00);
478     OV7670_DelayMs(2);
479     (void)OV7670_WriteReg(handle, OV7670_AECHH_REG, 0x00);
480     OV7670_DelayMs(2);
481     (void)OV7670_ModifyReg(handle, OV7670_COM1_REG, 0x3, 0x00);
482     OV7670_DelayMs(2);
483     /*!< AGC/AEC stable operation region configuration */
484     (void)OV7670_WriteReg(handle, OV7670_AEW_REG, 0x75);
485     OV7670_DelayMs(2);
486     (void)OV7670_WriteReg(handle, OV7670_AEB_REG, 0x63);
487     OV7670_DelayMs(2);
488     (void)OV7670_WriteReg(handle, OV7670_VPT_REG, 0xd4);
489     OV7670_DelayMs(2);
490 
491     return kStatus_Success;
492 }
493 
OV7670_ColorSaturation(camera_device_handle_t * handle,const ov7670_color_saturation_config_t * colorSaturationConfig)494 status_t OV7670_ColorSaturation(camera_device_handle_t *handle,
495                                 const ov7670_color_saturation_config_t *colorSaturationConfig)
496 {
497     (void)OV7670_WriteReg(handle, OV7670_MTX1_REG, colorSaturationConfig->mtx1);
498     (void)OV7670_WriteReg(handle, OV7670_MTX2_REG, colorSaturationConfig->mtx2);
499     (void)OV7670_WriteReg(handle, OV7670_MTX3_REG, colorSaturationConfig->mtx3);
500     (void)OV7670_WriteReg(handle, OV7670_MTX4_REG, colorSaturationConfig->mtx4);
501     (void)OV7670_WriteReg(handle, OV7670_MTX5_REG, colorSaturationConfig->mtx5);
502     (void)OV7670_WriteReg(handle, OV7670_MTX6_REG, colorSaturationConfig->mtx6);
503     (void)OV7670_WriteReg(handle, OV7670_MTXS_REG, colorSaturationConfig->mtxs);
504     (void)OV7670_ModifyReg(handle, OV7670_COM16_REG, 0x02, colorSaturationConfig->com16);
505 
506     return kStatus_Success;
507 }
508 
OV7670_SpecialEffects(camera_device_handle_t * handle,const ov7670_special_effect_config_t * specialEffectConfig)509 status_t OV7670_SpecialEffects(camera_device_handle_t *handle,
510                                const ov7670_special_effect_config_t *specialEffectConfig)
511 {
512     (void)OV7670_ModifyReg(handle, OV7670_TSLB_REG, 0xfe, specialEffectConfig->tslb);
513     (void)OV7670_WriteReg(handle, OV7670_MANU_REG, specialEffectConfig->manu);
514     (void)OV7670_WriteReg(handle, OV7670_MANV_REG, specialEffectConfig->manv);
515 
516     return kStatus_Success;
517 }
518 
OV7670_SetWindowByCoordinates(camera_device_handle_t * handle,ov7670_window_start_point_t * startPoint,uint32_t resolution)519 status_t OV7670_SetWindowByCoordinates(camera_device_handle_t *handle,
520                                        ov7670_window_start_point_t *startPoint,
521                                        uint32_t resolution)
522 {
523     uint16_t u16Temp, u16Href, u16Vref;
524 
525     (void)OV7670_ModifyReg(handle, OV7670_TSLB_REG, 0x01, 0x00);
526 
527     u16Temp = startPoint->hstartCoordinate + FSL_VIDEO_EXTRACT_WIDTH(resolution);
528     u16Href = (u16Temp & 0x07U);
529     u16Href = u16Href << 3;
530     u16Href |= (startPoint->hstartCoordinate & 0x07U);
531     u16Href |= 0xc0U;
532     (void)OV7670_WriteReg(handle, OV7670_HREF_REG, (uint8_t)u16Href);
533     u16Temp = u16Temp >> 3;
534     (void)OV7670_WriteReg(handle, OV7670_HSTOP_REG, (uint8_t)u16Temp);
535     u16Temp = ((startPoint->hstartCoordinate & 0x7f8U) >> 3);
536     (void)OV7670_WriteReg(handle, OV7670_HSTART_REG, (uint8_t)u16Temp);
537 
538     u16Temp = startPoint->vstartCoordinate + FSL_VIDEO_EXTRACT_HEIGHT(resolution);
539     u16Vref = (u16Temp & 0x03U);
540     u16Vref = u16Vref << 2;
541     u16Vref |= (startPoint->vstartCoordinate & 0x03U);
542     u16Vref &= 0xF0U;
543     (void)OV7670_ModifyReg(handle, OV7670_VREF_REG, 0xc0, (uint8_t)u16Vref);
544     u16Temp = u16Temp >> 2;
545     (void)OV7670_WriteReg(handle, OV7670_VSTOP_REG, (uint8_t)u16Temp);
546     u16Temp = ((startPoint->vstartCoordinate & 0x3fcU) >> 2);
547     (void)OV7670_WriteReg(handle, OV7670_VSTART_REG, (uint8_t)u16Temp);
548 
549     return kStatus_Success;
550 }
551 
OV7670_GammaCurveSlope(camera_device_handle_t * handle,const ov7670_gamma_curve_slope_config_t * gammaCurveSlopeConfig)552 status_t OV7670_GammaCurveSlope(camera_device_handle_t *handle,
553                                 const ov7670_gamma_curve_slope_config_t *gammaCurveSlopeConfig)
554 {
555     (void)OV7670_WriteReg(handle, OV7670_SLOP_REG, gammaCurveSlopeConfig->slope);
556     (void)OV7670_WriteReg(handle, OV7670_GAM1_REG, gammaCurveSlopeConfig->gam1);
557     (void)OV7670_WriteReg(handle, OV7670_GAM2_REG, gammaCurveSlopeConfig->gam2);
558     (void)OV7670_WriteReg(handle, OV7670_GAM3_REG, gammaCurveSlopeConfig->gam3);
559     (void)OV7670_WriteReg(handle, OV7670_GAM4_REG, gammaCurveSlopeConfig->gam4);
560     (void)OV7670_WriteReg(handle, OV7670_GAM5_REG, gammaCurveSlopeConfig->gam5);
561     (void)OV7670_WriteReg(handle, OV7670_GAM6_REG, gammaCurveSlopeConfig->gam6);
562     (void)OV7670_WriteReg(handle, OV7670_GAM7_REG, gammaCurveSlopeConfig->gam7);
563     (void)OV7670_WriteReg(handle, OV7670_GAM8_REG, gammaCurveSlopeConfig->gam8);
564     (void)OV7670_WriteReg(handle, OV7670_GAM9_REG, gammaCurveSlopeConfig->gam9);
565     (void)OV7670_WriteReg(handle, OV7670_GAM10_REG, gammaCurveSlopeConfig->gam10);
566     (void)OV7670_WriteReg(handle, OV7670_GAM11_REG, gammaCurveSlopeConfig->gam11);
567     (void)OV7670_WriteReg(handle, OV7670_GAM12_REG, gammaCurveSlopeConfig->gam12);
568     (void)OV7670_WriteReg(handle, OV7670_GAM13_REG, gammaCurveSlopeConfig->gam13);
569     (void)OV7670_WriteReg(handle, OV7670_GAM14_REG, gammaCurveSlopeConfig->gam14);
570     (void)OV7670_WriteReg(handle, OV7670_GAM15_REG, gammaCurveSlopeConfig->gam15);
571 
572     return kStatus_Success;
573 }
574 
OV7670_GetDefaultConfig(ov7670_config_t * config)575 void OV7670_GetDefaultConfig(ov7670_config_t *config)
576 {
577     config->outputFormat   = (ov7670_output_format_config_t *)&OV7670_FORMAT_RGB565;
578     config->resolution     = (uint32_t)kVIDEO_ResolutionQQVGA;
579     config->frameRate      = (ov7670_frame_rate_config_t *)&OV7670_25FPS_12MHZ_XCLK;
580     config->contrast       = 0x30;
581     config->brightness     = 0x10;
582     config->advancedConfig = NULL;
583 }
584 
OV7670_Init(camera_device_handle_t * handle,const camera_config_t * config)585 status_t OV7670_Init(camera_device_handle_t *handle, const camera_config_t *config)
586 {
587     status_t status;
588     ov7670_resource_t *resource = (ov7670_resource_t *)(handle->resource);
589     ov7670_config_t cameraConfig;
590 
591     if ((kVIDEO_PixelFormatYUYV != config->pixelFormat) && (kVIDEO_PixelFormatRGB565 != config->pixelFormat) &&
592         (kVIDEO_PixelFormatRGBX4444 != config->pixelFormat) && (kVIDEO_PixelFormatXRGB4444 != config->pixelFormat) &&
593         (kVIDEO_PixelFormatXRGB1555 != config->pixelFormat))
594     {
595         return kStatus_InvalidArgument;
596     }
597 
598     if ((15U != config->framePerSec) && (30U != config->framePerSec) && (25U != config->framePerSec) &&
599         (14U != config->framePerSec))
600     {
601         return kStatus_InvalidArgument;
602     }
603 
604     if ((kCAMERA_InterfaceNonGatedClock != config->interface) && (kCAMERA_InterfaceGatedClock != config->interface))
605     {
606         return kStatus_InvalidArgument;
607     }
608 
609     OV7670_GetDefaultConfig(&cameraConfig);
610     cameraConfig.resolution = config->resolution;
611     switch (resource->xclock)
612     {
613         case kOV7670_InputClock24MHZ:
614             if (config->framePerSec == 30U)
615             {
616                 cameraConfig.frameRate = &OV7670_30FPS_24MHZ_XCLK;
617             }
618             else if (config->framePerSec == 25U)
619             {
620                 cameraConfig.frameRate = &OV7670_25FPS_24MHZ_XCLK;
621             }
622             else if (config->framePerSec == 15U)
623             {
624                 cameraConfig.frameRate = &OV7670_15FPS_24MHZ_XCLK;
625             }
626             else if (config->framePerSec == 14U)
627             {
628                 cameraConfig.frameRate = &OV7670_14FPS_24MHZ_XCLK;
629             }
630             else
631             {
632                 assert(false);
633             }
634             break;
635         case kOV7670_InputClock12MHZ:
636             if (config->framePerSec == 30U)
637             {
638                 cameraConfig.frameRate = &OV7670_30FPS_12MHZ_XCLK;
639             }
640             else if (config->framePerSec == 25U)
641             {
642                 cameraConfig.frameRate = &OV7670_25FPS_12MHZ_XCLK;
643             }
644             else if (config->framePerSec == 15U)
645             {
646                 cameraConfig.frameRate = &OV7670_15FPS_12MHZ_XCLK;
647             }
648             else if (config->framePerSec == 14U)
649             {
650                 cameraConfig.frameRate = &OV7670_14FPS_12MHZ_XCLK;
651             }
652             else
653             {
654                 assert(false);
655             }
656             break;
657         case kOV7670_InputClock26MHZ:
658             if (config->framePerSec == 30U)
659             {
660                 cameraConfig.frameRate = &OV7670_30FPS_26MHZ_XCLK;
661             }
662             else if (config->framePerSec == 25U)
663             {
664                 cameraConfig.frameRate = &OV7670_25FPS_26MHZ_XCLK;
665             }
666             else if (config->framePerSec == 15U)
667             {
668                 cameraConfig.frameRate = &OV7670_15FPS_26MHZ_XCLK;
669             }
670             else if (config->framePerSec == 14U)
671             {
672                 cameraConfig.frameRate = &OV7670_14FPS_26MHZ_XCLK;
673             }
674             else
675             {
676                 assert(false);
677             }
678             break;
679         case kOV7670_InputClock13MHZ:
680             if (config->framePerSec == 30U)
681             {
682                 cameraConfig.frameRate = &OV7670_30FPS_13MHZ_XCLK;
683             }
684             else if (config->framePerSec == 25U)
685             {
686                 cameraConfig.frameRate = &OV7670_25FPS_13MHZ_XCLK;
687             }
688             else if (config->framePerSec == 15U)
689             {
690                 cameraConfig.frameRate = &OV7670_15FPS_13MHZ_XCLK;
691             }
692             else if (config->framePerSec == 14U)
693             {
694                 cameraConfig.frameRate = &OV7670_14FPS_13MHZ_XCLK;
695             }
696             else
697             {
698                 assert(false);
699             }
700             break;
701         default:
702             assert(false);
703             break;
704     }
705 
706     switch (config->pixelFormat)
707     {
708         case kVIDEO_PixelFormatYUYV:
709             cameraConfig.outputFormat = &OV7670_FORMAT_YUV422;
710             break;
711 
712         case kVIDEO_PixelFormatXRGB1555:
713             cameraConfig.outputFormat = &OV7670_FORMAT_RGB555;
714             break;
715 
716         case kVIDEO_PixelFormatRGBX4444:
717             cameraConfig.outputFormat = &OV7670_FORMAT_RGBx444;
718             break;
719 
720         case kVIDEO_PixelFormatXRGB4444:
721             cameraConfig.outputFormat = &OV7670_FORMAT_xRGB444;
722             break;
723 
724         case kVIDEO_PixelFormatRGB565:
725         default:
726             cameraConfig.outputFormat = &OV7670_FORMAT_RGB565;
727             break;
728     }
729 
730     do
731     {
732         status = OV7670_CameraInit(handle, &cameraConfig);
733     } while (status != kStatus_Success);
734 
735     return status;
736 }
737 
OV7670_Deinit(camera_device_handle_t * handle)738 status_t OV7670_Deinit(camera_device_handle_t *handle)
739 {
740     return kStatus_Success;
741 }
742 
OV7670_Start(camera_device_handle_t * handle)743 status_t OV7670_Start(camera_device_handle_t *handle)
744 {
745     return kStatus_Success;
746 }
747 
OV7670_Stop(camera_device_handle_t * handle)748 status_t OV7670_Stop(camera_device_handle_t *handle)
749 {
750     return kStatus_Success;
751 }
752 
OV7670_InitExt(camera_device_handle_t * handle,const camera_config_t * config,const void * specialConfig)753 status_t OV7670_InitExt(camera_device_handle_t *handle, const camera_config_t *config, const void *specialConfig)
754 {
755     return OV7670_Init(handle, config);
756 }
757 
OV7670_Control(camera_device_handle_t * handle,camera_device_cmd_t cmd,int32_t arg)758 status_t OV7670_Control(camera_device_handle_t *handle, camera_device_cmd_t cmd, int32_t arg)
759 {
760     return kStatus_InvalidArgument;
761 }
762