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

📄 ixdp2400i2c.c

📁 ixp2400 bsp for vxworks
💻 C
字号:
/*ixdp2400I2c.c - I2c protocol driver*//*modification history--------------------rev, 5apr02, vgd - creation*/#include "ixdp2400I2c.h"#include "ixdp2400.h"/*Function prototypes*/static void I2C_CLK(unsigned char x);static void I2C_DATA(unsigned char x);static void i2c_start(void);static void i2c_stop(void);static unsigned char i2c_ReadBit(void);static void i2c_WriteBit(unsigned char x);static void i2c_writebyte(unsigned char data);static unsigned char i2c_readbyte(void);unsigned char i2c_device_busy(unsigned char);/*i2c_ack_stat is 0 if there is no error.  *bit 0 is 1 if ack is not recd after writing slave address in write mode. *bit 1 is 1 if ack is not recd after writing word address,  *bit 2 is 1 if ack is not recd after writing slave address in read mode,  *bit 3 is 1 if ack not recd after sending a data byte. *//*************************************************************************Function Name	:	I2C_CLKInput			:	HIGH or LOWOutPut			:	NoneDesc			:	sets the SCL pin low or high**************************************************************************/static void I2C_CLK(unsigned char x){	int i = 5000;	int temp;	FAST int locKey;    locKey = intLock ();	switch(x)	{		/*To drive the clock high, set the direction as input i.e., write to 	 * the direction clear register     */	case HIGH:							IXP2400_REG_WRITE(IXP2400_GPIO_PDCR,CLOCK);		IXP2400_REG_READ(IXP2400_GPIO_PDCR, temp);		/*read PLR until it is high*/		while(!(*(volatile UINT32*) IXP2400_GPIO_PLR & CLOCK) && i--);		break;		/*To drive the clock low, set the direction as output i.e., write to 	 	 * the direction set register   		 */	case LOW:		IXP2400_REG_WRITE(IXP2400_GPIO_PDSR,CLOCK);		IXP2400_REG_READ(IXP2400_GPIO_PDSR, temp);		break;	}	intUnlock (locKey);}/*************************************************************************Function Name	:	I2C_DATAInput			:	High or LowOutPut			:	NoneDesc			:	Sets the SDA pin Low or High**************************************************************************/static void I2C_DATA(unsigned char x){	FAST int locKey;	int temp;    locKey = intLock ();	switch(x)	{	case HIGH:		IXP2400_REG_WRITE(IXP2400_GPIO_PDCR,DATA);		IXP2400_REG_READ(IXP2400_GPIO_PDCR, temp);		break;	case LOW:		IXP2400_REG_WRITE(IXP2400_GPIO_PDSR,DATA);		IXP2400_REG_READ(IXP2400_GPIO_PDSR, temp);		break;		}	 intUnlock (locKey);}/*************************************************************************Function Name	:	i2c_startInput			:	NoneOutPut			:	NoneDesc			:	generate i2c start condition.Start Condition: High to 					Low transition of SDA when SCL is high**************************************************************************/      static void i2c_start(void){	/*SDA=1, SCL=1 */	I2C_DATA(HIGH);	I2C_CLK(HIGH);	I2C_DELAY(CLOCK_HIGH_TIME);	/*SCL=1, SDA=0*/	I2C_DATA(LOW);	I2C_DELAY(START_CONDITION_HOLD_TIME);	/*SCL=0 SDA=0*/	I2C_CLK(LOW);	I2C_DELAY(CLOCK_LOW_TIME);}/*****************************************************************************Function name	:	i2c_stopInput			:	NoneOutPut			:	NoneDesc			:	Generate i2c stop condition:LOW to High transition of 					SDA when SCL is high*******************************************************************************/static void i2c_stop(void){    /*SCL=0, SDA=0 */	I2C_DATA(LOW);	I2C_DELAY(CLOCK_LOW_TIME*2);	/*SCL=1, SDA=0*/	I2C_CLK(HIGH);	I2C_DELAY(CLOCK_HIGH_TIME*2);	/*SCL=1 SDA=1*/	I2C_DATA(HIGH);	I2C_DELAY(STOP_CONDITION_HOLD_TIME);	}/***************************************************************************Function Name	:	i2c_ReadBit()Input			:	noneOutPut			:	returns the read bitDesc			:	read bit on sda*****************************************************************************/static unsigned char i2c_ReadBit(void){	unsigned char x;    FAST int locKey;		I2C_CLK(LOW);	I2C_DELAY(CLOCK_LOW_TIME );	I2C_CLK(HIGH);	I2C_DELAY(CLOCK_LOW_TIME );		locKey = intLock ();	x= (unsigned char)((*(unsigned int*)(IXP2400_GPIO_PLR)) & DATA);    intUnlock (locKey);	I2C_CLK(LOW);	I2C_DELAY(CLOCK_LOW_TIME);	return ( (x & DATA) ? 1 : 0); }/****************************************************************************Function Name	:	i2c_WriteBit()Input			:	bit to be writtenOutPut			:	noneDesc			:	output a bit onto sda******************************************************************************/static void i2c_WriteBit(unsigned char x){	I2C_CLK(LOW);	I2C_DELAY(CLOCK_LOW_TIME/2);	if (x & 0x80) /* the MSB is sent out first*/		I2C_DATA(HIGH);	else		I2C_DATA(LOW);	I2C_DELAY(CLOCK_LOW_TIME);	I2C_CLK(HIGH);	I2C_DELAY(CLOCK_HIGH_TIME);	I2C_CLK(LOW);	I2C_DELAY(CLOCK_LOW_TIME);    I2C_DATA(HIGH);	}/******************************************************************************Function Name	:	i2c_writebyteInput			:	byte to be writtenOutPut			:	NoneDesc			:	write a byte onto i2c ********************************************************************************/static void i2c_writebyte(unsigned char data){	int i;	for(i=0;i<8;i++){	i2c_WriteBit(data);	data<<=1;	}		I2C_DATA(HIGH);/*release SDA*/}/****************************************************************************Function Name	:	i2c_readbyteInput			:	noneOutPut			:	returns the byte read from the i2c deviceDesc			:	read a byte from i2c ******************************************************************************/static unsigned char i2c_readbyte(void){	unsigned char bit;	unsigned char data=0x0;		/*The MSB is read first*/	for(data=0,bit=0;bit<7;bit++)	{	data|=i2c_ReadBit();	data<<=1;	}	data|=i2c_ReadBit();	return data;	}void i2c_init0(void){	    FAST int locKey;    locKey = intLock ();	IXP2400_REG_WRITE((unsigned int *)IXP2400_GPIO_PDSR, (I2C_INIT_BIT)); 	 /*drive this pin high*/	IXP2400_REG_WRITE((unsigned int *)IXP2400_GPIO_POSR, (I2C_INIT_BIT));    intUnlock (locKey);		i2c_init();}/****************************************************************************Function Name	:	i2c_initInput			:	noneOutPut			:	noneDesc			:	configures the GPIO 2 and 3 for output******************************************************************************/void i2c_init(void){		int i;    FAST int locKey;	int temp;    locKey = intLock ();	/* initially at power up SDA has pull down because it is used as strap pin.	 * the PCI_ARB strap pin which is GPIO 2 should be driven high inorder to      * have a pull up on SDA line. This is required by this board design     */		/*configure pin 7 and 6 to be output*/	IXP2400_REG_WRITE((unsigned int *)IXP2400_GPIO_PDSR, (CLOCK|DATA));		/*make the output level on pins gpio 6 and 7 low*/	IXP2400_REG_WRITE((unsigned int *)IXP2400_GPIO_POCR, (CLOCK|DATA));			/*make pins 6 and 7 as input during init*/	IXP2400_REG_WRITE((unsigned int *)IXP2400_GPIO_PDCR, (CLOCK));	for(i=0;i<10;i++);			IXP2400_REG_WRITE((unsigned int *)IXP2400_GPIO_PDCR, (DATA));	IXP2400_REG_READ(IXP2400_GPIO_PDCR, temp);	intUnlock (locKey);}/******************************************************************************Function Name	:	i2c_readInput			:	Address of slave device to be read,                    location to be read                    ptr where read data has to be  storedOutPut			:	noneDesc			:	read a byte of data(random read) on to i2c device******************************************************************************/void i2c_read(unsigned char slave, unsigned char addr, unsigned char *x){	unsigned char data = 0;	unsigned char ack1, ack2, i2c_ack_stat;	i2c_ack_stat=0x0;		if(!i2c_device_busy(slave))	{		i2c_writebyte(addr);	ack1=i2c_ReadBit(); /*read ack from slave*/	if(ack1!=0)		i2c_ack_stat |= 0x2; 		i2c_start();	i2c_writebyte(slave|I2C_READ);	ack2=i2c_ReadBit();	if(ack2!=0)		i2c_ack_stat |= 0x3;	data = i2c_readbyte();		i2c_WriteBit(0x80);	i2c_stop();	}		*x=data;	return ;}/******************************************************************************Function Name	:	i2c_seq_readInput			:	Address of slave device to be read,                    starting location to be read,                     no.of locations to be read                    ptr where the read data has to be storedOutPut			:	noneDesc			:	read a byte of data(random read) on to i2c device******************************************************************************/void i2c_seq_read(unsigned char slave, unsigned char addr, unsigned char *data,														 unsigned char count){				int i;	unsigned char ack1, ack2, i2c_ack_stat;	i2c_ack_stat=0x0;	if(!i2c_device_busy(slave))	{			i2c_writebyte(addr);	ack1=i2c_ReadBit(); /*read ack from slave*/	if(ack1!=0)		i2c_ack_stat |= 0x2;		i2c_start();	i2c_writebyte(slave|I2C_READ);	ack2=i2c_ReadBit();	if(ack2!=0)		i2c_ack_stat |= 0x4;	for(i=0;i<count;i++)	{	data[i] = i2c_readbyte();	if(i != (count-1))        i2c_WriteBit(0x0); /*send ack*/    else        i2c_WriteBit(0x80); /*send nack after reading the last byte*/	}	i2c_stop();	}		return ;}/******************************************************************************Function Name	:	i2c_writeInput			:	Address of the slave device to be written,                     location to be wriiten,                     data to be writtenOutPut			:	noneDesc			:	Write a byte of data on to i2c device******************************************************************************/void i2c_write(unsigned char slave, unsigned char addr, unsigned char data){	unsigned char ack1, ack2, i2c_ack_stat;	i2c_ack_stat=0x0;	if(!i2c_device_busy(slave))	{			i2c_writebyte(addr);	ack1=i2c_ReadBit();	if(ack1!=0)		i2c_ack_stat |= 0x2;		i2c_writebyte(data);	ack2=i2c_ReadBit();	if(ack2!=0)		i2c_ack_stat |= 0x8;	i2c_stop();	}		}/******************************************************************************Function Name	:	i2c_page_writeInput			:	Address of the slave device to be written,                     location to be wriiten,                     ptr to data array to be writtenOutPut			:	noneDesc			:	Write a byte of data on to i2c device******************************************************************************/void i2c_page_write(unsigned char slave, unsigned char addr,									 unsigned char * data, unsigned char count){		int i;	unsigned char ack1, ack2, i2c_ack_stat;	i2c_ack_stat=0x0;	if(count>16)		count=16;	if(!i2c_device_busy(slave))	{	i2c_writebyte(addr);	ack1=i2c_ReadBit(); 	if(ack1!=0)		i2c_ack_stat |= 0x2;	for(i=0;i<count;i++)	{	i2c_writebyte(data[i]);	ack2=i2c_ReadBit();	if(ack2!=0)   		i2c_ack_stat |= 0x8;	}		i2c_stop();    }}/*once the stop condition is issued to indicate the end of the host's write *operation, the NM24c02/03 initialtes the internal write cycle. ACK polling  *can be initiated immediately. This involves issuing the strat condition  *followed by the slave address for write operation. if the i2c device is still *busy, no ack is returned. if the device completed its internal write  *operation, an ack will be returned and the master can then proceed with next  *read or write operation. the following function implements the ACLk polling. */unsigned char i2c_device_busy(unsigned char slave){	unsigned char busy=1;	int i=0;	while((busy!=0) && (i<100))	{	i2c_start();	i2c_writebyte(slave);	busy=i2c_ReadBit();	if(busy)	  i2c_stop();	i++;	}	return busy;	}

⌨️ 快捷键说明

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