/** * * This function handles the receive timeout interrupt. This interrupt occurs * whenever a number of bytes have been present in the RX FIFO and the receive * data line has been idle for at lease 4 or more character times, (the timeout * is set using XUartPs_SetrecvTimeout() function). * * @param InstancePtr is a pointer to the XUartPs instance * * @return None. * * @note None. * *****************************************************************************/ static void ReceiveTimeoutHandler(XUartPs *InstancePtr) { u32 Event; /* * If there are bytes still to be received in the specified buffer * go ahead and receive them. Removing bytes from the RX FIFO will * clear the interrupt. */ if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { (void)XUartPs_ReceiveBuffer(InstancePtr); } /* * If there are no more bytes to receive then indicate that this is * not a receive timeout but the end of the buffer reached, a timeout * normally occurs if # of bytes is not divisible by FIFO threshold, * don't rely on previous test of remaining bytes since receive * function updates it */ if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { Event = XUARTPS_EVENT_RECV_TOUT; } else { Event = XUARTPS_EVENT_RECV_DATA; } /* * Call the application handler to indicate that there is a receive * timeout or data event */ InstancePtr->Handler(InstancePtr->CallBackRef, Event, InstancePtr->ReceiveBuffer.RequestedBytes - InstancePtr->ReceiveBuffer.RemainingBytes); }
/** * * This function handles the interrupt when data is in RX FIFO. * * @param InstancePtr is a pointer to the XUartPs instance * * @return None. * * @note None. * *****************************************************************************/ static void ReceiveDataHandler(XUartPs *InstancePtr) { /* * If there are bytes still to be received in the specified buffer * go ahead and receive them. Removing bytes from the RX FIFO will * clear the interrupt. */ if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) { XUartPs_ReceiveBuffer(InstancePtr); } /* If the last byte of a message was received then call the application * handler, this code should not use an else from the previous check of * the number of bytes to receive because the call to receive the buffer * updates the bytes ramained */ if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) { InstancePtr->Handler(InstancePtr->CallBackRef, XUARTPS_EVENT_RECV_DATA, (InstancePtr->ReceiveBuffer.RequestedBytes - InstancePtr->ReceiveBuffer.RemainingBytes)); } }
/* * * This function handles interrupts for receive errors which include * overrun errors, framing errors, parity errors, and the break interrupt. * * @param InstancePtr is a pointer to the XUartPs instance. * * @return None. * * @note None. * *****************************************************************************/ static void ReceiveErrorHandler(XUartPs *InstancePtr, u32 IsrStatus) { u32 ByteStatusValue, EventData; u32 Event; InstancePtr->is_rxbs_error = 0; if ((InstancePtr->Platform == XPLAT_ZYNQ_ULTRA_MP) && (IsrStatus & ((u32)XUARTPS_IXR_PARITY | (u32)XUARTPS_IXR_RBRK | (u32)XUARTPS_IXR_FRAMING))) { InstancePtr->is_rxbs_error = 1; } /* * If there are bytes still to be received in the specified buffer * go ahead and receive them. Removing bytes from the RX FIFO will * clear the interrupt. */ (void)XUartPs_ReceiveBuffer(InstancePtr); if (!(InstancePtr->is_rxbs_error)) { Event = XUARTPS_EVENT_RECV_ERROR; EventData = InstancePtr->ReceiveBuffer.RequestedBytes - InstancePtr->ReceiveBuffer.RemainingBytes; /* * Call the application handler to indicate that there is a receive * error or a break interrupt, if the application cares about the * error it call a function to get the last errors. */ InstancePtr->Handler(InstancePtr->CallBackRef, Event, EventData); } }
/** * * This function attempts to receive a specified number of bytes of data * from the device and store it into the specified buffer. This function works * for both polled or interrupt driven modes. It is non-blocking. * * In a polled mode, this function will only receive the data already in the * RX FIFO. The application may need to call it repeatedly to receive the * entire buffer. Polled mode is the default mode of operation for the device. * * In interrupt mode, this function will start the receiving, if not the entire * buffer has been received, the interrupt handler will continue receiving data * until the entire buffer has been received. A callback function, as specified * by the application, will be called to indicate the completion of the * receiving or error conditions. * * @param InstancePtr is a pointer to the XUartPs instance * @param BufferPtr is pointer to buffer for data to be received into * @param NumBytes is the number of bytes to be received. A value of zero * will stop a previous receive operation that is in progress in * interrupt mode. * * @return The number of bytes received. * * @note * * The number of bytes is not asserted so that this function may be called * with a value of zero to stop an operation that is already in progress. * *****************************************************************************/ u32 XUartPs_Recv(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes) { u32 ReceivedCount; u32 ImrRegister; /* * Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(BufferPtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Disable all the interrupts. * This stops a previous operation that may be interrupt driven */ ImrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, XUARTPS_IXR_MASK); /* * Setup the buffer parameters */ InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes; InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes; InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr; /* * Receive the data from the device */ ReceivedCount = XUartPs_ReceiveBuffer(InstancePtr); /* * Restore the interrupt state */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET, ImrRegister); return ReceivedCount; }
/* * * This function handles interrupts for receive errors which include * overrun errors, framing errors, parity errors, and the break interrupt. * * @param InstancePtr is a pointer to the XUartPs instance. * * @return None. * * @note None. * *****************************************************************************/ static void ReceiveErrorHandler(XUartPs *InstancePtr) { /* * If there are bytes still to be received in the specified buffer * go ahead and receive them. Removing bytes from the RX FIFO will * clear the interrupt. */ if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { (void)XUartPs_ReceiveBuffer(InstancePtr); } /* * Call the application handler to indicate that there is a receive * error or a break interrupt, if the application cares about the * error it call a function to get the last errors. */ InstancePtr->Handler(InstancePtr->CallBackRef, XUARTPS_EVENT_RECV_ERROR, (InstancePtr->ReceiveBuffer.RequestedBytes - InstancePtr->ReceiveBuffer.RemainingBytes)); }