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

📄 cpvi2c.c

📁 VxWorks下 Cpv3060的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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)        cpvI2cdCcr (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 */    } /******************************************************************************** cpvI2cdIoctl - 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 cpvI2cdIoctl    (    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);    }/******************************************************************************** cpvI2cdCcr - 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 cpvI2cdCcr    (    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)	;    }/******************************************************************************** cpvI2cdAlarm - 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 cpvI2cdAlarm    (    FAST UINT immrVal,          /* Base address of Internal Memory Regs */     FAST UINT timeout           /* timeout value in seconds */    )    {    /* clear any possible pending alarm event */    *RTCSC(immrVal) |= RTCSC_ALR;     IO_SYNC;    /*     * add timeout to current RTC value and store into the     * alarm seconds counter     */    *RTCAL(immrVal) = *RTC(immrVal) + timeout;    }/******************************************************************************** cpvI2cEepromRead - read EEPROM for DRAM information** This function's purpose is to retrieve the serial presence* detect data (need the first 32 bytes) from the specified EEPROM.* These EEPROMs are located on the I2C bus.* * This routine is responsible for determining the size of the on-board* SDRAM.  It uses values read from the serial presence detect data to* perform the sizing.  The following fields are used in the sizing * algorithm:*    rows - number of row address lines per bank (byte 3)*    cols - number of column address lines per bank (byte 4)*    pBanks - number of physical banks (byte 5)*    dBanks - number of logical banks per device (byte 17)*    dWidth - data width, in bits of memory (byte 6)** The algorithm for determining the size of the SDRAM is:** total size in bytes = *    (2**rows * 2**cols) * (dWidth / 4) * (pBanks * dBanks)** RETURNS: size of DRAM array in bytes if OK or* -1 if I2C device access error, -2 if data failed sanity check*/UINT cpvI2cEepromRead    (    FAST UINT i2cDevAdrs,        /* I2C device address */    FAST UCHAR *pBuf,            /* buffer pointer (>= 32 bytes) */    FAST UINT epromType          /* EEPROM type: 0 = IBM, 1 = MOT */    )    {    FAST UINT value;             /* data variable */    FAST UINT counter;           /* counter variable */    FAST UINT bankSize;          /* used for calculating the size of memory */    FAST UINT bankAddrLines;	 /* set to total number of rows and columns */    FAST UINT dataWidth;	 /* data width size (in bits) */    FAST UINT memBanks;		 /* total number of mem. banks on the board */    FAST UINT devBanks;		 /* number of banks per device */    FAST UINT memSize;		 /* size of SDRAM */    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 */    cpvI2cdMain(&i2cp);    if (i2cp.csword & I2C_IO_S_ERROR) 	{        return ((UINT)-1);        }    /* if the EEPROM type is an IBM, just read the first 32 bytes */    if (epromType == 0) 	{        for (counter = 0; counter < 32; 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 */            cpvI2cdMain(&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 + SPD_ROW_ADDR_INDEX) & 0x7F;	/* rows */    if ((value < 8) || (value > 14)) 	counter++;    bankAddrLines = value;    value = *(pBuf + SPD_COL_ADDR_INDEX);		/* columns */    if ((value < 8) || (value > 14)) 	counter++;    bankAddrLines += value;    value = *(pBuf + SPD_NUM_PHYSBANKS_INDEX);		/* physical banks */    if ((value < 1) || (value > 4))         counter++;    memBanks = value;    /* save data width in bytes */    dataWidth = *(pBuf + SPD_DATA_WIDTH_INDEX) / 8;	/* width (lo) */    if ((dataWidth != 4) && (dataWidth != 8))	counter++;    value = *(pBuf + SPD_DATA_WIDTH_HI_INDEX);		/* width (hi) */    if (value)         counter++;    value = *(pBuf + SPD_TCYC_INDEX);			/* CAS access */    if ((value & 0x0f) > 9)         counter++;    devBanks = *(pBuf + SPD_DEV_BANKS_INDEX);		/* banks per device */    if (devBanks == 0)         counter++;    /* if an bounds error has occurred, return error code */    if (counter)         return ((UINT)-2);    /* calculate the total SDRAM size */    bankSize = (1 << bankAddrLines); /* size of 1 bank = 2**rows * 2**columns */    /* total banks = num physical banks * num of banks per device */    memBanks = (memBanks * devBanks);    /*      * multiply it all together to get the total size      * (in bytes) of the onboard memory      */    memSize = (bankSize * memBanks * dataWidth);    return (memSize);    }/******************************************************************************** cpvI2cSromRead - read SROM 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*/UINT cpvI2cSromRead    (    FAST UINT i2cDevAdrs,	/* I2C device address */    FAST UCHAR *pBuf,    	/* buffer pointer (>= 16 bytes) */    FAST UINT devOffset, 	/* I2C address offset */    FAST UINT byteCount  	/* I2C bytes to read */    )    {    FAST UINT counter;		/* counter variable */    FAST UINT inc;		/* increment size 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 = devOffset;		/* start from desired offset */    /* call the MPC8xx I2C bus device driver, exit on error */    cpvI2cdMain(&i2cp);    if (i2cp.csword & I2C_IO_S_ERROR)         return ((UINT)-1);    if (byteCount % 4)        inc = 1;                /* not evenly divisible by 4. */    else        inc = 4;		/* evenly divisible by 4. */    for (counter = 0; counter < byteCount; counter += inc) 	{        /* read "inc" bytes from the device */        i2cp.csword = (I2C_IO_C_RDATA);        i2cp.devAdrs = i2cDevAdrs;        i2cp.dataAdrs = (UINT)(pBuf + counter);        i2cp.dataSize = inc;        /* call the MPC8xx I2C bus device driver, exit on error */        cpvI2cdMain(&i2cp);        if (i2cp.csword & I2C_IO_S_ERROR)             return ((UINT)-1);        }    return (0);    }/******************************************************************************** localIntLock - Disable interrupts* * This function saves the current interrupt state and disables* interrupts.  localIntLock() and localIntUnlock() support ONLY* functions within this file.  It is necessary for this file* to be totally self contained (not access any routines not* defined in this file) in order to avoid build errors when* building the compressed boot ROMs.** See also: localIntUnlock()** RETURNS: N/A*/LOCAL void localIntLock    (    UINT *key		/* save the current interrupt state */    )    {    WRS_ASM(" mfmsr  4");    WRS_ASM(" stw    4, 0(3)");    WRS_ASM(" rlwinm 3, 4, 0, 17, 15");    WRS_ASM(" mtmsr  3");    WRS_ASM(" isync");    }/******************************************************************************** localIntUnlock - Restore original interrupt state* * This function restores the interrupt state which was in effect* when localIntLock() was last called with the "key" input* parameter.  localIntLock() and localIntUnlock() support ONLY* functions within this file.  It is necessary for this file to* be totally self contained (not access any routines outside of* this file) in order to avoid build errors when building the* compressed boot ROMs.** See also: localIntLock()** RETURNS: N/A*/LOCAL void localIntUnlock    (     UINT key		/* input requires value returned from lock call */    )    {    WRS_ASM(" rlwinm 3, 3, 0, 16, 16");    WRS_ASM(" mfmsr  4");    WRS_ASM(" or     3, 4, 3");    WRS_ASM(" mtmsr  3");    }

⌨️ 快捷键说明

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