📄 xiicps_slave.c
字号:
IntrStatusReg); StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); } } if (Error) { return XST_FAILURE; } return XST_SUCCESS;}/*****************************************************************************//*** This function receives a buffer in polled mode as a slave.** @param InstancePtr is a pointer to the XIicPs instance.* @param MsgPtr is the pointer to the receive buffer.* @param ByteCount is the number of bytes to be received.** @return* - XST_SUCCESS if everything went well.* - XST_FAILURE if timed out.** @note This receive routine is for polled mode transfer only.*****************************************************************************/int XIicPs_SlaveRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, int ByteCount){ volatile u32 IntrStatusReg; volatile u32 StatusReg; u32 BaseAddr; /* * Assert validates the input arguments. */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(MsgPtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); BaseAddr = InstancePtr->Config.BaseAddress; InstancePtr->RecvBufferPtr = MsgPtr; InstancePtr->RecvByteCount = ByteCount; StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); /* * Clear the interrupt status register. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); /* * Clear the status register. */ StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_SR_OFFSET, StatusReg); StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); while (InstancePtr->RecvByteCount > 0) { /* Wait for master to put data */ while ((StatusReg & XIICPS_SR_RXDV_MASK) == 0) { StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); /* * If master terminates the transfer before we get all * the data or the master tries to read from us, * it is an error. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); if ((IntrStatusReg & (XIICPS_IXR_DATA_MASK | XIICPS_IXR_COMP_MASK)) && ((StatusReg & XIICPS_SR_RXDV_MASK) == 0) && (InstancePtr->RecvByteCount > 0)) { return XST_FAILURE; } /* * Clear the interrupt status register. */ XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); } /* * Read all data from FIFO. */ while ((StatusReg & XIICPS_SR_RXDV_MASK) && (InstancePtr->RecvByteCount > 0)){ XIicPs_RecvByte(InstancePtr); StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); } } return XST_SUCCESS;}/*****************************************************************************//*** The interrupt handler for slave mode. It does the protocol handling for* the interrupt-driven transfers.** Completion events and errors are signaled to upper layer for proper* handling.** <pre>** The interrupts that are handled are:* - DATA* If the instance is sending, it means that the master wants to read more* data from us. Send more data, and check whether we are done with this* send.** If the instance is receiving, it means that the master has writen* more data to us. Receive more data, and check whether we are done with* with this receive.** - COMP* This marks that stop sequence has been sent from the master, transfer* is about to terminate. However, for receiving, the master may have* written us some data, so receive that first.** It is an error if the amount of transfered data is less than expected.** - NAK* This marks that master does not want our data. It is for send only.** - Other interrupts* These interrupts are marked as error.** </pre>** @param InstancePtr is a pointer to the XIicPs instance.** @return None.** @note None.*****************************************************************************/void XIicPs_SlaveInterruptHandler(XIicPs *InstancePtr){ volatile u32 IntrStatusReg; u32 IsSend = 0; u32 StatusEvent = 0; int LeftOver; u32 BaseAddr; /* * Assert validates the input arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); BaseAddr = InstancePtr->Config.BaseAddress; /* * Read the Interrupt status register. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); /* * Write the status back to clear the interrupts so no events are missed * while processing this interrupt. */ XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); /* * Use the Mask register AND with the Interrupt Status register so * disabled interrupts are not processed. */ IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, XIICPS_IMR_OFFSET)); /* * Determine whether the device is sending. */ if (InstancePtr->RecvBufferPtr == NULL) { IsSend = 1; } /* Data interrupt * * This means master wants to do more data transfers. * Also check for completion of transfer, signal upper layer if done. */ if (0 != (IntrStatusReg & XIICPS_IXR_DATA_MASK)) { if (IsSend) { LeftOver = TransmitFifoFill(InstancePtr); /* * We may finish send here */ if (LeftOver == 0) { StatusEvent |= XIICPS_EVENT_COMPLETE_SEND; } } else { LeftOver = SlaveRecvData(InstancePtr); /* We may finish the receive here */ if (LeftOver == 0) { StatusEvent |= XIICPS_EVENT_COMPLETE_RECV; } } } /* * Complete interrupt. * * In slave mode, it means the master has done with this transfer, so * we signal the application using completion event. */ if (0 != (IntrStatusReg & XIICPS_IXR_COMP_MASK)) { if (IsSend) { if (InstancePtr->SendByteCount > 0) { StatusEvent |= XIICPS_EVENT_ERROR; }else { StatusEvent |= XIICPS_EVENT_COMPLETE_SEND; } } else { LeftOver = SlaveRecvData(InstancePtr); if (LeftOver > 0) { StatusEvent |= XIICPS_EVENT_ERROR; } else { StatusEvent |= XIICPS_EVENT_COMPLETE_RECV; } } } /* * Nack interrupt, pass this information to application. */ if (0 != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) { StatusEvent |= XIICPS_EVENT_NACK; } /* * All other interrupts are treated as error. */ if (0 != (IntrStatusReg & (XIICPS_IXR_TO_MASK | XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_TX_OVR_MASK | XIICPS_IXR_RX_OVR_MASK))){ StatusEvent |= XIICPS_EVENT_ERROR; } /* * Signal application if there are any events. */ if (0 != StatusEvent) { InstancePtr->StatusHandler(InstancePtr->CallBackRef, StatusEvent); }}/*****************************************************************************//*** This function handles continuation of receiving data. It is invoked* from interrupt handler.** @param InstancePtr is a pointer to the XIicPs instance.** @return Number of bytes still expected by the instance.** @note None.*****************************************************************************/static int SlaveRecvData(XIicPs *InstancePtr){ volatile u32 StatusReg; u32 BaseAddr; BaseAddr = InstancePtr->Config.BaseAddress; StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); while (StatusReg & XIICPS_SR_RXDV_MASK) { XIicPs_RecvByte(InstancePtr); StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); } return InstancePtr->RecvByteCount;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -