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

Windows CE

开发平台:

Windows_Unix

  1. #include <windows.h>
  2. #include <Winbase.h>
  3. #include <s2440.h>
  4. #include <nkintr.h>
  5. #include <oalintr.h>
  6. #include <p2.h>
  7. #include "camif.h"
  8. #define U8 unsigned char
  9. #define U16 unsigned short
  10. #define U32 unsigned int
  11. #define CAM_OV7620 (0) // OMNI Vision camera, 640x480 VGA
  12. #define CAM_S5X433 (1) // Samsung S5X433 VGA camera
  13. #define CAM_S5X532 (2) // Samsung S5X532 VGA camera
  14. #define CAM_AU70H (3) // 1152x864 MegaPixel Camera, max 19.3Mhz
  15. #define CAM_S5X3A1 (4) // Mega pixel
  16. //#define SlaveID 0x42  //OV7620 Slave ID 
  17. #define SlaveID 0x5a  //S5X532 Slave ID 
  18. #define WRDATA      (1)
  19. #define RDDATA      (3)
  20. #define SETRDADDR   (4)
  21. #define CAMIICBUFSIZE 0x20
  22. #define IICBUFSIZE  0x20
  23. // Change GP8(I2CSDA) as input/output mode.
  24. #define SET_SDA_INPUT (s2440IOP->rGPECON &= ~(3<<30))
  25. #define SET_SDA_OUTPUT (s2440IOP->rGPECON = (s2440IOP->rGPECON & ~(2<<30)) |(1<<30) )
  26. static U8 _iicData[IICBUFSIZE];
  27. static volatile int _iicDataCount;
  28. static volatile int _iicStatus;
  29. static volatile int _iicMode;
  30. static int _iicPt;
  31. /*
  32. const unsigned char Ov7620_YCbCr8bit_TV[][2] = {
  33. // OMNI Vision
  34. {0x12, 0x80}, // Camera Soft reset. Self cleared after reset.
  35. {0x00, 0x00},
  36. {0x01, 0x80}, // set blue gain
  37. {0x02, 0x80}, // set red gain
  38. {0x03, 0xb0},
  39. {0x06, 0x60}, // set brightness
  40. {0x0c, 0x24}, // set blue background
  41. {0x0d, 0x24}, // set red background
  42. {0x10, 0xff}, // set exposure time, brightness control
  43. {0x11, 0x80}, // set frame rate CLK_input = PCLK
  44. {0x12, 0x74}, // set 8 Bit YUV mode, enable AGC/AWB, mirror image enabled.
  45. {0x13, 0x21},   // 8bit Data, CCIR601 Format
  46. {0x15, 0x01}, // Use PCLK falling edge to latch data, 8 Bit UYVY....
  47. {0x16, 0x03}, //
  48. {0x17, 0x2f}, //
  49. {0x18, 0xcf},        // (207-47)*4 = 640
  50. {0x19, 0x06}, //
  51. {0x1a, 0xf5},        // ((244-5)+1)*2=480
  52. {0x1b, 0x00},
  53. {0x20, 0x00},
  54. {0x21, 0x80},
  55. {0x22, 0x80},
  56. {0x23, 0x00},
  57. {0x26, 0xa2},
  58. {0x27, 0xea},
  59. {0x29, 0x00},
  60. {0x2a, 0x00},
  61. {0x2b, 0x00},
  62. {0x2c, 0x88},
  63. {0x2e, 0x80},
  64. {0x2f, 0x44},
  65. {0x60, 0x27},
  66. {0x61, 0x82},
  67. {0x62, 0x5f},
  68. {0x63, 0xd5},
  69. {0x64, 0x57},
  70. {0x65, 0x83},
  71. {0x66, 0x55},
  72. {0x68, 0xcf},
  73. {0x69, 0x76},
  74. {0x6a, 0x22},
  75. {0x6b, 0x00},
  76. {0x6c, 0x08},
  77. {0x6d, 0x48},
  78. {0x6e, 0x80},
  79. {0x6f, 0x0c},
  80. {0x70, 0x89},
  81. {0x71, 0x00},
  82. {0x72, 0x14},
  83. {0x73, 0x54},
  84. {0x75, 0x0e},
  85. {0x76, 0x00},
  86. {0x77, 0xff},
  87. {0x78, 0x80},
  88. {0x79, 0x80},
  89. {0x7a, 0x80},
  90. {0x7b, 0xe6},
  91. {0x7c, 0x00},
  92. {0x13, 0x21},
  93. {0x14, 0x94},
  94. {0x24, 0x10},
  95. {0x25, 0x8a},
  96. {0x28, 0x20}, // Progressive mode.
  97. {0x2d, 0x95}, //
  98. {0x67, 0x92}, // 
  99. {0x74, 0x00}, // -CJH
  100. {0x12, 0x74} // set 8 Bit YUV mode, enable AGC/AWB, mirror image enabled.
  101. };
  102. */
  103. const unsigned char S5X532_YCbCr8bit_TV[][2] = 
  104. {
  105. #if 0
  106. // page 5
  107. {0xec,0x05},
  108. {0x08,0x55},
  109. {0x0a,0x75},
  110. {0x0c,0x90},
  111. {0x0e,0x18},
  112. {0x12,0x09},
  113. {0x14,0x9d},
  114. {0x16,0x90},
  115. {0x1a,0x18},
  116. {0x1c,0x0c},
  117. {0x1e,0x09},
  118. {0x20,0x06},
  119. {0x22,0x20},
  120. {0x2a,0x00},
  121. {0x2d,0x04},
  122. {0x12,0x24},
  123. // page 3
  124. {0xec,0x03},
  125. {0x0c,0x09},
  126. {0x6c,0x09},
  127. {0x2b,0x10}, // momo clock inversion
  128. // page 2
  129. {0xec,0x02},
  130. {0x03,0x09},
  131. {0x05,0x08},
  132. {0x06,0x01},
  133. {0x07,0xf8},
  134. {0x15,0x25},
  135. {0x30,0x29},
  136. {0x36,0x12},
  137. {0x38,0x04},
  138. {0x1b,0x77}, // 24MHz : 0x77, 12MHz : 0x22
  139. {0x1c,0x77}, // 24MHz : 0x77, 12MHz : 0x22
  140. // page 1
  141. {0xec,0x01},
  142. {0x00,0x03}, // 
  143. {0x0a,0x08}, // 0x0-QQVGA, 0x06-CIF, 0x02-QCIF, 0x08-VGA, 0x04-QVGA, 0x0a-SXGA
  144. {0x0c,0x00}, // Pattern selectio. 0-CIS, 1-Color bar, 2-Ramp, 3-Blue screen
  145. //{0x10,0x27}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
  146. {0x10,0x21}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
  147. {0x50,0x21}, // Hblank
  148. {0x51,0x00}, // Hblank
  149. {0x52,0xA1}, // Hblank
  150. {0x53,0x02}, // Hblank
  151. {0x54,0x01}, // Vblank
  152. {0x55,0x00}, // Vblank
  153. {0x56,0xE1}, // Vblank 
  154. {0x57,0x01}, // Vblank
  155. {0x58,0x21}, // Hsync
  156. {0x59,0x00}, // Hsync
  157. {0x5a,0xA1}, // Hsync
  158. {0x5b,0x02}, // Hsync
  159. {0x5c,0x03}, // Vref
  160. {0x5d,0x00}, // Vref
  161. {0x5e,0x05}, // Vref
  162. {0x5f,0x00}, // Vref
  163. {0x70,0x0E},
  164. {0x71,0xD6},
  165. {0x72,0x30},
  166. {0x73,0xDB},
  167. {0x74,0x0E},
  168. {0x75,0xD6},
  169. {0x76,0x18},
  170. {0x77,0xF5},
  171. {0x78,0x0E},
  172. {0x79,0xD6},
  173. {0x7a,0x28},
  174. {0x7b,0xE6},
  175. {0x50,0x00},
  176. {0x5c,0x00},
  177. // page 0
  178. {0xec,0x00},
  179. {0x79,0x01},
  180. {0x58,0x90},
  181. {0x59,0xA0},
  182. {0x5a,0x50},
  183. {0x5b,0x70},
  184. {0x5c,0xD0},
  185. {0x5d,0xC0},
  186. {0x5e,0x28},
  187. {0x5f,0x08},
  188. {0x50,0x90},
  189. {0x51,0xA0},
  190. {0x52,0x50},
  191. {0x53,0x70},
  192. {0x54,0xD0},
  193. {0x55,0xC0},
  194. {0x56,0x28},
  195. {0x57,0x00},
  196. {0x48,0x90},
  197. {0x49,0xA0},
  198. {0x4a,0x50},
  199. {0x4b,0x70},
  200. {0x4c,0xD0},
  201. {0x4d,0xC0},
  202. {0x4e,0x28},
  203. {0x4f,0x08},
  204. {0x72,0x82}, // main clock = 24MHz:0xd2, 16M:0x82, 12M:0x54
  205. {0x75,0x05} // absolute vertical mirror.  junon
  206. #endif 
  207. #if 1
  208. {0xec,0x00},
  209. {0x02,0x00},
  210. {0x14,0x60},
  211. {0x15,0x60},
  212. {0x16,0x60},
  213. {0x1b,0x20},
  214. {0x1c,0x20},
  215. {0x1d,0x20},
  216. {0x1e,0x20},
  217. {0x72,0xdc},
  218. {0x73,0x11},
  219. {0x76,0x82},
  220. {0x77,0x90},
  221. {0x78,0x6c},
  222. {0x0a,0x02},
  223. {0x34,0x0d},
  224. {0x35,0x0a},
  225. {0x36,0x05},
  226. {0x37,0x05},
  227. {0x38,0x06},
  228. {0x39,0x08},
  229. {0x3A,0x0d},
  230. {0x3B,0x0d},
  231. {0x3C,0x18},
  232. {0x3D,0xE0},
  233. {0x3E,0x20},
  234. {0x66,0x02},
  235. {0x6c,0x40},
  236. {0x7c,0x01},
  237. {0x0D,0x24},
  238. {0x40,0x1B},
  239. {0x41,0x4F},
  240. {0x42,0x24},
  241. {0x43,0x3E},
  242. {0x44,0x32},
  243. {0x45,0x30},
  244. {0x48,0xa0},
  245. {0x49,0xd0},
  246. {0x4A,0x28},
  247. {0x4B,0x7d},
  248. {0x4C,0xd0},
  249. {0x4D,0xe0},
  250. {0x4E,0x1a},
  251. {0x4F,0xa0},
  252. {0x50,0xc0},
  253. {0x51,0xc0},
  254. {0x52,0x42},
  255. {0x53,0x7e},
  256. {0x54,0xc0},
  257. {0x55,0xf0},
  258. {0x56,0x1e},
  259. {0x57,0xe0},
  260. {0x58,0xc0},
  261. {0x59,0xa0},
  262. {0x5A,0x4a},
  263. {0x5B,0x7e},
  264. {0x5C,0xc0},
  265. {0x5D,0xf0},
  266. {0x5E,0x2a},
  267. {0x5F,0x10},
  268. {0x79,0x00},          
  269. {0x7a,0x00},
  270. {0xe0,0x0f},
  271. {0xe3,0x14}, 
  272. {0xe5,0x48},
  273. {0xe7,0x58},
  274. //=============== page1 ===============//
  275. {0xec,0x01},
  276. {0x10,0x05},
  277. {0x20,0xde},
  278. {0x0b,0x06},
  279. {0x30,0x00},
  280. {0x31,0x00},
  281. {0x32,0x00},
  282. {0x24,0x28},
  283. {0x25,0x3F},
  284. {0x26,0x65},
  285. {0x27,0xA1},
  286. {0x28,0xFF},
  287. {0x29,0x96},
  288. {0x2A,0x85},
  289. {0x2B,0xFF},
  290. {0x2C,0x00},
  291. {0x2D,0x1B},
  292. {0xB0,0x28},
  293. {0xB1,0x3F},
  294. {0xB2,0x65},
  295. {0xB3,0xA1},
  296. {0xB4,0xFF},
  297. {0xB5,0x96},
  298. {0xB6,0x85},
  299. {0xB7,0xFF},
  300. {0xB8,0x00},
  301. {0xB9,0x1B},
  302. {0x15,0x15},
  303. {0x18,0x85},
  304. {0x1f,0x05},
  305. {0x87,0x40},
  306. {0x37,0x60},
  307. {0x38,0xd5},
  308. {0x48,0xa0},
  309. {0x61,0x54},
  310. {0x62,0x54},
  311. {0x63,0x14},
  312. {0x64,0x14},
  313. {0x6d,0x12},
  314. {0x78,0x09},
  315. {0x79,0xD7},
  316. {0x7A,0x14},
  317. {0x7B,0xEE},
  318.                  
  319. //=============== page2 ===============//
  320. {0xec,0x02},
  321. {0x2c,0x76},
  322. {0x25,0x25},
  323. {0x27,0x27},
  324. {0x30,0x29},
  325. {0x36,0x08},
  326. {0x38,0x04},
  327. //=============== page3 ===============//
  328. {0xec,0x03},
  329. {0x08,0x00},
  330. {0x09,0x33},
  331. //=============== page4 ===============//
  332. {0xec,0x04},
  333. {0x00,0x21},
  334. {0x01,0x00},            
  335. {0x02,0x9d},            
  336. {0x03,0x02},            
  337. {0x04,0x04},         
  338. {0x05,0x00},            
  339. {0x06,0x1f},          
  340. {0x07,0x02},            
  341. {0x08,0x21},            
  342. {0x09,0x00},            
  343. {0x0a,0x9d},           
  344. {0x0b,0x02},            
  345. {0x0c,0x04},             
  346. {0x0d,0x00},            
  347. {0x0e,0x20},            
  348. {0x0f,0x02},            
  349. {0x1b,0x3c},            
  350. {0x1c,0x3c},            
  351. //=============== page5 ===============//
  352. {0xec,0x05},                               
  353. {0x1f,0x00},                               
  354. {0x08,0x59},            
  355. {0x0a,0x71},            
  356. {0x1e,0x23},            
  357. {0x0e,0x3c},            
  358. //=============== page7 ===============//
  359. {0xec,0x07},
  360. {0x11,0xfe},
  361. // added by junon
  362. {0xec,0x01}, 
  363. {0x10,0x26}, // 0x21-ITU-R656(CbYCrY), 0x25-ITU-R601(CbYCrY), 0x26-ITU-R601(YCrYCb)
  364. #endif
  365. };
  366. extern void Camera_Initialize(void);
  367. extern volatile IOPreg *s2440IOP;
  368. extern volatile IICreg *s2440IIC;
  369. void Camera_Initialize(void);
  370. void Delay(int time);
  371. void SetCAMClockDivider(int divn);
  372. void CAM_WriteBlock(void);
  373. void Wr_CamIIC(U32 slvAddr, U32 addr, U8 data);
  374. void Rd_CamIIC(U32 slvAddr, U32 addr, U8 *data);
  375. void Run_IicPoll(void);
  376. void IicPoll(void);
  377. static HANDLE IIC_InterruptEvent = NULL;
  378. void Camera_Initialize(void)
  379. {
  380. if (IIC_InterruptEvent == NULL)
  381. {
  382.     // allocate the interrupt event for IIC
  383.     IIC_InterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
  384.     
  385.     if (NULL == IIC_InterruptEvent) {
  386. RETAILMSG(1,(TEXT("IIC interrupt event Error1rn")));
  387.     }
  388.     // initialize the card insertion interrupt event
  389.     if (!InterruptInitialize (SYSINTR_IIC, IIC_InterruptEvent, NULL, 0)) {
  390. RETAILMSG(1,(TEXT("IIC interrupt event Error2rn")));
  391.     }
  392. }
  393. RETAILMSG(1,(TEXT("Use IIC for initializationrn")));
  394. // Use IIC for initialization
  395. CAM_WriteBlock();
  396. }
  397. void SetCAMClockDivider(int divn) // divn is even number 0~15
  398. {
  399. volatile CLKPWRreg *s2440PWR = (CLKPWRreg *)CLKPWR_BASE;
  400. s2440PWR->rCAMDIVN = (s2440PWR->rCAMDIVN & ~(0xf))|(0x10)|(divn); // CAMCLK is divided..
  401. // RETAILMSG(1,(TEXT("s2440PWR->rCLKCON:0x%xrn"),s2440PWR->rCLKCON));
  402. }
  403. void CAM_WriteBlock(void)
  404. {
  405.     unsigned int i, save_E, save_PE;
  406.     static U8 rdata[256]; 
  407.     int err = 0;
  408.       
  409.     save_E   = s2440IOP->rGPECON;
  410.     save_PE  = s2440IOP->rGPEUP;
  411.     s2440IOP->rGPEUP  &= ~0xc000;                   //Pull-up disable
  412.     s2440IOP->rGPEUP  |=  0xc000;                   //Pull-up disable
  413.     s2440IOP->rGPECON &= ~(0xF<<28);                //GPE15:IICSDA , GPE14:IICSCL    
  414.     s2440IOP->rGPECON |=  (0xa<<28);                //GPE15:IICSDA , GPE14:IICSCL    
  415.     //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
  416.     s2440IIC->rIICCON  = (1<<7) | (1<<6) | (1<<5) | (0xf);
  417.     s2440IIC->rIICADD  = 0x10;                     //2440 slave address = [7:1]. this is avialable when 240 is slave.
  418.     s2440IIC->rIICSTAT = 0x10;                     //IIC bus data output enable(Rx/Tx)
  419.     s2440IIC->rIICLC = (1<<2)|(3);   // Filter enable, 15 clocks SDA output delay     added into 2440
  420.   
  421.     for(i=0; i<(sizeof(S5X532_YCbCr8bit_TV)/2); i++){
  422.      //RETAILMSG(1,(TEXT("num:%drn"),i));
  423. Wr_CamIIC(SlaveID, S5X532_YCbCr8bit_TV[i][0], S5X532_YCbCr8bit_TV[i][1]);
  424. Sleep(1);
  425. }
  426.     RETAILMSG(1,(TEXT("Block TX Ended...rn")));
  427.     s2440IOP->rGPEUP  = save_PE;
  428.     s2440IOP->rGPECON = save_E;
  429. }
  430. void Wr_CamIIC(U32 slvAddr, U32 addr, U8 data)
  431. {
  432.     _iicMode      = WRDATA;
  433.     _iicPt        = 0;
  434.     _iicData[0]   = (U8)addr;
  435.     _iicData[1]   = data;
  436.     _iicDataCount = 2;
  437.     // write slave address
  438.     s2440IIC->rIICDS = slvAddr;  //0x42: OV7620 Slave ID 
  439.     // After this time, timing is critical, because IIC start.
  440.     s2440IIC->rIICSTAT = 0xf0;  //Start Master TX Condition    
  441.     s2440IIC->rIICCON = 0xef;    //Clearing the pending bit isn't needed because the pending bit has been cleared.
  442.     while(_iicDataCount!=-1)
  443.        Run_IicPoll();
  444.     
  445. }
  446. 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;        
  447.     // write slave address
  448.     s2440IIC->rIICDS = slvAddr;  //0x42: OV7620 Slave ID 
  449.     // After this time, timing is critical, because IIC start.
  450.     s2440IIC->rIICSTAT = 0xf0;  //Start Master TX Condition    
  451.     s2440IIC->rIICCON = 0xef;    //Clearing the pending bit isn't needed because the pending bit has been cleared.
  452.     while(_iicDataCount!=-1)
  453.        Run_IicPoll();
  454.     _iicMode      = RDDATA;
  455.     _iicPt        = 0;
  456.     _iicDataCount = 1;
  457.     
  458.     s2440IIC->rIICDS   = slvAddr;
  459.     s2440IIC->rIICSTAT = 0xb0;                    //Master Rx,Start
  460.     s2440IIC->rIICCON  = 0xef;                    //Resumes IIC operation. 
  461.     while(_iicDataCount!=-1)
  462.        Run_IicPoll();
  463. *data = _iicData[1];    
  464. //RETAILMSG(1,(TEXT("Data:0x%xrn"),_iicData[1]));
  465. }
  466. void Run_IicPoll(void)
  467. {
  468. DWORD waitStatus;
  469. // When using Interrupt mode
  470. waitStatus = WaitForSingleObject(IIC_InterruptEvent, INFINITE);
  471. // When using polling mode
  472. //    if(s2440IIC->rIICCON & 0x10)                  //Tx/Rx Interrupt Enable
  473.         IicPoll();
  474. }       
  475. void IicPoll(void)
  476. {
  477.     volatile U32 i;
  478. //RETAILMSG(1,(TEXT("IIC Interrupt occurrn")));
  479.     switch(_iicMode)
  480.     {
  481.         case RDDATA:
  482.             if((_iicDataCount--)==0)
  483.             {
  484.                 _iicData[_iicPt++] = s2440IIC->rIICDS;
  485.             
  486.                 s2440IIC->rIICSTAT = 0x90;      //Stop MasRx condition 
  487.                 s2440IIC->rIICCON  = 0xef;      //Resumes IIC operation.
  488.                 Delay(10);                 //Wait until stop condtion is in effect., Too long time... 
  489.                                                 //The pending bit will not be set after issuing stop condition.
  490.                 break;    
  491.             }      
  492.             _iicData[_iicPt++] = s2440IIC->rIICDS;     //The last data has to be read with no ack.
  493.             if((_iicDataCount)==0)
  494.                 s2440IIC->rIICCON = 0x6f;                 //Resumes IIC operation with NOACK in case of OV7620 Cameara  
  495.             else 
  496.                 s2440IIC->rIICCON = 0xef;                 //Resumes IIC operation with ACK
  497.             break;
  498.         case WRDATA:
  499.             if((_iicDataCount--)==0)
  500.             {
  501.                 s2440IIC->rIICSTAT = 0xd0;                //stop MasTx condition 
  502.                 s2440IIC->rIICCON  = 0xef;                //resumes IIC operation.
  503.                 Delay(10);                        // we should adjust this time.
  504.                 
  505.                 //The pending bit will not be set after issuing stop condition.
  506.                 break;    
  507.             }
  508.           
  509.             s2440IIC->rIICDS = _iicData[_iicPt++];         //_iicData[0] has dummy.
  510.             //for setup time until rising edge of IICSCL. we have to adjust this time.
  511. Delay(10);
  512.             //for(i=0;i<1000;i++);
  513. // IICDS has to be written before clearing the IIC interrupt pending bit
  514. //RETAILMSG(1,(TEXT("BB"))); // we should adjust this time.
  515.             
  516.             s2440IIC->rIICCON = 0xef;                      //resumes IIC operation.
  517.             
  518.             break;
  519.         case SETRDADDR:
  520.             if((_iicDataCount--)==0)
  521.             {
  522.                   s2440IIC->rIICSTAT = 0xd0;                //stop MasTx condition 
  523.            s2440IIC->rIICCON  = 0xef;                //resumes IIC operation.
  524.                   Delay(1);      //wait until stop condtion is in effect.
  525.                   
  526.                   
  527.                   break;                  //IIC operation is stopped because of IICCON[4]    
  528.             }
  529.             s2440IIC->rIICDS = _iicData[_iicPt++];
  530. Delay(10); 
  531. //for(i=0;i<1000;i++);          //for setup time until rising edge of IICSCL
  532.             //RETAILMSG(1,(TEXT("RD"))); // we should adjust this time.
  533.             s2440IIC->rIICCON = 0xef;             //resumes IIC operation.
  534.             break;
  535.         default:
  536.             break;      
  537.     }
  538.     
  539.     InterruptDone(SYSINTR_IIC);
  540. }
  541. void Delay(int time)
  542. {
  543.     volatile int i;
  544.     
  545.     for(;time>0;time--)
  546.         for(i=0;i<100;i++);
  547. }