XilinxProcessorIPLib/drivers/iic/src/xiic_master.c
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
{
	u32 CntlReg;
	u8 Temp;

	/*
	 * If the slave address is zero (general call) the master can't perform
	 * receive operations, indicate an error.
	 */
	if (InstancePtr->AddrOfSlave == 0) {
		return XST_IIC_GENERAL_CALL_ADDRESS;
	}

	XIic_IntrGlobalDisable(InstancePtr->BaseAddress);

	/*
	 * Ensure that the master processing has been included such that events
	 * will be properly handled.
	 */
	XIIC_MASTER_INCLUDE;
	InstancePtr->IsDynamic = FALSE;

	/*
	 * If the busy is busy, then exit the critical region and wait for the
	 * bus to not be busy, the function enables the bus not busy interrupt.
	 */
	if (IsBusBusy(InstancePtr)) {
		XIic_IntrGlobalEnable(InstancePtr->BaseAddress);

		return XST_IIC_BUS_BUSY;
	}

	/*
	 * Save message state for event driven processing.
	 */
	InstancePtr->RecvByteCount = ByteCount;
	InstancePtr->RecvBufferPtr = RxMsgPtr;
	InstancePtr->SendBufferPtr = NULL;

	/*
	 * Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait
	 * until last address byte sent in case arbitration gets lost while
	 * sending out address.
	 */
	if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
		XIic_ClearEnableIntr(InstancePtr->BaseAddress,
					XIIC_INTR_RX_FULL_MASK);
	}

	/*
	 * If already a master on the bus, the direction was set by Rx Interrupt
	 * routine to Tx which is throttling bus because during Rxing, Tx reg is
	 * empty = throttle. CR needs setting before putting data or the address
	 * written will go out as Tx instead of receive. Start Master Rx by
	 * setting CR Bits MSMS to Master and msg direction.
	 */
	CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);

	if (CntlReg & XIIC_CR_MSMS_MASK) {
		CntlReg |= XIIC_CR_REPEATED_START_MASK;
		XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);

		InstancePtr->Stats.RepeatedStarts++;
		XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
			 CntlReg);

	}

	/*
	 * Set receive FIFO occupancy depth which must be done prior to writing
	 * the address in the FIFO because the transmitter will immediatedly
	 * start when in repeated start mode followed by the receiver such that
	 * the number of  bytes to receive should be set 1st.
	 */
	if (ByteCount == 1) {
		Temp = 0;
	} else {
		if (ByteCount <= IIC_RX_FIFO_DEPTH) {
			Temp = ByteCount - 2;
		} else {
			Temp = IIC_RX_FIFO_DEPTH - 1;
		}
	}
	XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
			(u32) Temp);

	if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
		/*
		 * Send the 1st and 2nd byte of the 10 bit address of a write
		 * operation, write because it's a 10 bit address.
		 */
		XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
					 XIIC_WRITE_OPERATION);
		XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);

		/*
		 * Set flag to indicate the next byte of the address needs to be
		 * send, clear and enable Tx empty interrupt.
		 */
		InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
		XIic_ClearEnableIntr(InstancePtr->BaseAddress,
					XIIC_INTR_TX_EMPTY_MASK);
	} else {
		/*
		 * 7 bit slave address, send the address for a read operation
		 * and set the state to indicate the address has been sent.
		 */
		XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
				   XIIC_READ_OPERATION);
		InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
	}

	/*
	 * Tx error is enabled in case the address (7 or 10) has no device to
	 * answer with Ack. When only one byte of data, must set NO ACK before
	 * address goes out therefore Tx error must not be enabled as it will
	 * go off immediately and the Rx full interrupt will be checked.
	 * If full, then the one byte was received and the Tx error will be
	 * disabled without sending an error callback msg.
	 */
	XIic_ClearEnableIntr(InstancePtr->BaseAddress,
				XIIC_INTR_TX_ERROR_MASK);

	/*
	 * When repeated start not used, MSMS gets set after putting data
	 * in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
	 * msg direction.
	 */
	CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
	if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
		CntlReg |= XIIC_CR_MSMS_MASK;
		XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
		XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
				CntlReg);
	}

	XIic_IntrGlobalEnable(InstancePtr->BaseAddress);

	return XST_SUCCESS;
}
/*****************************************************************************/
/**
* This function receives data as a master from a slave device on the IIC bus.
* If the bus is busy, it will indicate so and then enable an interrupt such
* that the status handler will be called when the bus is no longer busy.  The
* slave address which has been set with the XIic_SetAddress() function is the
* address from which data is received. Receiving data on the bus performs a
* read operation.
*
* @param	InstancePtr is a pointer to the Iic instance to be worked on.
* @param	RxMsgPtr is a pointer to the data to be transmitted
* @param	ByteCount is the number of message bytes to be sent
*
* @return
*		- XST_SUCCESS indicates the message reception processes has
*		been initiated.
*		- XST_IIC_BUS_BUSY indicates the bus was in use and that the
*		BusNotBusy interrupt is enabled which will update the
*		EventStatus when the bus is no longer busy.
*		- XST_IIC_GENERAL_CALL_ADDRESS indicates the slave address
*		is set to the the general call address. This is not allowed
*		for Master receive mode.
*
* @internal
*
* The receive FIFO threshold is a zero based count such that 1 must be
* subtracted from the desired count to get the correct value. When receiving
* data it is also necessary to not receive the last byte with the prior bytes
* because the acknowledge must be setup before the last byte is received.
*
******************************************************************************/
This function receives data as a master from a slave device on the IIC bus.
If the bus is busy, it will indicate so and then enable an interrupt such
that the status handler will be called when the bus is no longer busy.  The
slave address which has been set with the XIic_SetAddress() function is the
address from which data is received. Receiving data on the bus performs a
read operation.
This function receives data as a master from a slave device on the IIC bus . If the bus is busy it will indicate so and then enable an interrupt such that the status handler will be called when the bus is no longer busy . The slave address which has been set with the XIic_SetAddress () function is the address from which data is received . Receiving data on the bus performs a read operation .
int XIic_MasterRecv(XIic *InstancePtr, u8 *RxMsgPtr, int ByteCount)
{
	u32 CntlReg;
	u8 Temp;
	if (InstancePtr->AddrOfSlave == 0) {
		return XST_IIC_GENERAL_CALL_ADDRESS;
	}
	XIic_IntrGlobalDisable(InstancePtr->BaseAddress);
	XIIC_MASTER_INCLUDE;
	InstancePtr->IsDynamic = FALSE;
	if (IsBusBusy(InstancePtr)) {
		XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
		return XST_IIC_BUS_BUSY;
	}
	InstancePtr->RecvByteCount = ByteCount;
	InstancePtr->RecvBufferPtr = RxMsgPtr;
	InstancePtr->SendBufferPtr = NULL;
	if ((InstancePtr->Options & XII_SEND_10_BIT_OPTION) == 0) {
		XIic_ClearEnableIntr(InstancePtr->BaseAddress,
					XIIC_INTR_RX_FULL_MASK);
	}
	CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
	if (CntlReg & XIIC_CR_MSMS_MASK) {
		CntlReg |= XIIC_CR_REPEATED_START_MASK;
		XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
		InstancePtr->Stats.RepeatedStarts++;
		XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
			 CntlReg);
	}
	if (ByteCount == 1) {
		Temp = 0;
	} else {
		if (ByteCount <= IIC_RX_FIFO_DEPTH) {
			Temp = ByteCount - 2;
		} else {
			Temp = IIC_RX_FIFO_DEPTH - 1;
		}
	}
	XIic_WriteReg(InstancePtr->BaseAddress, XIIC_RFD_REG_OFFSET,
			(u32) Temp);
	if (InstancePtr->Options & XII_SEND_10_BIT_OPTION) {
		XIic_Send10BitAddrByte1(InstancePtr->AddrOfSlave,
					 XIIC_WRITE_OPERATION);
		XIic_Send10BitAddrByte2(InstancePtr->AddrOfSlave);
		InstancePtr->TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK;
		XIic_ClearEnableIntr(InstancePtr->BaseAddress,
					XIIC_INTR_TX_EMPTY_MASK);
	} else {
		XIic_Send7BitAddr(InstancePtr->AddrOfSlave,
				   XIIC_READ_OPERATION);
		InstancePtr->TxAddrMode = XIIC_TX_ADDR_SENT;
	}
	XIic_ClearEnableIntr(InstancePtr->BaseAddress,
				XIIC_INTR_TX_ERROR_MASK);
	CntlReg = XIic_ReadReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET);
	if ((CntlReg & XIIC_CR_MSMS_MASK) == 0) {
		CntlReg |= XIIC_CR_MSMS_MASK;
		XIic_SetControlRegister(InstancePtr, CntlReg, ByteCount);
		XIic_WriteReg(InstancePtr->BaseAddress, XIIC_CR_REG_OFFSET,
				CntlReg);
	}
	XIic_IntrGlobalEnable(InstancePtr->BaseAddress);
	return XST_SUCCESS;
}
int XIic_MasterRecv ( XIic * InstancePtr , u8 * RxMsgPtr , int ByteCount ) { u32 CntlReg ; u8 Temp ; if ( InstancePtr -> AddrOfSlave == 0 ) { return XST_IIC_GENERAL_CALL_ADDRESS ; } XIic_IntrGlobalDisable ( InstancePtr -> BaseAddress ) ; XIIC_MASTER_INCLUDE ; InstancePtr -> IsDynamic = FALSE ; if ( IsBusBusy ( InstancePtr ) ) { XIic_IntrGlobalEnable ( InstancePtr -> BaseAddress ) ; return XST_IIC_BUS_BUSY ; } InstancePtr -> RecvByteCount = ByteCount ; InstancePtr -> RecvBufferPtr = RxMsgPtr ; InstancePtr -> SendBufferPtr = NULL ; if ( ( InstancePtr -> Options & XII_SEND_10_BIT_OPTION ) == 0 ) { XIic_ClearEnableIntr ( InstancePtr -> BaseAddress , XIIC_INTR_RX_FULL_MASK ) ; } CntlReg = XIic_ReadReg ( InstancePtr -> BaseAddress , XIIC_CR_REG_OFFSET ) ; if ( CntlReg & XIIC_CR_MSMS_MASK ) { CntlReg |= XIIC_CR_REPEATED_START_MASK ; XIic_SetControlRegister ( InstancePtr , CntlReg , ByteCount ) ; InstancePtr -> Stats . RepeatedStarts ++ ; XIic_WriteReg ( InstancePtr -> BaseAddress , XIIC_CR_REG_OFFSET , CntlReg ) ; } if ( ByteCount == 1 ) { Temp = 0 ; } else { if ( ByteCount <= IIC_RX_FIFO_DEPTH ) { Temp = ByteCount - 2 ; } else { Temp = IIC_RX_FIFO_DEPTH - 1 ; } } XIic_WriteReg ( InstancePtr -> BaseAddress , XIIC_RFD_REG_OFFSET , ( u32 ) Temp ) ; if ( InstancePtr -> Options & XII_SEND_10_BIT_OPTION ) { XIic_Send10BitAddrByte1 ( InstancePtr -> AddrOfSlave , XIIC_WRITE_OPERATION ) ; XIic_Send10BitAddrByte2 ( InstancePtr -> AddrOfSlave ) ; InstancePtr -> TxAddrMode = XIIC_TX_ADDR_MSTR_RECV_MASK ; XIic_ClearEnableIntr ( InstancePtr -> BaseAddress , XIIC_INTR_TX_EMPTY_MASK ) ; } else { XIic_Send7BitAddr ( InstancePtr -> AddrOfSlave , XIIC_READ_OPERATION ) ; InstancePtr -> TxAddrMode = XIIC_TX_ADDR_SENT ; } XIic_ClearEnableIntr ( InstancePtr -> BaseAddress , XIIC_INTR_TX_ERROR_MASK ) ; CntlReg = XIic_ReadReg ( InstancePtr -> BaseAddress , XIIC_CR_REG_OFFSET ) ; if ( ( CntlReg & XIIC_CR_MSMS_MASK ) == 0 ) { CntlReg |= XIIC_CR_MSMS_MASK ; XIic_SetControlRegister ( InstancePtr , CntlReg , ByteCount ) ; XIic_WriteReg ( InstancePtr -> BaseAddress , XIIC_CR_REG_OFFSET , CntlReg ) ; } XIic_IntrGlobalEnable ( InstancePtr -> BaseAddress ) ; return XST_SUCCESS ; }
This function receives data as a master from a slave device on the IIC bus.
This function receives data as a master from a slave device on the IIC bus .
/*
	 * If the slave address is zero (general call) the master can't perform
	 * receive operations, indicate an error.
	 */ /*
	 * Ensure that the master processing has been included such that events
	 * will be properly handled.
	 */ /*
	 * If the busy is busy, then exit the critical region and wait for the
	 * bus to not be busy, the function enables the bus not busy interrupt.
	 */ /*
	 * Save message state for event driven processing.
	 */ /*
	 * Clear and enable Rx full interrupt if using 7 bit, If 10 bit, wait
	 * until last address byte sent in case arbitration gets lost while
	 * sending out address.
	 */ /*
	 * If already a master on the bus, the direction was set by Rx Interrupt
	 * routine to Tx which is throttling bus because during Rxing, Tx reg is
	 * empty = throttle. CR needs setting before putting data or the address
	 * written will go out as Tx instead of receive. Start Master Rx by
	 * setting CR Bits MSMS to Master and msg direction.
	 */ /*
	 * Set receive FIFO occupancy depth which must be done prior to writing
	 * the address in the FIFO because the transmitter will immediatedly
	 * start when in repeated start mode followed by the receiver such that
	 * the number of  bytes to receive should be set 1st.
	 */ /*
		 * Send the 1st and 2nd byte of the 10 bit address of a write
		 * operation, write because it's a 10 bit address.
		 */ /*
		 * Set flag to indicate the next byte of the address needs to be
		 * send, clear and enable Tx empty interrupt.
		 */ /*
		 * 7 bit slave address, send the address for a read operation
		 * and set the state to indicate the address has been sent.
		 */ /*
	 * Tx error is enabled in case the address (7 or 10) has no device to
	 * answer with Ack. When only one byte of data, must set NO ACK before
	 * address goes out therefore Tx error must not be enabled as it will
	 * go off immediately and the Rx full interrupt will be checked.
	 * If full, then the one byte was received and the Tx error will be
	 * disabled without sending an error callback msg.
	 */ /*
	 * When repeated start not used, MSMS gets set after putting data
	 * in Tx reg. Start Master Rx by setting CR Bits MSMS to Master and
	 * msg direction.
	 */