/******************************************************************************
* This function reads a number of bytes from an IIC chip into a
* specified buffer.
* This function implements extended 16 bit addressing.
*
* @param    ChipAddress contains the address of the IIC core.
* @param    RegAddress contains the address of the register to write to.
* @param    pBuffer contains the address of the data buffer to be filled.
* @param    ByteCount contains the number of bytes in the buffer to be read.
*           This value is constrained by the page size of the device such
*           that up to 64K may be read in one call.
*
* @return   The number of bytes read. A value less than the specified input
*           value indicates an error.
*
* @note     None.
*
******************************************************************************/
int fmc_iic_axi_IicERead(fmc_iic_t *pIIC, Xuint8 ChipAddress, Xuint16 RegAddress, 
                                         Xuint8 *pBuffer, Xuint8 ByteCount)
{
  Xuint8 ReceivedByteCount = 0;
  Xuint8 SentByteCount = 0;
  Xuint8 WriteBuffer[2];
  Xuint8 StatusReg;
  XStatus TestStatus=XST_FAILURE;
  int cnt = 0;
  fmc_iic_axi_t *pContext = (fmc_iic_axi_t *)(pIIC->pContext);

#if 1
  // Make sure all the Fifo's are cleared and Bus is Not busy.
  do
  {
    StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg );
    StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
	                          XIIC_SR_TX_FIFO_EMPTY_MASK |
                             XIIC_SR_BUS_BUSY_MASK);
  } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK |
			                XIIC_SR_TX_FIFO_EMPTY_MASK));
#endif

  /*
   * A temporary write buffer must be used which contains both the address
   * and the data to be written, put the address in first 
   */
  WriteBuffer[0] = (Xuint8)((RegAddress>>8) & 0x00FF);
  WriteBuffer[1] = (Xuint8)( RegAddress     & 0x00FF);

  // Position the Read pointer to specific location.
  do
  {
    StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg );
    if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK))
    {
      SentByteCount = XIic_DynSend(pContext->CoreAddress, ChipAddress, 
                                            WriteBuffer, 2,
    								        XIIC_REPEATED_START);
    }
    cnt++;
  }while(SentByteCount != 1 && (cnt < 100));
  
  // Error writing chip address so return SentByteCount
  if (SentByteCount < 1) { return SentByteCount; }

  // Receive the data.
  ReceivedByteCount = XIic_DynRecv(pContext->CoreAddress, ChipAddress, pBuffer, 
                                   ByteCount);

  // Return the number of bytes received.
  return ReceivedByteCount;
}
/******************************************************************************
* This function reads a number of bytes from an IIC chip into a
* specified buffer.
*
* @param    ChipAddress contains the address of the IIC core.
* @param    RegAddress contains the address of the register to write to.
* @param    pBuffer contains the address of the data buffer to be filled.
* @param    ByteCount contains the number of bytes in the buffer to be read.
*           This value is constrained by the page size of the device such
*           that up to 64K may be read in one call.
*
* @return   The number of bytes read. A value less than the specified input
*           value indicates an error.
*
* @note     None.
*
******************************************************************************/
int fmc_iic_axi_IicRead(fmc_iic_t *pIIC, Xuint8 ChipAddress, Xuint8 RegAddress, 
                                         Xuint8 *pBuffer, Xuint8 ByteCount)
{
  Xuint8 ReceivedByteCount = 0;
  Xuint8 SentByteCount = 0;
  Xuint8 StatusReg;
  XStatus TestStatus=XST_FAILURE;
  int cnt = 0;
  fmc_iic_axi_t *pContext = (fmc_iic_axi_t *)(pIIC->pContext);

#if 1
  // Make sure all the Fifo's are cleared and Bus is Not busy.
  do
  {
    StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg );
    StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
	                          XIIC_SR_TX_FIFO_EMPTY_MASK |
                             XIIC_SR_BUS_BUSY_MASK);
  } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK |
			                XIIC_SR_TX_FIFO_EMPTY_MASK));
#endif

  // Position the Read pointer to specific location.
  do
  {
    StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg );
    if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK))
    {
      SentByteCount = XIic_DynSend(pContext->CoreAddress, ChipAddress, 
                                  (Xuint8 *)&RegAddress, 1,
    								        XIIC_REPEATED_START);
    }
    cnt++;
  }while(SentByteCount != 1 && (cnt < 100));
  
  // Error writing chip address so return SentByteCount
  if (SentByteCount < 1) { return SentByteCount; }

  // Receive the data.
  ReceivedByteCount = XIic_DynRecv(pContext->CoreAddress, ChipAddress, pBuffer, 
                                   ByteCount);

  // Return the number of bytes received.
  return ReceivedByteCount;
}
Пример #3
0
/******************************************************************************
* This function reads a number of bytes from an IIC chip into a
* specified buffer.
*
* @param    CoreAddress contains the address of the IIC core.
* @param    ChipAddress contains the address of the IIC core.
* @param    RegAddress contains the address of the register to write to.
* @param    BufferPtr contains the address of the data buffer to be filled.
* @param    ByteCount contains the number of bytes in the buffer to be read.
*           This value is constrained by the page size of the device such
*           that up to 64K may be read in one call.
*
* @return   The number of bytes read. A value less than the specified input
*           value indicates an error.
*
* @note     None.
*
******************************************************************************/
int fmc_ipmi_iic_read(Xuint32 CoreAddress, Xuint8 ChipAddress, Xuint8 RegAddress, 
                      Xuint8 *BufferPtr, Xuint8 ByteCount)
{
  Xuint8 ReceivedByteCount = 0;
  Xuint8 SentByteCount = 0;
  Xuint8 StatusReg;
  XStatus TestStatus=XST_FAILURE;
  int cnt = 0;

  // Make sure all the Fifo's are cleared and Bus is Not busy.
  do
  {
    StatusReg = XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[fmc_imageov_iic_read] XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", StatusReg );
    StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
	                          XIIC_SR_TX_FIFO_EMPTY_MASK |
                             XIIC_SR_BUS_BUSY_MASK);
  } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK |
			                XIIC_SR_TX_FIFO_EMPTY_MASK));

  // Position the Read pointer to specific location.
  do
  {
    StatusReg = XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[fmc_imageov_iic_read] XIo_In8(CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", StatusReg );
    if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK))
    {
      SentByteCount = XIic_DynSend(CoreAddress, ChipAddress, 
                                  (Xuint8 *)&RegAddress, 1,
    								        XIIC_REPEATED_START);
    }
    cnt++;
  }while(SentByteCount != 1 && (cnt < 100000));
  
  // Error writing chip address so return SentByteCount
  if (SentByteCount < 1) { return SentByteCount; }

  // Receive the data.
  ReceivedByteCount = XIic_DynRecv(CoreAddress, ChipAddress, BufferPtr, 
                                   ByteCount);

  // Return the number of bytes received.
  return ReceivedByteCount;
}
Пример #4
0
/******************************************************************************
* This function reads a number of bytes from an IIC chip into a
* specified buffer.
*
* @param    ChipAddress contains the address of the IIC core.
* @param    RegAddress contains the address of the register to write to.
* @param    pBuffer contains the address of the data buffer to be filled.
* @param    ByteCount contains the number of bytes in the buffer to be read.
*           This value is constrained by the page size of the device such
*           that up to 64K may be read in one call.
*
* @return   The number of bytes read. A value less than the specified input
*           value indicates an error.
*
* @note     None.
*
******************************************************************************/
int zed_iic_axi_IicRead(zed_iic_t *pIIC, Xuint8 ChipAddress, Xuint8 RegAddress, 
                                         Xuint8 *pBuffer, Xuint8 ByteCount)
{
  Xuint8 ReceivedByteCount = 0;
  Xuint8 SentByteCount = 0;
  Xuint8 ControlReg;
  Xuint8 StatusReg;
  int cnt = 0;
  zed_iic_axi_t *pContext = (zed_iic_axi_t *)(pIIC->pContext);

#if 1
  // Make sure all the Fifo's are cleared and Bus is Not busy.
  do
  {
    StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg );
    StatusReg = StatusReg & (XIIC_SR_RX_FIFO_EMPTY_MASK |
	                          XIIC_SR_TX_FIFO_EMPTY_MASK |
                             XIIC_SR_BUS_BUSY_MASK);
    if ((StatusReg & XIIC_SR_RX_FIFO_EMPTY_MASK) != XIIC_SR_RX_FIFO_EMPTY_MASK)
    {
      /*
       * The RX buffer is not empty and it is assumed there is a stale
       * message in there.  Attempt to clear out the RX buffer, otherwise
       * this loop spins forever.
       */
      XIic_ReadReg(pContext->CoreAddress, XIIC_DRR_REG_OFFSET);
    }

	/*
	 * Check to see if the bus is busy.  Since we are master, if the bus is
	 * still busy that means that arbitration has been lost.
	 *
	 * According to Product Guide PG090, October 16, 2012:
	 *
	 * Control Register (0x100), Bit 2 MSMS:
	 *
	 * "Master/Slave Mode Select. When this bit is changed from 0 to 1,
	 * the AXI IIC bus interface generates a START condition in master
	 * mode. When this bit is cleared, a STOP condition is generated and
	 * the AXI IIC bus interface switches to slave mode. When this bit is
	 * cleared by the hardware, because arbitration for the bus has been
	 * lost, a STOP condition is not generated. (See also Interrupt(0):
	 * Arbitration Lost in Chapter 3.)"
	 *
	 * According to this, it should be okay to clear the master/slave mode
	 * select to clear a false start condition with a stop and regain
	 * arbitration over the bus.
	 */
    if ((StatusReg & XIIC_SR_BUS_BUSY_MASK) == XIIC_SR_BUS_BUSY_MASK)
    {
    	ControlReg = Xil_In8(pContext->CoreAddress + XIIC_CR_REG_OFFSET);
    	ControlReg = ControlReg & 0xFB;  // Clear the MSMS bit.
    	Xil_Out8(pContext->CoreAddress + XIIC_CR_REG_OFFSET, ControlReg);
    }
  } while (StatusReg != (XIIC_SR_RX_FIFO_EMPTY_MASK |
			                XIIC_SR_TX_FIFO_EMPTY_MASK));
#endif

  // Position the Read pointer to specific location.
  do
  {
    StatusReg = Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET);
    //xil_printf("[%s] Xil_In8(pContext->CoreAddress + XIIC_SR_REG_OFFSET) => 0x%02X\n\r", pContext->szName, StatusReg );
    if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK))
    {
      SentByteCount = XIic_DynSend(pContext->CoreAddress, ChipAddress, 
                                  (Xuint8 *)&RegAddress, 1,
    								        XIIC_REPEATED_START);
    }
    cnt++;
  }while(SentByteCount != 1 && (cnt < 100));
  
  // Error writing chip address so return SentByteCount
  if (SentByteCount < 1) { return SentByteCount; }

  // Receive the data.
  ReceivedByteCount = XIic_DynRecv(pContext->CoreAddress, ChipAddress, pBuffer, 
                                   ByteCount);

  // Return the number of bytes received.
  return ReceivedByteCount;
}