diff --git a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h index d787456d6b..ddea5c6061 100644 --- a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h +++ b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h @@ -51,20 +51,53 @@ void endstop_ISR() { endstops.update(); } * There are more PCI-enabled processor pins on Port J, but they are not connected to Arduino MEGA. */ #if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA) + #define digitalPinHasPCICR(p) (WITHIN(p, 10, 15) || WITHIN(p, 50, 53) || WITHIN(p, 62, 69)) - #define moreDigitalPinToPCICR(p) digitalPinToPCICR(WITHIN(p, 14, 15) ? 10 : p) - #define moreDigitalPinToPCICRbit(p) (WITHIN(p, 14, 15) ? 1 : digitalPinToPCICRbit(p)) - #define moreDigitalPinToPCMSK(p) (WITHIN(p, 14, 15) ? (&PCMSK1) : digitalPinToPCMSK(p)) - #define moreDigitalPinToPCMSKbit(p) digitalPinToPCMSKbit(WITHIN(p, 14, 15) ? (p)+36 : p) + + #undef digitalPinToPCICR + #define digitalPinToPCICR(p) (digitalPinHasPCICR(p) ? (&PCICR) : nullptr) + + #undef digitalPinToPCICRbit + #define digitalPinToPCICRbit(p) (WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \ + WITHIN(p, 14, 15) ? 1 : \ + WITHIN(p, 62, 69) ? 2 : \ + 0) + + #undef digitalPinToPCMSK + #define digitalPinToPCMSK(p) (WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? (&PCMSK0) : \ + WITHIN(p, 14, 15) ? (&PCMSK1) : \ + WITHIN(p, 62, 69) ? (&PCMSK2) : \ + nullptr) + + #undef digitalPinToPCMSKbit + #define digitalPinToPCMSKbit(p) (WITHIN(p, 10, 13) ? ((p) - 6) : \ + (p) == 14 || (p) == 51 ? 2 : \ + (p) == 15 || (p) == 52 ? 1 : \ + (p) == 50 ? 3 : \ + (p) == 53 ? 0 : \ + WITHIN(p, 62, 69) ? ((p) - 62) : \ + 0) + +#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324A__) || \ + defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega324PB__) || \ + defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284__) || \ + defined(__AVR_ATmega1284P__) + + #define digitalPinHasPCICR(p) WITHIN(p, 0, NUM_DIGITAL_PINS) + +#else + + #error "Unsupported AVR variant!" + #endif // Install Pin change interrupt for a pin. Can be called multiple times. void pciSetup(const int8_t pin) { - if (moreDigitalPinToPCMSK(pin) != nullptr) { - SBI(*moreDigitalPinToPCMSK(pin), moreDigitalPinToPCMSKbit(pin)); // enable pin - SBI(PCIFR, moreDigitalPinToPCICRbit(pin)); // clear any outstanding interrupt - SBI(PCICR, moreDigitalPinToPCICRbit(pin)); // enable interrupt for the group + if (digitalPinToPCMSK(pin) != nullptr) { + SBI(*digitalPinToPCMSK(pin), digitalPinToPCMSKbit(pin)); // enable pin + SBI(PCIFR, digitalPinToPCICRbit(pin)); // clear any outstanding interrupt + SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group } } diff --git a/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino b/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino index 92c69cc90e..6dcfb67c54 100644 --- a/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino +++ b/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino @@ -2,16 +2,17 @@ // Compile with the same build settings you'd use for Marlin. #if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA) - #define moreDigitalPinToPCICR(p) digitalPinToPCICR(WITHIN(p, 14, 15) ? 10 : p) -#else - #define moreDigitalPinToPCICR(p) digitalPinToPCICR(p) + #undef digitalPinToPCICR + #define digitalPinToPCICR(p) ( ((p) >= 10 && (p) <= 15) || \ + ((p) >= 50 && (p) <= 53) || \ + ((p) >= 62 && (p) <= 69) ? (&PCICR) : nullptr) #endif void setup() { Serial.begin(9600); Serial.println("PINs causing interrupts are:"); for (int i = 2; i < NUM_DIGITAL_PINS; i++) { - if (moreDigitalPinToPCICR(i) || (int)digitalPinToInterrupt(i) != -1) { + if (digitalPinToPCICR(i) || (int)digitalPinToInterrupt(i) != -1) { for (int j = 0; j < NUM_ANALOG_INPUTS; j++) { if (analogInputToDigitalPin(j) == i) { Serial.print('A');