1 /******************************************************************************
3 * Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /****************************************************************************/
35 * @file xuartlite_intr.c
36 * @addtogroup uartlite_v3_1
39 * This file contains interrupt-related functions for the UART Lite component
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- ---- -------- -----------------------------------------------
47 * 1.00a ecm 08/31/01 First release
48 * 1.00b jhl 02/21/02 Repartitioned the driver for smaller files
49 * 1.02a rpm 02/14/07 Added check for outstanding transmission before
50 * calling the send callback (avoids extraneous
51 * callback invocations)
52 * 2.00a ktn 10/20/09 Updated to use HAL Processor APIs. The macros have been
53 * renamed to remove _m from the name.
56 *****************************************************************************/
58 /***************************** Include Files ********************************/
60 #include "xuartlite.h"
61 #include "xuartlite_i.h"
64 /************************** Constant Definitions ****************************/
66 /**************************** Type Definitions ******************************/
68 /***************** Macros (Inline Functions) Definitions ********************/
70 /************************** Function Prototypes *****************************/
72 static void ReceiveDataHandler(XUartLite *InstancePtr);
73 static void SendDataHandler(XUartLite *InstancePtr);
75 /************************** Variable Definitions ****************************/
77 typedef void (*Handler)(XUartLite *InstancePtr);
79 /****************************************************************************/
82 * This function sets the handler that will be called when an event (interrupt)
83 * occurs in the driver. The purpose of the handler is to allow application
84 * specific processing to be performed.
86 * @param InstancePtr is a pointer to the XUartLite instance.
87 * @param FuncPtr is the pointer to the callback function.
88 * @param CallBackRef is the upper layer callback reference passed back
89 * when the callback function is invoked.
93 * @note There is no assert on the CallBackRef since the driver doesn't
94 * know what it is (nor should it)
96 *****************************************************************************/
97 void XUartLite_SetRecvHandler(XUartLite *InstancePtr,
98 XUartLite_Handler FuncPtr, void *CallBackRef)
101 * Assert validates the input arguments
102 * CallBackRef not checked, no way to know what is valid
104 Xil_AssertVoid(InstancePtr != NULL);
105 Xil_AssertVoid(FuncPtr != NULL);
106 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
108 InstancePtr->RecvHandler = FuncPtr;
109 InstancePtr->RecvCallBackRef = CallBackRef;
112 /****************************************************************************/
115 * This function sets the handler that will be called when an event (interrupt)
116 * occurs in the driver. The purpose of the handler is to allow application
117 * specific processing to be performed.
119 * @param InstancePtr is a pointer to the XUartLite instance .
120 * @param FuncPtr is the pointer to the callback function.
121 * @param CallBackRef is the upper layer callback reference passed back
122 * when the callback function is invoked.
126 * @note There is no assert on the CallBackRef since the driver doesn't
127 * know what it is (nor should it)
129 *****************************************************************************/
130 void XUartLite_SetSendHandler(XUartLite *InstancePtr,
131 XUartLite_Handler FuncPtr, void *CallBackRef)
134 * Assert validates the input arguments
135 * CallBackRef not checked, no way to know what is valid
137 Xil_AssertVoid(InstancePtr != NULL);
138 Xil_AssertVoid(FuncPtr != NULL);
139 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
141 InstancePtr->SendHandler = FuncPtr;
142 InstancePtr->SendCallBackRef = CallBackRef;
145 /****************************************************************************/
148 * This function is the interrupt handler for the UART lite driver.
149 * It must be connected to an interrupt system by the user such that it is
150 * called when an interrupt for any UART lite occurs. This function
151 * does not save or restore the processor context such that the user must
152 * ensure this occurs.
154 * @param InstancePtr contains a pointer to the instance of the UART that
155 * the interrupt is for.
161 ******************************************************************************/
162 void XUartLite_InterruptHandler(XUartLite *InstancePtr)
166 Xil_AssertVoid(InstancePtr != NULL);
169 * Read the status register to determine which, coulb be both
170 * interrupt is active
172 IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
173 XUL_STATUS_REG_OFFSET);
175 if ((IsrStatus & (XUL_SR_RX_FIFO_FULL |
176 XUL_SR_RX_FIFO_VALID_DATA)) != 0) {
177 ReceiveDataHandler(InstancePtr);
180 if (((IsrStatus & XUL_SR_TX_FIFO_EMPTY) != 0) &&
181 (InstancePtr->SendBuffer.RequestedBytes > 0)) {
182 SendDataHandler(InstancePtr);
186 /****************************************************************************/
189 * This function handles the interrupt when data is received, either a single
190 * byte when FIFOs are not enabled, or multiple bytes with the FIFO.
192 * @param InstancePtr is a pointer to the XUartLite instance.
198 *****************************************************************************/
199 static void ReceiveDataHandler(XUartLite *InstancePtr)
202 * If there are bytes still to be received in the specified buffer
203 * go ahead and receive them
205 if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) {
206 XUartLite_ReceiveBuffer(InstancePtr);
210 * If the last byte of a message was received then call the application
211 * handler, this code should not use an else from the previous check of
212 * the number of bytes to receive because the call to receive the buffer
213 * updates the bytes to receive
215 if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) {
216 InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
217 InstancePtr->ReceiveBuffer.RequestedBytes -
218 InstancePtr->ReceiveBuffer.RemainingBytes);
222 * Update the receive stats to reflect the receive interrupt
224 InstancePtr->Stats.ReceiveInterrupts++;
227 /****************************************************************************/
230 * This function handles the interrupt when data has been sent, the transmit
231 * FIFO is empty (transmitter holding register).
233 * @param InstancePtr is a pointer to the XUartLite instance .
239 *****************************************************************************/
240 static void SendDataHandler(XUartLite *InstancePtr)
243 * If there are not bytes to be sent from the specified buffer,
244 * call the callback function
246 if (InstancePtr->SendBuffer.RemainingBytes == 0) {
250 * Save and zero the requested bytes since transmission
253 SaveReq = InstancePtr->SendBuffer.RequestedBytes;
254 InstancePtr->SendBuffer.RequestedBytes = 0;
257 * Call the application handler to indicate
258 * the data has been sent
260 InstancePtr->SendHandler(InstancePtr->SendCallBackRef, SaveReq);
263 * Otherwise there is still more data to send in the specified buffer
264 * so go ahead and send it
267 XUartLite_SendBuffer(InstancePtr);
271 * Update the transmit stats to reflect the transmit interrupt
273 InstancePtr->Stats.TransmitInterrupts++;
277 /*****************************************************************************/
280 * This function disables the UART interrupt. After calling this function,
281 * data may still be received by the UART but no interrupt will be generated
282 * since the hardware device has no way to disable the receiver.
284 * @param InstancePtr is a pointer to the XUartLite instance.
290 *****************************************************************************/
291 void XUartLite_DisableInterrupt(XUartLite *InstancePtr)
293 Xil_AssertVoid(InstancePtr != NULL);
294 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
297 * Write to the control register to disable the interrupts, the only
298 * other bits in this register are the FIFO reset bits such that
299 * writing them to zero will not affect them.
301 XUartLite_WriteReg(InstancePtr->RegBaseAddress,
302 XUL_CONTROL_REG_OFFSET, 0);
305 /*****************************************************************************/
308 * This function enables the UART interrupt such that an interrupt will occur
309 * when data is received or data has been transmitted. The device contains
310 * 16 byte receive and transmit FIFOs such that an interrupt is generated
311 * anytime there is data in the receive FIFO and when the transmit FIFO
312 * transitions from not empty to empty.
314 * @param InstancePtr is a pointer to the XUartLite instance.
320 *****************************************************************************/
321 void XUartLite_EnableInterrupt(XUartLite *InstancePtr)
323 Xil_AssertVoid(InstancePtr != NULL);
324 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
327 * Write to the control register to enable the interrupts, the only
328 * other bits in this register are the FIFO reset bits such that
329 * writing them to zero will not affect them.
331 XUartLite_WriteReg(InstancePtr->RegBaseAddress,
332 XUL_CONTROL_REG_OFFSET, XUL_CR_ENABLE_INTR);