From 90af1fe5eefd353c9fb9c40430f45031147fd675 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Sun, 1 Oct 2017 21:34:58 -0500
Subject: [PATCH] Implement NO_MOTION_BEFORE_HOMING option

---
 Marlin/Configuration.h            |  2 ++
 Marlin/src/gcode/bedlevel/G42.cpp |  2 +-
 Marlin/src/gcode/motion/G0_G1.cpp |  2 +-
 Marlin/src/gcode/motion/G2_G3.cpp |  2 +-
 Marlin/src/gcode/motion/G5.cpp    |  2 +-
 Marlin/src/lcd/ultralcd.cpp       | 20 ++++++++++----------
 Marlin/src/module/motion.cpp      |  6 +++---
 Marlin/src/module/motion.h        | 18 ++++++++++++++++--
 8 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 5b830d6704..c933b6887c 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -760,6 +760,8 @@
 
 // @section homing
 
+//#define NO_MOTION_BEFORE_HOMING  // Inhibit movement until all axes have been homed
+
 //#define Z_HOMING_HEIGHT 4  // (in mm) Minimal z height before homing (G28) for Z clearance above the bed, clamps, ...
                              // Be sure you have this distance over your Z_MAX_POS in case.
 
diff --git a/Marlin/src/gcode/bedlevel/G42.cpp b/Marlin/src/gcode/bedlevel/G42.cpp
index c46415b7db..f734fa8c86 100644
--- a/Marlin/src/gcode/bedlevel/G42.cpp
+++ b/Marlin/src/gcode/bedlevel/G42.cpp
@@ -33,7 +33,7 @@
  * G42: Move X & Y axes to mesh coordinates (I & J)
  */
 void GcodeSuite::G42() {
-  if (IsRunning()) {
+  if (MOTION_CONDITIONS) {
     const bool hasI = parser.seenval('I');
     const int8_t ix = hasI ? parser.value_int() : 0;
     const bool hasJ = parser.seenval('J');
diff --git a/Marlin/src/gcode/motion/G0_G1.cpp b/Marlin/src/gcode/motion/G0_G1.cpp
index d2fe3f98b2..1d34cb667a 100644
--- a/Marlin/src/gcode/motion/G0_G1.cpp
+++ b/Marlin/src/gcode/motion/G0_G1.cpp
@@ -41,7 +41,7 @@ void GcodeSuite::G0_G1(
     bool fast_move/*=false*/
   #endif
 ) {
-  if (IsRunning()) {
+  if (MOTION_CONDITIONS) {
     get_destination_from_command(); // For X Y Z E F
 
     #if ENABLED(FWRETRACT)
diff --git a/Marlin/src/gcode/motion/G2_G3.cpp b/Marlin/src/gcode/motion/G2_G3.cpp
index 44f0f53ba7..15fd7f7b9e 100644
--- a/Marlin/src/gcode/motion/G2_G3.cpp
+++ b/Marlin/src/gcode/motion/G2_G3.cpp
@@ -211,7 +211,7 @@ void plan_arc(
  *    G3 X20 Y12 R14   ; CCW circle with r=14 ending at X20 Y12
  */
 void GcodeSuite::G2_G3(const bool clockwise) {
-  if (IsRunning()) {
+  if (MOTION_CONDITIONS) {
 
     #if ENABLED(SF_ARC_FIX)
       const bool relative_mode_backup = relative_mode;
diff --git a/Marlin/src/gcode/motion/G5.cpp b/Marlin/src/gcode/motion/G5.cpp
index a09f588961..9df590b029 100644
--- a/Marlin/src/gcode/motion/G5.cpp
+++ b/Marlin/src/gcode/motion/G5.cpp
@@ -50,7 +50,7 @@ void plan_cubic_move(const float offset[4]) {
  * G5: Cubic B-spline
  */
 void GcodeSuite::G5() {
-  if (IsRunning()) {
+  if (MOTION_CONDITIONS) {
 
     #if ENABLED(CNC_WORKSPACE_PLANES)
       if (workspace_plane != PLANE_XY) {
diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp
index 2db06d5316..9a19104d71 100644
--- a/Marlin/src/lcd/ultralcd.cpp
+++ b/Marlin/src/lcd/ultralcd.cpp
@@ -2928,19 +2928,19 @@ void kill_screen(const char* lcd_msg) {
    *
    */
 
-  #if IS_KINEMATIC
+  #if IS_KINEMATIC || ENABLED(NO_MOTION_BEFORE_HOMING)
     #define _MOVE_XYZ_ALLOWED (axis_homed[X_AXIS] && axis_homed[Y_AXIS] && axis_homed[Z_AXIS])
-    #if ENABLED(DELTA)
-      #define _MOVE_XY_ALLOWED (current_position[Z_AXIS] <= delta_clip_start_height)
-      void lcd_lower_z_to_clip_height() {
-        line_to_z(delta_clip_start_height);
-        lcd_synchronize();
-      }
-    #else
-      #define _MOVE_XY_ALLOWED true
-    #endif
   #else
     #define _MOVE_XYZ_ALLOWED true
+  #endif
+
+  #if ENABLED(DELTA)
+    #define _MOVE_XY_ALLOWED (current_position[Z_AXIS] <= delta_clip_start_height)
+    void lcd_lower_z_to_clip_height() {
+      line_to_z(delta_clip_start_height);
+      lcd_synchronize();
+    }
+  #else
     #define _MOVE_XY_ALLOWED true
   #endif
 
diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp
index 407dd756b8..bb8ca3106a 100644
--- a/Marlin/src/module/motion.cpp
+++ b/Marlin/src/module/motion.cpp
@@ -51,7 +51,7 @@
   #include "../feature/bedlevel/bedlevel.h"
 #endif
 
-#if NEED_UNHOMED_ERR && ENABLED(ULTRA_LCD)
+#if HAS_AXIS_UNHOMED_ERR && ENABLED(ULTRA_LCD)
   #include "../lcd/ultralcd.h"
 #endif
 
@@ -820,7 +820,7 @@ void prepare_move_to_destination() {
   set_current_to_destination();
 }
 
-#if NEED_UNHOMED_ERR
+#if HAS_AXIS_UNHOMED_ERR
 
   bool axis_unhomed_error(const bool x/*=true*/, const bool y/*=true*/, const bool z/*=true*/) {
     #if ENABLED(HOME_AFTER_DEACTIVATE)
@@ -848,7 +848,7 @@ void prepare_move_to_destination() {
     return false;
   }
 
-#endif
+#endif // HAS_AXIS_UNHOMED_ERR
 
 /**
  * The homing feedrate may vary
diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h
index 084868e58f..5da373354b 100644
--- a/Marlin/src/module/motion.h
+++ b/Marlin/src/module/motion.h
@@ -167,12 +167,26 @@ void clean_up_after_endstop_or_probe_move();
 // Homing
 //
 
-#define NEED_UNHOMED_ERR (HAS_PROBING_PROCEDURE || HOTENDS > 1 || ENABLED(Z_PROBE_ALLEN_KEY) || ENABLED(Z_PROBE_SLED) || ENABLED(NOZZLE_CLEAN_FEATURE) || ENABLED(NOZZLE_PARK_FEATURE) || ENABLED(DELTA_AUTO_CALIBRATION))
+#define HAS_AXIS_UNHOMED_ERR (                                                     \
+         ENABLED(Z_PROBE_ALLEN_KEY)                                                \
+      || ENABLED(Z_PROBE_SLED)                                                     \
+      || HAS_PROBING_PROCEDURE                                                     \
+      || HOTENDS > 1                                                               \
+      || ENABLED(NOZZLE_CLEAN_FEATURE)                                             \
+      || ENABLED(NOZZLE_PARK_FEATURE)                                              \
+      || (ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(HOME_BEFORE_FILAMENT_CHANGE)) \
+    ) || ENABLED(NO_MOTION_BEFORE_HOMING)
 
-#if NEED_UNHOMED_ERR
+#if HAS_AXIS_UNHOMED_ERR
   bool axis_unhomed_error(const bool x=true, const bool y=true, const bool z=true);
 #endif
 
+#if ENABLED(NO_MOTION_BEFORE_HOMING)
+  #define MOTION_CONDITIONS (IsRunning() && !axis_unhomed_error())
+#else
+  #define MOTION_CONDITIONS IsRunning()
+#endif
+
 void set_axis_is_at_home(const AxisEnum axis);
 
 void homeaxis(const AxisEnum axis);