From 318c419f777688bb3e83d548134600c2d14b8837 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 27 Oct 2017 16:24:34 -0500 Subject: [PATCH] Implement support for Dual X and Y endstops --- .travis.yml | 5 +- Marlin/Conditionals_post.h | 179 ++++++++++++++++++------- Marlin/Marlin.h | 6 + Marlin/Marlin_main.cpp | 95 +++++++++---- Marlin/SanityCheck.h | 110 ++++++++++++---- Marlin/configuration_store.cpp | 234 +++++++++++++++++++++------------ Marlin/endstop_interrupts.h | 40 ++++++ Marlin/endstops.cpp | 177 ++++++++++++++++++------- Marlin/endstops.h | 8 +- Marlin/enum.h | 4 + Marlin/language.h | 4 + Marlin/macros.h | 7 + Marlin/stepper.cpp | 97 ++++++++------ Marlin/stepper.h | 20 ++- 14 files changed, 718 insertions(+), 268 deletions(-) diff --git a/.travis.yml b/.travis.yml index d73fe8123..4ed3a6484 100644 --- a/.travis.yml +++ b/.travis.yml @@ -199,12 +199,11 @@ 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 - - pins_set RAMPS X_MAX_PIN -1 - - opt_add_adv Z2_MAX_PIN 2 + - opt_add_adv Z2_MIN_PIN 2 - build_marlin # # Enable COREXY diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h index 681a2aae9..91942f96c 100644 --- a/Marlin/Conditionals_post.h +++ b/Marlin/Conditionals_post.h @@ -378,29 +378,114 @@ #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 + #elif 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 + #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 + #elif 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 + #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 @@ -423,28 +508,26 @@ #else #define Z2_MAX_ENDSTOP_INVERTING false #endif + #elif Z2_USE_ENDSTOP == _XMIN_ + #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING + #define Z2_MIN_PIN X_MIN_PIN + #elif Z2_USE_ENDSTOP == _XMAX_ + #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING + #define Z2_MIN_PIN X_MAX_PIN + #elif Z2_USE_ENDSTOP == _YMIN_ + #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING + #define Z2_MIN_PIN Y_MIN_PIN + #elif Z2_USE_ENDSTOP == _YMAX_ + #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING + #define Z2_MIN_PIN Y_MAX_PIN + #elif Z2_USE_ENDSTOP == _ZMIN_ + #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING + #define Z2_MIN_PIN Z_MIN_PIN + #elif Z2_USE_ENDSTOP == _ZMAX_ + #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING + #define Z2_MIN_PIN Z_MAX_PIN #else - #if Z2_USE_ENDSTOP == _XMIN_ - #define Z2_MIN_ENDSTOP_INVERTING X_MIN_ENDSTOP_INVERTING - #define Z2_MIN_PIN X_MIN_PIN - #elif Z2_USE_ENDSTOP == _XMAX_ - #define Z2_MIN_ENDSTOP_INVERTING X_MAX_ENDSTOP_INVERTING - #define Z2_MIN_PIN X_MAX_PIN - #elif Z2_USE_ENDSTOP == _YMIN_ - #define Z2_MIN_ENDSTOP_INVERTING Y_MIN_ENDSTOP_INVERTING - #define Z2_MIN_PIN Y_MIN_PIN - #elif Z2_USE_ENDSTOP == _YMAX_ - #define Z2_MIN_ENDSTOP_INVERTING Y_MAX_ENDSTOP_INVERTING - #define Z2_MIN_PIN Y_MAX_PIN - #elif Z2_USE_ENDSTOP == _ZMIN_ - #define Z2_MIN_ENDSTOP_INVERTING Z_MIN_ENDSTOP_INVERTING - #define Z2_MIN_PIN Z_MIN_PIN - #elif Z2_USE_ENDSTOP == _ZMAX_ - #define Z2_MIN_ENDSTOP_INVERTING Z_MAX_ENDSTOP_INVERTING - #define Z2_MIN_PIN Z_MAX_PIN - #else - #define Z2_MIN_ENDSTOP_INVERTING false - #endif + #define Z2_MIN_ENDSTOP_INVERTING false #endif #endif @@ -541,12 +624,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/Marlin.h b/Marlin/Marlin.h index 82ebe62a0..32c1594d2 100644 --- a/Marlin/Marlin.h +++ b/Marlin/Marlin.h @@ -331,6 +331,12 @@ extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ]; void set_z_fade_height(const float zfh); #endif +#if ENABLED(X_DUAL_ENDSTOPS) + extern float x_endstop_adj; +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + extern float y_endstop_adj; +#endif #if ENABLED(Z_DUAL_ENDSTOPS) extern float z_endstop_adj; #endif diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index a3627f6ac..0aae618a0 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -562,13 +562,19 @@ static uint8_t target_extruder; #define ADJUST_DELTA(V) NOOP #endif +#if ENABLED(X_DUAL_ENDSTOPS) + float x_endstop_adj; // Initialized by settings.load() +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + float y_endstop_adj; // Initialized by settings.load() +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - float z_endstop_adj; + float z_endstop_adj; // Initialized by settings.load() #endif // Extruder offsets #if HOTENDS > 1 - float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load() + float hotend_offset[XYZ][HOTENDS]; // Initialized by settings.load() #endif #if HAS_Z_SERVO_ENDSTOP @@ -3017,9 +3023,15 @@ static 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. @@ -3061,25 +3073,41 @@ static 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(z_endstop_adj); - bool lockZ1; - if (axis_home_dir > 0) { - adj = -adj; - lockZ1 = (z_endstop_adj > 0); + /** + * Home axes that have dual endstops... differently + */ + #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 ? (x_endstop_adj > 0) : (x_endstop_adj < 0); + const float adj = FABS(x_endstop_adj); + if (lock_x1) stepper.set_x_lock(true); else stepper.set_x2_lock(true); + do_homing_move(axis, pos_dir ? -adj : adj); + if (lock_x1) stepper.set_x_lock(false); else stepper.set_x2_lock(false); + stepper.set_homing_flag_x(false); } - else - lockZ1 = (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 ? (y_endstop_adj > 0) : (y_endstop_adj < 0); + const float adj = FABS(y_endstop_adj); + if (lock_y1) stepper.set_y_lock(true); else stepper.set_y2_lock(true); + do_homing_move(axis, pos_dir ? -adj : 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 ? (z_endstop_adj > 0) : (z_endstop_adj < 0); + const float adj = FABS(z_endstop_adj); + if (lock_z1) stepper.set_z_lock(true); else stepper.set_z2_lock(true); + do_homing_move(axis, pos_dir ? -adj : 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 @@ -8894,14 +8922,28 @@ inline void gcode_M205() { } } -#elif ENABLED(Z_DUAL_ENDSTOPS) // !DELTA && ENABLED(Z_DUAL_ENDSTOPS) + + +#elif ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) /** * M666: For Z Dual Endstop setup, set z axis offset to the z2 axis. */ inline void gcode_M666() { - if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units(); - SERIAL_ECHOLNPAIR("Z Endstop Adjustment set to (mm):", z_endstop_adj); + SERIAL_ECHOPGM("Dual Endstop Adjustment (mm): "); + #if ENABLED(X_DUAL_ENDSTOPS) + if (parser.seen('X')) x_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" X", x_endstop_adj); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + if (parser.seen('Y')) y_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" Y", y_endstop_adj); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + if (parser.seen('Z')) z_endstop_adj = parser.value_linear_units(); + SERIAL_ECHOPAIR(" Z", z_endstop_adj); + #endif + SERIAL_EOL(); } #endif // !DELTA && Z_DUAL_ENDSTOPS @@ -11606,7 +11648,7 @@ void process_next_command() { break; #endif - #if ENABLED(DELTA) || ENABLED(Z_DUAL_ENDSTOPS) + #if ENABLED(DELTA) || ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) case 666: // M666: Set delta or dual endstop adjustment gcode_M666(); break; @@ -13949,4 +13991,3 @@ void loop() { endstops.report_state(); idle(); } - diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h index 593293e3b..61b148206 100644 --- a/Marlin/SanityCheck.h +++ b/Marlin/SanityCheck.h @@ -78,8 +78,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) @@ -1059,23 +1057,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) @@ -1084,10 +1084,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/configuration_store.cpp b/Marlin/configuration_store.cpp index a07656fb9..0673bed70 100644 --- a/Marlin/configuration_store.cpp +++ b/Marlin/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) @@ -87,82 +87,83 @@ * 312 G29 L F bilinear_start (int x2) * 316 z_values[][] (float x9, up to float x256) +988 * - * AUTO_BED_LEVELING_UBL: 6 bytes + * AUTO_BED_LEVELING_UBL: 2 bytes * 324 G29 A planner.leveling_active (bool) * 325 G29 S ubl.storage_slot (int8_t) * - * DELTA: 48 bytes - * 348 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 z_endstop_adj (float) - * --- dummy data (float x11) + * [XYZ]_DUAL_ENDSTOPS: 12 bytes + * 352 M666 X x_endstop_adj (float) + * 356 M666 Y y_endstop_adj (float) + * 360 M666 Z 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 volumetric_enabled (bool) - * 538 M200 T D 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) @@ -209,8 +210,8 @@ MarlinSettings settings; #endif /** - * Post-process after Retrieve or Reset - */ +* Post-process after Retrieve or Reset +*/ void MarlinSettings::postprocess() { // steps per s2 needs to be updated to agree with units per s2 planner.reset_acceleration_rates(); @@ -448,7 +449,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 @@ -456,15 +457,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(z_endstop_adj); // 1 float - dummy = 0.0f; - for (uint8_t q = 11; q--;) EEPROM_WRITE(dummy); + #if ENABLED(X_DUAL_ENDSTOPS) + EEPROM_WRITE(x_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(Y_DUAL_ENDSTOPS) + EEPROM_WRITE(y_endstop_adj); // 1 float + #else + EEPROM_WRITE(dummy); + #endif + + #if ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_WRITE(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) @@ -845,13 +864,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(z_endstop_adj); - 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(x_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + EEPROM_READ(y_endstop_adj); // 1 float + #else + EEPROM_READ(dummy); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + EEPROM_READ(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) @@ -1234,15 +1271,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) - z_endstop_adj = - #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT - Z_DUAL_ENDSTOPS_ADJUSTMENT - #else - 0 - #endif - ; + #if ENABLED(X_DUAL_ENDSTOPS) + x_endstop_adj = ( + #ifdef X_DUAL_ENDSTOPS_ADJUSTMENT + X_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + y_endstop_adj = ( + #ifdef Y_DUAL_ENDSTOPS_ADJUSTMENT + Y_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + z_endstop_adj = ( + #ifdef Z_DUAL_ENDSTOPS_ADJUSTMENT + Z_DUAL_ENDSTOPS_ADJUSTMENT + #else + 0 + #endif + ); + #endif #endif @@ -1656,13 +1713,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(z_endstop_adj)); + SERIAL_ECHOPGM(" M666"); + #if ENABLED(X_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" X", LINEAR_UNIT(x_endstop_adj)); + #endif + #if ENABLED(Y_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" Y", LINEAR_UNIT(y_endstop_adj)); + #endif + #if ENABLED(Z_DUAL_ENDSTOPS) + SERIAL_ECHOPAIR(" Z", LINEAR_UNIT(z_endstop_adj)); + #endif + SERIAL_EOL(); #endif // DELTA #if ENABLED(ULTIPANEL) diff --git a/Marlin/endstop_interrupts.h b/Marlin/endstop_interrupts.h index 7d37c77c6..58e1fcc85 100644 --- a/Marlin/endstop_interrupts.h +++ b/Marlin/endstop_interrupts.h @@ -170,6 +170,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/endstops.cpp b/Marlin/endstops.cpp index 8ff6c7668..7e6dfc4bc 100644 --- a/Marlin/endstops.cpp +++ b/Marlin/endstops.cpp @@ -41,7 +41,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 @@ -67,6 +67,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); @@ -75,6 +83,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); @@ -99,6 +115,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); @@ -107,6 +131,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); @@ -185,37 +217,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); @@ -227,9 +267,27 @@ void Endstops::M119() { #endif } // Endstops::M119 +#if ENABLED(X_DUAL_ENDSTOPS) + void Endstops::test_dual_x_endstops(const EndstopEnum es1, const EndstopEnum es2) { + 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) { + 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 if (z_test && stepper.current_block->steps[Z_AXIS] > 0) { @@ -238,7 +296,6 @@ void Endstops::M119() { stepper.kill_current_block(); } } - #endif // Check endstops - Called from ISR! @@ -357,18 +414,36 @@ void Endstops::update() { /** * Check and update endstops according to conditions */ - 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 } } @@ -376,12 +451,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 } } @@ -390,27 +485,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) @@ -422,27 +511,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 } } diff --git a/Marlin/endstops.h b/Marlin/endstops.h index 2788fb64e..18c4fb2d2 100644 --- a/Marlin/endstops.h +++ b/Marlin/endstops.h @@ -36,7 +36,7 @@ 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(Z_DUAL_ENDSTOPS) + #if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS) static uint16_t #else static byte @@ -85,6 +85,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/enum.h b/Marlin/enum.h index c3e9ad012..4fa6496c2 100644 --- a/Marlin/enum.h +++ b/Marlin/enum.h @@ -93,6 +93,10 @@ enum EndstopEnum { X_MAX, Y_MAX, Z_MAX, + X2_MIN, + X2_MAX, + Y2_MIN, + Y2_MAX, Z2_MIN, Z2_MAX }; diff --git a/Marlin/language.h b/Marlin/language.h index 39af87200..878c12b66 100644 --- a/Marlin/language.h +++ b/Marlin/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/macros.h b/Marlin/macros.h index 05433597f..523dcaded 100644 --- a/Marlin/macros.h +++ b/Marlin/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/stepper.cpp b/Marlin/stepper.cpp index 2b86c4287..90e46ac83 100644 --- a/Marlin/stepper.cpp +++ b/Marlin/stepper.cpp @@ -72,7 +72,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 @@ -85,9 +85,14 @@ 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, Stepper::locked_x2_motor = false; +#endif +#if ENABLED(Y_DUAL_ENDSTOPS) + bool Stepper::locked_y_motor = false, Stepper::locked_y2_motor = false; +#endif #if ENABLED(Z_DUAL_ENDSTOPS) - bool Stepper::locked_z_motor = false; - bool Stepper::locked_z2_motor = false; + bool Stepper::locked_z_motor = false, Stepper::locked_z2_motor = false; #endif long Stepper::counter_X = 0, @@ -142,26 +147,54 @@ unsigned short 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) @@ -169,7 +202,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) @@ -178,21 +215,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/stepper.h b/Marlin/stepper.h index 682d684f8..6ec4311c9 100644 --- a/Marlin/stepper.h +++ b/Marlin/stepper.h @@ -87,7 +87,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 @@ -103,6 +103,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 @@ -250,8 +256,18 @@ 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