Sunday, February 13, 2011

OV3640 CMOS camera module device driver in Windows CE

The following source code is Original source of OV3640 CMOS camera module.

//OV3640_MODULE.cpp


#include
#include
#include "pmplatform.h"
#include "iic.h"
#include "ov3640.h"

#include "Module.h"

#define MSG_ERROR 1

#define CAMERA_WRITE 0x78
#define CAMERA_READ 0x79

#define DEFAULT_MODULE_ITUXXX CAM_ITU601
#define DEFAULT_MODULE_YUVORDER CAM_ORDER_YCBYCR // 0x00:YCbYCr, 0x01:YCrYCb, 0x10:CbYCrY, 0x11:CrYCbY
#define DEFAULT_MODULE_HSIZE 640 // Horizontal size
#define DEFAULT_MODULE_VSIZE 480 // Vertical size
#define DEFAULT_MODULE_HOFFSET 0 // Horizontal size
#define DEFAULT_MODULE_VOFFSET 0 // Vertical size
#define DEFAULT_MODULE_UVOFFSET CAM_UVOFFSET_0 // Cb, Cr value offset. 1: +128 , 0: 0
#define DEFAULT_MODULE_CLOCK 24000000 // clock
#define DEFAULT_MODULE_CODEC CAM_CODEC_422 // 422: 1 , 420: 0
#define DEFAULT_MODULE_HIGHRST 0 // Reset is Low->High: 1 High->Low: 0
#define DEFAULT_MODULE_INVPCLK 0 // 1: inverse the polarity of PCLK 0 : normal
#define DEFAULT_MODULE_INVVSYNC 0 // 1: inverse the polarity of VSYNC 0 : normal
#define DEFAULT_MODULE_INVHREF 0 // 1: inverse the polarity of HREF 0 : normal

// Variables
static MODULE_DESCRIPTOR gModuleDesc;
static HANDLE hI2C; // I2C Bus Driver

// Functions
DWORD HW_WriteRegisters(PUCHAR pBuff, DWORD nRegs);
DWORD HW_ReadRegisters(PUCHAR pBuff, PUCHAR StartReg, DWORD nRegs);

int ModuleInit()
{
DWORD dwErr = ERROR_SUCCESS, bytes;
UINT32 IICClock = 100000;
UINT32 uiIICDelay;
RETAILMSG(1,(TEXT("+OV3640_ModuleInit\n")));
// Initialize I2C Driver
hI2C = CreateFile( L"IIC0:",
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0);

if ( INVALID_HANDLE_VALUE == hI2C )
{
dwErr = GetLastError();
RETAILMSG(MSG_ERROR, (TEXT("Error %d opening OV3640 device '%s' \r\n"), dwErr, L"I2C0:" ));
return FALSE;
}

gModuleDesc.ITUXXX = DEFAULT_MODULE_ITUXXX;
gModuleDesc.UVOffset = DEFAULT_MODULE_UVOFFSET;
gModuleDesc.SourceHSize = DEFAULT_MODULE_HSIZE;
gModuleDesc.Order422 = DEFAULT_MODULE_YUVORDER;
gModuleDesc.SourceVSize = DEFAULT_MODULE_VSIZE;
gModuleDesc.Clock = DEFAULT_MODULE_CLOCK;
gModuleDesc.Codec = DEFAULT_MODULE_CODEC;
gModuleDesc.HighRst = DEFAULT_MODULE_HIGHRST;
gModuleDesc.SourceHOffset = DEFAULT_MODULE_HOFFSET;
gModuleDesc.SourceVOffset = DEFAULT_MODULE_VOFFSET;
gModuleDesc.InvPCLK = DEFAULT_MODULE_INVPCLK;
gModuleDesc.InvVSYNC = DEFAULT_MODULE_INVVSYNC;
gModuleDesc.InvHREF = DEFAULT_MODULE_INVHREF;

// use iocontrol to write
if ( !DeviceIoControl(hI2C,
IOCTL_IIC_SET_CLOCK,
&IICClock, sizeof(UINT32),
NULL, 0,
&bytes, NULL) )
{
dwErr = GetLastError();
RETAILMSG(MSG_ERROR,(TEXT("OV3640_IOCTL_IIC_SET_CLOCK ERROR: %u \r\n"), dwErr));
return FALSE;
}

uiIICDelay = Clk_0;

if ( !DeviceIoControl(hI2C,
IOCTL_IIC_SET_DELAY,
&uiIICDelay, sizeof(UINT32),
NULL, 0,
&bytes, NULL) )
{
dwErr = GetLastError();
RETAILMSG(MSG_ERROR,(TEXT("OV3640_IOCTL_IIC_SET_DELAY ERROR: %u \r\n"), dwErr));
return FALSE;
}


RETAILMSG(1,(TEXT("-OV3640_ModuleInit\n")));
return TRUE;
}

void ModuleDeinit()
{
CloseHandle(hI2C);
}

int ModuleWriteBlock()
{
int i;
UCHAR BUF=0;
RETAILMSG(1,(L"+ModuleWriteBlock\n"));

for(i=0; i<(sizeof(OV3640_YCbCr8bit)/3); i++)
{
HW_WriteRegisters(&OV3640_YCbCr8bit[i][0], 3) ;
}
RETAILMSG(1,(L"-ModuleWriteBlock\n"));
return TRUE;
}

DWORD
HW_WriteRegisters(
PUCHAR pBuff, // Optional buffer
DWORD nRegs // number of registers
)
{
DWORD dwErr=0;
DWORD bytes;
IIC_IO_DESC IIC_Data;

IIC_Data.SlaveAddress = CAMERA_WRITE;
IIC_Data.Count = nRegs;
IIC_Data.Data = pBuff;
// use iocontrol to write
if ( !DeviceIoControl(hI2C,
IOCTL_IIC_WRITE,
&IIC_Data, sizeof(IIC_IO_DESC),
NULL, 0,
&bytes, NULL) )
{
dwErr = GetLastError();
RETAILMSG(MSG_ERROR,(TEXT("OV3640_IOCTL_IIC_WRITE ERROR: %u \r\n"), dwErr));
}

if ( dwErr )
{
DEBUGMSG(ZONE_ERR, (TEXT("I2CWrite ERROR: %u \r\n"), dwErr));
}

return dwErr;
}

DWORD
HW_ReadRegisters(
PUCHAR pBuff, // Optional buffer
PUCHAR StartReg, // Start Register
DWORD nRegs // Number of Registers
)
{
DWORD dwErr=0;
DWORD bytes;
IIC_IO_DESC IIC_AddressData, IIC_Data;
IIC_AddressData.SlaveAddress = CAMERA_WRITE;
IIC_AddressData.Data = StartReg;
IIC_AddressData.Count = 2;

IIC_Data.SlaveAddress = CAMERA_READ;
IIC_Data.Data = pBuff;
IIC_Data.Count = 1;

if ( !DeviceIoControl(hI2C,
IOCTL_IIC_READ,
&IIC_AddressData, sizeof(IIC_IO_DESC),
&IIC_Data, sizeof(IIC_IO_DESC),
&bytes, NULL) )
{
dwErr = GetLastError();
RETAILMSG(MSG_ERROR,(TEXT("OV3640_IOCTL_IIC_WRITE ERROR: %u \r\n"), dwErr));
}

if ( dwErr )
{
DEBUGMSG(ZONE_ERR,(TEXT("I2CRead ERROR: %u \r\n"), dwErr));
}

return dwErr;
}

void ModuleGetFormat(MODULE_DESCRIPTOR &outModuleDesc)
{
memcpy(&outModuleDesc, &gModuleDesc, sizeof(MODULE_DESCRIPTOR));
}

int ModuleSetImageSize(int imageSize)
{
//BYTE page[2];
//BYTE sizeValue[2];
//
//sizeValue[0] = 0x02;
//switch(imageSize)
//{
// case UXGA:
// sizeValue[1] = 0;
// break;
// case SXGA:
// sizeValue[1] = 1;
// break;
// case VGA:
// sizeValue[1] = 2;
// break;
// case QVGA:
// sizeValue[1] = 3;
// break;
// case QQVGA:
// sizeValue[1] = 4;
// break;
// case CIF:
// sizeValue[1] = 5;
// break;
// case QCIF:
// sizeValue[1] = 6;
// break;
// case SUB_SAMPLING2:
// sizeValue[1] = 9;
// break;
// case SUB_SAMPLING4:
// sizeValue[1] = 0xB;
// break;
//}
//
//page[0] = 0xFC;
//page[1] = 0;
//HW_WriteRegisters(page, 2);
//HW_WriteRegisters(sizeValue, 2);
return TRUE;
}

//=========================================================================

// START OV3640.H

#ifndef _OV3640_H_

#define _OV3640_H_

unsigned char OV3640_YCbCr8bit[][3] =
{
//========================================================================
{0x30,0x12, 0x80},
{0x30,0x4d, 0x45},
{0x30,0xa7, 0x5e},
{0x30,0x87, 0x16},
{0x30,0x9c, 0x1a},
{0x30,0xa2, 0xe4},
{0x30,0xaa, 0x42},
{0x30,0xa9, 0xb5},
{0x30,0xb0, 0xff},
{0x30,0xb1, 0xff},
{0x30,0xb2, 0x18}, //;kenxu modify from 0x10-->0x18 @20090326
{0x30,0x0e, 0x32},
{0x30,0x0f, 0x21},
{0x30,0x10, 0x20},
{0x30,0x11, 0x04},
{0x30,0x4c, 0x81},
{0x30,0xd7, 0x10},
{0x30,0xd9, 0x0d},
{0x30,0xdb, 0x08},
{0x30,0x16, 0x82},
{0x30,0x18, 0x38},
{0x30,0x19, 0x30},
{0x30,0x1a, 0x61},
{0x30,0x7d, 0x00},
{0x30,0x87, 0x02},
{0x30,0x82, 0x20},
{0x30,0x15, 0x12},
{0x30,0x14, 0x84},
{0x30,0x16, 0x92},
{0x30,0x13, 0xf7},
{0x30,0x3c, 0x08},
{0x30,0x3d, 0x18},
{0x30,0x3e, 0x06},
{0x30,0x3f, 0x0c},
{0x30,0x30, 0x62},
{0x30,0x31, 0x26},
{0x30,0x32, 0xe6},
{0x30,0x33, 0x6e},
{0x30,0x34, 0xea},
{0x30,0x35, 0xae},
{0x30,0x36, 0xa6},
{0x30,0x37, 0x6a},
{0x31,0x04, 0x02},
{0x31,0x05, 0xfd},
{0x31,0x06, 0x00},
{0x31,0x07, 0xff},
{0x33,0x01, 0xde},
{0x33,0x02, 0xef},
{0x33,0x12, 0x26},
{0x33,0x14, 0x42},
{0x33,0x13, 0x2b},
{0x33,0x15, 0x42},
{0x33,0x10, 0xd0},
{0x33,0x11, 0xbd},
{0x33,0x0c, 0x18},
{0x33,0x0d, 0x18},
{0x33,0x0e, 0x56},
{0x33,0x0f, 0x5c},
{0x33,0x0b, 0x1c},
{0x33,0x06, 0x5c},
{0x33,0x07, 0x11},
{0x33,0x6a, 0x52},
{0x33,0x70, 0x46},
{0x33,0x76, 0x38},
{0x33,0x00, 0x13},
{0x30,0xb8, 0x20},
{0x30,0xb9, 0x17},
{0x30,0xba, 0x02},
{0x30,0xbb, 0x08},
{0x35,0x07, 0x06},
{0x35,0x0a, 0x4f},
{0x31,0x00, 0x02},
{0x33,0x01, 0xde},
{0x33,0x04, 0x00},
{0x34,0x00, 0x00},
{0x34,0x04, 0x02},
{0x33,0x5f, 0x68},
{0x33,0x60, 0x18},
{0x33,0x61, 0x0c},
{0x33,0x62, 0x12},
{0x33,0x63, 0x88},
{0x33,0x64, 0xe4},
{0x34,0x03, 0x42},
{0x30,0x88, 0x02},
{0x30,0x89, 0x80},
{0x30,0x8a, 0x01},
{0x30,0x8b, 0xe0},
{0x30,0xd7, 0x10},
{0x33,0x02, 0xef},
{0x33,0x5f, 0x68},
{0x33,0x60, 0x18},
{0x33,0x61, 0x0c},
{0x33,0x62, 0x12},
{0x33,0x63, 0x88},
{0x33,0x64, 0xe4},
{0x34,0x03, 0x42},
{0x30,0x88, 0x12},
{0x30,0x89, 0x80},
{0x30,0x8a, 0x01},
{0x30,0x8b, 0xe0},
{0x30,0x4c, 0x84},
{0x33,0x2a, 0x18},
{0x33,0x1b, 0x04},
{0x33,0x1c, 0x13},
{0x33,0x1d, 0x2b},
{0x33,0x1e, 0x53},
{0x33,0x1f, 0x66},
{0x33,0x20, 0x73},
{0x33,0x21, 0x80},
{0x33,0x22, 0x8c},
{0x33,0x23, 0x95},
{0x33,0x24, 0x9d},
{0x33,0x25, 0xac},
{0x33,0x26, 0xb8},
{0x33,0x27, 0xcc},
{0x33,0x28, 0xdd},
{0x33,0x29, 0xee},
{0x33,0x00, 0x13},
{0x33,0x67, 0x23},
{0x33,0x68, 0xb5},
{0x33,0x69, 0xc8},
{0x33,0x6A, 0x46},
{0x33,0x6B, 0x07},
{0x33,0x6C, 0x00},
{0x33,0x6D, 0x23},
{0x33,0x6E, 0xbb},
{0x33,0x6F, 0xcc},
{0x33,0x70, 0x49},
{0x33,0x71, 0x07},
{0x33,0x72, 0x00},
{0x33,0x73, 0x23},
{0x33,0x74, 0xab},
{0x33,0x75, 0xcc},
{0x33,0x76, 0x46},
{0x33,0x77, 0x07},
{0x33,0x78, 0x00},
{0x33,0x2a, 0x1d},
{0x33,0x1b, 0x08},
{0x33,0x1c, 0x16},
{0x33,0x1d, 0x2d},
{0x33,0x1e, 0x54},
{0x33,0x1f, 0x66},
{0x33,0x20, 0x73},
{0x33,0x21, 0x80},
{0x33,0x22, 0x8c},
{0x33,0x23, 0x95},
{0x33,0x24, 0x9d},
{0x33,0x25, 0xac},
{0x33,0x26, 0xb8},
{0x33,0x27, 0xcc},
{0x33,0x28, 0xdd},
{0x33,0x29, 0xee},
{0x33,0x17, 0x04},
{0x33,0x16, 0xf8},
{0x33,0x12, 0x31},
{0x33,0x14, 0x57},
{0x33,0x13, 0x28},
{0x33,0x15, 0x3d},
{0x33,0x11, 0xd0},
{0x33,0x10, 0xb6},
{0x33,0x0c, 0x16},
{0x33,0x0d, 0x16},
{0x33,0x0e, 0x5F},
{0x33,0x0f, 0x5C},
{0x33,0x0b, 0x18},
{0x33,0x06, 0x5c},
{0x33,0x07, 0x11},
{0x33,0x08, 0x25},
{0x33,0x18, 0x62},
{0x33,0x19, 0x62},
{0x33,0x1a, 0x62},
{0x33,0x40, 0x20},
{0x33,0x41, 0x58},
{0x33,0x42, 0x08},
{0x33,0x43, 0x21},
{0x33,0x44, 0xbe},
{0x33,0x45, 0xe0},
{0x33,0x46, 0xca},
{0x33,0x47, 0xc6},
{0x33,0x48, 0x04},
{0x33,0x49, 0x98},
{0x33,0x3F, 0x06},
{0x33,0x2e, 0x04},
{0x33,0x2f, 0x05},
{0x33,0x31, 0x03},
{0x30,0x2B, 0x6D},
{0x30,0x8d, 0x04},
{0x30,0x86, 0x03},
{0x30,0x86, 0x00},
{0x30,0x7d, 0x00},
{0x30,0x85, 0x00},
{0x30,0x6c, 0x10},
{0x30,0x7b, 0x40},
//;78 3300 12
{0x36,0x1d, 0x50},
//[Sensor.YUV]
{0x31,0x00, 0x02},
{0x33,0x01, 0xde},
{0x33,0x04, 0x00},
{0x34,0x00, 0x00},
{0x34,0x04, 0x00},
//;78 3610 60
//[Sensor.YUV.640x480]
//99 640 480
//;XGA->XGA;;
{0x30,0x12, 0x10},
{0x30,0x23, 0x06},
{0x30,0x26, 0x03},
{0x30,0x27, 0x04},
{0x30,0x2a, 0x03},
{0x30,0x2b, 0x10},
{0x30,0x75, 0x24},
{0x30,0x0d, 0x01},
{0x30,0xd7, 0x90},//;
{0x30,0x69, 0x04},
{0x30,0x3e, 0x00},
{0x30,0x3f, 0xc0},
{0x33,0x02, 0xef},
{0x33,0x5f, 0x34},
{0x33,0x60, 0x0c},
{0x33,0x61, 0x04},
{0x33,0x62, 0x34},
{0x33,0x63, 0x08},
{0x33,0x64, 0x04},
{0x34,0x03, 0x42},
{0x30,0x88, 0x04},
{0x30,0x89, 0x00},
{0x30,0x8a, 0x03},
{0x30,0x8b, 0x00},
{0x30,0x0e, 0x32},
{0x30,0x0f, 0x21},
{0x30,0x10, 0x20},
{0x30,0x11, 0x01},
{0x30,0x4c, 0x82},

//;XGA->VGA
{0x33,0x02, 0xef},
{0x33,0x5f, 0x34},
{0x33,0x60, 0x0c},
{0x33,0x61, 0x04},
{0x33,0x62, 0x12},
{0x33,0x63, 0x88},
{0x33,0x64, 0xe4},
{0x34,0x03, 0x42},
{0x30,0x88, 0x12},
{0x30,0x89, 0x80},
{0x30,0x8a, 0x01},
{0x30,0x8b, 0xe0},
{0x30,0x4c, 0x85},//;;

//[Sensor.YUV.640x480.15]
{0x30,0x0e, 0x39},
{0x30,0x0f, 0x21},
{0x30,0x11, 0x00},
{0x30,0x10, 0x81},
//;78 3014 04
{0x30,0x2e, 0x00},
{0x30,0x2d, 0x00},
{0x30,0x71, 0xeb},
{0x30,0x1C, 0x02}

//================================================
};
#endif

No comments:

Post a Comment