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