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

📄 i2c_app.c

📁 大名鼎鼎的mpc8260的bsp源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    IO_SYNC;

    /* unmask processor interrupts */

   /* localIntUnlock(dontCare);*/
 
    /*
     * check for data transfer count mismatch, on match copy receive
     * buffer to caller's
     */

    if (!(pPckt->csword & (I2C_IO_S_ERROR))) 
	{
        if (pRxbd->dataLength != (pPckt->dataSize + 1)) 
	    {
            pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_X_CNT);
            pPckt->dataSizeActual = pRxbd->dataLength;
            return (ERROR);
            } 
        else 
	    {

            /*
             * retrieve character(s) from driver's buffer and move to
             * user's buffer
             */

            pS = (pRxbd->dataPointer + 1);
            pD = (UCHAR *)pPckt->dataAdrs;
            for (counter = pRxbd->dataLength - 1; counter; counter--) 
                *pD++ = *pS++;

            IO_SYNC;
            }
        } 
    else 
        return (ERROR);

    return (OK);
    }

/******************************************************************************
*
* mbxI2cdInit - initialize I2C bus controller
* 
* This component's purpose is to initialize the I2C bus
* controller.
*
* RETURNS: I2C buffer descriptor pointer
*/

LOCAL I2C_DRV_BD * mbxI2cdInit
    (
    FAST I2C_CMD_PKT *pPckt,      /* command packet pointer */
    FAST UINT immrVal           /* Base address of Internal Memory Regs */ 
    )
    {
    FAST I2C_DRV_BD *pI2cdrvBd;      /* buffer descriptor pointer */
    FAST SCC_BUF *pBd;               /* TXBD/RXBD pointer */
    FAST I2C_PARAM  *pI2cPram;      /* parameter RAM pointer */

    FAST USHORT varWork;    /* the old general purpose variable */
    FAST UINT varDiv;       /* clock divide variable */
    FAST UINT varBdi;       /* buffer descriptor index variable */
    FAST UINT varBa;        /* buffer allocation variable */
    UINT dprbase = (UINT)DPRAM(immrVal); /* Dual-Ported RAM base address */
    int dontCare;

    /*
     * setup local pointers and variables
     * initialize the base address to all buffers
     */

    pI2cdrvBd = (I2C_DRV_BD *)DPRAM_I2C_BD;
    varBa = (UINT)((UCHAR *)DPRAM_I2C_BUFFER);

    /* mask processor interrupts */

  /*  localIntLock(&dontCare);*/
 
    /* disable i2c operation */

    *I2MOD(immrVal) &= ~CPM_I2C_MODE_EN; 
    IO_SYNC;
 
    /* initialize I2C specifics:
     * first, initialize the I2C clock (keep below 100khz)
     *
     * MAX_MPU_SPEED is the likely maximum MPU speed for an MPC
     * for the near future.  We could call mpc8xx_clk_value()
     * here to determine the actual speed but to do so causes
     * very slow accesses to SROM contents.  Using MAX_MPU_SPEED
     * instead here is ugly but since the I2C clock frequency is
     * legitimately variable, it works for all the supported
     * speeds and is much faster than calculating the clock speed
     * for every SROM access.
     */

    varDiv = (MAX_MPU_SPEED) / 16; 
    varDiv /= I2C_CLK_SPD;            /* divide by I2C bus clock - 10khz */
    varDiv /= 2;
    varDiv -= 3;

    *I2BRG(immrVal) = (UCHAR)varDiv;
    *I2MOD(immrVal) = (CPM_I2C_MODE_PDIV_BRGCLK16);

    IO_SYNC;
 
    /* enable the I2CSDA/I2CSCL pins */

    *PBPAR(immrVal) |= PORT_B_PINS_I2C;
    IO_SYNC;

    *PBDIR(immrVal) |= PORT_B_PINS_I2C; 
    IO_SYNC;

    *PBODR(immrVal) |= PORT_B_PINS_I2C; 
    IO_SYNC;

    /* initialize receive buffers */

    pBd = (SCC_BUF *)&pI2cdrvBd->rxbd[0];
    for (varBdi = 0; varBdi < (I2C_DRV_NBDS-1); varBdi++, pBd++) 
	{
        I2C_WRITE(pBd->dataLength,0x0000);
        I2C_WRITE(pBd->dataPointer,varBa);

        varWork = (CPM_I2C_R_CS_E|CPM_I2C_R_CS_I);

        I2C_WRITE(pBd->statusMode,varWork);

        varBa += I2C_RXBL_MAX;    /* update buffer allocation variable */
        }
     
     I2C_WRITE(pBd->dataLength,0x0000);
     I2C_WRITE(pBd->dataPointer,varBa);

     varWork = (CPM_I2C_R_CS_E|CPM_I2C_R_CS_I|CPM_I2C_R_CS_W);

     I2C_WRITE(pBd->statusMode,varWork);

     varBa += I2C_RXBL_MAX;    /* update buffer allocation variable */
 
    /* initialize transmit buffers */
    pBd = (SCC_BUF *)&pI2cdrvBd->txbd[0];
    for (varBdi = 0; varBdi < (I2C_DRV_NBDS-1); varBdi++, pBd++) 
	{

        I2C_WRITE(pBd->dataLength,0x0000);
        I2C_WRITE(pBd->dataPointer,varBa);

        varWork = (CPM_I2C_T_CS_I|CPM_I2C_T_CS_L|CPM_I2C_T_CS_S);

        I2C_WRITE(pBd->statusMode,varWork);

        varBa += I2C_TXBL_MAX;    /* update buffer allocation variable */
        }

        I2C_WRITE(pBd->dataLength,0x0000);
        I2C_WRITE(pBd->dataPointer,varBa);

        varWork = (CPM_I2C_T_CS_I|CPM_I2C_T_CS_L|CPM_I2C_T_CS_S|CPM_I2C_T_CS_W);

        I2C_WRITE(pBd->statusMode,varWork);

        varBa += I2C_TXBL_MAX;    /* update buffer allocation variable */

    /* initialize parameter RAM specifics */

    
   #if 1 /*have patch*/
     pI2cPram = (I2C_PARAM *)PPC860_DPR_I2C_PATCH(dprbase);
   #else  /*no patch*/
    pI2cPram = (I2C_PARAM *)PPC860_DPR_I2C(dprbase);
   #endif
   /*ori*/
  /*  pI2cPram = (I2C_PARAM *)PPC860_DPR_I2C(dprbase);*/

    pI2cPram->rbase =
    (USHORT)((UINT)&pI2cdrvBd->rxbd[0] - (UINT)DPRAM(immrVal));
    pI2cPram->tbase =
    (USHORT)((UINT)&pI2cdrvBd->txbd[0] - (UINT)DPRAM(immrVal));

    pI2cPram->rfcr  = 0x15;
    pI2cPram->tfcr  = 0x15;
    pI2cPram->mrblr = I2C_RXBL_MAX;
    pI2cPram->ris   = 0x00000000;
    pI2cPram->rbptr = pI2cPram->rbase;
    pI2cPram->tis   = 0x00000000;
    pI2cPram->tbptr = pI2cPram->tbase;
 
    /* issue initialize Rx and Tx parameters command */

    if (!PPC860_I2C_PATCH_INSTALLED)
        mbxI2cdCcr (immrVal, CPM_CR_OPCODE_INIT_RT);
 
    /*
     * clear any previous interrupt status
     * disable all interrupts (polled mode)
     */

    I2C_WRITE(*I2CER(immrVal),I2C_INT_CLR);
    I2C_WRITE(*I2CMR(immrVal),I2C_INT_DSBL);
 
    /*
     * configure to master mode
     * enable i2c operation
     */

    *I2COM(immrVal) = CPM_I2C_COMMAND_MS; 
    IO_SYNC;
    *I2MOD(immrVal) |= CPM_I2C_MODE_EN; 
    IO_SYNC;
 
    /* unmask processor interrupts */
 
  /*  localIntUnlock(dontCare);*/
 
    return (pI2cdrvBd);        /* return buffer descriptor pointer */
    }
 
/******************************************************************************
*
* mbxI2cdIoctl - I/O control
* 
* This component's purpose is to perform the specified action
* as requested by the passed arguments:
* 
* argument #1 = input/output control flag
*                    I2C_IOCTL_W = write
*                    I2C_IOCTL_R = read
*                    I2C_IOCTL_O = read/or/write
*                    I2C_IOCTL_A = read/and/write
*                    I2C_IOCTL_AO = read/and/or/write
* argument #2 = address of register
* argument #3 = register size in bytes (1/2/4)
* argument #4 = data to write #1 (na for read)
* argument #5 = data to write #2 (na for read)
*
* RETURNS: readdata, if read operation
*/

LOCAL UINT mbxI2cdIoctl
    (
    FAST UINT ioctlflg, /* io control flag */
    FAST UINT pReg,    /* register pointer */
    FAST UINT size,    /* register size (1/2/4 bytes) */
    FAST UINT wdata1,   /* write data #1 */
    FAST UINT wdata2    /* write data #2 */
    )
    {
    FAST UINT rdata;
    FAST UCHAR *pReg1;
    FAST USHORT *pReg2;
    FAST UINT *pReg4;

    rdata = 0;           /* make the compiler happy */

    switch (size) 
	{
        case 1:
            pReg1 = (UCHAR *)pReg;
            if(ioctlflg == I2C_IOCTL_W)               /* write */
                *pReg1 = wdata1;
            else if(ioctlflg == I2C_IOCTL_R)          /* read */
                rdata = *pReg1;
            else if(ioctlflg == I2C_IOCTL_O)          /* read/or/write */
                *pReg1 |= wdata1;
            else if(ioctlflg == I2C_IOCTL_A)          /* read/and/write */
                *pReg1 &= wdata1;
            else if(ioctlflg == I2C_IOCTL_AO)         /* read/and/or/write */
                *pReg1 = (*pReg1 & wdata1) | wdata2;
            break;
        case 2:
            pReg2 = (USHORT *)pReg;
            if(ioctlflg == I2C_IOCTL_W)               /* write */
                *pReg2 = wdata1;
            else if(ioctlflg == I2C_IOCTL_R)          /* read */
                rdata = *pReg2;
            else if(ioctlflg == I2C_IOCTL_O)          /* read/or/write */
                *pReg2 |= wdata1;
            else if(ioctlflg == I2C_IOCTL_A)          /* read/and/write */
                *pReg2 &= wdata1;
            else if(ioctlflg == I2C_IOCTL_AO)         /* read/and/or/write */
                *pReg2 = (*pReg2 & wdata1) | wdata2;
            break;
        case 4:
            pReg4 = (UINT *)pReg;
            if(ioctlflg == I2C_IOCTL_W)               /* write */
                *pReg4 = wdata1;
            else if(ioctlflg == I2C_IOCTL_R)          /* read */
                rdata = *pReg4;
            else if(ioctlflg == I2C_IOCTL_O)          /* read/or/write */
                *pReg4 |= wdata1;
            else if(ioctlflg == I2C_IOCTL_A)          /* read/and/write */
                *pReg4 &= wdata1;
            else if(ioctlflg == I2C_IOCTL_AO)         /* read/and/or/write */
                *pReg4 = (*pReg4 & wdata1) | wdata2;
            break;
        }

    /* synchronize all data */

    IO_SYNC;

    return (rdata);
    }

/******************************************************************************
*
* mbxI2cdCcr - execute channel command
* 
* This component's purpose is to execute the command
* passed.  The channel command register is read prior
* to execution to verify that there are no outstanding
* commands, this is done by waiting for a zero status.
* The channel command register is also read after the command
* execution to insure command completion prior to returning.
*
* RETURNS: N/A
*/

LOCAL void mbxI2cdCcr
    (
    FAST UINT immrVal,          /* Base address of Internal Memory Regs */ 
    FAST UINT cmd               /* command to execute */
    )
    {

    /* wait for any pending commands to complete */

    while (*CPCR(immrVal) & CPM_CR_FLG)
	;

    /* issue command */

    *CPCR(immrVal) = (cmd | CPM_CR_CHANNEL_I2C | CPM_CR_FLG); 
    IO_SYNC;

    /* wait for issued command to complete */

    while (*CPCR(immrVal) & CPM_CR_FLG)
	;
    }

/******************************************************************************
* mbxI2cdAlarm - enable alarm
* 
* This component's purpose is to initialize the alarm feature
* of the RTC.  It's the caller's responsibility to the handle
* the event (i.e., if the interrupt is enabled).
*
* RETURNS: N/A
*/
#if 0
LOCAL void mbxI2cdAlarm
    (
    FAST UINT immrVal,          /* Base address of Internal Memory Regs */ 
    FAST UINT timeout           /* timeout value in seconds */
    )
    {

    /* clear any possible pending alarm event */
    /* SPR 65678, unlock/lock wrapper around RTCSC write */
#ifdef USE_KEYED_REGS
    *RTCSCK(immrVal) = KEYED_REG_UNLOCK_VALUE;
    IO_ISYNC;
    *RTCSC(immrVal) |= RTCSC_ALR; 
    *RTCSCK(immrVal) = ~KEYED_REG_UNLOCK_VALUE;
#else
    *RTCSC(immrVal) |= RTCSC_ALR; 
#endif
    IO_SYNC;

    /*
     * add timeout to current RTC value and store into the
     * alarm seconds counter
     */
    /* SPR 65678 */
#ifdef USE_KEYED_REGS
    *RTCALK(immrVal) = KEYED_REG_UNLOCK_VALUE;
    IO_ISYNC;
    *RTCAL(immrVal) = *RTC(immrVal) + timeout;
    *RTCALK(immrVal) = ~KEYED_REG_UNLOCK_VALUE;
#else
    *RTCAL(immrVal) = *RTC(immrVal) + timeout;
#endif

    }

#endif
 UINT I2CWrite(  UINT i2cDevAdrs,    unsigned char *pBuf,     int    len)
{


    I2C_CMD_PKT i2cp;             /* command packet */

    /* reset eeprom internal address index */
    i2cp.csword = (I2C_IO_C_WDATA);
    i2cp.devAdrs = i2cDevAdrs;
    i2cp.dataAdrs = (UINT)pBuf;	
    i2cp.dataSize = len;	


    /* call the MPC8xx I2C bus device driver, exit on error */
     semTake(semI2CMutex,WAIT_FOREVER); 
    mbxI2cdMain(&i2cp);
     semGive(semI2CMutex);

    if (i2cp.csword & I2C_IO_S_ERROR) 
	{
        return ((UINT)-1);
        }
    else
    	return OK;

}


 UINT  I2CRead(  UINT  i2cDevAdrs,    unsigned char *pBuf,     int    len)
{

    I2C_CMD_PKT i2cp;             /* command packet */

    /* reset  internal address index */
    i2cp.csword = (I2C_IO_C_WDATA);
    i2cp.dataAdrs = pBuf;
    i2cp.devAdrs = i2cDevAdrs;
    i2cp.dataSize = 1;

    /* call the MPC8xx I2C bus device driver, exit on error */

     semTake(semI2CMutex,WAIT_FOREVER); 
    mbxI2cdMain(&i2cp);
     semGive(semI2CMutex);

    if (i2cp.csword & I2C_IO_S_ERROR) 
	{
        return ((UINT)-1);
        }
    else
    	{
          i2cp.csword = (I2C_IO_C_RDATA);
          
          i2cp.devAdrs = i2cDevAdrs;
          i2cp.dataAdrs = (UINT)(pBuf );
          i2cp.dataSize = len;
    	  semTake(semI2CMutex,WAIT_FOREVER); 
         mbxI2cdMain(&i2cp);
     semGive(semI2CMutex);

         return (i2cp.dataSizeActual);
    	}

    if (i2cp.csword & I2C_IO_S_ERROR) 
	{
        return ((UINT)-1);
        }
    else
    	return OK;
}



 UINT  I2CKBRead(  UINT  i2cDevAdrs,    unsigned char *pBuf,     int    len)
{

    I2C_CMD_PKT i2cp;             /* command packet */

    /* call the MPC8xx I2C bus device driver, exit on error */
      i2cp.csword = (I2C_IO_C_RDATA);
      i2cp.devAdrs = i2cDevAdrs;
      i2cp.dataAdrs = (UINT)(pBuf );
      i2cp.dataSize = len;
     semTake(semI2CMutex,WAIT_FOREVER); 
         mbxI2cdMain(&i2cp);
     semGive(semI2CMutex);

    if (i2cp.csword & I2C_IO_S_ERROR) 
        return ((UINT)-1);
    else
          return (i2cp.dataSizeActual);
}



void I2CInit(void)
{
    semI2CMutex = semBCreate(SEM_Q_FIFO,SEM_FULL);
}


⌨️ 快捷键说明

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