www.pudn.com > PPI.rar > I2C.c


#include "I2C.h" 
/*------------------------------------------------------------------------------ 
// I2C Peripheral Function Prototypes 
//------------------------------------------------------------------------------ 
void Init(void);								//  Initialize I2C port 
void Start(void);								//  Sends I2C Start Trasfer 
void Stop(void);								//  Sends I2C Stop Trasfer 
bool Write(unsigned char data_out);				//  Writes data over the I2C bus 
bool Read(unsigned char *data_in, bool send_ack);// Reads data from the I2C bus 
void SetSCLK(bool state);						//  Set SCLK to  
void SetSDATA(bool state);						//  Set SDATA to  
bool GetSDATA();								//  Get SDATA state 
*/ 
//------------------------------------------------------------------------------ 
// I2C Peripheral Variables 
//------------------------------------------------------------------------------ 
 
unsigned int Delay = 0x00000000; 
unsigned char IdentAddr = 0x0; 
 
//------------------------------------------------------------------------------ 
// I2C Functions - Master 
//------------------------------------------------------------------------------ 
 
//------------------------------------------------------------------------------ 
// 	Routine:	Init 
//	Inputs:		none 
//	Outputs:	none 
//	Purpose:	Initialize I2C for the ADu812C 
//------------------------------------------------------------------------------ 
void INL Init(void) 
{ 
	*pFIO_DIR	|=  SCLK;		// Set SCLK as output and SDATA as input/high 
	*pFIO_POLAR	&= ~SDATA;		// Enable Active Hight 
	*pFIO_EDGE	&= ~SDATA;		// Enable Level Sensitivity 
	*pFIO_INEN	|=  SDATA;		// Enable SDATA Input Buffer 
	SetSDATA(1);				// Set SDATA as input/high 
	SetSCLK(1);					// Set SCLK high 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	Start 
//	Inputs:		none 
//	Outputs:	none 
//	Purpose:	Sends I2C Start Trasfer - "S" 
//------------------------------------------------------------------------------ 
void INL Start(void) 
{ 
//	11182003 - Following line has been added! (Fixed thanks to Andrew Seddon). 
//			   Shouldn't Stop() be setting SCLK high? 
	SetSCLK(1);					// Set SCLK high 
	SetSDATA(0);				// Set SDATA output/low 
	SetSCLK(0);					// Set SCLK low 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	Stop 
//	Inputs:		none 
//	Outputs:	none 
//	Purpose:	Sends I2C Stop Trasfer - "P" 
//------------------------------------------------------------------------------ 
void INL Stop(void) 
{ 
	SetSDATA(0);				// Set SDATA output/low 
	SetSCLK(1);					// Set SCLK high 
	SetSDATA(1);				// Set SDATA as input/high 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	Write 
//	Inputs:		data_out 
//	Outputs:	bool 
//	Purpose:	Writes data over the I2C bus and return status. 
//------------------------------------------------------------------------------ 
bool INL Write(unsigned char data_out) 
{ 
	unsigned char index; 
 
	// An I2C output byte is bits 7-0 (MSB to LSB). Shift one bit at a time to 
	// the SDATA output, and then clock the data to the I2C Slave device. 
 
	// Send 8 bits out the port	 
	for(index = 0; index < 8; index++) 
	{ 
		// Output the data bit to the device 
		SetSDATA(((data_out & 0x80) ? 1 : 0)); 
 
		data_out <<= 1;						// Shift the byte by one bit 
		SetSCLK(1);							// Set SCLK high 
		SetSCLK(0);							// Set SCLK low 
	} 
 
	SetSDATA(1);							// Set SDATA input/high 
	SetSCLK(1);								// Set SCLK high 
 
	if (!GetSDATA()) 
	{ 
		SetSCLK(0);							// Set SCLK low 
		return true;						// ACK from slave 
	} else 
	{ 
		SetSCLK(0);							// Set SCLK low 
		return false;						// NACK from slave 
	} 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	Read 
//	Inputs:		*data_in, send_ack (if true send the ACK signal else send NACK) 
//	Outputs:	bool 
//	Purpose:	Reads data from the I2C bus and return it in data_in. 
//				Returns status. 
//------------------------------------------------------------------------------ 
bool INL Read(unsigned char *data_in, bool send_ack) 
{ 
	unsigned char index; 
 
	*data_in = 0x00; 
 
	SetSDATA(1);							// Set SDATA input/high 
	SetSCLK(0);								// Set SCLK low 
 
	// Get 8 bits from the device 
	for(index = 0; index < 8; index++) 
	{ 
		*data_in <<= 1;						// Shift the data right 1 bit 
		SetSCLK(1);							// Set SCLK high 
//		11182003 - Line moved... 
//		SetSCLK(0);							// Set SCLK low 
		*data_in |= GetSDATA();				// Read the data bit 
//		11182003 - to here! (Fixed thanks to Andrew Seddon). 
		SetSCLK(0);							// Set SCLK low 
	} 
 
	if (send_ack) 
		SetSDATA(0);		// Set data pin to output/low to ACK the read 
	else 
		SetSDATA(1);		// Set data pin to input/high to NACK the read 
 
	SetSCLK(1);								// Set SCLK high 
	SetSCLK(0);								// Set SCLK low 
	SetSDATA(0);							// Set SDATA output/low 
	SetSDATA(1);							// Set SDATA input/high 
 
	return true; 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	SetSDATA 
//	Inputs:		state 
//	Outputs:	none 
//	Purpose:	Set the I2C port SDATA pin to . 
//------------------------------------------------------------------------------ 
void INL SetSDATA(bool state) 
{ 
	unsigned int i, d; 
	 
	if (state) 
	{ 
		*pFIO_DIR	&=  ~SDATA;				// Set SDATA as input/high. 
	} else 
	{ 
		*pFIO_DIR	|=  SDATA;				// Set SDATA as output. 
		*pFIO_FLAG_D &= ~SDATA;				// Set SDATA low. 
	} 
 
	// Delay 
	for (i = 0; i < Delay; i++) { asm("nop;"); } 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	SetSCLK 
//	Inputs:		state 
//	Outputs:	none 
//	Purpose:	Set the I2C port SCLK pin to . 
//------------------------------------------------------------------------------ 
void INL SetSCLK(bool state) 
{ 
	unsigned int i, d; 
	 
	if (state) 
	{ 
		*pFIO_FLAG_D |= SCLK;				// Set SCLK high. 
	} else 
	{ 
		*pFIO_FLAG_D &= ~SCLK;				// Set SCLK low. 
	} 
 
	// Delay 
	for (i = 0; i < Delay; i++) { asm("nop;"); } 
} 
//------------------------------------------------------------------------------ 
// 	Routine:	GetSDATA 
//	Inputs:		none 
//	Outputs:	bool 
//	Purpose:	Get the I2C port SDATA pin state. 
//------------------------------------------------------------------------------ 
bool INL GetSDATA() 
{ 
	return ((*pFIO_FLAG_D & SDATA) ? 1 : 0);	 
} 
//------------------------------------------------------------------------------ 
// Procedure:	I2C_Init 
// Inputs:		identaddr 
// Outputs:		bool 
// Description:	Initialize I2C and setup Slave Ident Addr. then check the ident 
//				for response and returns true if ok. 
//------------------------------------------------------------------------------ 
bool I2C_Init(unsigned char identaddr) 
{ 
	bool ret; 
 
	// Calculate Delay NEED FIX!!! 
	Delay = ((*pPLL_CTL & 0x7e00) >> 9)*15; 
	//Delay = 0x1000; 
	if ((*pPLL_CTL & 0x0001) == 0x0001) 
		Delay /= 2; 
 
	IdentAddr = identaddr; 
 
	Init();								// Initialize I2C port 
	Start();							// Check Slave Ident Addr 
	ret = Write(IdentAddr); 
	Stop(); 
 
	return ret;							// Return true if Ident Addr. Ok 
} 
//------------------------------------------------------------------------------ 
// Procedure:	I2C_Write 
// Inputs:		data out, address 
// Outputs:		bool 
// Description:	Writes a byte to the given address and return status. 
//------------------------------------------------------------------------------ 
extern bool I2C_Write(unsigned char data_out, unsigned char address) 
{ 
	Start();	// Send start signal 
	if (!Write(IdentAddr))				// Send identifier I2C address 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	if (!Write(address))				// Send address to device 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	if (!Write(data_out))				// Send byte to device 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	Stop();								// Send I2C Stop Transfer 
//	DelayTVP5150(); 
	return true; 
} 
//------------------------------------------------------------------------------ 
// Procedure:	I2C_Read 
// Inputs:		*data_in, address 
// Outputs:		bool 
// Description:	Reads a byte from the given address and return status. 
//------------------------------------------------------------------------------ 
bool I2C_Read(unsigned char *data_in, unsigned char address) 
{ 
	Start();							// Send start signal 
	if (!Write(IdentAddr))				// Send identifer I2C address 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	if (!Write(address))				// Send address to device 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	Start();							// Send I2C Start Transer 
	if (!Write(IdentAddr+1))			// Send identifer I2C address 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	if (!Read(data_in, false))			// Read byte 
	{ 
		Stop();							// Send I2C Stop Transfer 
		return false; 
	} 
	DelayTVP5150(); 
	Stop();								// Send I2C Stop Transfer 
 
	return true; 
} 
 
void INL DelayTVP5150() 
{ 
	asm("p0.l=0x57C0;"); 
	asm("p0.h=0x1;"); 
	asm("lsetup(_delay_begin,_delay_end) lc0=p0;"); 
	asm("_delay_begin:"); 
	asm("_delay_end:"); 
	asm("nop;"); 
} 
//------------------------------------------------------------------------------ 
// Procedure:	TVP5150_Reset 
// Inputs:		bReset 
// Outputs:		bool 
// Description:	Reset TVP5150,bReset = 1 is reset  =0 is cancel 
//				returns true if ok. 
//Reset address is 0x05h 
//------------------------------------------------------------------------------ 
bool TVP5150_Reset(bool  bReset) 
{ 
	bool Status; 
	I2C_Init(0xB8);//0xBA for high I2CSEL 
	if(bReset){ 
		Status = I2C_Write(0x01,0x05); 
		return Status; 
	} 
	else return true; 
} 
//------------------------------------------------------------------------------ 
// Procedure:	TVP5150_Cnfg 
// Inputs: SourceMode£º 
//     			  0:from A Channel input the Composite analog Video signal 
//			      1:from B Channel input the Composite analog Video signal 
//			      2:from A and B Channel input luma and chroma signal 
//			      else: nothing 
//         OutputMode£º 
//       		  0:output ITU-R.BT601 PAL-N signal  625 
// 			      1:output ITU-R.BT601 PAL-M signal  625 
//			      2:output ITU-R.BT601 NTSC signal   525 
//			      3:output ITU-R.BT601 SECAM signal  625 
//			      4:output ITU-R.BT656 NTSC signal   525 
// 			      5:output ITU-R.BT656 PAL signal    625 
//		          other:not support 
// Outputs:		bool 
//     0=ok,1=error 
// Description:	 
//			Set TVP5150 signal input channel and output signal format. 
//			and set other correlative register 
//------------------------------------------------------------------------------ 
 
bool TVP5150_Cnfg(int  SourceMode, int  OutputMode) 
{ 
	bool Status; 
	//unsigned char temp; 
	switch(SourceMode){ 
		case 0: 
				Status = I2C_Write(0x0,0x0); 
			  break; 
		case 1: 
				Status = I2C_Write(0x02,0x0); 
			  break; 
		case 2: 
				Status = I2C_Write(0x01,0x0); 
			  break; 
		default: 
	} 
	switch(OutputMode){ 
		case 0: // 601 PAL-N 
			  Status = I2C_Write(0x0f,0x03); 
			  Status = I2C_Write(0xf4,0x04); 
			  Status = I2C_Write(0x40,0x0d); 
			  break; 
		case 1://601 PAL-M 
			  Status = I2C_Write(0x0f,0x03); 
			  Status = I2C_Write(0x0f,0x04); 
			  Status = I2C_Write(0x40,0x0d); 
			  break; 
		case 2://601 NTSC 
			  Status = I2C_Write(0x0f,0x03); 
			  Status = I2C_Write(0xec,0x04); 
			  Status = I2C_Write(0x40,0x0d); 
			  break; 
		case 3://601 SECAM 
			  Status = I2C_Write(0x0f,0x03); 
			  Status = I2C_Write(0xdc,0x04); 
			  Status = I2C_Write(0x40,0x0d); 
			  break; 
		case 4://656 NTSC 
			  Status = I2C_Write(0x29,0x03); 
			  Status = I2C_Write(0xec,0x04); 
			  Status = I2C_Write(0x47,0x0d); 
			  Status = I2C_Write(0x40,0x07);//insert ancilly header 
			  break; 
		case 5://656 PAL 
			  Status = I2C_Write(0x7f,0x03); 
		//	  Status = I2C_Write(0xc0,0x04); 
			  Status = I2C_Write(0x40,0x07);//insert ancilly header 
			  Status = I2C_Write(0x47,0x0d); 
			  Status = I2C_Write(0x0,0x0f); 
			  break; 
		default: 
	} 
	 
}