diff --git a/.travis.yml b/.travis.yml index e901ec3364..ea6aad9e6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -177,7 +177,7 @@ script: # - restore_configs - opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR SDSUPPORT - - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 + - opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632 USE_XMAX_PLUG - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS - opt_set_adv I2C_SLAVE_ADDRESS 63 - opt_enable_adv ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE LCD_INFO_MENU @@ -434,7 +434,7 @@ script: - restore_configs - opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS - pins_set RAMPS X_MAX_PIN -1 - - opt_set_adv Z2_MAX_PIN 2 + - opt_add_adv Z2_MAX_PIN 2 - build_marlin_pio ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM} ############################# diff --git a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h index d78ee97510..8bd6f0081d 100644 --- a/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h +++ b/Marlin/src/HAL/HAL_AVR/endstop_interrupts.h @@ -161,6 +161,46 @@ void setup_endstop_interrupts( void ) { #endif #endif + #if HAS_X2_MAX + #if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(X2_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X2_MAX_PIN) != NULL, "X2_MAX_PIN is not interrupt-capable"); + pciSetup(X2_MAX_PIN); + #endif + #endif + + #if HAS_X2_MIN + #if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(X2_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(X2_MIN_PIN) != NULL, "X2_MIN_PIN is not interrupt-capable"); + pciSetup(X2_MIN_PIN); + #endif + #endif + + #if HAS_Y2_MAX + #if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y2_MAX_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y2_MAX_PIN) != NULL, "Y2_MAX_PIN is not interrupt-capable"); + pciSetup(Y2_MAX_PIN); + #endif + #endif + + #if HAS_Y2_MIN + #if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT) + attachInterrupt(digitalPinToInterrupt(Y2_MIN_PIN), endstop_ISR, CHANGE); + #else + // Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration! + static_assert(digitalPinToPCICR(Y2_MIN_PIN) != NULL, "Y2_MIN_PIN is not interrupt-capable"); + pciSetup(Y2_MIN_PIN); + #endif + #endif + #if HAS_Z2_MAX #if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT) attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE); diff --git a/Marlin/src/core/language.h b/Marlin/src/core/language.h index b485a3c7c0..1cb6e02d82 100644 --- a/Marlin/src/core/language.h +++ b/Marlin/src/core/language.h @@ -150,8 +150,12 @@ #define MSG_ACTIVE_EXTRUDER "Active Extruder: " #define MSG_X_MIN "x_min: " #define MSG_X_MAX "x_max: " +#define MSG_X2_MIN "x2_min: " +#define MSG_X2_MAX "x2_max: " #define MSG_Y_MIN "y_min: " #define MSG_Y_MAX "y_max: " +#define MSG_Y2_MIN "y2_min: " +#define MSG_Y2_MAX "y2_max: " #define MSG_Z_MIN "z_min: " #define MSG_Z_MAX "z_max: " #define MSG_Z2_MIN "z2_min: " diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index a89b6dafce..1265ddbbc8 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -28,6 +28,13 @@ #define ABC 3 #define XYZ 3 +#define _XMIN_ 100 +#define _YMIN_ 200 +#define _ZMIN_ 300 +#define _XMAX_ 101 +#define _YMAX_ 201 +#define _ZMAX_ 301 + #define FORCE_INLINE __attribute__((always_inline)) inline #define _UNUSED __attribute__((unused)) #define _O0 __attribute__((optimize("O0"))) diff --git a/Marlin/src/gcode/calibrate/M666.cpp b/Marlin/src/gcode/calibrate/M666.cpp index bba2661410..96688f2bbf 100644 --- a/Marlin/src/gcode/calibrate/M666.cpp +++ b/Marlin/src/gcode/calibrate/M666.cpp @@ -64,11 +64,23 @@ #include "../../module/endstops.h" /** - * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis. + * M666: For a Dual Endstop setup, set offsets for any 2nd endstops. */ void GcodeSuite::M666() { - if (parser.seen('Z')) endstops.z_endstop_adj = parser.value_linear_units(); - SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", endstops.z_endstop_adj); + SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): "); + #if ENABLED(X_DUAL_ENDSTOPS) + if (parser.seen('X')) endstops.x_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" X", endstops.x_endstop_adj); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (parser.seen('Y')) endstops.y_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" Y", endstops.y_endstop_adj); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + if (parser.seen('Z')) endstops.z_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" Z", endstops.z_endstop_adj); + #endif + SERIAL_EOL(); } #endif diff --git a/Marlin/src/inc/Conditionals_post.h b/Marlin/src/inc/Conditionals_post.h index 8a71a9d4a6..06f9a54594 100644 --- a/Marlin/src/inc/Conditionals_post.h +++ b/Marlin/src/inc/Conditionals_post.h @@ -422,29 +422,122 @@ #define ARRAY_BY_HOTENDS(...) ARRAY_N(HOTENDS, __VA_ARGS__) #define ARRAY_BY_HOTENDS1(v1) ARRAY_BY_HOTENDS(v1, v1, v1, v1, v1, v1) +/** + * X_DUAL_ENDSTOPS endstop reassignment + */ +#if ENABLED(X_DUAL_ENDSTOPS) + #if X_HOME_DIR > 0 + #if X2_USE_ENDSTOP == _XMIN_ + #define X2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define X2_MAX_PIN X_MIN_PIN + #elif X2_USE_ENDSTOP == _XMAX_ + #define X2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define X2_MAX_PIN X_MAX_PIN + #elif X2_USE_ENDSTOP == _YMIN_ + #define X2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define X2_MAX_PIN Y_MIN_PIN + #elif X2_USE_ENDSTOP == _YMAX_ + #define X2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define X2_MAX_PIN Y_MAX_PIN + #elif X2_USE_ENDSTOP == _ZMIN_ + #define X2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define X2_MAX_PIN Z_MIN_PIN + #elif X2_USE_ENDSTOP == _ZMAX_ + #define X2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define X2_MAX_PIN Z_MAX_PIN + #else + #define X2_MAX_ENDSTOP_INVERTING false + #endif + #define X2_MIN_ENDSTOP_INVERTING false + #else + #if X2_USE_ENDSTOP == _XMIN_ + #define X2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define X2_MIN_PIN X_MIN_PIN + #elif X2_USE_ENDSTOP == _XMAX_ + #define X2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define X2_MIN_PIN X_MAX_PIN + #elif X2_USE_ENDSTOP == _YMIN_ + #define X2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define X2_MIN_PIN Y_MIN_PIN + #elif X2_USE_ENDSTOP == _YMAX_ + #define X2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define X2_MIN_PIN Y_MAX_PIN + #elif X2_USE_ENDSTOP == _ZMIN_ + #define X2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define X2_MIN_PIN Z_MIN_PIN + #elif X2_USE_ENDSTOP == _ZMAX_ + #define X2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define X2_MIN_PIN Z_MAX_PIN + #else + #define X2_MIN_ENDSTOP_INVERTING false + #endif + #define X2_MAX_ENDSTOP_INVERTING false + #endif +#endif + +// Is an endstop plug used for the X2 endstop? +#define IS_X2_ENDSTOP(A,M) (ENABLED(X_DUAL_ENDSTOPS) && X2_USE_ENDSTOP == _##A##M##_) + +/** + * Y_DUAL_ENDSTOPS endstop reassignment + */ +#if ENABLED(Y_DUAL_ENDSTOPS) + #if Y_HOME_DIR > 0 + #if Y2_USE_ENDSTOP == _XMIN_ + #define Y2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Y2_MAX_PIN X_MIN_PIN + #elif Y2_USE_ENDSTOP == _XMAX_ + #define Y2_MAX_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Y2_MAX_PIN X_MAX_PIN + #elif Y2_USE_ENDSTOP == _YMIN_ + #define Y2_MAX_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Y2_MAX_PIN Y_MIN_PIN + #elif Y2_USE_ENDSTOP == _YMAX_ + #define Y2_MAX_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Y2_MAX_PIN Y_MAX_PIN + #elif Y2_USE_ENDSTOP == _ZMIN_ + #define Y2_MAX_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Y2_MAX_PIN Z_MIN_PIN + #elif Y2_USE_ENDSTOP == _ZMAX_ + #define Y2_MAX_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Y2_MAX_PIN Z_MAX_PIN + #else + #define Y2_MAX_ENDSTOP_INVERTING false + #endif + #define Y2_MIN_ENDSTOP_INVERTING false + #else + #if Y2_USE_ENDSTOP == _XMIN_ + #define Y2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Y2_MIN_PIN X_MIN_PIN + #elif Y2_USE_ENDSTOP == _XMAX_ + #define Y2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Y2_MIN_PIN X_MAX_PIN + #elif Y2_USE_ENDSTOP == _YMIN_ + #define Y2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Y2_MIN_PIN Y_MIN_PIN + #elif Y2_USE_ENDSTOP == _YMAX_ + #define Y2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Y2_MIN_PIN Y_MAX_PIN + #elif Y2_USE_ENDSTOP == _ZMIN_ + #define Y2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Y2_MIN_PIN Z_MIN_PIN + #elif Y2_USE_ENDSTOP == _ZMAX_ + #define Y2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Y2_MIN_PIN Z_MAX_PIN + #else + #define Y2_MIN_ENDSTOP_INVERTING false + #endif + #define Y2_MAX_ENDSTOP_INVERTING false + #endif +#endif + +// Is an endstop plug used for the Y2 endstop or the bed probe? +#define IS_Y2_ENDSTOP(A,M) (ENABLED(Y_DUAL_ENDSTOPS) && Y2_USE_ENDSTOP == _##A##M##_) + /** * Z_DUAL_ENDSTOPS endstop reassignment */ #if ENABLED(Z_DUAL_ENDSTOPS) - #define _XMIN_ 100 - #define _YMIN_ 200 - #define _ZMIN_ 300 - #define _XMAX_ 101 - #define _YMAX_ 201 - #define _ZMAX_ 301 - #if Z2_USE_ENDSTOP == _XMIN_ - #define USE_XMIN_PLUG - #elif Z2_USE_ENDSTOP == _XMAX_ - #define USE_XMAX_PLUG - #elif Z2_USE_ENDSTOP == _YMIN_ - #define USE_YMIN_PLUG - #elif Z2_USE_ENDSTOP == _YMAX_ - #define USE_YMAX_PLUG - #elif Z2_USE_ENDSTOP == _ZMIN_ - #define USE_ZMIN_PLUG - #elif Z2_USE_ENDSTOP == _ZMAX_ - #define USE_ZMAX_PLUG - #endif #if Z_HOME_DIR > 0 #if Z2_USE_ENDSTOP == _XMIN_ #define Z2_MAX_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING @@ -467,6 +560,7 @@ #else #define Z2_MAX_ENDSTOP_INVERTING false #endif + #define Z2_MIN_ENDSTOP_INVERTING false #else #if Z2_USE_ENDSTOP == _XMIN_ #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING @@ -489,6 +583,7 @@ #else #define Z2_MIN_ENDSTOP_INVERTING false #endif + #define Z2_MAX_ENDSTOP_INVERTING false #endif #endif @@ -585,12 +680,16 @@ #define HAS_SOLENOID_4 (PIN_EXISTS(SOL4)) // Endstops and bed probe -#define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_Z2_OR_PROBE(X,MIN)) -#define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_Z2_OR_PROBE(X,MAX)) -#define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_Z2_OR_PROBE(Y,MIN)) -#define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_Z2_OR_PROBE(Y,MAX)) -#define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_Z2_OR_PROBE(Z,MIN)) -#define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_Z2_OR_PROBE(Z,MAX)) +#define HAS_X_MIN (PIN_EXISTS(X_MIN) && !IS_X2_ENDSTOP(X,MIN) && !IS_Y2_ENDSTOP(X,MIN) && !IS_Z2_OR_PROBE(X,MIN)) +#define HAS_X_MAX (PIN_EXISTS(X_MAX) && !IS_X2_ENDSTOP(X,MAX) && !IS_Y2_ENDSTOP(X,MAX) && !IS_Z2_OR_PROBE(X,MAX)) +#define HAS_Y_MIN (PIN_EXISTS(Y_MIN) && !IS_X2_ENDSTOP(Y,MIN) && !IS_Y2_ENDSTOP(Y,MIN) && !IS_Z2_OR_PROBE(Y,MIN)) +#define HAS_Y_MAX (PIN_EXISTS(Y_MAX) && !IS_X2_ENDSTOP(Y,MAX) && !IS_Y2_ENDSTOP(Y,MAX) && !IS_Z2_OR_PROBE(Y,MAX)) +#define HAS_Z_MIN (PIN_EXISTS(Z_MIN) && !IS_X2_ENDSTOP(Z,MIN) && !IS_Y2_ENDSTOP(Z,MIN) && !IS_Z2_OR_PROBE(Z,MIN)) +#define HAS_Z_MAX (PIN_EXISTS(Z_MAX) && !IS_X2_ENDSTOP(Z,MAX) && !IS_Y2_ENDSTOP(Z,MAX) && !IS_Z2_OR_PROBE(Z,MAX)) +#define HAS_X2_MIN (PIN_EXISTS(X2_MIN)) +#define HAS_X2_MAX (PIN_EXISTS(X2_MAX)) +#define HAS_Y2_MIN (PIN_EXISTS(Y2_MIN)) +#define HAS_Y2_MAX (PIN_EXISTS(Y2_MAX)) #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN)) #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX)) #define HAS_Z_MIN_PROBE_PIN (PIN_EXISTS(Z_MIN_PROBE)) diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 0da0f42684..fec4223a25 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -81,8 +81,6 @@ #error "FILAMENT_SENSOR is deprecated. Use FILAMENT_WIDTH_SENSOR instead." #elif defined(DISABLE_MAX_ENDSTOPS) || defined(DISABLE_MIN_ENDSTOPS) #error "DISABLE_MAX_ENDSTOPS and DISABLE_MIN_ENDSTOPS deprecated. Use individual USE_*_PLUG options instead." -#elif ENABLED(Z_DUAL_ENDSTOPS) && !defined(Z2_USE_ENDSTOP) - #error "Z_DUAL_ENDSTOPS settings are simplified. Just set Z2_USE_ENDSTOP to the endstop you want to repurpose for Z2." #elif defined(LANGUAGE_INCLUDE) #error "LANGUAGE_INCLUDE has been replaced by LCD_LANGUAGE. Please update your configuration." #elif defined(EXTRUDER_OFFSET_X) || defined(EXTRUDER_OFFSET_Y) @@ -1081,23 +1079,25 @@ static_assert(1 >= 0 #endif /** - * Endstops + * Endstop Tests */ -#if DISABLED(USE_XMIN_PLUG) && DISABLED(USE_XMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _XMAX_, _XMIN_)) - #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG." -#elif DISABLED(USE_YMIN_PLUG) && DISABLED(USE_YMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _YMAX_, _YMIN_)) - #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG." -#elif DISABLED(USE_ZMIN_PLUG) && DISABLED(USE_ZMAX_PLUG) && !(ENABLED(Z_DUAL_ENDSTOPS) && WITHIN(Z2_USE_ENDSTOP, _ZMAX_, _ZMIN_)) - #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG." -#elif ENABLED(Z_DUAL_ENDSTOPS) - #if !Z2_USE_ENDSTOP - #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS." - #elif Z2_MAX_PIN == 0 && Z2_MIN_PIN == 0 - #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!" - #elif ENABLED(DELTA) - #error "Z_DUAL_ENDSTOPS is not compatible with DELTA." - #endif -#elif !IS_SCARA + +#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_))) +#define _AXIS_PLUG_UNUSED_TEST(AXIS) (_PLUG_UNUSED_TEST(AXIS,X) && _PLUG_UNUSED_TEST(AXIS,Y) && _PLUG_UNUSED_TEST(AXIS,Z)) + +// At least 3 endstop plugs must be used +#if _AXIS_PLUG_UNUSED_TEST(X) + #error "You must enable USE_XMIN_PLUG or USE_XMAX_PLUG." +#endif +#if _AXIS_PLUG_UNUSED_TEST(Y) + #error "You must enable USE_YMIN_PLUG or USE_YMAX_PLUG." +#endif +#if _AXIS_PLUG_UNUSED_TEST(Z) + #error "You must enable USE_ZMIN_PLUG or USE_ZMAX_PLUG." +#endif + +// Delta and Cartesian use 3 homing endstops +#if !IS_SCARA #if X_HOME_DIR < 0 && DISABLED(USE_XMIN_PLUG) #error "Enable USE_XMIN_PLUG when homing X to MIN." #elif X_HOME_DIR > 0 && DISABLED(USE_XMAX_PLUG) @@ -1106,10 +1106,76 @@ static_assert(1 >= 0 #error "Enable USE_YMIN_PLUG when homing Y to MIN." #elif Y_HOME_DIR > 0 && DISABLED(USE_YMAX_PLUG) #error "Enable USE_YMAX_PLUG when homing Y to MAX." - #elif Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG) - #error "Enable USE_ZMIN_PLUG when homing Z to MIN." - #elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG) - #error "Enable USE_ZMAX_PLUG when homing Z to MAX." + #endif +#endif +#if Z_HOME_DIR < 0 && DISABLED(USE_ZMIN_PLUG) + #error "Enable USE_ZMIN_PLUG when homing Z to MIN." +#elif Z_HOME_DIR > 0 && DISABLED(USE_ZMAX_PLUG) + #error "Enable USE_ZMAX_PLUG when homing Z to MAX." +#endif + +// Dual endstops requirements +#if ENABLED(X_DUAL_ENDSTOPS) + #if !X2_USE_ENDSTOP + #error "You must set X2_USE_ENDSTOP with X_DUAL_ENDSTOPS." + #elif X2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG) + #error "USE_XMIN_PLUG is required when X2_USE_ENDSTOP is _X_MIN_." + #elif X2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG) + #error "USE_XMAX_PLUG is required when X2_USE_ENDSTOP is _X_MAX_." + #elif X2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG) + #error "USE_YMIN_PLUG is required when X2_USE_ENDSTOP is _Y_MIN_." + #elif X2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG) + #error "USE_YMAX_PLUG is required when X2_USE_ENDSTOP is _Y_MAX_." + #elif X2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG) + #error "USE_ZMIN_PLUG is required when X2_USE_ENDSTOP is _Z_MIN_." + #elif X2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG) + #error "USE_ZMAX_PLUG is required when X2_USE_ENDSTOP is _Z_MAX_." + #elif !HAS_X2_MIN && !HAS_X2_MAX + #error "X2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "X_DUAL_ENDSTOPS is not compatible with DELTA." + #endif +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + #if !Y2_USE_ENDSTOP + #error "You must set Y2_USE_ENDSTOP with Y_DUAL_ENDSTOPS." + #elif Y2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG) + #error "USE_XMIN_PLUG is required when Y2_USE_ENDSTOP is _X_MIN_." + #elif Y2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG) + #error "USE_XMAX_PLUG is required when Y2_USE_ENDSTOP is _X_MAX_." + #elif Y2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG) + #error "USE_YMIN_PLUG is required when Y2_USE_ENDSTOP is _Y_MIN_." + #elif Y2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG) + #error "USE_YMAX_PLUG is required when Y2_USE_ENDSTOP is _Y_MAX_." + #elif Y2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG) + #error "USE_ZMIN_PLUG is required when Y2_USE_ENDSTOP is _Z_MIN_." + #elif Y2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG) + #error "USE_ZMAX_PLUG is required when Y2_USE_ENDSTOP is _Z_MAX_." + #elif !HAS_Y2_MIN && !HAS_Y2_MAX + #error "Y2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "Y_DUAL_ENDSTOPS is not compatible with DELTA." + #endif +#endif +#if ENABLED(Z_DUAL_ENDSTOPS) + #if !Z2_USE_ENDSTOP + #error "You must set Z2_USE_ENDSTOP with Z_DUAL_ENDSTOPS." + #elif Z2_USE_ENDSTOP == _X_MIN_ && DISABLED(USE_XMIN_PLUG) + #error "USE_XMIN_PLUG is required when Z2_USE_ENDSTOP is _X_MIN_." + #elif Z2_USE_ENDSTOP == _X_MAX_ && DISABLED(USE_XMAX_PLUG) + #error "USE_XMAX_PLUG is required when Z2_USE_ENDSTOP is _X_MAX_." + #elif Z2_USE_ENDSTOP == _Y_MIN_ && DISABLED(USE_YMIN_PLUG) + #error "USE_YMIN_PLUG is required when Z2_USE_ENDSTOP is _Y_MIN_." + #elif Z2_USE_ENDSTOP == _Y_MAX_ && DISABLED(USE_YMAX_PLUG) + #error "USE_YMAX_PLUG is required when Z2_USE_ENDSTOP is _Y_MAX_." + #elif Z2_USE_ENDSTOP == _Z_MIN_ && DISABLED(USE_ZMIN_PLUG) + #error "USE_ZMIN_PLUG is required when Z2_USE_ENDSTOP is _Z_MIN_." + #elif Z2_USE_ENDSTOP == _Z_MAX_ && DISABLED(USE_ZMAX_PLUG) + #error "USE_ZMAX_PLUG is required when Z2_USE_ENDSTOP is _Z_MAX_." + #elif !HAS_Z2_MIN && !HAS_Z2_MAX + #error "Z2_USE_ENDSTOP has been assigned to a nonexistent endstop!" + #elif ENABLED(DELTA) + #error "Z_DUAL_ENDSTOPS is not compatible with DELTA." #endif #endif diff --git a/Marlin/src/module/configuration_store.cpp b/Marlin/src/module/configuration_store.cpp index 99d9eb9f4d..2b67ad5024 100644 --- a/Marlin/src/module/configuration_store.cpp +++ b/Marlin/src/module/configuration_store.cpp @@ -36,13 +36,13 @@ * */ -#define EEPROM_VERSION "V42" +#define EEPROM_VERSION "V43" // Change EEPROM version if these are changed: #define EEPROM_OFFSET 100 /** - * V42 EEPROM Layout: + * V43 EEPROM Layout: * * 100 Version (char x4) * 104 EEPROM CRC16 (uint16_t) @@ -68,7 +68,7 @@ * 219 z_fade_height (float) * * MESH_BED_LEVELING: 43 bytes - * 223 M420 S planner.leveling_active (bool) + * 223 M420 S planner.leveling_active (bool) * 224 mbl.z_offset (float) * 228 GRID_MAX_POINTS_X (uint8_t) * 229 GRID_MAX_POINTS_Y (uint8_t) @@ -91,78 +91,79 @@ * 324 G29 A planner.leveling_active (bool) * 325 G29 S ubl.storage_slot (int8_t) * - * DELTA: 48 bytes - * 344 M666 XYZ delta_endstop_adj (float x3) - * 360 M665 R delta_radius (float) - * 364 M665 L delta_diagonal_rod (float) - * 368 M665 S delta_segments_per_second (float) - * 372 M665 B delta_calibration_radius (float) - * 376 M665 X delta_tower_angle_trim[A] (float) - * 380 M665 Y delta_tower_angle_trim[B] (float) - * 384 M665 Z delta_tower_angle_trim[C] (float) + * DELTA: 40 bytes + * 352 M666 XYZ delta_endstop_adj (float x3) + * 364 M665 R delta_radius (float) + * 368 M665 L delta_diagonal_rod (float) + * 372 M665 S delta_segments_per_second (float) + * 376 M665 B delta_calibration_radius (float) + * 380 M665 X delta_tower_angle_trim[A] (float) + * 384 M665 Y delta_tower_angle_trim[B] (float) + * 388 M665 Z delta_tower_angle_trim[C] (float) * - * Z_DUAL_ENDSTOPS: 48 bytes - * 348 M666 Z endstops.z_endstop_adj (float) - * --- dummy data (float x11) + * [XYZ]_DUAL_ENDSTOPS: 12 bytes + * 352 M666 X endstops.x_endstop_adj (float) + * 356 M666 Y endstops.y_endstop_adj (float) + * 360 M666 Z endstops.z_endstop_adj (float) * * ULTIPANEL: 6 bytes - * 396 M145 S0 H lcd_preheat_hotend_temp (int x2) - * 400 M145 S0 B lcd_preheat_bed_temp (int x2) - * 404 M145 S0 F lcd_preheat_fan_speed (int x2) + * 392 M145 S0 H lcd_preheat_hotend_temp (int x2) + * 396 M145 S0 B lcd_preheat_bed_temp (int x2) + * 400 M145 S0 F lcd_preheat_fan_speed (int x2) * - * PIDTEMP: 66 bytes - * 408 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) - * 424 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) - * 440 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) - * 456 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) - * 472 M301 E4 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) - * 488 M301 L lpq_len (int) + * PIDTEMP: 82 bytes + * 404 M301 E0 PIDC Kp[0], Ki[0], Kd[0], Kc[0] (float x4) + * 420 M301 E1 PIDC Kp[1], Ki[1], Kd[1], Kc[1] (float x4) + * 436 M301 E2 PIDC Kp[2], Ki[2], Kd[2], Kc[2] (float x4) + * 452 M301 E3 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 468 M301 E4 PIDC Kp[3], Ki[3], Kd[3], Kc[3] (float x4) + * 484 M301 L lpq_len (int) * * PIDTEMPBED: 12 bytes - * 490 M304 PID thermalManager.bedKp, .bedKi, .bedKd (float x3) + * 486 M304 PID thermalManager.bedKp, .bedKi, .bedKd (float x3) * * DOGLCD: 2 bytes - * 502 M250 C lcd_contrast (uint16_t) + * 498 M250 C lcd_contrast (uint16_t) * * FWRETRACT: 33 bytes - * 504 M209 S autoretract_enabled (bool) - * 505 M207 S retract_length (float) - * 509 M207 F retract_feedrate_mm_s (float) - * 513 M207 Z retract_zlift (float) - * 517 M208 S retract_recover_length (float) - * 521 M208 F retract_recover_feedrate_mm_s (float) - * 525 M207 W swap_retract_length (float) - * 529 M208 W swap_retract_recover_length (float) - * 533 M208 R swap_retract_recover_feedrate_mm_s (float) + * 500 M209 S autoretract_enabled (bool) + * 501 M207 S retract_length (float) + * 505 M207 F retract_feedrate_mm_s (float) + * 509 M207 Z retract_zlift (float) + * 513 M208 S retract_recover_length (float) + * 517 M208 F retract_recover_feedrate_mm_s (float) + * 521 M207 W swap_retract_length (float) + * 525 M208 W swap_retract_recover_length (float) + * 529 M208 R swap_retract_recover_feedrate_mm_s (float) * * Volumetric Extrusion: 21 bytes - * 537 M200 D parser.volumetric_enabled (bool) - * 538 M200 T D planner.filament_size (float x5) (T0..3) + * 533 M200 D volumetric_enabled (bool) + * 534 M200 T D filament_size (float x5) (T0..3) * - * HAVE_TMC2130: 20 bytes - * 558 M906 X Stepper X current (uint16_t) - * 560 M906 Y Stepper Y current (uint16_t) - * 562 M906 Z Stepper Z current (uint16_t) - * 564 M906 X2 Stepper X2 current (uint16_t) - * 566 M906 Y2 Stepper Y2 current (uint16_t) - * 568 M906 Z2 Stepper Z2 current (uint16_t) - * 570 M906 E0 Stepper E0 current (uint16_t) - * 572 M906 E1 Stepper E1 current (uint16_t) - * 574 M906 E2 Stepper E2 current (uint16_t) - * 576 M906 E3 Stepper E3 current (uint16_t) - * 580 M906 E4 Stepper E4 current (uint16_t) + * HAVE_TMC2130: 22 bytes + * 554 M906 X Stepper X current (uint16_t) + * 556 M906 Y Stepper Y current (uint16_t) + * 558 M906 Z Stepper Z current (uint16_t) + * 560 M906 X2 Stepper X2 current (uint16_t) + * 562 M906 Y2 Stepper Y2 current (uint16_t) + * 564 M906 Z2 Stepper Z2 current (uint16_t) + * 566 M906 E0 Stepper E0 current (uint16_t) + * 568 M906 E1 Stepper E1 current (uint16_t) + * 570 M906 E2 Stepper E2 current (uint16_t) + * 572 M906 E3 Stepper E3 current (uint16_t) + * 574 M906 E4 Stepper E4 current (uint16_t) * * LIN_ADVANCE: 8 bytes - * 584 M900 K extruder_advance_k (float) - * 588 M900 WHD advance_ed_ratio (float) + * 576 M900 K extruder_advance_k (float) + * 580 M900 WHD advance_ed_ratio (float) * * HAS_MOTOR_CURRENT_PWM: - * 592 M907 X Stepper XY current (uint32_t) - * 596 M907 Z Stepper Z current (uint32_t) - * 600 M907 E Stepper E current (uint32_t) + * 584 M907 X Stepper XY current (uint32_t) + * 588 M907 Z Stepper Z current (uint32_t) + * 592 M907 E Stepper E current (uint32_t) * - * 604 Minimum end-point - * 1925 (604 + 36 + 9 + 288 + 988) Maximum end-point + * 596 Minimum end-point + * 1917 (596 + 36 + 9 + 288 + 988) Maximum end-point * * ======================================================================== * meshes_begin (between max and min end-point, directly above) @@ -419,7 +420,7 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(storage_slot); #endif // AUTO_BED_LEVELING_UBL - // 10 floats for DELTA / Z_DUAL_ENDSTOPS + // 10 floats for DELTA / [XYZ]_DUAL_ENDSTOPS #if ENABLED(DELTA) EEPROM_WRITE(delta_endstop_adj); // 3 floats EEPROM_WRITE(delta_radius); // 1 float @@ -427,15 +428,33 @@ void MarlinSettings::postprocess() { EEPROM_WRITE(delta_segments_per_second); // 1 float EEPROM_WRITE(delta_calibration_radius); // 1 float EEPROM_WRITE(delta_tower_angle_trim); // 3 floats + + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + // Write dual endstops in X, Y, Z order. Unused = 0.0 dummy = 0.0f; - for (uint8_t q = 2; q--;) EEPROM_WRITE(dummy); - #elif ENABLED(Z_DUAL_ENDSTOPS) - EEPROM_WRITE(endstops.z_endstop_adj); // 1 float - dummy = 0.0f; - for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy); + #if ENABLED(X_DUAL_ENDSTOPS) + EEPROM_WRITE(endstops.x_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(Y_DUAL_ENDSTOPS) + EEPROM_WRITE(endstops.y_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_WRITE(endstops.z_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + for (uint8_t q = 7; q--;) EEPROM_WRITE(dummy); + #else dummy = 0.0f; - for (uint8_t q = 12; q--;) EEPROM_WRITE(dummy); + for (uint8_t q = 10; q--;) EEPROM_WRITE(dummy); #endif #if DISABLED(ULTIPANEL) @@ -638,6 +657,7 @@ void MarlinSettings::postprocess() { if (ubl.storage_slot >= 0) store_mesh(ubl.storage_slot); #endif + return !eeprom_error; } @@ -814,13 +834,31 @@ void MarlinSettings::postprocess() { EEPROM_READ(delta_tower_angle_trim); // 3 floats dummy = 0.0f; for (uint8_t q=2; q--;) EEPROM_READ(dummy); - #elif ENABLED(Z_DUAL_ENDSTOPS) - EEPROM_READ(endstops.z_endstop_adj); // 1 float - dummy = 0.0f; - for (uint8_t q=11; q--;) EEPROM_READ(dummy); + + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + + #if ENABLED(X_DUAL_ENDSTOPS) + EEPROM_READ(endstops.x_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + EEPROM_READ(endstops.y_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_READ(endstops.z_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + + for (uint8_t q=7; q--;) EEPROM_READ(dummy); + #else - dummy = 0.0f; - for (uint8_t q=12; q--;) EEPROM_READ(dummy); + + for (uint8_t q=10; q--;) EEPROM_READ(dummy); + #endif #if DISABLED(ULTIPANEL) @@ -1218,15 +1256,35 @@ void MarlinSettings::reset() { COPY(delta_tower_angle_trim, dta); home_offset[Z_AXIS] = 0; - #elif ENABLED(Z_DUAL_ENDSTOPS) + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) - endstops.z_endstop_adj = - #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT - Z_DUAL_ENDSTOPS_ADJUSTMENT - #else - 0 - #endif - ; + #if ENABLED(X_DUAL_ENDSTOPS) + endstops.x_endstop_adj = ( + #ifdef X_DUAL_ENDSTOPS_ADJUSTMENT + X_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + endstops.y_endstop_adj = ( + #ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT + Y_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + endstops.z_endstop_adj = ( + #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT + Z_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif #endif @@ -1627,13 +1685,24 @@ void MarlinSettings::reset() { SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(delta_tower_angle_trim[B_AXIS])); SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(delta_tower_angle_trim[C_AXIS])); SERIAL_EOL(); - #elif ENABLED(Z_DUAL_ENDSTOPS) + + #elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) if (!forReplay) { CONFIG_ECHO_START; - SERIAL_ECHOLNPGM("Z2 Endstop adjustment:"); + SERIAL_ECHOLNPGM("Endstop adjustment:"); } CONFIG_ECHO_START; - SERIAL_ECHOLNPAIR(" M666 Z", LINEAR_UNIT(endstops.z_endstop_adj)); + SERIAL_ECHOPGM(" M666"); + #if ENABLED(X_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" X", LINEAR_UNIT(endstops.x_endstop_adj)); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(endstops.y_endstop_adj)); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(endstops.z_endstop_adj)); + #endif + SERIAL_EOL(); #endif // DELTA #if ENABLED(ULTIPANEL) @@ -1738,7 +1807,7 @@ void MarlinSettings::reset() { #endif // FWRETRACT /** - * Auto Bed Leveling + * Probe Offset */ #if HAS_BED_PROBE if (!forReplay) { diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index b194abd5df..dae888611c 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -42,7 +42,7 @@ Endstops endstops; bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load() volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value -#if ENABLED(Z_DUAL_ENDSTOPS) +#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) uint16_t #else byte @@ -54,8 +54,14 @@ volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_P volatile bool Endstops::z_probe_enabled = false; #endif +#if ENABLED(X_DUAL_ENDSTOPS) + float Endstops::x_endstop_adj; // Initialized by settings.load() +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + float Endstops::y_endstop_adj; // Initialized by settings.load() +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - float Endstops::z_endstop_adj; + float Endstops::z_endstop_adj; // Initialized by settings.load() #endif /** @@ -72,6 +78,14 @@ void Endstops::init() { #endif #endif + #if HAS_X2_MIN + #if ENABLED(ENDSTOPPULLUP_XMIN) + SET_INPUT_PULLUP(X2_MIN_PIN); + #else + SET_INPUT(X2_MIN_PIN); + #endif + #endif + #if HAS_Y_MIN #if ENABLED(ENDSTOPPULLUP_YMIN) SET_INPUT_PULLUP(Y_MIN_PIN); @@ -80,6 +94,14 @@ void Endstops::init() { #endif #endif + #if HAS_Y2_MIN + #if ENABLED(ENDSTOPPULLUP_YMIN) + SET_INPUT_PULLUP(Y2_MIN_PIN); + #else + SET_INPUT(Y2_MIN_PIN); + #endif + #endif + #if HAS_Z_MIN #if ENABLED(ENDSTOPPULLUP_ZMIN) SET_INPUT_PULLUP(Z_MIN_PIN); @@ -104,6 +126,14 @@ void Endstops::init() { #endif #endif + #if HAS_X2_MAX + #if ENABLED(ENDSTOPPULLUP_XMAX) + SET_INPUT_PULLUP(X2_MAX_PIN); + #else + SET_INPUT(X2_MAX_PIN); + #endif + #endif + #if HAS_Y_MAX #if ENABLED(ENDSTOPPULLUP_YMAX) SET_INPUT_PULLUP(Y_MAX_PIN); @@ -112,6 +142,14 @@ void Endstops::init() { #endif #endif + #if HAS_Y2_MAX + #if ENABLED(ENDSTOPPULLUP_YMAX) + SET_INPUT_PULLUP(Y2_MAX_PIN); + #else + SET_INPUT(Y2_MAX_PIN); + #endif + #endif + #if HAS_Z_MAX #if ENABLED(ENDSTOPPULLUP_ZMAX) SET_INPUT_PULLUP(Z_MAX_PIN); @@ -190,37 +228,45 @@ void Endstops::report_state() { void Endstops::M119() { SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT); + #define ES_REPORT(AXIS) do{ \ + SERIAL_PROTOCOLPGM(MSG_##AXIS); \ + SERIAL_PROTOCOLLN(((READ(AXIS##_PIN)^AXIS##_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); \ + }while(0) #if HAS_X_MIN - SERIAL_PROTOCOLPGM(MSG_X_MIN); - SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(X_MIN); + #endif + #if HAS_X2_MIN + ES_REPORT(X2_MIN); #endif #if HAS_X_MAX - SERIAL_PROTOCOLPGM(MSG_X_MAX); - SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(X_MAX); + #endif + #if HAS_X2_MAX + ES_REPORT(X2_MAX); #endif #if HAS_Y_MIN - SERIAL_PROTOCOLPGM(MSG_Y_MIN); - SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Y_MIN); + #endif + #if HAS_Y2_MIN + ES_REPORT(Y2_MIN); #endif #if HAS_Y_MAX - SERIAL_PROTOCOLPGM(MSG_Y_MAX); - SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Y_MAX); + #endif + #if HAS_Y2_MAX + ES_REPORT(Y2_MAX); #endif #if HAS_Z_MIN - SERIAL_PROTOCOLPGM(MSG_Z_MIN); - SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z_MIN); #endif #if HAS_Z2_MIN - SERIAL_PROTOCOLPGM(MSG_Z2_MIN); - SERIAL_PROTOCOLLN(((READ(Z2_MIN_PIN)^Z2_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z2_MIN); #endif #if HAS_Z_MAX - SERIAL_PROTOCOLPGM(MSG_Z_MAX); - SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z_MAX); #endif #if HAS_Z2_MAX - SERIAL_PROTOCOLPGM(MSG_Z2_MAX); - SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN)); + ES_REPORT(Z2_MAX); #endif #if ENABLED(Z_MIN_PROBE_ENDSTOP) SERIAL_PROTOCOLPGM(MSG_Z_PROBE); @@ -232,18 +278,35 @@ void Endstops::M119() { #endif } // Endstops::M119 +#if ENABLED(X_DUAL_ENDSTOPS) + void Endstops::test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2) { + const byte x_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for X, bit 1 for X2 + if (x_test && stepper.current_block->steps[X_AXIS] > 0) { + SBI(endstop_hit_bits, X_MIN); + if (!stepper.performing_homing || (x_test == 0x3)) //if not performing home or if both endstops were trigged during homing... + stepper.kill_current_block(); + } + } +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + void Endstops::test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2) { + const byte y_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Y, bit 1 for Y2 + if (y_test && stepper.current_block->steps[Y_AXIS] > 0) { + SBI(endstop_hit_bits, Y_MIN); + if (!stepper.performing_homing || (y_test == 0x3)) //if not performing home or if both endstops were trigged during homing... + stepper.kill_current_block(); + } + } +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - - // Pass the result of the endstop test void Endstops::test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2) { - byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2 + const byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2 if (z_test && stepper.current_block->steps[Z_AXIS] > 0) { SBI(endstop_hit_bits, Z_MIN); if (!stepper.performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing... stepper.kill_current_block(); } } - #endif // Check endstops - Called from ISR! @@ -364,16 +427,35 @@ void Endstops::update() { */ if (X_MOVE_TEST) { - if (stepper.motor_direction(X_AXIS_HEAD)) { - if (X_MIN_TEST) { // -direction - #if HAS_X_MIN - UPDATE_ENDSTOP(X, MIN); + if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction + #if HAS_X_MIN + #if ENABLED(X_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(X, MIN); + #if HAS_X2_MIN + UPDATE_ENDSTOP_BIT(X2, MIN); + #else + COPY_BIT(current_endstop_bits, X_MIN, X2_MIN); + #endif + test_dual_x_endstops(X_MIN, X2_MIN); + #else + if (X_MIN_TEST) UPDATE_ENDSTOP(X, MIN); #endif - } + #endif } - else if (X_MAX_TEST) { // +direction + else { // +direction #if HAS_X_MAX - UPDATE_ENDSTOP(X, MAX); + #if ENABLED(X_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(X, MAX); + #if HAS_X2_MAX + UPDATE_ENDSTOP_BIT(X2, MAX); + #else + COPY_BIT(current_endstop_bits, X_MAX, X2_MAX); + #endif + test_dual_x_endstops(X_MAX, X2_MAX); + #else + if (X_MIN_TEST) UPDATE_ENDSTOP(X, MAX); + #endif + #endif } } @@ -381,12 +463,32 @@ void Endstops::update() { if (Y_MOVE_TEST) { if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction #if HAS_Y_MIN - UPDATE_ENDSTOP(Y, MIN); + #if ENABLED(Y_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(Y, MIN); + #if HAS_Y2_MIN + UPDATE_ENDSTOP_BIT(Y2, MIN); + #else + COPY_BIT(current_endstop_bits, Y_MIN, Y2_MIN); + #endif + test_dual_y_endstops(Y_MIN, Y2_MIN); + #else + UPDATE_ENDSTOP(Y, MIN); + #endif #endif } else { // +direction #if HAS_Y_MAX - UPDATE_ENDSTOP(Y, MAX); + #if ENABLED(Y_DUAL_ENDSTOPS) + UPDATE_ENDSTOP_BIT(Y, MAX); + #if HAS_Y2_MAX + UPDATE_ENDSTOP_BIT(Y2, MAX); + #else + COPY_BIT(current_endstop_bits, Y_MAX, Y2_MAX); + #endif + test_dual_y_endstops(Y_MAX, Y2_MAX); + #else + UPDATE_ENDSTOP(Y, MAX); + #endif #endif } } @@ -395,27 +497,21 @@ void Endstops::update() { if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. #if HAS_Z_MIN #if ENABLED(Z_DUAL_ENDSTOPS) - UPDATE_ENDSTOP_BIT(Z, MIN); #if HAS_Z2_MIN UPDATE_ENDSTOP_BIT(Z2, MIN); #else COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN); #endif - test_dual_z_endstops(Z_MIN, Z2_MIN); - - #else // !Z_DUAL_ENDSTOPS - + #else #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN); #else UPDATE_ENDSTOP(Z, MIN); #endif - - #endif // !Z_DUAL_ENDSTOPS - - #endif // HAS_Z_MIN + #endif + #endif // When closing the gap check the enabled probe #if ENABLED(Z_MIN_PROBE_ENDSTOP) @@ -427,27 +523,21 @@ void Endstops::update() { } else { // Z +direction. Gantry up, bed down. #if HAS_Z_MAX - // Check both Z dual endstops #if ENABLED(Z_DUAL_ENDSTOPS) - UPDATE_ENDSTOP_BIT(Z, MAX); #if HAS_Z2_MAX UPDATE_ENDSTOP_BIT(Z2, MAX); #else COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX); #endif - test_dual_z_endstops(Z_MAX, Z2_MAX); - // If this pin is not hijacked for the bed probe // then it belongs to the Z endstop #elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN - UPDATE_ENDSTOP(Z, MAX); - - #endif // !Z_MIN_PROBE_PIN... - #endif // Z_MAX_PIN + #endif + #endif } } @@ -496,6 +586,18 @@ void Endstops::update() { #if HAS_Z_MIN_PROBE_PIN if (READ(Z_MIN_PROBE_PIN)) SBI(current_endstop_bits_local, Z_MIN_PROBE); #endif + #if HAS_X2_MIN + if (READ(X2_MIN_PIN)) SBI(current_endstop_bits_local, X2_MIN); + #endif + #if HAS_X2_MAX + if (READ(X2_MAX_PIN)) SBI(current_endstop_bits_local, X2_MAX); + #endif + #if HAS_Y2_MIN + if (READ(Y2_MIN_PIN)) SBI(current_endstop_bits_local, Y2_MIN); + #endif + #if HAS_Y2_MAX + if (READ(Y2_MAX_PIN)) SBI(current_endstop_bits_local, Y2_MAX); + #endif #if HAS_Z2_MIN if (READ(Z2_MIN_PIN)) SBI(current_endstop_bits_local, Z2_MIN); #endif @@ -527,6 +629,18 @@ void Endstops::update() { #if HAS_Z_MIN_PROBE_PIN if (TEST(endstop_change, Z_MIN_PROBE)) SERIAL_PROTOCOLPAIR(" PROBE:", !!TEST(current_endstop_bits_local, Z_MIN_PROBE)); #endif + #if HAS_X2_MIN + if (TEST(endstop_change, X2_MIN)) SERIAL_PROTOCOLPAIR(" X2_MIN:", !!TEST(current_endstop_bits_local, X2_MIN)); + #endif + #if HAS_X2_MAX + if (TEST(endstop_change, X2_MAX)) SERIAL_PROTOCOLPAIR(" X2_MAX:", !!TEST(current_endstop_bits_local, X2_MAX)); + #endif + #if HAS_Y2_MIN + if (TEST(endstop_change, Y2_MIN)) SERIAL_PROTOCOLPAIR(" Y2_MIN:", !!TEST(current_endstop_bits_local, Y2_MIN)); + #endif + #if HAS_Y2_MAX + if (TEST(endstop_change, Y2_MAX)) SERIAL_PROTOCOLPAIR(" Y2_MAX:", !!TEST(current_endstop_bits_local, Y2_MAX)); + #endif #if HAS_Z2_MIN if (TEST(endstop_change, Z2_MIN)) SERIAL_PROTOCOLPAIR(" Z2_MIN:", !!TEST(current_endstop_bits_local, Z2_MIN)); #endif diff --git a/Marlin/src/module/endstops.h b/Marlin/src/module/endstops.h index c0cef47655..24b498d490 100644 --- a/Marlin/src/module/endstops.h +++ b/Marlin/src/module/endstops.h @@ -38,6 +38,10 @@ enum EndstopEnum { X_MAX, Y_MAX, Z_MAX, + X2_MIN, + X2_MAX, + Y2_MIN, + Y2_MAX, Z2_MIN, Z2_MAX }; @@ -49,8 +53,16 @@ class Endstops { static bool enabled, enabled_globally; static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value + #if ENABLED(X_DUAL_ENDSTOPS) + static float x_endstop_adj; + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + static float y_endstop_adj; + #endif #if ENABLED(Z_DUAL_ENDSTOPS) static float z_endstop_adj; + #endif + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) typedef uint16_t esbits_t; #else typedef byte esbits_t; @@ -113,6 +125,12 @@ class Endstops { private: + #if ENABLED(X_DUAL_ENDSTOPS) + static void test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + static void test_dual_y_endstops(const EndstopEnum es1, const EndstopEnum es2); + #endif #if ENABLED(Z_DUAL_ENDSTOPS) static void test_dual_z_endstops(const EndstopEnum es1, const EndstopEnum es2); #endif diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index f887429b83..e7cd631ff3 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -1043,9 +1043,15 @@ void homeaxis(const AxisEnum axis) { if (axis == Z_AXIS && DEPLOY_PROBE()) return; #endif - // Set a flag for Z motor locking + // Set flags for X, Y, Z motor locking + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) stepper.set_homing_flag_x(true); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) stepper.set_homing_flag_y(true); + #endif #if ENABLED(Z_DUAL_ENDSTOPS) - if (axis == Z_AXIS) stepper.set_homing_flag(true); + if (axis == Z_AXIS) stepper.set_homing_flag_z(true); #endif // Disable stealthChop if used. Enable diag1 pin on driver. @@ -1087,25 +1093,41 @@ void homeaxis(const AxisEnum axis) { do_homing_move(axis, 2 * bump, get_homing_bump_feedrate(axis)); } - #if ENABLED(Z_DUAL_ENDSTOPS) - if (axis == Z_AXIS) { - float adj = FABS(endstops.z_endstop_adj); - bool lockZ1; - if (axis_home_dir > 0) { - adj = -adj; - lockZ1 = (endstops.z_endstop_adj > 0); + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + const bool pos_dir = axis_home_dir > 0; + #if ENABLED(X_DUAL_ENDSTOPS) + if (axis == X_AXIS) { + const bool lock_x1 = pos_dir ? (endstops.x_endstop_adj > 0) : (endstops.x_endstop_adj < 0); + float adj = FABS(endstops.x_endstop_adj); + if (pos_dir) adj = -adj; + if (lock_x1) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, adj); + if (lock_x1) stepper.set_x_lock(false); else stepper.set_x2_lock(false); + stepper.set_homing_flag_x(false); } - else - lockZ1 = (endstops.z_endstop_adj < 0); - - if (lockZ1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); - - // Move to the adjusted endstop height - do_homing_move(axis, adj); - - if (lockZ1) stepper.set_z_lock(false); else stepper.set_z2_lock(false); - stepper.set_homing_flag(false); - } // Z_AXIS + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (axis == Y_AXIS) { + const bool lock_y1 = pos_dir ? (endstops.y_endstop_adj > 0) : (endstops.y_endstop_adj < 0); + float adj = FABS(endstops.y_endstop_adj); + if (pos_dir) adj = -adj; + if (lock_y1) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, adj); + if (lock_y1) stepper.set_y_lock(false); else stepper.set_y2_lock(false); + stepper.set_homing_flag_y(false); + } + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + if (axis == Z_AXIS) { + const bool lock_z1 = pos_dir ? (endstops.z_endstop_adj > 0) : (endstops.z_endstop_adj < 0); + float adj = FABS(endstops.z_endstop_adj); + if (pos_dir) adj = -adj; + if (lock_z1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); + do_homing_move(axis, adj); + if (lock_z1) stepper.set_z_lock(false); else stepper.set_z2_lock(false); + stepper.set_homing_flag_z(false); + } + #endif #endif #if IS_SCARA diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 22c9ad3d92..c86575edee 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -83,7 +83,7 @@ block_t* Stepper::current_block = NULL; // A pointer to the block currently bei bool Stepper::abort_on_endstop_hit = false; #endif -#if ENABLED(Z_DUAL_ENDSTOPS) +#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) bool Stepper::performing_homing = false; #endif @@ -96,6 +96,16 @@ block_t* Stepper::current_block = NULL; // A pointer to the block currently bei uint8_t Stepper::last_direction_bits = 0; // The next stepping-bits to be output uint16_t Stepper::cleaning_buffer_counter = 0; +#if ENABLED(X_DUAL_ENDSTOPS) + bool Stepper::locked_x_motor = false; + bool Stepper::locked_x2_motor = false; +#endif + +#if ENABLED(Y_DUAL_ENDSTOPS) + bool Stepper::locked_y_motor = false; + bool Stepper::locked_y2_motor = false; +#endif + #if ENABLED(Z_DUAL_ENDSTOPS) bool Stepper::locked_z_motor = false; bool Stepper::locked_z2_motor = false; @@ -153,26 +163,54 @@ timer_t Stepper::OCR1A_nominal; volatile long Stepper::endstops_trigsteps[XYZ]; +#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) + #define LOCKED_X_MOTOR locked_x_motor + #define LOCKED_Y_MOTOR locked_y_motor + #define LOCKED_Z_MOTOR locked_z_motor + #define LOCKED_X2_MOTOR locked_x2_motor + #define LOCKED_Y2_MOTOR locked_y2_motor + #define LOCKED_Z2_MOTOR locked_z2_motor + #define DUAL_ENDSTOP_APPLY_STEP(AXIS,v) \ + if (performing_homing) { \ + if (AXIS##_HOME_DIR < 0) { \ + if (!(TEST(endstops.old_endstop_bits, AXIS##_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, AXIS##2_MIN) && (count_direction[AXIS##_AXIS] < 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v); \ + } \ + else { \ + if (!(TEST(endstops.old_endstop_bits, AXIS##_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##_MOTOR) AXIS##_STEP_WRITE(v); \ + if (!(TEST(endstops.old_endstop_bits, AXIS##2_MAX) && (count_direction[AXIS##_AXIS] > 0)) && !LOCKED_##AXIS##2_MOTOR) AXIS##2_STEP_WRITE(v); \ + } \ + } \ + else { \ + AXIS##_STEP_WRITE(v); \ + AXIS##2_STEP_WRITE(v); \ + } +#endif + #if ENABLED(X_DUAL_STEPPER_DRIVERS) #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE((v) != INVERT_X2_VS_X_DIR); }while(0) - #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) -#elif ENABLED(DUAL_X_CARRIAGE) - #define X_APPLY_DIR(v,ALWAYS) \ - if (extruder_duplication_enabled || ALWAYS) { \ - X_DIR_WRITE(v); \ - X2_DIR_WRITE(v); \ - } \ - else { \ - if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ - } - #define X_APPLY_STEP(v,ALWAYS) \ - if (extruder_duplication_enabled || ALWAYS) { \ - X_STEP_WRITE(v); \ - X2_STEP_WRITE(v); \ - } \ - else { \ - if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ - } + #if ENABLED(DUAL_X_CARRIAGE) + #define X_APPLY_DIR(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_DIR_WRITE(v); \ + X2_DIR_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ + } + #define X_APPLY_STEP(v,ALWAYS) \ + if (extruder_duplication_enabled || ALWAYS) { \ + X_STEP_WRITE(v); \ + X2_STEP_WRITE(v); \ + } \ + else { \ + if (current_block->active_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ + } + #elif ENABLED(X_DUAL_ENDSTOPS) + #define X_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(X,v) + #else + #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) + #endif #else #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v) @@ -180,7 +218,11 @@ volatile long Stepper::endstops_trigsteps[XYZ]; #if ENABLED(Y_DUAL_STEPPER_DRIVERS) #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE((v) != INVERT_Y2_VS_Y_DIR); }while(0) - #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) + #if ENABLED(Y_DUAL_ENDSTOPS) + #define Y_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Y,v) + #else + #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) + #endif #else #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v) #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v) @@ -189,21 +231,7 @@ volatile long Stepper::endstops_trigsteps[XYZ]; #if ENABLED(Z_DUAL_STEPPER_DRIVERS) #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(v); }while(0) #if ENABLED(Z_DUAL_ENDSTOPS) - #define Z_APPLY_STEP(v,Q) \ - if (performing_homing) { \ - if (Z_HOME_DIR < 0) { \ - if (!(TEST(endstops.old_endstop_bits, Z_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ - if (!(TEST(endstops.old_endstop_bits, Z2_MIN) && (count_direction[Z_AXIS] < 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ - } \ - else { \ - if (!(TEST(endstops.old_endstop_bits, Z_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z_motor) Z_STEP_WRITE(v); \ - if (!(TEST(endstops.old_endstop_bits, Z2_MAX) && (count_direction[Z_AXIS] > 0)) && !locked_z2_motor) Z2_STEP_WRITE(v); \ - } \ - } \ - else { \ - Z_STEP_WRITE(v); \ - Z2_STEP_WRITE(v); \ - } + #define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v) #else #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0) #endif diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index aa11ef929b..614b648f90 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -66,7 +66,7 @@ class Stepper { static bool abort_on_endstop_hit; #endif - #if ENABLED(Z_DUAL_ENDSTOPS) + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) static bool performing_homing; #endif @@ -82,6 +82,12 @@ class Stepper { static uint8_t last_direction_bits; // The next stepping-bits to be output static uint16_t cleaning_buffer_counter; + #if ENABLED(X_DUAL_ENDSTOPS) + static bool locked_x_motor, locked_x2_motor; + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + static bool locked_y_motor, locked_y2_motor; + #endif #if ENABLED(Z_DUAL_ENDSTOPS) static bool locked_z_motor, locked_z2_motor; #endif @@ -227,8 +233,20 @@ class Stepper { static void microstep_readings(); #endif + #if ENABLED(X_DUAL_ENDSTOPS) + static FORCE_INLINE void set_homing_flag_x(const bool state) { performing_homing = state; } + static FORCE_INLINE void set_x_lock(const bool state) { locked_x_motor = state; } + static FORCE_INLINE void set_x2_lock(const bool state) { locked_x2_motor = state; } + #endif + + #if ENABLED(Y_DUAL_ENDSTOPS) + static FORCE_INLINE void set_homing_flag_y(const bool state) { performing_homing = state; } + static FORCE_INLINE void set_y_lock(const bool state) { locked_y_motor = state; } + static FORCE_INLINE void set_y2_lock(const bool state) { locked_y2_motor = state; } + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) - static FORCE_INLINE void set_homing_flag(const bool state) { performing_homing = state; } + static FORCE_INLINE void set_homing_flag_z(const bool state) { performing_homing = state; } static FORCE_INLINE void set_z_lock(const bool state) { locked_z_motor = state; } static FORCE_INLINE void set_z2_lock(const bool state) { locked_z2_motor = state; } #endif