From b0888a34b5c9584ccbb07419d8890bf8c498ce24 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sun, 17 Oct 2010 14:05:46 -0400 Subject: [PATCH] Making attachInterrupt() check registers, not CPUs. Patch by Mark Sproul, via Christian Maglie. http://code.google.com/p/arduino/issues/detail?id=340 --- hardware/arduino/cores/arduino/WInterrupts.c | 50 ++++++++++++++++---- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/hardware/arduino/cores/arduino/WInterrupts.c b/hardware/arduino/cores/arduino/WInterrupts.c index 9c5741148..3b3e0c9ec 100755 --- a/hardware/arduino/cores/arduino/WInterrupts.c +++ b/hardware/arduino/cores/arduino/WInterrupts.c @@ -21,6 +21,7 @@ Boston, MA 02111-1307 USA Modified 24 November 2006 by David A. Mellis + Modified 1 August 2010 by Mark Sproul */ #include @@ -35,11 +36,6 @@ volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS]; // volatile static voidFuncPtr twiIntFunc; -#if defined(__AVR_ATmega8__) -#define EICRA MCUCR -#define EIMSK GICR -#endif - void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { intFunc[interruptNum] = userFunc; @@ -52,7 +48,7 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { // Enable the interrupt. switch (interruptNum) { -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(EICRA) && defined(EICRB) && defined(EIMSK) case 2: EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); EIMSK |= (1 << INT0); @@ -87,12 +83,33 @@ void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { break; #else case 0: + #if defined(EICRA) && defined(ISC00) && defined(EIMSK) EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); EIMSK |= (1 << INT0); + #elif defined(MCUCR) && defined(ISC00) && defined(GICR) + MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); + GICR |= (1 << INT0); + #elif defined(MCUCR) && defined(ISC00) && defined(GIMSK) + MCUCR = (MCUCR & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00); + GIMSK |= (1 << INT0); + #else + #error attachInterrupt not finished for this CPU (case 0) + #endif break; + case 1: + #if defined(EICRA) && defined(ISC10) && defined(ISC11) && defined(EIMSK) EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); EIMSK |= (1 << INT1); + #elif defined(MCUCR) && defined(ISC10) && defined(ISC11) && defined(GICR) + MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); + GICR |= (1 << INT1); + #elif defined(MCUCR) && defined(ISC10) && defined(GIMSK) && defined(GIMSK) + MCUCR = (MCUCR & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10); + GIMSK |= (1 << INT1); + #else + #warning attachInterrupt may need some more work for this cpu (case 1) + #endif break; #endif } @@ -105,7 +122,7 @@ void detachInterrupt(uint8_t interruptNum) { // to the number of the EIMSK bit to clear, as this isn't true on the // ATmega8. There, INT0 is 6 and INT1 is 7.) switch (interruptNum) { -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(EICRA) && defined(EICRB) && defined(EIMSK) case 2: EIMSK &= ~(1 << INT0); break; @@ -132,10 +149,27 @@ void detachInterrupt(uint8_t interruptNum) { break; #else case 0: + #if defined(EIMSK) && defined(INT0) EIMSK &= ~(1 << INT0); + #elif defined(GICR) && defined(ISC00) + GICR &= ~(1 << INT0); // atmega32 + #elif defined(GIMSK) && defined(INT0) + GIMSK &= ~(1 << INT0); + #else + #error detachInterrupt not finished for this cpu + #endif break; + case 1: + #if defined(EIMSK) && defined(INT1) EIMSK &= ~(1 << INT1); + #elif defined(GICR) && defined(INT1) + GICR &= ~(1 << INT1); // atmega32 + #elif defined(GIMSK) && defined(INT1) + GIMSK &= ~(1 << INT1); + #else + #warning detachInterrupt may need some more work for this cpu (case 1) + #endif break; #endif } @@ -150,7 +184,7 @@ void attachInterruptTwi(void (*userFunc)(void) ) { } */ -#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#if defined(EICRA) && defined(EICRB) SIGNAL(INT0_vect) { if(intFunc[EXTERNAL_INT_2])