Esempio n. 1
0
/**
* 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 and non-repeated start modes 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.
*
* @return
*
* The number of bytes received.
*
* @note
*
* None
*
******************************************************************************/
unsigned XIic_Recv(u32 BaseAddress, u8 Address,
		   u8 * BufferPtr, unsigned ByteCount)
{
	u8 CntlReg;
	unsigned RemainingByteCount;

	/* Tx error is enabled incase 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_mClearIisr(BaseAddress,
			XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK |
			XIIC_INTR_ARB_LOST_MASK);

	/* Set receive FIFO occupancy depth for 1 byte (zero based)
	 */
	XIo_Out8(BaseAddress + XIIC_RFD_REG_OFFSET, 0);

	/* 7 bit slave address, send the address for a read operation
	 * and set the state to indicate the address has been sent
	 */
	XIic_mSend7BitAddress(BaseAddress, Address, XIIC_READ_OPERATION);

	/* MSMS gets set after putting data in FIFO. Start the master receive
	 * operation by setting CR Bits MSMS to Master, if the buffer is only one
	 * byte, then it should not be acknowledged to indicate the end of data
	 */
	CntlReg = XIIC_CR_MSMS_MASK | XIIC_CR_ENABLE_DEVICE_MASK;
	if (ByteCount == 1) {
		CntlReg |= XIIC_CR_NO_ACK_MASK;
	}

	/* Write out the control register to start receiving data and call the
	 * function to receive each byte into the buffer
	 */
	XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, CntlReg);

	/* 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);

	/* Try to receive the data from the IIC bus */

	RemainingByteCount = RecvData(BaseAddress, BufferPtr, ByteCount);
	/*
	 * The receive is complete, disable the IIC device and return the number of
	 * bytes that was received
	 */
	XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, 0);

	/* Return the number of bytes that was received */

	return ByteCount - RemainingByteCount;
}
Esempio n. 2
0
/**
* 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 and non-repeated start modes 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.
*
* @return
*
* The number of bytes sent.
*
* @note
*
* None
*
******************************************************************************/
unsigned XIic_Send(u32 BaseAddress, u8 Address,
		   u8 * BufferPtr, unsigned ByteCount)
{
	unsigned RemainingByteCount;

	/* 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
	 */
	XIic_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);

	/* Send the specified data to the device on the IIC bus specified by the
	 * the address
	 */
	RemainingByteCount = SendData(BaseAddress, BufferPtr, ByteCount);

	/*
	 * The send is complete, disable the IIC device and return the number of
	 * bytes that was sent
	 */
	XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, 0);

	return ByteCount - RemainingByteCount;
}
Esempio n. 3
0
/**
* 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;
}