version 4.1.0 from http://fpga4u.epfl.ch/wiki/FX2
[fx2fw-sdcc] / fx2 / isr.c
1 /* -*- c++ -*- */\r
2 \r
3 /*-----------------------------------------------------------------------------\r
4 \r
5  * Interrupt handling for FX2\r
6 \r
7  *-----------------------------------------------------------------------------\r
8 \r
9  * Code taken from USRP2 firmware (GNU Radio Project), version 3.0.2,\r
10 \r
11  * Copyright 2003 Free Software Foundation, Inc.\r
12 \r
13  *-----------------------------------------------------------------------------\r
14 \r
15  * This code is part of usbjtag. usbjtag is free software; you can redistribute\r
16 \r
17  * it and/or modify it under the terms of the GNU General Public License as\r
18 \r
19  * published by the Free Software Foundation; either version 2 of the License,\r
20 \r
21  * or (at your option) any later version. usbjtag is distributed in the hope\r
22 \r
23  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied\r
24 \r
25  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
26 \r
27  * GNU General Public License for more details.  You should have received a\r
28 \r
29  * copy of the GNU General Public License along with this program in the file\r
30 \r
31  * COPYING; if not, write to the Free Software Foundation, Inc., 51 Franklin\r
32 \r
33  * St, Fifth Floor, Boston, MA  02110-1301  USA\r
34 \r
35  *-----------------------------------------------------------------------------\r
36 \r
37  */\r
38 \r
39 \r
40 \r
41 #include "isr.h"\r
42 \r
43 #include "fx2regs.h"\r
44 \r
45 #include "syncdelay.h"\r
46 \r
47 \r
48 \r
49 extern xdata unsigned char _standard_interrupt_vector[];\r
50 \r
51 extern xdata unsigned char _usb_autovector[];\r
52 \r
53 extern xdata unsigned char _fifo_gpif_autovector[];\r
54 \r
55 \r
56 \r
57 #define LJMP_OPCODE     0x02\r
58 \r
59 \r
60 \r
61 /*\r
62 \r
63  * Hook standard interrupt vector.\r
64 \r
65  *\r
66 \r
67  * vector_number is from the SV_<foo> list.\r
68 \r
69  * addr is the address of the interrupt service routine.\r
70 \r
71  */\r
72 \r
73 void \r
74 \r
75 hook_sv (unsigned char vector_number, unsigned short addr)\r
76 \r
77 {\r
78 \r
79   bit   t;\r
80 \r
81   \r
82 \r
83   // sanity checks\r
84 \r
85 \r
86 \r
87   if (vector_number < SV_MIN || vector_number > SV_MAX)\r
88 \r
89     return;\r
90 \r
91 \r
92 \r
93   if ((vector_number & 0x0f) != 0x03 && (vector_number & 0x0f) != 0x0b)\r
94 \r
95     return;\r
96 \r
97 \r
98 \r
99   t = EA;\r
100 \r
101   EA = 0;\r
102 \r
103   _standard_interrupt_vector[vector_number] = LJMP_OPCODE;\r
104 \r
105   _standard_interrupt_vector[vector_number + 1] = addr >> 8;\r
106 \r
107   _standard_interrupt_vector[vector_number + 2] = addr & 0xff;\r
108 \r
109   EA = t;\r
110 \r
111 }\r
112 \r
113 \r
114 \r
115 /*\r
116 \r
117  * Hook usb interrupt vector.\r
118 \r
119  *\r
120 \r
121  * vector_number is from the UV_<foo> list.\r
122 \r
123  * addr is the address of the interrupt service routine.\r
124 \r
125  */\r
126 \r
127 void \r
128 \r
129 hook_uv (unsigned char vector_number, unsigned short addr)\r
130 \r
131 {\r
132 \r
133   bit   t;\r
134 \r
135   \r
136 \r
137   // sanity checks\r
138 \r
139 \r
140 \r
141 #if UV_MIN>0\r
142 \r
143   if (vector_number < UV_MIN) return;\r
144 \r
145 #endif\r
146 \r
147   if (vector_number > UV_MAX)\r
148 \r
149     return;\r
150 \r
151 \r
152 \r
153   if ((vector_number & 0x3) != 0)\r
154 \r
155     return;\r
156 \r
157 \r
158 \r
159   t = EA;\r
160 \r
161   EA = 0;\r
162 \r
163   _usb_autovector[vector_number] = LJMP_OPCODE;\r
164 \r
165   _usb_autovector[vector_number + 1] = addr >> 8;\r
166 \r
167   _usb_autovector[vector_number + 2] = addr & 0xff;\r
168 \r
169   EA = t;\r
170 \r
171 }\r
172 \r
173 \r
174 \r
175 /*\r
176 \r
177  * Hook fifo/gpif interrupt vector.\r
178 \r
179  *\r
180 \r
181  * vector_number is from the FGV_<foo> list.\r
182 \r
183  * addr is the address of the interrupt service routine.\r
184 \r
185  */\r
186 \r
187 void \r
188 \r
189 hook_fgv (unsigned char vector_number, unsigned short addr)\r
190 \r
191 {\r
192 \r
193   bit   t;\r
194 \r
195   \r
196 \r
197   // sanity checks\r
198 \r
199 \r
200 \r
201   if (vector_number < FGV_MIN || vector_number > FGV_MAX)\r
202 \r
203     return;\r
204 \r
205 \r
206 \r
207   if ((vector_number & 0x3) != 0)\r
208 \r
209     return;\r
210 \r
211 \r
212 \r
213   t = EA;\r
214 \r
215   EA = 0;\r
216 \r
217   _fifo_gpif_autovector[vector_number] = LJMP_OPCODE;\r
218 \r
219   _fifo_gpif_autovector[vector_number + 1] = addr >> 8;\r
220 \r
221   _fifo_gpif_autovector[vector_number + 2] = addr & 0xff;\r
222 \r
223   EA = t;\r
224 \r
225 }\r
226 \r
227 \r
228 \r
229 /*\r
230 \r
231  * One time call to enable autovectoring for both USB and FIFO/GPIF.\r
232 \r
233  *\r
234 \r
235  * This disables all USB and FIFO/GPIF interrupts and clears\r
236 \r
237  * any pending interrupts too.  It leaves the master USB and FIFO/GPIF\r
238 \r
239  * interrupts enabled.\r
240 \r
241  */\r
242 \r
243 void\r
244 \r
245 setup_autovectors (void)\r
246 \r
247 {\r
248 \r
249   // disable master usb and fifo/gpif interrupt enables\r
250 \r
251   EIUSB = 0;\r
252 \r
253   EIEX4 = 0;\r
254 \r
255 \r
256 \r
257   hook_sv (SV_INT_2, (unsigned short) _usb_autovector);\r
258 \r
259   hook_sv (SV_INT_4, (unsigned short) _fifo_gpif_autovector);\r
260 \r
261 \r
262 \r
263   // disable all fifo interrupt enables\r
264 \r
265   SYNCDELAY;\r
266 \r
267   EP2FIFOIE = 0;        SYNCDELAY;\r
268 \r
269   EP4FIFOIE = 0;        SYNCDELAY;\r
270 \r
271   EP6FIFOIE = 0;        SYNCDELAY;\r
272 \r
273   EP8FIFOIE = 0;        SYNCDELAY;\r
274 \r
275 \r
276 \r
277   // clear all pending fifo irqs        \r
278 \r
279   EP2FIFOIRQ = 0xff;    SYNCDELAY;\r
280 \r
281   EP4FIFOIRQ = 0xff;    SYNCDELAY;\r
282 \r
283   EP6FIFOIRQ = 0xff;    SYNCDELAY;\r
284 \r
285   EP8FIFOIRQ = 0xff;    SYNCDELAY;\r
286 \r
287 \r
288 \r
289   IBNIE  = 0;\r
290 \r
291   IBNIRQ = 0xff;\r
292 \r
293   NAKIE  = 0;\r
294 \r
295   NAKIRQ = 0xff;\r
296 \r
297   USBIE  = 0;\r
298 \r
299   USBIRQ = 0xff;\r
300 \r
301   EPIE   = 0;\r
302 \r
303   EPIRQ  = 0xff;\r
304 \r
305   SYNCDELAY;    GPIFIE = 0;             \r
306 \r
307   SYNCDELAY;    GPIFIRQ = 0xff;\r
308 \r
309   USBERRIE = 0;\r
310 \r
311   USBERRIRQ = 0xff;\r
312 \r
313   CLRERRCNT = 0;\r
314 \r
315   \r
316 \r
317   INTSETUP = bmAV2EN | bmAV4EN | bmINT4IN;\r
318 \r
319 \r
320 \r
321   // clear master irq's for usb and fifo/gpif\r
322 \r
323   EXIF &= ~bmEXIF_USBINT;\r
324 \r
325   EXIF &= ~bmEXIF_IE4;\r
326 \r
327   \r
328 \r
329   // enable master usb and fifo/gpif interrrupts\r
330 \r
331   EIUSB = 1;\r
332 \r
333   EIEX4 = 1;\r
334 \r
335 }\r
336 \r