From c711701626d9309f391065b99aa78115a4d7f177 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Br=C3=A1zio?= <jbrazio@gmail.com>
Date: Thu, 14 Jul 2016 16:29:04 +0100
Subject: [PATCH 1/2] Implements a nozzle parking command (G27)

---
 .travis.yml            |  10 ++-
 Marlin/Configuration.h |  24 ++++++
 Marlin/Marlin_main.cpp |  27 +++++-
 Marlin/nozzle.h        | 189 +++++++++++++++++++++++++----------------
 4 files changed, 172 insertions(+), 78 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 4d003a95df2..5d7b7b6f7f8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -211,10 +211,16 @@ script:
   - opt_enable PRINTCOUNTER
   - build_marlin
   #
-  # Test CLEAN_NOZZLE_FEATURE
+  # Test NOZZLE_PARK_FEATURE
   #
   - restore_configs
-  - opt_enable AUTO_BED_LEVELING_FEATURE CLEAN_NOZZLE_FEATURE FIX_MOUNTED_PROBE
+  - opt_enable NOZZLE_PARK_FEATURE
+  - build_marlin
+  #
+  # Test NOZZLE_CLEAN_FEATURE
+  #
+  - restore_configs
+  - opt_enable AUTO_BED_LEVELING_FEATURE NOZZLE_CLEAN_FEATURE FIX_MOUNTED_PROBE
   - build_marlin
   #
   #
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 96cb5806894..27be90b7c08 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -787,6 +787,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 5091c421c47..9960c02f213 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2736,9 +2736,12 @@ inline void gcode_G4() {
 
 #endif //FWRETRACT
 
-#if ENABLED(NOZZLE_CLEAN_FEATURE) && ENABLED(AUTO_BED_LEVELING_FEATURE)
+#if ENABLED(NOZZLE_CLEAN_FEATURE) && HAS_BED_PROBE
   #include "nozzle.h"
 
+  /**
+   * G12: Clean the nozzle
+   */
   inline void gcode_G12() {
     // Don't allow nozzle cleaning without homing first
     if (axis_unhomed_error(true, true, true)) { return; }
@@ -2795,6 +2798,20 @@ inline void gcode_G4() {
 
 #endif // QUICK_HOME
 
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  #include "nozzle.h"
+
+  /**
+   * G27: Park the nozzle
+   */
+  inline void gcode_G27() {
+    // Don't allow nozzle parking without homing first
+    if (axis_unhomed_error(true, true, true)) { return; }
+    uint8_t const z_action = code_seen('P') ? code_value_ushort() : 0;
+    Nozzle::park(z_action);
+  }
+#endif // NOZZLE_PARK_FEATURE
+
 /**
  * G28: Home all axes according to settings
  *
@@ -6884,7 +6901,7 @@ void process_next_command() {
 
       #if ENABLED(NOZZLE_CLEAN_FEATURE) && HAS_BED_PROBE
         case 12:
-          gcode_G12(); // G12: Clean Nozzle
+          gcode_G12(); // G12: Nozzle Clean
           break;
       #endif // NOZZLE_CLEAN_FEATURE
 
@@ -6898,6 +6915,12 @@ void process_next_command() {
           break;
       #endif // INCH_MODE_SUPPORT
 
+      #if ENABLED(NOZZLE_PARK_FEATURE)
+        case 27: // G27: Nozzle Park
+          gcode_G27();
+          break;
+      #endif // NOZZLE_PARK_FEATURE
+
       case 28: // G28: Home all axes, one at a time
         gcode_G28();
         break;
diff --git a/Marlin/nozzle.h b/Marlin/nozzle.h
index 02771a51648..3e9ae879c9f 100644
--- a/Marlin/nozzle.h
+++ b/Marlin/nozzle.h
@@ -30,8 +30,6 @@
  * @brief Nozzle class
  *
  * @todo: Do not ignore the end.z value and allow XYZ movements
- * @todo: Currently this feature needs HAS_BED_PROBE to be active
- *  due to the do_blocking_move_to*() functions.
  */
 class Nozzle {
   private:
@@ -43,34 +41,40 @@ class Nozzle {
      * @param end point_t defining the ending point
      * @param strokes number of strokes to execute
      */
-    static void stroke(point_t const &start, point_t const &end, uint8_t const &strokes)
-    __attribute__ ((optimize ("Os"))) {
+    static void stroke(
+      __attribute__((unused)) point_t const &start,
+      __attribute__((unused)) point_t const &end,
+      __attribute__((unused)) uint8_t const &strokes
+    ) __attribute__((optimize ("Os"))) {
+      #if ENABLED(NOZZLE_CLEAN_FEATURE)
 
-      #if ENABLED(NOZZLE_CLEAN_PARK)
-        // Store the current coords
-        point_t const initial = {
-          current_position[X_AXIS],
-          current_position[Y_AXIS],
-          current_position[Z_AXIS],
-          current_position[E_AXIS]
-        };
-      #endif
+        #if ENABLED(NOZZLE_CLEAN_PARK)
+          // Store the current coords
+          point_t const initial = {
+            current_position[X_AXIS],
+            current_position[Y_AXIS],
+            current_position[Z_AXIS],
+            current_position[E_AXIS]
+          };
+        #endif // NOZZLE_CLEAN_PARK
 
-      // Move to the starting point
-      do_blocking_move_to_xy(start.x, start.y);
-      do_blocking_move_to_z(start.z);
-
-      // Start the stroke pattern
-      for (uint8_t i = 0; i < (strokes >>1); i++) {
-        do_blocking_move_to_xy(end.x, end.y);
+        // Move to the starting point
         do_blocking_move_to_xy(start.x, start.y);
-      }
+        do_blocking_move_to_z(start.z);
 
-      #if ENABLED(NOZZLE_CLEAN_PARK)
-        // Move the nozzle to the initial point
-        do_blocking_move_to_z(initial.z);
-        do_blocking_move_to_xy(initial.x, initial.y);
-      #endif
+        // Start the stroke pattern
+        for (uint8_t i = 0; i < (strokes >>1); i++) {
+          do_blocking_move_to_xy(end.x, end.y);
+          do_blocking_move_to_xy(start.x, start.y);
+        }
+
+        #if ENABLED(NOZZLE_CLEAN_PARK)
+          // Move the nozzle to the initial point
+          do_blocking_move_to_z(initial.z);
+          do_blocking_move_to_xy(initial.x, initial.y);
+        #endif // NOZZLE_CLEAN_PARK
+
+      #endif // NOZZLE_CLEAN_FEATURE
     }
 
     /**
@@ -82,47 +86,53 @@ class Nozzle {
      * @param strokes number of strokes to execute
      * @param objects number of objects to create
      */
-    static void zigzag(point_t const &start,
-      point_t const &end, uint8_t const &strokes, uint8_t const &objects)
-    __attribute__ ((optimize ("Os"))) {
-      float A = fabs(end.y - start.y); // [twice the] Amplitude
-      float P = fabs(end.x - start.x) / (objects << 1); // Period
+    static void zigzag(
+      __attribute__((unused)) point_t const &start,
+      __attribute__((unused)) point_t const &end,
+      __attribute__((unused)) uint8_t const &strokes,
+      __attribute__((unused)) uint8_t const &objects
+    ) __attribute__((optimize ("Os"))) {
+      #if ENABLED(NOZZLE_CLEAN_FEATURE)
+        float A = fabs(end.y - start.y); // [twice the] Amplitude
+        float P = fabs(end.x - start.x) / (objects << 1); // Period
 
-      // Don't allow impossible triangles
-      if (A <= 0.0f || P <= 0.0f ) return;
+        // Don't allow impossible triangles
+        if (A <= 0.0f || P <= 0.0f ) return;
 
-      #if ENABLED(NOZZLE_CLEAN_PARK)
-        // Store the current coords
-        point_t const initial = {
-          current_position[X_AXIS],
-          current_position[Y_AXIS],
-          current_position[Z_AXIS],
-          current_position[E_AXIS]
-        };
-      #endif
+        #if ENABLED(NOZZLE_CLEAN_PARK)
+          // Store the current coords
+          point_t const initial = {
+            current_position[X_AXIS],
+            current_position[Y_AXIS],
+            current_position[Z_AXIS],
+            current_position[E_AXIS]
+          };
+        #endif // NOZZLE_CLEAN_PARK
 
-      for (uint8_t j = 0; j < strokes; j++) {
-        for (uint8_t i = 0; i < (objects << 1); i++) {
-          float const x = start.x + i * P;
-          float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
+        for (uint8_t j = 0; j < strokes; j++) {
+          for (uint8_t i = 0; i < (objects << 1); i++) {
+            float const x = start.x + i * P;
+            float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
 
-          do_blocking_move_to_xy(x, y);
-          if (i == 0) do_blocking_move_to_z(start.z);
+            do_blocking_move_to_xy(x, y);
+            if (i == 0) do_blocking_move_to_z(start.z);
+          }
+
+          for (int i = (objects << 1); i > -1; i--) {
+            float const x = start.x + i * P;
+            float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
+
+            do_blocking_move_to_xy(x, y);
+          }
         }
 
-        for (int i = (objects << 1); i > -1; i--) {
-          float const x = start.x + i * P;
-          float const y = start.y + (A/P) * (P - fabs(fmod((i*P), (2*P)) - P));
+        #if ENABLED(NOZZLE_CLEAN_PARK)
+          // Move the nozzle to the initial point
+          do_blocking_move_to_z(initial.z);
+          do_blocking_move_to_xy(initial.x, initial.y);
+        #endif // NOZZLE_CLEAN_PARK
 
-          do_blocking_move_to_xy(x, y);
-        }
-      }
-
-      #if ENABLED(NOZZLE_CLEAN_PARK)
-        // Move the nozzle to the initial point
-        do_blocking_move_to_z(initial.z);
-        do_blocking_move_to_xy(initial.x, initial.y);
-      #endif
+      #endif // NOZZLE_CLEAN_FEATURE
     }
 
   public:
@@ -133,21 +143,52 @@ class Nozzle {
      * @param pattern one of the available patterns
      * @param argument depends on the cleaning pattern
      */
-    static void clean(uint8_t const &pattern,
-      uint8_t const &strokes, uint8_t const &objects = 0)
-    __attribute__ ((optimize ("Os"))) {
-      switch (pattern) {
-        case 1:
-          Nozzle::zigzag(
-            NOZZLE_CLEAN_START_PT,
-            NOZZLE_CLEAN_END_PT, strokes, objects);
-          break;
+    static void clean(
+      __attribute__((unused)) uint8_t const &pattern,
+      __attribute__((unused)) uint8_t const &strokes,
+      __attribute__((unused)) uint8_t const &objects = 0
+    ) __attribute__((optimize ("Os"))) {
+      #if ENABLED(NOZZLE_CLEAN_FEATURE)
+        switch (pattern) {
+          case 1:
+            Nozzle::zigzag(
+              NOZZLE_CLEAN_START_PT,
+              NOZZLE_CLEAN_END_PT, strokes, objects);
+            break;
 
-        default:
-          Nozzle::stroke(
-            NOZZLE_CLEAN_START_PT,
-            NOZZLE_CLEAN_END_PT, strokes);
-      }
+          default:
+            Nozzle::stroke(
+              NOZZLE_CLEAN_START_PT,
+              NOZZLE_CLEAN_END_PT, strokes);
+        }
+      #endif // NOZZLE_CLEAN_FEATURE
+    }
+
+    static void park(
+      __attribute__((unused)) uint8_t const &z_action
+    ) __attribute__((optimize ("Os"))) {
+      #if ENABLED(NOZZLE_PARK_FEATURE)
+        float const z = current_position[Z_AXIS];
+        point_t const park = NOZZLE_PARK_POINT;
+
+        switch(z_action) {
+          case 1: // force Z-park height
+            do_blocking_move_to_z(park.z);
+            break;
+
+          case 2: // Raise by Z-park height
+            do_blocking_move_to_z(
+              (z + park.z > Z_MAX_POS) ? Z_MAX_POS : z + park.z);
+            break;
+
+          default: // Raise to Z-park height if lower
+            if (current_position[Z_AXIS] < park.z)
+              do_blocking_move_to_z(park.z);
+        }
+
+        do_blocking_move_to_xy(park.x, park.y);
+
+      #endif // NOZZLE_PARK_FEATURE
     }
 };
 

From 336481ea8130daff6ebfe208b53a3e07807a6ce0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Br=C3=A1zio?= <jbrazio@gmail.com>
Date: Thu, 14 Jul 2016 16:42:58 +0100
Subject: [PATCH 2/2] Added G27 configuration options to all configs

---
 .../Cartesio/Configuration.h                  | 24 +++++++++++++++++++
 .../Felix/Configuration.h                     | 24 +++++++++++++++++++
 .../Felix/DUAL/Configuration.h                | 24 +++++++++++++++++++
 .../Hephestos/Configuration.h                 | 24 +++++++++++++++++++
 .../Hephestos_2/Configuration.h               | 24 +++++++++++++++++++
 .../K8200/Configuration.h                     | 24 +++++++++++++++++++
 .../K8400/Configuration.h                     | 24 +++++++++++++++++++
 .../K8400/Dual-head/Configuration.h           | 24 +++++++++++++++++++
 .../RepRapWorld/Megatronics/Configuration.h   | 24 +++++++++++++++++++
 .../RigidBot/Configuration.h                  | 24 +++++++++++++++++++
 .../SCARA/Configuration.h                     | 24 +++++++++++++++++++
 .../TAZ4/Configuration.h                      | 24 +++++++++++++++++++
 .../WITBOX/Configuration.h                    | 24 +++++++++++++++++++
 .../adafruit/ST7565/Configuration.h           | 24 +++++++++++++++++++
 .../delta/biv2.5/Configuration.h              | 24 +++++++++++++++++++
 .../delta/generic/Configuration.h             | 24 +++++++++++++++++++
 .../delta/kossel_mini/Configuration.h         | 24 +++++++++++++++++++
 .../delta/kossel_pro/Configuration.h          | 24 +++++++++++++++++++
 .../delta/kossel_xl/Configuration.h           | 24 +++++++++++++++++++
 .../makibox/Configuration.h                   | 24 +++++++++++++++++++
 .../tvrrug/Round2/Configuration.h             | 24 +++++++++++++++++++
 21 files changed, 504 insertions(+)

diff --git a/Marlin/example_configurations/Cartesio/Configuration.h b/Marlin/example_configurations/Cartesio/Configuration.h
index b4d1f08523e..8cad9204e7e 100644
--- a/Marlin/example_configurations/Cartesio/Configuration.h
+++ b/Marlin/example_configurations/Cartesio/Configuration.h
@@ -786,6 +786,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index 50ace1c2d56..eb9553f9ecb 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -770,6 +770,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/Felix/DUAL/Configuration.h b/Marlin/example_configurations/Felix/DUAL/Configuration.h
index 3c2be5a228f..996205cb17f 100644
--- a/Marlin/example_configurations/Felix/DUAL/Configuration.h
+++ b/Marlin/example_configurations/Felix/DUAL/Configuration.h
@@ -768,6 +768,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index 31ac6728fba..5c7f504fe8c 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -779,6 +779,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration.h b/Marlin/example_configurations/Hephestos_2/Configuration.h
index 648df90a04d..020f98be48d 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration.h
@@ -781,6 +781,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index 37fe86722f8..8a34167bd40 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -804,6 +804,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED     60 // K8200: set back to 110 if you have an upgraded heatbed power supply
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/K8400/Configuration.h b/Marlin/example_configurations/K8400/Configuration.h
index c900fc263f9..656e8c2ecf2 100644
--- a/Marlin/example_configurations/K8400/Configuration.h
+++ b/Marlin/example_configurations/K8400/Configuration.h
@@ -787,6 +787,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED      0
 #define PREHEAT_2_FAN_SPEED   165 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/K8400/Dual-head/Configuration.h b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
index d69c5bdfe38..f69fd3b5bcd 100644
--- a/Marlin/example_configurations/K8400/Dual-head/Configuration.h
+++ b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
@@ -787,6 +787,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED      0
 #define PREHEAT_2_FAN_SPEED   165 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
index 315010fe8fc..7e2abad9866 100644
--- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
+++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
@@ -787,6 +787,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h
index 829c8d8a549..67277b9ad8b 100644
--- a/Marlin/example_configurations/RigidBot/Configuration.h
+++ b/Marlin/example_configurations/RigidBot/Configuration.h
@@ -785,6 +785,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index 4d32f85a760..5db09f202df 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -795,6 +795,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/TAZ4/Configuration.h b/Marlin/example_configurations/TAZ4/Configuration.h
index f8f49db47b0..f864675f0c4 100644
--- a/Marlin/example_configurations/TAZ4/Configuration.h
+++ b/Marlin/example_configurations/TAZ4/Configuration.h
@@ -808,6 +808,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index d4102ef995f..f45dde22c3b 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -779,6 +779,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
index 2bb90a191a1..6d954811b27 100644
--- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h
+++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
@@ -787,6 +787,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    110
 #define PREHEAT_2_FAN_SPEED     0 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/delta/biv2.5/Configuration.h b/Marlin/example_configurations/delta/biv2.5/Configuration.h
index 981ae59dd72..dc65d382d60 100644
--- a/Marlin/example_configurations/delta/biv2.5/Configuration.h
+++ b/Marlin/example_configurations/delta/biv2.5/Configuration.h
@@ -882,6 +882,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index 2fed91a1a62..ba2bda57fc3 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -876,6 +876,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index 9e97af3c329..5dc35adcdd2 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -879,6 +879,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
index 2b49bd039b1..cfb5ec1780f 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
@@ -879,6 +879,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
index 258ba72c9b1..7125ceeb445 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
@@ -881,6 +881,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index c51d75d36f4..2477d981eeb 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -790,6 +790,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the l
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index eeee6530416..531dc7069c7 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -781,6 +781,30 @@ const bool Z_MIN_PROBE_ENDSTOP_INVERTING = true; // set to true to invert the lo
 #define PREHEAT_2_TEMP_BED    100
 #define PREHEAT_2_FAN_SPEED   255 // Value from 0 to 255
 
+//
+// Nozzle Park -- EXPERIMENTAL
+//
+// When enabled allows the user to define a special XYZ position, inside the
+// machine's topology, to park the nozzle when idle or when receiving the G27
+// command.
+//
+// The "P" paramenter controls what is the action applied to the Z axis:
+//    P0: (Default) If current Z-pos is lower than Z-park then the nozzle will
+//        be raised to reach Z-park height.
+//
+//    P1: No matter the current Z-pos, the nozzle will be raised/lowered to
+//        reach Z-park height.
+//
+//    P2: The nozzle height will be raised by Z-park amount but never going over
+//        the machine's limit of Z_MAX_POS.
+//
+//#define NOZZLE_PARK_FEATURE
+
+#if ENABLED(NOZZLE_PARK_FEATURE)
+  // Specify a park position as { X, Y, Z }
+  #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
+#endif
+
 //
 // Clean Nozzle Feature -- EXPERIMENTAL
 //