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

📄 i2c_poll.c

📁 ARM7的I2C读写
💻 C
字号:
#include "i2c.h"

//
//  Default timeout, in milliseconds for generic read/write
//
#define I2C_DEFAULT_TIMEOUT 100



//
//
//
typedef enum
{
	I2CFLAGS_START         = 0x0001,
	I2CFLAGS_REPEATEDSTART = 0x0002,
	I2CFLAGS_STOP          = 0x0004,
	I2CFLAGS_ADDRESS       = 0x0008,
	I2CFLAGS_WRITEDATA     = 0x0010,
	I2CFLAGS_READDATA      = 0x0020,
}
i2cFlags_e;

typedef enum
{
	I2CMODE_ACK = 0,
	I2CMODE_NACK,
	I2CMODE_READ
}
i2cMode_e;


static uint32 i2cTimeoutInTicks = I2C_DEFAULT_TIMEOUT ;

void i2cInit (void)
{
	SCB_PCONP |= SCB_PCONP_PCI2C0;

	PCB_PINSEL0 = (PCB_PINSEL0 & ~(PCB_PINSEL0_P02_MASK | PCB_PINSEL0_P03_MASK)) | (PCB_PINSEL0_P02_SCL0 | PCB_PINSEL0_P03_SDA0);

	I2C0_CONCLR = I2C_CONCLR_MASK;
	I2C0_CONSET = I2C_CONSET_I2EN;
	/* 设置高低电平时间 */
	I2C0_SCLL   = 480;    
	I2C0_SCLH   = 480;
}

static i2cErr_e i2cStatus (void)
{
	i2cErr_e status;

	while (!(I2C0_CONSET & I2C_CONSET_SI))
		;

	if ((status = I2C0_STAT) == I2CERR_BUSERRORx)
		return I2CERR_BUSERROR;

	return status;
}


static i2cErr_e i2cStop (void)
{
	//清中断
	I2C0_CONCLR = I2C_CONCLR_SIC;
	//发送停止标志
	I2C0_CONSET = I2C_CONSET_STO;

	while (I2C0_CONSET & I2C_CONSET_STO)
		;

	return I2CERR_NONE;
}

static i2cErr_e i2cStart (void)
{
	I2C0_CONCLR = I2C_CONCLR_SIC;
	I2C0_CONSET = I2C_CONSET_STA;

	while (1)
	{
		i2cErr_e status;

		if (((status = i2cStatus ()) == I2CERR_STARTTX) || (status == I2CERR_REPEATEDSTARTTX))
		{
			I2C0_CONCLR = I2C_CONCLR_STAC;
			return I2CERR_NONE;
		}
		else if (status != I2CERR_NOINFO)
		{
			I2C0_CONCLR = I2C_CONCLR_STAC;
			return status;
		}
		else
			I2C0_CONCLR = I2C_CONCLR_SIC;
	}
}

static i2cErr_e i2cRepeatedStart (void)
{
	while (!(I2C0_CONSET & I2C_CONSET_SI))
		;

	I2C0_CONCLR = I2C_CONCLR_SIC;
	I2C0_CONSET = I2C_CONSET_STA;

	while (1)
	{
		i2cErr_e status;

		if (((status = i2cStatus ()) == I2CERR_STARTTX) || (status == I2CERR_REPEATEDSTARTTX))
		{
			I2C0_CONCLR = I2C_CONCLR_STAC;
			return I2CERR_NONE;
		}
		else if (status != I2CERR_NOINFO)
		{
			I2C0_CONCLR = I2C_CONCLR_STAC;
			return status;
		}
		else
			I2C0_CONCLR = I2C_CONCLR_SIC;
	}
}

static i2cErr_e i2cPutByte (uint8 data)
{
	if (!(I2C0_CONSET & I2C_CONSET_SI))
		return I2CERR_BUSY;

	I2C0_DAT = data;
	I2C0_CONCLR = I2C_CONCLR_SIC;

	return I2CERR_NONE;
}

static i2cErr_e i2cGetByte (i2cMode_e mode, uint8 *pData)
{
	switch (mode)
	{
	case I2CMODE_ACK :
		I2C0_CONCLR = I2C_CONCLR_SIC;
		I2C0_CONSET = I2C_CONSET_AA;
		break;

	case I2CMODE_NACK :
		I2C0_CONCLR = (I2C_CONCLR_AAC | I2C_CONCLR_SIC);
		break;

	case I2CMODE_READ :
		{
			if (!(I2C0_CONSET & I2C_CONSET_SI))
				return I2CERR_EMPTY;

			*pData = (uint8) I2C0_DAT;
		}
		break;
	}

	return I2CERR_NONE;
} 

static i2cErr_e i2cWriteBufferEx (uint8 address, uint8 *buffer, uint32 bufferLength, i2cFlags_e flags)
{
	uint32 i;
	i2cErr_e status;

	if (flags & I2CFLAGS_START)
	{
		if ((status = i2cStart ()) != I2CERR_NONE)
		{
			i2cStop ();
			return status;
		}
	}
	else if (flags & I2CFLAGS_REPEATEDSTART)
	{
		if ((status = i2cRepeatedStart ()) != I2CERR_NONE)
		{
			i2cStop ();
			return status;
		}
	}

	if (flags & I2CFLAGS_ADDRESS)
	{
		do
		if (((status = i2cPutByte (address & ~0x01)) != I2CERR_NONE) && (status != I2CERR_BUSY))
			return status;
		while (status == I2CERR_BUSY);
	}

	if (flags & I2CFLAGS_WRITEDATA)
	{
		for (i = 0; i < bufferLength; i++, buffer++)
		{
			while (1)
			{
				if (((status = i2cStatus ()) == I2CERR_SLAWTX_ACKRX) || (status == I2CERR_DATTX_ACKRX))
				{
					do
					if (((status = i2cPutByte (*buffer)) != I2CERR_NONE) && (status != I2CERR_BUSY))
						return status;
					while (status == I2CERR_BUSY);

					break;
				}
				else if (status != I2CERR_NOINFO)
				{
					i2cStop ();
					return status;
				}
			}
		}
	}

	if (flags & I2CFLAGS_STOP)
	{
		while (1)
		{
			if (((status = i2cStatus ()) == I2CERR_SLAWTX_ACKRX) || (status == I2CERR_DATTX_ACKRX))
			{
				i2cStop ();
				return I2CERR_NONE;
			}
			else if (status != I2CERR_NOINFO)
			{
				i2cStop ();
				return status;
			}
		}
	}

	return I2CERR_NONE;
}

static i2cErr_e i2cReadBufferEx (uint8 address, uint8 *buffer, uint32 bufferLength, i2cFlags_e flags)
{
	uint32 i;
	i2cErr_e status;

	if (flags & I2CFLAGS_START)
	{
		if ((status = i2cStart ()) != I2CERR_NONE)
		{
			i2cStop ();
			return status;
		}
	}
	else if (flags & I2CFLAGS_REPEATEDSTART)
	{
		if ((status = i2cRepeatedStart ()) != I2CERR_NONE)
		{
			i2cStop ();
			return status;
		}
	}

	if (flags & I2CFLAGS_ADDRESS)
	{
		do
		if (((status = i2cPutByte (address | 0x01)) != I2CERR_NONE) && (status != I2CERR_BUSY))
			return status;
		while (status == I2CERR_BUSY);
	}

	if (flags & I2CFLAGS_READDATA)
	{
		for (i = 0; i < bufferLength; i++, buffer++)
		{
			while (1)
			{
				if (((status = i2cStatus ()) == I2CERR_SLARTX_ACKRX) || (status == I2CERR_SLARTX_NACKRX) || (status == I2CERR_DATRX_ACKTX))
				{
					i2cGetByte ((i != bufferLength - 1) ? I2CMODE_ACK : I2CMODE_NACK, NULL);

					do
					status = i2cGetByte (I2CMODE_READ, buffer);
					while (status == I2CERR_EMPTY);

					break;
				}
				else if (status != I2CERR_NOINFO)
				{
					i2cStop ();
					return status;
				}
			}
		}
	}

	if (flags & I2CFLAGS_STOP)
		i2cStop ();

	return I2CERR_NONE;
}

static int i2cPoll (uint8 address)
{
	uint32 theFuture = OSTime + i2cTimeoutInTicks;

	while (OSTime < theFuture)
	{
		if ((i2cErrno = i2cStart ()) != I2CERR_NONE)
			break;
		if ((i2cErrno = i2cPutByte (address & ~0x01)) != I2CERR_NONE)
			break;
		if ((i2cErrno = i2cStatus ()) == I2CERR_SLAWTX_ACKRX)
			break;
	}

	if (i2cErrno != I2CERR_SLAWTX_ACKRX)
		i2cErrno = I2CERR_TIMEOUTACKPOLL;

	i2cStop ();

	return (i2cErrno == I2CERR_SLAWTX_ACKRX) ? 0 : -1;
}

int32 i2cWriteBuffer (uint8 address, uint8 *buffer, uint32 bufferLength)
{
	if ((i2cErrno = i2cWriteBufferEx (address, buffer, bufferLength, I2CFLAGS_START | I2CFLAGS_ADDRESS | I2CFLAGS_WRITEDATA | I2CFLAGS_STOP)) != I2CERR_NONE)
		return -1;

	return 0;
}


int32 i2cReadBuffer (uint8 address, uint8 *buffer, uint32 bufferLength)
{
	if ((i2cErrno = i2cReadBufferEx (address, buffer, bufferLength, I2CFLAGS_START | I2CFLAGS_ADDRESS | I2CFLAGS_READDATA | I2CFLAGS_STOP)) != I2CERR_NONE)
		return -1;

	return 0;
}

int32 i2cWriteReadBuffer (uint8 address, uint8 *buffer, uint32 putLength, uint32 getLength)
{
	if ((i2cErrno = i2cWriteBufferEx (address, buffer, putLength, I2CFLAGS_START | I2CFLAGS_ADDRESS | I2CFLAGS_WRITEDATA)) != I2CERR_NONE)
		return -1;

	if ((i2cErrno = i2cReadBufferEx (address, buffer, getLength, I2CFLAGS_REPEATEDSTART | I2CFLAGS_ADDRESS | I2CFLAGS_READDATA | I2CFLAGS_STOP)) != I2CERR_NONE)
		return -1;

	return 0;
}

int32 i2cWriteBufferPoll (uint8 address, uint8 *buffer, uint32 bufferLength)
{
	int32 r;

	if (!(r = i2cWriteBuffer (address, buffer, bufferLength)))
		r = i2cPoll (address);

	return r;
}

int32 i2cWriteReadBufferPoll (uint8 address, uint8 *buffer, uint32 putLength, uint32 getLength)
{
	int32 r;

	if (!(r = i2cWriteReadBuffer (address, buffer, putLength, getLength)))
		r = i2cPoll (address);

	return r;
}

⌨️ 快捷键说明

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