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