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

📄 i2cint.c

📁 最新的LPC214X I2C驱动程序
💻 C
字号:
////  $Id: i2cInt.c 143 2008-10-13 16:02:41Z jcw $//  $Revision: 143 $//  $Author: jcw $//  $Date: 2008-10-13 12:02:41 -0400 (Mon, 13 Oct 2008) $//  $HeadURL: http://tinymicros.com/svn_public/arm/lpc2148_demo/trunk/i2c/i2cInt.c $//#include "FreeRTOS.h"#include <stdio.h>#include <string.h>#include <sys/times.h>#include "i2c.h"////  Default timeout, in milliseconds for generic read/write//#define I2C_DEFAULT_TIMEOUT 100#undef  I2C_DEBUG//////typedef enum{  ACKPOLL_NO = 0,  ACKPOLL_YES}ackPoll_e;//////static volatile int i2cBusInUse;static U8 i2cAddress;static U8 *i2cDataBuffer;static int i2cDataLenWrite;static int i2cDataLenRead;static unsigned int i2cTimeoutInTicks = I2C_DEFAULT_TIMEOUT / portTICK_RATE_MS;static int i2cDataCnt;static ackPoll_e i2cAckPoll = ACKPOLL_NO;//////#ifdef I2C_DEBUGstatic U8 i2cTransactions [64];static int i2cTransactionsIndex;#define i2cDebug(x) do { if (i2cAckPoll && (i2cTransactionsIndex < (int) sizeof (i2cTransactions))) i2cTransactions [i2cTransactionsIndex++] = x; } while (0)#define i2cDebugReset() do { i2cTransactionsIndex = 0; } while (0)#else#define i2cDebug(x) do { } while (0)#define i2cDebugReset() do { } while (0)#endifstatic void i2cISR_Handler (void){  i2cErrno = (I2C0_STAT & I2C_STAT_STATMASK);  i2cDebug (i2cErrno);  switch (i2cErrno)  {    //    //  Transmit conditions    //    case I2CERR_BUSERRORx : // 0x00      {        I2C0_CONSET = I2C_CONSET_STO | I2C_CONSET_AA;        i2cAckPoll = ACKPOLL_NO;        i2cBusInUse = FALSE;      }      break;    case I2CERR_STARTTX : // 0x08    case I2CERR_REPEATEDSTARTTX : // 0x10      {        i2cDebug (i2cAddress);        I2C0_DAT = i2cAddress;      }      break;    case I2CERR_SLAWTX_ACKRX : // 0x18    case I2CERR_DATTX_ACKRX : // 0x28      {        i2cAckPoll = ACKPOLL_NO;        if (i2cDataLenWrite && (i2cDataCnt < i2cDataLenWrite))        {          i2cDebug (i2cDataBuffer [i2cDataCnt]);          I2C0_DAT = i2cDataBuffer [i2cDataCnt++];          I2C0_CONCLR = I2C_CONCLR_STAC;        }        else        {          if (!i2cDataLenRead)          {            i2cDebug (0xff);            I2C0_CONCLR = I2C_CONCLR_STAC;            I2C0_CONSET = I2C_CONSET_STO;            i2cErrno = I2CERR_NONE;            i2cBusInUse = FALSE;          }          else          {            i2cDebug (0xfe);            i2cAddress |= 0x01;            i2cDataCnt = 0;            I2C0_CONSET = I2C_CONSET_STA;          }        }      }      break;    case I2CERR_DATRX_NACKTX : // 0x58      {        i2cDataBuffer [i2cDataCnt++] = I2C0_DAT;        i2cDebug (i2cDataBuffer [i2cDataCnt - 1]);        i2cErrno = I2CERR_NONE;      }    case I2CERR_SLAWTX_NACKRX : // 0x20    case I2CERR_SLARTX_NACKRX : // 0x48      {        if (i2cAckPoll)          break;      }    case I2CERR_DATTX_NACKRX : // 0x30      {        I2C0_CONCLR = I2C_CONCLR_STAC;        I2C0_CONSET = I2C_CONSET_STO;        i2cBusInUse = FALSE;      }      break;    case I2CERR_ARBLOST : // 0x38      {        I2C0_CONSET = I2C_CONSET_STA;      }      break;    //    //  Receive byte conditions (fall through is intentional)    //    case I2CERR_DATRX_ACKTX : // 0x50      {        i2cDataBuffer [i2cDataCnt++] = I2C0_DAT;        i2cDebug (i2cDataBuffer [i2cDataCnt - 1]);      }    case I2CERR_SLARTX_ACKRX : // 0x40      {        if (i2cDataCnt < i2cDataLenRead - 1)        {          I2C0_CONCLR = I2C_CONCLR_STAC;          I2C0_CONSET = I2C_CONSET_AA;        }        else          I2C0_CONCLR = I2C_CONCLR_STAC | I2C_CONCLR_AAC;      }      break;    case I2CERR_NOINFO :      break;    default:      {        I2C0_CONCLR = I2C_CONCLR_I2ENC;        i2cAckPoll = ACKPOLL_NO;        i2cBusInUse = FALSE;      }      break;  }  I2C0_CONCLR = I2C_CONSET_SI;  VIC_VectAddr = 0;}static void i2cISR (void) __attribute__ ((naked));static void i2cISR (void){  portSAVE_CONTEXT ();  i2cISR_Handler ();  portRESTORE_CONTEXT ();}//// i2c1Init//void i2cInit (void){  i2cBusInUse = FALSE;  i2cAckPoll = ACKPOLL_NO;  PCB_PINSEL0 = (PCB_PINSEL0 & ~(PCB_PINSEL0_P02_MASK | PCB_PINSEL0_P03_MASK)) | (PCB_PINSEL0_P02_SCL0 | PCB_PINSEL0_P03_SDA0);  SCB_PCONP |= SCB_PCONP_PCI2C0;  I2C0_CONCLR = I2C_CONCLR_MASK;  I2C0_CONSET = I2C_CONSET_I2EN;  I2C0_SCLL   = 240;  I2C0_SCLH   = 240;  //  //  Initialize the interrupt vector  //  VIC_IntSelect &= ~VIC_IntSelect_I2C0;  VIC_VectCntl7 = VIC_VectCntl_ENABLE | VIC_Channel_I2C0;  VIC_VectAddr7 = (int) i2cISR;  VIC_IntEnable = VIC_IntEnable_I2C0;}////  Waits for the interrupt handler to mark the I2C bus as no longer in use, then//  return 0 on success or -1 if any error occurred.//static int i2cWaitComplete (int ticks){  if (i2cBusInUse)  {    clock_t theFuture;    for (theFuture = times (NULL) + ticks; i2cBusInUse; )    {      if (times (NULL) > theFuture)      {        I2C0_CONCLR = I2C_CONCLR_I2ENC;        i2cErrno = I2CERR_TIMEOUTWC;        return -1;      }    }  }  return (i2cErrno == I2CERR_NONE) ? 0 : -1;}////  Disables interrupts then starts sending repeated STARTs until the slave device//  returns ACK.  This indicates the slave has completed any operation in progress.//static int i2cPoll (U8 address){  clock_t theFuture = times (NULL) + 10;  VIC_IntEnClr = VIC_IntEnClr_I2C0;  while (times (NULL) < theFuture)  {    I2C0_CONCLR = I2C_CONSET_SI;    I2C0_CONSET = I2C_CONSET_STA;    while (!(I2C0_CONSET & I2C_CONSET_SI))      ;    I2C0_CONCLR = I2C_CONCLR_STAC | I2C_CONCLR_SIC;    I2C0_DAT = address & ~0x01;    while (!(I2C0_CONSET & I2C_CONSET_SI))      ;    if ((i2cErrno = I2C0_STAT) == I2CERR_SLAWTX_ACKRX)      break;  }  if (i2cErrno != I2CERR_SLAWTX_ACKRX)    i2cErrno = I2CERR_TIMEOUTACKPOLL;  I2C0_CONCLR = I2C_CONCLR_SIC;  I2C0_CONSET = I2C_CONSET_STO | I2C_CONSET_AA;  while (I2C0_CONSET & I2C_CONSET_STO)    ;  VIC_IntEnable = VIC_IntEnable_I2C0;  return (i2cErrno == I2CERR_SLAWTX_ACKRX) ? 0 : -1;}//////static int i2cKickOff (U8 address, U8 *buffer, int bufferLenWrite, int bufferLenRead, ackPoll_e ackPoll){  //  //  Determine if our first operation will be a write or read.  If both, the  //  write always occurs first.  //  if (bufferLenWrite)    address &= ~0x01;  else if (bufferLenRead)    address |= 0x01;  else    address &= ~0x01;  //  //  Wait until last I2C operation has finished.    //  if (i2cBusInUse && i2cWaitComplete (i2cTimeoutInTicks))  {    i2cErrno = I2CERR_TIMEOUT;    return -1;  }  //  //  Mark bus as in use, save the address, buffer and length  //  i2cBusInUse = TRUE;  i2cAddress = address;  i2cDataBuffer = buffer;  i2cDataLenWrite = bufferLenWrite;  i2cDataLenRead = bufferLenRead;  i2cDataCnt = 0;  i2cAckPoll = ackPoll;  i2cDebugReset ();  //  //  Clear any outstanding bits, enable the interface, and send a start bit.  //  Once the start bit goes out, the interrupt drive state machine begins.  //  I2C0_CONCLR = I2C_CONCLR_MASK;  I2C0_CONSET = I2C_CONSET_I2EN;  I2C0_CONSET = I2C_CONSET_STA;  return 0;}//////static int i2cWriteBufferEx (U8 address, U8 *buffer, U32 bufferLength, int milliseconds){  int r;  if (!(r = i2cKickOff (address, buffer, bufferLength, 0, ACKPOLL_NO)))    r = i2cWaitComplete (milliseconds / portTICK_RATE_MS);  return r;}static int i2cReadBufferEx (U8 address, U8 *buffer, U32 bufferLength, int milliseconds){  int r;  if (!(r = i2cKickOff (address, buffer, 0, bufferLength, ACKPOLL_NO)))    r = i2cWaitComplete (milliseconds / portTICK_RATE_MS);  return r;}static int i2cWriteReadBufferEx (U8 address, U8 *buffer, U32 putLength, U32 getLength, int milliseconds){  int r;  if (!(r = i2cKickOff (address, buffer, putLength, getLength, ACKPOLL_NO)))    r = i2cWaitComplete (milliseconds / portTICK_RATE_MS);  return r;}//////void i2cSetTimeout (unsigned int timeoutInMilliseconds){  if (timeoutInMilliseconds < portTICK_RATE_MS)    timeoutInMilliseconds = portTICK_RATE_MS;  i2cTimeoutInTicks = timeoutInMilliseconds / portTICK_RATE_MS;}void i2cDump (void){#ifdef I2C_DEBUG  int i;  for (i = 0; i < i2cTransactionsIndex; i++)    printf ("0x%02x ", i2cTransactions [i]);  printf ("\n");#else  printf ("Not compiled for i2c debugging\n");#endif}////  DANGER, WILL ROBINSON!  The callers buffer must persist until we're done//int i2cWriteBuffer (U8 address, U8 *buffer, U32 bufferLength){  return i2cWriteBufferEx (address, buffer, bufferLength, i2cTimeoutInTicks);}int i2cReadBuffer (U8 address, U8 *buffer, U32 bufferLength){  return i2cReadBufferEx (address, buffer, bufferLength, i2cTimeoutInTicks);}int i2cWriteReadBuffer (U8 address, U8 *buffer, U32 putLength, U32 getLength){  return i2cWriteReadBufferEx (address, buffer, putLength, getLength, i2cTimeoutInTicks);}int i2cWriteBufferPoll (U8 address, U8 *buffer, U32 bufferLength){  int r;  if (!(r = i2cKickOff (address, buffer, bufferLength, 0, ACKPOLL_NO)))    if (!(r = i2cWaitComplete (i2cTimeoutInTicks)))      r = i2cPoll (address);  return r;}int i2cWriteReadBufferPoll (U8 address, U8 *buffer, U32 putLength, U32 getLength){  int r;  if (!(r = i2cKickOff (address, buffer, putLength, getLength, ACKPOLL_NO)))    if (!(r = i2cWaitComplete (i2cTimeoutInTicks)))      r = i2cPoll (address);  return r;}

⌨️ 快捷键说明

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