?? iic.c
字號:
#include <windows.h>
#include <s2440.h>
#include <nkintr.h>
#include <oalintr.h>
#include <p2.h>
#include "IIC_OV7620.h"
#define ERRORMSG(a,b) RETAILMSG(1,b)
//#define U8 unsigned char
//#define U16 unsigned short
//#define U32 unsigned int
#define CAM_ID (0x42)
// GP9:SCL, GP8:SDA
#define SCL (1<<14)
#define SDA (1<<15)
#define SCL0 (s2440IOP->rGPEDAT &= ~SCL)
#define SCL1 (s2440IOP->rGPEDAT |= SCL)
#define SDA0 (s2440IOP->rGPEDAT &= ~SDA)
#define SDA1 (s2440IOP->rGPEDAT |= SDA)
//#define SDAOUT SDA
#define GetSDA (s2440IOP->rGPEDAT)
static U8 _iicData[IICBUFSIZE];
static volatile int _iicDataCount;
static volatile int _iicStatus;
static volatile int _iicMode;
static int _iicPt;
const unsigned char Ov7620_YCbCr8bit_TV[][2] = {
{0x12, 0x80}, // Camera Soft reset. Self cleared after reset.
{0x00, 0x00},
{0x01, 0x80}, // set blue gain
{0x02, 0x80}, // set red gain
{0x03, 0xb0},
{0x06, 0x60}, // set brightness
{0x0c, 0x24}, // set blue background
{0x0d, 0x24}, // set red background
{0x10, 0xff}, // set exposure time, brightness control
{0x11, 0x80}, // set frame rate CLK_input = PCLK
{0x12, 0x34}, // set 8 Bit YUV mode, enable AGC/AWB, mirror image.
{0x13, 0x21}, // 8bit Data, CCIR601 Format
{0x15, 0x01}, // Use PCLK falling edge to latch data, 8 Bit UYVY....
{0x16, 0x03}, //
{0x17, 0x2f}, //
{0x18, 0xcf}, // (207-47)*4 = 640
{0x19, 0x06}, //
{0x1a, 0xf5}, // ((244-5)+1)*2=480
{0x1b, 0x00},
{0x20, 0x00},
{0x21, 0x80},
{0x22, 0x80},
{0x23, 0x00},
{0x26, 0xa2},
{0x27, 0xea},
{0x29, 0x00},
{0x2a, 0x00},
{0x2b, 0x00},
{0x2c, 0x88},
{0x2e, 0x80},
{0x2f, 0x44},
{0x60, 0x27},
{0x61, 0x82},
{0x62, 0x5f},
{0x63, 0xd5},
{0x64, 0x57},
{0x65, 0x83},
{0x66, 0x55},
{0x68, 0xcf},
{0x69, 0x76},
{0x6a, 0x22},
{0x6b, 0x00},
{0x6c, 0x08},
{0x6d, 0x48},
{0x6e, 0x80},
{0x6f, 0x0c},
{0x70, 0x89},
{0x71, 0x00},
{0x72, 0x14},
{0x73, 0x54},
{0x75, 0x0e},
{0x76, 0x00},
{0x77, 0xff},
{0x78, 0x80},
{0x79, 0x80},
{0x7a, 0x80},
{0x7b, 0xe6},
{0x7c, 0x00},
{0x13, 0x21},
{0x14, 0x94},
{0x24, 0x10},
{0x25, 0x8a},
{0x28, 0x20}, // Progressive mode.
{0x2d, 0x95}, //
{0x67, 0x92}, //
{0x74, 0x00}, // -CJH
{0x12, 0x34} // set 8 Bit YUV mode, enable AGC/AWB, mirror image.
};
// Change GP8(I2CSDA) as input/output mode.
#define SET_SDA_INPUT (s2440IOP->rGPECON &= ~(3<<30))
#define SET_SDA_OUTPUT (s2440IOP->rGPECON = (s2440IOP->rGPECON & ~(2<<30)) |(1<<30) )
volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
volatile IICreg *s2440IIC = (IICreg *)IIC_BASE;
extern void Camera_Initialize(void);
void Init_Sccb_Port(void);
void Camera_Initialize(void);
void Init_Camera_Module_YCbCr_VGA(void);
void setCIS(unsigned char bSubAddr, unsigned char bData);
void outSCCB(unsigned char *bpData, unsigned char bSize);
void Sccb_Start(void);
void loopn(U32 wCount);
void Sccb_Write_8bit(U8 Write_Byte);
void Sccb_Ack(void);
void Sccb_Stop(void);
void Delay(int time);
void SetCAMClockDivider(int divn);
void OV7620_WriteBlock(void);
void Wr_OV7620(U32 slvAddr, U32 addr, U8 data);
void Run_IicPoll(void);
void IicPoll(void);
void Init_Sccb_Port(void)
{
// GP9:SCL, GP8:SDA, set all GPIO output.
s2440IOP->rGPECON = (s2440IOP->rGPECON & ~(0xA<<28)) | (5<<28); //GPE 14, 15
}
void outSCCB(unsigned char *bpData, unsigned char bSize)
{
int i;
int j;
unsigned char bTemp, bCombineMode;
SET_SDA_OUTPUT;
Sccb_Start();
while(bSize--){
Sccb_Write_8bit(*bpData);
bpData++;
Sccb_Ack();
//SET_SDA_INPUT;
//while(GetSDA & SDA); // check ACK
} //while(bSize--)
Sccb_Stop();
}
void setCIS(unsigned char bSubAddr, unsigned char bData)
{
unsigned char bTemp[3];
bTemp[0] = CAM_ID; // slave Address ( Omni)
bTemp[1] = bSubAddr;
bTemp[2] = bData;
//while(1)
outSCCB(bTemp, 3);
}
void loopn(U32 wCount)
{
int i, j;
for (i=0; i<wCount; i++);
for(j=0; j<1000; j++); // 451Mhz
// for(j=0; j<1500; j++); // 531Mhz
}
void Sccb_Start(void)
{
SET_SDA_OUTPUT;
// start
SCL1;
loopn(4);
SDA1;
loopn(8);
SDA0; //start point
loopn(4);
}
void Sccb_Ack(void)
{
SET_SDA_OUTPUT;
SCL0;
loopn(4);
SDA1;
loopn(4);
SCL1;
loopn(4);
}
void Sccb_Write_8bit(U8 Write_Byte)
{
int i;
SET_SDA_OUTPUT;
for(i=0;i<8;i++){
SCL0;
loopn(4);
if(Write_Byte & 0x80) SDA1;
else SDA0;
loopn(4);
Write_Byte <<= 1;
SCL1;
loopn(4);
} //for(i=0;i<8;i++){
}
void Sccb_Stop(void)
{
// stop
SET_SDA_OUTPUT;
SCL0;
loopn(4);
SDA0;
loopn(4);
SCL1;
loopn(4);
SDA1; // stop point
}
static int delayLoopCount = 100;
void Delay(int time)
{
int i;
for(;time>0;time--)
for(i=0;i<delayLoopCount;i++);
}
void Init_Camera_Module_YCbCr_VGA(void)
{
setCIS(0x12, 0x80); // Camera Soft reset. Self cleared after reset.
Delay(10);
// From Omnivision...
setCIS(0x00, 0x00); //
// setCIS(0x01, 0x40); // set blue gain
// setCIS(0x02, 0x40); // set red gain
setCIS(0x01, 0x80); // set blue gain
setCIS(0x02, 0x80); // set red gain
setCIS(0x03, 0xb0); // saturation control
//setCIS(0x03, 0xb0); // saturation control
//setCIS(0x06, 0x80); // set brightness
setCIS(0x06, 0x60); // set brightness - CJH
//setCIS(0x07, 0x00); // Sharpness control : Threshold-0, Magnitude-0
setCIS(0x0c, 0x24); // set white balance blue background
setCIS(0x0d, 0x24); // set white balance red background
//setCIS(0x10, 0xb0); // set auto exposure time, brightness control
setCIS(0x10, 0xff); // set auto exposure time, brightness control - CJH
setCIS(0x11, (1<<7)+(0<<6)+(0x0)); // HSYNC positive, CHSYNC negative, VSYNC posigive
// 16 Bit : PCLK = CLK_in/((1+x)*2)
// 8 Bit : PCLK = CLK_in/(1+x)
setCIS(0x12, 0x34); // mirror image, enable AGC/AWB
// precise A/D black level compensation
setCIS(0x13, (0x1<<5)+(0x0<<4)+(0x1)); // 8bit Data, CCIR601 Format
setCIS(0x15, 0x01); // Use PCLK rising edge to latch data
// UV data output: 16 Bit - UVUV..., 8 Bit - UYVY...
setCIS(0x16, 0x03); // Field mode : 00-OFF mode, 01-ODD mode, 10-EVEN mode, 11-FRAME mode
//setCIS(0x17, CAM_STX); //
//setCIS(0x18, CAM_ENDX); // (207-47)*4 = 640
//setCIS(0x19, CAM_STY); //
//setCIS(0x1a, CAM_ENDY); // ((244-5)+1)*2=480
setCIS(0x17, 0x2f);
setCIS(0x18, 0xcf);
setCIS(0x19, 0x06);
setCIS(0x1a, 0xf5);
setCIS(0x1b, 0x00); // Pixel Shift
// setCIS(0x1b, 0x00); // Pixel Shift - 0
setCIS(0x20, 0x00); // limit vertical size to 480, second stage aperture correction enable
// AWB smart mode disable, AWB is slow mode
setCIS(0x21, 0x80); // Y Channel Offset Adjustment - 0 , direction - Subtract
setCIS(0x22, 0x80); // U Channel Offset Adjustment - 0
setCIS(0x23, 0x00); // Crystal Current control : maximum current
setCIS(0x26, 0xa2); // Digital sharpness threshold, magnitude.
setCIS(0x27, 0xea); // Disable CCIR rang clip
//setCIS(0x27, 0xe0); // Disable CCIR rang clip - CJH
setCIS(0x29, 0x00); //
//setCIS(0x2a, 0x10); // frame rate high, 60Hz, 50Hz:0x80, UV delay 2 pixel.
setCIS(0x2a, 0x00); // frame rate high, 60Hz, 50Hz:0x80, UV delay 2 pixel. - CJH
setCIS(0x2b, 0x00); // frame rate low, 60Hz, 50Hz:0xac
setCIS(0x2c, 0x88); //
setCIS(0x2e, 0x80); //
setCIS(0x2f, 0x44); //
setCIS(0x60, 0x27); //
setCIS(0x61, 0x82); // 02?x.........................................
setCIS(0x62, 0x5f); //
//setCIS(0x63, 0xcc); //
setCIS(0x63, 0xd5); //
setCIS(0x64, 0x57); // Enable Y Gamma
setCIS(0x65, 0x83); //
setCIS(0x66, 0x55); //
setCIS(0x68, 0xcf); //
//setCIS(0x68, 0xca); // -CJH
setCIS(0x69, 0x76); //
setCIS(0x6a, 0x22); //
setCIS(0x6b, 0x00); //
setCIS(0x6c, 0x08); //
//setCIS(0x6d, 0x44); //
setCIS(0x6d, 0x48); //
setCIS(0x6e, 0x80); //
//setCIS(0x6f, 0x0d); //
setCIS(0x6f, 0x0c); // -CJH
//setCIS(0x70, 0x8b); //
setCIS(0x70, 0x89); // -CJH
setCIS(0x71, 0x00); // freerun PCLK
setCIS(0x72, 0x14); //
setCIS(0x73, 0x54); //
//setCIS(0x75, 0x8e); //
setCIS(0x75, 0x0e); // -CJH
setCIS(0x76, 0x00); //
setCIS(0x77, 0xff); //
setCIS(0x78, 0x80); //
setCIS(0x79, 0x80); //
setCIS(0x7a, 0x80); //
//setCIS(0x7b, 0xe2); //
setCIS(0x7b, 0xe6); // -CJH
setCIS(0x7c, 0x00); //
setCIS(0x13, 0x21); // YUV 8-bit format, Enable AEC/AGC/AWB
//setCIS(0x14, 0x04); // turn off GAMMA
setCIS(0x14, 0x94); // turn off GAMMA - CJH
//setCIS(0x24, 0x3a); //
setCIS(0x24, 0x10); // -CJH
//setCIS(0x25, 0x60); //
setCIS(0x25, 0x8a); // -CJH
setCIS(0x28, 0x20); // Progressive mode.
setCIS(0x2d, 0x95); //
setCIS(0x67, 0x92); //
//setCIS(0x74, 0x00); //
setCIS(0x74, 0x00); // -CJH
setCIS(0x12, 0x34); // mirror image, enable AGC/AWB
}
void Camera_Initialize(void)
{
// Use GPIO as IIC
/*
RETAILMSG(1,(TEXT("Camera_Initialize\n")));
SetCAMClockDivider(1);
Init_Sccb_Port(); //Initializing GPIO for Serial Camera Control Bus
Init_Camera_Module_YCbCr_VGA(); //Initializing Camera Processor. Using SCCB interface
*/
SetCAMClockDivider(1); // for 24M Camera, set to 1 if it's 24M camera
RETAILMSG(1,(TEXT("Use IIC for initialization\n")));
// Use IIC for initialization
OV7620_WriteBlock();
}
void SetCAMClockDivider(int divn) // divn is even number 0~15
{
volatile CLKPWRreg *s2440PWR = (CLKPWRreg *)CLKPWR_BASE;
// s2440PWR->rCLKDIVN |= (1<<3); // UCLK 48MHz setting
s2440PWR->rCAMDIVN = (s2440PWR->rCAMDIVN & ~(0xf))|(0x10)|(divn); // CAMCLK is divided..
// RETAILMSG(1,(TEXT("s2440PWR->rCLKCON:0x%x\r\n"),s2440PWR->rCLKCON));
}
void OV7620_WriteBlock(void)
{
unsigned int i, j, save_E, save_PE, RegAddr, RegData;
static U8 rdata[256];
save_E = s2440IOP->rGPECON;
save_PE = s2440IOP->rGPEUP;
s2440IOP->rGPEUP &= ~0xc000; //Pull-up disable
s2440IOP->rGPEUP |= 0xc000; //Pull-up disable
s2440IOP->rGPECON &= ~(0xF<<28); //GPE15:IICSDA , GPE14:IICSCL
s2440IOP->rGPECON |= (0xa<<28); //GPE15:IICSDA , GPE14:IICSCL
//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
s2440IIC->rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);
s2440IIC->rIICADD = 0x10; //2440 slave address = [7:1]. this is avialable when 240 is slave.
s2440IIC->rIICSTAT = 0x10; //IIC bus data output enable(Rx/Tx)
s2440IIC->rIICLC = (1<<2)|(3); // Filter enable, 15 clocks SDA output delay added into 2440
for(i=0; i<(sizeof(Ov7620_YCbCr8bit_TV)/2); i++){
RETAILMSG(1,(TEXT("number:%d\r\n"),i));
Wr_OV7620(SlaveID, Ov7620_YCbCr8bit_TV[i][0], Ov7620_YCbCr8bit_TV[i][1]);
}
RETAILMSG(1,(TEXT("Block TX Ended...\r\n")));
s2440IOP->rGPEUP = save_PE;
s2440IOP->rGPECON = save_E;
}
void Wr_OV7620(U32 slvAddr, U32 addr, U8 data)
{
_iicMode = WRDATA;
_iicPt = 0;
_iicData[0] = (U8)addr;
_iicData[1] = data;
_iicDataCount = 2;
// write slave address
s2440IIC->rIICDS = slvAddr; //0x42: OV7620 Slave ID
// After this time, timing is critical, because IIC start.
s2440IIC->rIICSTAT = 0xf0; //Start Master TX Condition
s2440IIC->rIICCON = 0xaf; //Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1)
Run_IicPoll();
}
void Run_IicPoll(void)
{
if(s2440IIC->rIICCON & 0x10) //Tx/Rx Interrupt Enable
IicPoll();
}
void IicPoll(void)
{
U32 iicSt,i;
/*
iicSt = s2440IIC->rIICSTAT;
if(iicSt & 0x8){} //When bus arbitration is failed.
if(iicSt & 0x4){} //When a slave address is matched with IICADD
if(iicSt & 0x2){} //When a slave address is 0000000b
if(iicSt & 0x1){} //When ACK isn't received
*/
switch(_iicMode)
{
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++] = s2440IIC->rIICDS;
s2440IIC->rIICSTAT = 0x90; //Stop MasRx condition
s2440IIC->rIICCON = 0xaf; //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect., Too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
_iicData[_iicPt++] = s2440IIC->rIICDS; //The last data has to be read with no ack.
if((_iicDataCount)==0)
s2440IIC->rIICCON = 0x2f; //Resumes IIC operation with NOACK in case of OV7620 Cameara
else
s2440IIC->rIICCON = 0xaf; //Resumes IIC operation with ACK
break;
case WRDATA:
if((_iicDataCount--)==0)
{
s2440IIC->rIICSTAT = 0xd0; //stop MasTx condition
s2440IIC->rIICCON = 0xaf; //resumes IIC operation.
Delay(10); // we should adjust this time.
//The pending bit will not be set after issuing stop condition.
break;
}
s2440IIC->rIICDS = _iicData[_iicPt++]; //_iicData[0] has dummy.
// for(i=0;i<20;i++); //for setup time until rising edge of IICSCL. we have to adjust this time.
RETAILMSG(1,(TEXT("B")));
s2440IIC->rIICCON = 0xaf; //resumes IIC operation.
break;
case SETRDADDR:
RETAILMSG(1,(TEXT("[S%d]",_iicDataCount)));
if((_iicDataCount--)==0)
{
s2440IIC->rIICSTAT = 0xd0; //stop MasTx condition
s2440IIC->rIICCON = 0xaf; //resumes IIC operation.
Delay(1); //wait until stop condtion is in effect.
break; //IIC operation is stopped because of IICCON[4]
}
s2440IIC->rIICDS = _iicData[_iicPt++];
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
s2440IIC->rIICCON = 0xaf; //resumes IIC operation.
break;
default:
break;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -