www.pudn.com > 8202S.rar > c_i2c.c


/*================================================================= 
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: _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: _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;loopACK__ 
// 
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;loopACK____ 
// 
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