c_i2c.c
上传用户:poi891205
上传日期:2013-07-15
资源大小:9745k
文件大小:10k
源码类别:

DVD

开发平台:

C/C++

  1. /*=================================================================
  2. c_i2c.c: 
  3. Description:
  4. This is a C implement of i2c.Compare to the previous IOP 
  5. implement,it is more fast and easy to modify by programer.
  6. On the other hand,it consume more system time.So,delay must 
  7. be carefully considered.
  8. This code is currently use by HD DVD,for we need such a high
  9. speed I2C interface to initialize SPV311 and maintain the HDCP
  10. protocol.
  11. Read/Write operation for 24C02 is also using this way in HD 
  12. DVD case.For some types of 24C02 may not work well in high 
  13. speed,engineer should adjust some timming to improve the 
  14. capability. 
  15. huziqin 2004-11-23
  16. ================================================================*/
  17. #define K_loopMax 200//
  18. #ifdef SPHE8202
  19. #define I2C_SDA 56  /*pin 200*/
  20. #define I2C_SCL 51  /*pin 194*/  
  21. #else
  22. #define I2C_SDA 1 // GPIOE[0]
  23. #define I2C_SCL 0 // GPIOE[1]
  24. #endif
  25. #ifdef SPHE8202
  26.     #define DDC_SDA 44  
  27.     #define DDC_SCL 43  
  28. #else
  29. #error define
  30. #define DDC_SDA // GPIOE[0]
  31. #define DDC_SCL // GPIOE[1]
  32. #endif
  33. //======================================================
  34. #define I2C_PULL_HIGH//Addedd by ChenZhao on 2004-10-13 13:59  
  35. #define I2C_SCL_SET(d) GPIO_O_SET(I2C_SCL,d)
  36. #define I2C_SDA_SET(d) GPIO_O_SET(I2C_SDA,d)
  37. #define I2C_SDA_GET() GPIO_I_GET(I2C_SDA)
  38. #define I2C_SCL_IN() GPIO_E_SET(I2C_SCL,0)
  39. #define I2C_SDA_IN() GPIO_E_SET(I2C_SDA,0)
  40. #define I2C_SCL_OUT() GPIO_E_SET(I2C_SCL,1)
  41. #define I2C_SDA_OUT() GPIO_E_SET(I2C_SDA,1)
  42. #ifdef I2C_PULL_HIGH
  43.     #define I2C_SDA_H()     GPIO_E_SET(I2C_SDA,0)
  44.     #define I2C_SDA_L()     {I2C_SDA_SET(0);GPIO_E_SET(I2C_SDA,1);}
  45.     #define I2C_SCL_H()     GPIO_E_SET(I2C_SCL,0)
  46.     #define I2C_SCL_L()     {I2C_SCL_SET(0);GPIO_E_SET(I2C_SCL,1);}
  47. #else
  48.     #define I2C_SDA_H()     {I2C_SDA_SET(1);GPIO_E_SET(I2C_SDA,1);}
  49.     #define I2C_SDA_L()     {I2C_SDA_SET(0);GPIO_E_SET(I2C_SDA,1);}
  50.     #define I2C_SCL_H()     {I2C_SCL_SET(1);GPIO_E_SET(I2C_SCL,1);}
  51.     #define I2C_SCL_L()     {I2C_SCL_SET(0);GPIO_E_SET(I2C_SCL,1);}
  52. #endif//I2C_PULL_HIGH
  53. #define DDC_PULL_HIGH//Addedd by ChenZhao on 2004-10-13 13:59  
  54. #define DDC_SCL_SET(d) GPIO_O_SET(DDC_SCL,d)
  55. #define DDC_SDA_SET(d) GPIO_O_SET(DDC_SDA,d)
  56. #define DDC_SDA_GET() GPIO_I_GET(DDC_SDA)
  57. #define DDC_SCL_IN() GPIO_E_SET(DDC_SCL,0)
  58. #define DDC_SDA_IN() GPIO_E_SET(DDC_SDA,0)
  59. #define DDC_SCL_OUT() GPIO_E_SET(DDC_SCL,1)
  60. #define DDC_SDA_OUT() GPIO_E_SET(DDC_SDA,1)
  61. #ifdef DDC_PULL_HIGH
  62.     #define DDC_SDA_H()     GPIO_E_SET(DDC_SDA,0)
  63.     #define DDC_SDA_L()     {DDC_SDA_SET(0);GPIO_E_SET(DDC_SDA,1);}
  64.     #define DDC_SCL_H()     GPIO_E_SET(DDC_SCL,0)
  65.     #define DDC_SCL_L()     {DDC_SCL_SET(0);GPIO_E_SET(DDC_SCL,1);}
  66. #else
  67.     #define DDC_SDA_H()     {DDC_SDA_SET(1);GPIO_E_SET(DDC_SDA,1);}
  68.     #define DDC_SDA_L()     {DDC_SDA_SET(0);GPIO_E_SET(DDC_SDA,1);}
  69.     #define DDC_SCL_H()     {DDC_SCL_SET(1);GPIO_E_SET(DDC_SCL,1);}
  70.     #define DDC_SCL_L()     {DDC_SCL_SET(0);GPIO_E_SET(DDC_SCL,1);}
  71. #endif//DDC_PULL_HIGH
  72. void i2c_init_io_risc();
  73. void i2c_init_io_iop();
  74. void i2c_start_sig();
  75. void i2c_stop_sig();
  76. int i2c_byte_w(int data);
  77. void i2c_stop(void);
  78. void init_i2c(void);
  79. unsigned char i2c_byte_r();
  80. void write_i2c(unsigned char addr, unsigned char  aa, unsigned char  data);
  81. unsigned char read_i2c(unsigned char addr, unsigned char aa);
  82. static void ddc_start_sig();
  83. static int ddc_byte_w(int data);
  84. static void ddc_stop_sig();
  85. static void ddc_stop(void);
  86. static void init_ddc(void);
  87. void write_ddc(unsigned char addr, unsigned char  aa, unsigned char  data);
  88. static unsigned char ddc_byte_r();
  89. unsigned char read_ddc(unsigned char addr, unsigned char aa);
  90. static void delay_gpio(int i)
  91. {
  92.   do {
  93.     
  94.     int j =6;//kevin change add it to 100 it should be also OK if setted to 2 without HDCP
  95.     do {
  96.       asm volatile ("nop");
  97.     } while (--j>=0);
  98.   } while (--i>=0);
  99. }
  100. #define delay_i2c(i) delay_gpio(i)
  101. #define i2c_delay()   delay_i2c(1)
  102. #define delay_ddc(i) delay_gpio(i)
  103. #define ddc_delay()   delay_ddc(1)
  104. //
  105. // i2c_start_sig()
  106. // SCL: --
  107. // SDA: -_
  108. //
  109. void i2c_start_sig()
  110. {
  111. I2C_SCL_H();
  112. I2C_SDA_H();
  113. delay_i2c(1);
  114.     I2C_SDA_L();
  115. delay_i2c(1);
  116.     
  117. }
  118. //
  119. // i2c_byte_w(data)
  120. // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
  121. // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK__
  122. //
  123. int i2c_byte_w(int data)
  124. { int i;
  125. I2C_SCL_L()
  126. delay_i2c(1);
  127. for(i=8;i;i--)
  128. { if(data&0x80){I2C_SDA_H();}
  129. else {I2C_SDA_L();}
  130. delay_i2c(1); // scl -- low
  131. I2C_SCL_H(); delay_i2c(1); //hawk // scl -> high
  132. data<<=1;
  133. I2C_SCL_L(); delay_i2c(1); // scl -> low
  134. }
  135. // Get ACK
  136. I2C_SDA_IN();  delay_i2c(1); // scl -- low
  137. I2C_SCL_H(); delay_i2c(1); // scl -> high
  138. i= I2C_SDA_GET(); // 0 for no error
  139. //printf(" state=%d  ",i);
  140. I2C_SCL_L(); delay_i2c(1); // scl -> low
  141. return ((i)?1:0);
  142. }
  143. //
  144. // i2c_stop_sig()
  145. // SCL: _/-
  146. // SDA: __/
  147. //
  148. void i2c_stop_sig()
  149. { I2C_SDA_L(); I2C_SCL_L();delay_i2c(1);
  150. I2C_SCL_H(); delay_i2c(1);
  151. I2C_SDA_H();
  152. }
  153. void i2c_stop(void)
  154. {
  155.     I2C_SCL_L();
  156.     I2C_SDA_L();
  157. i2c_delay();
  158. I2C_SCL_H();
  159. i2c_delay();
  160. I2C_SDA_H();
  161. i2c_delay();
  162. I2C_SCL_L();
  163.   i2c_delay();
  164. I2C_SCL_H();
  165. I2C_SDA_H();
  166. }
  167. void init_i2c(void)
  168. {
  169.        I2C_SCL_H();
  170.        I2C_SDA_H();
  171.        i2c_delay();
  172.        i2c_stop();
  173. }
  174. //
  175. // i2c_byte_r()
  176. // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
  177. // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK____
  178. //
  179. unsigned char i2c_byte_r()
  180. { int i;
  181.       unsigned char data=0;
  182. I2C_SCL_L();
  183. I2C_SDA_IN(); delay_i2c(1); // scl -> low
  184. for(i=8;i;i--)
  185. { I2C_SCL_IN(); delay_i2c(1); // scl -> high
  186. data = (data<<1) | (I2C_SDA_GET() ? 1 : 0);
  187. I2C_SCL_L(); delay_i2c(1); // scl -> low
  188. }
  189. // Set ACK !!
  190. I2C_SDA_H(); // scl -- low
  191. delay_i2c(1); // scl -- low
  192. I2C_SCL_H(); delay_i2c(1); // scl -> high
  193. I2C_SCL_L(); delay_i2c(1); // scl -> low
  194. return data;
  195. }
  196.  void write_i2c(unsigned char addr, unsigned char  aa, unsigned char  data)
  197. { int ret=0;
  198. // Write Addr & DATA
  199. unsigned char loop;
  200. //i2c_init_io_risc();
  201. for (loop=0;loop<K_loopMax;loop++)
  202. {
  203. ret=0;
  204. init_i2c();
  205. i2c_start_sig();
  206. ret+=i2c_byte_w(addr); //W add data(addr<<1|0); //W add data
  207.         if(ret)  continue;
  208. ret+=i2c_byte_w(aa);
  209. if(ret)  continue;
  210. ret+=i2c_byte_w(data);
  211. if(ret)  continue;
  212. i2c_stop_sig();  
  213. break;
  214. }
  215. // if (loop == K_loopMax) 
  216. // {printf("t I2C Write error  ");printf("Sub-addr 0x%xn",addr);}
  217. //i2c_init_io_iop();
  218. }
  219. unsigned char read_i2c(unsigned char addr, unsigned char aa)
  220. {
  221. int ret=0;
  222. unsigned char data=0;
  223. // Write ADDR
  224. unsigned char loop;
  225. //i2c_init_io_risc();
  226. for (loop=0;loop<K_loopMax;loop++)
  227. {
  228. ret=0;
  229. init_i2c();
  230. i2c_start_sig();
  231. ret+=i2c_byte_w(addr); //W add
  232. if(ret)  continue;
  233. ret+=i2c_byte_w(aa);
  234. if(ret)  continue;
  235. // i2c_stop_sig();  
  236. // Read DATA
  237. i2c_start_sig();
  238. ret+=i2c_byte_w(addr|1); //R data
  239. if(ret)  continue;
  240. //{
  241. //printf("read_i2c error!n");
  242. //}
  243. // else
  244. // printf("read ok!n");
  245. data=i2c_byte_r();
  246. i2c_stop_sig();  
  247. break;
  248. }
  249. // if (loop == K_loopMax) {printf("t I2C Read error  ");printf("Sub-addr 0x%xn",addr);}
  250. //i2c_init_io_iop();
  251.  return data;
  252. }
  253. //
  254. // ddc_start_sig()
  255. // SCL: --
  256. // SDA: -_
  257. //
  258. static void ddc_start_sig()
  259. {
  260. DDC_SCL_H();
  261. DDC_SDA_H();
  262. delay_ddc(1);
  263.     DDC_SDA_L();
  264. delay_ddc(1);
  265.     
  266. }
  267. //
  268. // ddc_byte_w(data)
  269. // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
  270. // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK__
  271. //
  272. static int ddc_byte_w(int data)
  273. { int i;
  274. DDC_SCL_L()
  275. delay_ddc(1);
  276. for(i=8;i;i--)
  277. { if(data&0x80){DDC_SDA_H();}
  278. else {DDC_SDA_L();}
  279. delay_ddc(1); // scl -- low
  280. DDC_SCL_H(); delay_ddc(1); //hawk // scl -> high
  281. data<<=1;
  282. DDC_SCL_L(); delay_ddc(1); // scl -> low
  283. }
  284. // Get ACK
  285. DDC_SDA_IN();  delay_ddc(1); // scl -- low
  286. DDC_SCL_H(); delay_ddc(1); // scl -> high
  287. i= DDC_SDA_GET(); // 0 for no error
  288. //printf(" state=%d  ",i);
  289. DDC_SCL_L(); delay_ddc(1); // scl -> low
  290. return ((i)?1:0);
  291. }
  292. //
  293. // ddc_stop_sig()
  294. // SCL: _/-
  295. // SDA: __/
  296. //
  297. static void ddc_stop_sig()
  298. { DDC_SDA_L(); DDC_SCL_L();delay_ddc(1);
  299. DDC_SCL_H(); delay_ddc(1);
  300. DDC_SDA_H();
  301. }
  302. static void ddc_stop(void)
  303. {
  304.     DDC_SCL_L();
  305.     DDC_SDA_L();
  306. ddc_delay();
  307. DDC_SCL_H();
  308. ddc_delay();
  309. DDC_SDA_H();
  310. ddc_delay();
  311. DDC_SCL_L();
  312.   ddc_delay();
  313. DDC_SCL_H();
  314. DDC_SDA_H();
  315. }
  316. static void init_ddc(void)
  317. {
  318.        DDC_SCL_H();
  319.        DDC_SDA_H();
  320.        ddc_delay();
  321.        ddc_stop();
  322. }
  323. void write_ddc(unsigned char addr, unsigned char  aa, unsigned char  data)
  324. {
  325.     int ret;
  326. // Write Addr & DATA
  327. unsigned char loop;
  328. //ddc_init_io_risc();
  329. for (loop=0;loop<K_loopMax;loop++)
  330. {
  331. init_ddc();
  332. ddc_start_sig();
  333. ret=ddc_byte_w(addr); //W add data(addr<<1|0); //W add data
  334.         if(ret)  continue;
  335. ret=ddc_byte_w(aa);
  336. if(ret)  continue;
  337. ret=ddc_byte_w(data);
  338. if(ret)  continue;
  339. ddc_stop_sig();  
  340. break;
  341. }
  342. // if (loop == K_loopMax) 
  343.          {
  344.       //   printf("t DDC Write error  ");printf("Sub-addr 0x%xn",addr);
  345.       //    ddc_stop_sig();  
  346.          }
  347. //ddc_init_io_iop();
  348. }
  349. //
  350. // ddc_byte_r()
  351. // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
  352. // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK____
  353. //
  354. static unsigned char ddc_byte_r()
  355. { int i;
  356.       unsigned char data=0;
  357. DDC_SCL_L();
  358. DDC_SDA_IN(); delay_ddc(1); // scl -> low
  359. for(i=8;i;i--)
  360. { DDC_SCL_IN(); delay_ddc(1); // scl -> high
  361. data = (data<<1) | (DDC_SDA_GET() ? 1 : 0);
  362. DDC_SCL_L(); delay_ddc(1); // scl -> low
  363. }
  364. // Set ACK !!
  365. DDC_SDA_H(); // scl -- low
  366. delay_ddc(1); // scl -- low
  367. DDC_SCL_H(); delay_ddc(1); // scl -> high
  368. DDC_SCL_L(); delay_ddc(1); // scl -> low
  369. return data;
  370. }
  371. unsigned char read_ddc(unsigned char addr, unsigned char aa)
  372. {
  373. int ret;
  374. unsigned char data=0;
  375. // Write ADDR
  376. unsigned char loop;
  377. //ddc_init_io_risc();
  378. for (loop=0;loop<K_loopMax;loop++)
  379. {
  380. init_ddc();
  381. ddc_start_sig();
  382. ret=ddc_byte_w(addr); //W add
  383. if(ret)  continue;
  384. ret=ddc_byte_w(aa);
  385. if(ret)  continue;
  386. // ddc_stop_sig();  
  387. // Read DATA
  388. ddc_start_sig();
  389. ret=ddc_byte_w(addr|1); //R data
  390. if(ret)  continue;
  391. data=ddc_byte_r();
  392. ddc_stop_sig();  
  393. break;
  394. }
  395.  //if (loop == K_loopMax) 
  396.          {
  397.        //  printf("t DDC Read error  ");printf("Sub-addr 0x%xn",addr);
  398.        //  ddc_stop_sig();  
  399.          }
  400. //ddc_init_io_iop();
  401.  return data;
  402. }