//------------------------------------------------------------------------------
//
// Copyright (C) 2006,2007, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//------------------------------------------------------------------------------
//
//  File:  CameraOV2640.cpp    
//
//  Definitions for OminVisionChip camera module specific
//
//------------------------------------------------------------------------------

#pragma warning(push)
#pragma warning(disable: 4201)
#include <windows.h>
#pragma warning(pop)

#include "cameradbg.h"
#include "bsp.h"
#include "ipu.h"
#include "i2cbus.h"
#include "CsiClass.h"
#include "bspcsi.h"
#include "CameraOV2640.h"

//------------------------------------------------------------------------------
// External Functions

//------------------------------------------------------------------------------
// External Variables
extern csiSensorId gSensorInUse;
extern HANDLE hI2C;

//------------------------------------------------------------------------------
// Defines
#define OV2640_I2C_ADDRESS        0x30
#define OV2640_I2C_SPEED          40000
#define Definition_low 1

#define CAMERA_FUNCTION_ENTRY() \
    DEBUGMSG(ZONE_FUNCTION, (TEXT("++%s\r\n"), __WFUNCTION__))
#define CAMERA_FUNCTION_EXIT() \
    DEBUGMSG(ZONE_FUNCTION, (TEXT("--%s\r\n"), __WFUNCTION__))
    
//------------------------------------------------------------------------------
// Types


//------------------------------------------------------------------------------
// Global Variables


//------------------------------------------------------------------------------
// Local Variables

//------------------------------------------------------------------------------
// Local Functions


//------------------------------------------------------------------------------
//
// Function: CameraOV2640Init
//
// Initializes the OV2640 camera sensor.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void CameraOV2640Init()
{
    INT iResult;
    DWORD dwFrequency;
    BYTE bySlaveAddr, byCsiAddr;
    
    CAMERA_FUNCTION_ENTRY();

    byCsiAddr = CSI_I2C_ADDRESS;

    switch (gSensorInUse)
    {
     case csiSensorId_OV2640:
           dwFrequency = OV2640_I2C_SPEED;
           bySlaveAddr = OV2640_I2C_ADDRESS;
           break;               

     default:
           DEBUGMSG(ZONE_ERROR, (TEXT("%s: We don't support this kind of sensor!\r\n"), __WFUNCTION__));
           return;
    }        

    hI2C = CreateFile(I2C_FID_CAM,                              // name of device
               GENERIC_READ|GENERIC_WRITE,              // desired access
               FILE_SHARE_READ|FILE_SHARE_WRITE,     // sharing mode
               NULL,                                                             // security attributes (ignored)
               OPEN_EXISTING,                                        // creation disposition
               FILE_FLAG_RANDOM_ACCESS,                  // flags/attributes
               NULL);

    if (hI2C == INVALID_HANDLE_VALUE)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: CreateFile for I2C failed!\r\n"), __WFUNCTION__));
    }

    // Initialize the device internal fields
    if (!I2C_MACRO_SET_FREQUENCY(hI2C, dwFrequency))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: Set I2C frequency failed!\r\n"), __WFUNCTION__));
    }
    if (!I2C_MACRO_SET_SELF_ADDR(hI2C, byCsiAddr))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("%s: Set I2C self address failed!\r\n"), __WFUNCTION__));
    }
#ifdef Definition_low
{
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x01, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x12, 0x80, &iResult);  
    
    Sleep(10);
     
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x2c, 0xff, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x2e, 0xdf, &iResult);  


    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x01, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3c, 0x32, &iResult);  


    I2CWriteOneByte(hI2C, bySlaveAddr, 0x11, 0x01, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x09, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x04, 0x28, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x13, 0xe5, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x14, 0x48, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x2c, 0x0c, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x33, 0x78, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3a, 0x33, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3b, 0xfb, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3e, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x43, 0x11, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x16, 0x10, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x39, 0x92, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x35, 0xda, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x22, 0x1a, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x37, 0xc3, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x23, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x34, 0xc0, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x36, 0x1a, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x06, 0x88, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x07, 0xc0, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x0d, 0x87, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x0e, 0x41, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4c, 0x00, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4a, 0x81, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x21, 0x99, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x24, 0x40, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x25, 0x38, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x26, 0x82, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5c, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x63, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x46, 0x22, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x0c, 0x3c, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5d, 0x55, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5e, 0x7d, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5f, 0x7d, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x60, 0x55, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x61, 0x70, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x62, 0x80, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x05, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x20, 0x80, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x28, 0x30, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6c, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6d, 0x80, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6e, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x70, 0x02, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x71, 0x94, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x73, 0xc1, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x12, 0x40, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x17, 0x11, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x18, 0x43, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x19, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x1a, 0x4b, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x32, 0x09, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x37, 0xc0, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4f, 0xca, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x50, 0xa8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6d, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3d, 0x38, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe5, 0x7f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xf9, 0xc0, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x41, 0x24, &iResult); 
//    I2CWriteOneByte(hI2C, bySlaveAddr, 0x44, 0x06, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe0, 0x14, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x76, 0xff, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x33, 0xa0, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x42, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x43, 0x18, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4c, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x87, 0xd0, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x88, 0x3f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xd7, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xd9, 0x10, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xd3, 0x82, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc8, 0x08, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc9, 0x80, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x48, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x48, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x08, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x10, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x0e, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x90, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x0e, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x1a, &iResult);                           
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x5a, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x69, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x75, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x7e, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x88, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x8f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x96, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xa3, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xaf, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xc4, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xd7, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xe8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x20, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x92, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x06, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0xe3, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x02, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x96, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x08, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x19, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x02, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x0c, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x24, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x30, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x28, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x26, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x02, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x98, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x80, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x00, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa4, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa8, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc5, 0x11, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc6, 0x51, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xbf, 0x80, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc7, 0x10, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb6, 0x66, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb8, 0xA5, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb7, 0x64, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb9, 0x7C, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb3, 0xaf, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb4, 0x97, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb5, 0xFF, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb0, 0xC5, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb1, 0x94, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb2, 0x0f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc4, 0x5c, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa6, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0xd8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x1b, &iResult);                           
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x18, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0xd8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x19, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x18, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0xd8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x19, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x18, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc0, 0x64, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc1, 0x4b, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x86, 0x1d, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x50, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x51, 0xc8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x52, 0x96, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x53, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x54, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x55, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x57, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5a, 0xc8, &iResult);
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5b, 0x96, &iResult);
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5c, 0x00, &iResult);
                                                 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc3, 0xef, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7f, 0x00, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xda, 0x01, &iResult);

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe5, 0x1f, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe1, 0x67, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe0, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xdd, 0x7f, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x05, 0x00, &iResult);  
}

#else
{
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x01, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x12, 0x80, &iResult);  
    
    Sleep(10);
     
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x2c, 0xff, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x2e, 0xdf, &iResult);  


    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x01, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3c, 0x32, &iResult);  


    I2CWriteOneByte(hI2C, bySlaveAddr, 0x11, 0x01, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x09, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x04, 0x28, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x13, 0xe5, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x14, 0x48, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x2c, 0x0c, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x33, 0x78, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3a, 0x33, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3b, 0xfb, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3e, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x43, 0x11, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x16, 0x10, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x39, 0x92, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x35, 0xda, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x22, 0x1a, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x37, 0xc3, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x23, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x34, 0xc0, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x36, 0x1a, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x06, 0x88, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x07, 0xc0, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x0d, 0x87, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x0e, 0x41, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4c, 0x00, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4a, 0x81, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x21, 0x99, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x24, 0x40, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x25, 0x38, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x26, 0x82, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5c, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x63, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x46, 0x22, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x0c, 0x3c, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5d, 0x55, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5e, 0x7d, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5f, 0x7d, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x60, 0x55, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x61, 0x70, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x62, 0x80, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x05, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x20, 0x80, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x28, 0x30, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6c, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6d, 0x80, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6e, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x70, 0x02, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x71, 0x94, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x73, 0xc1, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x12, 0x40, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x17, 0x11, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x18, 0x43, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x19, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x1a, 0x4b, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x32, 0x09, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x37, 0xc0, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4f, 0xca, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x50, 0xa8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x6d, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x3d, 0x38, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe5, 0x7f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xf9, 0xc0, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x41, 0x24, &iResult); 
//    I2CWriteOneByte(hI2C, bySlaveAddr, 0x44, 0x06, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe0, 0x14, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x76, 0xff, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x33, 0xa0, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x42, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x43, 0x18, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x4c, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x87, 0xd0, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x88, 0x3f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xd7, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xd9, 0x10, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xd3, 0x82, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc8, 0x08, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc9, 0x80, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x48, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x48, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7c, 0x08, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x10, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7d, 0x0e, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x90, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x0e, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x1a, &iResult);                           
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x5a, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x69, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x75, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x7e, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x88, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x8f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x96, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xa3, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xaf, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xc4, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xd7, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0xe8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x91, 0x20, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x92, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x06, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0xe3, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x03, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x02, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x93, 0x00, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0x96, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x08, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x19, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x02, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x0c, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x24, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x30, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x28, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x26, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x02, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x98, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x80, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x97, 0x00, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa4, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa8, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc5, 0x11, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc6, 0x51, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xbf, 0x80, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc7, 0x10, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb6, 0x66, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb8, 0xA5, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb7, 0x64, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb9, 0x7C, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb3, 0xaf, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb4, 0x97, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb5, 0xFF, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb0, 0xC5, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb1, 0x94, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xb2, 0x0f, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc4, 0x5c, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa6, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0xd8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x1b, &iResult);                           
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x18, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0xd8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x19, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x18, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x20, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0xd8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x19, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x31, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xa7, 0x18, &iResult); 

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc0, 0x64, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc1, 0x4b, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x86, 0x1d, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x50, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x51, 0xc8, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x52, 0x96, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x53, 0x00, &iResult); 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x54, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x55, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x57, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5a, 0xc8, &iResult);
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5b, 0x96, &iResult);
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x5c, 0x00, &iResult);
                                                 
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xc3, 0xef, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x7f, 0x00, &iResult);  

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xda, 0x01, &iResult);

    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe5, 0x1f, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe1, 0x67, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xe0, 0x00, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0xdd, 0x7f, &iResult);  
    I2CWriteOneByte(hI2C, bySlaveAddr, 0x05, 0x00, &iResult);  
}
#endif
}


//------------------------------------------------------------------------------
//
// Function: CameraOV2640Deinit
//
// Deinitializes the OV2640 camera sensor.
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void CameraOV2640Deinit(void)
{
    CAMERA_FUNCTION_ENTRY();

    CloseHandle(hI2C);

    CAMERA_FUNCTION_EXIT();
}

//------------------------------------------------------------------------------
//
// Function: CameraOV2640SetOutputFormat
//
// Set interface to configure camera output format.
//
// Parameters:
//      outputFormat
//          [in] structure indicating the sensor output format:
//              csiSensorOutputFormat_CCIR656 - CCIR656
//              csiSensorOutputFormat_RGB565 - RGB565
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void CameraOV2640SetOutputFormat(cameraOutputFormat outputFormat)
{
    INT iResult;
    BYTE bySlaveAddr;

    CAMERA_FUNCTION_ENTRY();

    switch (gSensorInUse)
    {
     case csiSensorId_OV2640:
           bySlaveAddr = OV2640_I2C_ADDRESS;
           break;               

     default:
           DEBUGMSG(ZONE_ERROR, (TEXT("%s: We don't support this kind of sensor!\r\n"), __WFUNCTION__));
           return;
    }        
    
    switch (outputFormat)
    {
     case cameraOutputFormat_CCIR656:
          I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x00, &iResult); 
          I2CWriteOneByte(hI2C, bySlaveAddr, 0xda, 0x01, &iResult);           
          break;

     case cameraOutputFormat_RGB565:        
          I2CWriteOneByte(hI2C, bySlaveAddr, 0xff, 0x00, &iResult); 
          I2CWriteOneByte(hI2C, bySlaveAddr, 0xda, 0x08, &iResult);
          break;

     default:
          DEBUGMSG(ZONE_ERROR, (TEXT("%s: We don't support this kind of format!\r\n"), __WFUNCTION__));
	 	
    }

    CAMERA_FUNCTION_EXIT();
}


//------------------------------------------------------------------------------
//
// Function: CameraOV2640SetOutputResolution
//
// Set interface to configure camera output resolution.
//
// Parameters:
//      outputResolution
//          [in]  Structure indicating the camera output resolution:
//              csiSensorOutputResolution outputResolution :
//              csiSensorOutputResolution_VGA - VGA 640x480
//              csiSensorOutputResolution_XGA - XGA 1280x960
//              csiSensorOutputResolution_SXGA - SXGA 1280x1024		
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void CameraOV2640SetOutputResolution(csiSensorOutputResolution outputResolution)
{
    //    INT iResult;
    BYTE bySlaveAddr;

    CAMERA_FUNCTION_ENTRY();

    switch (gSensorInUse)
    {
     case csiSensorId_OV2640:
           bySlaveAddr = OV2640_I2C_ADDRESS;
           break;               

     default:
           DEBUGMSG(ZONE_ERROR, (TEXT("%s: We don't support this kind of sensor!\r\n"), __WFUNCTION__));
           return;
    }        

    switch (outputResolution)
    {
        case csiSensorOutputResolution_SXGA:
             break;

        case csiSensorOutputResolution_XGA:
             break;

        case csiSensorOutputResolution_VGA:
             break;

        default:  
             DEBUGMSG(ZONE_ERROR, (TEXT("%s: We don't support this kind of resolution for the sensor!\r\n"), __WFUNCTION__));
             return;
    }

    CAMERA_FUNCTION_EXIT();
}


//----------------------------------------------------------------------------
//
// Function: CameraOV2640SetDigitalZoom
//
// Sets the camera digital zoom level .
//
// Parameters:
//      zoom
//          [in] Camera zoom value that will be set
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void CameraOV2640SetDigitalZoom(DWORD ZoomLevel)
{    
    CAMERA_FUNCTION_ENTRY();

    // Remove-W4: Warning C4100 workaround
    UNREFERENCED_PARAMETER(ZoomLevel);

    //Currently, We set OV2640 Output as XGA 1280*960; for this resolution, OV2640 don't support digital zoom.
    //OV2640 digital zoom only support the ouput resolution less than SVGA.
    CAMERA_FUNCTION_EXIT();
}
