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

📄 mbxi2c.c

📁 适用于ppc8xx的i2驱动程序文件(mbxi2.rar)
💻 C
📖 第 1 页 / 共 3 页
字号:
    /*     * 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) / 4;     varDiv /= I2C_CLK_SPD;            /* divide by I2C bus clock - 90khz */    varDiv /= 2;    varDiv -= 3;    *I2BRG(immrVal) = (UCHAR)varDiv;    *I2MOD(immrVal) = (CPM_I2C_MODE_PDIV_BRGCLK4);    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 */    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*/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    }/******************************************************************************** mbxI2cEepromRead - read EEPROM for DRAM information** This function's purpose is to retrieve the serial presence* detect data (the first 16 bytes) from the specified EEPROM.* These EEPROMs are located on the I2C bus.** RETURNS: size of DRAM array in bytes if OK or* -1 if I2C device access error, -2 if data failed sanity check*/LOCAL UINT mbxI2cEepromRead    (    FAST UINT i2cDevAdrs,        /* I2C device address */    FAST UCHAR *pBuf,         /* buffer pointer (>= 16 bytes) */    FAST UINT epromType         /* EEPROM type: 0 = IBM, 1 = MOT */    )    {    FAST UINT counter;       /* counter variable */    FAST UINT value;       /* data variable */    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 = 1;    *pBuf = 0x00;    /* call the MPC8xx I2C bus device driver, exit on error */    mbxI2cdMain(&i2cp);    if (i2cp.csword & I2C_IO_S_ERROR) 	{        return ((UINT)-1);        }    /* if the EEPROM type is an IBM, just read the first 16 bytes */    if (epromType == 0) 	{        for (counter = 0; counter < 16; counter += 4) 	    {            /* read 4 bytes from the device */            i2cp.csword = (I2C_IO_C_RDATA);            i2cp.devAdrs = i2cDevAdrs;            i2cp.dataAdrs = (UINT)(pBuf + counter);            i2cp.dataSize = 4;            /* call the MPC8xx I2C bus device driver, exit on error */            mbxI2cdMain(&i2cp);            if (i2cp.csword & I2C_IO_S_ERROR) 		{                return ((UINT)-1);                }            }        }       /*     * make some sense of the information read, basically perform     * a sanity check on the data which is used to determine the     * size and speed of the DRAM array     */    counter = 0;    value = *(pBuf + 3) & 0x7F;                         /* rows */    if ((value < 8) || (value > 14)) 	counter++;    value = *(pBuf + 4);                                /* columns */    if ((value < 8) || (value > 14)) 	counter++;    value = *(pBuf + 5);                                /* banks */    if ((value < 1) || (value > 4))         counter++;    value = *(pBuf + 6) / 32;                           /* width (lo) */    if ((value < 1) || (value > 2))         counter++;    value = *(pBuf + 7);                                /* width (hi) */    if (value)         counter++;    value = *(pBuf + 9);                                /* RAS access */

⌨️ 快捷键说明

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