📄 iic.cpp
字号:
{0x2D,0x1B},
{0xB0,0x28},
{0xB1,0x3F},
{0xB2,0x65},
{0xB3,0xA1},
{0xB4,0xFF},
{0xB5,0x96},
{0xB6,0x85},
{0xB7,0xFF},
{0xB8,0x00},
{0xB9,0x1B},
{0x15,0x15},
{0x18,0x85},
{0x1f,0x05},
{0x87,0x40},
{0x37,0x60},
{0x38,0xd5},
{0x48,0xa0},
{0x61,0x54},
{0x62,0x54},
{0x63,0x14},
{0x64,0x14},
{0x6d,0x12},
{0x78,0x09},
{0x79,0xD7},
{0x7A,0x14},
{0x7B,0xEE},
//=============== page2 ===============//
{0xec,0x02},
{0x2c,0x76},
{0x25,0x25},
{0x27,0x27},
{0x30,0x29},
{0x36,0x08},
{0x38,0x04},
//=============== page3 ===============//
{0xec,0x03},
{0x08,0x00},
{0x09,0x33},
//=============== page4 ===============//
{0xec,0x04},
{0x00,0x21},
{0x01,0x00},
{0x02,0x9d},
{0x03,0x02},
{0x04,0x04},
{0x05,0x00},
{0x06,0x1f},
{0x07,0x02},
{0x08,0x21},
{0x09,0x00},
{0x0a,0x9d},
{0x0b,0x02},
{0x0c,0x04},
{0x0d,0x00},
{0x0e,0x20},
{0x0f,0x02},
{0x1b,0x3c},
{0x1c,0x3c},
//=============== page5 ===============//
{0xec,0x05},
{0x1f,0x00},
{0x08,0x59},
{0x0a,0x71},
{0x1e,0x23},
{0x0e,0x3c},
//=============== page7 ===============//
{0xec,0x07},
{0x11,0xfe},
// added by junon
{0xec,0x01},
{0x10,0x26}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
#endif
};
extern void Camera_Initialize(void);
extern volatile IOPreg *s2440IOP;
extern volatile IICreg *s2440IIC;
void Camera_Initialize(void);
void Delay(int time);
void SetCAMClockDivider(int divn);
void CAM_WriteBlock(void);
void Wr_CamIIC(U32 slvAddr, U32 addr, U8 data);
void Rd_CamIIC(U32 slvAddr, U32 addr, U8 *data);
void Run_IicPoll(void);
void IicPoll(void);
static HANDLE IIC_InterruptEvent = NULL;
void Camera_Initialize(void)
{
if (IIC_InterruptEvent == NULL)
{
// allocate the interrupt event for IIC
IIC_InterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == IIC_InterruptEvent) {
RETAILMSG(1,(TEXT("IIC interrupt event Error1\r\n")));
}
// initialize the card insertion interrupt event
if (!InterruptInitialize (SYSINTR_IIC, IIC_InterruptEvent, NULL, 0)) {
RETAILMSG(1,(TEXT("IIC interrupt event Error2\r\n")));
}
}
RETAILMSG(1,(TEXT("Use IIC for initialization\r\n")));
// Use IIC for initialization
CAM_WriteBlock();
}
void SetCAMClockDivider(int divn) // divn is even number 0~15
{
volatile CLKPWRreg *s2440PWR = (CLKPWRreg *)CLKPWR_BASE;
s2440PWR->rCAMDIVN = (s2440PWR->rCAMDIVN & ~(0xf))|(0x10)|(divn); // CAMCLK is divided..
// RETAILMSG(1,(TEXT("s2440PWR->rCLKCON:0x%x\r\n"),s2440PWR->rCLKCON));
}
void CAM_WriteBlock(void)
{
unsigned int i, save_E, save_PE;
static U8 rdata[256];
int err = 0;
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) | (1<<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(S5X532_YCbCr8bit_TV)/2); i++){
//RETAILMSG(1,(TEXT("num:%d\r\n"),i));
Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
Sleep(1);
}
RETAILMSG(1,(TEXT("Block TX Ended...\r\n")));
s2440IOP->rGPEUP = save_PE;
s2440IOP->rGPECON = save_E;
}
void Wr_CamIIC(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 = 0xef; //Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1)
Run_IicPoll();
}
void Rd_CamIIC(U32 slvAddr,U32 addr,U8 *data){ /*IIC Slave Addr Write + IIC Reg Addr Write */ _iicMode = SETRDADDR; _iicPt = 0; _iicData[0] = (U8)addr; _iicDataCount = 1;
// 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 = 0xef; //Clearing the pending bit isn't needed because the pending bit has been cleared.
while(_iicDataCount!=-1)
Run_IicPoll();
_iicMode = RDDATA;
_iicPt = 0;
_iicDataCount = 1;
s2440IIC->rIICDS = slvAddr;
s2440IIC->rIICSTAT = 0xb0; //Master Rx,Start
s2440IIC->rIICCON = 0xef; //Resumes IIC operation.
while(_iicDataCount!=-1)
Run_IicPoll();
*data = _iicData[1];
//RETAILMSG(1,(TEXT("Data:0x%x\r\n"),_iicData[1]));
}
void Run_IicPoll(void)
{
DWORD waitStatus;
// When using Interrupt mode
waitStatus = WaitForSingleObject(IIC_InterruptEvent, INFINITE);
// When using polling mode
// if(s2440IIC->rIICCON & 0x10) //Tx/Rx Interrupt Enable
IicPoll();
}
void IicPoll(void)
{
volatile U32 i;
//RETAILMSG(1,(TEXT("IIC Interrupt occur\r\n")));
switch(_iicMode)
{
case RDDATA:
if((_iicDataCount--)==0)
{
_iicData[_iicPt++] = s2440IIC->rIICDS;
s2440IIC->rIICSTAT = 0x90; //Stop MasRx condition
s2440IIC->rIICCON = 0xef; //Resumes IIC operation.
Delay(10); //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 = 0x6f; //Resumes IIC operation with NOACK in case of OV7620 Cameara
else
s2440IIC->rIICCON = 0xef; //Resumes IIC operation with ACK
break;
case WRDATA:
if((_iicDataCount--)==0)
{
s2440IIC->rIICSTAT = 0xd0; //stop MasTx condition
s2440IIC->rIICCON = 0xef; //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 setup time until rising edge of IICSCL. we have to adjust this time.
Delay(10);
//for(i=0;i<1000;i++);
// IICDS has to be written before clearing the IIC interrupt pending bit
//RETAILMSG(1,(TEXT("BB"))); // we should adjust this time.
s2440IIC->rIICCON = 0xef; //resumes IIC operation.
break;
case SETRDADDR:
if((_iicDataCount--)==0)
{
s2440IIC->rIICSTAT = 0xd0; //stop MasTx condition
s2440IIC->rIICCON = 0xef; //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++];
Delay(10);
//for(i=0;i<1000;i++); //for setup time until rising edge of IICSCL
//RETAILMSG(1,(TEXT("RD"))); // we should adjust this time.
s2440IIC->rIICCON = 0xef; //resumes IIC operation.
break;
default:
break;
}
InterruptDone(SYSINTR_IIC);
}
void Delay(int time)
{
volatile int i;
for(;time>0;time--)
for(i=0;i<100;i++);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -