📄 ixi2cdrv.c
字号:
ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_SEND_STOP_MASK)) | (IX_I2C_DISABLE << IX_I2C_SEND_STOP_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_MASTER_ABORT_MASK)) | (IX_I2C_DISABLE << IX_I2C_MASTER_ABORT_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_TRANSFER_BYTE_MASK)) | (IX_I2C_ENABLE << IX_I2C_TRANSFER_BYTE_LOC); /* Read the I2C Status Register */ ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr); /* Check if the I2C bus is busy before starting transfer */ if(IX_I2C_TRIGGERED == ((ixI2cStsStored & IX_I2C_BUS_BUSY_MASK) >> IX_I2C_BUS_BUSY_LOC)) { return IX_I2C_MASTER_BUS_BUSY; } /* end of I2C bus is busy */ /* Write the configuration to the ICR to start the transfer */ IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored); /* Check if master callback is NULL (sync) or not (async) */ if(NULL == ixI2cMasterRdCallbackP) { /* Poll the ixI2cIntrXferStatus for status of transfer complete or transfer errors. Every 20us is 1 byte transferred at 400 Kbps and 4 bytes transferred at 100Kbps */ while(IX_I2C_INTR_XFER_IN_PROGRESS == ixI2cIntrXferStatus) { ixI2cDrvSleep(IX_I2C_US_POLL_FOR_XFER_STATUS); } /* end of while IX_I2C_TRANSFER_IN_PROGRESS */ return ixI2cIntrXferStatus; } /* end of ixI2cMasterRdCallbackP = NULL */ else /* async: so after transfer is complete (or error) master read callback will be called, so return. */ { return IX_I2C_SUCCESS; } /* end of async */ } /* end of interrupt mode */ else /* Poll Mode */ { /* Enable the start signal to control the bus and the Transfer byte bit to transmit a data byte */ ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_SEND_START_MASK)) | (IX_I2C_ENABLE << IX_I2C_SEND_START_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_SEND_STOP_MASK)) | (IX_I2C_DISABLE << IX_I2C_SEND_STOP_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_MASTER_ABORT_MASK)) | (IX_I2C_DISABLE << IX_I2C_MASTER_ABORT_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_TRANSFER_BYTE_MASK)) | (IX_I2C_ENABLE << IX_I2C_TRANSFER_BYTE_LOC); /* Read the I2C Status Register */ ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr); /* Check if the I2C bus is busy before starting transfer */ if(IX_I2C_TRIGGERED == ((ixI2cStsStored & IX_I2C_BUS_BUSY_MASK) >> IX_I2C_BUS_BUSY_LOC)) { return IX_I2C_MASTER_BUS_BUSY; } /* end of I2C bus is busy */ /* Write the configuration to the ICR to start the transfer */ IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored); /* Poll for the IDBR Tx Empty bit and if does not see it after a few tries, check if it is due to arb loss and return arb loss else return as transfer error. */ IX_I2C_POLL_IDBR_TX_EMPTY_AND_CHECK_FOR_ARB_LOSS(0); /* Clear the IDBR transmit empty detected bit by writing one to the bit location */ ixI2cStsStored = (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_IDBR_TX_EMPTY_LOC); IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored); do /* more bytes to receive */ { /* Check if last byte to receive */ if(1 == (dataSize - dataSizeRcvd)) { /* Check if in normal transfer (ends with a stop) */ if(IX_I2C_NORMAL == XferModeSelect) { /* Enable the stop signal to free control of the I2C bus. */ ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_SEND_STOP_MASK)) | (IX_I2C_ENABLE << IX_I2C_SEND_STOP_LOC); } /* end of IX_I2C_NORMAL */ /* Send a Nack to end the transfer */ ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_ACK_NACK_CTL_MASK)) | (IX_I2C_NACK << IX_I2C_ACK_NACK_CTL_LOC); } /* end of last byte to receive */ else /* not last byte to receive */ { ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_ACK_NACK_CTL_MASK)) | (IX_I2C_ACK << IX_I2C_ACK_NACK_CTL_LOC); } /* end of not last byte to receive */ /* Disable the start signal as already got control of the bus and enable the Transfer byte bit to transmit a data byte */ ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_SEND_START_MASK)) | (IX_I2C_DISABLE << IX_I2C_SEND_START_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_MASTER_ABORT_MASK)) | (IX_I2C_DISABLE << IX_I2C_MASTER_ABORT_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_TRANSFER_BYTE_MASK)) | (IX_I2C_ENABLE << IX_I2C_TRANSFER_BYTE_LOC); IX_I2C_CHECK_FOR_BUS_ERROR; /* send master abort if bus error */ /* Write the configuration to the ICR to start the transfer */ IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored); /* Reset numOfTries to zero for polling */ numOfTries = 0; /* Poll for IDBR Receive Full to determine data is received into the IDBR */ do /* IX_I2C_TRIGGERED != ixI2cStsStored.IDBRRxFull */ { ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr); ixI2cDrvSleep(IX_I2C_US_DELAY_FOR_REG_READ); } while ((IX_I2C_TRIGGERED != ((ixI2cStsStored & IX_I2C_IDBR_RX_FULL_MASK) >> IX_I2C_IDBR_RX_FULL_LOC)) && (numOfTries++ < IX_I2C_NUM_TO_POLL_IDBR_RX_FULL)); /* Check if master failed to received */ if(IX_I2C_TRIGGERED != ((ixI2cStsStored & IX_I2C_IDBR_RX_FULL_MASK) >> IX_I2C_IDBR_RX_FULL_LOC)) { /* Read the I2C status register */ ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr); /* Check if receive 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 /* receive failure */ { /* increment the stats for number of bytes master has received and one byte for master failed to received and one byte for slave address transmitted */ ixI2cStatsCounters.ixI2cMasterRcvCounter += dataSizeRcvd; ixI2cStatsCounters.ixI2cMasterFailedRcvCounter++; ixI2cStatsCounters.ixI2cMasterXmitCounter++; return IX_I2C_MASTER_XFER_ERROR; } /* end of receive failure */ } /* end of master failed to receive */ /* Clear the IDBR Receive Full detected bit by writing one to the bit location */ ixI2cStsStored = (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_IDBR_RX_FULL_LOC); IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored); /* Read the data from IDBR into client buffer */ bufP[dataSizeRcvd++] = IX_OSAL_READ_LONG(ixI2cDBRAddr); }while (dataSize > dataSizeRcvd); /* more bytes to receive? */ /* increment the stats for number of bytes master has received and one byte for slave address transmitted */ ixI2cStatsCounters.ixI2cMasterRcvCounter += dataSizeRcvd; ixI2cStatsCounters.ixI2cMasterXmitCounter++; } /* end of poll mode */ return IX_I2C_SUCCESS;} /* end of ixI2cDrvReadTransfer */PUBLIC IX_I2C_STATUSixI2cDrvSlaveAddrAndGenCallDetectedCheck(void){ /* Disallow this function from running if I2C not initialized */ IX_I2C_INIT_SUCCESS_CHECK("ixI2cDrvSlaveAddrAndGenCallDetectedCheck"); /* Read the I2C Status Register */ ixI2cStsStored = IX_OSAL_READ_LONG(ixI2cSRAddr); /* Check if a Slave address detected was triggered */ if(IX_I2C_TRIGGERED != ((ixI2cStsStored & IX_I2C_SLAVE_ADDR_DETECTED_MASK) >> IX_I2C_SLAVE_ADDR_DETECTED_LOC)) { return IX_I2C_SLAVE_ADDR_NOT_DETECTED; } /* end of slave address triggered */ /* Check if a general call address detected was triggered */ if(IX_I2C_TRIGGERED == ((ixI2cStsStored & IX_I2C_GEN_CALL_ADDR_DETECTED_MASK) >> IX_I2C_GEN_CALL_ADDR_DETECTED_LOC)) { /* Clear the slave address detected and general call address detected bits by writing one to bit locations */ ixI2cStsStored = (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_SLAVE_ADDR_DETECTED_LOC) | (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_GEN_CALL_ADDR_DETECTED_LOC); IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored); return IX_I2C_GEN_CALL_ADDR_DETECTED; } /* end of General Call detected */ /* Check if a Slave write detected was triggered */ if(IX_I2C_TRIGGERED == ((ixI2cStsStored & IX_I2C_READ_WRITE_MODE_MASK) >> IX_I2C_READ_WRITE_MODE_LOC)) { /* Clear the slave address detected bit by writing one to the bit location */ ixI2cStsStored = (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_SLAVE_ADDR_DETECTED_LOC); IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored); return IX_I2C_SLAVE_WRITE_DETECTED; } /* end of Slave Write detected */ /* Clear the slave address detected bit by writing one to the bit location */ ixI2cStsStored = (IX_I2C_SET_TO_BE_CLEARED << IX_I2C_SLAVE_ADDR_DETECTED_LOC); IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored); return IX_I2C_SLAVE_READ_DETECTED;} /* end of ixI2cDrvSlaveAddrAndGenCallDetectedCheck */PUBLIC IX_I2C_STATUSixI2cDrvSlaveOrGenDataReceive( char *bufP, const UINT32 bufSize, UINT32 *dataSizeRcvd){ UINT32 numOfTries = 0; /* Disallow this function from running if I2C not initialized */ IX_I2C_INIT_SUCCESS_CHECK("ixI2cDrvSlaveOrGenDataReceive"); /* Check if buffer pointer is NULL */ if(NULL == bufP) { return IX_I2C_SLAVE_NO_BUFFER; } /* end of buffer pointer is NULL */ /* Check if dataSize is zero */ if(0 == bufSize) { return IX_I2C_DATA_SIZE_ZERO; } /* end of bufSize is zero */ /* Check if dataSizeXmtd pointer is NULL */ if(NULL == dataSizeRcvd) { return IX_I2C_NULL_POINTER; } /* end of dataSizeXmtd pointer is NULL */ dataSizeRcvd[0] = 0; /* Reset the number of data received to zero */ /* Keep receiving data until slave stop is detected */ do /* while not slave stop detected or error */ { /* Reset the numOfTries to zero */ numOfTries = 0; /* Enable the Transfer byte bit to receive a data byte */ ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_TRANSFER_BYTE_MASK)) | (IX_I2C_ENABLE << IX_I2C_TRANSFER_BYTE_LOC); ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_ACK_NACK_CTL_MASK)) | (IX_I2C_ACK << IX_I2C_ACK_NACK_CTL_LOC); IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored); /* Poll for IDBR Receive Full to determine there's data in the IDBR to be read */ do /* IX_I2C_TRIGGERED != ixI2cStsStored.IDBRRxFull */ { ixI2cStsStored = IX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -