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