From f3eee02596240b5db0e5491ae93acd750acce719 Mon Sep 17 00:00:00 2001 From: AnHardt Date: Sat, 5 Nov 2016 22:38:48 +0100 Subject: [PATCH] Introduce endstop interrupts If ENDSTOP_INTERRUPTS_FEATURE is enabled this tries to set up interrupt routines for all used endstop pins. If this worked without errors, `endstops.update()` is called only if one of the endstops changed its state. The new interrupt routines do not really check the endstops and react upon them. All what they do, is to set a flag if it makes sense to call the endstop test we are used to. This can be used on: * ARM (DUE) based boards - all pins can raise interrupts, * RAMPS - all 6 endstop pins plus some other on EXT-2 can raise interrupts, * RAMPS based boards - as long the designers did not change the pins for the endstops or at least left enough, * all boards, if there are enough pins that can raise interrupts, and you are willing/able to swap with pins dedicated to other purpose. --- Marlin/Configuration.h | 3 + Marlin/Marlin_main.cpp | 7 + Marlin/endstop_interrupts.h | 211 ++++++++++++++++++ .../Cartesio/Configuration.h | 3 + .../Felix/Configuration.h | 3 + .../Felix/DUAL/Configuration.h | 3 + .../Hephestos/Configuration.h | 3 + .../Hephestos_2/Configuration.h | 3 + .../K8200/Configuration.h | 3 + .../K8400/Configuration.h | 3 + .../K8400/Dual-head/Configuration.h | 3 + .../RepRapWorld/Megatronics/Configuration.h | 3 + .../RigidBot/Configuration.h | 3 + .../SCARA/Configuration.h | 3 + .../TAZ4/Configuration.h | 3 + .../WITBOX/Configuration.h | 3 + .../adafruit/ST7565/Configuration.h | 3 + .../delta/biv2.5/Configuration.h | 3 + .../delta/generic/Configuration.h | 3 + .../delta/kossel_mini/Configuration.h | 3 + .../delta/kossel_pro/Configuration.h | 3 + .../delta/kossel_xl/Configuration.h | 3 + .../makibox/Configuration.h | 3 + .../tvrrug/Round2/Configuration.h | 3 + Marlin/stepper.cpp | 14 +- .../pin_interrupt_test/pin_interrupt_test.ino | 32 +++ 26 files changed, 329 insertions(+), 1 deletion(-) create mode 100644 Marlin/endstop_interrupts.h create mode 100644 buildroot/share/pin_interrupt_test/pin_interrupt_test.ino diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index 75ab781a7..5b15c3f3f 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -445,6 +445,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 5473f5387..862f7dfc5 100755 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -89,6 +89,9 @@ #include "twibus.h" #endif +#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + #include "endstop_interrupts.h" +#endif /** * Look here for descriptions of G-codes: * - http://linuxcnc.org/handbook/gcode/g-code.html @@ -10000,6 +10003,10 @@ void setup() { i2c.onReceive(i2c_on_receive); i2c.onRequest(i2c_on_request); #endif + + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + setup_enstop_interrupts(); + #endif } /** diff --git a/Marlin/endstop_interrupts.h b/Marlin/endstop_interrupts.h new file mode 100644 index 000000000..db8691d19 --- /dev/null +++ b/Marlin/endstop_interrupts.h @@ -0,0 +1,211 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Endstop interrupts + * Without endstop interrups the stepper-ISR must always test all endstops when interested in their states (endstops.update()). + * Most time the test will result in finding out nothing has changed. + * With endstop interrupts endstops.update() is called only when we know that at least one endstop has changed its state. + * + * This can work only if all __used__ endstop pins can provide ether an 'external interrupt' or a 'pin change interrupt'. + * You can find out about pins issuing interrupts by running 'pin_interrupt_test.ino' (Marlin\buildroot\share\pin_interrupt_test\pin_interrupt_test.ino) + */ + + #ifndef _ENDSTOP_INTERRUPTS_H_ + #define _ENDSTOP_INTERRUPTS_H_ + + /** + * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h) + * + * These macros for the Arduino MEGA do not include the two connected pins on Port J (D13, D14). + * So we extend them here because this are the normal pins for Y_MIN and Y_MAX on RAMPS. + * 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) + #undef digitalPinToPCICR + #define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 15)) || \ + (((p) >= 50) && ((p) <= 53)) || \ + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) + #undef digitalPinToPCICRbit + #define digitalPinToPCICRbit(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? 0 : \ + ( (((p) >= 14) && ((p) <= 15)) ? 1 : \ + ( (((p) >= 62) && ((p) <= 69)) ? 2 : \ + 0 ) ) ) + #undef digitalPinToPCMSK + #define digitalPinToPCMSK(p) ( (((p) >= 10) && ((p) <= 13)) || (((p) >= 50) && ((p) <= 53)) ? (&PCMSK0) : \ + ( (((p) >= 14) && ((p) <= 15)) ? (&PCMSK1) : \ + ( (((p) >= 62) && ((p) <= 69)) ? (&PCMSK2) : \ + ((uint8_t *)0) ) ) ) + #undef digitalPinToPCMSKbit + #define digitalPinToPCMSKbit(p) ( (((p) >= 10) && ((p) <= 13)) ? ((p) - 6) : \ + ( ((p) == 14) ? 2 : \ + ( ((p) == 15) ? 1 : \ + ( ((p) == 50) ? 3 : \ + ( ((p) == 51) ? 2 : \ + ( ((p) == 52) ? 1 : \ + ( ((p) == 53) ? 0 : \ + ( (((p) >= 62) && ((p) <= 69)) ? ((p) - 62) : \ + 0 ) ) ) ) ) ) ) ) + #endif + + volatile uint8_t e_hit = 0; // Different from 0 when the endstops shall be tested in detail. + // Must be reset to 0 by the test function when the tests are finished. + + // Install Pin change interrupt for a pin, can be called multiple times + void pciSetup(byte pin) { + *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin + PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt + PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group + } + + // This is what is really done inside the interrupts. + FORCE_INLINE void endstop_ISR_worker( void ) { + e_hit = 2; // Because the detection of a e-stop hit has a 1 step debouncer it has to be called at least twice. + } + + // Use one Routine to handle each group + // One ISR for all EXT-Interrupts + void endstop_ISR(void) { + endstop_ISR_worker(); + } + + #ifdef PCINT0_vect + ISR(PCINT0_vect) { // handle pin change interrupt + endstop_ISR_worker(); + } + #endif + + #ifdef PCINT1_vect + ISR(PCINT1_vect) { // handle pin change interrupt + endstop_ISR_worker(); + } + #endif + + #ifdef PCINT2_vect + ISR(PCINT2_vect) { // handle pin change interrupt + endstop_ISR_worker(); + } + #endif + + #ifdef PCINT3_vect + ISR(PCINT3_vect) { // handle pin change interrupt + endstop_ISR_worker(); + } + #endif + + void setup_enstop_interrupts( void ) { + + #if HAS_X_MAX + #if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT) // if pin has an external interrupt + attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE); // assign it + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X_MAX_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); // if pin has no pin change interrupt - error + pciSetup(X_MAX_PIN); // assign it + #endif + #endif + + #if HAS_X_MIN + #if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(X_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X_MIN_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(X_MIN_PIN); + #endif + #endif + + #if HAS_Y_MAX + #if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y_MAX_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Y_MAX_PIN); + #endif + #endif + + #if HAS_Y_MIN + #if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y_MIN_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Y_MIN_PIN); + #endif + #endif + + #if HAS_Z_MAX + #if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z_MAX_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Z_MAX_PIN); + #endif + #endif + + #if HAS_Z_MIN + #if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z_MIN_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Z_MIN_PIN); + #endif + #endif + + #if HAS_Z2_MAX + #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z2_MAX_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Z2_MAX_PIN); + #endif + #endif + + #if HAS_Z2_MIN + #if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z2_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z2_MIN_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Z2_MIN_PIN); + #endif + #endif + + #if HAS_Z_MIN_PROBE_PIN + #if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Z_MIN_PROBE_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Z_MIN_PROBE_PIN) != NULL, "ENDSTOP_INTERRUPT_ERROR"); + pciSetup(Z_MIN_PROBE_PIN); + #endif + #endif + + // When we arive here without error each pin has ether a EXT-interrupt or a PCI. + } + + +#endif //_ENDSTOP_INTERRUPTS_H_ diff --git a/Marlin/example_configurations/Cartesio/Configuration.h b/Marlin/example_configurations/Cartesio/Configuration.h index 634afc7dd..b25931b58 100644 --- a/Marlin/example_configurations/Cartesio/Configuration.h +++ b/Marlin/example_configurations/Cartesio/Configuration.h @@ -445,6 +445,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h index f59173cba..f11ec8a80 100644 --- a/Marlin/example_configurations/Felix/Configuration.h +++ b/Marlin/example_configurations/Felix/Configuration.h @@ -427,6 +427,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/Felix/DUAL/Configuration.h b/Marlin/example_configurations/Felix/DUAL/Configuration.h index af0af9427..5f65aa52f 100644 --- a/Marlin/example_configurations/Felix/DUAL/Configuration.h +++ b/Marlin/example_configurations/Felix/DUAL/Configuration.h @@ -427,6 +427,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h index 2d5f51997..d2cce0106 100644 --- a/Marlin/example_configurations/Hephestos/Configuration.h +++ b/Marlin/example_configurations/Hephestos/Configuration.h @@ -437,6 +437,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/Hephestos_2/Configuration.h b/Marlin/example_configurations/Hephestos_2/Configuration.h index 162a2628b..7a352d802 100644 --- a/Marlin/example_configurations/Hephestos_2/Configuration.h +++ b/Marlin/example_configurations/Hephestos_2/Configuration.h @@ -439,6 +439,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h index 9f8b54d07..fb2adee3e 100644 --- a/Marlin/example_configurations/K8200/Configuration.h +++ b/Marlin/example_configurations/K8200/Configuration.h @@ -462,6 +462,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/K8400/Configuration.h b/Marlin/example_configurations/K8400/Configuration.h index 8b52c085c..4ea9328f0 100644 --- a/Marlin/example_configurations/K8400/Configuration.h +++ b/Marlin/example_configurations/K8400/Configuration.h @@ -445,6 +445,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/K8400/Dual-head/Configuration.h b/Marlin/example_configurations/K8400/Dual-head/Configuration.h index 79fcf4726..b290503f5 100644 --- a/Marlin/example_configurations/K8400/Dual-head/Configuration.h +++ b/Marlin/example_configurations/K8400/Dual-head/Configuration.h @@ -445,6 +445,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h index 14de17911..c8f4ac97a 100644 --- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h +++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h @@ -445,6 +445,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h index fb329ca09..f6c0dc1ee 100644 --- a/Marlin/example_configurations/RigidBot/Configuration.h +++ b/Marlin/example_configurations/RigidBot/Configuration.h @@ -442,6 +442,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h index ec244874f..c2c0e6a8b 100644 --- a/Marlin/example_configurations/SCARA/Configuration.h +++ b/Marlin/example_configurations/SCARA/Configuration.h @@ -460,6 +460,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/TAZ4/Configuration.h b/Marlin/example_configurations/TAZ4/Configuration.h index 92a9c033d..d7f6aefc7 100644 --- a/Marlin/example_configurations/TAZ4/Configuration.h +++ b/Marlin/example_configurations/TAZ4/Configuration.h @@ -466,6 +466,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h index 60d79d52f..0d933e805 100644 --- a/Marlin/example_configurations/WITBOX/Configuration.h +++ b/Marlin/example_configurations/WITBOX/Configuration.h @@ -437,6 +437,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h index fdd8d79ea..3e9da7b79 100644 --- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h +++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h @@ -445,6 +445,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/delta/biv2.5/Configuration.h b/Marlin/example_configurations/delta/biv2.5/Configuration.h index f6a1b8cdd..e939c4b72 100644 --- a/Marlin/example_configurations/delta/biv2.5/Configuration.h +++ b/Marlin/example_configurations/delta/biv2.5/Configuration.h @@ -489,6 +489,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h index 6dd1b8191..107ccb65d 100644 --- a/Marlin/example_configurations/delta/generic/Configuration.h +++ b/Marlin/example_configurations/delta/generic/Configuration.h @@ -489,6 +489,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h index 057320b31..cf2d63b7a 100644 --- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h @@ -489,6 +489,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h index 2cd160adc..233ce8b1b 100644 --- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h @@ -478,6 +478,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h index 679fa5564..c6ca06f4e 100644 --- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h @@ -487,6 +487,9 @@ #define Z_MAX_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h index 802c9bbbc..5f5ad1d8a 100644 --- a/Marlin/example_configurations/makibox/Configuration.h +++ b/Marlin/example_configurations/makibox/Configuration.h @@ -448,6 +448,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING false // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h index 75bbded7f..03bb14b5b 100644 --- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h +++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h @@ -435,6 +435,9 @@ #define Z_MAX_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. #define Z_MIN_PROBE_ENDSTOP_INVERTING true // set to true to invert the logic of the endstop. +// If all used endstop pins are able to cause interrupts, you can enable ENDSTOP_INTERRUPTS_FEATURE. +// Then the function testing the endstops will only be called, if the state of one of the endstops changed. +//#define ENDSTOP_INTERRUPTS_FEATURE //============================================================================= //============================== Movement Settings ============================ diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp index dd35990a5..9f712faad 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -310,6 +310,10 @@ void Stepper::set_directions() { #endif // !ADVANCE && !LIN_ADVANCE } +#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + extern volatile uint8_t e_hit; +#endif + /** * Stepper Driver Interrupt * @@ -378,7 +382,15 @@ void Stepper::isr() { #if HAS_BED_PROBE || endstops.z_probe_enabled #endif - ) endstops.update(); + ) + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + if(e_hit) { + #endif + endstops.update(); + #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) + e_hit--; + } + #endif // Take multiple steps per interrupt (For high speed moves) bool all_steps_done = false; diff --git a/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino b/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino new file mode 100644 index 000000000..8650a3d13 --- /dev/null +++ b/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino @@ -0,0 +1,32 @@ +// Search pins uasable for endstop-interupts +// Compile with the same settings you'd use with Marlin. + +#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA) + #undef digitalPinToPCICR + #define digitalPinToPCICR(p) ( (((p) >= 10) && ((p) <= 15)) || \ + (((p) >= 50) && ((p) <= 53)) || \ + (((p) >= 62) && ((p) <= 69)) ? (&PCICR) : ((uint8_t *)0) ) +#endif + +void setup() { + Serial.begin(9600); + Serial.println("PINs causing interrups are:"); + for(int i=2; i