⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xi2c_l.c

📁 Viertex 2 开发板的接口程序
💻 C
📖 第 1 页 / 共 2 页
字号:
 * @return   The number of bytes sent.
 *
 ****************************************************************************/
Xuint8 XI2c_Send(Xuint32 BaseAddress, Xuint8 SlaveAddress,
		 Xuint8 *BufferPtr, Xuint8 ByteCount) {

  Xuint8 CtrlReg;

  XI2c_mClearTXFifo(BaseAddress);

  /** Send the device address **/
  XI2c_mSend7BitAddress(BaseAddress, SlaveAddress, XIIC_WRITE_OPERATION);

  /** Enable the device and begin transmitting **/
  CtrlReg = XIIC_CR_ENABLE_DEVICE_MASK | XIIC_CR_MSMS_MASK |
    XIIC_CR_DIR_IS_TX_MASK;
  XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, CtrlReg);

  return SendData(BaseAddress, SlaveAddress, BufferPtr, ByteCount);

} // end XI2c_Send()


Xuint8 XI2c_RSSend(Xuint32 BaseAddress, Xuint8 SlaveAddress, 
		   Xuint8 StartAddress, Xuint8 *BufferPtr, 
		   Xuint8 ByteCount) {

  Xuint8 CtrlReg;

  XI2c_mClearTXFifo(BaseAddress);
  
  /* Put the address into the FIFO to be sent and indicate that the operation
   * to be performed on the bus is a write operation */
  XI2c_mSend7BitAddress(BaseAddress, SlaveAddress, XIIC_WRITE_OPERATION);
  XI2c_mSendStartAddress(BaseAddress, StartAddress);  

  /* MSMS must be set after putting data into transmit FIFO, indicate the
   * direction is transmit, this device is master and enable the IIC device */
  CtrlReg = XIIC_CR_ENABLE_DEVICE_MASK | XIIC_CR_MSMS_MASK | 
    XIIC_CR_DIR_IS_TX_MASK;
  XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, CtrlReg);
    
  /** Wait for tx_fifo empty **/
  XI2c_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK);
  if( !TXSuccess(BaseAddress) ) {
    //print("XI2c_RSSend : 1 : TXFailure\r\n");
    return 0;
  }
  
  /** Initiate the repeated start **/
  CtrlReg = CtrlReg | XIIC_CR_REPEATED_START_MASK;
  XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, CtrlReg);

  /** Send the device address **/
  XI2c_mSend7BitAddress(BaseAddress, SlaveAddress, XIIC_WRITE_OPERATION);

  return SendData(BaseAddress, SlaveAddress, BufferPtr, ByteCount);

} // end XI2c_RSSend()



static Xuint8 SendData(Xuint32 BaseAddress, Xuint8 SlaveAddress, 
		       Xuint8 *BufferPtr, Xuint8 ByteCount) {

  Xuint8 IntrStatus, CtrlReg;
  Xuint8 count = 0;
  
  for( count = 0; count < ByteCount-1; count++ ) 
    XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, *(BufferPtr++));

  /** Wait for tx_fifo empty **/
  XI2c_mClearIisr(BaseAddress, XIIC_INTR_BNB_MASK | XIIC_INTR_TX_ERROR_MASK);

  if( !TXSuccess(BaseAddress) ) {
    //print("SendData : 1 : TXFailure\r\n");
    return 0;
  }

  /** Generate the stop condition **/
  CtrlReg = XIIC_CR_ENABLE_DEVICE_MASK | XIIC_CR_DIR_IS_TX_MASK;
  XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, CtrlReg);

  /** Send the last byte **/
  XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, *BufferPtr);

  /** Wait for tx_fifo empty **/
  if( !TXSuccess(BaseAddress) ) {
    //print("SendData : 2 : TXFailure\r\n");
    return 0;
  }

  /* The receive is complete, disable the IIC device and return the number of
   * bytes that was received, we must wait for the bnb flag to properly
   * disable the device. */
  do {
    IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
  } while(!(IntrStatus & XIIC_INTR_BNB_MASK));

  XIo_Out8(BaseAddress + XIIC_CR_REG_OFFSET, 0);
  
  return ++count;

} // end SendData()


static Xuint8 TXSuccess(Xuint32 BaseAddress) {
  Xuint32 IntrStatus, ErrorMask;
  
  ErrorMask = XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_ARB_LOST_MASK | 
    XIIC_INTR_BNB_MASK;

  do {
    IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);

    if( IntrStatus & ErrorMask )
      return 0;

  } while(!(IntrStatus & XIIC_INTR_TX_EMPTY_MASK));

  return 1;

} // end RecvAck()


static Xuint8 RXSuccess(Xuint32 BaseAddress) {
  Xuint32 IntrStatus, ErrorMask;
  
  ErrorMask = XIIC_INTR_ARB_LOST_MASK | XIIC_INTR_BNB_MASK;
  
  /** Wait until the rx_fifo is full **/
  while(1) {
    IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
    
    if( IntrStatus & XIIC_INTR_RX_FULL_MASK ) {
      XI2c_mClearIisr(BaseAddress, XIIC_INTR_RX_FULL_MASK);
      return 1;
    }
    
    if( IntrStatus & ErrorMask )
      return 0;
  }
  
} // end RXSuccess()


Xuint8 XI2c_SlaveAccess(Xuint32 BaseAddress, Xuint8 SlaveAddress, 
			Xuint8 *BufferPtr) {
  
  Xuint8 CtrlReg, StatusReg, SlaveSendFlag, DeviceAddress;
  Xuint8 IntrStatus, count = 0;

  XI2c_mClearTXFifo(BaseAddress);

  /** Set the device slave address **/
  DeviceAddress = SlaveAddress << 1;
  XIo_Out8(BaseAddress + XIIC_ADR_REG_OFFSET, DeviceAddress);

  /** Wait until the device is addressed as slave **/
  do {
    IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
  } while(!(IntrStatus & XIIC_INTR_AAS_MASK));

  XIo_Out8(BaseAddress + XIIC_RFD_REG_OFFSET, 0);

  /** Clear the recieve-fifo interrupt register **/
  XI2c_mClearIisr(BaseAddress, XIIC_INTR_RX_FULL_MASK);

  /** Read the status register to see if we need to receive or send data **/
  StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET);
  
  XI2c_mClearIisr(BaseAddress, XIIC_INTR_NAAS_MASK | XIIC_INTR_BNB_MASK);

  SlaveSendFlag = StatusReg & XIIC_SR_MSTR_RDING_SLAVE_MASK;

  if( SlaveSendFlag ) {
    SlaveSendData(BaseAddress, BufferPtr);
  }
  else {
    SlaveRecvData(BaseAddress, BufferPtr);
  }

  XI2c_mClearIisr(BaseAddress, XIIC_INTR_AAS_MASK); 
  
  return 1;

} // XI2c_SlaveAccess()


static Xuint8 SlaveRecvData(Xuint32 BaseAddress, Xuint8 *BufferPtr) {
  Xuint8 IntrStatus;

  while(1) {
    IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
    if( IntrStatus & XIIC_INTR_NAAS_MASK ) {
      //xil_printf("Recv complete: %02x\r\n", IntrStatus);
      break;
    }
    if( IntrStatus & XIIC_INTR_RX_FULL_MASK ) {
      *(BufferPtr++) = XIo_In8(BaseAddress + XIIC_DRR_REG_OFFSET);
      //xil_printf("Data received: %d\r\n", *(BufferPtr-1));
      XI2c_mClearIisr(BaseAddress, XIIC_INTR_RX_FULL_MASK);
    }
  }

} // end SlaveRecvData()


static Xuint8 SlaveSendData(Xuint32 BaseAddress, Xuint8 *BufferPtr) {
  Xuint8 IntrStatus;

  XI2c_mClearIisr(BaseAddress, XIIC_INTR_TX_ERROR_MASK);

  while(1) {

    do {
      IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);

      if( IntrStatus & (XIIC_INTR_TX_ERROR_MASK | XIIC_INTR_NAAS_MASK) ) {
	//xil_printf("Send complete: %02x\r\n", IntrStatus);
	return;
      }

    } while( !(IntrStatus & XIIC_INTR_TX_EMPTY_MASK) );

    //xil_printf("Data sent: %d\r\n", *BufferPtr);
    XIo_Out8(BaseAddress + XIIC_DTR_REG_OFFSET, *(BufferPtr++));
    XI2c_mClearIisr(BaseAddress, XIIC_INTR_TX_EMPTY_MASK);
  }
  
} // end SlaveSendData()


static void PrintStatus(Xuint32 BaseAddress) {

  Xuint8 CtrlReg, StatusReg, IntrStatus, DevAddress;
  Xuint8 RxFifoOcy, TxFifoOcy, RxFifoDepth;
   
  CtrlReg = XIo_In8(BaseAddress + XIIC_CR_REG_OFFSET);
  StatusReg = XIo_In8(BaseAddress + XIIC_SR_REG_OFFSET);
  IntrStatus = XIIF_V123B_READ_IISR(BaseAddress);
  DevAddress = XIo_In8(BaseAddress + XIIC_ADR_REG_OFFSET);
  RxFifoOcy = XIo_In8(BaseAddress + XIIC_RFO_REG_OFFSET);
  TxFifoOcy = XIo_In8(BaseAddress + XIIC_TFO_REG_OFFSET);
  RxFifoDepth = XIo_In8(BaseAddress + XIIC_RFD_REG_OFFSET);

  xil_printf("\r\nControl Reg:\t\t 0x%02x\r\n", CtrlReg);
  xil_printf("Status Reg:\t\t 0x%02x\r\n", StatusReg);
  xil_printf("Interrupts:\t\t 0x%02x\r\n", IntrStatus);
  //xil_printf("Device Address:\t\t 0x%02x\r\n", DevAddress);
  //xil_printf("Rx Fifo Occupancy:\t 0x%02x\r\n", RxFifoOcy);
  //xil_printf("Tx Fifo Occupancy:\t 0x%02x\r\n", TxFifoOcy);
  //xil_printf("Rx Fifo Depth:\t\t 0x%02x\r\n", RxFifoDepth);

} // end PrintStatus()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -