i2c.c

来自「TVP5150 视频解码芯片驱动包含I2C模拟 VDSP环境」· C语言 代码 · 共 395 行

C
395
字号
#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 <state>
void SetSDATA(bool state);						//  Set SDATA to <state>
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 <state>.
//------------------------------------------------------------------------------
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 <state>.
//------------------------------------------------------------------------------
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:
	}
	
}

⌨️ 快捷键说明

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