📄 xi2c_l.c
字号:
* @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 + -