SAMV71 Xplained Ultra Software Package 1.3

omnivision.c

00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2013, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029  
00030 /*----------------------------------------------------------------------------
00031  *        Headers
00032  *----------------------------------------------------------------------------*/
00033 #include "board.h"
00034 
00035 /** Slave address of OMNIVISION chips. */
00036 #define OV_CAPTOR_ADDRESS_1   0x30 
00037 #define OV_CAPTOR_ADDRESS_2   0x21
00038 #define OV_CAPTOR_ADDRESS_3   0x3c 
00039 #define OV_CAPTOR_ADDRESS_4   0x10
00040 
00041 /** terminating list entry for register in configuration file */
00042 #define OV_REG_TERM 0xFF
00043 #define OV_REG_DELAY 0xFFFF
00044 /** terminating list entry for value in configuration file */
00045 #define OV_VAL_TERM 0xFF 
00046 
00047 static const Pin pin_ISI_RST= BOARD_ISI_RST;
00048 static uint8_t twiSlaveAddr = OV_CAPTOR_ADDRESS_1;
00049 /*----------------------------------------------------------------------------
00050  *        Local Functions
00051  *----------------------------------------------------------------------------*/
00052 static void ov_reset(void)
00053 {
00054     volatile uint32_t i;
00055     PIO_Configure(&pin_ISI_RST, 1);
00056     PIO_Clear(&pin_ISI_RST);
00057     for(i = 0; i < 6000; i++ );
00058     PIO_Set(&pin_ISI_RST);
00059     for(i = 0; i<6000; i++ );
00060 }
00061 
00062 
00063 /**
00064  * \brief  Read PID and VER
00065  * \param pTwid TWI interface
00066  * \return  VER | (PID<<8)
00067  */
00068 static uint16_t ov_id8(Twid *pTwid)
00069 {
00070     uint8_t id, ver;
00071     uint8_t status;
00072     // OV_PID
00073     status = ov_read_reg8(pTwid, 0x0A, &id);
00074     if( status != 0 )
00075         return 0;
00076     TRACE_INFO("PID  = 0x%X\n\r", id);
00077 
00078     // OV_VER
00079     status = ov_read_reg8(pTwid, 0x0B, &ver);
00080     if( status != 0 )
00081         return 0;
00082     TRACE_INFO("VER  = 0x%X\n\r", ver);
00083 
00084     return((uint16_t)(id <<8) | ver);
00085 }
00086 
00087 /**
00088  * \brief  Read PID and VER
00089  * \param pTwid TWI interface
00090  * \return  VER | (PID<<8)
00091  */
00092 static uint16_t ov_id16(Twid *pTwid)
00093 {
00094     uint8_t id, ver;
00095     // OV_PID
00096     ov_read_reg16(pTwid, 0x300A, &id);
00097     TRACE_INFO("PID  = 0x%X\n\r", id);
00098 
00099     // OV_VER
00100     ov_read_reg16(pTwid, 0x300B, &ver);
00101     TRACE_INFO("VER  = 0x%X\n\r", ver);
00102 
00103     return((uint16_t)(id <<8) | ver);
00104 }
00105 
00106 /**
00107  * \brief  Read PID and VER
00108  * \param pTwid TWI interface
00109  * \return  VER | (PID<<8)
00110  */
00111 static uint16_t ov_id(Twid *pTwid)
00112 {
00113     uint16_t id;
00114     TRACE_INFO(" Try TWI address 0x%x \n\r", twiSlaveAddr);
00115     twiSlaveAddr = OV_CAPTOR_ADDRESS_1;
00116     id = ov_id8(pTwid);
00117     if (id == 0) {
00118         twiSlaveAddr = OV_CAPTOR_ADDRESS_2;
00119         TRACE_INFO("Try TWI address 0x%x \n\r", twiSlaveAddr);
00120         id = ov_id8(pTwid);
00121         if (id == 0) {
00122             twiSlaveAddr = OV_CAPTOR_ADDRESS_3;
00123             TRACE_INFO("Try TWI address 0x%x \n\r", twiSlaveAddr);
00124             id = ov_id16(pTwid);
00125             if (id == 0) {
00126                 twiSlaveAddr = OV_CAPTOR_ADDRESS_4;
00127                 TRACE_INFO("Try TWI address 0x%x \n\r", twiSlaveAddr);
00128                 id = ov_id16(pTwid);
00129             }
00130         }
00131     }
00132     return id;
00133 }
00134 
00135 
00136 /*----------------------------------------------------------------------------
00137  *        Global Functions
00138  *----------------------------------------------------------------------------*/
00139 /**
00140  * \brief  Read a value from a register in an OV sensor device.
00141  * \param pTwid TWI interface
00142  * \param reg Register to be read
00143  * \param pData Data read
00144  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00145  */
00146 uint8_t ov_read_reg8(Twid *pTwid, uint8_t reg, uint8_t *pData)
00147 {
00148     uint8_t status;
00149 
00150     status = TWID_Write( pTwid, twiSlaveAddr, 0, 0, &reg, 1, 0);
00151     status |= TWID_Read( pTwid, twiSlaveAddr, 0, 0, pData, 1, 0);
00152     if( status != 0 ) {
00153         TRACE_ERROR("ov_read_reg pb\n\r");
00154     }
00155     return status;
00156 }
00157 
00158 /**
00159  * \brief  Read a value from a register in an OV sensor device.
00160  * \param pTwid TWI interface
00161  * \param reg Register to be read
00162  * \param pData Data read
00163  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00164  */
00165 uint8_t ov_read_reg16(Twid *pTwid, uint16_t reg, uint8_t *pData)
00166 {
00167     uint8_t status;
00168     uint8_t reg8[2];
00169     reg8[0] = reg>>8;
00170     reg8[1] = reg & 0xff;
00171 
00172     status = TWID_Write( pTwid, twiSlaveAddr, 0, 0, reg8,  2, 0);
00173     status |= TWID_Read( pTwid, twiSlaveAddr, 0, 0, pData, 1, 0);
00174     if( status != 0 ) {
00175         TRACE_ERROR("ov_read_reg pb\n\r");
00176     }
00177     return status;
00178 }
00179 
00180 /**
00181  * \brief  Write a value to a register in an OV sensor device.
00182  * \param pTwid TWI interface
00183  * \param reg Register to be written
00184  * \param pData Data written
00185  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00186  */
00187 uint8_t ov_write_reg8(Twid *pTwid, uint8_t reg, uint8_t val)
00188 {
00189     uint8_t status;
00190 
00191     status = TWID_Write(pTwid, twiSlaveAddr, reg, 1, &val, 1, 0);
00192     if( status != 0 ) {
00193         TRACE_ERROR("ov_write_reg pb\n\r");
00194     }
00195     return status;
00196 }
00197 
00198 /**
00199  * \brief  Write a value to a register in an OV sensor device.
00200  * \param pTwid TWI interface
00201  * \param reg Register to be written
00202  * \param pData Data written
00203  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00204  */
00205 uint8_t ov_write_reg16(Twid *pTwid, uint16_t reg,  uint8_t val)
00206 {
00207     uint8_t status;
00208     status = TWID_Write(pTwid, twiSlaveAddr, reg, 2, &val, 1, 0);
00209     if( status != 0 ) {
00210         TRACE_ERROR("ov_write_reg pb\n\r");
00211     }
00212 
00213     return status;
00214 }
00215 
00216 
00217 /**
00218  * \brief  Initialize a list of OV registers.
00219  * The list of registers is terminated by the pair of values
00220  * \param pTwid TWI interface
00221  * \param pReglist Register list to be written
00222  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00223  */
00224 uint32_t ov_write_regs8(Twid *pTwid, const struct ov_reg* pReglist)
00225 {
00226     uint32_t err;
00227     uint32_t size=0;
00228     const struct ov_reg *pNext = pReglist;
00229     volatile uint32_t delay;
00230 
00231     TRACE_DEBUG("ov_write_regs:");
00232     while (!((pNext->reg == OV_REG_TERM) && (pNext->val == OV_VAL_TERM))) {
00233         err = ov_write_reg8(pTwid, pNext->reg, pNext->val);
00234         
00235         size++;
00236         for(delay=0;delay<=10000;delay++); 
00237         if (err == TWID_ERROR_BUSY){
00238             TRACE_ERROR("ov_write_regs: TWI ERROR\n\r");
00239             return err;
00240         }
00241         pNext++;
00242     }
00243     TRACE_DEBUG_WP("\n\r");
00244     return 0;
00245 }
00246 
00247 
00248 /**
00249  * \brief  Initialize a list of OV registers.
00250  * The list of registers is terminated by the pair of values
00251  * \param pTwid TWI interface
00252  * \param pReglist Register list to be written
00253  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00254  */
00255 uint32_t ov_write_regs16(Twid *pTwid, const struct ov_reg* pReglist)
00256 {
00257     uint32_t err = 0;
00258     uint32_t size = 0;
00259     const struct ov_reg *pNext = pReglist;
00260     volatile uint32_t delay;
00261 
00262     TRACE_DEBUG("ov_write_regs:");
00263     while (!((pNext->reg == OV_REG_TERM) && (pNext->val == OV_VAL_TERM))) {
00264         err = ov_write_reg16(pTwid, pNext->reg, pNext->val);
00265         size++;
00266         for(delay = 0;delay <= 10000; delay++); 
00267         if (err == TWID_ERROR_BUSY){
00268             TRACE_ERROR("ov_write_regs: TWI ERROR\n\r");
00269             return err;
00270         }
00271         pNext++;
00272     }
00273     TRACE_DEBUG_WP("\n\r");
00274     return 0;
00275 }
00276 
00277 void isOV5640_AF_InitDone(Twid *pTwid)
00278 {
00279     uint8_t value = 0;
00280     while(1){
00281         ov_read_reg16(pTwid, 0x3029, &value);
00282         if (value == 0x70)
00283             break;
00284     }
00285 }
00286 
00287 /**
00288  * \brief  AF for OV 5640
00289  * \param pTwid TWI interface
00290  * \return 0 if no error; otherwise TWID_ERROR_BUSY
00291  */
00292 uint32_t ov_5640_AF_single(Twid *pTwid)
00293 {
00294     uint8_t value;
00295     ov_write_reg16(pTwid, 0x3023, 1);
00296     ov_write_reg16(pTwid, 0x3022, 3);
00297     value =1;
00298     while(1){
00299         ov_read_reg16(pTwid, 0x3023, &value);
00300         if (value == 0) 
00301             break;
00302     }
00303     return 0;
00304 }
00305 
00306 uint32_t ov_5640_AF_continue(Twid *pTwid)
00307 {
00308     uint8_t value;
00309     ov_write_reg16(pTwid, 0x3024, 1);
00310     ov_write_reg16(pTwid, 0x3022, 4);
00311     value =1;
00312     while(1){
00313         ov_read_reg16(pTwid, 0x3023, &value);
00314         if (value == 0) 
00315             break;
00316     }
00317     return 0;
00318 }
00319 
00320 uint32_t ov_5640_AFPause(Twid *pTwid)
00321 {
00322     uint8_t value;
00323     ov_write_reg16(pTwid, 0x3023, 1);
00324     ov_write_reg16(pTwid, 0x3022, 6);
00325     value =1;
00326     while(1){
00327         ov_read_reg16(pTwid, 0x3023, &value);
00328         if (value == 0)
00329             break;
00330     }
00331     return 0;
00332 }
00333 
00334 uint32_t ov_5640_AFrelease(Twid *pTwid)
00335 {
00336     uint8_t value;
00337     ov_write_reg16(pTwid, 0x3023, 1);
00338     ov_write_reg16(pTwid, 0x3022, 8);
00339     value =1;
00340     while(1){
00341         ov_read_reg16(pTwid, 0x3023, &value);
00342         if (value == 0)
00343             break;
00344     }
00345     return 0;
00346 }
00347 
00348 /**
00349  * \brief  Dump all register
00350  * \param pTwid TWI interface
00351  */
00352 void ov_DumpRegisters8(Twid *pTwid)
00353 {
00354     uint32_t i;
00355     uint8_t value;
00356 
00357     TRACE_INFO_WP("Dump all camera register\n\r");
00358     for(i = 0; i <= 0x5C; i++) {
00359         value = 0;
00360         ov_read_reg8(pTwid, i,  &value);
00361         TRACE_INFO_WP("[0x%02x]=0x%02x ", i, value);
00362         if( ((i+1)%5) == 0 ) {
00363             TRACE_INFO_WP("\n\r");
00364         }
00365     }
00366     TRACE_INFO_WP("\n\r");
00367 }
00368 
00369 /**
00370  * \brief  Dump all register
00371  * \param pTwid TWI interface
00372  */
00373 void ov_DumpRegisters16(Twid *pTwid)
00374 {
00375     uint32_t i;
00376     uint8_t value;
00377 
00378     TRACE_INFO_WP("Dump all camera register\n\r");
00379     for(i = 3000; i <= 0x305C; i++) {
00380         value = 0;
00381         ov_read_reg16(pTwid, i, &value);
00382         TRACE_INFO_WP("[0x%02x]=0x%02x ", i, value);
00383         if( ((i+1)%5) == 0 ) {
00384             TRACE_INFO_WP("\n\r");
00385         }
00386     }
00387     TRACE_INFO_WP("\n\r");
00388 }
00389 
00390 /**
00391  * \brief Sequence For correct operation of the sensor
00392  * \param pTwid TWI interface
00393  * \return OV type
00394  */
00395 uint8_t ov_init(Twid *pTwid)
00396 {
00397     uint16_t id = 0;
00398     uint8_t ovType;
00399     ov_reset();
00400     id = ov_id(pTwid);
00401     switch (id) {
00402     case 0x7740: case 0x7742:
00403         ovType =  OV_7740;
00404         TRACE_INFO(" Camera Model :- OV_7740");
00405         break;
00406     case 0x9740: case 0x9742:
00407         ovType =  OV_9740;
00408         TRACE_INFO(" Camera Model :- OV_9740");
00409         break;
00410     case 0x2642: case 0x2640:
00411         ovType =  OV_2640;
00412         TRACE_INFO(" Camera Model :- OV_2640");
00413         break;
00414     case 0x2643: 
00415         ovType =  OV_2643;
00416         TRACE_INFO(" Camera Model :- OV_2643");
00417         break;
00418     case 0x5640:
00419         ovType =  OV_5640;
00420         TRACE_INFO(" Camera Model :- OV_5640");
00421         break;
00422     default:
00423         ovType = OV_UNKNOWN;
00424         TRACE_INFO(" Camera Model :- UNKNOWN");
00425         TRACE_ERROR("Can not support product ID %x \n\r", id);
00426         break;
00427     }
00428     return ovType;
00429 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines