/** * Put more data into the transmit FIFO, number of bytes is ether expected * number of bytes for this transfer or available space in FIFO, which ever * is less. * * @param InstancePtr is a pointer to the XIicPs instance. * * @return Number of bytes left for this instance. * * @note This is function is shared by master and slave. * ******************************************************************************/ int TransmitFifoFill(XIicPs *InstancePtr) { u8 AvailBytes; int LoopCnt; int NumBytesToSend; /* * Determine number of bytes to write to FIFO. */ AvailBytes = XIICPS_FIFO_DEPTH - XIicPs_ReadReg(InstancePtr->Config.BaseAddress, XIICPS_TRANS_SIZE_OFFSET); if (InstancePtr->SendByteCount > AvailBytes) { NumBytesToSend = AvailBytes; } else { NumBytesToSend = InstancePtr->SendByteCount; } /* * Fill FIFO with amount determined above. */ for (LoopCnt = 0; LoopCnt < NumBytesToSend; LoopCnt++) { XIicPs_SendByte(InstancePtr); } return InstancePtr->SendByteCount; }
/** * This function sends a buffer in polled mode as a slave. * * @param InstancePtr is a pointer to the XIicPs instance. * @param MsgPtr is the pointer to the send buffer. * @param ByteCount is the number of bytes to be sent. * * @return * - XST_SUCCESS if everything went well. * - XST_FAILURE if master sends us data or master terminates the * transfer before all data has sent out. * * @note This send routine is for polled mode transfer only. * ****************************************************************************/ s32 XIicPs_SlaveSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount) { u32 IntrStatusReg; u32 StatusReg; u32 BaseAddr; s32 Tmp; s32 BytesToSend; s32 Error = 0; s32 Status = (s32)XST_SUCCESS; u32 Value; /* * Assert validates the input arguments. */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(MsgPtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY); BaseAddr = InstancePtr->Config.BaseAddress; InstancePtr->SendBufferPtr = MsgPtr; InstancePtr->SendByteCount = ByteCount; /* * Use RXRW bit in status register to wait master to start a read. */ StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); while (((StatusReg & XIICPS_SR_RXRW_MASK) == 0U) && ((!Error) != 0)) { /* * If master tries to send us data, it is an error. */ if ((StatusReg & XIICPS_SR_RXDV_MASK) != 0x0U) { Error = 1; } StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); } if (Error != 0) { Status = (s32)XST_FAILURE; } else { /* * Clear the interrupt status register. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); /* * Send data as long as there is more data to send and * there are no errors. */ Value = (InstancePtr->SendByteCount > (s32)0) && ((!Error) != 0); while (Value != (u32)0x00U) { /* * Find out how many can be sent. */ BytesToSend = InstancePtr->SendByteCount; if (BytesToSend > (s32)(XIICPS_FIFO_DEPTH)) { BytesToSend = (s32)(XIICPS_FIFO_DEPTH); } for(Tmp = 0; Tmp < BytesToSend; Tmp ++) { XIicPs_SendByte(InstancePtr); } StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); /* * Wait for master to read the data out of fifo. */ while (((StatusReg & XIICPS_SR_TXDV_MASK) != (u32)0x00U) && ((!Error) != 0)) { /* * If master terminates the transfer before all data is * sent, it is an error. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); if ((IntrStatusReg & XIICPS_IXR_NACK_MASK) != 0x0U) { Error = 1; } /* Clear ISR. */ XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); } Value = (InstancePtr->SendByteCount > (s32)0U) && ((!Error) != 0); } } if (Error != 0) { Status = (s32)XST_FAILURE; } return Status; }