sanguino/cores/arduino/WInterrupts.c

changeset 2
b373b0288715
equal deleted inserted replaced
1:b584642d4f58 2:b373b0288715
1 /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2
3 /*
4 Part of the Wiring project - http://wiring.uniandes.edu.co
5
6 Copyright (c) 2004-05 Hernando Barragan
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General
19 Public License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 Boston, MA 02111-1307 USA
22
23 Modified 24 November 2006 by David A. Mellis
24 Modified 1 August 2010 by Mark Sproul
25 */
26
27 #include <inttypes.h>
28 #include <avr/io.h>
29 #include <avr/interrupt.h>
30 #include <avr/pgmspace.h>
31 #include <stdio.h>
32
33 #include "wiring_private.h"
34
35 static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
36 // volatile static voidFuncPtr twiIntFunc;
37
38 void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
39 if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
40 intFunc[interruptNum] = userFunc;
41
42 // Configure the interrupt mode (trigger on low input, any change, rising
43 // edge, or falling edge). The mode constants were chosen to correspond
44 // to the configuration bits in the hardware register, so we simply shift
45 // the mode into place.
46
47 // Enable the interrupt.
48
49 switch (interruptNum) {
50 #if defined(__AVR_ATmega32U4__)
51 // I hate doing this, but the register assignment differs between the 1280/2560
52 // and the 32U4. Since avrlib defines registers PCMSK1 and PCMSK2 that aren't
53 // even present on the 32U4 this is the only way to distinguish between them.
54 case 0:
55 EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
56 EIMSK |= (1<<INT0);
57 break;
58 case 1:
59 EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
60 EIMSK |= (1<<INT1);
61 break;
62 #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
63 case 2:
64 EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
65 EIMSK |= (1 << INT0);
66 break;
67 case 3:
68 EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
69 EIMSK |= (1 << INT1);
70 break;
71 case 4:
72 EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
73 EIMSK |= (1 << INT2);
74 break;
75 case 5:
76 EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
77 EIMSK |= (1 << INT3);
78 break;
79 case 0:
80 EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
81 EIMSK |= (1 << INT4);
82 break;
83 case 1:
84 EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
85 EIMSK |= (1 << INT5);
86 break;
87 case 6:
88 EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
89 EIMSK |= (1 << INT6);
90 break;
91 case 7:
92 EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
93 EIMSK |= (1 << INT7);
94 break;
95 #else
96 case 0:
97 #if defined(EICRA) && defined(ISC00) && defined(EIMSK)
98 EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
99 EIMSK |= (1 << INT0);
100 #elif defined(MCUCR) && defined(ISC00) && defined(GICR)
101 MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
102 GICR |= (1 << INT0);
103 #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK)
104 MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
105 GIMSK |= (1 << INT0);
106 #else
107 #error attachInterrupt not finished for this CPU (case 0)
108 #endif
109 break;
110
111 case 1:
112 #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK)
113 EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
114 EIMSK |= (1 << INT1);
115 #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR)
116 MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
117 GICR |= (1 << INT1);
118 #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK)
119 MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
120 GIMSK |= (1 << INT1);
121 #else
122 #warning attachInterrupt may need some more work for this cpu (case 1)
123 #endif
124 break;
125
126 case 2:
127 #if defined(EICRA) && defined(ISC20) && defined(ISC21) && defined(EIMSK)
128 EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
129 EIMSK |= (1 << INT2);
130 #elif defined(MCUCR) && defined(ISC20) && defined(ISC21) && defined(GICR)
131 MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
132 GICR |= (1 << INT2);
133 #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK)
134 MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
135 GIMSK |= (1 << INT2);
136 #endif
137 break;
138 #endif
139 }
140 }
141 }
142
143 void detachInterrupt(uint8_t interruptNum) {
144 if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
145 // Disable the interrupt. (We can't assume that interruptNum is equal
146 // to the number of the EIMSK bit to clear, as this isn't true on the
147 // ATmega8. There, INT0 is 6 and INT1 is 7.)
148 switch (interruptNum) {
149 #if defined(__AVR_ATmega32U4__)
150 case 0:
151 EIMSK &= ~(1<<INT0);
152 break;
153 case 1:
154 EIMSK &= ~(1<<INT1);
155 break;
156 #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
157 case 2:
158 EIMSK &= ~(1 << INT0);
159 break;
160 case 3:
161 EIMSK &= ~(1 << INT1);
162 break;
163 case 4:
164 EIMSK &= ~(1 << INT2);
165 break;
166 case 5:
167 EIMSK &= ~(1 << INT3);
168 break;
169 case 0:
170 EIMSK &= ~(1 << INT4);
171 break;
172 case 1:
173 EIMSK &= ~(1 << INT5);
174 break;
175 case 6:
176 EIMSK &= ~(1 << INT6);
177 break;
178 case 7:
179 EIMSK &= ~(1 << INT7);
180 break;
181 #else
182 case 0:
183 #if defined(EIMSK) && defined(INT0)
184 EIMSK &= ~(1 << INT0);
185 #elif defined(GICR) && defined(ISC00)
186 GICR &= ~(1 << INT0); // atmega32
187 #elif defined(GIMSK) && defined(INT0)
188 GIMSK &= ~(1 << INT0);
189 #else
190 #error detachInterrupt not finished for this cpu
191 #endif
192 break;
193
194 case 1:
195 #if defined(EIMSK) && defined(INT1)
196 EIMSK &= ~(1 << INT1);
197 #elif defined(GICR) && defined(INT1)
198 GICR &= ~(1 << INT1); // atmega32
199 #elif defined(GIMSK) && defined(INT1)
200 GIMSK &= ~(1 << INT1);
201 #else
202 #warning detachInterrupt may need some more work for this cpu (case 1)
203 #endif
204 break;
205 #endif
206 }
207
208 intFunc[interruptNum] = 0;
209 }
210 }
211
212 /*
213 void attachInterruptTwi(void (*userFunc)(void) ) {
214 twiIntFunc = userFunc;
215 }
216 */
217
218 #if defined(__AVR_ATmega32U4__)
219 SIGNAL(INT0_vect) {
220 if(intFunc[EXTERNAL_INT_0])
221 intFunc[EXTERNAL_INT_0]();
222 }
223
224 SIGNAL(INT1_vect) {
225 if(intFunc[EXTERNAL_INT_1])
226 intFunc[EXTERNAL_INT_1]();
227 }
228
229 #elif defined(EICRA) && defined(EICRB)
230
231 SIGNAL(INT0_vect) {
232 if(intFunc[EXTERNAL_INT_2])
233 intFunc[EXTERNAL_INT_2]();
234 }
235
236 SIGNAL(INT1_vect) {
237 if(intFunc[EXTERNAL_INT_3])
238 intFunc[EXTERNAL_INT_3]();
239 }
240
241 SIGNAL(INT2_vect) {
242 if(intFunc[EXTERNAL_INT_4])
243 intFunc[EXTERNAL_INT_4]();
244 }
245
246 SIGNAL(INT3_vect) {
247 if(intFunc[EXTERNAL_INT_5])
248 intFunc[EXTERNAL_INT_5]();
249 }
250
251 SIGNAL(INT4_vect) {
252 if(intFunc[EXTERNAL_INT_0])
253 intFunc[EXTERNAL_INT_0]();
254 }
255
256 SIGNAL(INT5_vect) {
257 if(intFunc[EXTERNAL_INT_1])
258 intFunc[EXTERNAL_INT_1]();
259 }
260
261 SIGNAL(INT6_vect) {
262 if(intFunc[EXTERNAL_INT_6])
263 intFunc[EXTERNAL_INT_6]();
264 }
265
266 SIGNAL(INT7_vect) {
267 if(intFunc[EXTERNAL_INT_7])
268 intFunc[EXTERNAL_INT_7]();
269 }
270
271 #else
272
273 SIGNAL(INT0_vect) {
274 if(intFunc[EXTERNAL_INT_0])
275 intFunc[EXTERNAL_INT_0]();
276 }
277
278 SIGNAL(INT1_vect) {
279 if(intFunc[EXTERNAL_INT_1])
280 intFunc[EXTERNAL_INT_1]();
281 }
282
283 #if defined(EICRA) && defined(ISC20)
284 SIGNAL(INT2_vect) {
285 if(intFunc[EXTERNAL_INT_2])
286 intFunc[EXTERNAL_INT_2]();
287 }
288 #endif
289
290 #endif
291
292 /*
293 SIGNAL(SIG_2WIRE_SERIAL) {
294 if(twiIntFunc)
295 twiIntFunc();
296 }
297 */
298

mercurial