📄 ixi2cdrv.c
字号:
{ /* check if device found by checking Ack reply */ if(IX_I2C_ACK == ((ixI2cStsStored & IX_I2C_ACK_NACK_STATUS_MASK) >> IX_I2C_ACK_NACK_STATUS_LOC)) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "Slave device detected at :0x%x\n", slaveAddrToScan,0,0,0,0,0); numOfSlaveDeviceFound++; } } /* end of slave device found */ /* Clear the IDBR transmit empty detected bit by writing one to the bit location */ IX_OSAL_WRITE_LONG(ixI2cSRAddr, ixI2cStsStored); /* Send a master abort to stop transfers in order to scan next address */ 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); /* Write the configuration to the ICR to start the transfer */ IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored); } /* restore to previous configuration */ ixI2cCfgStored = storedI2cCfg; IX_OSAL_WRITE_LONG(ixI2cCRAddr, ixI2cCfgStored); /* Check if any slave devices were found */ if(0 == numOfSlaveDeviceFound) { return IX_I2C_FAIL; } /* end of no slave device found */ else /* found at least one slave device */ { return IX_I2C_SUCCESS; } /* end of found at least one slave device */} /* end of ixI2cDrvBusScan */PUBLIC IX_I2C_STATUSixI2cDrvWriteTransfer( UINT8 SlaveAddr, char *bufP, UINT32 dataSize, IxI2cXferMode XferModeSelect){ UINT32 dataSizeXmtd = 0; UINT32 numOfTries = 0; /* Disallow this function from running if I2C not initialized */ IX_I2C_INIT_SUCCESS_CHECK("ixI2cDrvWriteTransfer"); /* Check if the buffer provided by the client is NULL */ if(NULL == bufP) { return IX_I2C_MASTER_NO_BUFFER; } /* end of bufP is zero */ /* Check if dataSize is zero */ if(0 == dataSize) { return IX_I2C_DATA_SIZE_ZERO; } /* end of dataSize is zero */ /* Check if XferModeSelect is invalid */ if(IX_I2C_REPEATED_START < XferModeSelect) { return IX_I2C_MASTER_INVALID_XFER_MODE; } /* end of XferModeSelect is invalid */ /* Write SlaveAddr into the IDBR after shifting left 1 bit (LSB is zero indicating a write access for the slave that is to be accessed */ IX_OSAL_WRITE_LONG(ixI2cDBRAddr, (SlaveAddr << 1) | IX_I2C_SLAVE_WRITE); /* Determine if configured for poll or interrupt mode */ if(TRUE == ixI2cInterruptMode) /* Interrupt Mode */ { /* Set the flag that will be polled later for transfer complete */ ixI2cIntrXferStatus = IX_I2C_INTR_XFER_IN_PROGRESS; /* Set the Op Mode flag to master write */ ixI2cOpMode = IX_I2C_MASTER_WRITE_OPERATION; /* Fill the Master buffer tracker with the parameters passed in to track the buffer information as it moves from one interrupt handler to another */ ixI2cMasterBufTracker.bufP = bufP; ixI2cMasterBufTracker.offset = 0; ixI2cMasterBufTracker.bufSize = dataSize; ixI2cMasterBufTracker.XferMode = XferModeSelect; /* Enable the start signal to control the bus and the Transfer byte bit to receive 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); /* Check if master callback is NULL (sync) or not (async) */ if(NULL == ixI2cMasterWrCallbackP) { /* 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 ixI2cMasterWrCallbackP = NULL */ else /* async: so after transfer is complete (or error) master write 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 */ do /* while not last byte to transmit */ { /* 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(dataSizeXmtd); /* 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); /* Write data byte from client buffer into IDBR and increment the number of data bytes transmitted */ IX_OSAL_WRITE_LONG(ixI2cDBRAddr, bufP[dataSizeXmtd++]); /* 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_TRANSFER_BYTE_MASK)) | (IX_I2C_ENABLE << IX_I2C_TRANSFER_BYTE_LOC); IX_I2C_CHECK_FOR_BUS_ERROR; /* send master abort if bus error */ } while (dataSize > dataSizeXmtd); /* not last byte to transmit? */ /* Last data byte to transfer */ /* If IX_I2C_NORMAL then send a stop to free the bus */ 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 */ /* 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(dataSizeXmtd); /* Clear the IDBR Tx empty 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); /* Increment the stats for master transmit */ ixI2cStatsCounters.ixI2cMasterXmitCounter += dataSizeXmtd; } /* end of poll mode */ return IX_I2C_SUCCESS;} /* end of ixI2cDrvWriteTransfer */PUBLIC IX_I2C_STATUSixI2cDrvReadTransfer( UINT8 SlaveAddr, char *bufP, UINT32 dataSize, IxI2cXferMode XferModeSelect){ UINT32 dataSizeRcvd = 0; UINT32 numOfTries = 0; /* Disallow this function from running if I2C not initialized */ IX_I2C_INIT_SUCCESS_CHECK("ixI2cDrvReadTransfer"); /* Check if the buffer provided by the client is NULL */ if(NULL == bufP) { return IX_I2C_MASTER_NO_BUFFER; } /* end of bufP is NULL */ /* Check if dataSize is zero */ if(0 == dataSize) { return IX_I2C_DATA_SIZE_ZERO; } /* end of dataSize is zero */ /* Check if XferModeSelect is invalid */ if(IX_I2C_REPEATED_START < XferModeSelect) { return IX_I2C_MASTER_INVALID_XFER_MODE; } /* end of XferModeSelect is invalid */ /* Check if SlaveAddr is invalid (zero) */ if(IX_I2C_INVALID_SLAVE_ADDRESS == SlaveAddr) { return IX_I2C_INVALID_SLAVE_ADDR; } /* end of SlaveAddr is invalid (zero) */ /* Write SlaveAddr into the IDBR after shifting left 1 bit and OR with 1 (LSB is one indicating a read access for the slave that is to be accessed */ IX_OSAL_WRITE_LONG(ixI2cDBRAddr, ((SlaveAddr << 1) | IX_I2C_SLAVE_READ)); /* Determine if configured for poll or interrupt mode */ if(TRUE == ixI2cInterruptMode) /* Interrupt Mode */ { /* Set the flag that will be polled later for transfer complete */ ixI2cIntrXferStatus = IX_I2C_INTR_XFER_IN_PROGRESS; /* Set the Op Mode flag to master read */ ixI2cOpMode = IX_I2C_MASTER_READ_OPERATION; /* Fill the Master buffer tracker with the parameters passed in to track the buffer information as it moves from one interrupt handler to another */ ixI2cMasterBufTracker.bufP = bufP; ixI2cMasterBufTracker.offset = 0; ixI2cMasterBufTracker.bufSize = dataSize; ixI2cMasterBufTracker.XferMode = XferModeSelect; /* Enable the start signal to control the bus and the Transfer byte bit to receive a data byte */ ixI2cCfgStored = (ixI2cCfgStored & (~IX_I2C_SEND_START_MASK)) | (IX_I2C_ENABLE << IX_I2C_SEND_START_LOC);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -