Browse Source

Filter endstops state at all times (#11066)

Scott Lahteine 6 years ago
parent
commit
99591dc20c
No account linked to committer's email address

+ 1
- 1
Marlin/src/HAL/HAL_AVR/endstop_interrupts.h View File

43
 #include "../../module/endstops.h"
43
 #include "../../module/endstops.h"
44
 
44
 
45
 // One ISR for all EXT-Interrupts
45
 // One ISR for all EXT-Interrupts
46
-void endstop_ISR(void) { endstops.check_possible_change(); }
46
+void endstop_ISR(void) { endstops.update(); }
47
 
47
 
48
 /**
48
 /**
49
  * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)
49
  * Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)

+ 1
- 1
Marlin/src/HAL/HAL_DUE/endstop_interrupts.h View File

40
 #include "../../module/endstops.h"
40
 #include "../../module/endstops.h"
41
 
41
 
42
 // One ISR for all EXT-Interrupts
42
 // One ISR for all EXT-Interrupts
43
-void endstop_ISR(void) { endstops.check_possible_change(); }
43
+void endstop_ISR(void) { endstops.update(); }
44
 
44
 
45
 /**
45
 /**
46
  *  Endstop interrupts for Due based targets.
46
  *  Endstop interrupts for Due based targets.

+ 1
- 3
Marlin/src/HAL/HAL_ESP32/endstop_interrupts.h View File

40
 #include "../../module/endstops.h"
40
 #include "../../module/endstops.h"
41
 
41
 
42
 // One ISR for all EXT-Interrupts
42
 // One ISR for all EXT-Interrupts
43
-void ICACHE_RAM_ATTR endstop_ISR(void) {
44
-  endstops.check_possible_change();
45
-}
43
+void ICACHE_RAM_ATTR endstop_ISR(void) { endstops.update(); }
46
 
44
 
47
 void setup_endstop_interrupts(void) {
45
 void setup_endstop_interrupts(void) {
48
   #if HAS_X_MAX
46
   #if HAS_X_MAX

+ 1
- 1
Marlin/src/HAL/HAL_LPC1768/endstop_interrupts.h View File

43
 #include "../../module/endstops.h"
43
 #include "../../module/endstops.h"
44
 
44
 
45
 // One ISR for all EXT-Interrupts
45
 // One ISR for all EXT-Interrupts
46
-void endstop_ISR(void) { endstops.check_possible_change(); }
46
+void endstop_ISR(void) { endstops.update(); }
47
 
47
 
48
 void setup_endstop_interrupts(void) {
48
 void setup_endstop_interrupts(void) {
49
   #if HAS_X_MAX
49
   #if HAS_X_MAX

+ 1
- 1
Marlin/src/HAL/HAL_STM32F1/endstop_interrupts.h View File

52
 #include "../../module/endstops.h"
52
 #include "../../module/endstops.h"
53
 
53
 
54
 // One ISR for all EXT-Interrupts
54
 // One ISR for all EXT-Interrupts
55
-void endstop_ISR(void) { endstops.check_possible_change(); }
55
+void endstop_ISR(void) { endstops.update(); }
56
 
56
 
57
 void setup_endstop_interrupts(void) {
57
 void setup_endstop_interrupts(void) {
58
   #if HAS_X_MAX
58
   #if HAS_X_MAX

+ 1
- 1
Marlin/src/HAL/HAL_STM32F4/endstop_interrupts.h View File

27
 #include "../../module/endstops.h"
27
 #include "../../module/endstops.h"
28
 
28
 
29
 // One ISR for all EXT-Interrupts
29
 // One ISR for all EXT-Interrupts
30
-void endstop_ISR(void) { endstops.check_possible_change(); }
30
+void endstop_ISR(void) { endstops.update(); }
31
 
31
 
32
 void setup_endstop_interrupts(void) {
32
 void setup_endstop_interrupts(void) {
33
   #if HAS_X_MAX
33
   #if HAS_X_MAX

+ 1
- 1
Marlin/src/HAL/HAL_STM32F7/endstop_interrupts.h View File

29
 #include "../../module/endstops.h"
29
 #include "../../module/endstops.h"
30
 
30
 
31
 // One ISR for all EXT-Interrupts
31
 // One ISR for all EXT-Interrupts
32
-void endstop_ISR(void) { endstops.check_possible_change(); }
32
+void endstop_ISR(void) { endstops.update(); }
33
 
33
 
34
 void setup_endstop_interrupts(void) {
34
 void setup_endstop_interrupts(void) {
35
   #if HAS_X_MAX
35
   #if HAS_X_MAX

+ 1
- 1
Marlin/src/HAL/HAL_TEENSY35_36/endstop_interrupts.h View File

40
 #include "../../module/endstops.h"
40
 #include "../../module/endstops.h"
41
 
41
 
42
 // One ISR for all EXT-Interrupts
42
 // One ISR for all EXT-Interrupts
43
-void endstop_ISR(void) { endstops.check_possible_change(); }
43
+void endstop_ISR(void) { endstops.update(); }
44
 
44
 
45
 /**
45
 /**
46
  *  Endstop interrupts for Due based targets.
46
  *  Endstop interrupts for Due based targets.

+ 35
- 45
Marlin/src/module/endstops.cpp View File

36
   #include HAL_PATH(../HAL, endstop_interrupts.h)
36
   #include HAL_PATH(../HAL, endstop_interrupts.h)
37
 #endif
37
 #endif
38
 
38
 
39
-#if HAS_BED_PROBE
40
-  #define ENDSTOPS_ENABLED  (enabled || z_probe_enabled)
41
-#else
42
-  #define ENDSTOPS_ENABLED  enabled
43
-#endif
44
-
45
 Endstops endstops;
39
 Endstops endstops;
46
 
40
 
47
 // public:
41
 // public:
50
 volatile uint8_t Endstops::hit_state;
44
 volatile uint8_t Endstops::hit_state;
51
 
45
 
52
 Endstops::esbits_t Endstops::live_state = 0;
46
 Endstops::esbits_t Endstops::live_state = 0;
47
+
53
 #if ENABLED(ENDSTOP_NOISE_FILTER)
48
 #if ENABLED(ENDSTOP_NOISE_FILTER)
54
-  Endstops::esbits_t Endstops::old_live_state,
55
-                     Endstops::validated_live_state;
49
+  Endstops::esbits_t Endstops::validated_live_state;
56
   uint8_t Endstops::endstop_poll_count;
50
   uint8_t Endstops::endstop_poll_count;
57
 #endif
51
 #endif
58
 
52
 
222
 
216
 
223
 } // Endstops::init
217
 } // Endstops::init
224
 
218
 
225
-// Called from ISR. A change was detected. Find out what happened!
226
-void Endstops::check_possible_change() { if (ENDSTOPS_ENABLED) update(); }
227
-
228
 // Called from ISR: Poll endstop state if required
219
 // Called from ISR: Poll endstop state if required
229
 void Endstops::poll() {
220
 void Endstops::poll() {
230
 
221
 
232
     run_monitor();  // report changes in endstop status
223
     run_monitor();  // report changes in endstop status
233
   #endif
224
   #endif
234
 
225
 
235
-  #if DISABLED(ENDSTOP_INTERRUPTS_FEATURE) || ENABLED(ENDSTOP_NOISE_FILTER)
236
-    if (ENDSTOPS_ENABLED) update();
226
+  #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && ENABLED(ENDSTOP_NOISE_FILTER)
227
+    if (endstop_poll_count) update();
228
+  #elif DISABLED(ENDSTOP_INTERRUPTS_FEATURE) || ENABLED(ENDSTOP_NOISE_FILTER)
229
+    update();
237
   #endif
230
   #endif
238
 }
231
 }
239
 
232
 
241
   enabled_globally = enabled = onoff;
234
   enabled_globally = enabled = onoff;
242
 
235
 
243
   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
236
   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
244
-    if (onoff) update(); // If enabling, update state now
237
+    update();
245
   #endif
238
   #endif
246
 }
239
 }
247
 
240
 
250
   enabled = onoff;
243
   enabled = onoff;
251
 
244
 
252
   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
245
   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
253
-    if (onoff) update(); // If enabling, update state now
246
+    update();
254
   #endif
247
   #endif
255
 }
248
 }
256
 
249
 
259
   enabled = enabled_globally;
252
   enabled = enabled_globally;
260
 
253
 
261
   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
254
   #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
262
-    if (enabled) update(); // If enabling, update state now
255
+    update();
263
   #endif
256
   #endif
264
 }
257
 }
265
 
258
 
269
     z_probe_enabled = onoff;
262
     z_probe_enabled = onoff;
270
 
263
 
271
     #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
264
     #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
272
-      if (enabled) update(); // If enabling, update state now
265
+      update();
273
     #endif
266
     #endif
274
   }
267
   }
275
 #endif
268
 #endif
396
 // Check endstops - Could be called from ISR!
389
 // Check endstops - Could be called from ISR!
397
 void Endstops::update() {
390
 void Endstops::update() {
398
 
391
 
399
-  // UPDATE_ENDSTOP_BIT: set the current endstop bits for an endstop to its status
392
+  #if DISABLED(ENDSTOP_NOISE_FILTER)
393
+    if (!abort_enabled()) return;
394
+  #endif
395
+
400
   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
396
   #define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
401
-  // COPY_BIT: copy the value of SRC_BIT to DST_BIT in DST
402
-  #define COPY_BIT(DST, SRC_BIT, DST_BIT) SET_BIT_TO(DST, DST_BIT, TEST(DST, SRC_BIT))
397
+  #define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT))
403
 
398
 
404
   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ)
399
   #if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ)
405
     // If G38 command is active check Z_MIN_PROBE for ALL movement
400
     // If G38 command is active check Z_MIN_PROBE for ALL movement
444
           #if HAS_X2_MIN
439
           #if HAS_X2_MIN
445
             UPDATE_ENDSTOP_BIT(X2, MIN);
440
             UPDATE_ENDSTOP_BIT(X2, MIN);
446
           #else
441
           #else
447
-            COPY_BIT(live_state, X_MIN, X2_MIN);
442
+            COPY_LIVE_STATE(X_MIN, X2_MIN);
448
           #endif
443
           #endif
449
         #else
444
         #else
450
           if (X_MIN_TEST) UPDATE_ENDSTOP_BIT(X, MIN);
445
           if (X_MIN_TEST) UPDATE_ENDSTOP_BIT(X, MIN);
458
           #if HAS_X2_MAX
453
           #if HAS_X2_MAX
459
             UPDATE_ENDSTOP_BIT(X2, MAX);
454
             UPDATE_ENDSTOP_BIT(X2, MAX);
460
           #else
455
           #else
461
-            COPY_BIT(live_state, X_MAX, X2_MAX);
456
+            COPY_LIVE_STATE(X_MAX, X2_MAX);
462
           #endif
457
           #endif
463
         #else
458
         #else
464
           if (X_MAX_TEST) UPDATE_ENDSTOP_BIT(X, MAX);
459
           if (X_MAX_TEST) UPDATE_ENDSTOP_BIT(X, MAX);
475
           #if HAS_Y2_MIN
470
           #if HAS_Y2_MIN
476
             UPDATE_ENDSTOP_BIT(Y2, MIN);
471
             UPDATE_ENDSTOP_BIT(Y2, MIN);
477
           #else
472
           #else
478
-            COPY_BIT(live_state, Y_MIN, Y2_MIN);
473
+            COPY_LIVE_STATE(Y_MIN, Y2_MIN);
479
           #endif
474
           #endif
480
         #else
475
         #else
481
           UPDATE_ENDSTOP_BIT(Y, MIN);
476
           UPDATE_ENDSTOP_BIT(Y, MIN);
489
           #if HAS_Y2_MAX
484
           #if HAS_Y2_MAX
490
             UPDATE_ENDSTOP_BIT(Y2, MAX);
485
             UPDATE_ENDSTOP_BIT(Y2, MAX);
491
           #else
486
           #else
492
-            COPY_BIT(live_state, Y_MAX, Y2_MAX);
487
+            COPY_LIVE_STATE(Y_MAX, Y2_MAX);
493
           #endif
488
           #endif
494
         #else
489
         #else
495
           UPDATE_ENDSTOP_BIT(Y, MAX);
490
           UPDATE_ENDSTOP_BIT(Y, MAX);
506
           #if HAS_Z2_MIN
501
           #if HAS_Z2_MIN
507
             UPDATE_ENDSTOP_BIT(Z2, MIN);
502
             UPDATE_ENDSTOP_BIT(Z2, MIN);
508
           #else
503
           #else
509
-            COPY_BIT(live_state, Z_MIN, Z2_MIN);
504
+            COPY_LIVE_STATE(Z_MIN, Z2_MIN);
510
           #endif
505
           #endif
511
         #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
506
         #elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
512
           if (z_probe_enabled) UPDATE_ENDSTOP_BIT(Z, MIN);
507
           if (z_probe_enabled) UPDATE_ENDSTOP_BIT(Z, MIN);
528
           #if HAS_Z2_MAX
523
           #if HAS_Z2_MAX
529
             UPDATE_ENDSTOP_BIT(Z2, MAX);
524
             UPDATE_ENDSTOP_BIT(Z2, MAX);
530
           #else
525
           #else
531
-            COPY_BIT(live_state, Z_MAX, Z2_MAX);
526
+            COPY_LIVE_STATE(Z_MAX, Z2_MAX);
532
           #endif
527
           #endif
533
         #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
528
         #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
534
           // If this pin isn't the bed probe it's the Z endstop
529
           // If this pin isn't the bed probe it's the Z endstop
538
     }
533
     }
539
   }
534
   }
540
 
535
 
541
-  // All endstops were updated.
542
   #if ENABLED(ENDSTOP_NOISE_FILTER)
536
   #if ENABLED(ENDSTOP_NOISE_FILTER)
543
-    if (old_live_state != live_state) { // We detected a change. Reinit the timeout
544
-      /**
545
-       * Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise,
546
-       * that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution
547
-       * of random noise). Then the first sample has a 50% chance to be good or bad. The 2nd sample
548
-       * also has a 50% chance to be good or bad. The chances of 2 samples both being bad becomes
549
-       * 50% of 50%, or 25%. That was the previous implementation of Marlin endstop handling. It
550
-       * reduces chances of bad readings in half, at the cost of 1 extra sample period, but chances
551
-       * still exist. The only way to reduce them further is to increase the number of samples.
552
-       * To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay).
553
-       */
537
+    /**
538
+     * Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise,
539
+     * that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution
540
+     * of random noise). Then the first sample has a 50% chance to be good or bad. The 2nd sample
541
+     * also has a 50% chance to be good or bad. The chances of 2 samples both being bad becomes
542
+     * 50% of 50%, or 25%. That was the previous implementation of Marlin endstop handling. It
543
+     * reduces chances of bad readings in half, at the cost of 1 extra sample period, but chances
544
+     * still exist. The only way to reduce them further is to increase the number of samples.
545
+     * To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay).
546
+     */
547
+    static esbits_t old_live_state;
548
+    if (old_live_state != live_state) {
554
       endstop_poll_count = 7;
549
       endstop_poll_count = 7;
555
       old_live_state = live_state;
550
       old_live_state = live_state;
556
     }
551
     }
557
     else if (endstop_poll_count && !--endstop_poll_count)
552
     else if (endstop_poll_count && !--endstop_poll_count)
558
       validated_live_state = live_state;
553
       validated_live_state = live_state;
559
 
554
 
560
-  #else
561
-
562
-    // Lets accept the new endstop values as valid - We assume hardware filtering of lines
563
-    esbits_t validated_live_state = live_state;
555
+    if (!abort_enabled()) return;
564
 
556
 
565
   #endif
557
   #endif
566
 
558
 
567
-  // Endstop readings are validated in validated_live_state
568
-
569
   // Test the current status of an endstop
559
   // Test the current status of an endstop
570
-  #define TEST_ENDSTOP(ENDSTOP) (TEST(validated_live_state, ENDSTOP))
560
+  #define TEST_ENDSTOP(ENDSTOP) (TEST(state(), ENDSTOP))
571
 
561
 
572
   // Record endstop was hit
562
   // Record endstop was hit
573
   #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX))
563
   #define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX))

+ 14
- 6
Marlin/src/module/endstops.h View File

70
   private:
70
   private:
71
     static esbits_t live_state;
71
     static esbits_t live_state;
72
     static volatile uint8_t hit_state;      // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index
72
     static volatile uint8_t hit_state;      // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index
73
+
73
     #if ENABLED(ENDSTOP_NOISE_FILTER)
74
     #if ENABLED(ENDSTOP_NOISE_FILTER)
74
-      static esbits_t old_live_state,       // Old endstop value for debouncing and denoising
75
-                      validated_live_state; // The validated (accepted as true) endstop bits
75
+      static esbits_t validated_live_state;
76
+      uint8_t Endstops::endstop_poll_count;
76
       static uint8_t endstop_poll_count;    // Countdown from threshold for polling
77
       static uint8_t endstop_poll_count;    // Countdown from threshold for polling
77
     #endif
78
     #endif
78
 
79
 
85
     static void init();
86
     static void init();
86
 
87
 
87
     /**
88
     /**
88
-     * A change was detected or presumed to be in endstops pins. Find out what
89
-     * changed, if anything. Called from ISR contexts
89
+     * Are endstops or the probe set to abort the move?
90
      */
90
      */
91
-    static void check_possible_change();
91
+    FORCE_INLINE static bool abort_enabled() {
92
+      return (enabled
93
+        #if HAS_BED_PROBE
94
+          || z_probe_enabled
95
+        #endif
96
+      );
97
+    }
92
 
98
 
93
     /**
99
     /**
94
      * Periodic call to poll endstops if required. Called from temperature ISR
100
      * Periodic call to poll endstops if required. Called from temperature ISR
96
     static void poll();
102
     static void poll();
97
 
103
 
98
     /**
104
     /**
99
-     * Update the endstops bits from the pins
105
+     * Update endstops bits from the pins. Apply filtering to get a verified state.
106
+     * If abort_enabled() and moving towards a triggered switch, abort the current move.
107
+     * Called from ISR contexts.
100
      */
108
      */
101
     static void update();
109
     static void update();
102
 
110
 

+ 1
- 1
Marlin/src/module/stepper.cpp View File

1742
       // done against the endstop. So, check the limits here: If the movement
1742
       // done against the endstop. So, check the limits here: If the movement
1743
       // is against the limits, the block will be marked as to be killed, and
1743
       // is against the limits, the block will be marked as to be killed, and
1744
       // on the next call to this ISR, will be discarded.
1744
       // on the next call to this ISR, will be discarded.
1745
-      endstops.check_possible_change();
1745
+      endstops.update();
1746
 
1746
 
1747
       #if ENABLED(Z_LATE_ENABLE)
1747
       #if ENABLED(Z_LATE_ENABLE)
1748
         // If delayed Z enable, enable it now. This option will severely interfere with
1748
         // If delayed Z enable, enable it now. This option will severely interfere with

Loading…
Cancel
Save