Parcourir la source

Implement support for Dual X and Y endstops

Scott Lahteine il y a 7 ans
Parent
révision
723f2a77f6

+ 2
- 2
.travis.yml Voir le fichier

@@ -177,7 +177,7 @@ script:
177 177
   #
178 178
   - restore_configs
179 179
   - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR SDSUPPORT
180
-  - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632
180
+  - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG
181 181
   - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS
182 182
   - opt_set_adv I2C_SLAVE_ADDRESS 63
183 183
   - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU
@@ -434,7 +434,7 @@ script:
434 434
   - restore_configs
435 435
   - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS
436 436
   - pins_set RAMPS X_MAX_PIN -1
437
-  - opt_set_adv Z2_MAX_PIN 2
437
+  - opt_add_adv Z2_MAX_PIN 2
438 438
   - build_marlin_pio ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}
439 439
 
440 440
   #############################

+ 40
- 0
Marlin/src/HAL/HAL_AVR/endstop_interrupts.h Voir le fichier

@@ -161,6 +161,46 @@ void setup_endstop_interrupts( void ) {
161 161
     #endif
162 162
   #endif
163 163
 
164
+  #if HAS_X2_MAX
165
+    #if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
166
+      attachInterrupt(digitalPinToInterrupt(X2_MAX_PIN), endstop_ISR, CHANGE);
167
+    #else
168
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
169
+      static_assert(digitalPinToPCICR(X2_MAX_PIN) != NULL, "X2_MAX_PIN is not interrupt-capable");
170
+      pciSetup(X2_MAX_PIN);
171
+    #endif
172
+  #endif
173
+
174
+  #if HAS_X2_MIN
175
+    #if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
176
+      attachInterrupt(digitalPinToInterrupt(X2_MIN_PIN), endstop_ISR, CHANGE);
177
+    #else
178
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
179
+      static_assert(digitalPinToPCICR(X2_MIN_PIN) != NULL, "X2_MIN_PIN is not interrupt-capable");
180
+      pciSetup(X2_MIN_PIN);
181
+    #endif
182
+  #endif
183
+
184
+  #if HAS_Y2_MAX
185
+    #if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
186
+      attachInterrupt(digitalPinToInterrupt(Y2_MAX_PIN), endstop_ISR, CHANGE);
187
+    #else
188
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
189
+      static_assert(digitalPinToPCICR(Y2_MAX_PIN) != NULL, "Y2_MAX_PIN is not interrupt-capable");
190
+      pciSetup(Y2_MAX_PIN);
191
+    #endif
192
+  #endif
193
+
194
+  #if HAS_Y2_MIN
195
+    #if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
196
+      attachInterrupt(digitalPinToInterrupt(Y2_MIN_PIN), endstop_ISR, CHANGE);
197
+    #else
198
+      // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
199
+      static_assert(digitalPinToPCICR(Y2_MIN_PIN) != NULL, "Y2_MIN_PIN is not interrupt-capable");
200
+      pciSetup(Y2_MIN_PIN);
201
+    #endif
202
+  #endif
203
+
164 204
   #if HAS_Z2_MAX
165 205
     #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
166 206
       attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE);

+ 4
- 0
Marlin/src/core/language.h Voir le fichier

@@ -150,8 +150,12 @@
150 150
 #define MSG_ACTIVE_EXTRUDER                 "Active Extruder: "
151 151
 #define MSG_X_MIN                           "x_min: "
152 152
 #define MSG_X_MAX                           "x_max: "
153
+#define MSG_X2_MIN                          "x2_min: "
154
+#define MSG_X2_MAX                          "x2_max: "
153 155
 #define MSG_Y_MIN                           "y_min: "
154 156
 #define MSG_Y_MAX                           "y_max: "
157
+#define MSG_Y2_MIN                          "y2_min: "
158
+#define MSG_Y2_MAX                          "y2_max: "
155 159
 #define MSG_Z_MIN                           "z_min: "
156 160
 #define MSG_Z_MAX                           "z_max: "
157 161
 #define MSG_Z2_MIN                          "z2_min: "

+ 7
- 0
Marlin/src/core/macros.h Voir le fichier

@@ -28,6 +28,13 @@
28 28
 #define ABC  3
29 29
 #define XYZ  3
30 30
 
31
+#define _XMIN_ 100
32
+#define _YMIN_ 200
33
+#define _ZMIN_ 300
34
+#define _XMAX_ 101
35
+#define _YMAX_ 201
36
+#define _ZMAX_ 301
37
+
31 38
 #define FORCE_INLINE __attribute__((always_inline)) inline
32 39
 #define _UNUSED      __attribute__((unused))
33 40
 #define _O0          __attribute__((optimize("O0")))

+ 15
- 3
Marlin/src/gcode/calibrate/M666.cpp Voir le fichier

@@ -64,11 +64,23 @@
64 64
   #include "../../module/endstops.h"
65 65
 
66 66
   /**
67
-   * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis.
67
+   * M666: For a Dual Endstop setup, set offsets for any 2nd endstops.
68 68
    */
69 69
   void GcodeSuite::M666() {
70
-    if (parser.seen('Z')) endstops.z_endstop_adj = parser.value_linear_units();
71
-    SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", endstops.z_endstop_adj);
70
+    SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): ");
71
+    #if ENABLED(X_DUAL_ENDSTOPS)
72
+      if (parser.seen('X')) endstops.x_endstop_adj = parser.value_linear_units();
73
+      SERIAL_ECHOPAIR(" X", endstops.x_endstop_adj);
74
+    #endif
75
+    #if ENABLED(Y_DUAL_ENDSTOPS)
76
+      if (parser.seen('Y')) endstops.y_endstop_adj = parser.value_linear_units();
77
+      SERIAL_ECHOPAIR(" Y", endstops.y_endstop_adj);
78
+    #endif
79
+    #if ENABLED(Z_DUAL_ENDSTOPS)
80
+      if (parser.seen('Z')) endstops.z_endstop_adj = parser.value_linear_units();
81
+      SERIAL_ECHOPAIR(" Z", endstops.z_endstop_adj);
82
+    #endif
83
+    SERIAL_EOL();
72 84
   }
73 85
 
74 86
 #endif

+ 124
- 25
Marlin/src/inc/Conditionals_post.h Voir le fichier

@@ -423,28 +423,121 @@
423 423
 #define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1)
424 424
 
425 425
 /**
426
+ * X_DUAL_ENDSTOPS endstop reassignment
427
+ */
428
+#if ENABLED(X_DUAL_ENDSTOPS)
429
+  #if X_HOME_DIR > 0
430
+    #if X2_USE_ENDSTOP == _XMIN_
431
+      #define X2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
432
+      #define X2_MAX_PIN X_MIN_PIN
433
+    #elif X2_USE_ENDSTOP == _XMAX_
434
+      #define X2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
435
+      #define X2_MAX_PIN X_MAX_PIN
436
+    #elif X2_USE_ENDSTOP == _YMIN_
437
+      #define X2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
438
+      #define X2_MAX_PIN Y_MIN_PIN
439
+    #elif X2_USE_ENDSTOP == _YMAX_
440
+      #define X2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
441
+      #define X2_MAX_PIN Y_MAX_PIN
442
+    #elif X2_USE_ENDSTOP == _ZMIN_
443
+      #define X2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
444
+      #define X2_MAX_PIN Z_MIN_PIN
445
+    #elif X2_USE_ENDSTOP == _ZMAX_
446
+      #define X2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
447
+      #define X2_MAX_PIN Z_MAX_PIN
448
+    #else
449
+      #define X2_MAX_ENDSTOP_INVERTING false
450
+    #endif
451
+    #define X2_MIN_ENDSTOP_INVERTING false
452
+  #else
453
+    #if X2_USE_ENDSTOP == _XMIN_
454
+      #define X2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
455
+      #define X2_MIN_PIN X_MIN_PIN
456
+    #elif X2_USE_ENDSTOP == _XMAX_
457
+      #define X2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
458
+      #define X2_MIN_PIN X_MAX_PIN
459
+    #elif X2_USE_ENDSTOP == _YMIN_
460
+      #define X2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
461
+      #define X2_MIN_PIN Y_MIN_PIN
462
+    #elif X2_USE_ENDSTOP == _YMAX_
463
+      #define X2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
464
+      #define X2_MIN_PIN Y_MAX_PIN
465
+    #elif X2_USE_ENDSTOP == _ZMIN_
466
+      #define X2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
467
+      #define X2_MIN_PIN Z_MIN_PIN
468
+    #elif X2_USE_ENDSTOP == _ZMAX_
469
+      #define X2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
470
+      #define X2_MIN_PIN Z_MAX_PIN
471
+    #else
472
+      #define X2_MIN_ENDSTOP_INVERTING false
473
+    #endif
474
+    #define X2_MAX_ENDSTOP_INVERTING false
475
+  #endif
476
+#endif
477
+
478
+// Is an endstop plug used for the X2 endstop?
479
+#define IS_X2_ENDSTOP(A,M) (ENABLED(X_DUAL_ENDSTOPS) && X2_USE_ENDSTOP == _##A##M##_)
480
+
481
+/**
482
+ * Y_DUAL_ENDSTOPS endstop reassignment
483
+ */
484
+#if ENABLED(Y_DUAL_ENDSTOPS)
485
+  #if Y_HOME_DIR > 0
486
+    #if Y2_USE_ENDSTOP == _XMIN_
487
+      #define Y2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
488
+      #define Y2_MAX_PIN X_MIN_PIN
489
+    #elif Y2_USE_ENDSTOP == _XMAX_
490
+      #define Y2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
491
+      #define Y2_MAX_PIN X_MAX_PIN
492
+    #elif Y2_USE_ENDSTOP == _YMIN_
493
+      #define Y2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
494
+      #define Y2_MAX_PIN Y_MIN_PIN
495
+    #elif Y2_USE_ENDSTOP == _YMAX_
496
+      #define Y2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
497
+      #define Y2_MAX_PIN Y_MAX_PIN
498
+    #elif Y2_USE_ENDSTOP == _ZMIN_
499
+      #define Y2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
500
+      #define Y2_MAX_PIN Z_MIN_PIN
501
+    #elif Y2_USE_ENDSTOP == _ZMAX_
502
+      #define Y2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
503
+      #define Y2_MAX_PIN Z_MAX_PIN
504
+    #else
505
+      #define Y2_MAX_ENDSTOP_INVERTING false
506
+    #endif
507
+    #define Y2_MIN_ENDSTOP_INVERTING false
508
+  #else
509
+    #if Y2_USE_ENDSTOP == _XMIN_
510
+      #define Y2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
511
+      #define Y2_MIN_PIN X_MIN_PIN
512
+    #elif Y2_USE_ENDSTOP == _XMAX_
513
+      #define Y2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING
514
+      #define Y2_MIN_PIN X_MAX_PIN
515
+    #elif Y2_USE_ENDSTOP == _YMIN_
516
+      #define Y2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING
517
+      #define Y2_MIN_PIN Y_MIN_PIN
518
+    #elif Y2_USE_ENDSTOP == _YMAX_
519
+      #define Y2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING
520
+      #define Y2_MIN_PIN Y_MAX_PIN
521
+    #elif Y2_USE_ENDSTOP == _ZMIN_
522
+      #define Y2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING
523
+      #define Y2_MIN_PIN Z_MIN_PIN
524
+    #elif Y2_USE_ENDSTOP == _ZMAX_
525
+      #define Y2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING
526
+      #define Y2_MIN_PIN Z_MAX_PIN
527
+    #else
528
+      #define Y2_MIN_ENDSTOP_INVERTING false
529
+    #endif
530
+    #define Y2_MAX_ENDSTOP_INVERTING false
531
+  #endif
532
+#endif
533
+
534
+// Is an endstop plug used for the Y2 endstop or the bed probe?
535
+#define IS_Y2_ENDSTOP(A,M) (ENABLED(Y_DUAL_ENDSTOPS) && Y2_USE_ENDSTOP == _##A##M##_)
536
+
537
+/**
426 538
  * Z_DUAL_ENDSTOPS endstop reassignment
427 539
  */
428 540
 #if ENABLED(Z_DUAL_ENDSTOPS)
429
-  #define _XMIN_ 100
430
-  #define _YMIN_ 200
431
-  #define _ZMIN_ 300
432
-  #define _XMAX_ 101
433
-  #define _YMAX_ 201
434
-  #define _ZMAX_ 301
435
-  #if Z2_USE_ENDSTOP == _XMIN_
436
-    #define USE_XMIN_PLUG
437
-  #elif Z2_USE_ENDSTOP == _XMAX_
438
-    #define USE_XMAX_PLUG
439
-  #elif Z2_USE_ENDSTOP == _YMIN_
440
-    #define USE_YMIN_PLUG
441
-  #elif Z2_USE_ENDSTOP == _YMAX_
442
-    #define USE_YMAX_PLUG
443
-  #elif Z2_USE_ENDSTOP == _ZMIN_
444
-    #define USE_ZMIN_PLUG
445
-  #elif Z2_USE_ENDSTOP == _ZMAX_
446
-    #define USE_ZMAX_PLUG
447
-  #endif
448 541
   #if Z_HOME_DIR > 0
449 542
     #if Z2_USE_ENDSTOP == _XMIN_
450 543
       #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
@@ -467,6 +560,7 @@
467 560
     #else
468 561
       #define Z2_MAX_ENDSTOP_INVERTING false
469 562
     #endif
563
+    #define Z2_MIN_ENDSTOP_INVERTING false
470 564
   #else
471 565
     #if Z2_USE_ENDSTOP == _XMIN_
472 566
       #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING
@@ -489,6 +583,7 @@
489 583
     #else
490 584
       #define Z2_MIN_ENDSTOP_INVERTING false
491 585
     #endif
586
+    #define Z2_MAX_ENDSTOP_INVERTING false
492 587
   #endif
493 588
 #endif
494 589
 
@@ -585,12 +680,16 @@
585 680
 #define HAS_SOLENOID_4    (PIN_EXISTS(SOL4))
586 681
 
587 682
 // Endstops and bed probe
588
-#define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_Z2_OR_PROBE(X,MIN))
589
-#define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_Z2_OR_PROBE(X,MAX))
590
-#define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_Z2_OR_PROBE(Y,MIN))
591
-#define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_Z2_OR_PROBE(Y,MAX))
592
-#define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_Z2_OR_PROBE(Z,MIN))
593
-#define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_Z2_OR_PROBE(Z,MAX))
683
+#define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_X2_ENDSTOP(X,MIN) && !IS_Y2_ENDSTOP(X,MIN) && !IS_Z2_OR_PROBE(X,MIN))
684
+#define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_X2_ENDSTOP(X,MAX) && !IS_Y2_ENDSTOP(X,MAX) && !IS_Z2_OR_PROBE(X,MAX))
685
+#define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_X2_ENDSTOP(Y,MIN) && !IS_Y2_ENDSTOP(Y,MIN) && !IS_Z2_OR_PROBE(Y,MIN))
686
+#define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_X2_ENDSTOP(Y,MAX) && !IS_Y2_ENDSTOP(Y,MAX) && !IS_Z2_OR_PROBE(Y,MAX))
687
+#define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_X2_ENDSTOP(Z,MIN) && !IS_Y2_ENDSTOP(Z,MIN) && !IS_Z2_OR_PROBE(Z,MIN))
688
+#define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_X2_ENDSTOP(Z,MAX) && !IS_Y2_ENDSTOP(Z,MAX) && !IS_Z2_OR_PROBE(Z,MAX))
689
+#define HAS_X2_MIN (PIN_EXISTS(X2_MIN))
690
+#define HAS_X2_MAX (PIN_EXISTS(X2_MAX))
691
+#define HAS_Y2_MIN (PIN_EXISTS(Y2_MIN))
692
+#define HAS_Y2_MAX (PIN_EXISTS(Y2_MAX))
594 693
 #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN))
595 694
 #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
596 695
 #define HAS_Z_MIN_PROBE_PIN (PIN_EXISTS(Z_MIN_PROBE))

+ 88
- 22
Marlin/src/inc/SanityCheck.h Voir le fichier

@@ -81,8 +81,6 @@
81 81
   #error "FILAMENT_SENSOR is deprecated. Use FILAMENT_WIDTH_SENSOR instead."
82 82
 #elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS)
83 83
   #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead."
84
-#elif ENABLED(Z_DUAL_ENDSTOPS) && !defined(Z2_USE_ENDSTOP)
85
-  #error "Z_DUAL_ENDSTOPS settings are simplified. Just set Z2_USE_ENDSTOP to the endstop you want to repurpose for Z2."
86 84
 #elif defined(LANGUAGE_INCLUDE)
87 85
   #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE. Please update your configuration."
88 86
 #elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y)
@@ -1081,23 +1079,25 @@ static_assert(1 >= 0
1081 1079
 #endif
1082 1080
 
1083 1081
 /**
1084
- * Endstops
1082
+ * Endstop Tests
1085 1083
  */
1086
-#if DISABLED(USE_XMIN_PLUG) && DISABLED(USE_XMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _XMAX_, _XMIN_))
1087
- #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
1088
-#elif DISABLED(USE_YMIN_PLUG) && DISABLED(USE_YMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _YMAX_, _YMIN_))
1089
- #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
1090
-#elif DISABLED(USE_ZMIN_PLUG) && DISABLED(USE_ZMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _ZMAX_, _ZMIN_))
1091
- #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
1092
-#elif ENABLED(Z_DUAL_ENDSTOPS)
1093
-  #if !Z2_USE_ENDSTOP
1094
-    #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS."
1095
-  #elif Z2_MAX_PIN == 0 && Z2_MIN_PIN == 0
1096
-    #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1097
-  #elif ENABLED(DELTA)
1098
-    #error "Z_DUAL_ENDSTOPS is not compatible with DELTA."
1099
-  #endif
1100
-#elif !IS_SCARA
1084
+
1085
+#define _PLUG_UNUSED_TEST(AXIS,PLUG) (DISABLED(USE_##PLUG##MIN_PLUG) && DISABLED(USE_##PLUG##MAX_PLUG) && !(ENABLED(AXIS##_DUAL_ENDSTOPS) && WITHIN(AXIS##2_USE_ENDSTOP, _##PLUG##MAX_, _##PLUG##MIN_)))
1086
+#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z))
1087
+
1088
+// At least 3 endstop plugs must be used
1089
+#if _AXIS_PLUG_UNUSED_TEST(X)
1090
+  #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG."
1091
+#endif
1092
+#if _AXIS_PLUG_UNUSED_TEST(Y)
1093
+  #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG."
1094
+#endif
1095
+#if _AXIS_PLUG_UNUSED_TEST(Z)
1096
+  #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG."
1097
+#endif
1098
+
1099
+// Delta and Cartesian use 3 homing endstops
1100
+#if !IS_SCARA
1101 1101
   #if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG)
1102 1102
     #error "Enable USE_XMIN_PLUG when homing X to MIN."
1103 1103
   #elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG)
@@ -1106,10 +1106,76 @@ static_assert(1 >= 0
1106 1106
     #error "Enable USE_YMIN_PLUG when homing Y to MIN."
1107 1107
   #elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG)
1108 1108
     #error "Enable USE_YMAX_PLUG when homing Y to MAX."
1109
-  #elif Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
1110
-    #error "Enable USE_ZMIN_PLUG when homing Z to MIN."
1111
-  #elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
1112
-    #error "Enable USE_ZMAX_PLUG when homing Z to MAX."
1109
+  #endif
1110
+#endif
1111
+#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG)
1112
+  #error "Enable USE_ZMIN_PLUG when homing Z to MIN."
1113
+#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG)
1114
+  #error "Enable USE_ZMAX_PLUG when homing Z to MAX."
1115
+#endif
1116
+
1117
+// Dual endstops requirements
1118
+#if ENABLED(X_DUAL_ENDSTOPS)
1119
+  #if !X2_USE_ENDSTOP
1120
+    #error "You must set X2_USE_ENDSTOP with X_DUAL_ENDSTOPS."
1121
+  #elif X2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG)
1122
+    #error "USE_XMIN_PLUG is required when X2_USE_ENDSTOP is _X_MIN_."
1123
+  #elif X2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG)
1124
+    #error "USE_XMAX_PLUG is required when X2_USE_ENDSTOP is _X_MAX_."
1125
+  #elif X2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG)
1126
+    #error "USE_YMIN_PLUG is required when X2_USE_ENDSTOP is _Y_MIN_."
1127
+  #elif X2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG)
1128
+    #error "USE_YMAX_PLUG is required when X2_USE_ENDSTOP is _Y_MAX_."
1129
+  #elif X2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG)
1130
+    #error "USE_ZMIN_PLUG is required when X2_USE_ENDSTOP is _Z_MIN_."
1131
+  #elif X2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG)
1132
+    #error "USE_ZMAX_PLUG is required when X2_USE_ENDSTOP is _Z_MAX_."
1133
+  #elif !HAS_X2_MIN && !HAS_X2_MAX
1134
+    #error "X2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1135
+  #elif ENABLED(DELTA)
1136
+    #error "X_DUAL_ENDSTOPS is not compatible with DELTA."
1137
+  #endif
1138
+#endif
1139
+#if ENABLED(Y_DUAL_ENDSTOPS)
1140
+  #if !Y2_USE_ENDSTOP
1141
+    #error "You must set Y2_USE_ENDSTOP with Y_DUAL_ENDSTOPS."
1142
+  #elif Y2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG)
1143
+    #error "USE_XMIN_PLUG is required when Y2_USE_ENDSTOP is _X_MIN_."
1144
+  #elif Y2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG)
1145
+    #error "USE_XMAX_PLUG is required when Y2_USE_ENDSTOP is _X_MAX_."
1146
+  #elif Y2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG)
1147
+    #error "USE_YMIN_PLUG is required when Y2_USE_ENDSTOP is _Y_MIN_."
1148
+  #elif Y2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG)
1149
+    #error "USE_YMAX_PLUG is required when Y2_USE_ENDSTOP is _Y_MAX_."
1150
+  #elif Y2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG)
1151
+    #error "USE_ZMIN_PLUG is required when Y2_USE_ENDSTOP is _Z_MIN_."
1152
+  #elif Y2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG)
1153
+    #error "USE_ZMAX_PLUG is required when Y2_USE_ENDSTOP is _Z_MAX_."
1154
+  #elif !HAS_Y2_MIN && !HAS_Y2_MAX
1155
+    #error "Y2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1156
+  #elif ENABLED(DELTA)
1157
+    #error "Y_DUAL_ENDSTOPS is not compatible with DELTA."
1158
+  #endif
1159
+#endif
1160
+#if ENABLED(Z_DUAL_ENDSTOPS)
1161
+  #if !Z2_USE_ENDSTOP
1162
+    #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS."
1163
+  #elif Z2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG)
1164
+    #error "USE_XMIN_PLUG is required when Z2_USE_ENDSTOP is _X_MIN_."
1165
+  #elif Z2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG)
1166
+    #error "USE_XMAX_PLUG is required when Z2_USE_ENDSTOP is _X_MAX_."
1167
+  #elif Z2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG)
1168
+    #error "USE_YMIN_PLUG is required when Z2_USE_ENDSTOP is _Y_MIN_."
1169
+  #elif Z2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG)
1170
+    #error "USE_YMAX_PLUG is required when Z2_USE_ENDSTOP is _Y_MAX_."
1171
+  #elif Z2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG)
1172
+    #error "USE_ZMIN_PLUG is required when Z2_USE_ENDSTOP is _Z_MIN_."
1173
+  #elif Z2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG)
1174
+    #error "USE_ZMAX_PLUG is required when Z2_USE_ENDSTOP is _Z_MAX_."
1175
+  #elif !HAS_Z2_MIN && !HAS_Z2_MAX
1176
+    #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!"
1177
+  #elif ENABLED(DELTA)
1178
+    #error "Z_DUAL_ENDSTOPS is not compatible with DELTA."
1113 1179
   #endif
1114 1180
 #endif
1115 1181
 

+ 151
- 82
Marlin/src/module/configuration_store.cpp Voir le fichier

@@ -36,13 +36,13 @@
36 36
  *
37 37
  */
38 38
 
39
-#define EEPROM_VERSION "V42"
39
+#define EEPROM_VERSION "V43"
40 40
 
41 41
 // Change EEPROM version if these are changed:
42 42
 #define EEPROM_OFFSET 100
43 43
 
44 44
 /**
45
- * V42 EEPROM Layout:
45
+ * V43 EEPROM Layout:
46 46
  *
47 47
  *  100  Version                                    (char x4)
48 48
  *  104  EEPROM CRC16                               (uint16_t)
@@ -68,7 +68,7 @@
68 68
  *  219            z_fade_height                    (float)
69 69
  *
70 70
  * MESH_BED_LEVELING:                               43 bytes
71
- *  223  M420 S    planner.leveling_active         (bool)
71
+ *  223  M420 S    planner.leveling_active          (bool)
72 72
  *  224            mbl.z_offset                     (float)
73 73
  *  228            GRID_MAX_POINTS_X                (uint8_t)
74 74
  *  229            GRID_MAX_POINTS_Y                (uint8_t)
@@ -91,78 +91,79 @@
91 91
  *  324  G29 A     planner.leveling_active          (bool)
92 92
  *  325  G29 S     ubl.storage_slot                 (int8_t)
93 93
  *
94
- * DELTA:                                           48 bytes
95
- *  344  M666 XYZ  delta_endstop_adj                (float x3)
96
- *  360  M665 R    delta_radius                     (float)
97
- *  364  M665 L    delta_diagonal_rod               (float)
98
- *  368  M665 S    delta_segments_per_second        (float)
99
- *  372  M665 B    delta_calibration_radius         (float)
100
- *  376  M665 X    delta_tower_angle_trim[A]        (float)
101
- *  380  M665 Y    delta_tower_angle_trim[B]        (float)
102
- *  384  M665 Z    delta_tower_angle_trim[C]        (float)
94
+ * DELTA:                                           40 bytes
95
+ *  352  M666 XYZ  delta_endstop_adj                (float x3)
96
+ *  364  M665 R    delta_radius                     (float)
97
+ *  368  M665 L    delta_diagonal_rod               (float)
98
+ *  372  M665 S    delta_segments_per_second        (float)
99
+ *  376  M665 B    delta_calibration_radius         (float)
100
+ *  380  M665 X    delta_tower_angle_trim[A]        (float)
101
+ *  384  M665 Y    delta_tower_angle_trim[B]        (float)
102
+ *  388  M665 Z    delta_tower_angle_trim[C]        (float)
103 103
  *
104
- * Z_DUAL_ENDSTOPS:                                 48 bytes
105
- *  348  M666 Z    endstops.z_endstop_adj           (float)
106
- *  ---            dummy data                       (float x11)
104
+ * [XYZ]_DUAL_ENDSTOPS:                             12 bytes
105
+ *  352  M666 X    endstops.x_endstop_adj           (float)
106
+ *  356  M666 Y    endstops.y_endstop_adj           (float)
107
+ *  360  M666 Z    endstops.z_endstop_adj           (float)
107 108
  *
108 109
  * ULTIPANEL:                                       6 bytes
109
- *  396  M145 S0 H lcd_preheat_hotend_temp          (int x2)
110
- *  400  M145 S0 B lcd_preheat_bed_temp             (int x2)
111
- *  404  M145 S0 F lcd_preheat_fan_speed            (int x2)
110
+ *  392  M145 S0 H lcd_preheat_hotend_temp          (int x2)
111
+ *  396  M145 S0 B lcd_preheat_bed_temp             (int x2)
112
+ *  400  M145 S0 F lcd_preheat_fan_speed            (int x2)
112 113
  *
113
- * PIDTEMP:                                         66 bytes
114
- *  408  M301 E0 PIDC  Kp[0], Ki[0], Kd[0], Kc[0]   (float x4)
115
- *  424  M301 E1 PIDC  Kp[1], Ki[1], Kd[1], Kc[1]   (float x4)
116
- *  440  M301 E2 PIDC  Kp[2], Ki[2], Kd[2], Kc[2]   (float x4)
117
- *  456  M301 E3 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
118
- *  472  M301 E4 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
119
- *  488  M301 L        lpq_len                      (int)
114
+ * PIDTEMP:                                         82 bytes
115
+ *  404  M301 E0 PIDC  Kp[0], Ki[0], Kd[0], Kc[0]   (float x4)
116
+ *  420  M301 E1 PIDC  Kp[1], Ki[1], Kd[1], Kc[1]   (float x4)
117
+ *  436  M301 E2 PIDC  Kp[2], Ki[2], Kd[2], Kc[2]   (float x4)
118
+ *  452  M301 E3 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
119
+ *  468  M301 E4 PIDC  Kp[3], Ki[3], Kd[3], Kc[3]   (float x4)
120
+ *  484  M301 L        lpq_len                      (int)
120 121
  *
121 122
  * PIDTEMPBED:                                      12 bytes
122
- *  490  M304 PID  thermalManager.bedKp, .bedKi, .bedKd (float x3)
123
+ *  486  M304 PID  thermalManager.bedKp, .bedKi, .bedKd (float x3)
123 124
  *
124 125
  * DOGLCD:                                          2 bytes
125
- *  502  M250 C    lcd_contrast                     (uint16_t)
126
+ *  498  M250 C    lcd_contrast                     (uint16_t)
126 127
  *
127 128
  * FWRETRACT:                                       33 bytes
128
- *  504  M209 S    autoretract_enabled              (bool)
129
- *  505  M207 S    retract_length                   (float)
130
- *  509  M207 F    retract_feedrate_mm_s            (float)
131
- *  513  M207 Z    retract_zlift                    (float)
132
- *  517  M208 S    retract_recover_length           (float)
133
- *  521  M208 F    retract_recover_feedrate_mm_s    (float)
134
- *  525  M207 W    swap_retract_length              (float)
135
- *  529  M208 W    swap_retract_recover_length      (float)
136
- *  533  M208 R    swap_retract_recover_feedrate_mm_s (float)
129
+ *  500  M209 S    autoretract_enabled              (bool)
130
+ *  501  M207 S    retract_length                   (float)
131
+ *  505  M207 F    retract_feedrate_mm_s            (float)
132
+ *  509  M207 Z    retract_zlift                    (float)
133
+ *  513  M208 S    retract_recover_length           (float)
134
+ *  517  M208 F    retract_recover_feedrate_mm_s    (float)
135
+ *  521  M207 W    swap_retract_length              (float)
136
+ *  525  M208 W    swap_retract_recover_length      (float)
137
+ *  529  M208 R    swap_retract_recover_feedrate_mm_s (float)
137 138
  *
138 139
  * Volumetric Extrusion:                            21 bytes
139
- *  537  M200 D    parser.volumetric_enabled        (bool)
140
- *  538  M200 T D  planner.filament_size            (float x5) (T0..3)
140
+ *  533  M200 D    volumetric_enabled               (bool)
141
+ *  534  M200 T D  filament_size                    (float x5) (T0..3)
141 142
  *
142
- * HAVE_TMC2130:                                    20 bytes
143
- *  558  M906 X    Stepper X current                (uint16_t)
144
- *  560  M906 Y    Stepper Y current                (uint16_t)
145
- *  562  M906 Z    Stepper Z current                (uint16_t)
146
- *  564  M906 X2   Stepper X2 current               (uint16_t)
147
- *  566  M906 Y2   Stepper Y2 current               (uint16_t)
148
- *  568  M906 Z2   Stepper Z2 current               (uint16_t)
149
- *  570  M906 E0   Stepper E0 current               (uint16_t)
150
- *  572  M906 E1   Stepper E1 current               (uint16_t)
151
- *  574  M906 E2   Stepper E2 current               (uint16_t)
152
- *  576  M906 E3   Stepper E3 current               (uint16_t)
153
- *  580  M906 E4   Stepper E4 current               (uint16_t)
143
+ * HAVE_TMC2130:                                    22 bytes
144
+ *  554  M906 X    Stepper X current                (uint16_t)
145
+ *  556  M906 Y    Stepper Y current                (uint16_t)
146
+ *  558  M906 Z    Stepper Z current                (uint16_t)
147
+ *  560  M906 X2   Stepper X2 current               (uint16_t)
148
+ *  562  M906 Y2   Stepper Y2 current               (uint16_t)
149
+ *  564  M906 Z2   Stepper Z2 current               (uint16_t)
150
+ *  566  M906 E0   Stepper E0 current               (uint16_t)
151
+ *  568  M906 E1   Stepper E1 current               (uint16_t)
152
+ *  570  M906 E2   Stepper E2 current               (uint16_t)
153
+ *  572  M906 E3   Stepper E3 current               (uint16_t)
154
+ *  574  M906 E4   Stepper E4 current               (uint16_t)
154 155
  *
155 156
  * LIN_ADVANCE:                                     8 bytes
156
- *  584  M900 K    extruder_advance_k               (float)
157
- *  588  M900 WHD  advance_ed_ratio                 (float)
157
+ *  576  M900 K    extruder_advance_k               (float)
158
+ *  580  M900 WHD  advance_ed_ratio                 (float)
158 159
  *
159 160
  * HAS_MOTOR_CURRENT_PWM:
160
- *  592  M907 X    Stepper XY current               (uint32_t)
161
- *  596  M907 Z    Stepper Z current                (uint32_t)
162
- *  600  M907 E    Stepper E current                (uint32_t)
161
+ *  584  M907 X    Stepper XY current               (uint32_t)
162
+ *  588  M907 Z    Stepper Z current                (uint32_t)
163
+ *  592  M907 E    Stepper E current                (uint32_t)
163 164
  *
164
- *  604                                Minimum end-point
165
- * 1925 (604 + 36 + 9 + 288 + 988)     Maximum end-point
165
+ *  596                                Minimum end-point
166
+ * 1917 (596 + 36 + 9 + 288 + 988)     Maximum end-point
166 167
  *
167 168
  * ========================================================================
168 169
  * meshes_begin (between max and min end-point, directly above)
@@ -419,7 +420,7 @@ void MarlinSettings::postprocess() {
419 420
       EEPROM_WRITE(storage_slot);
420 421
     #endif // AUTO_BED_LEVELING_UBL
421 422
 
422
-    // 10 floats for DELTA / Z_DUAL_ENDSTOPS
423
+    // 10 floats for DELTA / [XYZ]_DUAL_ENDSTOPS
423 424
     #if ENABLED(DELTA)
424 425
       EEPROM_WRITE(delta_endstop_adj);         // 3 floats
425 426
       EEPROM_WRITE(delta_radius);              // 1 float
@@ -427,15 +428,33 @@ void MarlinSettings::postprocess() {
427 428
       EEPROM_WRITE(delta_segments_per_second); // 1 float
428 429
       EEPROM_WRITE(delta_calibration_radius);  // 1 float
429 430
       EEPROM_WRITE(delta_tower_angle_trim);    // 3 floats
431
+
432
+    #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
433
+      // Write dual endstops in X, Y, Z order. Unused = 0.0
430 434
       dummy = 0.0f;
431
-      for (uint8_t q = 2; q--;) EEPROM_WRITE(dummy);
432
-    #elif ENABLED(Z_DUAL_ENDSTOPS)
433
-      EEPROM_WRITE(endstops.z_endstop_adj);    // 1 float
434
-      dummy = 0.0f;
435
-      for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy);
435
+      #if ENABLED(X_DUAL_ENDSTOPS)
436
+        EEPROM_WRITE(endstops.x_endstop_adj);   // 1 float
437
+      #else
438
+        EEPROM_WRITE(dummy);
439
+      #endif
440
+
441
+      #if ENABLED(Y_DUAL_ENDSTOPS)
442
+        EEPROM_WRITE(endstops.y_endstop_adj);   // 1 float
443
+      #else
444
+        EEPROM_WRITE(dummy);
445
+      #endif
446
+
447
+      #if ENABLED(Z_DUAL_ENDSTOPS)
448
+        EEPROM_WRITE(endstops.z_endstop_adj);   // 1 float
449
+      #else
450
+        EEPROM_WRITE(dummy);
451
+      #endif
452
+
453
+      for (uint8_t q = 7; q--;) EEPROM_WRITE(dummy);
454
+
436 455
     #else
437 456
       dummy = 0.0f;
438
-      for (uint8_t q = 12; q--;) EEPROM_WRITE(dummy);
457
+      for (uint8_t q = 10; q--;) EEPROM_WRITE(dummy);
439 458
     #endif
440 459
 
441 460
     #if DISABLED(ULTIPANEL)
@@ -638,6 +657,7 @@ void MarlinSettings::postprocess() {
638 657
       if (ubl.storage_slot >= 0)
639 658
         store_mesh(ubl.storage_slot);
640 659
     #endif
660
+
641 661
     return !eeprom_error;
642 662
   }
643 663
 
@@ -814,13 +834,31 @@ void MarlinSettings::postprocess() {
814 834
         EEPROM_READ(delta_tower_angle_trim);    // 3 floats
815 835
         dummy = 0.0f;
816 836
         for (uint8_t q=2; q--;) EEPROM_READ(dummy);
817
-      #elif ENABLED(Z_DUAL_ENDSTOPS)
818
-        EEPROM_READ(endstops.z_endstop_adj);    // 1 float
819
-        dummy = 0.0f;
820
-        for (uint8_t q=11; q--;) EEPROM_READ(dummy);
837
+
838
+      #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
839
+
840
+        #if ENABLED(X_DUAL_ENDSTOPS)
841
+          EEPROM_READ(endstops.x_endstop_adj);  // 1 float
842
+        #else
843
+          EEPROM_READ(dummy);
844
+        #endif
845
+        #if ENABLED(Y_DUAL_ENDSTOPS)
846
+          EEPROM_READ(endstops.y_endstop_adj);  // 1 float
847
+        #else
848
+          EEPROM_READ(dummy);
849
+        #endif
850
+        #if ENABLED(Z_DUAL_ENDSTOPS)
851
+          EEPROM_READ(endstops.z_endstop_adj); // 1 float
852
+        #else
853
+          EEPROM_READ(dummy);
854
+        #endif
855
+
856
+        for (uint8_t q=7; q--;) EEPROM_READ(dummy);
857
+
821 858
       #else
822
-        dummy = 0.0f;
823
-        for (uint8_t q=12; q--;) EEPROM_READ(dummy);
859
+
860
+        for (uint8_t q=10; q--;) EEPROM_READ(dummy);
861
+
824 862
       #endif
825 863
 
826 864
       #if DISABLED(ULTIPANEL)
@@ -1218,15 +1256,35 @@ void MarlinSettings::reset() {
1218 1256
     COPY(delta_tower_angle_trim, dta);
1219 1257
     home_offset[Z_AXIS] = 0;
1220 1258
 
1221
-  #elif ENABLED(Z_DUAL_ENDSTOPS)
1259
+  #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
1222 1260
 
1223
-    endstops.z_endstop_adj =
1224
-      #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT
1225
-        Z_DUAL_ENDSTOPS_ADJUSTMENT
1226
-      #else
1227
-        0
1228
-      #endif
1229
-    ;
1261
+    #if ENABLED(X_DUAL_ENDSTOPS)
1262
+      endstops.x_endstop_adj = (
1263
+        #ifdef X_DUAL_ENDSTOPS_ADJUSTMENT
1264
+          X_DUAL_ENDSTOPS_ADJUSTMENT
1265
+        #else
1266
+          0
1267
+        #endif
1268
+      );
1269
+    #endif
1270
+    #if ENABLED(Y_DUAL_ENDSTOPS)
1271
+      endstops.y_endstop_adj = (
1272
+        #ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT
1273
+          Y_DUAL_ENDSTOPS_ADJUSTMENT
1274
+        #else
1275
+          0
1276
+        #endif
1277
+      );
1278
+    #endif
1279
+    #if ENABLED(Z_DUAL_ENDSTOPS)
1280
+      endstops.z_endstop_adj = (
1281
+        #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT
1282
+          Z_DUAL_ENDSTOPS_ADJUSTMENT
1283
+        #else
1284
+          0
1285
+        #endif
1286
+      );
1287
+    #endif
1230 1288
 
1231 1289
   #endif
1232 1290
 
@@ -1627,13 +1685,24 @@ void MarlinSettings::reset() {
1627 1685
       SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS]));
1628 1686
       SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS]));
1629 1687
       SERIAL_EOL();
1630
-    #elif ENABLED(Z_DUAL_ENDSTOPS)
1688
+
1689
+    #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
1631 1690
       if (!forReplay) {
1632 1691
         CONFIG_ECHO_START;
1633
-        SERIAL_ECHOLNPGM("Z2 Endstop adjustment:");
1692
+        SERIAL_ECHOLNPGM("Endstop adjustment:");
1634 1693
       }
1635 1694
       CONFIG_ECHO_START;
1636
-      SERIAL_ECHOLNPAIR("  M666 Z", LINEAR_UNIT(endstops.z_endstop_adj));
1695
+      SERIAL_ECHOPGM("  M666");
1696
+      #if ENABLED(X_DUAL_ENDSTOPS)
1697
+        SERIAL_ECHOPAIR(" X", LINEAR_UNIT(endstops.x_endstop_adj));
1698
+      #endif
1699
+      #if ENABLED(Y_DUAL_ENDSTOPS)
1700
+        SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(endstops.y_endstop_adj));
1701
+      #endif
1702
+      #if ENABLED(Z_DUAL_ENDSTOPS)
1703
+        SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(endstops.z_endstop_adj));
1704
+      #endif
1705
+      SERIAL_EOL();
1637 1706
     #endif // DELTA
1638 1707
 
1639 1708
     #if ENABLED(ULTIPANEL)
@@ -1738,7 +1807,7 @@ void MarlinSettings::reset() {
1738 1807
     #endif // FWRETRACT
1739 1808
 
1740 1809
     /**
1741
-     * Auto Bed Leveling
1810
+     * Probe Offset
1742 1811
      */
1743 1812
     #if HAS_BED_PROBE
1744 1813
       if (!forReplay) {

+ 162
- 48
Marlin/src/module/endstops.cpp Voir le fichier

@@ -42,7 +42,7 @@ Endstops endstops;
42 42
 bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load()
43 43
 volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value
44 44
 
45
-#if ENABLED(Z_DUAL_ENDSTOPS)
45
+#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
46 46
   uint16_t
47 47
 #else
48 48
   byte
@@ -54,8 +54,14 @@ volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_P
54 54
   volatile bool Endstops::z_probe_enabled = false;
55 55
 #endif
56 56
 
57
+#if ENABLED(X_DUAL_ENDSTOPS)
58
+  float Endstops::x_endstop_adj; // Initialized by settings.load()
59
+#endif
60
+#if ENABLED(Y_DUAL_ENDSTOPS)
61
+  float Endstops::y_endstop_adj; // Initialized by settings.load()
62
+#endif
57 63
 #if ENABLED(Z_DUAL_ENDSTOPS)
58
-  float Endstops::z_endstop_adj;
64
+  float Endstops::z_endstop_adj; // Initialized by settings.load()
59 65
 #endif
60 66
 
61 67
 /**
@@ -72,6 +78,14 @@ void Endstops::init() {
72 78
     #endif
73 79
   #endif
74 80
 
81
+  #if HAS_X2_MIN
82
+    #if ENABLED(ENDSTOPPULLUP_XMIN)
83
+      SET_INPUT_PULLUP(X2_MIN_PIN);
84
+    #else
85
+      SET_INPUT(X2_MIN_PIN);
86
+    #endif
87
+  #endif
88
+
75 89
   #if HAS_Y_MIN
76 90
     #if ENABLED(ENDSTOPPULLUP_YMIN)
77 91
       SET_INPUT_PULLUP(Y_MIN_PIN);
@@ -80,6 +94,14 @@ void Endstops::init() {
80 94
     #endif
81 95
   #endif
82 96
 
97
+  #if HAS_Y2_MIN
98
+    #if ENABLED(ENDSTOPPULLUP_YMIN)
99
+      SET_INPUT_PULLUP(Y2_MIN_PIN);
100
+    #else
101
+      SET_INPUT(Y2_MIN_PIN);
102
+    #endif
103
+  #endif
104
+
83 105
   #if HAS_Z_MIN
84 106
     #if ENABLED(ENDSTOPPULLUP_ZMIN)
85 107
       SET_INPUT_PULLUP(Z_MIN_PIN);
@@ -104,6 +126,14 @@ void Endstops::init() {
104 126
     #endif
105 127
   #endif
106 128
 
129
+  #if HAS_X2_MAX
130
+    #if ENABLED(ENDSTOPPULLUP_XMAX)
131
+      SET_INPUT_PULLUP(X2_MAX_PIN);
132
+    #else
133
+      SET_INPUT(X2_MAX_PIN);
134
+    #endif
135
+  #endif
136
+
107 137
   #if HAS_Y_MAX
108 138
     #if ENABLED(ENDSTOPPULLUP_YMAX)
109 139
       SET_INPUT_PULLUP(Y_MAX_PIN);
@@ -112,6 +142,14 @@ void Endstops::init() {
112 142
     #endif
113 143
   #endif
114 144
 
145
+  #if HAS_Y2_MAX
146
+    #if ENABLED(ENDSTOPPULLUP_YMAX)
147
+      SET_INPUT_PULLUP(Y2_MAX_PIN);
148
+    #else
149
+      SET_INPUT(Y2_MAX_PIN);
150
+    #endif
151
+  #endif
152
+
115 153
   #if HAS_Z_MAX
116 154
     #if ENABLED(ENDSTOPPULLUP_ZMAX)
117 155
       SET_INPUT_PULLUP(Z_MAX_PIN);
@@ -190,37 +228,45 @@ void Endstops::report_state() {
190 228
 
191 229
 void Endstops::M119() {
192 230
   SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT);
231
+  #define ES_REPORT(AXIS) do{ \
232
+    SERIAL_PROTOCOLPGM(MSG_##AXIS); \
233
+    SERIAL_PROTOCOLLN(((READ(AXIS##_PIN)^AXIS##_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); \
234
+  }while(0)
193 235
   #if HAS_X_MIN
194
-    SERIAL_PROTOCOLPGM(MSG_X_MIN);
195
-    SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
236
+    ES_REPORT(X_MIN);
237
+  #endif
238
+  #if HAS_X2_MIN
239
+    ES_REPORT(X2_MIN);
196 240
   #endif
197 241
   #if HAS_X_MAX
198
-    SERIAL_PROTOCOLPGM(MSG_X_MAX);
199
-    SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
242
+    ES_REPORT(X_MAX);
243
+  #endif
244
+  #if HAS_X2_MAX
245
+    ES_REPORT(X2_MAX);
200 246
   #endif
201 247
   #if HAS_Y_MIN
202
-    SERIAL_PROTOCOLPGM(MSG_Y_MIN);
203
-    SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
248
+    ES_REPORT(Y_MIN);
249
+  #endif
250
+  #if HAS_Y2_MIN
251
+    ES_REPORT(Y2_MIN);
204 252
   #endif
205 253
   #if HAS_Y_MAX
206
-    SERIAL_PROTOCOLPGM(MSG_Y_MAX);
207
-    SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
254
+    ES_REPORT(Y_MAX);
255
+  #endif
256
+  #if HAS_Y2_MAX
257
+    ES_REPORT(Y2_MAX);
208 258
   #endif
209 259
   #if HAS_Z_MIN
210
-    SERIAL_PROTOCOLPGM(MSG_Z_MIN);
211
-    SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
260
+    ES_REPORT(Z_MIN);
212 261
   #endif
213 262
   #if HAS_Z2_MIN
214
-    SERIAL_PROTOCOLPGM(MSG_Z2_MIN);
215
-    SERIAL_PROTOCOLLN(((READ(Z2_MIN_PIN)^Z2_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
263
+    ES_REPORT(Z2_MIN);
216 264
   #endif
217 265
   #if HAS_Z_MAX
218
-    SERIAL_PROTOCOLPGM(MSG_Z_MAX);
219
-    SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
266
+    ES_REPORT(Z_MAX);
220 267
   #endif
221 268
   #if HAS_Z2_MAX
222
-    SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
223
-    SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
269
+    ES_REPORT(Z2_MAX);
224 270
   #endif
225 271
   #if ENABLED(Z_MIN_PROBE_ENDSTOP)
226 272
     SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
@@ -232,18 +278,35 @@ void Endstops::M119() {
232 278
   #endif
233 279
 } // Endstops::M119
234 280
 
281
+#if ENABLED(X_DUAL_ENDSTOPS)
282
+  void Endstops::test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2) {
283
+    const byte x_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for X, bit 1 for X2
284
+    if (x_test && stepper.current_block->steps[X_AXIS] > 0) {
285
+      SBI(endstop_hit_bits, X_MIN);
286
+      if (!stepper.performing_homing || (x_test == 0x3))  //if not performing home or if both endstops were trigged during homing...
287
+        stepper.kill_current_block();
288
+    }
289
+  }
290
+#endif
291
+#if ENABLED(Y_DUAL_ENDSTOPS)
292
+  void Endstops::test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2) {
293
+    const byte y_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Y, bit 1 for Y2
294
+    if (y_test && stepper.current_block->steps[Y_AXIS] > 0) {
295
+      SBI(endstop_hit_bits, Y_MIN);
296
+      if (!stepper.performing_homing || (y_test == 0x3))  //if not performing home or if both endstops were trigged during homing...
297
+        stepper.kill_current_block();
298
+    }
299
+  }
300
+#endif
235 301
 #if ENABLED(Z_DUAL_ENDSTOPS)
236
-
237
-  // Pass the result of the endstop test
238 302
   void Endstops::test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2) {
239
-    byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2
303
+    const byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2
240 304
     if (z_test && stepper.current_block->steps[Z_AXIS] > 0) {
241 305
       SBI(endstop_hit_bits, Z_MIN);
242 306
       if (!stepper.performing_homing || (z_test == 0x3))  //if not performing home or if both endstops were trigged during homing...
243 307
         stepper.kill_current_block();
244 308
     }
245 309
   }
246
-
247 310
 #endif
248 311
 
249 312
 // Check endstops - Called from ISR!
@@ -364,16 +427,35 @@ void Endstops::update() {
364 427
    */
365 428
 
366 429
   if (X_MOVE_TEST) {
367
-    if (stepper.motor_direction(X_AXIS_HEAD)) {
368
-      if (X_MIN_TEST) { // -direction
369
-        #if HAS_X_MIN
370
-          UPDATE_ENDSTOP(X, MIN);
430
+    if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction
431
+      #if HAS_X_MIN
432
+        #if ENABLED(X_DUAL_ENDSTOPS)
433
+          UPDATE_ENDSTOP_BIT(X, MIN);
434
+          #if HAS_X2_MIN
435
+            UPDATE_ENDSTOP_BIT(X2, MIN);
436
+          #else
437
+            COPY_BIT(current_endstop_bits, X_MIN, X2_MIN);
438
+          #endif
439
+          test_dual_x_endstops(X_MIN, X2_MIN);
440
+        #else
441
+          if (X_MIN_TEST) UPDATE_ENDSTOP(X, MIN);
371 442
         #endif
372
-      }
443
+      #endif
373 444
     }
374
-    else if (X_MAX_TEST) { // +direction
445
+    else { // +direction
375 446
       #if HAS_X_MAX
376
-        UPDATE_ENDSTOP(X, MAX);
447
+        #if ENABLED(X_DUAL_ENDSTOPS)
448
+          UPDATE_ENDSTOP_BIT(X, MAX);
449
+          #if HAS_X2_MAX
450
+            UPDATE_ENDSTOP_BIT(X2, MAX);
451
+          #else
452
+            COPY_BIT(current_endstop_bits, X_MAX, X2_MAX);
453
+          #endif
454
+          test_dual_x_endstops(X_MAX, X2_MAX);
455
+        #else
456
+          if (X_MIN_TEST) UPDATE_ENDSTOP(X, MAX);
457
+        #endif
458
+
377 459
       #endif
378 460
     }
379 461
   }
@@ -381,12 +463,32 @@ void Endstops::update() {
381 463
   if (Y_MOVE_TEST) {
382 464
     if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
383 465
       #if HAS_Y_MIN
384
-        UPDATE_ENDSTOP(Y, MIN);
466
+        #if ENABLED(Y_DUAL_ENDSTOPS)
467
+          UPDATE_ENDSTOP_BIT(Y, MIN);
468
+          #if HAS_Y2_MIN
469
+            UPDATE_ENDSTOP_BIT(Y2, MIN);
470
+          #else
471
+            COPY_BIT(current_endstop_bits, Y_MIN, Y2_MIN);
472
+          #endif
473
+          test_dual_y_endstops(Y_MIN, Y2_MIN);
474
+        #else
475
+          UPDATE_ENDSTOP(Y, MIN);
476
+        #endif
385 477
       #endif
386 478
     }
387 479
     else { // +direction
388 480
       #if HAS_Y_MAX
389
-        UPDATE_ENDSTOP(Y, MAX);
481
+        #if ENABLED(Y_DUAL_ENDSTOPS)
482
+          UPDATE_ENDSTOP_BIT(Y, MAX);
483
+          #if HAS_Y2_MAX
484
+            UPDATE_ENDSTOP_BIT(Y2, MAX);
485
+          #else
486
+            COPY_BIT(current_endstop_bits, Y_MAX, Y2_MAX);
487
+          #endif
488
+          test_dual_y_endstops(Y_MAX, Y2_MAX);
489
+        #else
490
+          UPDATE_ENDSTOP(Y, MAX);
491
+        #endif
390 492
       #endif
391 493
     }
392 494
   }
@@ -395,27 +497,21 @@ void Endstops::update() {
395 497
     if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
396 498
       #if HAS_Z_MIN
397 499
         #if ENABLED(Z_DUAL_ENDSTOPS)
398
-
399 500
           UPDATE_ENDSTOP_BIT(Z, MIN);
400 501
           #if HAS_Z2_MIN
401 502
             UPDATE_ENDSTOP_BIT(Z2, MIN);
402 503
           #else
403 504
             COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
404 505
           #endif
405
-
406 506
           test_dual_z_endstops(Z_MIN, Z2_MIN);
407
-
408
-        #else // !Z_DUAL_ENDSTOPS
409
-
507
+        #else
410 508
           #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
411 509
             if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN);
412 510
           #else
413 511
             UPDATE_ENDSTOP(Z, MIN);
414 512
           #endif
415
-
416
-        #endif // !Z_DUAL_ENDSTOPS
417
-
418
-      #endif // HAS_Z_MIN
513
+        #endif
514
+      #endif
419 515
 
420 516
       // When closing the gap check the enabled probe
421 517
       #if ENABLED(Z_MIN_PROBE_ENDSTOP)
@@ -427,27 +523,21 @@ void Endstops::update() {
427 523
     }
428 524
     else { // Z +direction. Gantry up, bed down.
429 525
       #if HAS_Z_MAX
430
-
431 526
         // Check both Z dual endstops
432 527
         #if ENABLED(Z_DUAL_ENDSTOPS)
433
-
434 528
           UPDATE_ENDSTOP_BIT(Z, MAX);
435 529
           #if HAS_Z2_MAX
436 530
             UPDATE_ENDSTOP_BIT(Z2, MAX);
437 531
           #else
438 532
             COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
439 533
           #endif
440
-
441 534
           test_dual_z_endstops(Z_MAX, Z2_MAX);
442
-
443 535
         // If this pin is not hijacked for the bed probe
444 536
         // then it belongs to the Z endstop
445 537
         #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
446
-
447 538
           UPDATE_ENDSTOP(Z, MAX);
448
-
449
-        #endif // !Z_MIN_PROBE_PIN...
450
-      #endif // Z_MAX_PIN
539
+        #endif
540
+      #endif
451 541
     }
452 542
   }
453 543
 
@@ -496,6 +586,18 @@ void Endstops::update() {
496 586
     #if HAS_Z_MIN_PROBE_PIN
497 587
       if (READ(Z_MIN_PROBE_PIN)) SBI(current_endstop_bits_local, Z_MIN_PROBE);
498 588
     #endif
589
+    #if HAS_X2_MIN
590
+      if (READ(X2_MIN_PIN)) SBI(current_endstop_bits_local, X2_MIN);
591
+    #endif
592
+    #if HAS_X2_MAX
593
+      if (READ(X2_MAX_PIN)) SBI(current_endstop_bits_local, X2_MAX);
594
+    #endif
595
+    #if HAS_Y2_MIN
596
+      if (READ(Y2_MIN_PIN)) SBI(current_endstop_bits_local, Y2_MIN);
597
+    #endif
598
+    #if HAS_Y2_MAX
599
+      if (READ(Y2_MAX_PIN)) SBI(current_endstop_bits_local, Y2_MAX);
600
+    #endif
499 601
     #if HAS_Z2_MIN
500 602
       if (READ(Z2_MIN_PIN)) SBI(current_endstop_bits_local, Z2_MIN);
501 603
     #endif
@@ -527,6 +629,18 @@ void Endstops::update() {
527 629
       #if HAS_Z_MIN_PROBE_PIN
528 630
         if (TEST(endstop_change, Z_MIN_PROBE)) SERIAL_PROTOCOLPAIR("  PROBE:", !!TEST(current_endstop_bits_local, Z_MIN_PROBE));
529 631
       #endif
632
+      #if HAS_X2_MIN
633
+        if (TEST(endstop_change, X2_MIN)) SERIAL_PROTOCOLPAIR("  X2_MIN:", !!TEST(current_endstop_bits_local, X2_MIN));
634
+      #endif
635
+      #if HAS_X2_MAX
636
+        if (TEST(endstop_change, X2_MAX)) SERIAL_PROTOCOLPAIR("  X2_MAX:", !!TEST(current_endstop_bits_local, X2_MAX));
637
+      #endif
638
+      #if HAS_Y2_MIN
639
+        if (TEST(endstop_change, Y2_MIN)) SERIAL_PROTOCOLPAIR("  Y2_MIN:", !!TEST(current_endstop_bits_local, Y2_MIN));
640
+      #endif
641
+      #if HAS_Y2_MAX
642
+        if (TEST(endstop_change, Y2_MAX)) SERIAL_PROTOCOLPAIR("  Y2_MAX:", !!TEST(current_endstop_bits_local, Y2_MAX));
643
+      #endif
530 644
       #if HAS_Z2_MIN
531 645
         if (TEST(endstop_change, Z2_MIN)) SERIAL_PROTOCOLPAIR("  Z2_MIN:", !!TEST(current_endstop_bits_local, Z2_MIN));
532 646
       #endif

+ 18
- 0
Marlin/src/module/endstops.h Voir le fichier

@@ -38,6 +38,10 @@ enum EndstopEnum {
38 38
   X_MAX,
39 39
   Y_MAX,
40 40
   Z_MAX,
41
+  X2_MIN,
42
+  X2_MAX,
43
+  Y2_MIN,
44
+  Y2_MAX,
41 45
   Z2_MIN,
42 46
   Z2_MAX
43 47
 };
@@ -49,8 +53,16 @@ class Endstops {
49 53
     static bool enabled, enabled_globally;
50 54
     static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value
51 55
 
56
+    #if ENABLED(X_DUAL_ENDSTOPS)
57
+      static float x_endstop_adj;
58
+    #endif
59
+    #if ENABLED(Y_DUAL_ENDSTOPS)
60
+      static float y_endstop_adj;
61
+    #endif
52 62
     #if ENABLED(Z_DUAL_ENDSTOPS)
53 63
       static float z_endstop_adj;
64
+    #endif
65
+    #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
54 66
       typedef uint16_t esbits_t;
55 67
     #else
56 68
       typedef byte esbits_t;
@@ -113,6 +125,12 @@ class Endstops {
113 125
 
114 126
   private:
115 127
 
128
+    #if ENABLED(X_DUAL_ENDSTOPS)
129
+      static void test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2);
130
+    #endif
131
+    #if ENABLED(Y_DUAL_ENDSTOPS)
132
+      static void test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2);
133
+    #endif
116 134
     #if ENABLED(Z_DUAL_ENDSTOPS)
117 135
       static void test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2);
118 136
     #endif

+ 42
- 20
Marlin/src/module/motion.cpp Voir le fichier

@@ -1043,9 +1043,15 @@ void homeaxis(const AxisEnum axis) {
1043 1043
     if (axis == Z_AXIS && DEPLOY_PROBE()) return;
1044 1044
   #endif
1045 1045
 
1046
-  // Set a flag for Z motor locking
1046
+  // Set flags for X, Y, Z motor locking
1047
+  #if ENABLED(X_DUAL_ENDSTOPS)
1048
+    if (axis == X_AXIS) stepper.set_homing_flag_x(true);
1049
+  #endif
1050
+  #if ENABLED(Y_DUAL_ENDSTOPS)
1051
+    if (axis == Y_AXIS) stepper.set_homing_flag_y(true);
1052
+  #endif
1047 1053
   #if ENABLED(Z_DUAL_ENDSTOPS)
1048
-    if (axis == Z_AXIS) stepper.set_homing_flag(true);
1054
+    if (axis == Z_AXIS) stepper.set_homing_flag_z(true);
1049 1055
   #endif
1050 1056
 
1051 1057
   // Disable stealthChop if used. Enable diag1 pin on driver.
@@ -1087,25 +1093,41 @@ void homeaxis(const AxisEnum axis) {
1087 1093
     do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis));
1088 1094
   }
1089 1095
 
1090
-  #if ENABLED(Z_DUAL_ENDSTOPS)
1091
-    if (axis == Z_AXIS) {
1092
-      float adj = FABS(endstops.z_endstop_adj);
1093
-      bool lockZ1;
1094
-      if (axis_home_dir > 0) {
1095
-        adj = -adj;
1096
-        lockZ1 = (endstops.z_endstop_adj > 0);
1096
+  #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
1097
+    const bool pos_dir = axis_home_dir > 0;
1098
+    #if ENABLED(X_DUAL_ENDSTOPS)
1099
+      if (axis == X_AXIS) {
1100
+        const bool lock_x1 = pos_dir ? (endstops.x_endstop_adj > 0) : (endstops.x_endstop_adj < 0);
1101
+        float adj = FABS(endstops.x_endstop_adj);
1102
+        if (pos_dir) adj = -adj;
1103
+        if (lock_x1) stepper.set_x_lock(true); else stepper.set_x2_lock(true);
1104
+        do_homing_move(axis, adj);
1105
+        if (lock_x1) stepper.set_x_lock(false); else stepper.set_x2_lock(false);
1106
+        stepper.set_homing_flag_x(false);
1097 1107
       }
1098
-      else
1099
-        lockZ1 = (endstops.z_endstop_adj < 0);
1100
-
1101
-      if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
1102
-
1103
-      // Move to the adjusted endstop height
1104
-      do_homing_move(axis, adj);
1105
-
1106
-      if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false);
1107
-      stepper.set_homing_flag(false);
1108
-    } // Z_AXIS
1108
+    #endif
1109
+    #if ENABLED(Y_DUAL_ENDSTOPS)
1110
+      if (axis == Y_AXIS) {
1111
+        const bool lock_y1 = pos_dir ? (endstops.y_endstop_adj > 0) : (endstops.y_endstop_adj < 0);
1112
+        float adj = FABS(endstops.y_endstop_adj);
1113
+        if (pos_dir) adj = -adj;
1114
+        if (lock_y1) stepper.set_y_lock(true); else stepper.set_y2_lock(true);
1115
+        do_homing_move(axis, adj);
1116
+        if (lock_y1) stepper.set_y_lock(false); else stepper.set_y2_lock(false);
1117
+        stepper.set_homing_flag_y(false);
1118
+      }
1119
+    #endif
1120
+    #if ENABLED(Z_DUAL_ENDSTOPS)
1121
+      if (axis == Z_AXIS) {
1122
+        const bool lock_z1 = pos_dir ? (endstops.z_endstop_adj > 0) : (endstops.z_endstop_adj < 0);
1123
+        float adj = FABS(endstops.z_endstop_adj);
1124
+        if (pos_dir) adj = -adj;
1125
+        if (lock_z1) stepper.set_z_lock(true); else stepper.set_z2_lock(true);
1126
+        do_homing_move(axis, adj);
1127
+        if (lock_z1) stepper.set_z_lock(false); else stepper.set_z2_lock(false);
1128
+        stepper.set_homing_flag_z(false);
1129
+      }
1130
+    #endif
1109 1131
   #endif
1110 1132
 
1111 1133
   #if IS_SCARA

+ 63
- 35
Marlin/src/module/stepper.cpp Voir le fichier

@@ -83,7 +83,7 @@ block_t* Stepper::current_block = NULL;  // A pointer to the block currently bei
83 83
   bool Stepper::abort_on_endstop_hit = false;
84 84
 #endif
85 85
 
86
-#if ENABLED(Z_DUAL_ENDSTOPS)
86
+#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
87 87
   bool Stepper::performing_homing = false;
88 88
 #endif
89 89
 
@@ -96,6 +96,16 @@ block_t* Stepper::current_block = NULL;  // A pointer to the block currently bei
96 96
 uint8_t Stepper::last_direction_bits = 0;        // The next stepping-bits to be output
97 97
 uint16_t Stepper::cleaning_buffer_counter = 0;
98 98
 
99
+#if ENABLED(X_DUAL_ENDSTOPS)
100
+  bool Stepper::locked_x_motor = false;
101
+  bool Stepper::locked_x2_motor = false;
102
+#endif
103
+
104
+#if ENABLED(Y_DUAL_ENDSTOPS)
105
+  bool Stepper::locked_y_motor = false;
106
+  bool Stepper::locked_y2_motor = false;
107
+#endif
108
+
99 109
 #if ENABLED(Z_DUAL_ENDSTOPS)
100 110
   bool Stepper::locked_z_motor = false;
101 111
   bool Stepper::locked_z2_motor = false;
@@ -153,26 +163,54 @@ timer_t Stepper::OCR1A_nominal;
153 163
 
154 164
 volatile long Stepper::endstops_trigsteps[XYZ];
155 165
 
166
+#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
167
+  #define LOCKED_X_MOTOR  locked_x_motor
168
+  #define LOCKED_Y_MOTOR  locked_y_motor
169
+  #define LOCKED_Z_MOTOR  locked_z_motor
170
+  #define LOCKED_X2_MOTOR locked_x2_motor
171
+  #define LOCKED_Y2_MOTOR locked_y2_motor
172
+  #define LOCKED_Z2_MOTOR locked_z2_motor
173
+  #define DUAL_ENDSTOP_APPLY_STEP(AXIS,v)                                                                                                             \
174
+    if (performing_homing) {                                                                                                                          \
175
+      if (AXIS##_HOME_DIR < 0) {                                                                                                                      \
176
+        if (!(TEST(endstops.old_endstop_bits, AXIS##_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v);     \
177
+        if (!(TEST(endstops.old_endstop_bits, AXIS##2_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v);  \
178
+      }                                                                                                                                               \
179
+      else {                                                                                                                                          \
180
+        if (!(TEST(endstops.old_endstop_bits, AXIS##_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v);     \
181
+        if (!(TEST(endstops.old_endstop_bits, AXIS##2_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v);  \
182
+      }                                                                                                                                               \
183
+    }                                                                                                                                                 \
184
+    else {                                                                                                                                            \
185
+      AXIS##_STEP_WRITE(v);                                                                                                                           \
186
+      AXIS##2_STEP_WRITE(v);                                                                                                                          \
187
+    }
188
+#endif
189
+
156 190
 #if ENABLED(X_DUAL_STEPPER_DRIVERS)
157 191
   #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0)
158
-  #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0)
159
-#elif ENABLED(DUAL_X_CARRIAGE)
160
-  #define X_APPLY_DIR(v,ALWAYS) \
161
-    if (extruder_duplication_enabled || ALWAYS) { \
162
-      X_DIR_WRITE(v); \
163
-      X2_DIR_WRITE(v); \
164
-    } \
165
-    else { \
166
-      if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
167
-    }
168
-  #define X_APPLY_STEP(v,ALWAYS) \
169
-    if (extruder_duplication_enabled || ALWAYS) { \
170
-      X_STEP_WRITE(v); \
171
-      X2_STEP_WRITE(v); \
172
-    } \
173
-    else { \
174
-      if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
175
-    }
192
+  #if ENABLED(DUAL_X_CARRIAGE)
193
+    #define X_APPLY_DIR(v,ALWAYS) \
194
+      if (extruder_duplication_enabled || ALWAYS) { \
195
+        X_DIR_WRITE(v); \
196
+        X2_DIR_WRITE(v); \
197
+      } \
198
+      else { \
199
+        if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \
200
+      }
201
+    #define X_APPLY_STEP(v,ALWAYS) \
202
+      if (extruder_duplication_enabled || ALWAYS) { \
203
+        X_STEP_WRITE(v); \
204
+        X2_STEP_WRITE(v); \
205
+      } \
206
+      else { \
207
+        if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \
208
+      }
209
+  #elif ENABLED(X_DUAL_ENDSTOPS)
210
+    #define X_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(X,v)
211
+  #else
212
+    #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0)
213
+  #endif
176 214
 #else
177 215
   #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v)
178 216
   #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v)
@@ -180,7 +218,11 @@ volatile long Stepper::endstops_trigsteps[XYZ];
180 218
 
181 219
 #if ENABLED(Y_DUAL_STEPPER_DRIVERS)
182 220
   #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0)
183
-  #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0)
221
+  #if ENABLED(Y_DUAL_ENDSTOPS)
222
+    #define Y_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Y,v)
223
+  #else
224
+    #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0)
225
+  #endif
184 226
 #else
185 227
   #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v)
186 228
   #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v)
@@ -189,21 +231,7 @@ volatile long Stepper::endstops_trigsteps[XYZ];
189 231
 #if ENABLED(Z_DUAL_STEPPER_DRIVERS)
190 232
   #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0)
191 233
   #if ENABLED(Z_DUAL_ENDSTOPS)
192
-    #define Z_APPLY_STEP(v,Q) \
193
-    if (performing_homing) { \
194
-      if (Z_HOME_DIR < 0) { \
195
-        if (!(TEST(endstops.old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
196
-        if (!(TEST(endstops.old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
197
-      } \
198
-      else { \
199
-        if (!(TEST(endstops.old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \
200
-        if (!(TEST(endstops.old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \
201
-      } \
202
-    } \
203
-    else { \
204
-      Z_STEP_WRITE(v); \
205
-      Z2_STEP_WRITE(v); \
206
-    }
234
+    #define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v)
207 235
   #else
208 236
     #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0)
209 237
   #endif

+ 20
- 2
Marlin/src/module/stepper.h Voir le fichier

@@ -66,7 +66,7 @@ class Stepper {
66 66
       static bool abort_on_endstop_hit;
67 67
     #endif
68 68
 
69
-    #if ENABLED(Z_DUAL_ENDSTOPS)
69
+    #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
70 70
       static bool performing_homing;
71 71
     #endif
72 72
 
@@ -82,6 +82,12 @@ class Stepper {
82 82
     static uint8_t last_direction_bits;        // The next stepping-bits to be output
83 83
     static uint16_t cleaning_buffer_counter;
84 84
 
85
+    #if ENABLED(X_DUAL_ENDSTOPS)
86
+      static bool locked_x_motor, locked_x2_motor;
87
+    #endif
88
+    #if ENABLED(Y_DUAL_ENDSTOPS)
89
+      static bool locked_y_motor, locked_y2_motor;
90
+    #endif
85 91
     #if ENABLED(Z_DUAL_ENDSTOPS)
86 92
       static bool locked_z_motor, locked_z2_motor;
87 93
     #endif
@@ -227,8 +233,20 @@ class Stepper {
227 233
       static void microstep_readings();
228 234
     #endif
229 235
 
236
+    #if ENABLED(X_DUAL_ENDSTOPS)
237
+      static FORCE_INLINE void set_homing_flag_x(const bool state) { performing_homing = state; }
238
+      static FORCE_INLINE void set_x_lock(const bool state) { locked_x_motor = state; }
239
+      static FORCE_INLINE void set_x2_lock(const bool state) { locked_x2_motor = state; }
240
+    #endif
241
+
242
+    #if ENABLED(Y_DUAL_ENDSTOPS)
243
+      static FORCE_INLINE void set_homing_flag_y(const bool state) { performing_homing = state; }
244
+      static FORCE_INLINE void set_y_lock(const bool state) { locked_y_motor = state; }
245
+      static FORCE_INLINE void set_y2_lock(const bool state) { locked_y2_motor = state; }
246
+    #endif
247
+
230 248
     #if ENABLED(Z_DUAL_ENDSTOPS)
231
-      static FORCE_INLINE void set_homing_flag(const bool state) { performing_homing = state; }
249
+      static FORCE_INLINE void set_homing_flag_z(const bool state) { performing_homing = state; }
232 250
       static FORCE_INLINE void set_z_lock(const bool state) { locked_z_motor = state; }
233 251
       static FORCE_INLINE void set_z2_lock(const bool state) { locked_z2_motor = state; }
234 252
     #endif

Chargement…
Annuler
Enregistrer