Filter endstops state at all times (#11066)
This commit is contained in:
		| @@ -43,7 +43,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h) |  * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h) | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  Endstop interrupts for Due based targets. |  *  Endstop interrupts for Due based targets. | ||||||
|   | |||||||
| @@ -40,9 +40,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void ICACHE_RAM_ATTR endstop_ISR(void) { | void ICACHE_RAM_ATTR endstop_ISR(void) { endstops.update(); } | ||||||
|   endstops.check_possible_change(); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void setup_endstop_interrupts(void) { | void setup_endstop_interrupts(void) { | ||||||
|   #if HAS_X_MAX |   #if HAS_X_MAX | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| void setup_endstop_interrupts(void) { | void setup_endstop_interrupts(void) { | ||||||
|   #if HAS_X_MAX |   #if HAS_X_MAX | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| void setup_endstop_interrupts(void) { | void setup_endstop_interrupts(void) { | ||||||
|   #if HAS_X_MAX |   #if HAS_X_MAX | ||||||
|   | |||||||
| @@ -27,7 +27,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| void setup_endstop_interrupts(void) { | void setup_endstop_interrupts(void) { | ||||||
|   #if HAS_X_MAX |   #if HAS_X_MAX | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| void setup_endstop_interrupts(void) { | void setup_endstop_interrupts(void) { | ||||||
|   #if HAS_X_MAX |   #if HAS_X_MAX | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ | |||||||
| #include "../../module/endstops.h" | #include "../../module/endstops.h" | ||||||
|  |  | ||||||
| // One ISR for all EXT-Interrupts | // One ISR for all EXT-Interrupts | ||||||
| void endstop_ISR(void) { endstops.check_possible_change(); } | void endstop_ISR(void) { endstops.update(); } | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  *  Endstop interrupts for Due based targets. |  *  Endstop interrupts for Due based targets. | ||||||
|   | |||||||
| @@ -36,12 +36,6 @@ | |||||||
|   #include HAL_PATH(../HAL, endstop_interrupts.h) |   #include HAL_PATH(../HAL, endstop_interrupts.h) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if HAS_BED_PROBE |  | ||||||
|   #define ENDSTOPS_ENABLED  (enabled || z_probe_enabled) |  | ||||||
| #else |  | ||||||
|   #define ENDSTOPS_ENABLED  enabled |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| Endstops endstops; | Endstops endstops; | ||||||
|  |  | ||||||
| // public: | // public: | ||||||
| @@ -50,9 +44,9 @@ bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.l | |||||||
| volatile uint8_t Endstops::hit_state; | volatile uint8_t Endstops::hit_state; | ||||||
|  |  | ||||||
| Endstops::esbits_t Endstops::live_state = 0; | Endstops::esbits_t Endstops::live_state = 0; | ||||||
|  |  | ||||||
| #if ENABLED(ENDSTOP_NOISE_FILTER) | #if ENABLED(ENDSTOP_NOISE_FILTER) | ||||||
|   Endstops::esbits_t Endstops::old_live_state, |   Endstops::esbits_t Endstops::validated_live_state; | ||||||
|                      Endstops::validated_live_state; |  | ||||||
|   uint8_t Endstops::endstop_poll_count; |   uint8_t Endstops::endstop_poll_count; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -222,9 +216,6 @@ void Endstops::init() { | |||||||
|  |  | ||||||
| } // Endstops::init | } // Endstops::init | ||||||
|  |  | ||||||
| // Called from ISR. A change was detected. Find out what happened! |  | ||||||
| void Endstops::check_possible_change() { if (ENDSTOPS_ENABLED) update(); } |  | ||||||
|  |  | ||||||
| // Called from ISR: Poll endstop state if required | // Called from ISR: Poll endstop state if required | ||||||
| void Endstops::poll() { | void Endstops::poll() { | ||||||
|  |  | ||||||
| @@ -232,8 +223,10 @@ void Endstops::poll() { | |||||||
|     run_monitor();  // report changes in endstop status |     run_monitor();  // report changes in endstop status | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   #if DISABLED(ENDSTOP_INTERRUPTS_FEATURE) || ENABLED(ENDSTOP_NOISE_FILTER) |   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && ENABLED(ENDSTOP_NOISE_FILTER) | ||||||
|     if (ENDSTOPS_ENABLED) update(); |     if (endstop_poll_count) update(); | ||||||
|  |   #elif DISABLED(ENDSTOP_INTERRUPTS_FEATURE) || ENABLED(ENDSTOP_NOISE_FILTER) | ||||||
|  |     update(); | ||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -241,7 +234,7 @@ void Endstops::enable_globally(const bool onoff) { | |||||||
|   enabled_globally = enabled = onoff; |   enabled_globally = enabled = onoff; | ||||||
|  |  | ||||||
|   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) |   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) | ||||||
|     if (onoff) update(); // If enabling, update state now |     update(); | ||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -250,7 +243,7 @@ void Endstops::enable(const bool onoff) { | |||||||
|   enabled = onoff; |   enabled = onoff; | ||||||
|  |  | ||||||
|   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) |   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) | ||||||
|     if (onoff) update(); // If enabling, update state now |     update(); | ||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -259,7 +252,7 @@ void Endstops::not_homing() { | |||||||
|   enabled = enabled_globally; |   enabled = enabled_globally; | ||||||
|  |  | ||||||
|   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) |   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) | ||||||
|     if (enabled) update(); // If enabling, update state now |     update(); | ||||||
|   #endif |   #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -269,7 +262,7 @@ void Endstops::not_homing() { | |||||||
|     z_probe_enabled = onoff; |     z_probe_enabled = onoff; | ||||||
|  |  | ||||||
|     #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) |     #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) | ||||||
|       if (enabled) update(); // If enabling, update state now |       update(); | ||||||
|     #endif |     #endif | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| @@ -396,10 +389,12 @@ void Endstops::M119() { | |||||||
| // Check endstops - Could be called from ISR! | // Check endstops - Could be called from ISR! | ||||||
| void Endstops::update() { | void Endstops::update() { | ||||||
|  |  | ||||||
|   // UPDATE_ENDSTOP_BIT: set the current endstop bits for an endstop to its status |   #if DISABLED(ENDSTOP_NOISE_FILTER) | ||||||
|  |     if (!abort_enabled()) return; | ||||||
|  |   #endif | ||||||
|  |  | ||||||
|   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) |   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX))) | ||||||
|   // COPY_BIT: copy the value of SRC_BIT to DST_BIT in DST |   #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT)) | ||||||
|   #define COPY_BIT(DST, SRC_BIT, DST_BIT) SET_BIT_TO(DST, DST_BIT, TEST(DST, SRC_BIT)) |  | ||||||
|  |  | ||||||
|   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) |   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ) | ||||||
|     // If G38 command is active check Z_MIN_PROBE for ALL movement |     // If G38 command is active check Z_MIN_PROBE for ALL movement | ||||||
| @@ -444,7 +439,7 @@ void Endstops::update() { | |||||||
|           #if HAS_X2_MIN |           #if HAS_X2_MIN | ||||||
|             UPDATE_ENDSTOP_BIT(X2, MIN); |             UPDATE_ENDSTOP_BIT(X2, MIN); | ||||||
|           #else |           #else | ||||||
|             COPY_BIT(live_state, X_MIN, X2_MIN); |             COPY_LIVE_STATE(X_MIN, X2_MIN); | ||||||
|           #endif |           #endif | ||||||
|         #else |         #else | ||||||
|           if (X_MIN_TEST) UPDATE_ENDSTOP_BIT(X, MIN); |           if (X_MIN_TEST) UPDATE_ENDSTOP_BIT(X, MIN); | ||||||
| @@ -458,7 +453,7 @@ void Endstops::update() { | |||||||
|           #if HAS_X2_MAX |           #if HAS_X2_MAX | ||||||
|             UPDATE_ENDSTOP_BIT(X2, MAX); |             UPDATE_ENDSTOP_BIT(X2, MAX); | ||||||
|           #else |           #else | ||||||
|             COPY_BIT(live_state, X_MAX, X2_MAX); |             COPY_LIVE_STATE(X_MAX, X2_MAX); | ||||||
|           #endif |           #endif | ||||||
|         #else |         #else | ||||||
|           if (X_MAX_TEST) UPDATE_ENDSTOP_BIT(X, MAX); |           if (X_MAX_TEST) UPDATE_ENDSTOP_BIT(X, MAX); | ||||||
| @@ -475,7 +470,7 @@ void Endstops::update() { | |||||||
|           #if HAS_Y2_MIN |           #if HAS_Y2_MIN | ||||||
|             UPDATE_ENDSTOP_BIT(Y2, MIN); |             UPDATE_ENDSTOP_BIT(Y2, MIN); | ||||||
|           #else |           #else | ||||||
|             COPY_BIT(live_state, Y_MIN, Y2_MIN); |             COPY_LIVE_STATE(Y_MIN, Y2_MIN); | ||||||
|           #endif |           #endif | ||||||
|         #else |         #else | ||||||
|           UPDATE_ENDSTOP_BIT(Y, MIN); |           UPDATE_ENDSTOP_BIT(Y, MIN); | ||||||
| @@ -489,7 +484,7 @@ void Endstops::update() { | |||||||
|           #if HAS_Y2_MAX |           #if HAS_Y2_MAX | ||||||
|             UPDATE_ENDSTOP_BIT(Y2, MAX); |             UPDATE_ENDSTOP_BIT(Y2, MAX); | ||||||
|           #else |           #else | ||||||
|             COPY_BIT(live_state, Y_MAX, Y2_MAX); |             COPY_LIVE_STATE(Y_MAX, Y2_MAX); | ||||||
|           #endif |           #endif | ||||||
|         #else |         #else | ||||||
|           UPDATE_ENDSTOP_BIT(Y, MAX); |           UPDATE_ENDSTOP_BIT(Y, MAX); | ||||||
| @@ -506,7 +501,7 @@ void Endstops::update() { | |||||||
|           #if HAS_Z2_MIN |           #if HAS_Z2_MIN | ||||||
|             UPDATE_ENDSTOP_BIT(Z2, MIN); |             UPDATE_ENDSTOP_BIT(Z2, MIN); | ||||||
|           #else |           #else | ||||||
|             COPY_BIT(live_state, Z_MIN, Z2_MIN); |             COPY_LIVE_STATE(Z_MIN, Z2_MIN); | ||||||
|           #endif |           #endif | ||||||
|         #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) |         #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) | ||||||
|           if (z_probe_enabled) UPDATE_ENDSTOP_BIT(Z, MIN); |           if (z_probe_enabled) UPDATE_ENDSTOP_BIT(Z, MIN); | ||||||
| @@ -528,7 +523,7 @@ void Endstops::update() { | |||||||
|           #if HAS_Z2_MAX |           #if HAS_Z2_MAX | ||||||
|             UPDATE_ENDSTOP_BIT(Z2, MAX); |             UPDATE_ENDSTOP_BIT(Z2, MAX); | ||||||
|           #else |           #else | ||||||
|             COPY_BIT(live_state, Z_MAX, Z2_MAX); |             COPY_LIVE_STATE(Z_MAX, Z2_MAX); | ||||||
|           #endif |           #endif | ||||||
|         #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN |         #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN | ||||||
|           // If this pin isn't the bed probe it's the Z endstop |           // If this pin isn't the bed probe it's the Z endstop | ||||||
| @@ -538,9 +533,7 @@ void Endstops::update() { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // All endstops were updated. |  | ||||||
|   #if ENABLED(ENDSTOP_NOISE_FILTER) |   #if ENABLED(ENDSTOP_NOISE_FILTER) | ||||||
|     if (old_live_state != live_state) { // We detected a change. Reinit the timeout |  | ||||||
|     /** |     /** | ||||||
|      * Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise, |      * Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise, | ||||||
|      * that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution |      * that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution | ||||||
| @@ -551,23 +544,20 @@ void Endstops::update() { | |||||||
|      * still exist. The only way to reduce them further is to increase the number of samples. |      * still exist. The only way to reduce them further is to increase the number of samples. | ||||||
|      * To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay). |      * To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay). | ||||||
|      */ |      */ | ||||||
|  |     static esbits_t old_live_state; | ||||||
|  |     if (old_live_state != live_state) { | ||||||
|       endstop_poll_count = 7; |       endstop_poll_count = 7; | ||||||
|       old_live_state = live_state; |       old_live_state = live_state; | ||||||
|     } |     } | ||||||
|     else if (endstop_poll_count && !--endstop_poll_count) |     else if (endstop_poll_count && !--endstop_poll_count) | ||||||
|       validated_live_state = live_state; |       validated_live_state = live_state; | ||||||
|  |  | ||||||
|   #else |     if (!abort_enabled()) return; | ||||||
|  |  | ||||||
|     // Lets accept the new endstop values as valid - We assume hardware filtering of lines |  | ||||||
|     esbits_t validated_live_state = live_state; |  | ||||||
|  |  | ||||||
|   #endif |   #endif | ||||||
|  |  | ||||||
|   // Endstop readings are validated in validated_live_state |  | ||||||
|  |  | ||||||
|   // Test the current status of an endstop |   // Test the current status of an endstop | ||||||
|   #define TEST_ENDSTOP(ENDSTOP) (TEST(validated_live_state, ENDSTOP)) |   #define TEST_ENDSTOP(ENDSTOP) (TEST(state(), ENDSTOP)) | ||||||
|  |  | ||||||
|   // Record endstop was hit |   // Record endstop was hit | ||||||
|   #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX)) |   #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX)) | ||||||
|   | |||||||
| @@ -70,9 +70,10 @@ class Endstops { | |||||||
|   private: |   private: | ||||||
|     static esbits_t live_state; |     static esbits_t live_state; | ||||||
|     static volatile uint8_t hit_state;      // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index |     static volatile uint8_t hit_state;      // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index | ||||||
|  |  | ||||||
|     #if ENABLED(ENDSTOP_NOISE_FILTER) |     #if ENABLED(ENDSTOP_NOISE_FILTER) | ||||||
|       static esbits_t old_live_state,       // Old endstop value for debouncing and denoising |       static esbits_t validated_live_state; | ||||||
|                       validated_live_state; // The validated (accepted as true) endstop bits |       uint8_t Endstops::endstop_poll_count; | ||||||
|       static uint8_t endstop_poll_count;    // Countdown from threshold for polling |       static uint8_t endstop_poll_count;    // Countdown from threshold for polling | ||||||
|     #endif |     #endif | ||||||
|  |  | ||||||
| @@ -85,10 +86,15 @@ class Endstops { | |||||||
|     static void init(); |     static void init(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * A change was detected or presumed to be in endstops pins. Find out what |      * Are endstops or the probe set to abort the move? | ||||||
|      * changed, if anything. Called from ISR contexts |  | ||||||
|      */ |      */ | ||||||
|     static void check_possible_change(); |     FORCE_INLINE static bool abort_enabled() { | ||||||
|  |       return (enabled | ||||||
|  |         #if HAS_BED_PROBE | ||||||
|  |           || z_probe_enabled | ||||||
|  |         #endif | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Periodic call to poll endstops if required. Called from temperature ISR |      * Periodic call to poll endstops if required. Called from temperature ISR | ||||||
| @@ -96,7 +102,9 @@ class Endstops { | |||||||
|     static void poll(); |     static void poll(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Update the endstops bits from the pins |      * Update endstops bits from the pins. Apply filtering to get a verified state. | ||||||
|  |      * If abort_enabled() and moving towards a triggered switch, abort the current move. | ||||||
|  |      * Called from ISR contexts. | ||||||
|      */ |      */ | ||||||
|     static void update(); |     static void update(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1742,7 +1742,7 @@ uint32_t Stepper::stepper_block_phase_isr() { | |||||||
|       // done against the endstop. So, check the limits here: If the movement |       // done against the endstop. So, check the limits here: If the movement | ||||||
|       // is against the limits, the block will be marked as to be killed, and |       // is against the limits, the block will be marked as to be killed, and | ||||||
|       // on the next call to this ISR, will be discarded. |       // on the next call to this ISR, will be discarded. | ||||||
|       endstops.check_possible_change(); |       endstops.update(); | ||||||
|  |  | ||||||
|       #if ENABLED(Z_LATE_ENABLE) |       #if ENABLED(Z_LATE_ENABLE) | ||||||
|         // If delayed Z enable, enable it now. This option will severely interfere with |         // If delayed Z enable, enable it now. This option will severely interfere with | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user