IIC.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:15k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. #include <windows.h>
  2. #include <s2440.h>
  3. #include <nkintr.h>
  4. #include <oalintr.h>
  5. #include <p2.h>
  6. #include "IIC_OV7620.h"
  7. #define ERRORMSG(a,b) RETAILMSG(1,b)
  8. //#define U8 unsigned char
  9. //#define U16 unsigned short
  10. //#define U32 unsigned int
  11. #define CAM_ID (0x42)
  12. // GP9:SCL, GP8:SDA
  13. #define SCL (1<<14)
  14. #define SDA (1<<15)
  15. #define SCL0 (s2440IOP->rGPEDAT &= ~SCL)
  16. #define SCL1 (s2440IOP->rGPEDAT |= SCL)
  17. #define SDA0 (s2440IOP->rGPEDAT &= ~SDA)
  18. #define SDA1 (s2440IOP->rGPEDAT |= SDA)
  19. //#define SDAOUT  SDA
  20. #define GetSDA (s2440IOP->rGPEDAT)
  21. static U8 _iicData[IICBUFSIZE];
  22. static volatile int _iicDataCount;
  23. static volatile int _iicStatus;
  24. static volatile int _iicMode;
  25. static int _iicPt;
  26. const unsigned char Ov7620_YCbCr8bit_TV[][2] = {
  27. {0x12, 0x80}, // Camera Soft reset. Self cleared after reset.
  28. {0x00, 0x00},
  29. {0x01, 0x80}, // set blue gain
  30. {0x02, 0x80}, // set red gain
  31. {0x03, 0xb0},
  32. {0x06, 0x60}, // set brightness
  33. {0x0c, 0x24}, // set blue background
  34. {0x0d, 0x24}, // set red background
  35. {0x10, 0xff}, // set exposure time, brightness control
  36. {0x11, 0x80}, // set frame rate CLK_input = PCLK
  37. {0x12, 0x34}, // set 8 Bit YUV mode, enable AGC/AWB, mirror image.
  38. {0x13, 0x21},   // 8bit Data, CCIR601 Format
  39. {0x15, 0x01}, // Use PCLK falling edge to latch data, 8 Bit UYVY....
  40. {0x16, 0x03}, //
  41. {0x17, 0x2f}, //
  42. {0x18, 0xcf},        // (207-47)*4 = 640
  43. {0x19, 0x06}, //
  44. {0x1a, 0xf5},        // ((244-5)+1)*2=480
  45. {0x1b, 0x00},
  46. {0x20, 0x00},
  47. {0x21, 0x80},
  48. {0x22, 0x80},
  49. {0x23, 0x00},
  50. {0x26, 0xa2},
  51. {0x27, 0xea},
  52. {0x29, 0x00},
  53. {0x2a, 0x00},
  54. {0x2b, 0x00},
  55. {0x2c, 0x88},
  56. {0x2e, 0x80},
  57. {0x2f, 0x44},
  58. {0x60, 0x27},
  59. {0x61, 0x82},
  60. {0x62, 0x5f},
  61. {0x63, 0xd5},
  62. {0x64, 0x57},
  63. {0x65, 0x83},
  64. {0x66, 0x55},
  65. {0x68, 0xcf},
  66. {0x69, 0x76},
  67. {0x6a, 0x22},
  68. {0x6b, 0x00},
  69. {0x6c, 0x08},
  70. {0x6d, 0x48},
  71. {0x6e, 0x80},
  72. {0x6f, 0x0c},
  73. {0x70, 0x89},
  74. {0x71, 0x00},
  75. {0x72, 0x14},
  76. {0x73, 0x54},
  77. {0x75, 0x0e},
  78. {0x76, 0x00},
  79. {0x77, 0xff},
  80. {0x78, 0x80},
  81. {0x79, 0x80},
  82. {0x7a, 0x80},
  83. {0x7b, 0xe6},
  84. {0x7c, 0x00},
  85. {0x13, 0x21},
  86. {0x14, 0x94},
  87. {0x24, 0x10},
  88. {0x25, 0x8a},
  89. {0x28, 0x20}, // Progressive mode.
  90. {0x2d, 0x95}, //
  91. {0x67, 0x92}, // 
  92. {0x74, 0x00}, // -CJH
  93. {0x12, 0x34} // set 8 Bit YUV mode, enable AGC/AWB, mirror image.
  94. };
  95. // Change GP8(I2CSDA) as input/output mode.
  96. #define SET_SDA_INPUT (s2440IOP->rGPECON &= ~(3<<30))
  97. #define SET_SDA_OUTPUT (s2440IOP->rGPECON = (s2440IOP->rGPECON & ~(2<<30)) |(1<<30) )
  98. volatile IOPreg *s2440IOP = (IOPreg *)IOP_BASE;
  99. volatile IICreg *s2440IIC = (IICreg *)IIC_BASE;
  100. extern void Camera_Initialize(void);
  101. void Init_Sccb_Port(void);
  102. void Camera_Initialize(void);
  103. void Init_Camera_Module_YCbCr_VGA(void);
  104. void setCIS(unsigned char bSubAddr, unsigned char bData);
  105. void outSCCB(unsigned char *bpData, unsigned char bSize);
  106. void Sccb_Start(void);
  107. void loopn(U32 wCount);
  108. void Sccb_Write_8bit(U8 Write_Byte);
  109. void Sccb_Ack(void);
  110. void Sccb_Stop(void);
  111. void Delay(int time);
  112. void SetCAMClockDivider(int divn);
  113. void OV7620_WriteBlock(void);
  114. void Wr_OV7620(U32 slvAddr, U32 addr, U8 data);
  115. void Run_IicPoll(void);
  116. void IicPoll(void);
  117. void Init_Sccb_Port(void)
  118. {
  119. // GP9:SCL, GP8:SDA, set all GPIO output.
  120. s2440IOP->rGPECON = (s2440IOP->rGPECON & ~(0xA<<28)) | (5<<28); //GPE 14, 15
  121. }
  122. void outSCCB(unsigned char *bpData, unsigned char bSize)
  123. {
  124. int i;
  125. int j;
  126. unsigned char bTemp, bCombineMode;
  127. SET_SDA_OUTPUT;
  128. Sccb_Start();
  129. while(bSize--){
  130. Sccb_Write_8bit(*bpData);
  131. bpData++;
  132. Sccb_Ack();
  133. //SET_SDA_INPUT;
  134. //while(GetSDA & SDA); // check ACK
  135. } //while(bSize--)
  136. Sccb_Stop();
  137. }
  138. void setCIS(unsigned char bSubAddr, unsigned char bData)
  139. {
  140. unsigned char bTemp[3];
  141. bTemp[0] = CAM_ID; // slave Address ( Omni)
  142. bTemp[1] = bSubAddr;
  143. bTemp[2] = bData;
  144. //while(1)
  145. outSCCB(bTemp, 3);
  146. }
  147. void loopn(U32 wCount)
  148. {
  149. int i, j;
  150. for (i=0; i<wCount; i++);
  151. for(j=0; j<1000; j++); // 451Mhz
  152. // for(j=0; j<1500; j++); // 531Mhz
  153. }
  154. void Sccb_Start(void)
  155. {
  156. SET_SDA_OUTPUT;
  157. // start
  158. SCL1;
  159. loopn(4);
  160. SDA1;
  161. loopn(8);
  162. SDA0; //start point
  163. loopn(4);
  164. }
  165. void Sccb_Ack(void)
  166. {
  167. SET_SDA_OUTPUT;
  168. SCL0;
  169. loopn(4);
  170. SDA1;
  171. loopn(4);
  172. SCL1;
  173. loopn(4);
  174. }
  175. void Sccb_Write_8bit(U8 Write_Byte)
  176. {
  177. int i;
  178. SET_SDA_OUTPUT;
  179. for(i=0;i<8;i++){
  180. SCL0;
  181. loopn(4);
  182. if(Write_Byte & 0x80) SDA1;
  183. else SDA0;
  184. loopn(4);
  185. Write_Byte <<= 1;
  186. SCL1;
  187. loopn(4);
  188. } //for(i=0;i<8;i++){
  189. }
  190. void Sccb_Stop(void)
  191. {
  192. // stop
  193. SET_SDA_OUTPUT;
  194. SCL0;
  195. loopn(4);
  196. SDA0;
  197. loopn(4);
  198. SCL1;
  199. loopn(4);
  200. SDA1; // stop point
  201. }
  202. static int delayLoopCount = 100;
  203. void Delay(int time)
  204. {
  205.     int i;
  206.     
  207.     for(;time>0;time--)
  208.         for(i=0;i<delayLoopCount;i++);
  209. }
  210. void Init_Camera_Module_YCbCr_VGA(void)
  211. {
  212. setCIS(0x12, 0x80); // Camera Soft reset. Self cleared after reset.
  213. Delay(10);
  214. // From Omnivision...
  215. setCIS(0x00, 0x00); // 
  216. // setCIS(0x01, 0x40); // set blue gain
  217. // setCIS(0x02, 0x40); // set red gain
  218. setCIS(0x01, 0x80); // set blue gain
  219. setCIS(0x02, 0x80); // set red gain
  220. setCIS(0x03, 0xb0); // saturation control
  221. //setCIS(0x03, 0xb0); // saturation control
  222. //setCIS(0x06, 0x80); // set brightness
  223. setCIS(0x06, 0x60); // set brightness - CJH
  224. //setCIS(0x07, 0x00); // Sharpness control : Threshold-0, Magnitude-0
  225. setCIS(0x0c, 0x24); // set white balance blue background
  226. setCIS(0x0d, 0x24); // set white balance red background
  227. //setCIS(0x10, 0xb0); // set auto exposure time, brightness control
  228. setCIS(0x10, 0xff); // set auto exposure time, brightness control - CJH
  229. setCIS(0x11, (1<<7)+(0<<6)+(0x0)); // HSYNC positive, CHSYNC negative, VSYNC posigive
  230. // 16 Bit : PCLK = CLK_in/((1+x)*2)
  231. //  8 Bit : PCLK = CLK_in/(1+x)
  232. setCIS(0x12, 0x34); // mirror image, enable AGC/AWB
  233. // precise A/D black level compensation
  234. setCIS(0x13, (0x1<<5)+(0x0<<4)+(0x1));  // 8bit Data, CCIR601 Format
  235. setCIS(0x15, 0x01); // Use PCLK rising edge to latch data
  236. // UV data output: 16 Bit - UVUV..., 8 Bit - UYVY...
  237. setCIS(0x16, 0x03); // Field mode : 00-OFF mode, 01-ODD mode, 10-EVEN mode, 11-FRAME mode 
  238. //setCIS(0x17, CAM_STX); // 
  239. //setCIS(0x18, CAM_ENDX); // (207-47)*4 = 640
  240. //setCIS(0x19, CAM_STY); // 
  241. //setCIS(0x1a, CAM_ENDY); // ((244-5)+1)*2=480 
  242. setCIS(0x17, 0x2f);
  243. setCIS(0x18, 0xcf);
  244. setCIS(0x19, 0x06);
  245. setCIS(0x1a, 0xf5);
  246. setCIS(0x1b, 0x00); // Pixel Shift
  247. // setCIS(0x1b, 0x00); // Pixel Shift - 0
  248. setCIS(0x20, 0x00); // limit vertical size to 480, second stage aperture correction enable
  249. // AWB smart mode disable, AWB is slow mode
  250. setCIS(0x21, 0x80); // Y Channel Offset Adjustment - 0 , direction - Subtract
  251. setCIS(0x22, 0x80); // U Channel Offset Adjustment - 0
  252. setCIS(0x23, 0x00); // Crystal Current control : maximum current
  253. setCIS(0x26, 0xa2); // Digital sharpness threshold, magnitude.
  254. setCIS(0x27, 0xea); // Disable CCIR rang clip
  255. //setCIS(0x27, 0xe0); // Disable CCIR rang clip - CJH
  256. setCIS(0x29, 0x00); // 
  257. //setCIS(0x2a, 0x10); // frame rate high, 60Hz, 50Hz:0x80, UV delay 2 pixel.
  258. setCIS(0x2a, 0x00); // frame rate high, 60Hz, 50Hz:0x80, UV delay 2 pixel. - CJH
  259. setCIS(0x2b, 0x00); // frame rate low, 60Hz, 50Hz:0xac
  260. setCIS(0x2c, 0x88); // 
  261. setCIS(0x2e, 0x80); // 
  262. setCIS(0x2f, 0x44); // 
  263. setCIS(0x60, 0x27); // 
  264. setCIS(0x61, 0x82); // 02?x.........................................
  265. setCIS(0x62, 0x5f); // 
  266. //setCIS(0x63, 0xcc); // 
  267. setCIS(0x63, 0xd5); // 
  268. setCIS(0x64, 0x57); // Enable Y Gamma
  269. setCIS(0x65, 0x83); // 
  270. setCIS(0x66, 0x55); // 
  271. setCIS(0x68, 0xcf); // 
  272. //setCIS(0x68, 0xca); // -CJH
  273. setCIS(0x69, 0x76); // 
  274. setCIS(0x6a, 0x22); // 
  275. setCIS(0x6b, 0x00); // 
  276. setCIS(0x6c, 0x08); // 
  277. //setCIS(0x6d, 0x44); // 
  278. setCIS(0x6d, 0x48); // 
  279. setCIS(0x6e, 0x80); // 
  280. //setCIS(0x6f, 0x0d); // 
  281. setCIS(0x6f, 0x0c); // -CJH
  282. //setCIS(0x70, 0x8b); // 
  283. setCIS(0x70, 0x89); // -CJH
  284. setCIS(0x71, 0x00); //  freerun PCLK
  285. setCIS(0x72, 0x14); // 
  286. setCIS(0x73, 0x54); // 
  287. //setCIS(0x75, 0x8e); // 
  288. setCIS(0x75, 0x0e); // -CJH
  289. setCIS(0x76, 0x00); // 
  290. setCIS(0x77, 0xff); // 
  291. setCIS(0x78, 0x80); // 
  292. setCIS(0x79, 0x80); // 
  293. setCIS(0x7a, 0x80); // 
  294. //setCIS(0x7b, 0xe2); // 
  295. setCIS(0x7b, 0xe6); // -CJH
  296. setCIS(0x7c, 0x00); // 
  297. setCIS(0x13, 0x21); // YUV 8-bit format, Enable AEC/AGC/AWB 
  298. //setCIS(0x14, 0x04); // turn off GAMMA
  299. setCIS(0x14, 0x94); // turn off GAMMA - CJH
  300. //setCIS(0x24, 0x3a); // 
  301. setCIS(0x24, 0x10); // -CJH
  302. //setCIS(0x25, 0x60); // 
  303. setCIS(0x25, 0x8a); // -CJH
  304. setCIS(0x28, 0x20); // Progressive mode.
  305. setCIS(0x2d, 0x95); //
  306. setCIS(0x67, 0x92); // 
  307. //setCIS(0x74, 0x00); // 
  308. setCIS(0x74, 0x00); // -CJH
  309. setCIS(0x12, 0x34); // mirror image, enable AGC/AWB
  310. }
  311. void Camera_Initialize(void)
  312. {
  313. // Use GPIO as IIC
  314. /*
  315. RETAILMSG(1,(TEXT("Camera_Initializen")));
  316. SetCAMClockDivider(1);
  317. Init_Sccb_Port(); //Initializing GPIO for Serial Camera Control Bus
  318. Init_Camera_Module_YCbCr_VGA(); //Initializing Camera Processor.  Using SCCB interface
  319. */
  320. SetCAMClockDivider(1); // for 24M Camera, set to 1 if it's 24M camera
  321. RETAILMSG(1,(TEXT("Use IIC for initializationn")));
  322. // Use IIC for initialization
  323. OV7620_WriteBlock();
  324. }
  325. void SetCAMClockDivider(int divn) // divn is even number 0~15
  326. {
  327. volatile CLKPWRreg *s2440PWR = (CLKPWRreg *)CLKPWR_BASE;
  328. // s2440PWR->rCLKDIVN |= (1<<3); // UCLK 48MHz setting
  329. s2440PWR->rCAMDIVN = (s2440PWR->rCAMDIVN & ~(0xf))|(0x10)|(divn); // CAMCLK is divided..
  330. // RETAILMSG(1,(TEXT("s2440PWR->rCLKCON:0x%xrn"),s2440PWR->rCLKCON));
  331. }
  332. void OV7620_WriteBlock(void)
  333. {
  334.     unsigned int i, j, save_E, save_PE, RegAddr, RegData;
  335.     static U8 rdata[256]; 
  336.       
  337.     save_E   = s2440IOP->rGPECON;
  338.     save_PE  = s2440IOP->rGPEUP;
  339.     s2440IOP->rGPEUP  &= ~0xc000;                   //Pull-up disable
  340.     s2440IOP->rGPEUP  |=  0xc000;                   //Pull-up disable
  341.     s2440IOP->rGPECON &= ~(0xF<<28);                //GPE15:IICSDA , GPE14:IICSCL    
  342.     s2440IOP->rGPECON |=  (0xa<<28);                //GPE15:IICSDA , GPE14:IICSCL    
  343.     //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
  344.     s2440IIC->rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);
  345.     s2440IIC->rIICADD  = 0x10;                     //2440 slave address = [7:1]. this is avialable when 240 is slave.
  346.     s2440IIC->rIICSTAT = 0x10;                     //IIC bus data output enable(Rx/Tx)
  347.     s2440IIC->rIICLC = (1<<2)|(3);   // Filter enable, 15 clocks SDA output delay     added into 2440
  348.     
  349.     for(i=0; i<(sizeof(Ov7620_YCbCr8bit_TV)/2); i++){
  350.      RETAILMSG(1,(TEXT("number:%drn"),i));
  351. Wr_OV7620(SlaveID, Ov7620_YCbCr8bit_TV[i][0], Ov7620_YCbCr8bit_TV[i][1]);
  352. }
  353.     RETAILMSG(1,(TEXT("Block TX Ended...rn")));
  354.     s2440IOP->rGPEUP  = save_PE;
  355.     s2440IOP->rGPECON = save_E;
  356. }
  357. void Wr_OV7620(U32 slvAddr, U32 addr, U8 data)
  358. {
  359.     _iicMode      = WRDATA;
  360.     _iicPt        = 0;
  361.     _iicData[0]   = (U8)addr;
  362.     _iicData[1]   = data;
  363.     _iicDataCount = 2;
  364.     // write slave address
  365.     s2440IIC->rIICDS = slvAddr;  //0x42: OV7620 Slave ID 
  366.     // After this time, timing is critical, because IIC start.
  367.     s2440IIC->rIICSTAT = 0xf0;  //Start Master TX Condition    
  368.     s2440IIC->rIICCON = 0xaf;    //Clearing the pending bit isn't needed because the pending bit has been cleared.
  369.     while(_iicDataCount!=-1)
  370.        Run_IicPoll();
  371.     
  372. }
  373. void Run_IicPoll(void)
  374. {
  375.     if(s2440IIC->rIICCON & 0x10)                  //Tx/Rx Interrupt Enable
  376.         IicPoll();
  377. }       
  378. void IicPoll(void)
  379. {
  380.     U32 iicSt,i;
  381. /*    
  382.     iicSt = s2440IIC->rIICSTAT; 
  383.     if(iicSt & 0x8){}                   //When bus arbitration is failed.
  384.     if(iicSt & 0x4){}                   //When a slave address is matched with IICADD
  385.     if(iicSt & 0x2){}                   //When a slave address is 0000000b
  386.     if(iicSt & 0x1){}                   //When ACK isn't received
  387. */
  388.     switch(_iicMode)
  389.     {
  390.         case RDDATA:
  391.             if((_iicDataCount--)==0)
  392.             {
  393.                 _iicData[_iicPt++] = s2440IIC->rIICDS;
  394.             
  395.                 s2440IIC->rIICSTAT = 0x90;      //Stop MasRx condition 
  396.                 s2440IIC->rIICCON  = 0xaf;      //Resumes IIC operation.
  397.                 Delay(1);                 //Wait until stop condtion is in effect., Too long time... 
  398.                                                 //The pending bit will not be set after issuing stop condition.
  399.                 break;    
  400.             }      
  401.             _iicData[_iicPt++] = s2440IIC->rIICDS;     //The last data has to be read with no ack.
  402.             if((_iicDataCount)==0)
  403.                 s2440IIC->rIICCON = 0x2f;                 //Resumes IIC operation with NOACK in case of OV7620 Cameara  
  404.             else 
  405.                 s2440IIC->rIICCON = 0xaf;                 //Resumes IIC operation with ACK
  406.             break;
  407.         case WRDATA:
  408.             
  409.             if((_iicDataCount--)==0)
  410.             {
  411.                 s2440IIC->rIICSTAT = 0xd0;                //stop MasTx condition 
  412.                 s2440IIC->rIICCON  = 0xaf;                //resumes IIC operation.
  413.                 Delay(10);                        // we should adjust this time.
  414.                 //The pending bit will not be set after issuing stop condition.
  415.                 break;    
  416.             }
  417.             
  418.             s2440IIC->rIICDS = _iicData[_iicPt++];         //_iicData[0] has dummy.
  419.             
  420. //            for(i=0;i<20;i++);                   //for setup time until rising edge of IICSCL. we have to adjust this time.
  421. RETAILMSG(1,(TEXT("B")));
  422.             
  423.             s2440IIC->rIICCON = 0xaf;                      //resumes IIC operation.
  424.             
  425.             break;
  426.         case SETRDADDR:
  427.           RETAILMSG(1,(TEXT("[S%d]",_iicDataCount)));
  428.             if((_iicDataCount--)==0)
  429.             {
  430.                   s2440IIC->rIICSTAT = 0xd0;                //stop MasTx condition 
  431.          s2440IIC->rIICCON  = 0xaf;                //resumes IIC operation.
  432.                   Delay(1);      //wait until stop condtion is in effect.
  433.                   break;                  //IIC operation is stopped because of IICCON[4]    
  434.             }
  435.             s2440IIC->rIICDS = _iicData[_iicPt++];
  436.             for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL
  437.             s2440IIC->rIICCON = 0xaf;             //resumes IIC operation.
  438.             break;
  439.         default:
  440.             break;      
  441.     }
  442. }