1 /* ----------------------------------------------------------------------------
\r
2 * SAM Software Package License
\r
3 * ----------------------------------------------------------------------------
\r
4 * Copyright (c) 2013, Atmel Corporation
\r
6 * All rights reserved.
\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
11 * - Redistributions of source code must retain the above copyright notice,
\r
12 * this list of conditions and the disclaimer below.
\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
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
30 /*----------------------------------------------------------------------------
\r
32 *----------------------------------------------------------------------------*/
\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
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
47 static const Pin pin_ISI_RST= PIN_ISI_RST;
\r
48 static uint8_t twiSlaveAddr = OV_CAPTOR_ADDRESS_1;
\r
49 /*----------------------------------------------------------------------------
\r
51 *----------------------------------------------------------------------------*/
\r
52 static void ov_reset(void)
\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
64 * \brief Read PID and VER
\r
65 * \param pTwid TWI interface
\r
66 * \return VER | (PID<<8)
\r
68 static uint16_t ov_id8(Twid *pTwid)
\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
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
82 return((uint16_t)(id <<8) | ver);
\r
86 * \brief Read PID and VER
\r
87 * \param pTwid TWI interface
\r
88 * \return VER | (PID<<8)
\r
90 static uint16_t ov_id16(Twid *pTwid)
\r
94 ov_read_reg16(pTwid, 0x300A, &id);
\r
95 TRACE_INFO("PID = 0x%X\n\r", id);
\r
98 ov_read_reg16(pTwid, 0x300B, &ver);
\r
99 TRACE_INFO("VER = 0x%X\n\r", ver);
\r
101 return((uint16_t)(id <<8) | ver);
\r
105 * \brief Read PID and VER
\r
106 * \param pTwid TWI interface
\r
107 * \return VER | (PID<<8)
\r
109 static uint16_t ov_id(Twid *pTwid)
\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
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
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
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
134 /*----------------------------------------------------------------------------
\r
136 *----------------------------------------------------------------------------*/
\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
145 uint8_t ov_read_reg8(Twid *pTwid, uint8_t reg, uint8_t *pData)
\r
149 status = TWID_Write( pTwid, twiSlaveAddr, 0, 0, ®, 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
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
164 uint8_t ov_read_reg16(Twid *pTwid, uint16_t reg, uint8_t *pData)
\r
169 reg8[1] = reg & 0xff;
\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
175 TRACE_ERROR("ov_read_reg pb\n\r");
\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
187 uint8_t ov_write_reg8(Twid *pTwid, uint8_t reg, uint8_t val)
\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
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
206 uint8_t ov_write_reg16(Twid *pTwid, uint16_t reg, uint8_t val)
\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
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
225 uint32_t ov_write_regs8(Twid *pTwid, const struct ov_reg* pReglist)
\r
229 const struct ov_reg *pNext = pReglist;
\r
230 volatile uint32_t delay;
\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
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
242 //printf("(0x%02x,0x%02x) \n\r", pNext->reg,pNext->val);
\r
245 TRACE_DEBUG_WP("\n\r");
\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
257 uint32_t ov_write_regs16(Twid *pTwid, const struct ov_reg* pReglist)
\r
261 const struct ov_reg *pNext = pReglist;
\r
262 volatile uint32_t delay;
\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
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
273 //printf("(0x%02x,0x%02x) \n\r", pNext->reg,pNext->val);
\r
276 TRACE_DEBUG_WP("\n\r");
\r
280 void isOV5640_AF_InitDone(Twid *pTwid)
\r
284 ov_read_reg16(pTwid, 0x3029, &value);
\r
285 if (value == 0x70) break;
\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
294 uint32_t ov_5640_AF_single(Twid *pTwid)
\r
297 ov_write_reg16(pTwid, 0x3023, 1);
\r
298 ov_write_reg16(pTwid, 0x3022, 3);
\r
301 ov_read_reg16(pTwid, 0x3023, &value);
\r
302 if (value == 0) break;
\r
307 uint32_t ov_5640_AF_continue(Twid *pTwid)
\r
310 ov_write_reg16(pTwid, 0x3024, 1);
\r
311 ov_write_reg16(pTwid, 0x3022, 4);
\r
314 ov_read_reg16(pTwid, 0x3023, &value);
\r
315 if (value == 0) break;
\r
320 uint32_t ov_5640_AFPause(Twid *pTwid)
\r
323 ov_write_reg16(pTwid, 0x3023, 1);
\r
324 ov_write_reg16(pTwid, 0x3022, 6);
\r
327 ov_read_reg16(pTwid, 0x3023, &value);
\r
328 if (value == 0) break;
\r
333 uint32_t ov_5640_AFrelease(Twid *pTwid)
\r
336 ov_write_reg16(pTwid, 0x3023, 1);
\r
337 ov_write_reg16(pTwid, 0x3022, 8);
\r
340 ov_read_reg16(pTwid, 0x3023, &value);
\r
341 if (value == 0) break;
\r
347 * \brief Dump all register
\r
348 * \param pTwid TWI interface
\r
350 void ov_DumpRegisters8(Twid *pTwid)
\r
355 TRACE_INFO_WP("Dump all camera register\n\r");
\r
356 for(i = 0; i <= 0x5C; i++) {
\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
364 TRACE_INFO_WP("\n\r");
\r
368 * \brief Dump all register
\r
369 * \param pTwid TWI interface
\r
371 void ov_DumpRegisters16(Twid *pTwid)
\r
376 TRACE_INFO_WP("Dump all camera register\n\r");
\r
377 for(i = 3000; i <= 0x305C; i++) {
\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
385 TRACE_INFO_WP("\n\r");
\r
389 * \brief Sequence For correct operation of the sensor
\r
390 * \param pTwid TWI interface
\r
393 uint8_t ov_init(Twid *pTwid)
\r
400 case 0x7740: case 0x7742:
\r
403 case 0x9740: case 0x9742:
\r
406 case 0x2642: case 0x2640:
\r
416 ovType = OV_UNKNOWN;
\r
417 TRACE_ERROR("Can not support product ID %x \n\r", id);
\r