]> git.sur5r.net Git - freertos/blob
cd7c5da29e6256c7c04e428e9577b38b5a73781c
[freertos] /
1 /******************************************************************************
2 *
3 * Copyright (C) 2002 - 2014 Xilinx, Inc.  All rights reserved.
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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.
18 *
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
25 * SOFTWARE.
26 *
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.
30 *
31 ******************************************************************************/
32 /****************************************************************************/
33 /**
34 *
35 * @file xuartlite_intr.c
36 *
37 * This file contains interrupt-related functions for the UART Lite component
38 * (XUartLite).
39 *
40 * <pre>
41 * MODIFICATION HISTORY:
42 *
43 * Ver   Who  Date     Changes
44 * ----- ---- -------- -----------------------------------------------
45 * 1.00a ecm  08/31/01 First release
46 * 1.00b jhl  02/21/02 Repartitioned the driver for smaller files
47 * 1.02a rpm  02/14/07 Added check for outstanding transmission before
48 *                       calling the send callback (avoids extraneous
49 *                       callback invocations)
50 * 2.00a ktn  10/20/09 Updated to use HAL Processor APIs. The macros have been
51 *                     renamed to remove _m from the name.
52 * </pre>
53 *
54 *****************************************************************************/
55
56 /***************************** Include Files ********************************/
57
58 #include "xuartlite.h"
59 #include "xuartlite_i.h"
60 #include "xil_io.h"
61
62 /************************** Constant Definitions ****************************/
63
64 /**************************** Type Definitions ******************************/
65
66 /***************** Macros (Inline Functions) Definitions ********************/
67
68 /************************** Function Prototypes *****************************/
69
70 static void ReceiveDataHandler(XUartLite *InstancePtr);
71 static void SendDataHandler(XUartLite *InstancePtr);
72
73 /************************** Variable Definitions ****************************/
74
75 typedef void (*Handler)(XUartLite *InstancePtr);
76
77 /****************************************************************************/
78 /**
79 *
80 * This function sets the handler that will be called when an event (interrupt)
81 * occurs in the driver. The purpose of the handler is to allow application
82 * specific processing to be performed.
83 *
84 * @param        InstancePtr is a pointer to the XUartLite instance.
85 * @param        FuncPtr is the pointer to the callback function.
86 * @param        CallBackRef is the upper layer callback reference passed back
87 *               when the callback function is invoked.
88 *
89 * @return       None.
90 *
91 * @note         There is no assert on the CallBackRef since the driver doesn't
92 *               know what it is (nor should it)
93 *
94 *****************************************************************************/
95 void XUartLite_SetRecvHandler(XUartLite *InstancePtr,
96                                 XUartLite_Handler FuncPtr, void *CallBackRef)
97 {
98         /*
99          * Assert validates the input arguments
100          * CallBackRef not checked, no way to know what is valid
101          */
102         Xil_AssertVoid(InstancePtr != NULL);
103         Xil_AssertVoid(FuncPtr != NULL);
104         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
105
106         InstancePtr->RecvHandler = FuncPtr;
107         InstancePtr->RecvCallBackRef = CallBackRef;
108 }
109
110 /****************************************************************************/
111 /**
112 *
113 * This function sets the handler that will be called when an event (interrupt)
114 * occurs in the driver. The purpose of the handler is to allow application
115 * specific processing to be performed.
116 *
117 * @param        InstancePtr is a pointer to the XUartLite instance .
118 * @param        FuncPtr is the pointer to the callback function.
119 * @param        CallBackRef is the upper layer callback reference passed back
120 *               when the callback function is invoked.
121 *
122 * @return       None.
123 *
124 * @note         There is no assert on the CallBackRef since the driver doesn't
125 *               know what it is (nor should it)
126 *
127 *****************************************************************************/
128 void XUartLite_SetSendHandler(XUartLite *InstancePtr,
129                                 XUartLite_Handler FuncPtr, void *CallBackRef)
130 {
131         /*
132          * Assert validates the input arguments
133          * CallBackRef not checked, no way to know what is valid
134          */
135         Xil_AssertVoid(InstancePtr != NULL);
136         Xil_AssertVoid(FuncPtr != NULL);
137         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
138
139         InstancePtr->SendHandler = FuncPtr;
140         InstancePtr->SendCallBackRef = CallBackRef;
141 }
142
143 /****************************************************************************/
144 /**
145 *
146 * This function is the interrupt handler for the UART lite driver.
147 * It must be connected to an interrupt system by the user such that it is
148 * called when an interrupt for any UART lite occurs. This function
149 * does not save or restore the processor context such that the user must
150 * ensure this occurs.
151 *
152 * @param        InstancePtr contains a pointer to the instance of the UART that
153 *               the interrupt is for.
154 *
155 * @return       None.
156 *
157 * @note         None.
158 *
159 ******************************************************************************/
160 void XUartLite_InterruptHandler(XUartLite *InstancePtr)
161 {
162         u32 IsrStatus;
163
164         Xil_AssertVoid(InstancePtr != NULL);
165
166         /*
167          * Read the status register to determine which, coulb be both
168          * interrupt is active
169          */
170         IsrStatus = XUartLite_ReadReg(InstancePtr->RegBaseAddress,
171                                         XUL_STATUS_REG_OFFSET);
172
173         if ((IsrStatus & (XUL_SR_RX_FIFO_FULL |
174                 XUL_SR_RX_FIFO_VALID_DATA)) != 0) {
175                 ReceiveDataHandler(InstancePtr);
176         }
177
178         if (((IsrStatus & XUL_SR_TX_FIFO_EMPTY) != 0) &&
179                 (InstancePtr->SendBuffer.RequestedBytes > 0)) {
180                 SendDataHandler(InstancePtr);
181         }
182 }
183
184 /****************************************************************************/
185 /**
186 *
187 * This function handles the interrupt when data is received, either a single
188 * byte when FIFOs are not enabled, or multiple bytes with the FIFO.
189 *
190 * @param        InstancePtr is a pointer to the XUartLite instance.
191 *
192 * @return       None.
193 *
194 * @note         None.
195 *
196 *****************************************************************************/
197 static void ReceiveDataHandler(XUartLite *InstancePtr)
198 {
199         /*
200          * If there are bytes still to be received in the specified buffer
201          * go ahead and receive them
202          */
203         if (InstancePtr->ReceiveBuffer.RemainingBytes != 0) {
204                 XUartLite_ReceiveBuffer(InstancePtr);
205         }
206
207         /*
208          * If the last byte of a message was received then call the application
209          * handler, this code should not use an else from the previous check of
210          * the number of bytes to receive because the call to receive the buffer
211          * updates the bytes to receive
212          */
213         if (InstancePtr->ReceiveBuffer.RemainingBytes == 0) {
214                 InstancePtr->RecvHandler(InstancePtr->RecvCallBackRef,
215                 InstancePtr->ReceiveBuffer.RequestedBytes -
216                 InstancePtr->ReceiveBuffer.RemainingBytes);
217         }
218
219         /*
220          * Update the receive stats to reflect the receive interrupt
221          */
222         InstancePtr->Stats.ReceiveInterrupts++;
223 }
224
225 /****************************************************************************/
226 /**
227 *
228 * This function handles the interrupt when data has been sent, the transmit
229 * FIFO is empty (transmitter holding register).
230 *
231 * @param        InstancePtr is a pointer to the XUartLite instance .
232 *
233 * @return       None.
234 *
235 * @note         None.
236 *
237 *****************************************************************************/
238 static void SendDataHandler(XUartLite *InstancePtr)
239 {
240         /*
241          * If there are not bytes to be sent from the specified buffer,
242          * call the callback function
243          */
244         if (InstancePtr->SendBuffer.RemainingBytes == 0) {
245                 int SaveReq;
246
247                 /*
248                  * Save and zero the requested bytes since transmission
249                  * is complete
250                  */
251                 SaveReq = InstancePtr->SendBuffer.RequestedBytes;
252                 InstancePtr->SendBuffer.RequestedBytes = 0;
253
254                 /*
255                  * Call the application handler to indicate
256                  * the data has been sent
257                  */
258                 InstancePtr->SendHandler(InstancePtr->SendCallBackRef, SaveReq);
259         }
260         /*
261          * Otherwise there is still more data to send in the specified buffer
262          * so go ahead and send it
263          */
264         else {
265                 XUartLite_SendBuffer(InstancePtr);
266         }
267
268         /*
269          * Update the transmit stats to reflect the transmit interrupt
270          */
271         InstancePtr->Stats.TransmitInterrupts++;
272 }
273
274
275 /*****************************************************************************/
276 /**
277 *
278 * This function disables the UART interrupt. After calling this function,
279 * data may still be received by the UART but no interrupt will be generated
280 * since the hardware device has no way to disable the receiver.
281 *
282 * @param        InstancePtr is a pointer to the XUartLite instance.
283 *
284 * @return       None.
285 *
286 * @note         None.
287 *
288 *****************************************************************************/
289 void XUartLite_DisableInterrupt(XUartLite *InstancePtr)
290 {
291         Xil_AssertVoid(InstancePtr != NULL);
292         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
293
294         /*
295          * Write to the control register to disable the interrupts, the only
296          * other bits in this register are the FIFO reset bits such that
297          * writing them to zero will not affect them.
298          */
299         XUartLite_WriteReg(InstancePtr->RegBaseAddress,
300                                 XUL_CONTROL_REG_OFFSET, 0);
301 }
302
303 /*****************************************************************************/
304 /**
305 *
306 * This function enables the UART interrupt such that an interrupt will occur
307 * when data is received or data has been transmitted. The device contains
308 * 16 byte receive and transmit FIFOs such that an interrupt is generated
309 * anytime there is data in the receive FIFO and when the transmit FIFO
310 * transitions from not empty to empty.
311 *
312 * @param        InstancePtr is a pointer to the XUartLite instance.
313 *
314 * @return       None.
315 *
316 * @note         None.
317 *
318 *****************************************************************************/
319 void XUartLite_EnableInterrupt(XUartLite *InstancePtr)
320 {
321         Xil_AssertVoid(InstancePtr != NULL);
322         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
323
324         /*
325          * Write to the control register to enable the interrupts, the only
326          * other bits in this register are the FIFO reset bits such that
327          * writing them to zero will not affect them.
328          */
329         XUartLite_WriteReg(InstancePtr->RegBaseAddress,
330                                 XUL_CONTROL_REG_OFFSET, XUL_CR_ENABLE_INTR);
331 }
332