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

📄 i2c.c

📁 LPC2102的keil vendor code
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************
 *   i2c.c:  I2C C file for NXP LPC210x Family Microprocessors
 *
 *   Copyright(C) 2006, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2005.10.01  ver 1.00    Prelimnary version, first Release
 *
*****************************************************************************/
#include "LPC210x.H"	/* LPC21xx definitions */
#include "type.h"
#include "irq.h"
#include "i2c.h"
#include "gpio.h"

#define SpiComm_Write	(0x12)
 
BYTE I2C0RxCounter;
BYTE I2C0RxFinished = 0;
BYTE I2C0RxBuffer[BUFSIZE];

BYTE I2C0TxCounter;
BYTE I2C0TxFinished = 0;
BYTE I2C0TxBuffer[BUFSIZE];

BYTE mi2cstatus;		// I2C_OK or I2C_ERROR
static BYTE mbytenum;	// Number of transmitted bytes

#ifdef LPC2102_I2C1_MASTER
	unsigned long I2C1MasterState = I2C_IDLE;
	unsigned long I2CCmd;
	unsigned char I2C1MasterBuffer[BUFSIZE];
	unsigned long I2C1ReadLength;
	unsigned long I2C1WriteLength;
	unsigned long RdIndex = 0;
	unsigned long WrIndex = 0;
#endif

/*****************************************************************************
** Function name:	I2C0_Init
** Description:		Initialize I2C0 controller
** Parameter:		I2c mode is either MASTER or SLAVE
** Returned value:	true or false; return false if the I2C
**					interrupt handler was not installed correctly
*****************************************************************************/
DWORD I2C0_Init( DWORD I2cMode ) 
{
	BYTE i=0;

	PINSEL0 |= 0x00000050;		// Set P0.2 as SCL0 and P0.3 as SDA0

	/*--- Clear flags ---*/
	I2C0CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;    

    /*--- Reset registers ---*/
	I2C0SCLL = I2SCLL_SCLL;
	I2C0SCLH = I2SCLH_SCLH;

	if( I2cMode == I2CSLAVE )		/* I2C Slave */
	{
		I2C0ADR = I2CSL_ADDRS << 1;
	}

    /* Install interrupt handler */	
	if( install_irq( I2C0_INT, (void *)I2C0_SlaveHandler ) == FALSE )
	{
		return( FALSE );
	}

	/* Enable I2C controller for Master or Slave functions */
	if( I2cMode == I2CMASTER )
	{
		I2C0CONSET = I2CONSET_I2EN;
	}
	else
	{
		I2C0CONSET = I2CONSET_I2EN | I2CONSET_AA;
	}

	/* Initialize I2C Tx and Rx and SPI Rx counters */
	I2C0TxCounter = 0;
	I2C0RxCounter = 0;

	/* Initialize I2C Tx and Rx buffers */
	for(i=1; i<BUFSIZE; i++)
	{
		I2C0TxBuffer[i] = 0x00;
		I2C0RxBuffer[i] = 0x00;
	}

	return( TRUE );
} // I2C0_Init

/*****************************************************************************
** Function name:	I2C0_SlaveHandler
** Description:		I2C0 interrupt handler, deal with SLAVE mode only.
** Parameter:		None
** Returned value:	None
*****************************************************************************/
void I2C0_SlaveHandler (void) __irq 
{
	BYTE StatValue;

	/* Reads the I2C status to branch to one of the I2C state routines */
	StatValue = I2C0STAT;
  
	IENABLE;

	I2C0CONCLR = I2CONCLR_AAC | I2CONCLR_STAC;	// Clear STA and AA flags

	/* Handles I2C state routines */ 
	switch(StatValue)
	{
		/****************************************************       
		*		S L A V E   R E C E I V E R    M O D E		*
 		*****************************************************/
		case 0x60:	/* Own SLA+W received; ACK returned; Data will be received and ACK returned (Slave Receiver) */
		case 0x68:
		case 0x70:	
		case 0x78:
			I2C0CONSET = I2CONSET_AA;
			I2C0CONCLR = I2CONCLR_SIC;
			I2C0RxCounter = 0;		// Clear I2C Rx counter
			break;

		case 0x80:	/* Addressed with own SLV address; Data received; ACK returned; Additional data will be read */
		case 0x90:
		case 0x88:	/* Addressed with own SLV address; Data received; Not ACK returned */
		case 0x98:
			I2C0RxBuffer[I2C0RxCounter] = I2DAT;

			if( I2C0RxBuffer[0] == SpiComm_Write )	/* Checks Fn ID: Write I2C receive data to Spi device */
			{
				if( I2C0RxCounter == 0 )				/* SPI function ID handling */
				{
					I2C0CONCLR = I2CONCLR_SIC;
					I2C0RxCounter++;
				}
				else								/* Unbuffered SPI Write operation */
				{
					IODIR |= 0x80;					// Set P0.7 as output
					IOCLR |= 0x80;					// Set P0.7 as Low to activate SSEL signal (active-low)
					SPI_Send((BYTE*)&I2C0RxBuffer[1], 1);
					I2C0CONCLR = I2CONCLR_SIC;  	// Release SCL clock after SPI communication is completed
				}
			}
			else									/* Functions that are not SPI Write */
			{
				I2C0CONCLR = I2CONCLR_SIC;  		// Clear SI flag to release SCL clock 
				if(	(I2C0RxCounter+1) <= BUFSIZE )
					I2C0RxCounter++;
			}

			I2C0CONSET = I2CONSET_AA;
			break;
		
		case 0xA0: /* STOP or REP.START received while addressed as slave */

			if( I2C0RxBuffer[0] == SpiComm_Write )
				IOSET |= 0x80;		// P0.7 is set as High to de-activate SSEL signal (active-low)

			mi2cstatus = I2C_OK;
			I2C0CONSET = I2CONSET_AA;
			I2C0CONCLR = I2CONCLR_SIC;				
			i2c_receive_finished();
			break;

		/************************************************************       
		*		S L A V E   T R A N S M I T T E R    M O D E		*
 		************************************************************/
		case 0xA8: /* Own SLA+R received, Ack returned (slave transmitter) */
		case 0xB0:
			mbytenum = 0;

		case 0xB8: /* Data transmitted, ACK received */

			I2C0DAT = I2C0TxBuffer[mbytenum];
			I2C0CONSET = I2CONSET_AA;				
			I2C0CONCLR = I2CONCLR_SIC;

			if( i2c_slave_islasttxbyte(mbytenum) )
				I2C0TxFinished = 1;			// no more data bytes to transmit

			mbytenum++;
			break;
			
		case 0xC0:	/* Data byte transmitted, NACK received last data byte transmitted, NACK received */
		case 0xC8:
			mi2cstatus = I2C_OK;
			I2C0CONSET = I2CONSET_AA;
			I2C0CONCLR = I2CONCLR_SIC;				
			I2C0TxFinished = 1;
			i2c_transfer_finished();
			break;  

		default:	/* Unknown state */
			mi2cstatus = I2C_ERROR;
			I2C0CONSET = I2CONSET_AA;
			I2C0CONCLR = I2CONCLR_SIC;
			break;
    }

    IDISABLE;
    VICVectAddr = 0;		/* Acknowledge Interrupt */
} // I2C0_SlaveHandler

/***********************************************************************
** Function name:	i2c_receive_finished
** Description:    	Called when an I2C transfer has finished.
**          		mi2cstatus may be read to determine if the transfer 
**					was	successful (I2C_OK) or failed (I2C_ERROR)
** Parameter:		None
** Returned value:	None
************************************************************************/
void i2c_receive_finished(void)
{
	I2C0RxFinished = 1;
	ApplnHandler_Flag = 1;
} // i2c_receive_finished

/***********************************************************************
** Function name:	i2c_transfer_finished
** Description:    	Called when an I2C transfer has finished.
**          		Resets the transmit buffer and transmit counter.
** Parameter:		None
** Returned value:	None
************************************************************************/
void i2c_transfer_finished(void)
{	
	BYTE i;	

	if(I2C0TxFinished)
	{
		 I2C0TxCounter = 0;				/* Clears I2C Tx counter */
		 for (i=0; i<BUFSIZE; i++)
		 {
		 	I2C0TxBuffer[i] = 0;			/* Clears I2C Tx buffer */
		 }	 
	}

	/* Release interrupt to I2C host */
	IODIR |= P0_0_MASKBITPATTERN;		/* Ensure P0.0 is configured as output */
	IOSET |= P0_0_MASKBITPATTERN;		/* Set P0.0 (Active-Low) as High  */
	
	if(gInterrupt_Status)
		gInterrupt_Status = 0;

	i2c_send_flag = 1;

} // i2c_transfer_finished

/***********************************************************************
** Function name:	i2c_slave_islasttxbyte
** Description:    	Determines if a byte will be the last one to be
**          		transmitted when operating as a slave.
** Parameter:		None
** Returned value:	return 1 if the byte will be the last one to transmit
**         			return 0 if the byte will not be the last one to transmit
************************************************************************/
BYTE i2c_slave_islasttxbyte(BYTE bytenum )
{
  	if( bytenum == (I2C0TxCounter-1) )
		return 1;
  	else
 		return 0;
} // i2c_slave_islasttxbyte

#ifdef LPC2102_I2C1_MASTER
/*****************************************************************************
** Function name:	I2C1_Master_Demo
** Description:		This function demonstrates how I2C1 can be used as an I2C 
**					Master Mode.
** Parameter:		None
** Returned value:	None
*****************************************************************************/
void I2C1_Master_Demo(void)
{
	BYTE i;

	/* Initialize I2C1 controller */
	I2C1_Init(I2CMASTER);

	/* Demonstration of using I2C1 in I2C Master mode - WRITE */
    I2C1WriteLength = 4;
	I2C1ReadLength = 0;
    I2C1MasterBuffer[0] = SLV_ADDRESS | WR_BIT;
    I2C1MasterBuffer[1] = 0xa5;
    I2C1MasterBuffer[2] = 0x5a;
    I2C1MasterBuffer[3] = 0xaa;
    I2C1MasterBuffer[4] = 0x55;
	
	I2CCmd = I2C_WRITE;
    I2CEngine(); 

    /* Clear buffer */
    for(i=0; i<BUFSIZE; i++)
    {
		I2C1MasterBuffer[i] = 0;
    }
	
	/* Demonstration of using I2C1 in I2C Master mode - READ */
	I2C1ReadLength = 4;
    I2C1WriteLength = 0;
    I2C1MasterBuffer[0] = SLV_ADDRESS | RD_BIT;

	I2CCmd = I2C_READ;
    I2CEngine(); 

    /* Clear buffer */
    for(i=0; i<BUFSIZE; i++)
    {
		I2C1MasterBuffer[i] = 0;
    }

	/* Demonstration of using I2C1 in I2C Master mode - WRITE + READ */
    I2C1WriteLength = 4;
    I2C1ReadLength = 4;
    I2C1MasterBuffer[0] = SLV_ADDRESS | WR_BIT;
    I2C1MasterBuffer[1] = 0x11;
    I2C1MasterBuffer[2] = 0x22;
    I2C1MasterBuffer[3] = 0x33;
    I2C1MasterBuffer[4] = 0x44;
    I2C1MasterBuffer[5] = SLV_ADDRESS | RD_BIT;

⌨️ 快捷键说明

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