]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M7_SAMV71_Xplained_IAR_Keil/libboard_samv7-ek/source/omnivision.c
Final V8.2.1 release ready for tagging:
[freertos] / FreeRTOS / Demo / CORTEX_M7_SAMV71_Xplained_IAR_Keil / libboard_samv7-ek / source / omnivision.c
1 /* ----------------------------------------------------------------------------\r
2  *         SAM Software Package License \r
3  * ----------------------------------------------------------------------------\r
4  * Copyright (c) 2013, Atmel Corporation\r
5  *\r
6  * All rights reserved.\r
7  *\r
8  * Redistribution and use in source and binary forms, with or without\r
9  * modification, are permitted provided that the following conditions are met:\r
10  *\r
11  * - Redistributions of source code must retain the above copyright notice,\r
12  * this list of conditions and the disclaimer below.\r
13  *\r
14  * Atmel's name may not be used to endorse or promote products derived from\r
15  * this software without specific prior written permission.\r
16  *\r
17  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
20  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
23  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
24  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
25  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
27  * ----------------------------------------------------------------------------\r
28  */\r
29 \r
30 /*----------------------------------------------------------------------------\r
31  *        Headers\r
32  *----------------------------------------------------------------------------*/\r
33 #include "board.h"\r
34 \r
35 /** Slave address of OMNIVISION chips. */\r
36 #define OV_CAPTOR_ADDRESS_1   0x30 \r
37 #define OV_CAPTOR_ADDRESS_2   0x21\r
38 #define OV_CAPTOR_ADDRESS_3   0x3c \r
39 #define OV_CAPTOR_ADDRESS_4   0x10\r
40 \r
41 /** terminating list entry for register in configuration file */\r
42 #define OV_REG_TERM 0xFF\r
43 #define OV_REG_DELAY 0xFFFF\r
44 /** terminating list entry for value in configuration file */\r
45 #define OV_VAL_TERM 0xFF \r
46 \r
47 //static const Pin pin_ISI_RST= PIN_ISI_RST;\r
48 static uint8_t twiSlaveAddr = OV_CAPTOR_ADDRESS_1;\r
49 /*----------------------------------------------------------------------------\r
50  *        Local Functions\r
51  *----------------------------------------------------------------------------*/\r
52 static void ov_reset(void)\r
53 {\r
54     volatile uint32_t i;\r
55     //PIO_Configure(&pin_ISI_RST, 1);\r
56     //PIO_Clear(&pin_ISI_RST);\r
57     for(i = 0; i < 6000; i++ );\r
58     //PIO_Set(&pin_ISI_RST);\r
59     for(i = 0; i<6000; i++ );\r
60 }\r
61 \r
62 \r
63 /**\r
64  * \brief  Read PID and VER\r
65  * \param pTwid TWI interface\r
66  * \return  VER | (PID<<8)\r
67  */\r
68 static uint16_t ov_id8(Twid *pTwid)\r
69 {\r
70     uint8_t id, ver;\r
71     uint8_t status;\r
72     // OV_PID\r
73     status = ov_read_reg8(pTwid, 0x0A, &id);\r
74     if( status != 0 ) return 0;\r
75     TRACE_INFO("PID  = 0x%X\n\r", id);\r
76 \r
77     // OV_VER\r
78     status = ov_read_reg8(pTwid, 0x0B, &ver);\r
79     if( status != 0 ) return 0;\r
80     TRACE_INFO("VER  = 0x%X\n\r", ver);\r
81 \r
82     return((uint16_t)(id <<8) | ver);\r
83 }\r
84 \r
85 /**\r
86  * \brief  Read PID and VER\r
87  * \param pTwid TWI interface\r
88  * \return  VER | (PID<<8)\r
89  */\r
90 static uint16_t ov_id16(Twid *pTwid)\r
91 {\r
92     uint8_t id, ver;\r
93     // OV_PID\r
94     ov_read_reg16(pTwid, 0x300A, &id);\r
95     TRACE_INFO("PID  = 0x%X\n\r", id);\r
96 \r
97     // OV_VER\r
98     ov_read_reg16(pTwid, 0x300B, &ver);\r
99     TRACE_INFO("VER  = 0x%X\n\r", ver);\r
100 \r
101     return((uint16_t)(id <<8) | ver);\r
102 }\r
103 \r
104 /**\r
105  * \brief  Read PID and VER\r
106  * \param pTwid TWI interface\r
107  * \return  VER | (PID<<8)\r
108  */\r
109 static uint16_t ov_id(Twid *pTwid)\r
110 {\r
111     uint16_t id;\r
112     printf("-I- Try TWI address 0x%x \n\r", twiSlaveAddr);\r
113     twiSlaveAddr = OV_CAPTOR_ADDRESS_1;\r
114     id = ov_id8(pTwid);\r
115     if (id == 0) {\r
116         twiSlaveAddr = OV_CAPTOR_ADDRESS_2;\r
117         printf("-I- Try TWI address 0x%x \n\r", twiSlaveAddr);\r
118         id = ov_id8(pTwid);\r
119         if (id == 0) {\r
120             twiSlaveAddr = OV_CAPTOR_ADDRESS_3;\r
121             printf("-I- Try TWI address 0x%x \n\r", twiSlaveAddr);\r
122             id = ov_id16(pTwid);\r
123             if (id == 0) {\r
124                 twiSlaveAddr = OV_CAPTOR_ADDRESS_4;\r
125                 printf("-I- Try TWI address 0x%x \n\r", twiSlaveAddr);\r
126                 id = ov_id16(pTwid);\r
127             }\r
128         }\r
129     }\r
130     return id;\r
131 }\r
132 \r
133 \r
134 /*----------------------------------------------------------------------------\r
135  *        Global Functions\r
136  *----------------------------------------------------------------------------*/\r
137 /**\r
138  * \brief  Read a value from a register in an OV sensor device.\r
139  * \param pTwid TWI interface\r
140  * \param reg Register to be read\r
141  * \param isize Internal address size in bytes.\r
142  * \param pData Data read\r
143  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
144  */\r
145 uint8_t ov_read_reg8(Twid *pTwid, uint8_t reg, uint8_t *pData)\r
146 {\r
147     uint8_t status;\r
148 \r
149     status = TWID_Write( pTwid, twiSlaveAddr, 0, 0, &reg, 1, 0);\r
150     status |= TWID_Read( pTwid, twiSlaveAddr, 0, 0, pData, 1, 0);\r
151     if( status != 0 ) {\r
152         TRACE_ERROR("ov_read_reg pb\n\r");\r
153     }\r
154     return status;\r
155 }\r
156 \r
157 /**\r
158  * \brief  Read a value from a register in an OV sensor device.\r
159  * \param pTwid TWI interface\r
160  * \param reg Register to be read\r
161  * \param pData Data read\r
162  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
163  */\r
164 uint8_t ov_read_reg16(Twid *pTwid, uint16_t reg, uint8_t *pData)\r
165 {\r
166     uint8_t status;\r
167     uint8_t reg8[2];\r
168     reg8[0] = reg>>8;\r
169     reg8[1] = reg & 0xff;\r
170 \r
171     status = TWID_Write( pTwid, twiSlaveAddr, 0, 0, reg8,  2, 0);\r
172     status |= TWID_Read( pTwid, twiSlaveAddr, 0, 0, pData, 1, 0);\r
173     if( status != 0 ) {\r
174 \r
175         TRACE_ERROR("ov_read_reg pb\n\r");\r
176     }\r
177     return status;\r
178 }\r
179 \r
180 /**\r
181  * \brief  Write a value to a register in an OV sensor device.\r
182  * \param pTwid TWI interface\r
183  * \param reg Register to be writen\r
184  * \param pData Data written\r
185  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
186  */\r
187 uint8_t ov_write_reg8(Twid *pTwid, uint8_t reg, uint8_t val)\r
188 {\r
189     uint8_t status;\r
190 \r
191     status = TWID_Write(pTwid, twiSlaveAddr, reg, 1, &val, 1, 0);\r
192     if( status != 0 ) {\r
193         TRACE_ERROR("ov_write_reg pb\n\r");\r
194     }\r
195 \r
196     return status;\r
197 }\r
198 \r
199 /**\r
200  * \brief  Write a value to a register in an OV sensor device.\r
201  * \param pTwid TWI interface\r
202  * \param reg Register to be writen\r
203  * \param pData Data written\r
204  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
205  */\r
206 uint8_t ov_write_reg16(Twid *pTwid, uint16_t reg,  uint8_t val)\r
207 {\r
208     uint8_t status;\r
209     status = TWID_Write(pTwid, twiSlaveAddr, reg, 2, &val, 1, 0);\r
210     if( status != 0 ) {\r
211         TRACE_ERROR("ov_write_reg pb\n\r");\r
212     }\r
213 \r
214     return status;\r
215 }\r
216 \r
217 \r
218 /**\r
219  * \brief  Initialize a list of OV registers.\r
220  * The list of registers is terminated by the pair of values\r
221  * \param pTwid TWI interface\r
222  * \param pReglist Register list to be written\r
223  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
224  */\r
225 uint32_t ov_write_regs8(Twid *pTwid, const struct ov_reg* pReglist)\r
226 {\r
227     uint32_t err;\r
228     uint32_t size=0;\r
229     const struct ov_reg *pNext = pReglist;\r
230     volatile uint32_t delay;\r
231 \r
232     TRACE_DEBUG("ov_write_regs:");\r
233     while (!((pNext->reg == OV_REG_TERM) && (pNext->val == OV_VAL_TERM))) {\r
234         err = ov_write_reg8(pTwid, pNext->reg, pNext->val);\r
235 \r
236         size++;\r
237         for(delay=0;delay<=10000;delay++); \r
238         if (err == TWID_ERROR_BUSY){\r
239             TRACE_ERROR("ov_write_regs: TWI ERROR\n\r");\r
240             return err;\r
241         }\r
242         //printf("(0x%02x,0x%02x) \n\r",  pNext->reg,pNext->val);\r
243         pNext++;\r
244     }\r
245     TRACE_DEBUG_WP("\n\r");\r
246     return 0;\r
247 }\r
248 \r
249 \r
250 /**\r
251  * \brief  Initialize a list of OV registers.\r
252  * The list of registers is terminated by the pair of values\r
253  * \param pTwid TWI interface\r
254  * \param pReglist Register list to be written\r
255  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
256  */\r
257 uint32_t ov_write_regs16(Twid *pTwid, const struct ov_reg* pReglist)\r
258 {\r
259     uint32_t err = 0;\r
260     uint32_t size = 0;\r
261     const struct ov_reg *pNext = pReglist;\r
262     volatile uint32_t delay;\r
263 \r
264     TRACE_DEBUG("ov_write_regs:");\r
265     while (!((pNext->reg == OV_REG_TERM) && (pNext->val == OV_VAL_TERM))) {\r
266         err = ov_write_reg16(pTwid, pNext->reg, pNext->val);\r
267         size++;\r
268         for(delay = 0;delay <= 10000; delay++); \r
269         if (err == TWID_ERROR_BUSY){\r
270             TRACE_ERROR("ov_write_regs: TWI ERROR\n\r");\r
271             return err;\r
272         }\r
273         //printf("(0x%02x,0x%02x) \n\r",  pNext->reg,pNext->val);\r
274         pNext++;\r
275     }\r
276     TRACE_DEBUG_WP("\n\r");\r
277     return 0;\r
278 }\r
279 \r
280 void isOV5640_AF_InitDone(Twid *pTwid)\r
281 {\r
282     uint8_t value = 0;\r
283     while(1){\r
284         ov_read_reg16(pTwid, 0x3029, &value);\r
285         if (value == 0x70) break;\r
286     }\r
287 }\r
288 \r
289 /**\r
290  * \brief  AF for OV 5640\r
291  * \param pTwid TWI interface\r
292  * \return 0 if no error; otherwize TWID_ERROR_BUSY\r
293  */\r
294 uint32_t ov_5640_AF_single(Twid *pTwid)\r
295 {\r
296     uint8_t value;\r
297     ov_write_reg16(pTwid, 0x3023, 1);\r
298     ov_write_reg16(pTwid, 0x3022, 3);\r
299     value =1;\r
300     while(1){\r
301         ov_read_reg16(pTwid, 0x3023, &value);\r
302         if (value == 0) break;\r
303     }\r
304     return 0;\r
305 }\r
306 \r
307 uint32_t ov_5640_AF_continue(Twid *pTwid)\r
308 {\r
309     uint8_t value;\r
310     ov_write_reg16(pTwid, 0x3024, 1);\r
311     ov_write_reg16(pTwid, 0x3022, 4);\r
312     value =1;\r
313     while(1){\r
314         ov_read_reg16(pTwid, 0x3023, &value);\r
315         if (value == 0) break;\r
316     }\r
317     return 0;\r
318 }\r
319 \r
320 uint32_t ov_5640_AFPause(Twid *pTwid)\r
321 {\r
322     uint8_t value;\r
323     ov_write_reg16(pTwid, 0x3023, 1);\r
324     ov_write_reg16(pTwid, 0x3022, 6);\r
325     value =1;\r
326     while(1){\r
327         ov_read_reg16(pTwid, 0x3023, &value);\r
328         if (value == 0) break;\r
329     }\r
330     return 0;\r
331 }\r
332 \r
333 uint32_t ov_5640_AFrelease(Twid *pTwid)\r
334 {\r
335     uint8_t value;\r
336     ov_write_reg16(pTwid, 0x3023, 1);\r
337     ov_write_reg16(pTwid, 0x3022, 8);\r
338     value =1;\r
339     while(1){\r
340         ov_read_reg16(pTwid, 0x3023, &value);\r
341         if (value == 0) break;\r
342     }\r
343     return 0;\r
344 }\r
345 \r
346 /**\r
347  * \brief  Dump all register\r
348  * \param pTwid TWI interface\r
349  */\r
350 void ov_DumpRegisters8(Twid *pTwid)\r
351 {\r
352     uint32_t i;\r
353     uint8_t value;\r
354 \r
355     TRACE_INFO_WP("Dump all camera register\n\r");\r
356     for(i = 0; i <= 0x5C; i++) {\r
357         value = 0;\r
358         ov_read_reg8(pTwid, i,  &value);\r
359         TRACE_INFO_WP("[0x%02x]=0x%02x ", i, value);\r
360         if( ((i+1)%5) == 0 ) {\r
361             TRACE_INFO_WP("\n\r");\r
362         }        \r
363     }\r
364     TRACE_INFO_WP("\n\r");\r
365 }\r
366 \r
367 /**\r
368  * \brief  Dump all register\r
369  * \param pTwid TWI interface\r
370  */\r
371 void ov_DumpRegisters16(Twid *pTwid)\r
372 {\r
373     uint32_t i;\r
374     uint8_t value;\r
375 \r
376     TRACE_INFO_WP("Dump all camera register\n\r");\r
377     for(i = 3000; i <= 0x305C; i++) {\r
378         value = 0;\r
379         ov_read_reg16(pTwid, i, &value);\r
380         TRACE_INFO_WP("[0x%02x]=0x%02x ", i, value);\r
381         if( ((i+1)%5) == 0 ) {\r
382             TRACE_INFO_WP("\n\r");\r
383         }        \r
384     }\r
385     TRACE_INFO_WP("\n\r");\r
386 }\r
387 \r
388 /**\r
389  * \brief Sequence For correct operation of the sensor\r
390  * \param pTwid TWI interface\r
391  * \return OV type\r
392  */\r
393 uint8_t ov_init(Twid *pTwid)\r
394 {\r
395     uint16_t id = 0;\r
396     uint8_t ovType;\r
397     ov_reset();\r
398     id = ov_id(pTwid);\r
399     switch (id) {\r
400         case 0x7740: case 0x7742:\r
401             ovType =  OV_7740;\r
402             break;\r
403         case 0x9740: case 0x9742:\r
404             ovType =  OV_9740;\r
405             break;\r
406         case 0x2642: case 0x2640:\r
407             ovType =  OV_2640;\r
408             break;\r
409         case 0x2643: \r
410             ovType =  OV_2643;\r
411             break;\r
412         case 0x5640:\r
413             ovType =  OV_5640;\r
414             break;\r
415         default:\r
416             ovType = OV_UNKNOWN;\r
417             TRACE_ERROR("Can not support product ID %x \n\r", id);\r
418             break;\r
419     }\r
420     return ovType;\r
421 }\r