Imported Upstream version 3.0
[debian/gnuradio] / usrp / firmware / lib / isr.c
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2003 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include "isr.h"
24 #include "fx2regs.h"
25 #include "syncdelay.h"
26
27 extern xdata unsigned char _standard_interrupt_vector[];
28 extern xdata unsigned char _usb_autovector[];
29 extern xdata unsigned char _fifo_gpif_autovector[];
30
31 #define LJMP_OPCODE     0x02
32
33 /*
34  * Hook standard interrupt vector.
35  *
36  * vector_number is from the SV_<foo> list.
37  * addr is the address of the interrupt service routine.
38  */
39 void 
40 hook_sv (unsigned char vector_number, unsigned short addr)
41 {
42   bit   t;
43   
44   // sanity checks
45
46   if (vector_number < SV_MIN || vector_number > SV_MAX)
47     return;
48
49   if ((vector_number & 0x0f) != 0x03 && (vector_number & 0x0f) != 0x0b)
50     return;
51
52   t = EA;
53   EA = 0;
54   _standard_interrupt_vector[vector_number] = LJMP_OPCODE;
55   _standard_interrupt_vector[vector_number + 1] = addr >> 8;
56   _standard_interrupt_vector[vector_number + 2] = addr & 0xff;
57   EA = t;
58 }
59
60 /*
61  * Hook usb interrupt vector.
62  *
63  * vector_number is from the UV_<foo> list.
64  * addr is the address of the interrupt service routine.
65  */
66 void 
67 hook_uv (unsigned char vector_number, unsigned short addr)
68 {
69   bit   t;
70   
71   // sanity checks
72
73   if (vector_number < UV_MIN || vector_number > UV_MAX)
74     return;
75
76   if ((vector_number & 0x3) != 0)
77     return;
78
79   t = EA;
80   EA = 0;
81   _usb_autovector[vector_number] = LJMP_OPCODE;
82   _usb_autovector[vector_number + 1] = addr >> 8;
83   _usb_autovector[vector_number + 2] = addr & 0xff;
84   EA = t;
85 }
86
87 /*
88  * Hook fifo/gpif interrupt vector.
89  *
90  * vector_number is from the FGV_<foo> list.
91  * addr is the address of the interrupt service routine.
92  */
93 void 
94 hook_fgv (unsigned char vector_number, unsigned short addr)
95 {
96   bit   t;
97   
98   // sanity checks
99
100   if (vector_number < FGV_MIN || vector_number > FGV_MAX)
101     return;
102
103   if ((vector_number & 0x3) != 0)
104     return;
105
106   t = EA;
107   EA = 0;
108   _fifo_gpif_autovector[vector_number] = LJMP_OPCODE;
109   _fifo_gpif_autovector[vector_number + 1] = addr >> 8;
110   _fifo_gpif_autovector[vector_number + 2] = addr & 0xff;
111   EA = t;
112 }
113
114 /*
115  * One time call to enable autovectoring for both USB and FIFO/GPIF.
116  *
117  * This disables all USB and FIFO/GPIF interrupts and clears
118  * any pending interrupts too.  It leaves the master USB and FIFO/GPIF
119  * interrupts enabled.
120  */
121 void
122 setup_autovectors (void)
123 {
124   // disable master usb and fifo/gpif interrupt enables
125   EIUSB = 0;
126   EIEX4 = 0;
127
128   hook_sv (SV_INT_2, (unsigned short) _usb_autovector);
129   hook_sv (SV_INT_4, (unsigned short) _fifo_gpif_autovector);
130
131   // disable all fifo interrupt enables
132   SYNCDELAY;
133   EP2FIFOIE = 0;        SYNCDELAY;
134   EP4FIFOIE = 0;        SYNCDELAY;
135   EP6FIFOIE = 0;        SYNCDELAY;
136   EP8FIFOIE = 0;        SYNCDELAY;
137
138   // clear all pending fifo irqs        
139   EP2FIFOIRQ = 0xff;    SYNCDELAY;
140   EP4FIFOIRQ = 0xff;    SYNCDELAY;
141   EP6FIFOIRQ = 0xff;    SYNCDELAY;
142   EP8FIFOIRQ = 0xff;    SYNCDELAY;
143
144   IBNIE  = 0;
145   IBNIRQ = 0xff;
146   NAKIE  = 0;
147   NAKIRQ = 0xff;
148   USBIE  = 0;
149   USBIRQ = 0xff;
150   EPIE   = 0;
151   EPIRQ  = 0xff;
152   SYNCDELAY;    GPIFIE = 0;             
153   SYNCDELAY;    GPIFIRQ = 0xff;
154   USBERRIE = 0;
155   USBERRIRQ = 0xff;
156   CLRERRCNT = 0;
157   
158   INTSETUP = bmAV2EN | bmAV4EN | bmINT4IN;
159
160   // clear master irq's for usb and fifo/gpif
161   EXIF &= ~bmEXIF_USBINT;
162   EXIF &= ~bmEXIF_IE4;
163   
164   // enable master usb and fifo/gpif interrrupts
165   EIUSB = 1;
166   EIEX4 = 1;
167 }