/**
* 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;
}
Exemple #2
0
/**
* 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;
}