c_i2c.c
上传用户:caisangzi8
上传日期:2013-10-25
资源大小:15756k
文件大小:11k
- /*=================================================================
- c_i2c.c:
- Description:
- This is a C implement of i2c.Compare to the previous IOP
- implement,it is more fast and easy to modify by programer.
- On the other hand,it consume more system time.So,delay must
- be carefully considered.
- This code is currently use by HD DVD,for we need such a high
- speed I2C interface to initialize SPV311 and maintain the HDCP
- protocol.
- Read/Write operation for 24C02 is also using this way in HD
- DVD case.For some types of 24C02 may not work well in high
- speed,engineer should adjust some timming to improve the
- capability.
- huziqin 2004-11-23
- ================================================================*/
- #include "config.h"
- #include "regmap.h"
- #include "global.h"
- #include "user_init.h"
- #include "gpio.h"
- #if defined(DVI_I2C_SET)&&defined(SPHE8202)
- #define K_loopMax 200//
- #ifdef SPHE8202
- #define I2C_SDA 56 /*pin 200*/
- #define I2C_SCL 51 /*pin 194*/
- #else
- #define I2C_SDA 1 // GPIOE[0]
- #define I2C_SCL 0 // GPIOE[1]
- #endif
- #ifdef SPHE8202
- #ifdef NEW_HDDVD_GPIO//add by chenzhao on 2004-12-14 16:11
- #define DDC_SDA 32
- #define DDC_SCL 33
- #else
- #define DDC_SDA 44
- #define DDC_SCL 43
- #endif
- #else
- #error define
- #define DDC_SDA // GPIOE[0]
- #define DDC_SCL // GPIOE[1]
- #endif
- //======================================================
- #define I2C_PULL_HIGH//Addedd by ChenZhao on 2004-10-13 13:59
- #define I2C_SCL_SET(d) GPIO_O_SET(I2C_SCL,d)
- #define I2C_SDA_SET(d) GPIO_O_SET(I2C_SDA,d)
- #define I2C_SDA_GET() GPIO_I_GET(I2C_SDA)
- #define I2C_SCL_IN() GPIO_E_SET(I2C_SCL,0)
- #define I2C_SDA_IN() GPIO_E_SET(I2C_SDA,0)
- #define I2C_SCL_OUT() GPIO_E_SET(I2C_SCL,1)
- #define I2C_SDA_OUT() GPIO_E_SET(I2C_SDA,1)
- #ifdef I2C_PULL_HIGH
- #define I2C_SDA_H() GPIO_E_SET(I2C_SDA,0)
- #define I2C_SDA_L() {I2C_SDA_SET(0);GPIO_E_SET(I2C_SDA,1);}
- #define I2C_SCL_H() GPIO_E_SET(I2C_SCL,0)
- #define I2C_SCL_L() {I2C_SCL_SET(0);GPIO_E_SET(I2C_SCL,1);}
- #else
- #define I2C_SDA_H() {I2C_SDA_SET(1);GPIO_E_SET(I2C_SDA,1);}
- #define I2C_SDA_L() {I2C_SDA_SET(0);GPIO_E_SET(I2C_SDA,1);}
- #define I2C_SCL_H() {I2C_SCL_SET(1);GPIO_E_SET(I2C_SCL,1);}
- #define I2C_SCL_L() {I2C_SCL_SET(0);GPIO_E_SET(I2C_SCL,1);}
- #endif//I2C_PULL_HIGH
- #define DDC_PULL_HIGH//Addedd by ChenZhao on 2004-10-13 13:59
- #define DDC_SCL_SET(d) GPIO_O_SET(DDC_SCL,d)
- #define DDC_SDA_SET(d) GPIO_O_SET(DDC_SDA,d)
- #define DDC_SDA_GET() GPIO_I_GET(DDC_SDA)
- #define DDC_SCL_IN() GPIO_E_SET(DDC_SCL,0)
- #define DDC_SDA_IN() GPIO_E_SET(DDC_SDA,0)
- #define DDC_SCL_OUT() GPIO_E_SET(DDC_SCL,1)
- #define DDC_SDA_OUT() GPIO_E_SET(DDC_SDA,1)
- #ifdef DDC_PULL_HIGH
- #define DDC_SDA_H() GPIO_E_SET(DDC_SDA,0)
- #define DDC_SDA_L() {DDC_SDA_SET(0);GPIO_E_SET(DDC_SDA,1);}
- #define DDC_SCL_H() GPIO_E_SET(DDC_SCL,0)
- #define DDC_SCL_L() {DDC_SCL_SET(0);GPIO_E_SET(DDC_SCL,1);}
- #else
- #define DDC_SDA_H() {DDC_SDA_SET(1);GPIO_E_SET(DDC_SDA,1);}
- #define DDC_SDA_L() {DDC_SDA_SET(0);GPIO_E_SET(DDC_SDA,1);}
- #define DDC_SCL_H() {DDC_SCL_SET(1);GPIO_E_SET(DDC_SCL,1);}
- #define DDC_SCL_L() {DDC_SCL_SET(0);GPIO_E_SET(DDC_SCL,1);}
- #endif//DDC_PULL_HIGH
- /*
- BIT 1 ; NORMAL I2C BUS ERR
- BIT 2 : DDC ERROR
- */
- BYTE i2c_err_flag = 0;
- void i2c_init_io_risc();
- void i2c_init_io_iop();
- void i2c_start_sig();
- void i2c_stop_sig();
- int i2c_byte_w(int data);
- void i2c_stop(void);
- void init_i2c(void);
- unsigned char i2c_byte_r();
- void write_i2c(unsigned char addr, unsigned char aa, unsigned char data);
- unsigned char read_i2c(unsigned char addr, unsigned char aa);
- static void ddc_start_sig();
- static int ddc_byte_w(int data);
- static void ddc_stop_sig();
- static void ddc_stop(void);
- static void init_ddc(void);
- void write_ddc(unsigned char addr, unsigned char aa, unsigned char data);
- static unsigned char ddc_byte_r();
- unsigned char read_ddc(unsigned char addr, unsigned char aa);
- static void delay_gpio(int i)
- {
- do {
-
- int j =6;//kevin change add it to 100 it should be also OK if setted to 2 without HDCP
- do {
- asm volatile ("nop");
- } while (--j>=0);
- } while (--i>=0);
- }
- #define delay_i2c(i) delay_gpio(i)
- #define i2c_delay() delay_i2c(1)
- #define delay_ddc(i) delay_gpio(i)
- #define ddc_delay() delay_ddc(1)
- //
- // i2c_start_sig()
- // SCL: --
- // SDA: -_
- //
- void i2c_start_sig()
- {
- I2C_SCL_H();
- I2C_SDA_H();
- delay_i2c(1);
- I2C_SDA_L();
- delay_i2c(1);
-
- }
- //
- // i2c_byte_w(data)
- // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
- // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK__
- //
- int i2c_byte_w(int data)
- { int i;
- I2C_SCL_L()
- delay_i2c(1);
- for(i=8;i;i--)
- { if(data&0x80){I2C_SDA_H();}
- else {I2C_SDA_L();}
- delay_i2c(1); // scl -- low
- I2C_SCL_H(); delay_i2c(1); //hawk // scl -> high
- data<<=1;
- I2C_SCL_L(); delay_i2c(1); // scl -> low
- }
- // Get ACK
- I2C_SDA_IN(); delay_i2c(1); // scl -- low
- I2C_SCL_H(); delay_i2c(1); // scl -> high
- i= I2C_SDA_GET(); // 0 for no error
- //printf(" state=%d ",i);
- I2C_SCL_L(); delay_i2c(1); // scl -> low
- return ((i)?1:0);
- }
- //
- // i2c_stop_sig()
- // SCL: _/-
- // SDA: __/
- //
- void i2c_stop_sig()
- { I2C_SDA_L(); I2C_SCL_L();delay_i2c(1);
- I2C_SCL_H(); delay_i2c(1);
- I2C_SDA_H();
- }
- void i2c_stop(void)
- {
- I2C_SCL_L();
- I2C_SDA_L();
- i2c_delay();
- I2C_SCL_H();
- i2c_delay();
- I2C_SDA_H();
- i2c_delay();
- I2C_SCL_L();
- i2c_delay();
- I2C_SCL_H();
- I2C_SDA_H();
- }
- void init_i2c(void)
- {
- I2C_SCL_H();
- I2C_SDA_H();
- i2c_delay();
- i2c_stop();
- }
- //
- // i2c_byte_r()
- // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
- // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK____
- //
- unsigned char i2c_byte_r()
- { int i;
- unsigned char data=0;
- I2C_SCL_L();
- I2C_SDA_IN(); delay_i2c(1); // scl -> low
- for(i=8;i;i--)
- { I2C_SCL_IN(); delay_i2c(1); // scl -> high
- data = (data<<1) | (I2C_SDA_GET() ? 1 : 0);
- I2C_SCL_L(); delay_i2c(1); // scl -> low
- }
- // Set ACK !!
- I2C_SDA_H(); // scl -- low
- delay_i2c(1); // scl -- low
- I2C_SCL_H(); delay_i2c(1); // scl -> high
- I2C_SCL_L(); delay_i2c(1); // scl -> low
- return data;
- }
- void write_i2c(unsigned char addr, unsigned char aa, unsigned char data)
- { int ret=0;
- // Write Addr & DATA
- unsigned char loop;
- //i2c_init_io_risc();
- for (loop=0;loop<K_loopMax;loop++)
- {
- ret=0;
- init_i2c();
- i2c_start_sig();
- ret+=i2c_byte_w(addr); //W add data(addr<<1|0); //W add data
- if(ret) continue;
- ret+=i2c_byte_w(aa);
- if(ret) continue;
- ret+=i2c_byte_w(data);
- if(ret) continue;
- i2c_stop_sig();
- break;
- }
- // if (loop == K_loopMax)
- // {printf("t I2C Write error ");printf("Sub-addr 0x%xn",addr);}
- //i2c_init_io_iop();
- }
- unsigned char read_i2c(unsigned char addr, unsigned char aa)
- {
- int ret=0;
- unsigned char data=0;
- // Write ADDR
- unsigned char loop;
- //i2c_init_io_risc();
- for (loop=0;loop<K_loopMax;loop++)
- {
- ret=0;
- init_i2c();
- i2c_start_sig();
- ret+=i2c_byte_w(addr); //W add
- if(ret) continue;
- ret+=i2c_byte_w(aa);
- if(ret) continue;
- // i2c_stop_sig();
- // Read DATA
- i2c_start_sig();
- ret+=i2c_byte_w(addr|1); //R data
- if(ret) continue;
- //{
- //printf("read_i2c error!n");
- //}
- // else
- // printf("read ok!n");
- data=i2c_byte_r();
- i2c_stop_sig();
- break;
- }
- // if (loop == K_loopMax) {printf("t I2C Read error ");printf("Sub-addr 0x%xn",addr);}
- //i2c_init_io_iop();
- return data;
- }
- //
- // ddc_start_sig()
- // SCL: --
- // SDA: -_
- //
- static void ddc_start_sig()
- {
- DDC_SCL_H();
- DDC_SDA_H();
- delay_ddc(1);
- DDC_SDA_L();
- delay_ddc(1);
-
- }
- //
- // ddc_byte_w(data)
- // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
- // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK__
- //
- static int ddc_byte_w(int data)
- { int i;
- DDC_SCL_L()
- delay_ddc(1);
- for(i=8;i;i--)
- { if(data&0x80){DDC_SDA_H();}
- else {DDC_SDA_L();}
- delay_ddc(1); // scl -- low
- DDC_SCL_H(); delay_ddc(1); //hawk // scl -> high
- data<<=1;
- DDC_SCL_L(); delay_ddc(1); // scl -> low
- }
- // Get ACK
- DDC_SDA_IN(); delay_ddc(1); // scl -- low
- DDC_SCL_H(); delay_ddc(1); // scl -> high
- i= DDC_SDA_GET(); // 0 for no error
- //printf(" state=%d ",i);
- DDC_SCL_L(); delay_ddc(1); // scl -> low
- return ((i)?1:0);
- }
- //
- // ddc_stop_sig()
- // SCL: _/-
- // SDA: __/
- //
- static void ddc_stop_sig()
- { DDC_SDA_L(); DDC_SCL_L();delay_ddc(1);
- DDC_SCL_H(); delay_ddc(1);
- DDC_SDA_H();
- }
- static void ddc_stop(void)
- {
- DDC_SCL_L();
- DDC_SDA_L();
- ddc_delay();
- DDC_SCL_H();
- ddc_delay();
- DDC_SDA_H();
- ddc_delay();
- DDC_SCL_L();
- ddc_delay();
- DDC_SCL_H();
- DDC_SDA_H();
- }
- static void init_ddc(void)
- {
- DDC_SCL_H();
- DDC_SDA_H();
- ddc_delay();
- ddc_stop();
- }
- void write_ddc(unsigned char addr, unsigned char aa, unsigned char data)
- {
- int ret;
- // Write Addr & DATA
- unsigned char loop;
- //ddc_init_io_risc();
- for (loop=0;loop<K_loopMax;loop++)
- {
- init_ddc();
- ddc_start_sig();
- ret=ddc_byte_w(addr); //W add data(addr<<1|0); //W add data
- if(ret) continue;
- ret=ddc_byte_w(aa);
- if(ret) continue;
- ret=ddc_byte_w(data);
- if(ret) continue;
- ddc_stop_sig();
- break;
- }
- // if (loop == K_loopMax)
- {
- // printf("t DDC Write error ");printf("Sub-addr 0x%xn",addr);
- // ddc_stop_sig();
- }
- //ddc_init_io_iop();
- }
- //
- // ddc_byte_r()
- // SCL: _/-_/-_/-_/-_/-_/-_/-_/-_/-_
- // SDA: _<D7><D6><D5><D4><D3><D2><D1><D0>ACK____
- //
- static unsigned char ddc_byte_r()
- { int i;
- unsigned char data=0;
- DDC_SCL_L();
- DDC_SDA_IN(); delay_ddc(1); // scl -> low
- for(i=8;i;i--)
- { DDC_SCL_IN(); delay_ddc(1); // scl -> high
- data = (data<<1) | (DDC_SDA_GET() ? 1 : 0);
- DDC_SCL_L(); delay_ddc(1); // scl -> low
- }
- // Set ACK !!
- DDC_SDA_H(); // scl -- low
- delay_ddc(1); // scl -- low
- DDC_SCL_H(); delay_ddc(1); // scl -> high
- DDC_SCL_L(); delay_ddc(1); // scl -> low
- return data;
- }
- unsigned char read_ddc(unsigned char addr, unsigned char aa)
- {
- int ret;
- unsigned char data=0;
- // Write ADDR
- unsigned char loop;
- //ddc_init_io_risc();
- for (loop=0;loop<K_loopMax;loop++)
- {
- init_ddc();
- ddc_start_sig();
- ret=ddc_byte_w(addr); //W add
- if(ret) continue;
- ret=ddc_byte_w(aa);
- if(ret) continue;
- // ddc_stop_sig();
- // Read DATA
- ddc_start_sig();
- ret=ddc_byte_w(addr|1); //R data
- if(ret) continue;
- data=ddc_byte_r();
- ddc_stop_sig();
- break;
- }
- if (loop == K_loopMax)
- {
- i2c_err_flag |= 0x02;
- // printf("t DDC Read error ");printf("Sub-addr 0x%xn",addr);
- // ddc_stop_sig();
- }
- //ddc_init_io_iop();
- return data;
- }
- #endif//#if defined(DVI_I2C_SET)&&defined(SPHE8202)