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

📄 i2c.c

📁 其中包括88796网卡驱动、mbmflash驱动、i2c接口的eeprom驱动、oki的ml9620can网卡驱动、扩展的串口驱动源代码。适用于moto的ppc8××系列在vxworks环境下。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
* i2c.c - I2c Function.
* 
* This file contain all the functions about I2C bus. This function 
* include:
* (1) Initialize the PPC885 's I2C controller
* (2) Initialize the real time clock chip - DS1307
* (3) eeprom read function
* (4) eeprom write function
* (5) DS1307 read function 
* (6) DS1307 write function
*
**********************************************************************/

#include "vxWorks.h"
#include "stdio.h"
#include "string.h"
#include "drv/multi/ppc860Siu.h"
#include "drv/sio/ppc860Sio.h"
#include "ads88x.h"
#include "i2c.h"
#include "config.h"

#define I2C_TXBD_OFF	0x600
#define I2C_RXBD_OFF	(I2C_TXBD_OFF + 0x10)
#define I2C_TXBUF_OFF   0x700
#define I2C_RXBUF_OFF   (I2C_TXBUF_OFF + 0x50)

#ifdef AT24C256
#define EEPROM_MEM_SIZE  0x4000
#define PAGE_SIZE   64
#define PAGE_NUM_MAX    (EEPROM_MEM_SIZE/PAGE_SIZE)
#endif

#ifdef AT24C16
#define EEPROM_MEM_SIZE  0x800
#define PAGE_SIZE   16
#define PAGE_NUM_MAX    (EEPROM_MEM_SIZE/PAGE_SIZE)
#endif

#define EEPROM_DELAY_TIME	25000
#define RTC_DELAY_TIME		6000

I2C_DEV *pChan;

extern UINT32 vxImmrIsbGet(void);

void delay(int n);

/**********************************************************************
* readAddrVerify - verify the read address of slave device
*
* For read operation, the lsb bit of device address is '1'.
*
* RETURN: OK or ERROR
**********************************************************************/

STATUS readAddrVerify(UCHAR deviceAddr)
{
    if((deviceAddr & 0x01) == 0x00)
    {
    	   printf("It's not a valid read address\n");
        return(ERROR);
     }

    return(OK);
}

/**********************************************************************
* writeAddrVerify - verify the write address of slave device
*
* For write operation, the lsb bit of device address is '0'.
*
* RETURN: OK or ERROR
**********************************************************************/

STATUS writeAddrVerify(UCHAR deviceAddr)
{
    if((deviceAddr & 0x01) == 0x01)
    {
    	   printf("It's not a valid write address\n");
        return(ERROR);
     }

    return(OK);
}

/**********************************************************************
* I2cInit - initialize the MPC885's i2c controller
*
* Initialize the MPC885's i2c controller including:
* (1) set PB26 PB27 as I2CSCL and I2CSDA
* (2) initialize the i2c's parameter RAM
* (3) initialize the i2c's registers
* (4) initialize the i2c's BD. There has one RXBD and one TXBD
* If you want detail information about this, please see the MPC885's 
* User Manual in detail.
*
* RETURN: none
**********************************************************************/

STATUS I2cInit(void)
{
	UINT32	regBase;

    /* get the registers' base address */
	
    regBase = vxImmrIsbGet ();
	
    /* set PB26 PB27 as I2CSCL and I2CSDA */

    *PBODR(regBase) |= (PB26 | PB27);
    *PBPAR(regBase) |= (PB26 | PB27);
    *PBDIR(regBase) |= (PB26 | PB27);

    /* get the parameter RAM address */
	
    pChan->i2cParam = (I2C_PARAM *) PPC860_DPR_I2C (MPC860_DPRAM_BASE(regBase));
	
    pChan->i2cParam->rbase = (UINT16) (I2C_RXBD_OFF);
    pChan->i2cParam->tbase = (UINT16) (I2C_TXBD_OFF);

    /* set the parameter RAM */
	
    pChan->i2cParam->rfcr = 0x10;
    pChan->i2cParam->tfcr = 0x10;
    pChan->i2cParam->mrblr = 0x50;     /* maximum receive buffer length is 64 bytes */
	
    *CPCR(regBase) = 0x11;      /* initialize i2c RX and TX parameter RAM */
	
    *I2MOD(regBase) = 0x00;
    *I2BRG(regBase) = 0x20;     /* set the i2c baudrate */
    *I2ADD(regBase) = 0x80;     /* set the i2c controller's address */
    *I2CER(regBase) = 0x17;     /* clear all interrupt pending bit */
    *I2CMR(regBase) = 0x00;     /* mask all interrupt */
    *I2COM(regBase) = 0x01;     /* set i2c as master */
    *I2MOD(regBase) = 0x01;     /* enable i2c controller */

    /* get the transmit and receive BD address */
	
    pChan->i2cRxBuf = (I2C_BUF *)(MPC860_DPRAM_BASE(regBase) + I2C_RXBD_OFF);
    pChan->i2cTxBuf = (I2C_BUF *)(MPC860_DPRAM_BASE(regBase) + I2C_TXBD_OFF);

    /* initialize the RXBD */
	
    pChan->i2cRxBuf->statusMode = 0xb000;
    pChan->i2cRxBuf->dataLength = 0x0;
    pChan->i2cRxBuf->dataPointer = (u_char *)(MPC860_DPRAM_BASE(regBase) + I2C_RXBUF_OFF);

    /* initialize the TXBD */

    pChan->i2cTxBuf->statusMode = 0x3c00;
    pChan->i2cTxBuf->dataPointer = (u_char *)(MPC860_DPRAM_BASE(regBase) + I2C_TXBUF_OFF);
  
/*  
    	if (eepromWriteEnable() == ERROR)
	{
		return (ERROR);
	}
*/
	
	return (OK);
}

/**********************************************************************
* I2cStart - generate a start operation and sending data
*
* RETURN: none
**********************************************************************/

void I2cStart(UINT32 regBase)
{   
    *I2COM(regBase) |= 0x80;
}

/**********************************************************************
* eepromWriteEnable - be enable to write eeprom
*
* RETURN: OK or ERROR
**********************************************************************/

STATUS eepromWriteEnable(void)
{
     UCHAR intStat;
	u_char *txPtr;
	UINT32 regBase = vxImmrIsbGet();
	
	txPtr = pChan->i2cTxBuf->dataPointer;
	
	txPtr[0] = 0xa0;
     txPtr[1] = 0xff;
     txPtr[2] = 0xff;
     txPtr[3] = 0x02;
     
     pChan->i2cTxBuf->statusMode = 0x3c00;
     pChan->i2cTxBuf->dataLength = 0x04;
     pChan->i2cTxBuf->statusMode |= 0x8000;
     
     I2cStart (regBase);
     
     while((pChan->i2cTxBuf->statusMode) & 0x8000);
     
     if (pChan->i2cTxBuf->statusMode & 0x0004 )
     {
     	*I2CER(regBase) = 0x17;
     	printf ("eepromWriteEnable: no ACK\n");
     	return (ERROR);
     }
     	
     intStat = *I2CER(regBase);

     if (intStat & 0x10)
     {
        *I2CER(regBase) = 0x17;
        return(ERROR);
     }
     
     *I2CER(regBase) = 0x17;
     
     delay (EEPROM_DELAY_TIME);
     
     return(OK);
}

/**********************************************************************
* eepromWriteDisable - be disable to write eeprom
*
* RETURN: OK or ERROR
**********************************************************************/

STATUS eepromWriteDisable(void)
{
     UCHAR intStat;
	u_char *txPtr;
	UINT32 regBase = vxImmrIsbGet();
	
	txPtr = pChan->i2cTxBuf->dataPointer;
	
	txPtr[0] = 0xa0;
     txPtr[1] = 0xff;
     txPtr[2] = 0xff;
     txPtr[3] = 0x00;
     
     pChan->i2cTxBuf->statusMode = 0x3c00;
     pChan->i2cTxBuf->dataLength = 0x04;
     pChan->i2cTxBuf->statusMode |= 0x8000;
     
     I2cStart (regBase);
     
     while((pChan->i2cTxBuf->statusMode) & 0x8000);
     
     if (pChan->i2cTxBuf->statusMode & 0x0004 )
     {
     	*I2CER(regBase) = 0x17;
     	printf ("eepromWriteDisable: no ACK\n");
     	return (ERROR);
     }
     	
     intStat = *I2CER(regBase);

     if (intStat & 0x10)
     {
        *I2CER(regBase) = 0x17;
        return(ERROR);
     }
     
     *I2CER(regBase) = 0x17;
     
     delay (EEPROM_DELAY_TIME);

    return(OK);
}


/**********************************************************************
* eepromByteWrite -  write a byte to eeprom
*
* RETURN: OK or ERROR
**********************************************************************/

STATUS eepromByteWrite(UCHAR deviceAddr, UCHAR wordAddrH, UCHAR wordAddrL, char data)
{
	UCHAR intStat;
	UCHAR count = 0;
	u_char *txPtr;
	UINT32 regBase = vxImmrIsbGet();
	UINT16 offset;
	
	if (writeAddrVerify(deviceAddr) == ERROR)
	{
		return (ERROR);
	}
	
	offset = wordAddrH * 256 + wordAddrL;
	
	if (offset >= EEPROM_MEM_SIZE)
	{
		printf ("Invalid address\n");
		return (ERROR);
	}
	
	txPtr = pChan->i2cTxBuf->dataPointer;
	
#ifdef AT24C16

	deviceAddr &= (~0x0e);
	deviceAddr |= (wordAddrH<<1);
	
	txPtr[0] = deviceAddr;
     txPtr[1] = wordAddrL;
     txPtr[2] = data;
     
     pChan->i2cTxBuf->statusMode = 0x3c00;
     pChan->i2cTxBuf->dataLength = 0x03;
     pChan->i2cTxBuf->statusMode |= 0x8000;
#else
	txPtr[0] = deviceAddr;
     txPtr[1] = wordAddrH;
     txPtr[2] = wordAddrL;
     txPtr[3] = data;
     
     pChan->i2cTxBuf->statusMode = 0x3c00;
     pChan->i2cTxBuf->dataLength = 0x04;
     pChan->i2cTxBuf->statusMode |= 0x8000;
#endif     
     
     I2cStart (regBase);
     
     while((pChan->i2cTxBuf->statusMode) & 0x8000);
     
     if (pChan->i2cTxBuf->statusMode & 0x0007)
     {
     	*I2CER(regBase) = 0x17;
     	return (ERROR);
     }
     	
     intStat = *I2CER(regBase);

     if (intStat & 0x10)
     {
        *I2CER(regBase) = 0x17;
        return(ERROR);
     }
     
     *I2CER(regBase) = 0x17;
     
     delay (EEPROM_DELAY_TIME);
 
/*    
     do
     {
     	pChan->i2cTxBuf->statusMode = 0x3c00;
          pChan->i2cTxBuf->dataLength = 0x03;
          pChan->i2cTxBuf->statusMode |= 0x8000;
          
          I2cStart (regBase);
          
          while((pChan->i2cTxBuf->statusMode) & 0x8000);
          
          if ((count++) >100)
          {
          	*I2CER(regBase) = 0x17;
          	printf ("polling timeout\n");
          	return (ERROR);
          }
          
          delay (EEPROM_DELAY_TIME);
          
     } while (pChan->i2cTxBuf->statusMode & 0x0004 );
     
     *I2CER(regBase) = 0x17;
     
     delay (EEPROM_DELAY_TIME);

*/     
     return(OK);
}

/**********************************************************************
* eepromPageWrite -  page write to eeprom
*
* This function is used to write a page to eeprom. A page is 64 byte.
* You can write less number, but cannot write more than 64 byte, or
* it will roll over the page head and destroy the exsiting data.
*
* RETURN: the number that you write to eeprom or ERROR if failed
**********************************************************************/

STATUS eepromPageWrite(UCHAR deviceAddr, int pageNum, UCHAR offset, char *buf, int number)
{
	UCHAR wordAddrH;
	UCHAR wordAddrL;
	UINT16 address;
	UCHAR intStat;
	UCHAR count = 0;
	u_char *txPtr;
	UINT32 regBase = vxImmrIsbGet();
	
	printf ("deviceAddr = %x\n", deviceAddr);
	printf ("pageNum = %x\n", pageNum);
	printf ("offset = %x\n", offset);
	printf ("number = %x\n", number);
	printf ("buf: %s\n", buf);
	
	if ((buf == NULL) ||(number < 0) || (number > PAGE_SIZE))
	{
	   return(ERROR);
	}
	
	if((pageNum >= PAGE_NUM_MAX) || (offset >= PAGE_SIZE))
	{
	   printf("Invalid address\n");
	   return(ERROR);
	}
	
	if (writeAddrVerify(deviceAddr) == ERROR)
	{
		return (ERROR);
	}
	
	txPtr = pChan->i2cTxBuf->dataPointer;

#ifdef AT24C16
	deviceAddr &= (~0x0e);
	deviceAddr |= (pageNum<<1);
	
	txPtr[0] = deviceAddr;
	txPtr[1] = offset;
	
	 memcpy((txPtr + 2), buf, number);
     
     pChan->i2cTxBuf->statusMode = 0x3c00;
     pChan->i2cTxBuf->dataLength = (number + 2);
     pChan->i2cTxBuf->statusMode |= 0x8000;
     
#else
	address = (pageNum * PAGE_SIZE) + offset;
	wordAddrL = (UCHAR) (address & 0xff);
	wordAddrH = (UCHAR) ((address & 0xff00) >> 8);
	
	txPtr[0] = deviceAddr;
     txPtr[1] = wordAddrH;
     txPtr[2] = wordAddrL;
     
     memcpy((txPtr + 3), buf, number);
     
     pChan->i2cTxBuf->statusMode = 0x3c00;
     pChan->i2cTxBuf->dataLength = (number + 3);
     pChan->i2cTxBuf->statusMode |= 0x8000;
     
#endif
     
     I2cStart (regBase);
     
     while((pChan->i2cTxBuf->statusMode) & 0x8000);
     
     if (pChan->i2cTxBuf->statusMode & 0x0007)
     {
     	*I2CER(regBase) = 0x17;
     	return (ERROR);
     }
     	
     intStat = *I2CER(regBase);

     if (intStat & 0x10)
     {
        *I2CER(regBase) = 0x17;
        return(ERROR);
     }
     
     *I2CER(regBase) = 0x17;
     
     delay (EEPROM_DELAY_TIME);
 
 /*    
     do
     {
     	pChan->i2cTxBuf->statusMode = 0x3c00;
          pChan->i2cTxBuf->dataLength = 0x03;
          pChan->i2cTxBuf->statusMode |= 0x8000;
          
          I2cStart (regBase);
          
          while((pChan->i2cTxBuf->statusMode) & 0x8000);
          
          if ((count++) >100)
          {
          	*I2CER(regBase) = 0x17;
          	printf ("polling timeout\n");
          	return (ERROR);
          }
          
          delay (EEPROM_DELAY_TIME);
          
     } while (pChan->i2cTxBuf->statusMode & 0x0004 );
     
     *I2CER(regBase) = 0x17;
     
     delay (EEPROM_DELAY_TIME);
 */
	
	return(OK);
}

/**********************************************************************
* eepromCurrentRead -  read a byte of current address from eeprom
*
* RETURN: the number that you write to eeprom or ERROR if failed
**********************************************************************/


STATUS eepromCurrentRead(UCHAR deviceAddr, char *data)
{
    UCHAR *txPtr;
    UCHAR *rxPtr;
    UINT32 regBase;
    UCHAR intStat;

    if(readAddrVerify(deviceAddr) == ERROR)
    {
        return(ERROR);
	}
    regBase = vxImmrIsbGet();

    txPtr = pChan->i2cTxBuf->dataPointer;

    txPtr[0] = deviceAddr;

    pChan->i2cTxBuf->statusMode = 0x3c00;
    pChan->i2cTxBuf->dataLength = 2;
    pChan->i2cTxBuf->statusMode |= 0x8000;

    I2cStart(regBase);

    while((pChan->i2cTxBuf->statusMode) & 0x8000);

    if (pChan->i2cTxBuf->statusMode & 0x0007)
     {
     	*I2CER(regBase) = 0x17;
     	return (ERROR);
     }
     	
     intStat = *I2CER(regBase);

     if (intStat & 0x10)
     {
        *I2CER(regBase) = 0x17;
        return(ERROR);
     }
     
     *I2CER(regBase) = 0x12;
     
    while((pChan->i2cRxBuf->statusMode) & 0x8000);

    intStat = *I2CER(regBase);

    if ((intStat & 0x01) != 0x01) {
        *I2CER(regBase) = 0x17;
        return(ERROR);
    }

    rxPtr = pChan->i2cRxBuf->dataPointer;
    *data = *rxPtr;

    pChan->i2cRxBuf->statusMode = 0xb000;
    pChan->i2cRxBuf->dataLength = 0x0;
    
    delay (EEPROM_DELAY_TIME);

    return(OK);
}


/*********************************************************************
* eepromRandomRead - random read from eeprom.
*
* RETURN: OK or ERROR.
*/

STATUS eepromRandomRead (UCHAR deviceAddr, UCHAR wordAddrH, UCHAR wordAddrL, char *data)
{
	UCHAR intStat;
	UCHAR count = 0;
	u_char *txPtr;
	u_char *rxPtr;
	UINT32 regBase = vxImmrIsbGet();
	UINT16 offset;
	
	if (readAddrVerify(deviceAddr) == ERROR)
	{
		return (ERROR);
	}
	
	offset = wordAddrH * 256 + wordAddrL;
	
	if (offset >= EEPROM_MEM_SIZE)
	{
		printf ("Invalid address\n");
		return (ERROR);
	}
	
	txPtr = pChan->i2cTxBuf->dataPointer;

⌨️ 快捷键说明

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