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

📄 mbxi2c.c

📁 适用于ppc8xx的i2驱动程序文件(mbxi2.rar)
💻 C
📖 第 1 页 / 共 3 页
字号:
/* mbxI2c.c - I2C bus interface for PPC 8xx *//* Copyright 1998-2001 Wind River Systems, Inc. *//* Copyright 1997,1998,1999 Motorola, Inc., All Rights Reserved *//*modification history--------------------01k,30jan02,dtr  Removing inline asm for diab compatibility.01j,16oct01,dtr  Putting in fix for SPR65678 plus mod history.01g,09apr01,rip  added KEYED_REG unlock/lock wrappers (SPR 65678)01i,16sep01,dat  Use of WRS_ASM macro01h,10mar00,rcs  merge mot's latest version01g,17aug99,rhk  fixed memory autosizing problem in routine mbxI2cMemcConfig.01f,16mar99,rhk  fixed potential SROM parsing problem in mbxI2cSromValueGet.01e,11mar99,srr  add 32/64/128 MB onboard/DIMM DRAM support.01d,25mar98,map  code cleanup01c,21nov97,rhk  cleanup to comply with WRS code review01b,27sep97,scb  Modified for crystal or 1:1 oscillator input clock.01a,17jun97,scb  written by rb, integrated by scb.*//*DESCRIPTIONThis module implements the I2c bus access functions for PPC 8xx, and includes initilization of DPRAM from values in SROM.This module is linked in with others to create the compressed bootrom image,and also separately included in sysLib.c to make routines available tosysHwInit().  It is thus necessary for this module to beself-contained. Therefore there are no external references in this module.The mbxI2cdMain() or mbxI2cdInit() should be called when CPU interrupts arenot enabled, so they should not typically be called after sysHwInit2().  areexecuting.  This implies that this routine not be called after*//* includes */#include "vxWorks.h"            /* types */#include "intLib.h"#include "drv/multi/ppc860Siu.h"#include "drv/sio/ppc860Sio.h"#include "drv/multi/ppc860Cpm.h"#include "config.h"             /* mbx860 BSP definitions */#include "vxLib.h"#include "mbxI2c.h"             /* I2C I/O definitions *//* externals *//* defines */#define OR_OPTIONS_BITS_MSK	0x0007fff#define IO_SYNC  WRS_ASM(" sync") /* Macro for all i/o operations to use */#define IO_ISYNC  WRS_ASM(" isync") /* Macro for all i/o operations to use *//* I2C IOCTL data macros */#define I2C_WRITE(registername, data)                                   \	mbxI2cdIoctl(I2C_IOCTL_W, &registername, sizeof (registername), data)#define I2C_READ(registername)                   			\	mbxI2cdIoctl(I2C_IOCTL_R, &registername, sizeof (registername))#define I2C_OR(registername, data)                			\	mbxI2cdIoctl(I2C_IOCTL_O, &registername, sizeof (registername), data)#define I2C_AND(registername, data)               			\	mbxI2cdIoctl(I2C_IOCTL_A, &registername,sizeof (registername), data)#define I2C_ANDOR(registername, data1, data2)                            \	mbxI2cdIoctl(I2C_IOCTL_AO, &registername, sizeof (registername), \                     data1, data2)/* typedefs *//* globals */void mbxI2cConfigParamsGet();       	/* Fetch config. info. from SROM */void mbxI2cMemcConfig();/* locals */LOCAL STATUS mbxI2cdMain();          /* i2c driver main */LOCAL void mbxI2cdAlarm();           /* enable alarm */LOCAL void mbxI2cdCcr();             /* execute i2c command */LOCAL I2C_DRV_BD *mbxI2cdInit();     /* initialize i2c bus controller */LOCAL UINT mbxI2cdIoctl();           /* i2c I/O control */LOCAL UINT mbxI2cEepromRead();       /* read EEPROM for DRAM information */LOCAL UINT mbxI2cSromRead();         /* read SROM for DRAM information */LOCAL int  mbxI2cSromValueGet();     /* read SROM value */IMPORT void localIntLock();	     /* Disable interrupts */IMPORT void localIntUnlock();	     /* Reestablish interrupt state *//* forward declarations *//******************************************************************************** mbxI2cdMain - i2c driver main* * This function is the main entry point into the driver,* the driver is responsible for handling the specified* command request, the specified command requests are* local to the module.** Possible command requests (entry points):*         transmit (put/write) data packet*         receive (get/read) data packet* notes:*      1. error codes are passed back via the control/status word*         field of the command packet** RETURNS: OK, and ERROR on failure*/LOCAL STATUS mbxI2cdMain    (    FAST I2C_CMD_PKT *pPckt           /* command packet pointer */    )    {    FAST I2C_DRV_BD *pI2cdrvBd;    /* buffer descriptor pointer */    FAST SCC_BUF  *pRxbd;          /* RXBD pointer */    FAST SCC_BUF  *pTxbd;          /* TXBD pointer */    FAST UINT counter;              /* general purpose counter variable */    FAST UCHAR *pS;                /* general purpose buffer pointer */    FAST UCHAR *pD;                /* general purpose buffer pointer */    int dontCare;    UINT immrVal = INTERNAL_MEM_MAP_ADDR; /* Base address of Internal Memory */    /* check transfer size */    if (pPckt->csword & I2C_IO_C_RDATA) 	{        if ((pPckt->dataSize + 1) > I2C_RXBL_MAX) 	    {            pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_X_BUF);            return (ERROR);            }        }    if (pPckt->csword & I2C_IO_C_WDATA) 	{        if ((pPckt->dataSize + 1) > I2C_TXBL_MAX) 	    {            pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_X_BUF);            return (ERROR);            }        }        /* initialize I2C bus controller */    pI2cdrvBd = mbxI2cdInit(pPckt, immrVal);    /* setup pointers to transmit/receive buffer descriptors */    pRxbd = (SCC_BUF *)&pI2cdrvBd->rxbd[0];    pTxbd = (SCC_BUF *)&pI2cdrvBd->txbd[0];    /* perform transmit operation, any operation requires it     *     * retrieve character(s) from user's buffer and move to     * the transmit buffer     */    pS = (UCHAR *)pPckt->dataAdrs;    pD = pTxbd->dataPointer;    *pD = (UCHAR)(pPckt->devAdrs & 0xFE);    if (pPckt->csword & I2C_IO_C_RDATA)         *pD |= 0x01;    for (++pD, counter = pPckt->dataSize; counter; counter--)         *pD++ = *pS++;    IO_SYNC;    /* mask processor interrupts */    localIntLock(&dontCare);    /*     * give transmit buffer descriptor to I2C (i.e., transmit     * the buffer)     */    I2C_WRITE(pTxbd->dataLength,pPckt->dataSize + 1);    I2C_OR(pTxbd->statusMode,CPM_I2C_T_CS_R);    /*     * clear the slave address register, we do this due to the fact     * that the I2C bus controller (i.e., the MPC8xx) will answer to     * the transmitted buffer if the contents of the slave address     * register equals the device address that we're communicating     * with (only on I2C bus write operations)     */    *I2ADD(immrVal) = 0x00;    if (pPckt->csword & I2C_IO_C_RDATA)         *I2ADD(immrVal) = (UCHAR)((pPckt->devAdrs & 0xFE) | 0x01);    IO_SYNC;    /* issue the start command (i.e., transmit the buffer) */    *I2COM(immrVal) |= CPM_I2C_COMMAND_STR;     IO_SYNC;    /*      * poll for completion     * enable RTC alarm for 10 seconds and poll for transmit-buffer     * or transmit-error interrupt     */    /* wrap the RTCSC write with unlock/lock code (SPR 65678) */#ifdef USE_KEYED_REGS    *RTCSCK(immrVal) = KEYED_REG_UNLOCK_VALUE; /* unlock the RTCSC */    IO_ISYNC;    *RTCSC(immrVal) &= ~RTCSC_ALE;       /* disable alarm interrupt */    *RTCSCK(immrVal) = ~KEYED_REG_UNLOCK_VALUE; /* lock the RTCSC */#else    *RTCSC(immrVal) &= ~RTCSC_ALE;       /* disable alarm interrupt */#endif    for (mbxI2cdAlarm(immrVal, 10);;) 	{        /* check for some type of transmit interrupt condition */        if (*I2CER(immrVal) & (CPM_I2C_ER_TXE|CPM_I2C_ER_TXB)) 	    {            if (*I2CER(immrVal) & (CPM_I2C_ER_TXE)) 		{                pPckt->csword |= (I2C_IO_S_ERROR);                if (pTxbd->statusMode & CPM_I2C_T_CS_NAK)                     pPckt->csword |= (I2C_IO_S_T_NAK);                if (pTxbd->statusMode & CPM_I2C_T_CS_UN)                     pPckt->csword |= (I2C_IO_S_T_UN);                if (pTxbd->statusMode & CPM_I2C_T_CS_CL)                     pPckt->csword |= (I2C_IO_S_T_CL);                }            break;        }        /* poll for alarm condition */        if (*RTCSC(immrVal) & RTCSC_ALR)       	   {           pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_T_TO);           break;           }       }    /* unmask processor interrupts */    localIntUnlock(dontCare);    /* check for data transfer count mismatch */    if (!(pPckt->csword & (I2C_IO_S_ERROR))) 	{        if (pTxbd->dataLength != (pPckt->dataSize + 1)) 	    {            pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_X_CNT);            pPckt->dataSizeActual = pTxbd->dataLength;            }        }    /* exit on error */    if (pPckt->csword & (I2C_IO_S_ERROR)) 	{        /* disable i2c operation and exit with error status */        *I2MOD(immrVal) &= ~CPM_I2C_MODE_EN; 	IO_SYNC;        return (ERROR);        }    /* exit if no receive data is expected */    if (!(pPckt->csword & I2C_IO_C_RDATA)) 	{        /* disable i2c operation and exit with okay status */        *I2MOD(immrVal) &= ~CPM_I2C_MODE_EN; 	IO_SYNC;        return (OK);        }    /* poll for completion of receive data */    localIntLock(&dontCare);    /*     * enable RTC alarm for 10 seconds and poll for transmit-buffer     * or transmit-error interrupt     */    /* wrap the RTCSC write with unlock/lock code (SPR 65678) */#ifdef USE_KEYED_REGS    *RTCSCK(immrVal) = KEYED_REG_UNLOCK_VALUE; /* unlock the RTCSC */    IO_ISYNC;    *RTCSC(immrVal) &= ~RTCSC_ALE;       /* Disable alarm interrupt */    *RTCSCK(immrVal) = ~KEYED_REG_UNLOCK_VALUE; /* lock the RTCSC */#else    *RTCSC(immrVal) &= ~RTCSC_ALE;       /* Disable alarm interrupt */#endif    for (mbxI2cdAlarm(immrVal, 10);;) 	{        /* check for some type of transmit interrupt condition */        if (*I2CER(immrVal) & (CPM_I2C_ER_BSY|CPM_I2C_ER_RXB)) 	    {            if (*I2CER(immrVal) & (CPM_I2C_ER_BSY))                 pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_R_BSY);            if (pRxbd->statusMode & CPM_I2C_R_CS_OV)                 pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_R_OV);            break;            }        /* poll for alarm condition */        if (*RTCSC(immrVal) & RTCSC_ALR)       	    {            pPckt->csword |= (I2C_IO_S_ERROR|I2C_IO_S_R_TO);            break;            }        }    /* disable i2c operation */    *I2MOD(immrVal) &= ~CPM_I2C_MODE_EN;     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;

⌨️ 快捷键说明

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