📄 xiic_l.c
字号:
XIIC_INTR_ARB_LOST_MASK); ByteCount--; } if (Option == XIIC_STOP) { /* If the Option is to release the bus after Reception of data, wait * for the bus to transition to not busy before returning, the IIC * device cannot be disabled until this occurs. It should transition as * the MSMS bit of the control register was cleared before the last byte * was read from the FIFO. */ while (1) { if (XIIC_READ_IISR(BaseAddress) & XIIC_INTR_BNB_MASK) { break; } } } return ByteCount;}/****************************************************************************//*** Send data as a master on the IIC bus. This function sends the data* using polled I/O and blocks until the data has been sent. It only supports* 7 bit addressing mode of operation. The user is responsible for ensuring* the bus is not busy if multiple masters are present on the bus.** @param BaseAddress contains the base address of the IIC device.* @param Address contains the 7 bit IIC address of the device to send the* specified data to.* @param BufferPtr points to the data to be sent.* @param ByteCount is the number of bytes to be sent.* @param Option indicates whether to hold or free the bus after* transmitting the data.** @return** The number of bytes sent.** @note** None*******************************************************************************/unsigned XIic_Send(u32 BaseAddress, u8 Address, u8 *BufferPtr, unsigned ByteCount, u8 Option){ unsigned RemainingByteCount; u8 ControlReg; volatile u8 StatusReg; /* Check to see if already Master on the Bus. * If Repeated Start bit is not set send Start bit by setting MSMS bit else * Send the address. */ ControlReg = XIo_In8(BaseAddress + XIIC_CR_REG_OFFSET); if ((ControlReg & XIIC_CR_REPEATED_START_MASK) == 0) { /* Put the address into the FIFO to be sent and indicate that the operation * to be performed on the bus is a write operation */ XIic_mSend7BitAddress(BaseAddress, Address, XIIC_WRITE_OPERATION); /* Clear the latched interrupt status so that it will be updated with the * new state when it changes, this must be done after the address is put * in the FIFO */ XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK); /* MSMS must be set after putting data into transmit FIFO, indicate the * direction is transmit, this device is master and enable the IIC device */ XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, XIIC_CR_MSMS_MASK | XIIC_CR_DIR_IS_TX_MASK | XIIC_CR_ENABLE_DEVICE_MASK); /* Clear the latched interrupt * status for the bus not busy bit which must be done while the bus is busy */ StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); while ((StatusReg & XIIC_SR_BUS_BUSY_MASK) == 0) { StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); } XIic_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK); } else { /* Already owns the Bus indicating that its a Repeated Start call. * 7 bit slave address, send the address for a write operation * and set the state to indicate the address has been sent */ XIic_mSend7BitAddress(BaseAddress, Address, XIIC_WRITE_OPERATION); } /* Send the specified data to the device on the IIC bus specified by the * the address */ RemainingByteCount = SendData(BaseAddress, BufferPtr, ByteCount, Option); ControlReg = XIo_In8(BaseAddress + XIIC_CR_REG_OFFSET); if ((ControlReg & XIIC_CR_REPEATED_START_MASK) == 0) { /* The Transmission is completed, disable the IIC device if the Option * is to release the Bus after transmission of data and return the number * of bytes that was received. Only wait if master, if addressed as slave * just reset to release the bus. */ if ((ControlReg & XIIC_CR_MSMS_MASK) != 0) { XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, (ControlReg & ~XIIC_CR_MSMS_MASK)); StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); while ((StatusReg & XIIC_SR_BUS_BUSY_MASK) != 0) { StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); } } XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, 0); } return ByteCount - RemainingByteCount;}/******************************************************************************** Send the specified buffer to the device that has been previously addressed* on the IIC bus. This function assumes that the 7 bit address has been sent* and it should wait for the transmit of the address to complete.** @param BaseAddress contains the base address of the IIC device.* @param BufferPtr points to the data to be sent.* @param ByteCount is the number of bytes to be sent.* @param Option indicates whether to hold or free the bus after* transmitting the data.** @return** The number of bytes remaining to be sent.** @note** This function does not take advantage of the transmit FIFO because it is* designed for minimal code space and complexity. It contains loops that* that could cause the function not to return if the hardware is not working.*******************************************************************************/static unsigned SendData(u32 BaseAddress, u8 *BufferPtr, unsigned ByteCount, u8 Option){ u32 IntrStatus; /* Send the specified number of bytes in the specified buffer by polling * the device registers and blocking until complete */ while (ByteCount > 0) { /* Wait for the transmit to be empty before sending any more data * by polling the interrupt status register */ while (1) { IntrStatus = XIIC_READ_IISR(BaseAddress); if (IntrStatus & (XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK)) { return ByteCount; } if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) { break; } } /* If there is more than one byte to send then put the next byte to send * into the transmit FIFO */ if (ByteCount > 1) { XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, *BufferPtr++); } else { if (Option == XIIC_STOP) { /* If the Option is to release the bus after the last data * byte, Set the stop Option before sending the last byte * of data so that the stop Option will be generated * immediately following the data. This is done by clearing * the MSMS bit in the control register. */ XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK | XIIC_CR_DIR_IS_TX_MASK); } /* Put the last byte to send in the transmit FIFO */ XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, *BufferPtr++); if (Option == XIIC_REPEATED_START) { XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK); /* Wait for the transmit to be empty before setting RSTA bit. */ while (1) { IntrStatus = XIIC_READ_IISR (BaseAddress); if (IntrStatus & XIIC_INTR_TX_EMPTY_MASK) { /* RSTA bit should be set only when the FIFO is completely Empty. */ XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, XIIC_CR_REPEATED_START_MASK | XIIC_CR_ENABLE_DEVICE_MASK | XIIC_CR_DIR_IS_TX_MASK | XIIC_CR_MSMS_MASK); break; } } } } /* Clear the latched interrupt status register and this must be done after * the transmit FIFO has been written to or it won't clear */ XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK); /* Update the byte count to reflect the byte sent and clear the latched * interrupt status so it will be updated for the new state */ ByteCount--; } if (Option == XIIC_STOP) { /* If the Option is to release the bus after transmission of data, * Wait for the bus to transition to not busy before returning, the IIC * device cannot be disabled until this occurs. * Note that this is different from a receive operation because the stop * Option causes the bus to go not busy. */ while (1) { if (XIIC_READ_IISR(BaseAddress) & XIIC_INTR_BNB_MASK) { break; } } } return ByteCount;}/*****************************************************************************//*** Receive data as a master on the IIC bus. This function receives the data* using polled I/O and blocks until the data has been received. It only* supports 7 bit addressing. The user is responsible for ensuring the bus is* not busy if multiple masters are present on the bus.** @param BaseAddress contains the base address of the IIC Device.* @param Address contains the 7 bit IIC Device address of the device to send* the specified data to.* @param BufferPtr points to the data to be sent.* @param ByteCount is the number of bytes to be sent. This value can't be* greater than 255 and needs to be greater than 0.** @return The number of bytes received.** @note Upon entry to this function, the IIC interface needs to be already* enabled in the CR register.*******************************************************************************/unsigned XIic_DynRecv(u32 BaseAddress, u8 Address, u8 *BufferPtr, u8 ByteCount){ unsigned RemainingByteCount; u32 StatusRegister; /* * Clear the latched interrupt status so that it will be updated with * the new state when it changes. */ XIic_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK); /* * Send the 7 bit slave address for a read operation and set the state * to indicate the address has been sent. Upon writing the address, a * start condition is initiated. MSMS is automatically set to master * when the address is written to the Fifo. If MSMS was already set, * then a re-start is sent prior to the address. */ XIic_mDynSend7BitAddress(BaseAddress, Address, XIIC_READ_OPERATION); /* * Wait for the bus to go busy. */ StatusRegister = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); while (( StatusRegister & XIIC_SR_BUS_BUSY_MASK) != XIIC_SR_BUS_BUSY_MASK) { StatusRegister = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET); } /* * Clear the latched interrupt status for the bus not busy bit which * must be done while the bus is busy. */ XIic_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK); /* * Write to the Tx Fifo the dynamic stop control bit with the number of * bytes that are to be read over the IIC interface from the presently
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -