iic.cpp
资源名称:SMDK2440.rar [点击查看]
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:15k
源码类别:
Windows CE
开发平台:
Windows_Unix
- #include <windows.h>
- #include <Winbase.h>
- #include <s2440.h>
- #include <nkintr.h>
- #include <oalintr.h>
- #include <p2.h>
- #include "camif.h"
- #define U8 unsigned char
- #define U16 unsigned short
- #define U32 unsigned int
- #define CAM_OV7620 (0) // OMNI Vision camera, 640x480 VGA
- #define CAM_S5X433 (1) // Samsung S5X433 VGA camera
- #define CAM_S5X532 (2) // Samsung S5X532 VGA camera
- #define CAM_AU70H (3) // 1152x864 MegaPixel Camera, max 19.3Mhz
- #define CAM_S5X3A1 (4) // Mega pixel
- //#define SlaveID 0x42 //OV7620 Slave ID
- #define SlaveID 0x5a //S5X532 Slave ID
- #define WRDATA (1)
- #define RDDATA (3)
- #define SETRDADDR (4)
- #define CAMIICBUFSIZE 0x20
- #define IICBUFSIZE 0x20
- // 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) )
- 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] = {
- // OMNI Vision
- {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, 0x74}, // set 8 Bit YUV mode, enable AGC/AWB, mirror image enabled.
- {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, 0x74} // set 8 Bit YUV mode, enable AGC/AWB, mirror image enabled.
- };
- */
- const unsigned char S5X532_YCbCr8bit_TV[][2] =
- {
- #if 0
- // page 5
- {0xec,0x05},
- {0x08,0x55},
- {0x0a,0x75},
- {0x0c,0x90},
- {0x0e,0x18},
- {0x12,0x09},
- {0x14,0x9d},
- {0x16,0x90},
- {0x1a,0x18},
- {0x1c,0x0c},
- {0x1e,0x09},
- {0x20,0x06},
- {0x22,0x20},
- {0x2a,0x00},
- {0x2d,0x04},
- {0x12,0x24},
- // page 3
- {0xec,0x03},
- {0x0c,0x09},
- {0x6c,0x09},
- {0x2b,0x10}, // momo clock inversion
- // page 2
- {0xec,0x02},
- {0x03,0x09},
- {0x05,0x08},
- {0x06,0x01},
- {0x07,0xf8},
- {0x15,0x25},
- {0x30,0x29},
- {0x36,0x12},
- {0x38,0x04},
- {0x1b,0x77}, // 24MHz : 0x77, 12MHz : 0x22
- {0x1c,0x77}, // 24MHz : 0x77, 12MHz : 0x22
- // page 1
- {0xec,0x01},
- {0x00,0x03}, //
- {0x0a,0x08}, // 0x0-QQVGA, 0x06-CIF, 0x02-QCIF, 0x08-VGA, 0x04-QVGA, 0x0a-SXGA
- {0x0c,0x00}, // Pattern selectio. 0-CIS, 1-Color bar, 2-Ramp, 3-Blue screen
- //{0x10,0x27}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
- {0x10,0x21}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
- {0x50,0x21}, // Hblank
- {0x51,0x00}, // Hblank
- {0x52,0xA1}, // Hblank
- {0x53,0x02}, // Hblank
- {0x54,0x01}, // Vblank
- {0x55,0x00}, // Vblank
- {0x56,0xE1}, // Vblank
- {0x57,0x01}, // Vblank
- {0x58,0x21}, // Hsync
- {0x59,0x00}, // Hsync
- {0x5a,0xA1}, // Hsync
- {0x5b,0x02}, // Hsync
- {0x5c,0x03}, // Vref
- {0x5d,0x00}, // Vref
- {0x5e,0x05}, // Vref
- {0x5f,0x00}, // Vref
- {0x70,0x0E},
- {0x71,0xD6},
- {0x72,0x30},
- {0x73,0xDB},
- {0x74,0x0E},
- {0x75,0xD6},
- {0x76,0x18},
- {0x77,0xF5},
- {0x78,0x0E},
- {0x79,0xD6},
- {0x7a,0x28},
- {0x7b,0xE6},
- {0x50,0x00},
- {0x5c,0x00},
- // page 0
- {0xec,0x00},
- {0x79,0x01},
- {0x58,0x90},
- {0x59,0xA0},
- {0x5a,0x50},
- {0x5b,0x70},
- {0x5c,0xD0},
- {0x5d,0xC0},
- {0x5e,0x28},
- {0x5f,0x08},
- {0x50,0x90},
- {0x51,0xA0},
- {0x52,0x50},
- {0x53,0x70},
- {0x54,0xD0},
- {0x55,0xC0},
- {0x56,0x28},
- {0x57,0x00},
- {0x48,0x90},
- {0x49,0xA0},
- {0x4a,0x50},
- {0x4b,0x70},
- {0x4c,0xD0},
- {0x4d,0xC0},
- {0x4e,0x28},
- {0x4f,0x08},
- {0x72,0x82}, // main clock = 24MHz:0xd2, 16M:0x82, 12M:0x54
- {0x75,0x05} // absolute vertical mirror. junon
- #endif
- #if 1
- {0xec,0x00},
- {0x02,0x00},
- {0x14,0x60},
- {0x15,0x60},
- {0x16,0x60},
- {0x1b,0x20},
- {0x1c,0x20},
- {0x1d,0x20},
- {0x1e,0x20},
- {0x72,0xdc},
- {0x73,0x11},
- {0x76,0x82},
- {0x77,0x90},
- {0x78,0x6c},
- {0x0a,0x02},
- {0x34,0x0d},
- {0x35,0x0a},
- {0x36,0x05},
- {0x37,0x05},
- {0x38,0x06},
- {0x39,0x08},
- {0x3A,0x0d},
- {0x3B,0x0d},
- {0x3C,0x18},
- {0x3D,0xE0},
- {0x3E,0x20},
- {0x66,0x02},
- {0x6c,0x40},
- {0x7c,0x01},
- {0x0D,0x24},
- {0x40,0x1B},
- {0x41,0x4F},
- {0x42,0x24},
- {0x43,0x3E},
- {0x44,0x32},
- {0x45,0x30},
- {0x48,0xa0},
- {0x49,0xd0},
- {0x4A,0x28},
- {0x4B,0x7d},
- {0x4C,0xd0},
- {0x4D,0xe0},
- {0x4E,0x1a},
- {0x4F,0xa0},
- {0x50,0xc0},
- {0x51,0xc0},
- {0x52,0x42},
- {0x53,0x7e},
- {0x54,0xc0},
- {0x55,0xf0},
- {0x56,0x1e},
- {0x57,0xe0},
- {0x58,0xc0},
- {0x59,0xa0},
- {0x5A,0x4a},
- {0x5B,0x7e},
- {0x5C,0xc0},
- {0x5D,0xf0},
- {0x5E,0x2a},
- {0x5F,0x10},
- {0x79,0x00},
- {0x7a,0x00},
- {0xe0,0x0f},
- {0xe3,0x14},
- {0xe5,0x48},
- {0xe7,0x58},
- //=============== page1 ===============//
- {0xec,0x01},
- {0x10,0x05},
- {0x20,0xde},
- {0x0b,0x06},
- {0x30,0x00},
- {0x31,0x00},
- {0x32,0x00},
- {0x24,0x28},
- {0x25,0x3F},
- {0x26,0x65},
- {0x27,0xA1},
- {0x28,0xFF},
- {0x29,0x96},
- {0x2A,0x85},
- {0x2B,0xFF},
- {0x2C,0x00},
- {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 Error1rn")));
- }
- // initialize the card insertion interrupt event
- if (!InterruptInitialize (SYSINTR_IIC, IIC_InterruptEvent, NULL, 0)) {
- RETAILMSG(1,(TEXT("IIC interrupt event Error2rn")));
- }
- }
- RETAILMSG(1,(TEXT("Use IIC for initializationrn")));
- // 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%xrn"),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:%drn"),i));
- Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
- Sleep(1);
- }
- RETAILMSG(1,(TEXT("Block TX Ended...rn")));
- 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%xrn"),_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 occurrn")));
- 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++);
- }