]> git.sur5r.net Git - freertos/blob
83c4c62541e09cf90ea41f991cdb2c318700afa9
[freertos] /
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2015 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 xgpiops_intr.c
36 *
37 * This file contains functions related to GPIO interrupt handling.
38 *
39 * <pre>
40 * MODIFICATION HISTORY:
41 *
42 * Ver   Who  Date     Changes
43 * ----- ---- -------- -----------------------------------------------
44 * 1.00a sv   01/18/10 First Release
45 * 2.2   sk       10/13/14 Used Pin number in Bank instead of pin number
46 *                                         passed to API's. CR# 822636
47 * 3.00  kvn  02/13/15 Modified code for MISRA-C:2012 compliance.
48 * </pre>
49 *
50 ******************************************************************************/
51
52 /***************************** Include Files *********************************/
53
54 #include "xgpiops.h"
55
56 /************************** Constant Definitions *****************************/
57
58 /**************************** Type Definitions *******************************/
59
60 /***************** Macros (Inline Functions) Definitions *********************/
61
62 /************************** Variable Definitions *****************************/
63
64 /************************** Function Prototypes ******************************/
65
66 void StubHandler(void *CallBackRef, u32 Bank, u32 Status);
67
68 /****************************************************************************/
69 /**
70 *
71 * This function enables the interrupts for the specified pins in the specified
72 * bank.
73 *
74 * @param        InstancePtr is a pointer to the XGpioPs instance.
75 * @param        Bank is the bank number of the GPIO to operate on.
76 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
77 * @param        Mask is the bit mask of the pins for which interrupts are to
78 *               be enabled. Bit positions of 1 will be enabled. Bit positions
79 *               of 0 will keep the previous setting.
80 *
81 * @return       None.
82 *
83 * @note         None.
84 *
85 *****************************************************************************/
86 void XGpioPs_IntrEnable(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
87 {
88         Xil_AssertVoid(InstancePtr != NULL);
89         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
90         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
91
92         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
93                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
94                           XGPIOPS_INTEN_OFFSET, Mask);
95 }
96
97 /****************************************************************************/
98 /**
99 *
100 * This function enables the interrupt for the specified pin.
101 *
102 * @param        InstancePtr is a pointer to the XGpioPs instance.
103 * @param        Pin is the pin number for which the interrupt is to be enabled.
104 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
105 *
106 * @return       None.
107 *
108 * @note         None.
109 *
110 *****************************************************************************/
111 void XGpioPs_IntrEnablePin(XGpioPs *InstancePtr, u32 Pin)
112 {
113         u8 Bank;
114         u8 PinNumber;
115         u32 IntrReg = 0U;
116
117         Xil_AssertVoid(InstancePtr != NULL);
118         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
119         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
120
121         /*
122          * Get the Bank number and Pin number within the bank.
123          */
124         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
125
126         IntrReg = ((u32)1 << (u32)PinNumber);
127         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
128                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
129                           XGPIOPS_INTEN_OFFSET, IntrReg);
130 }
131
132 /****************************************************************************/
133 /**
134 *
135 * This function disables the interrupts for the specified pins in the specified
136 * bank.
137 *
138 * @param        InstancePtr is a pointer to the XGpioPs instance.
139 * @param        Bank is the bank number of the GPIO to operate on.
140 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
141 * @param        Mask is the bit mask of the pins for which interrupts are
142 *               to be disabled. Bit positions of 1 will be disabled. Bit
143 *               positions of 0 will keep the previous setting.
144 *
145 * @return       None.
146 *
147 * @note         None.
148 *
149 *****************************************************************************/
150 void XGpioPs_IntrDisable(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
151 {
152         Xil_AssertVoid(InstancePtr != NULL);
153         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
154         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
155
156         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
157                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
158                           XGPIOPS_INTDIS_OFFSET, Mask);
159 }
160
161 /****************************************************************************/
162 /**
163 *
164 * This function disables the interrupts for the specified pin.
165 *
166 * @param        InstancePtr is a pointer to the XGpioPs instance.
167 * @param        Pin is the pin number for which the interrupt is to be disabled.
168 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
169 *
170 * @return       None.
171 *
172 * @note         None.
173 *
174 *****************************************************************************/
175 void XGpioPs_IntrDisablePin(XGpioPs *InstancePtr, u32 Pin)
176 {
177         u8 Bank;
178         u8 PinNumber;
179         u32 IntrReg = 0U;
180
181         Xil_AssertVoid(InstancePtr != NULL);
182         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
183         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
184
185         /*
186          * Get the Bank number and Pin number within the bank.
187          */
188         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
189
190         IntrReg =  ((u32)1 << (u32)PinNumber);
191         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
192                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
193                           XGPIOPS_INTDIS_OFFSET, IntrReg);
194 }
195
196 /****************************************************************************/
197 /**
198 *
199 * This function returns the interrupt enable status for a bank.
200 *
201 * @param        InstancePtr is a pointer to the XGpioPs instance.
202 * @param        Bank is the bank number of the GPIO to operate on.
203 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
204 *
205 * @return       Enabled interrupt(s) in a 32-bit format. Bit positions with 1
206 *               indicate that the interrupt for that pin is enabled, bit
207 *               positions with 0 indicate that the interrupt for that pin is
208 *               disabled.
209 *
210 * @note         None.
211 *
212 *****************************************************************************/
213 u32 XGpioPs_IntrGetEnabled(XGpioPs *InstancePtr, u8 Bank)
214 {
215         u32 IntrMask;
216
217         Xil_AssertNonvoid(InstancePtr != NULL);
218         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
219         Xil_AssertNonvoid(Bank < XGPIOPS_MAX_BANKS);
220
221         IntrMask = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
222                                     ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
223                                     XGPIOPS_INTMASK_OFFSET);
224         return (~IntrMask);
225 }
226
227 /****************************************************************************/
228 /**
229 *
230 * This function returns whether interrupts are enabled for the specified pin.
231 *
232 * @param        InstancePtr is a pointer to the XGpioPs instance.
233 * @param        Pin is the pin number for which the interrupt enable status
234 *               is to be known.
235 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
236 *
237 * @return
238 *               - TRUE if the interrupt is enabled.
239 *               - FALSE if the interrupt is disabled.
240 *
241 * @note         None.
242 *
243 *****************************************************************************/
244 u32 XGpioPs_IntrGetEnabledPin(XGpioPs *InstancePtr, u32 Pin)
245 {
246         u8 Bank;
247         u8 PinNumber;
248         u32 IntrReg;
249
250         Xil_AssertNonvoid(InstancePtr != NULL);
251         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
252         Xil_AssertNonvoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
253
254         /*
255          * Get the Bank number and Pin number within the bank.
256          */
257         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
258
259         IntrReg  = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
260                                     ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
261                                     XGPIOPS_INTMASK_OFFSET);
262
263         return (((IntrReg & ((u32)1 << PinNumber)) != (u32)0)? FALSE : TRUE);
264 }
265
266 /****************************************************************************/
267 /**
268 *
269 * This function returns interrupt status read from Interrupt Status Register.
270 *
271 * @param        InstancePtr is a pointer to the XGpioPs instance.
272 * @param        Bank is the bank number of the GPIO to operate on.
273 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
274 *
275 * @return       The value read from Interrupt Status Register.
276 *
277 * @note         None.
278 *
279 *****************************************************************************/
280 u32 XGpioPs_IntrGetStatus(XGpioPs *InstancePtr, u8 Bank)
281 {
282         Xil_AssertNonvoid(InstancePtr != NULL);
283         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
284         Xil_AssertNonvoid(Bank < XGPIOPS_MAX_BANKS);
285
286         return XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
287                                 ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
288                                 XGPIOPS_INTSTS_OFFSET);
289 }
290
291 /****************************************************************************/
292 /**
293 *
294 * This function returns interrupt enable status of the specified pin.
295 *
296 * @param        InstancePtr is a pointer to the XGpioPs instance.
297 * @param        Pin is the pin number for which the interrupt enable status
298 *               is to be known.
299 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
300 *
301 * @return
302 *               - TRUE if the interrupt has occurred.
303 *               - FALSE if the interrupt has not occurred.
304 *
305 * @note         None.
306 *
307 *****************************************************************************/
308 u32 XGpioPs_IntrGetStatusPin(XGpioPs *InstancePtr, u32 Pin)
309 {
310         u8 Bank;
311         u8 PinNumber;
312         u32 IntrReg;
313
314         Xil_AssertNonvoid(InstancePtr != NULL);
315         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
316         Xil_AssertNonvoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
317
318         /*
319          * Get the Bank number and Pin number within the bank.
320          */
321         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
322
323         IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
324                                    ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
325                                    XGPIOPS_INTSTS_OFFSET);
326
327         return (((IntrReg & ((u32)1 << PinNumber)) != (u32)0)? TRUE : FALSE);
328 }
329
330 /****************************************************************************/
331 /**
332 *
333 * This function clears pending interrupt(s) with the provided mask. This
334 * function should be called after the software has serviced the interrupts
335 * that are pending.
336 *
337 * @param        InstancePtr is a pointer to the XGpioPs instance.
338 * @param        Bank is the bank number of the GPIO to operate on.
339 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
340 * @param        Mask is the mask of the interrupts to be cleared. Bit positions
341 *               of 1 will be cleared. Bit positions of 0 will not change the
342 *               previous interrupt status.
343 *
344 * @note         None.
345 *
346 *****************************************************************************/
347 void XGpioPs_IntrClear(XGpioPs *InstancePtr, u8 Bank, u32 Mask)
348 {
349         Xil_AssertVoid(InstancePtr != NULL);
350         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
351         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
352
353         /*
354          * Clear the currently pending interrupts.
355          */
356         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
357                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
358                           XGPIOPS_INTSTS_OFFSET, Mask);
359 }
360
361 /****************************************************************************/
362 /**
363 *
364 * This function clears the specified pending interrupt. This function should be
365 * called after the software has serviced the interrupts that are pending.
366 *
367 * @param        InstancePtr is a pointer to the XGpioPs instance.
368 * @param        Pin is the pin number for which the interrupt status is to be
369 *               cleared. Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
370 *
371 * @note         None.
372 *
373 *****************************************************************************/
374 void XGpioPs_IntrClearPin(XGpioPs *InstancePtr, u32 Pin)
375 {
376         u8 Bank;
377         u8 PinNumber;
378         u32 IntrReg;
379
380         Xil_AssertVoid(InstancePtr != NULL);
381         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
382         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
383
384         /*
385          * Get the Bank number and Pin number within the bank.
386          */
387         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
388
389         /*
390          * Clear the specified pending interrupts.
391          */
392         IntrReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
393                                    ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
394                                    XGPIOPS_INTSTS_OFFSET);
395
396         IntrReg &= ((u32)1 << PinNumber);
397         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
398                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
399                           XGPIOPS_INTSTS_OFFSET, IntrReg);
400 }
401
402 /****************************************************************************/
403 /**
404 *
405 * This function is used for setting the Interrupt Type, Interrupt Polarity and
406 * Interrupt On Any for the specified GPIO Bank pins.
407 *
408 * @param        InstancePtr is a pointer to an XGpioPs instance.
409 * @param        Bank is the bank number of the GPIO to operate on.
410 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
411 * @param        IntrType is the 32 bit mask of the interrupt type.
412 *               0 means Level Sensitive and 1 means Edge Sensitive.
413 * @param        IntrPolarity is the 32 bit mask of the interrupt polarity.
414 *               0 means Active Low or Falling Edge and 1 means Active High or
415 *               Rising Edge.
416 * @param        IntrOnAny is the 32 bit mask of the interrupt trigger for
417 *               edge triggered interrupts. 0 means trigger on single edge using
418 *               the configured interrupt polarity and 1 means  trigger on both
419 *               edges.
420 *
421 * @return       None.
422 *
423 * @note         This function is used for setting the interrupt related
424 *               properties of all the pins in the specified bank. The previous
425 *               state of the pins is not maintained.
426 *               To change the Interrupt properties of a single GPIO pin, use the
427 *               function XGpioPs_SetPinIntrType().
428 *
429 *****************************************************************************/
430 void XGpioPs_SetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
431                           u32 IntrPolarity, u32 IntrOnAny)
432 {
433         Xil_AssertVoid(InstancePtr != NULL);
434         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
435         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
436
437         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
438                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
439                           XGPIOPS_INTTYPE_OFFSET, IntrType);
440
441         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
442                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
443                           XGPIOPS_INTPOL_OFFSET, IntrPolarity);
444
445         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
446                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
447                           XGPIOPS_INTANY_OFFSET, IntrOnAny);
448 }
449
450 /****************************************************************************/
451 /**
452 *
453 * This function is used for getting the Interrupt Type, Interrupt Polarity and
454 * Interrupt On Any for the specified GPIO Bank pins.
455 *
456 * @param        InstancePtr is a pointer to an XGpioPs instance.
457 * @param        Bank is the bank number of the GPIO to operate on.
458 *               Valid values are 0 to XGPIOPS_MAX_BANKS - 1.
459 * @param        IntrType returns the 32 bit mask of the interrupt type.
460 *               0 means Level Sensitive and 1 means Edge Sensitive.
461 * @param        IntrPolarity returns the 32 bit mask of the interrupt
462 *               polarity. 0 means Active Low or Falling Edge and 1 means
463 *               Active High or Rising Edge.
464 * @param        IntrOnAny returns the 32 bit mask of the interrupt trigger for
465 *               edge triggered interrupts. 0 means trigger on single edge using
466 *               the configured interrupt polarity and 1 means trigger on both
467 *               edges.
468 *
469 * @return       None.
470 *
471 * @note         None.
472 *
473 *****************************************************************************/
474 void XGpioPs_GetIntrType(XGpioPs *InstancePtr, u8 Bank, u32 *IntrType,
475                           u32 *IntrPolarity, u32 *IntrOnAny)
476
477 {
478         Xil_AssertVoid(InstancePtr != NULL);
479         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
480         Xil_AssertVoid(Bank < XGPIOPS_MAX_BANKS);
481
482         *IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
483                                      ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
484                                      XGPIOPS_INTTYPE_OFFSET);
485
486         *IntrPolarity = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
487                                          ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
488                                          XGPIOPS_INTPOL_OFFSET);
489
490         *IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
491                                       ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
492                                       XGPIOPS_INTANY_OFFSET);
493 }
494
495 /****************************************************************************/
496 /**
497 *
498 * This function is used for setting the IRQ Type of a single GPIO pin.
499 *
500 * @param        InstancePtr is a pointer to an XGpioPs instance.
501 * @param        Pin is the pin number whose IRQ type is to be set.
502 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
503 * @param        IrqType is the IRQ type for GPIO Pin. Use XGPIOPS_IRQ_TYPE_*
504 *               defined in xgpiops.h to specify the IRQ type.
505 *
506 * @return       None.
507 *
508 * @note         None.
509 *
510 *****************************************************************************/
511 void XGpioPs_SetIntrTypePin(XGpioPs *InstancePtr, u32 Pin, u8 IrqType)
512 {
513         u32 IntrTypeReg;
514         u32 IntrPolReg;
515         u32 IntrOnAnyReg;
516         u8 Bank;
517         u8 PinNumber;
518
519         Xil_AssertVoid(InstancePtr != NULL);
520         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
521         Xil_AssertVoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
522         Xil_AssertVoid(IrqType <= XGPIOPS_IRQ_TYPE_LEVEL_LOW);
523
524         /*
525          * Get the Bank number and Pin number within the bank.
526          */
527         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
528
529         IntrTypeReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
530                                        ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
531                                        XGPIOPS_INTTYPE_OFFSET);
532
533         IntrPolReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
534                                       ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
535                                       XGPIOPS_INTPOL_OFFSET);
536
537         IntrOnAnyReg = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
538                                         ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
539                                         XGPIOPS_INTANY_OFFSET);
540
541         switch (IrqType) {
542                 case XGPIOPS_IRQ_TYPE_EDGE_RISING:
543                         IntrTypeReg |= ((u32)1 << (u32)PinNumber);
544                         IntrPolReg |= ((u32)1 << (u32)PinNumber);
545                         IntrOnAnyReg &= ~((u32)1 << (u32)PinNumber);
546                         break;
547                 case XGPIOPS_IRQ_TYPE_EDGE_FALLING:
548                         IntrTypeReg |= ((u32)1 << (u32)PinNumber);
549                         IntrPolReg &= ~((u32)1 << (u32)PinNumber);
550                         IntrOnAnyReg &= ~((u32)1 << (u32)PinNumber);
551                         break;
552                 case XGPIOPS_IRQ_TYPE_EDGE_BOTH:
553                         IntrTypeReg |= ((u32)1 << (u32)PinNumber);
554                         IntrOnAnyReg |= ((u32)1 << (u32)PinNumber);
555                         break;
556                 case XGPIOPS_IRQ_TYPE_LEVEL_HIGH:
557                         IntrTypeReg &= ~((u32)1 << (u32)PinNumber);
558                         IntrPolReg |= ((u32)1 << (u32)PinNumber);
559                         break;
560                 case XGPIOPS_IRQ_TYPE_LEVEL_LOW:
561                         IntrTypeReg &= ~((u32)1 << (u32)PinNumber);
562                         IntrPolReg &= ~((u32)1 << (u32)PinNumber);
563                         break;
564                 default:
565                         /**< Default statement is added for MISRA C compliance. */
566                         break;
567         }
568
569         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
570                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
571                           XGPIOPS_INTTYPE_OFFSET, IntrTypeReg);
572
573         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
574                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
575                           XGPIOPS_INTPOL_OFFSET, IntrPolReg);
576
577         XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
578                           ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
579                           XGPIOPS_INTANY_OFFSET, IntrOnAnyReg);
580 }
581
582 /****************************************************************************/
583 /**
584 *
585 * This function returns the IRQ Type of a given GPIO pin.
586 *
587 * @param        InstancePtr is a pointer to an XGpioPs instance.
588 * @param        Pin is the pin number whose IRQ type is to be obtained.
589 *               Valid values are 0 to XGPIOPS_DEVICE_MAX_PIN_NUM - 1.
590 *
591 * @return       None.
592 *
593 * @note         Use XGPIOPS_IRQ_TYPE_* defined in xgpiops.h for the IRQ type
594 *               returned by this function.
595 *
596 *****************************************************************************/
597 u8 XGpioPs_GetIntrTypePin(XGpioPs *InstancePtr, u32 Pin)
598 {
599         u32 IntrType;
600         u32 IntrPol;
601         u32 IntrOnAny;
602         u8 Bank;
603         u8 PinNumber;
604         u8 IrqType;
605
606         Xil_AssertNonvoid(InstancePtr != NULL);
607         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
608         Xil_AssertNonvoid(Pin < XGPIOPS_DEVICE_MAX_PIN_NUM);
609
610         /*
611          * Get the Bank number and Pin number within the bank.
612          */
613         XGpioPs_GetBankPin((u8)Pin, &Bank, &PinNumber);
614
615         IntrType = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
616                                     ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
617                                     XGPIOPS_INTTYPE_OFFSET) & ((u32)1 << PinNumber);
618
619         if (IntrType == ((u32)1 << PinNumber)) {
620
621                 IntrOnAny = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
622                                      ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
623                                      XGPIOPS_INTANY_OFFSET) & ((u32)1 << PinNumber);
624
625                 IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
626                                    ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
627                                    XGPIOPS_INTPOL_OFFSET) & ((u32)1 << PinNumber);
628
629
630                 if (IntrOnAny == ((u32)1 << PinNumber)) {
631                         IrqType = XGPIOPS_IRQ_TYPE_EDGE_BOTH;
632                 } else if (IntrPol == ((u32)1 << PinNumber)) {
633                         IrqType = XGPIOPS_IRQ_TYPE_EDGE_RISING;
634                 } else {
635                         IrqType = XGPIOPS_IRQ_TYPE_EDGE_FALLING;
636                 }
637         } else {
638
639                 IntrPol = XGpioPs_ReadReg(InstancePtr->GpioConfig.BaseAddr,
640                                    ((u32)(Bank) * XGPIOPS_REG_MASK_OFFSET) +
641                                    XGPIOPS_INTPOL_OFFSET) & ((u32)1 << PinNumber);
642
643                 if (IntrPol == ((u32)1 << PinNumber)) {
644                         IrqType = XGPIOPS_IRQ_TYPE_LEVEL_HIGH;
645                 } else {
646                         IrqType = XGPIOPS_IRQ_TYPE_LEVEL_LOW;
647                 }
648         }
649
650         return IrqType;
651 }
652
653 /*****************************************************************************/
654 /**
655 *
656 * This function sets the status callback function. The callback function is
657 * called by the  XGpioPs_IntrHandler when an interrupt occurs.
658 *
659 * @param        InstancePtr is a pointer to the XGpioPs instance.
660 * @param        CallBackRef is the upper layer callback reference passed back
661 *               when the callback function is invoked.
662 * @param        FuncPtr is the pointer to the callback function.
663 *
664 *
665 * @return       None.
666 *
667 * @note         The handler is called within interrupt context, so it should do
668 *               its work quickly and queue potentially time-consuming work to a
669 *               task-level thread.
670 *
671 ******************************************************************************/
672 void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
673                                  XGpioPs_Handler FuncPointer)
674 {
675         Xil_AssertVoid(InstancePtr != NULL);
676         Xil_AssertVoid(FuncPointer != NULL);
677         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
678
679         InstancePtr->Handler = FuncPointer;
680         InstancePtr->CallBackRef = CallBackRef;
681 }
682
683 /*****************************************************************************/
684 /**
685 *
686 * This function is the interrupt handler for GPIO interrupts.It checks the
687 * interrupt status registers of all the banks to determine the actual bank in
688 * which an interrupt has been triggered. It then calls the upper layer callback
689 * handler set by the function XGpioPs_SetBankHandler(). The callback is called
690 * when an interrupt
691 *
692 * @param        InstancePtr is a pointer to the XGpioPs instance.
693 *
694 * @return       None.
695 *
696 * @note         This function does not save and restore the processor context
697 *               such that the user must provide this processing.
698 *
699 ******************************************************************************/
700 void XGpioPs_IntrHandler(XGpioPs *InstancePtr)
701 {
702         u8 Bank;
703         u32 IntrStatus;
704         u32 IntrEnabled;
705
706         Xil_AssertVoid(InstancePtr != NULL);
707         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
708
709         for (Bank = 0U; Bank < XGPIOPS_MAX_BANKS; Bank++) {
710                 IntrStatus = XGpioPs_IntrGetStatus(InstancePtr, Bank);
711                 if (IntrStatus != (u32)0) {
712                         IntrEnabled = XGpioPs_IntrGetEnabled(InstancePtr,
713                                                               Bank);
714                         XGpioPs_IntrClear((XGpioPs *)InstancePtr, Bank,
715                                                         (IntrStatus & IntrEnabled));
716                         InstancePtr->Handler(InstancePtr->
717                                              CallBackRef, Bank,
718                                              (IntrStatus & IntrEnabled));
719                 }
720         }
721 }
722
723 /*****************************************************************************/
724 /**
725 *
726 * This is a stub for the status callback. The stub is here in case the upper
727 * layers do not set the handler.
728 *
729 * @param        CallBackRef is a pointer to the upper layer callback reference
730 * @param        Bank is the GPIO Bank in which an interrupt occurred.
731 * @param        Status is the Interrupt status of the GPIO bank.
732 *
733 * @return       None.
734 *
735 * @note         None.
736 *
737 ******************************************************************************/
738 void StubHandler(void *CallBackRef, u32 Bank, u32 Status)
739 {
740         (void*) CallBackRef;
741         (void) Bank;
742         (void) Status;
743
744         Xil_AssertVoidAlways();
745 }