1 /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
4 Part of the Wiring project - http://wiring.uniandes.edu.co
6 Copyright (c) 2004-05 Hernando Barragan
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.
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.
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
23 Modified 24 November 2006 by David A. Mellis
24 Modified 1 August 2010 by Mark Sproul
29 #include <avr/interrupt.h>
30 #include <avr/pgmspace.h>
33 #include "wiring_private.h"
35 static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
36 // volatile static voidFuncPtr twiIntFunc;
38 void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
39 if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
40 intFunc[interruptNum] = userFunc;
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.
47 // Enable the interrupt.
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.
55 EICRA = (EICRA & ~((1<<ISC00) | (1<<ISC01))) | (mode << ISC00);
59 EICRA = (EICRA & ~((1<<ISC10) | (1<<ISC11))) | (mode << ISC10);
62 #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
64 EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
68 EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
72 EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
76 EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
80 EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
84 EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
88 EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
92 EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
97 #if defined(EICRA) && defined(ISC00) && defined(EIMSK)
98 EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
100 #elif defined(MCUCR) && defined(ISC00) && defined(GICR)
101 MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
103 #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK)
104 MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
105 GIMSK |= (1 << INT0);
107 #error attachInterrupt not finished for this CPU (case 0)
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);
118 #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK)
119 MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
120 GIMSK |= (1 << INT1);
122 #warning attachInterrupt may need some more work for this cpu (case 1)
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);
133 #elif defined(MCUCR) && defined(ISC20) && defined(GIMSK) && defined(GIMSK)
134 MCUCR = (MCUCR & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
135 GIMSK |= (1 << INT2);
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__)
156 #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
158 EIMSK &= ~(1 << INT0);
161 EIMSK &= ~(1 << INT1);
164 EIMSK &= ~(1 << INT2);
167 EIMSK &= ~(1 << INT3);
170 EIMSK &= ~(1 << INT4);
173 EIMSK &= ~(1 << INT5);
176 EIMSK &= ~(1 << INT6);
179 EIMSK &= ~(1 << INT7);
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);
190 #error detachInterrupt not finished for this cpu
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);
202 #warning detachInterrupt may need some more work for this cpu (case 1)
208 intFunc[interruptNum] = 0;
213 void attachInterruptTwi(void (*userFunc)(void) ) {
214 twiIntFunc = userFunc;
218 #if defined(__AVR_ATmega32U4__)
220 if(intFunc[EXTERNAL_INT_0])
221 intFunc[EXTERNAL_INT_0]();
225 if(intFunc[EXTERNAL_INT_1])
226 intFunc[EXTERNAL_INT_1]();
229 #elif defined(EICRA) && defined(EICRB)
232 if(intFunc[EXTERNAL_INT_2])
233 intFunc[EXTERNAL_INT_2]();
237 if(intFunc[EXTERNAL_INT_3])
238 intFunc[EXTERNAL_INT_3]();
242 if(intFunc[EXTERNAL_INT_4])
243 intFunc[EXTERNAL_INT_4]();
247 if(intFunc[EXTERNAL_INT_5])
248 intFunc[EXTERNAL_INT_5]();
252 if(intFunc[EXTERNAL_INT_0])
253 intFunc[EXTERNAL_INT_0]();
257 if(intFunc[EXTERNAL_INT_1])
258 intFunc[EXTERNAL_INT_1]();
262 if(intFunc[EXTERNAL_INT_6])
263 intFunc[EXTERNAL_INT_6]();
267 if(intFunc[EXTERNAL_INT_7])
268 intFunc[EXTERNAL_INT_7]();
274 if(intFunc[EXTERNAL_INT_0])
275 intFunc[EXTERNAL_INT_0]();
279 if(intFunc[EXTERNAL_INT_1])
280 intFunc[EXTERNAL_INT_1]();
283 #if defined(EICRA) && defined(ISC20)
285 if(intFunc[EXTERNAL_INT_2])
286 intFunc[EXTERNAL_INT_2]();
293 SIGNAL(SIG_2WIRE_SERIAL) {