Imported Upstream version 3.2.2
[debian/gnuradio] / usrp2 / firmware / lib / pic.c
1 /* -*- c -*- */
2 /*
3  * Copyright 2007 Free Software Foundation, Inc.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "pic.h"
20 #include "hal_io.h"
21 #include "memory_map.h"
22
23
24 #define NVECTORS 8
25
26 /*
27  * Our secondary interrupt vector.
28  */
29 irq_handler_t pic_vector[NVECTORS] = {
30   nop_handler,
31   nop_handler,
32   nop_handler,
33   nop_handler,
34   nop_handler,
35   nop_handler,
36   nop_handler,
37   nop_handler
38 };
39
40
41 void
42 pic_init(void)
43 {
44   // uP is level triggered
45
46   pic_regs->mask = ~0;                                 // mask all interrupts
47   pic_regs->edge_enable = PIC_TIMER_INT | PIC_PHY_INT;
48   pic_regs->polarity = ~0 & ~PIC_PHY_INT;              // rising edge
49   pic_regs->pending = ~0;                              // clear all pending ints
50 }
51
52 /*
53  * This magic gets pic_interrupt_handler wired into the
54  * system interrupt handler with the appropriate prologue and
55  * epilogue.
56  */
57 void pic_interrupt_handler() __attribute__ ((interrupt_handler));
58
59 void pic_interrupt_handler()
60 {
61   // pending and not masked interrupts
62   int live = pic_regs->pending & ~pic_regs->mask;
63
64   // FIXME loop while there are interrupts to service.
65   //   That will reduce our overhead.
66
67   // handle the first one set
68   int i;
69   int mask;
70   for (i=0, mask=1; i < NVECTORS; i++, mask <<= 1){
71     if (mask & live){           // handle this one
72       // puthex_nl(i);
73       (*pic_vector[i])(i);
74       pic_regs->pending = mask; // clear pending interrupt
75       return;
76     }
77   }
78 }
79
80 void
81 pic_register_handler(unsigned irq, irq_handler_t handler)
82 {
83   if (irq >= NVECTORS)
84     return;
85   pic_vector[irq] = handler;
86
87   pic_regs->mask &= ~IRQ_TO_MASK(irq);
88 }
89
90 void
91 nop_handler(unsigned irq)
92 {
93   // nop
94 }