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