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

📄 ixi2cdrv.c

📁 有关ARM开发板上的IXP400网络驱动程序的源码以。
💻 C
📖 第 1 页 / 共 5 页
字号:
    ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr);                        \    /* Delay before next read */                                            \    ixI2cDrvSleep(IX_I2C_US_DELAY_FOR_REG_READ);                            \} while ((IX_I2C_TRIGGERED != ((ixI2cStsStored & IX_I2C_IDBR_TX_EMPTY_MASK) >>\    IX_I2C_IDBR_TX_EMPTY_LOC)) &&                                           \    (numOfTries++ < IX_I2C_NUM_TO_POLL_IDBR_TX_EMPTY));                     \                                                                            \/* Check if master failed to transmit */                                    \if(IX_I2C_TRIGGERED != ((ixI2cStsStored & IX_I2C_IDBR_TX_EMPTY_MASK) >>     \    IX_I2C_IDBR_TX_EMPTY_LOC))                                              \{                                                                           \    /* Check if transmit failure is due to arbitration loss */              \    if(IX_I2C_TRIGGERED == ((ixI2cStsStored &                               \    IX_I2C_ARB_LOSS_DETECTED_MASK) >> IX_I2C_ARB_LOSS_DETECTED_LOC))        \    {                                                                       \        /* Clear the slave address detected bit by writing                  \            one to the bit location */                                      \        ixI2cStsStored =                                                    \            (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_ARB_LOSS_DETECTED_LOC);     \        IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored);                    \        ixI2cStatsCounters.ixI2cArbLossCounter++;                           \        return IX_I2C_MASTER_ARB_LOSS;                                      \    } /* end of arbitration loss */                                         \    else /* transmit failure */                                             \    {                                                                       \        /* increment the stats for number of bytes master has Tx (includes  \            slave address) and one byte for master failed to transmit */    \        if(dataXferred != 0) /* slave addr already sent */                  \        {                                                                   \            ixI2cStatsCounters.ixI2cMasterXmitCounter += (dataXferred + 1); \        } /* end of slave addr already sent */                              \        ixI2cStatsCounters.ixI2cMasterFailedXmitCounter++;                  \        return IX_I2C_MASTER_XFER_ERROR;                                    \    } /* end of transmit failure */                                         \} /* end of master failed to transmit *//* Used in ixI2cDrvWriteTransfer and ixI2cDrvReadTransfer to check for bus    error occurences during transfers. If a bus error occurs, then it will    send a master abort. */#define IX_I2C_CHECK_FOR_BUS_ERROR                                          \/* Check for bus error due to previous transfer before continuing           \    transfering more data by checking the I2C Status Register */            \ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr);                            \if(IX_I2C_TRIGGERED == ((ixI2cStsStored & IX_I2C_BUS_ERROR_DETECTED_MASK) >>\    IX_I2C_BUS_ERROR_DETECTED_LOC))                                         \{                                                                           \    /* Clear the bus error detected bit by writing one to the bit           \        location */                                                         \    ixI2cStsStored =                                                        \        (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_BUS_ERROR_DETECTED_LOC) |       \        (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_IDBR_TX_EMPTY_LOC);             \    IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored);                        \                                                                            \    /* Send master abort signal */                                          \    ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_MASTER_ABORT_MASK)) |       \                    (IX_I2C_ENABLE << IX_I2C_MASTER_ABORT_LOC);             \    ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_TRANSFER_BYTE_MASK)) |      \                    (IX_I2C_DISABLE << IX_I2C_TRANSFER_BYTE_LOC);           \    IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored);                        \    return IX_I2C_MASTER_BUS_ERROR;                                         \} /* end of bus error detected *//* * section for enums *//* Used in interrupt mode to determine the operation mode */typedef enum{    IX_I2C_SLAVE_READ_OPERATION = 0x0,    IX_I2C_SLAVE_WRITE_OPERATION,    IX_I2C_MASTER_READ_OPERATION,    IX_I2C_MASTER_WRITE_OPERATION,    IX_I2C_GENERAL_CALL_OPERATION} IxI2cOperationMode;/* Used in interrupt mode by master in sync mode to determine transfer status */typedef enum{    IX_I2C_INTR_XFER_IN_PROGRESS = 0xFF,    IX_I2C_INTR_XFER_SUCCESSFUL = IX_I2C_SUCCESS,    IX_I2C_INTR_ARB_LOSS = IX_I2C_MASTER_ARB_LOSS,    IX_I2C_INTR_XFER_ERROR = IX_I2C_MASTER_XFER_ERROR,    IX_I2C_INTR_BUS_ERROR = IX_I2C_MASTER_BUS_ERROR} IxI2cInterruptTransferStatus;/** * section for typedef *//* typedef for I2C buffer tracker */typedef struct{    char* bufP;             /**< pointer to the location of the buffer */    UINT32 offset;          /**< offset from the pointer head */    UINT32 bufSize;         /**< size of the buffer */    IxI2cXferMode XferMode; /**< USED ONLY IN MASTER: to indicate transaction                                mode */} IxI2cBufTracker;/** * Private variables defined here *//* Interrupt handler function pointers */PRIVATE IxI2cMasterReadCallbackP ixI2cMasterRdCallbackP = NULL;PRIVATE IxI2cMasterWriteCallbackP ixI2cMasterWrCallbackP = NULL;PRIVATE IxI2cSlaveReadCallbackP ixI2cSlaveRdCallbackP = NULL;PRIVATE IxI2cSlaveWriteCallbackP ixI2cSlaveWrCallbackP = NULL;PRIVATE IxI2cGenCallCallbackP ixI2cGenCallCallbackP = NULL;PRIVATE UINT32 ixI2cBaseAddr = 0;/* Base addr of the I2C registers */PRIVATE UINT32 ixI2cCRAddr = 0; /* Addr of the I2C control register (CR) */PRIVATE UINT32 ixI2cSRAddr = 0; /* Addr of the I2C status register (CR) */PRIVATE UINT32 ixI2cSARAddr = 0;/* Addr of the I2C slave addr register (CR) */PRIVATE UINT32 ixI2cDBRAddr = 0;/* Addr of the I2C data buffer register (CR) */PRIVATE UINT32 ixI2cDelayType = IX_I2C_LOOP_DELAY;/* Storage for the I2C configuration which is used over many functions to    increase efficiency */PRIVATE UINT32 ixI2cCfgStored;/* Storage for the I2C status which is used by many functions to avoid    declaration of the same struct multiple times */PRIVATE UINT32 ixI2cStsStored;/* Storage for the I2C statistics counters */PRIVATE IxI2cStatsCounters ixI2cStatsCounters;/* Storage for the buffer info that is used for tracking slave or general    calls in interrupt mode */PRIVATE IxI2cBufTracker ixI2cSlaveOrGenBufTracker;/* Storage for the buffer info that is used for tracking master in    interrupt mode */PRIVATE IxI2cBufTracker ixI2cMasterBufTracker;/* Flag used in interrupt mode to indicate the operation mode - master read,    master write, slave read, slave write, or general call. By default it is    set to slave read */PRIVATE IxI2cOperationMode ixI2cOpMode = IX_I2C_SLAVE_READ_OPERATION;/* Flag used in interrupt mode to indicate the status of the master transfer -    in progress, successful, arb loss, or transfer error */PRIVATE IxI2cInterruptTransferStatus ixI2cIntrXferStatus = IX_I2C_INTR_XFER_SUCCESSFUL;/* Flag to indicate if the mode is interrupt or poll. */PRIVATE BOOL ixI2cInterruptMode = FALSE;/* Flag to indicate if the init has been done and thus not performing some    instructions that should not be done more than once (please refer to the    init API. Example: memory mapping). if init is called more than once    (which is allowed) */PRIVATE BOOL ixI2cInitComplete = FALSE;/** * Private function declaration */PRIVATE void ixI2cDrvInterruptDetected (void);PRIVATE void ixI2cDrvBusErrorHdlr (void);PRIVATE void ixI2cDrvSlaveAddrDetectedHdlr (void);PRIVATE void ixI2cDrvGenCallAddrDetectedHdlr (void);PRIVATE void ixI2cDrvIDBRRxFullHdlr (void);PRIVATE void ixI2cDrvIDBRTxEmptyHdlr (void);PRIVATE void ixI2cDrvArbLossDetectedHdlr (void);PRIVATE void ixI2cDrvSlaveStopDetectedHdlr (void);PRIVATE void ixI2cDrvSleep(UINT32 delay);/** * Function definitions */PUBLIC IX_I2C_STATUSixI2cDrvInit (IxI2cInitVars *initVarsSelected){    UINT32 localTempI2cCfg;    /* Check if the hardware supports I2C. By reading the device type, it can        be determined if the hardware supports I2C. Currenlty only the IXP46X        supports I2C. */  if(IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X != ixFeatureCtrlDeviceRead())    {        ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR,            "ixI2cDrvInit: There's no dedicated I2C hardware"            " support!\n", 0,0,0,0,0,0);        return IX_I2C_NOT_SUPPORTED;    } /* end of device detected is not IXP46x */    /* Valid parameter check section */    /* Check if the initVarsSelected is NULL */    if(NULL == initVarsSelected)    {        return IX_I2C_NULL_POINTER;    } /* end of initVarsSelected is NULL */    /* Check if the I2C speed mode (100Kbps or 400Kbps) selected is valid */    if(initVarsSelected->I2cSpeedSelect > IX_I2C_FAST_MODE)    {        return IX_I2C_INVALID_SPEED_MODE_ENUM_VALUE;    } /* end of invalid I2cSpeedSelect */    /* Check if the I2C flow mode (interrupt or poll) selected is valid */    if(initVarsSelected->I2cFlowSelect > IX_I2C_INTERRUPT_MODE)    {        return IX_I2C_INVALID_FLOW_MODE_ENUM_VALUE;    } /* end of invalid I2cFlowSelect */        /* Check if the I2C Hardware Address is valid (non-zero) */    if(IX_I2C_INVALID_SLAVE_ADDRESS == initVarsSelected->I2cHWAddr)    {        return IX_I2C_INVALID_SLAVE_ADDR;    } /* end of invalid I2C slave address */    /* Clear I2C Configurations to zero, only client configurations that        are non-zero will be set to one in the following */    localTempI2cCfg = 0;        /* Set the I2C speed mode selected */    localTempI2cCfg = (localTempI2cCfg & (~IX_I2C_SPEEDMODE_MASK)) |                    (initVarsSelected->I2cSpeedSelect << IX_I2C_SPEEDMODE_LOC);    /* If previously Interrupt Mode was set, then unbind the interrupt        and reset callback pointers to NULL */    if(TRUE == ixI2cInterruptMode)    {        if(IX_SUCCESS != ixOsalIrqUnbind(IX_OSAL_IXP400_I2C_IRQ_LVL))        {            return IX_I2C_INT_UNBIND_FAIL;        } /* end of ixOsalIrqUnbind */        ixI2cMasterRdCallbackP = NULL;        ixI2cMasterWrCallbackP = NULL;        ixI2cSlaveRdCallbackP = NULL;        ixI2cSlaveWrCallbackP = NULL;        ixI2cGenCallCallbackP = NULL;        ixI2cInterruptMode = FALSE;    } /* end of TRUE == ixI2cInterruptMode */    /* Check if interrupt mode is selected */    if(IX_I2C_INTERRUPT_MODE == initVarsSelected->I2cFlowSelect)    {        /* Check if configuration is set to respond to slave address */        if(TRUE == initVarsSelected->I2cSlaveAddrResponseEnable)        {            /* Check if slave callbacks are NULL, then return error */            if((NULL == initVarsSelected->SlaveReadCBP) ||                (NULL == initVarsSelected->SlaveWriteCBP))            {                return IX_I2C_SLAVE_ADDR_CB_MISSING;            } /* end of slave callback are NULL */            ixI2cSlaveRdCallbackP = initVarsSelected->SlaveReadCBP;            ixI2cSlaveWrCallbackP = initVarsSelected->SlaveWriteCBP;            localTempI2cCfg =                (localTempI2cCfg & (~IX_I2C_SLAVE_ADDR_DETECT_ENABLE_MASK)) |                (IX_I2C_INTERRUPT_ENABLE << IX_I2C_SLAVE_ADDR_DETECT_ENABLE_LOC);            localTempI2cCfg =                (localTempI2cCfg & (~IX_I2C_SLAVE_STOP_DETECT_ENABLE_MASK)) |                (IX_I2C_INTERRUPT_ENABLE << IX_I2C_SLAVE_STOP_DETECT_ENABLE_LOC);        } /* end of I2cSlaveAddrResponseEnable == TRUE */        /* Check if configuration is set to respond to general calls */        if(TRUE == initVarsSelected->I2cGenCallResponseEnable)        {            /* Check gen call callback is NULL, then return error */            if(NULL == initVarsSelected->GenCallCBP)            {                return IX_I2C_GEN_CALL_CB_MISSING;            } /* end of gen call callback is NULL */            localTempI2cCfg =                (localTempI2cCfg & (~IX_I2C_SLAVE_ADDR_DETECT_ENABLE_MASK)) |                (IX_I2C_INTERRUPT_ENABLE << IX_I2C_SLAVE_ADDR_DETECT_ENABLE_LOC);            localTempI2cCfg =                (localTempI2cCfg & (~IX_I2C_SLAVE_STOP_DETECT_ENABLE_MASK)) |                (IX_I2C_INTERRUPT_ENABLE << IX_I2C_SLAVE_STOP_DETECT_ENABLE_LOC);            ixI2cGenCallCallbackP = initVarsSelected->GenCallCBP;        } /* end of I2cGenCallResponseEnable == TRUE */        else /* I2cGenCallResponseEnable = FALSE */        {            localTempI2cCfg =

⌨️ 快捷键说明

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