c_i2c.c
上传用户:caisangzi8
上传日期:2013-10-25
资源大小:15756k
文件大小:11k
源码类别:

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