⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_i2c.c

📁 Sunplus 8202S source code.
💻 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: _<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%x\n",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%x\n",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%x\n",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%x\n",addr);
       //  ddc_stop_sig();  
         }

	//ddc_init_io_iop();

	 return data;
}

#endif//#if defined(DVI_I2C_SET)&&defined(SPHE8202)


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -