IIC.c
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:15k
源码类别:
Windows CE
开发平台:
Windows_Unix
- #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_Initializen")));
- 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 initializationn")));
- // 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%xrn"),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:%drn"),i));
- Wr_OV7620(SlaveID, Ov7620_YCbCr8bit_TV[i][0], Ov7620_YCbCr8bit_TV[i][1]);
- }
- RETAILMSG(1,(TEXT("Block TX Ended...rn")));
- 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;
- }
- }