root / arduino-1.0 / hardware / arduino / cores / arduino / WInterrupts.c @ 58d82c77
History | View | Annotate | Download (6.53 KB)
1 | 58d82c77 | Tom Mullins | /* -*- 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 | */
|