root / arduino-1.0 / hardware / arduino / cores / arduino / WInterrupts.c @ 58d82c77
History | View | Annotate | Download (6.53 KB)
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 |
volatile static 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(EICRA) && defined(EICRB) && defined(EIMSK)
|
51 |
case 2: |
52 |
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); |
53 |
EIMSK |= (1 << INT0);
|
54 |
break;
|
55 |
case 3: |
56 |
EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); |
57 |
EIMSK |= (1 << INT1);
|
58 |
break;
|
59 |
case 4: |
60 |
EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20); |
61 |
EIMSK |= (1 << INT2);
|
62 |
break;
|
63 |
case 5: |
64 |
EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30); |
65 |
EIMSK |= (1 << INT3);
|
66 |
break;
|
67 |
case 0: |
68 |
EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40); |
69 |
EIMSK |= (1 << INT4);
|
70 |
break;
|
71 |
case 1: |
72 |
EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50); |
73 |
EIMSK |= (1 << INT5);
|
74 |
break;
|
75 |
case 6: |
76 |
EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60); |
77 |
EIMSK |= (1 << INT6);
|
78 |
break;
|
79 |
case 7: |
80 |
EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70); |
81 |
EIMSK |= (1 << INT7);
|
82 |
break;
|
83 |
#else
|
84 |
case 0: |
85 |
#if defined(EICRA) && defined(ISC00) && defined(EIMSK)
|
86 |
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); |
87 |
EIMSK |= (1 << INT0);
|
88 |
#elif defined(MCUCR) && defined(ISC00) && defined(GICR)
|
89 |
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); |
90 |
GICR |= (1 << INT0);
|
91 |
#elif defined(MCUCR) && defined(ISC00) && defined(GIMSK)
|
92 |
MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); |
93 |
GIMSK |= (1 << INT0);
|
94 |
#else
|
95 |
#error attachInterrupt not finished for this CPU (case 0) |
96 |
#endif
|
97 |
break;
|
98 |
|
99 |
case 1: |
100 |
#if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK)
|
101 |
EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); |
102 |
EIMSK |= (1 << INT1);
|
103 |
#elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR)
|
104 |
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); |
105 |
GICR |= (1 << INT1);
|
106 |
#elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK)
|
107 |
MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); |
108 |
GIMSK |= (1 << INT1);
|
109 |
#else
|
110 |
#warning attachInterrupt may need some more work for this cpu (case 1) |
111 |
#endif
|
112 |
break;
|
113 |
#endif
|
114 |
} |
115 |
} |
116 |
} |
117 |
|
118 |
void detachInterrupt(uint8_t interruptNum) {
|
119 |
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
|
120 |
// Disable the interrupt. (We can't assume that interruptNum is equal
|
121 |
// to the number of the EIMSK bit to clear, as this isn't true on the
|
122 |
// ATmega8. There, INT0 is 6 and INT1 is 7.)
|
123 |
switch (interruptNum) {
|
124 |
#if defined(EICRA) && defined(EICRB) && defined(EIMSK)
|
125 |
case 2: |
126 |
EIMSK &= ~(1 << INT0);
|
127 |
break;
|
128 |
case 3: |
129 |
EIMSK &= ~(1 << INT1);
|
130 |
break;
|
131 |
case 4: |
132 |
EIMSK &= ~(1 << INT2);
|
133 |
break;
|
134 |
case 5: |
135 |
EIMSK &= ~(1 << INT3);
|
136 |
break;
|
137 |
case 0: |
138 |
EIMSK &= ~(1 << INT4);
|
139 |
break;
|
140 |
case 1: |
141 |
EIMSK &= ~(1 << INT5);
|
142 |
break;
|
143 |
case 6: |
144 |
EIMSK &= ~(1 << INT6);
|
145 |
break;
|
146 |
case 7: |
147 |
EIMSK &= ~(1 << INT7);
|
148 |
break;
|
149 |
#else
|
150 |
case 0: |
151 |
#if defined(EIMSK) && defined(INT0)
|
152 |
EIMSK &= ~(1 << INT0);
|
153 |
#elif defined(GICR) && defined(ISC00)
|
154 |
GICR &= ~(1 << INT0); // atmega32 |
155 |
#elif defined(GIMSK) && defined(INT0)
|
156 |
GIMSK &= ~(1 << INT0);
|
157 |
#else
|
158 |
#error detachInterrupt not finished for this cpu |
159 |
#endif
|
160 |
break;
|
161 |
|
162 |
case 1: |
163 |
#if defined(EIMSK) && defined(INT1)
|
164 |
EIMSK &= ~(1 << INT1);
|
165 |
#elif defined(GICR) && defined(INT1)
|
166 |
GICR &= ~(1 << INT1); // atmega32 |
167 |
#elif defined(GIMSK) && defined(INT1)
|
168 |
GIMSK &= ~(1 << INT1);
|
169 |
#else
|
170 |
#warning detachInterrupt may need some more work for this cpu (case 1) |
171 |
#endif
|
172 |
break;
|
173 |
#endif
|
174 |
} |
175 |
|
176 |
intFunc[interruptNum] = 0;
|
177 |
} |
178 |
} |
179 |
|
180 |
/*
|
181 |
void attachInterruptTwi(void (*userFunc)(void) ) {
|
182 |
twiIntFunc = userFunc;
|
183 |
}
|
184 |
*/
|
185 |
|
186 |
#if defined(EICRA) && defined(EICRB)
|
187 |
|
188 |
SIGNAL(INT0_vect) { |
189 |
if(intFunc[EXTERNAL_INT_2])
|
190 |
intFunc[EXTERNAL_INT_2](); |
191 |
} |
192 |
|
193 |
SIGNAL(INT1_vect) { |
194 |
if(intFunc[EXTERNAL_INT_3])
|
195 |
intFunc[EXTERNAL_INT_3](); |
196 |
} |
197 |
|
198 |
SIGNAL(INT2_vect) { |
199 |
if(intFunc[EXTERNAL_INT_4])
|
200 |
intFunc[EXTERNAL_INT_4](); |
201 |
} |
202 |
|
203 |
SIGNAL(INT3_vect) { |
204 |
if(intFunc[EXTERNAL_INT_5])
|
205 |
intFunc[EXTERNAL_INT_5](); |
206 |
} |
207 |
|
208 |
SIGNAL(INT4_vect) { |
209 |
if(intFunc[EXTERNAL_INT_0])
|
210 |
intFunc[EXTERNAL_INT_0](); |
211 |
} |
212 |
|
213 |
SIGNAL(INT5_vect) { |
214 |
if(intFunc[EXTERNAL_INT_1])
|
215 |
intFunc[EXTERNAL_INT_1](); |
216 |
} |
217 |
|
218 |
SIGNAL(INT6_vect) { |
219 |
if(intFunc[EXTERNAL_INT_6])
|
220 |
intFunc[EXTERNAL_INT_6](); |
221 |
} |
222 |
|
223 |
SIGNAL(INT7_vect) { |
224 |
if(intFunc[EXTERNAL_INT_7])
|
225 |
intFunc[EXTERNAL_INT_7](); |
226 |
} |
227 |
|
228 |
#else
|
229 |
|
230 |
SIGNAL(INT0_vect) { |
231 |
if(intFunc[EXTERNAL_INT_0])
|
232 |
intFunc[EXTERNAL_INT_0](); |
233 |
} |
234 |
|
235 |
SIGNAL(INT1_vect) { |
236 |
if(intFunc[EXTERNAL_INT_1])
|
237 |
intFunc[EXTERNAL_INT_1](); |
238 |
} |
239 |
|
240 |
#endif
|
241 |
|
242 |
/*
|
243 |
SIGNAL(SIG_2WIRE_SERIAL) {
|
244 |
if(twiIntFunc)
|
245 |
twiIntFunc();
|
246 |
}
|
247 |
*/
|
248 |
|