From 9f3ff14008fbcdc82e12a4cdf57129fde29219b6 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 04:31:51 -0500
Subject: [PATCH 01/83] Enabled separate Z Probe and Z Axis endstop use at same
 time. Typo fixes in comments in existing code.

---
 Marlin/Configuration.h | 28 +++++++++++++++++++++++
 Marlin/pins.h          |  4 ++++
 Marlin/pins_RAMPS_13.h |  1 +
 Marlin/stepper.cpp     | 52 +++++++++++++++++++++++++++++++++++++++++-
 4 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index ad7ec459094..ff6a57c2396 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -317,6 +317,7 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 const bool X_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 const bool Y_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
+
 //#define DISABLE_MAX_ENDSTOPS
 //#define DISABLE_MIN_ENDSTOPS
 
@@ -483,6 +484,33 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
   #endif
 
+// If you have are a Z Probe in addition to endstop(s) for Z Homing, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
+// Only use this if you have both a Z PROBE and Z HOMING ENDSTOP(S). If you are using Z_SAFE_HOMING above, then you probably don't need this unless you want to make use of
+// a non-default pin for your Z Probe.
+// Note: It's expected that your Z Probe triggers in the direction towards your bed. If your Z Probe does not trigger when traveling towards you bed, it will trigger when it's moving
+// away from the bed.
+
+//  #define Z_PROBE_AND_ENDSTOP
+
+  #ifdef Z_PROBE_AND_ENDSTOP
+
+// As of 3-28-2015, there are NO Z Probe pins defined in any board config files.
+// Z_PROBE_PIN is for the signal pin only. RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D1 pin in the Aux 1 section of the RAMPS board for the signal.
+// The D1 pin in Aux 1 on RAMPS maps to the Arduino D1 pin. The Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D1 pin on the RAMPS maps to D1 on Arduino, this works.
+// If you have RAMPS 1.3/1.4 and want to use the RAMPS D1 pin, set Z_PROBE_PIN to 1 and use ground and 5v next to it as needed. Check the RAMPS 1.3/1.4 pinout diagram for details.
+// WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
+  #define Z_PROBE_PIN -1
+
+// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
+    const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
+
+// The pullups are needed if you directly connect a mechanical endstop between the signal and ground pins.
+    #define ENDSTOPPULLUP_ZPROBE
+
+// If you want to enable the Z Probe pin, but disable its use, uncomment the line below.
+//    #define DISABLE_Z_PROBE_ENDSTOP
+  #endif
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/pins.h b/Marlin/pins.h
index 939dab5e660..8f013d5d010 100644
--- a/Marlin/pins.h
+++ b/Marlin/pins.h
@@ -178,6 +178,10 @@
   #define Z_MIN_PIN          -1
 #endif
 
+#ifdef DISABLE_Z_PROBE_ENDSTOP
+  #define Z_PROBE_PIN        -1
+#endif
+
 #ifdef DISABLE_XMAX_ENDSTOP
   #undef X_MAX_PIN
   #define X_MAX_PIN          -1
diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h
index 71287f68325..ece70005b30 100644
--- a/Marlin/pins_RAMPS_13.h
+++ b/Marlin/pins_RAMPS_13.h
@@ -34,6 +34,7 @@
 #define Z_ENABLE_PIN       62
 #define Z_MIN_PIN          18
 #define Z_MAX_PIN          19
+#define Z_PROBE_PIN        -1
 
 #define Y2_STEP_PIN        36
 #define Y2_DIR_PIN         34
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 40d5a36eb4d..bf83c927e58 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -97,6 +97,9 @@ static bool old_x_min_endstop = false,
               old_z2_min_endstop = false,
               old_z2_max_endstop = false;
             #endif
+            #if defined Z_PROBE_AND_ENDSTOP
+              old_z_probe_endstop = false;
+            #endif
 
 static bool check_endstops = true;
 
@@ -520,6 +523,26 @@ ISR(TIMER1_COMPA_vect) {
             old_z2_min_endstop = z2_min_endstop;
           #endif
         #endif
+
+        #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
+          UPDATE_ENDSTOP(z, Z, probe, PROBE);
+          bool z_probe_endstop(READ(Z_PROBE_PIN) != Z_MIN_ENDSTOP_INVERTING);
+          if(z_probe_endstop && old_z_probe_endstop)
+          {
+        	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
+        	  endstop_z_hit=true;
+
+//        	  if (z_probe_endstop && old_z_probe_endstop) SERIAL_ECHOLN("z_probe_endstop = true");
+
+
+        	  if (!(performing_homing)) //if not performing home
+        	  {
+        		  step_events_completed = current_block->step_event_count;
+        	  }
+          }
+          old_z_probe_endstop = z_probe_endstop;
+          old_z2_probe_endstop = z2_probe_endstop;
+        #endif
       }
     }
     else { // +direction
@@ -554,6 +577,26 @@ ISR(TIMER1_COMPA_vect) {
             old_z2_max_endstop = z2_max_endstop;
           #endif
         #endif
+
+        #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
+          UPDATE_ENDSTOP(z, Z, probe, PROBE);
+          bool z_probe_endstop(READ(Z_PROBE_PIN) != Z_MAX_ENDSTOP_INVERTING);
+          if(z_probe_endstop && old_z_probe_endstop)
+          {
+        	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
+        	  endstop_z_hit=true;
+
+//        	  if (z_probe_endstop && old_z_probe_endstop) SERIAL_ECHOLN("z_probe_endstop = true");
+
+
+        	  if (!(performing_homing)) //if not performing home
+        	  {
+        		  step_events_completed = current_block->step_event_count;
+        	  }
+          }
+          old_z_probe_endstop = z_probe_endstop;
+          old_z2_probe_endstop = z2_probe_endstop;
+        #endif
       }
     }
 
@@ -635,7 +678,7 @@ ISR(TIMER1_COMPA_vect) {
       step_events_completed++;
       if (step_events_completed >= current_block->step_event_count) break;
     }
-    // Calculare new timer value
+    // Calculate new timer value
     unsigned short timer;
     unsigned short step_rate;
     if (step_events_completed <= (unsigned long int)current_block->accelerate_until) {
@@ -918,6 +961,13 @@ void st_init() {
     #endif
   #endif  
   
+#if defined(Z_PROBE_PIN) && Z_PROBE_PIN >= 0
+  SET_INPUT(Z_PROBE_PIN);
+  #ifdef ENDSTOPPULLUP_ZPROBE
+    WRITE(Z_PROBE_PIN,HIGH);
+  #endif
+#endif
+
   #define AXIS_INIT(axis, AXIS, PIN) \
     AXIS ##_STEP_INIT; \
     AXIS ##_STEP_WRITE(INVERT_## PIN ##_STEP_PIN); \

From 2979b40a7a3ef2937aa900c06b733ee3f6b4373a Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 04:41:03 -0500
Subject: [PATCH 02/83] Fixed typo in Z Probe and Endstop section.

---
 Marlin/Configuration.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index ff6a57c2396..21141938bad 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -484,7 +484,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
   #endif
 
-// If you have are a Z Probe in addition to endstop(s) for Z Homing, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
+// If you have a Z Probe in addition to endstop(s) for Z Homing, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
 // Only use this if you have both a Z PROBE and Z HOMING ENDSTOP(S). If you are using Z_SAFE_HOMING above, then you probably don't need this unless you want to make use of
 // a non-default pin for your Z Probe.
 // Note: It's expected that your Z Probe triggers in the direction towards your bed. If your Z Probe does not trigger when traveling towards you bed, it will trigger when it's moving

From 44b88b41a29ffd436ae79539a35749a5f98f9650 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 05:01:04 -0500
Subject: [PATCH 03/83] Added credit for code.

---
 Marlin/Configuration.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 21141938bad..b8ef0755a27 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -484,6 +484,8 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
   #endif
 
+// Z Probe and Z endstop support
+// Added by Chris Roadfeldt 3-28-2015
 // If you have a Z Probe in addition to endstop(s) for Z Homing, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
 // Only use this if you have both a Z PROBE and Z HOMING ENDSTOP(S). If you are using Z_SAFE_HOMING above, then you probably don't need this unless you want to make use of
 // a non-default pin for your Z Probe.

From 92eb8109ab73871da4b651c6f45cb908f0155a2f Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 05:09:48 -0500
Subject: [PATCH 04/83] Fix declaration of old_z_probe_endstop.

---
 Marlin/stepper.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index bf83c927e58..4241111d780 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -97,9 +97,10 @@ static bool old_x_min_endstop = false,
               old_z2_min_endstop = false,
               old_z2_max_endstop = false;
             #endif
-            #if defined Z_PROBE_AND_ENDSTOP
-              old_z_probe_endstop = false;
-            #endif
+
+#ifdef Z_PROBE_AND_ENDSTOP
+static bool old_z_probe_endstop = false;
+#endif
 
 static bool check_endstops = true;
 

From fd823449adc46369ff4e3efdb51dfc03f041615e Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 05:42:38 -0500
Subject: [PATCH 05/83] Added serial message for Z Probe trigger.

---
 Marlin/Configuration.h | 6 +++---
 Marlin/Marlin_main.cpp | 5 ++++-
 Marlin/language.h      | 1 +
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index b8ef0755a27..262b4e15b64 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -497,9 +497,9 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
   #ifdef Z_PROBE_AND_ENDSTOP
 
 // As of 3-28-2015, there are NO Z Probe pins defined in any board config files.
-// Z_PROBE_PIN is for the signal pin only. RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D1 pin in the Aux 1 section of the RAMPS board for the signal.
-// The D1 pin in Aux 1 on RAMPS maps to the Arduino D1 pin. The Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D1 pin on the RAMPS maps to D1 on Arduino, this works.
-// If you have RAMPS 1.3/1.4 and want to use the RAMPS D1 pin, set Z_PROBE_PIN to 1 and use ground and 5v next to it as needed. Check the RAMPS 1.3/1.4 pinout diagram for details.
+// Z_PROBE_PIN is for the signal pin only. RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board for the signal.
+// The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. The Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+// If you have RAMPS 1.3/1.4 and want to use the RAMPS D32 pin, set Z_PROBE_PIN to 32 and use ground and 5v next to it as needed. Check the RAMPS 1.3/1.4 pinout diagram for details.
 // WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
   #define Z_PROBE_PIN -1
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 0808a727dc7..ca06000b6a3 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3509,7 +3509,10 @@ inline void gcode_M119() {
     SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
     SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
   #endif
-  
+  #if defined(Z_PROBE_PIN) && Z_PROBE_PIN >-1
+    SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
+    SERIALPROTOCOLLN(((READ(Z_PROBE_PIN)^72Z_PROBE_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
+  #endif
 }
 
 /**
diff --git a/Marlin/language.h b/Marlin/language.h
index 3f2291a947a..0fbaa39b141 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -132,6 +132,7 @@
 #define MSG_Z_MIN                           "z_min: "
 #define MSG_Z_MAX                           "z_max: "
 #define MSG_Z2_MAX                          "z2_max: "
+#define MSG_Z_PROBE							"z_probe: "
 #define MSG_M119_REPORT                     "Reporting endstop status"
 #define MSG_ENDSTOP_HIT                     "TRIGGERED"
 #define MSG_ENDSTOP_OPEN                    "open"

From 8b81f20c6127f4fd579512f004a85facf1a2501a Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 05:55:42 -0500
Subject: [PATCH 06/83] Filling in more places where Z_PROBE_PIN and
 Z_PROBE_AND_ENDSTOP need to be. Added Sanity Check for it. Added hook so it's
 enabled.

---
 Marlin/Marlin_main.cpp |  5 +++++
 Marlin/SanityCheck.h   | 11 ++++++-----
 Marlin/pins.h          |  2 +-
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index ca06000b6a3..7f8592b2c0c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1290,8 +1290,13 @@ static void engage_z_probe() {
     
     st_synchronize();
     
+    #if defined(Z_PROBE_AND_ENDSTOP)
+    bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
+    if (z_probe_endstop)
+    #else
     bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
     if (z_min_endstop)
+    #endif
     {
         if (!Stopped)
         {
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index d5183abbaaf..1024b6ab473 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -90,13 +90,14 @@
      * Require a Z Min pin
      */
     #if Z_MIN_PIN == -1
-      #ifdef Z_PROBE_REPEATABILITY_TEST
-        #error You must have a Z_MIN endstop to enable Z_PROBE_REPEATABILITY_TEST.
-      #else
-        #error ENABLE_AUTO_BED_LEVELING requires a Z_MIN endstop. Z_MIN_PIN must point to a valid hardware pin.
+      #if Z_PROBE_PIN == -1
+        #ifdef Z_PROBE_REPEATABILITY_TEST
+          #error You must have a Z_MIN endstop to enable Z_PROBE_REPEATABILITY_TEST.
+        #else
+          #error ENABLE_AUTO_BED_LEVELING requires a Z_MIN or Z_PROBE endstop. Z_MIN_PIN or Z_PROBE_PIN must point to a valid hardware pin.
+        #endif
       #endif
     #endif
-
     /**
      * Check if Probe_Offset * Grid Points is greater than Probing Range
      */
diff --git a/Marlin/pins.h b/Marlin/pins.h
index 8f013d5d010..e9d06e998cc 100644
--- a/Marlin/pins.h
+++ b/Marlin/pins.h
@@ -211,7 +211,7 @@
   #define Z_MIN_PIN          -1
 #endif
 
-#define SENSITIVE_PINS { 0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, PS_ON_PIN, \
+#define SENSITIVE_PINS { 0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, Z_PROBE_PIN, PS_ON_PIN, \
                         HEATER_BED_PIN, FAN_PIN, \
                         _E0_PINS _E1_PINS _E2_PINS _E3_PINS \
                         analogInputToDigitalPin(TEMP_BED_PIN) \

From 059052889f76dea37bfe9bd8e6b402231b9c0995 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sat, 28 Mar 2015 06:08:04 -0500
Subject: [PATCH 07/83] Further Sanity Checks for Z_PROBE_AND_ENDSTOP.

---
 Marlin/SanityCheck.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 1024b6ab473..5a24cbc1cea 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -92,12 +92,22 @@
     #if Z_MIN_PIN == -1
       #if Z_PROBE_PIN == -1
         #ifdef Z_PROBE_REPEATABILITY_TEST
-          #error You must have a Z_MIN endstop to enable Z_PROBE_REPEATABILITY_TEST.
+          #error You must have a Z_MIN or Z_PROBE endstop to enable Z_PROBE_REPEATABILITY_TEST.
         #else
           #error ENABLE_AUTO_BED_LEVELING requires a Z_MIN or Z_PROBE endstop. Z_MIN_PIN or Z_PROBE_PIN must point to a valid hardware pin.
         #endif
       #endif
     #endif
+
+    /**
+     * Require a Z Probe Pin if Z_PROBE_AND_ENDSTOP is enabled.
+     */
+    #if defined(Z_PROBE_AND_ENDSTOP)
+      #if Z_PROBE_PIN == -1
+        #error You must have a Z_PROBE_PIN defined if you enable Z_PROBE_AND_ENDSTOP
+      #endif
+    #endif
+
     /**
      * Check if Probe_Offset * Grid Points is greater than Probing Range
      */

From 324c14943bdb58a26cf95574dc9b0d329bbe4027 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 02:16:09 -0500
Subject: [PATCH 08/83] Bug fixes for Z_PROBE_AND_ENDSTOP. Code cleanup for
 Z_PROBE_AND_ENDSTOP. Added Z_PROBE_PIN to pins_RAMPS_13.h

---
 Marlin/Configuration.h |  3 +--
 Marlin/Marlin_main.cpp |  9 +++++++--
 Marlin/pins_RAMPS_13.h |  5 +++++
 Marlin/stepper.cpp     | 19 ++-----------------
 4 files changed, 15 insertions(+), 21 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 262b4e15b64..b23864065c8 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -499,9 +499,8 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // As of 3-28-2015, there are NO Z Probe pins defined in any board config files.
 // Z_PROBE_PIN is for the signal pin only. RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board for the signal.
 // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. The Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
-// If you have RAMPS 1.3/1.4 and want to use the RAMPS D32 pin, set Z_PROBE_PIN to 32 and use ground and 5v next to it as needed. Check the RAMPS 1.3/1.4 pinout diagram for details.
+// D32 is currently selected in the RAMPS 1.3/1.4 pin file. Update the pins.h file for your control board to make use of this. Not doing so nullifies Z_PROBE_AND_ENDSTOP
 // WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
-  #define Z_PROBE_PIN -1
 
 // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
     const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 7f8592b2c0c..87ec4792cdd 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1359,8 +1359,13 @@ static void retract_z_probe() {
     
     st_synchronize();
     
+    #if defined(Z_PROBE_AND_ENDSTOP)
+    bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
+    if (z_probe_endstop)
+    #else
     bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-    if (!z_min_endstop)
+    if (z_min_endstop)
+    #endif
     {
         if (!Stopped)
         {
@@ -3516,7 +3521,7 @@ inline void gcode_M119() {
   #endif
   #if defined(Z_PROBE_PIN) && Z_PROBE_PIN >-1
     SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
-    SERIALPROTOCOLLN(((READ(Z_PROBE_PIN)^72Z_PROBE_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
+    SERIAL_PROTOCOLLN(((READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
   #endif
 }
 
diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h
index ece70005b30..4bd2bce468e 100644
--- a/Marlin/pins_RAMPS_13.h
+++ b/Marlin/pins_RAMPS_13.h
@@ -62,6 +62,11 @@
   #define FILWIDTH_PIN        5
 #endif
 
+#if defined(Z_PROBE_ANDENDSTOP)
+  // Define a pin to use as the signal pin on Arduino for the Z_PROBE endstop.
+ #define 32
+#endif
+
 #if defined(FILAMENT_RUNOUT_SENSOR)
   // define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector
   #define FILRUNOUT_PIN        4
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 4241111d780..c246e5e52e6 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -527,22 +527,15 @@ ISR(TIMER1_COMPA_vect) {
 
         #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
-          bool z_probe_endstop(READ(Z_PROBE_PIN) != Z_MIN_ENDSTOP_INVERTING);
+          z_probe_endstop=(READ(Z_PROBE_PIN) != Z_MIN_ENDSTOP_INVERTING);
           if(z_probe_endstop && old_z_probe_endstop)
           {
         	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
         	  endstop_z_hit=true;
 
 //        	  if (z_probe_endstop && old_z_probe_endstop) SERIAL_ECHOLN("z_probe_endstop = true");
-
-
-        	  if (!(performing_homing)) //if not performing home
-        	  {
-        		  step_events_completed = current_block->step_event_count;
-        	  }
           }
           old_z_probe_endstop = z_probe_endstop;
-          old_z2_probe_endstop = z2_probe_endstop;
         #endif
       }
     }
@@ -581,22 +574,14 @@ ISR(TIMER1_COMPA_vect) {
 
         #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
-          bool z_probe_endstop(READ(Z_PROBE_PIN) != Z_MAX_ENDSTOP_INVERTING);
+          z_probe_endstop=(READ(Z_PROBE_PIN) != Z_MAX_ENDSTOP_INVERTING);
           if(z_probe_endstop && old_z_probe_endstop)
           {
         	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
         	  endstop_z_hit=true;
-
 //        	  if (z_probe_endstop && old_z_probe_endstop) SERIAL_ECHOLN("z_probe_endstop = true");
-
-
-        	  if (!(performing_homing)) //if not performing home
-        	  {
-        		  step_events_completed = current_block->step_event_count;
-        	  }
           }
           old_z_probe_endstop = z_probe_endstop;
-          old_z2_probe_endstop = z2_probe_endstop;
         #endif
       }
     }

From 6125124d6c3e76d7826f81355779c9d0e958dce2 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 02:29:16 -0500
Subject: [PATCH 09/83] Config file cleanup for Z_PROBE_AND_ENDSTOP support.

---
 Marlin/Configuration.h | 37 ++++++++++++++-----------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index b23864065c8..e2b0bfc37f0 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -309,6 +309,7 @@ your extruder heater takes 2 minutes to hit the target on heating.
 #define ENDSTOPPULLUP_XMIN
 #define ENDSTOPPULLUP_YMIN
 #define ENDSTOPPULLUP_ZMIN
+#define ENDSTOPPULLUP_ZPROBE
 
 // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
 const bool X_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
@@ -317,9 +318,15 @@ const bool Z_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 const bool X_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 const bool Y_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
+const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 
 //#define DISABLE_MAX_ENDSTOPS
 //#define DISABLE_MIN_ENDSTOPS
+// If you want to enable the Z Probe pin, but disable its use, uncomment the line below.
+// This only affects a Z Probe Endstop if you have separate Z min endstop as well and have
+// activated Z_PROBE_AND_ENDSTOP below. If you are using the Z Min endstop on your Z Probe,
+// this has no effect.
+//#define DISABLE_Z_PROBE_ENDSTOP
 
 // For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
 #define X_ENABLE_ON 0
@@ -484,33 +491,17 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
   #endif
 
-// Z Probe and Z endstop support
+// Seaparte concurrent Z Probe and Z min endstop support
 // Added by Chris Roadfeldt 3-28-2015
-// If you have a Z Probe in addition to endstop(s) for Z Homing, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
-// Only use this if you have both a Z PROBE and Z HOMING ENDSTOP(S). If you are using Z_SAFE_HOMING above, then you probably don't need this unless you want to make use of
-// a non-default pin for your Z Probe.
-// Note: It's expected that your Z Probe triggers in the direction towards your bed. If your Z Probe does not trigger when traveling towards you bed, it will trigger when it's moving
-// away from the bed.
-
-//  #define Z_PROBE_AND_ENDSTOP
-
-  #ifdef Z_PROBE_AND_ENDSTOP
-
-// As of 3-28-2015, there are NO Z Probe pins defined in any board config files.
-// Z_PROBE_PIN is for the signal pin only. RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board for the signal.
+// If you have a Z Probe in addition to a Z min endstop, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
+// Only use this if you have both a Z PROBE and Z Min ENDSTOP.
+// Note: It's expected that your Z Probe triggers in the direction towards your bed.
+// In order to use this, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+// RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board for the signal.
 // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. The Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
 // D32 is currently selected in the RAMPS 1.3/1.4 pin file. Update the pins.h file for your control board to make use of this. Not doing so nullifies Z_PROBE_AND_ENDSTOP
 // WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
-
-// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
-    const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
-
-// The pullups are needed if you directly connect a mechanical endstop between the signal and ground pins.
-    #define ENDSTOPPULLUP_ZPROBE
-
-// If you want to enable the Z Probe pin, but disable its use, uncomment the line below.
-//    #define DISABLE_Z_PROBE_ENDSTOP
-  #endif
+//  #define Z_PROBE_AND_ENDSTOP
 
 #endif // ENABLE_AUTO_BED_LEVELING
 

From a98ac4033b605e622be3f0e35039b1bdd95c0466 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 02:36:26 -0500
Subject: [PATCH 10/83] Added Z_PROBE_PIN to #define for Z_PROBE_AND_ENDSTOP
 support.

---
 Marlin/pins_RAMPS_13.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h
index 4bd2bce468e..173310031c9 100644
--- a/Marlin/pins_RAMPS_13.h
+++ b/Marlin/pins_RAMPS_13.h
@@ -64,7 +64,7 @@
 
 #if defined(Z_PROBE_ANDENDSTOP)
   // Define a pin to use as the signal pin on Arduino for the Z_PROBE endstop.
- #define 32
+ #define Z_PROBE_PIN 32
 #endif
 
 #if defined(FILAMENT_RUNOUT_SENSOR)

From c75a5e8c551985cbb5aabc4e4475be6f54782c12 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 02:38:08 -0500
Subject: [PATCH 11/83] Fixed typo for Z_PROBE_AND_ENDSTOP support in
 pins_RAMPS.h. Confirmed Sanity checks are working.....

---
 Marlin/pins_RAMPS_13.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h
index 173310031c9..3ca12dd1568 100644
--- a/Marlin/pins_RAMPS_13.h
+++ b/Marlin/pins_RAMPS_13.h
@@ -62,7 +62,7 @@
   #define FILWIDTH_PIN        5
 #endif
 
-#if defined(Z_PROBE_ANDENDSTOP)
+#if defined(Z_PROBE_AND_ENDSTOP)
   // Define a pin to use as the signal pin on Arduino for the Z_PROBE endstop.
  #define Z_PROBE_PIN 32
 #endif

From 05134f0807a1a3be6306947e5cf5a1c567522c5e Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 02:51:51 -0500
Subject: [PATCH 12/83] Additional Sanity Checks for Z_PROBE_AND_ENDSTOP

---
 Marlin/SanityCheck.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 5a24cbc1cea..cd8ef97c9a2 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -106,8 +106,16 @@
       #if Z_PROBE_PIN == -1
         #error You must have a Z_PROBE_PIN defined if you enable Z_PROBE_AND_ENDSTOP
       #endif
+      #ifndef (NUM_SERVOS)
+        #error You must have NUM_SERVOS defined and there must be at least 1 configured to use Z_PROBE_AND_ENDSTOP
+      #endif
+      #if defined(NUM_SERVOS) && NUM_SERVOS < 1
+        #error You must have at least 1 servo defined for NUM_SERVOS to use Z_PROBE_AND_ENDSTOP
+      #endif
+      #ifndef SERVO_ENDSTOPS
+        #error You must have SERVO_ENDSTOPS defined and have the Z index set to at least 1 to use Z_PROBE_AND_ENDSTOP
+      #endif
     #endif
-
     /**
      * Check if Probe_Offset * Grid Points is greater than Probing Range
      */

From 82d2f111299f7c48be64b6f5830fc17cd2a0873d Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 02:53:55 -0500
Subject: [PATCH 13/83] More additional sanity checks for Z_PROBE_AND_ENDSTOP

---
 Marlin/SanityCheck.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index cd8ef97c9a2..8c60415fa89 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -115,6 +115,9 @@
       #ifndef SERVO_ENDSTOPS
         #error You must have SERVO_ENDSTOPS defined and have the Z index set to at least 1 to use Z_PROBE_AND_ENDSTOP
       #endif
+      #ifndef SERVO_ENDSTOP_ANGLES
+        #error You must have SERVO_ENDSTOP_ANGLES defined for Z Extend and Retract to use Z_PROBE_AND_ENSTOP
+      #endif
     #endif
     /**
      * Check if Probe_Offset * Grid Points is greater than Probing Range

From fe4549cd834e1b6b4901b74e163c2f8c12bf09fb Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 03:04:59 -0500
Subject: [PATCH 14/83] Config file Z_PROBE_AND_ENDSTOP description clean up.

---
 Marlin/Configuration.h | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index e2b0bfc37f0..6d76a8ee41f 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -491,14 +491,13 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
 
   #endif
 
-// Seaparte concurrent Z Probe and Z min endstop support
+// Support for concurrent and seperate Z Probe and Z min endstop use.
 // Added by Chris Roadfeldt 3-28-2015
-// If you have a Z Probe in addition to a Z min endstop, uncomment the #define Z_PROBE_AND_ENDSTOP line below and configure Z Probe settings.
-// Only use this if you have both a Z PROBE and Z Min ENDSTOP.
-// Note: It's expected that your Z Probe triggers in the direction towards your bed.
+// If you would like to use both a Z Probe and a Z min endstop at the same time, uncomment #define Z_PROBE_AND_ENDSTOP below
+// You will want to disable Z_SAFE_HOMING above as you will still use the Z min endstop for homing.
 // In order to use this, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
 // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board for the signal.
-// The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. The Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+// The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
 // D32 is currently selected in the RAMPS 1.3/1.4 pin file. Update the pins.h file for your control board to make use of this. Not doing so nullifies Z_PROBE_AND_ENDSTOP
 // WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
 //  #define Z_PROBE_AND_ENDSTOP

From 80285251cccf1464b39469122e26804e23a96efb Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 03:06:20 -0500
Subject: [PATCH 15/83] More config cleanup work for Z_PROBE_AND_ENDSTOP.

---
 Marlin/Configuration.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 6d76a8ee41f..29ea48c5926 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -500,6 +500,7 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
 // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
 // D32 is currently selected in the RAMPS 1.3/1.4 pin file. Update the pins.h file for your control board to make use of this. Not doing so nullifies Z_PROBE_AND_ENDSTOP
 // WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
+
 //  #define Z_PROBE_AND_ENDSTOP
 
 #endif // ENABLE_AUTO_BED_LEVELING

From 08a7aa16c548951c0be7f7b5a4956f62768447f9 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 03:21:48 -0500
Subject: [PATCH 16/83] Don't deploy Z Probe on Z homing if Z_PROBE_AND_ENDSTOP
 is defined.

---
 Marlin/Marlin_main.cpp | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 87ec4792cdd..a020c6e0d52 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1493,18 +1493,20 @@ static void homeaxis(int axis) {
 
 
 #ifndef Z_PROBE_SLED
-    // Engage Servo endstop if enabled
-    #ifdef SERVO_ENDSTOPS
-      #if SERVO_LEVELING
+    // Engage Servo endstop if enabled and we are not using Z_PROBE_AND_ENDSTOP
+    #ifndef Z_PROBE_AND_ENDSTOP
+      #ifdef SERVO_ENDSTOPS
+        #if SERVO_LEVELING
         if (axis==Z_AXIS) {
           engage_z_probe();
         }
       else
-      #endif
+        #endif
       if (servo_endstops[axis] > -1) {
         servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
       }
-    #endif
+      #endif
+    #endif // Z_PROBE_AND_ENDSTOP
 #endif // Z_PROBE_SLED
     #ifdef Z_DUAL_ENDSTOPS
       if (axis==Z_AXIS) In_Homing_Process(true);
@@ -1922,10 +1924,12 @@ inline void gcode_G28() {
 
         if (home_all_axis || code_seen(axis_codes[Z_AXIS])) {
           #if defined(Z_RAISE_BEFORE_HOMING) && Z_RAISE_BEFORE_HOMING > 0
+            #ifndef Z_PROBE_AND_ENDSTOP
             destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
             feedrate = max_feedrate[Z_AXIS];
             plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
             st_synchronize();
+            #endif
           #endif
           HOMEAXIS(Z);
         }

From 666fad349471c7d1d3b5556d30497966df5f7104 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 03:25:03 -0500
Subject: [PATCH 17/83] Typo fixed in sanity check.

---
 Marlin/SanityCheck.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 8c60415fa89..11d4d846451 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -106,7 +106,7 @@
       #if Z_PROBE_PIN == -1
         #error You must have a Z_PROBE_PIN defined if you enable Z_PROBE_AND_ENDSTOP
       #endif
-      #ifndef (NUM_SERVOS)
+      #ifndef NUM_SERVOS
         #error You must have NUM_SERVOS defined and there must be at least 1 configured to use Z_PROBE_AND_ENDSTOP
       #endif
       #if defined(NUM_SERVOS) && NUM_SERVOS < 1

From 62834a1c43ad20fe815d52fef1d3c1944b81a609 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 03:55:41 -0500
Subject: [PATCH 18/83] Don't deploy probe on Z Axis homing if
 Z_PROBE_AND_ENDSTOP is enabled, unless Z_SAFE_HOMING is.

---
 Marlin/Marlin_main.cpp | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index a020c6e0d52..520d4a6a50b 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1493,20 +1493,18 @@ static void homeaxis(int axis) {
 
 
 #ifndef Z_PROBE_SLED
-    // Engage Servo endstop if enabled and we are not using Z_PROBE_AND_ENDSTOP
-    #ifndef Z_PROBE_AND_ENDSTOP
-      #ifdef SERVO_ENDSTOPS
-        #if SERVO_LEVELING
+    // Engage Servo endstop if enabled and we are not using Z_PROBE_AND_ENDSTOP unless we are using Z_SAFE_HOMING
+    #ifdef SERVO_ENDSTOPS && (defined (Z_SAFE_HOMING) || ! defined (Z_PROBE_AND_ENDSTOP))
+      #if SERVO_LEVELING
         if (axis==Z_AXIS) {
           engage_z_probe();
         }
       else
-        #endif
+      #endif
       if (servo_endstops[axis] > -1) {
         servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
       }
-      #endif
-    #endif // Z_PROBE_AND_ENDSTOP
+    #endif
 #endif // Z_PROBE_SLED
     #ifdef Z_DUAL_ENDSTOPS
       if (axis==Z_AXIS) In_Homing_Process(true);

From a9802c95b32eac41b35b520db299fabf7a88e205 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Sun, 29 Mar 2015 04:18:37 -0500
Subject: [PATCH 19/83] Ensure Z_PROBE_PIN is defined if Z_PROBE_AND_ENDSTOP
 is.

---
 Marlin/SanityCheck.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 11d4d846451..1427da21274 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -103,8 +103,11 @@
      * Require a Z Probe Pin if Z_PROBE_AND_ENDSTOP is enabled.
      */
     #if defined(Z_PROBE_AND_ENDSTOP)
+      #ifndef Z_PROBE_PIN
+        #error You must have a Z_PROBE_PIN defined in your pins_XXXX.h file if you enable Z_PROBE_AND_ENDSTOP
+      #endif
       #if Z_PROBE_PIN == -1
-        #error You must have a Z_PROBE_PIN defined if you enable Z_PROBE_AND_ENDSTOP
+        #error You must set Z_PROBE_PIN to a valid pin if you enable Z_PROBE_AND_ENDSTOP
       #endif
       #ifndef NUM_SERVOS
         #error You must have NUM_SERVOS defined and there must be at least 1 configured to use Z_PROBE_AND_ENDSTOP

From 992b07ca5741fe179670d521f9e3912e720debf8 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Mon, 30 Mar 2015 22:58:10 -0500
Subject: [PATCH 20/83] Don't disable Z_RAISE_BEFORE_HOMING when
 Z_PROBE_AND_ENDSTOP is enabled.

---
 Marlin/Marlin_main.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 0f044535235..d4c454ba3b1 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2032,12 +2032,10 @@ inline void gcode_G28() {
         if (home_all_axis || homeZ) {
           // Raise Z before homing Z? Shouldn't this happen before homing X or Y?
           #if defined(Z_RAISE_BEFORE_HOMING) && Z_RAISE_BEFORE_HOMING > 0
-            #ifndef Z_PROBE_AND_ENDSTOP
             destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
             feedrate = max_feedrate[Z_AXIS];
             line_to_destination();
             st_synchronize();
-            #endif
           #endif
           HOMEAXIS(Z);
         }

From e08f8eed0581bb91c886ffbf7e1234ef58935501 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Mon, 30 Mar 2015 23:51:36 -0500
Subject: [PATCH 21/83] Revert 06f767d..cba5692

This rolls back to commit 06f767d608120f09bcd0fd0aee582220cd8657d9.
---
 Marlin/Marlin.h                               |   1 +
 Marlin/Marlin_main.cpp                        | 869 +++++++-----------
 Marlin/dogm_lcd_implementation.h              |   2 +-
 Marlin/planner.cpp                            |   4 +-
 Marlin/stepper.cpp                            | 115 +--
 Marlin/ultralcd.cpp                           |   2 +-
 .../ultralcd_implementation_hitachi_HD44780.h |  16 +-
 7 files changed, 409 insertions(+), 600 deletions(-)

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 45a94e82e34..46720d9a345 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -229,6 +229,7 @@ void refresh_cmd_timeout(void);
 extern float homing_feedrate[];
 extern bool axis_relative_modes[];
 extern int feedmultiply;
+extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
 extern bool volumetric_enabled;
 extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
 extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 0f044535235..00962062460 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -79,7 +79,7 @@
 // G4  - Dwell S<seconds> or P<milliseconds>
 // G10 - retract filament according to settings of M207
 // G11 - retract recover filament according to settings of M208
-// G28 - Home one or more axes
+// G28 - Home all Axis
 // G29 - Detailed Z-Probe, probes the bed at 3 or more points.  Will fail if you haven't homed yet.
 // G30 - Single Z Probe, probes bed at current XY location.
 // G31 - Dock sled (Z_PROBE_SLED only)
@@ -210,6 +210,7 @@ int homing_bump_divisor[] = HOMING_BUMP_DIVISOR;
 bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
 int feedmultiply = 100; //100->1 200->2
 int saved_feedmultiply;
+int extrudemultiply = 100; //100->1 200->2
 int extruder_multiply[EXTRUDERS] = ARRAY_BY_EXTRUDERS(100, 100, 100, 100);
 bool volumetric_enabled = false;
 float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA);
@@ -305,7 +306,7 @@ int fanSpeed = 0;
 #ifdef SCARA
   float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
   static float delta[3] = { 0, 0, 0 };		
-#endif
+#endif        
 
 bool cancel_heatup = false;
 
@@ -476,6 +477,8 @@ bool enquecommand(const char *cmd)
   return true;
 }
 
+
+
 void setup_killpin()
 {
   #if defined(KILL_PIN) && KILL_PIN > -1
@@ -898,7 +901,7 @@ bool code_seen(char code) {
   strchr_pointer = strchr(cmdbuffer[bufindr], code);
   return (strchr_pointer != NULL);  //Return True if a character was found
 }
-  
+
 #define DEFINE_PGM_READ_ANY(type, reader)       \
     static inline type pgm_read_any(const type *p)  \
     { return pgm_read_##reader##_near(p); }
@@ -929,7 +932,7 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir,  HOME_DIR);
 
   static float x_home_pos(int extruder) {
     if (extruder == 0)
-      return base_home_pos(X_AXIS) + home_offset[X_AXIS];
+    return base_home_pos(X_AXIS) + home_offset[X_AXIS];
     else
       // In dual carriage mode the extruder offset provides an override of the
       // second X-carriage offset when homed - otherwise X2_HOME_POS is used.
@@ -958,15 +961,15 @@ static void axis_is_at_home(int axis) {
     if (axis == X_AXIS) {
       if (active_extruder != 0) {
         current_position[X_AXIS] = x_home_pos(active_extruder);
-                 min_pos[X_AXIS] = X2_MIN_POS;
-                 max_pos[X_AXIS] = max(extruder_offset[1][X_AXIS], X2_MAX_POS);
+        min_pos[X_AXIS] = X2_MIN_POS;
+        max_pos[X_AXIS] = max(extruder_offset[1][X_AXIS], X2_MAX_POS);
         return;
       }
       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
-        float xoff = home_offset[X_AXIS];
-        current_position[X_AXIS] = base_home_pos(X_AXIS) + xoff;
-                 min_pos[X_AXIS] = base_min_pos(X_AXIS) + xoff;
-                 max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + xoff, max(extruder_offset[1][X_AXIS], X2_MAX_POS) - duplicate_extruder_x_offset);
+        current_position[X_AXIS] = base_home_pos(X_AXIS) + home_offset[X_AXIS];
+        min_pos[X_AXIS] = base_min_pos(X_AXIS) + home_offset[X_AXIS];
+        max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + home_offset[X_AXIS],
+                                max(extruder_offset[1][X_AXIS], X2_MAX_POS) - duplicate_extruder_x_offset);
         return;
       }
     }
@@ -1020,189 +1023,178 @@ static void axis_is_at_home(int axis) {
 }
 
 /**
- * Some planner shorthand inline functions
+ * Shorthand to tell the planner our current position (in mm).
  */
-inline void line_to_current_position() {
-  plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
-}
-inline void line_to_z(float zPosition) {
-  plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
-}
-inline void line_to_destination() {
-  plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
-}
 inline void sync_plan_position() {
   plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 }
 
 #ifdef ENABLE_AUTO_BED_LEVELING
+#ifdef AUTO_BED_LEVELING_GRID
 
-  #ifdef AUTO_BED_LEVELING_GRID
+#ifndef DELTA
+  static void set_bed_level_equation_lsq(double *plane_equation_coefficients) {
+    vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
+    planeNormal.debug("planeNormal");
+    plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
+    //bedLevel.debug("bedLevel");
 
-    #ifndef DELTA
+    //plan_bed_level_matrix.debug("bed level before");
+    //vector_3 uncorrected_position = plan_get_position_mm();
+    //uncorrected_position.debug("position before");
 
-      static void set_bed_level_equation_lsq(double *plane_equation_coefficients) {
-        vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
-        planeNormal.debug("planeNormal");
-        plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
-        //bedLevel.debug("bedLevel");
+    vector_3 corrected_position = plan_get_position();
+    //corrected_position.debug("position after");
+    current_position[X_AXIS] = corrected_position.x;
+    current_position[Y_AXIS] = corrected_position.y;
+    current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
 
-        //plan_bed_level_matrix.debug("bed level before");
-        //vector_3 uncorrected_position = plan_get_position_mm();
-        //uncorrected_position.debug("position before");
+    sync_plan_position();
+  }
+#endif
 
-        vector_3 corrected_position = plan_get_position();
-        //corrected_position.debug("position after");
-        current_position[X_AXIS] = corrected_position.x;
-        current_position[Y_AXIS] = corrected_position.y;
-        current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
+#else // not AUTO_BED_LEVELING_GRID
 
-        sync_plan_position();
-      }
+static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) {
 
-    #endif // !DELTA
+    plan_bed_level_matrix.set_to_identity();
 
-  #else // !AUTO_BED_LEVELING_GRID
+    vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1);
+    vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2);
+    vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3);
+    vector_3 planeNormal = vector_3::cross(pt1 - pt2, pt3 - pt2).get_normal();
 
-    static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) {
-
-      plan_bed_level_matrix.set_to_identity();
-
-      vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1);
-      vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2);
-      vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3);
-      vector_3 planeNormal = vector_3::cross(pt1 - pt2, pt3 - pt2).get_normal();
-
-      if (planeNormal.z < 0) {
-        planeNormal.x = -planeNormal.x;
-        planeNormal.y = -planeNormal.y;
-        planeNormal.z = -planeNormal.z;
-      }
-
-      plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
-
-      vector_3 corrected_position = plan_get_position();
-      current_position[X_AXIS] = corrected_position.x;
-      current_position[Y_AXIS] = corrected_position.y;
-      current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
-
-      sync_plan_position();
+    if (planeNormal.z < 0) {
+      planeNormal.x = -planeNormal.x;
+      planeNormal.y = -planeNormal.y;
+      planeNormal.z = -planeNormal.z;
     }
 
-  #endif // !AUTO_BED_LEVELING_GRID
+    plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
 
-  static void run_z_probe() {
+    vector_3 corrected_position = plan_get_position();
+    current_position[X_AXIS] = corrected_position.x;
+    current_position[Y_AXIS] = corrected_position.y;
+    current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
 
-    #ifdef DELTA
+    sync_plan_position();
+}
+
+#endif // AUTO_BED_LEVELING_GRID
+
+static void run_z_probe() {
+  #ifdef DELTA
     
-      float start_z = current_position[Z_AXIS];
-      long start_steps = st_get_position(Z_AXIS);
+    float start_z = current_position[Z_AXIS];
+    long start_steps = st_get_position(Z_AXIS);
+  
+    // move down slowly until you find the bed
+    feedrate = homing_feedrate[Z_AXIS] / 4;
+    destination[Z_AXIS] = -10;
+    prepare_move_raw();
+    st_synchronize();
+    endstops_hit_on_purpose();
     
-      // move down slowly until you find the bed
-      feedrate = homing_feedrate[Z_AXIS] / 4;
-      destination[Z_AXIS] = -10;
-      prepare_move_raw();
-      st_synchronize();
-      endstops_hit_on_purpose();
-      
-      // we have to let the planner know where we are right now as it is not where we said to go.
-      long stop_steps = st_get_position(Z_AXIS);
-      float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
-      current_position[Z_AXIS] = mm;
-      calculate_delta(current_position);
-      plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
-      
-    #else // !DELTA
+    // we have to let the planner know where we are right now as it is not where we said to go.
+    long stop_steps = st_get_position(Z_AXIS);
+    float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
+    current_position[Z_AXIS] = mm;
+    calculate_delta(current_position);
+    plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
+    
+  #else
 
-      plan_bed_level_matrix.set_to_identity();
-      feedrate = homing_feedrate[Z_AXIS];
+    plan_bed_level_matrix.set_to_identity();
+    feedrate = homing_feedrate[Z_AXIS];
 
-      // move down until you find the bed
-      float zPosition = -10;
-      line_to_z(zPosition);
-      st_synchronize();
+    // move down until you find the bed
+    float zPosition = -10;
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
+    st_synchronize();
 
-      // we have to let the planner know where we are right now as it is not where we said to go.
-      zPosition = st_get_position_mm(Z_AXIS);
-      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
+        // we have to let the planner know where we are right now as it is not where we said to go.
+    zPosition = st_get_position_mm(Z_AXIS);
+    plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
 
-      // move up the retract distance
-      zPosition += home_retract_mm(Z_AXIS);
-      line_to_z(zPosition);
-      st_synchronize();
-      endstops_hit_on_purpose();
+    // move up the retract distance
+    zPosition += home_retract_mm(Z_AXIS);
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
+    st_synchronize();
+    endstops_hit_on_purpose();
 
-      // move back down slowly to find bed
-      if (homing_bump_divisor[Z_AXIS] >= 1)
-        feedrate = homing_feedrate[Z_AXIS] / homing_bump_divisor[Z_AXIS];
-      else {
-        feedrate = homing_feedrate[Z_AXIS] / 10;
-        SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
-      }
+    // move back down slowly to find bed
+    if (homing_bump_divisor[Z_AXIS] >= 1) {
+      feedrate = homing_feedrate[Z_AXIS]/homing_bump_divisor[Z_AXIS];
+    } 
+    else {
+      feedrate = homing_feedrate[Z_AXIS]/10;
+      SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less then 1");
+    }
 
-      zPosition -= home_retract_mm(Z_AXIS) * 2;
-      line_to_z(zPosition);
-      st_synchronize();
-      endstops_hit_on_purpose();
+    zPosition -= home_retract_mm(Z_AXIS) * 2;
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
+    st_synchronize();
+    endstops_hit_on_purpose();
 
-      current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
-      // make sure the planner knows where we are as it may be a bit different than we last said to move to
-      sync_plan_position();
-      
-    #endif // !DELTA
-  }
+    current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
+    // make sure the planner knows where we are as it may be a bit different than we last said to move to
+    sync_plan_position();
+    
+  #endif
+}
 
-  static void do_blocking_move_to(float x, float y, float z) {
+static void do_blocking_move_to(float x, float y, float z) {
     float oldFeedRate = feedrate;
 
-    #ifdef DELTA
+#ifdef DELTA
 
-      feedrate = XY_TRAVEL_SPEED;
-      
-      destination[X_AXIS] = x;
-      destination[Y_AXIS] = y;
-      destination[Z_AXIS] = z;
-      prepare_move_raw();
-      st_synchronize();
+    feedrate = XY_TRAVEL_SPEED;
+    
+    destination[X_AXIS] = x;
+    destination[Y_AXIS] = y;
+    destination[Z_AXIS] = z;
+    prepare_move_raw();
+    st_synchronize();
 
-    #else
+#else
 
-      feedrate = homing_feedrate[Z_AXIS];
+    feedrate = homing_feedrate[Z_AXIS];
 
-      current_position[Z_AXIS] = z;
-      line_to_current_position();
-      st_synchronize();
+    current_position[Z_AXIS] = z;
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
+    st_synchronize();
 
-      feedrate = xy_travel_speed;
+    feedrate = xy_travel_speed;
 
-      current_position[X_AXIS] = x;
-      current_position[Y_AXIS] = y;
-      line_to_current_position();
-      st_synchronize();
+    current_position[X_AXIS] = x;
+    current_position[Y_AXIS] = y;
+    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
+    st_synchronize();
 
-    #endif
+#endif
 
     feedrate = oldFeedRate;
-  }
+}
 
-  static void setup_for_endstop_move() {
+static void setup_for_endstop_move() {
     saved_feedrate = feedrate;
     saved_feedmultiply = feedmultiply;
     feedmultiply = 100;
     previous_millis_cmd = millis();
-    enable_endstops(true);
-  }
 
-  static void clean_up_after_endstop_move() {
-    #ifdef ENDSTOPS_ONLY_FOR_HOMING
-      enable_endstops(false);
-    #endif
+    enable_endstops(true);
+}
+
+static void clean_up_after_endstop_move() {
+#ifdef ENDSTOPS_ONLY_FOR_HOMING
+    enable_endstops(false);
+#endif
+
     feedrate = saved_feedrate;
     feedmultiply = saved_feedmultiply;
     previous_millis_cmd = millis();
-  }
+}
 
-<<<<<<< HEAD
 static void engage_z_probe() {
   // Engage Z Servo endstop if enabled
   #ifdef SERVO_ENDSTOPS
@@ -1250,59 +1242,13 @@ static void engage_z_probe() {
             SERIAL_ERROR_START;
             SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
             LCD_ALERTMESSAGEPGM("Err: ZPROBE");
-=======
-  static void engage_z_probe() {
-
-    #ifdef SERVO_ENDSTOPS
-
-      // Engage Z Servo endstop if enabled
-      if (servo_endstops[Z_AXIS] >= 0) {
-        #if SERVO_LEVELING
-          servos[servo_endstops[Z_AXIS]].attach(0);
-        #endif
-        servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2]);
-        #if SERVO_LEVELING
-          delay(PROBE_SERVO_DEACTIVATION_DELAY);
-          servos[servo_endstops[Z_AXIS]].detach();
-        #endif
-      }
-
-    #elif defined(Z_PROBE_ALLEN_KEY)
-
-      feedrate = homing_feedrate[X_AXIS];
-
-      // Move to the start position to initiate deployment
-      destination[X_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_X;
-      destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_Y;
-      destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_Z;
-      prepare_move_raw();
-
-      // Home X to touch the belt
-      feedrate = homing_feedrate[X_AXIS]/10;
-      destination[X_AXIS] = 0;
-      prepare_move_raw();
-      
-      // Home Y for safety
-      feedrate = homing_feedrate[X_AXIS]/2;
-      destination[Y_AXIS] = 0;
-      prepare_move_raw();
-      
-      st_synchronize();
-      
-      bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-      if (z_min_endstop) {
-        if (!Stopped) {
-          SERIAL_ERROR_START;
-          SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
-          LCD_ALERTMESSAGEPGM("Err: ZPROBE");
->>>>>>> MarlinFirmware/Development
         }
         Stop();
-      }
+    }
+  #endif
 
-    #endif // Z_PROBE_ALLEN_KEY
+}
 
-<<<<<<< HEAD
 static void retract_z_probe() {
   // Retract Z Servo endstop if enabled
   #ifdef SERVO_ENDSTOPS
@@ -1365,216 +1311,126 @@ static void retract_z_probe() {
             SERIAL_ERROR_START;
             SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
             LCD_ALERTMESSAGEPGM("Err: ZPROBE");
-=======
-  }
-
-  static void retract_z_probe(const float z_after=Z_RAISE_AFTER_PROBING) {
-
-    #ifdef SERVO_ENDSTOPS
-
-      // Retract Z Servo endstop if enabled
-      if (servo_endstops[Z_AXIS] >= 0) {
-
-        if (z_after > 0) {
-          do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_after);
-          st_synchronize();
->>>>>>> MarlinFirmware/Development
-        }
-      
-        #if SERVO_LEVELING
-          servos[servo_endstops[Z_AXIS]].attach(0);
-        #endif
-
-        servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2 + 1]);
-
-        #if SERVO_LEVELING
-          delay(PROBE_SERVO_DEACTIVATION_DELAY);
-          servos[servo_endstops[Z_AXIS]].detach();
-        #endif
-      }
-
-    #elif defined(Z_PROBE_ALLEN_KEY)
-
-      // Move up for safety
-      feedrate = homing_feedrate[X_AXIS];
-      destination[Z_AXIS] = current_position[Z_AXIS] + Z_RAISE_AFTER_PROBING;
-      prepare_move_raw();
-
-      // Move to the start position to initiate retraction
-      destination[X_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_X;
-      destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Y;
-      destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Z;
-      prepare_move_raw();
-
-      // Move the nozzle down to push the probe into retracted position
-      feedrate = homing_feedrate[Z_AXIS]/10;
-      destination[Z_AXIS] = current_position[Z_AXIS] - Z_PROBE_ALLEN_KEY_RETRACT_DEPTH;
-      prepare_move_raw();
-      
-      // Move up for safety
-      feedrate = homing_feedrate[Z_AXIS]/2;
-      destination[Z_AXIS] = current_position[Z_AXIS] + Z_PROBE_ALLEN_KEY_RETRACT_DEPTH * 2;
-      prepare_move_raw();
-      
-      // Home XY for safety
-      feedrate = homing_feedrate[X_AXIS]/2;
-      destination[X_AXIS] = 0;
-      destination[Y_AXIS] = 0;
-      prepare_move_raw();
-      
-      st_synchronize();
-      
-      bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-      if (!z_min_endstop) {
-        if (!Stopped) {
-          SERIAL_ERROR_START;
-          SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
-          LCD_ALERTMESSAGEPGM("Err: ZPROBE");
         }
         Stop();
-      }
+    }
+  #endif
 
-    #endif
+}
 
+enum ProbeAction {
+  ProbeStay             = 0,
+  ProbeEngage           = BIT(0),
+  ProbeRetract          = BIT(1),
+  ProbeEngageAndRetract = (ProbeEngage | ProbeRetract)
+};
+
+/// Probe bed height at position (x,y), returns the measured z value
+static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageAndRetract, int verbose_level=1) {
+  // move to right place
+  do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
+  do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
+
+  #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
+    if (retract_action & ProbeEngage) engage_z_probe();
+  #endif
+
+  run_z_probe();
+  float measured_z = current_position[Z_AXIS];
+
+  #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
+    if (retract_action & ProbeRetract) retract_z_probe();
+  #endif
+
+  if (verbose_level > 2) {
+    SERIAL_PROTOCOLPGM(MSG_BED);
+    SERIAL_PROTOCOLPGM(" X: ");
+    SERIAL_PROTOCOL_F(x, 3);
+    SERIAL_PROTOCOLPGM(" Y: ");
+    SERIAL_PROTOCOL_F(y, 3);
+    SERIAL_PROTOCOLPGM(" Z: ");
+    SERIAL_PROTOCOL_F(measured_z, 3);
+    SERIAL_EOL;
   }
+  return measured_z;
+}
 
-  enum ProbeAction {
-    ProbeStay             = 0,
-    ProbeEngage           = BIT(0),
-    ProbeRetract          = BIT(1),
-    ProbeEngageAndRetract = (ProbeEngage | ProbeRetract)
-  };
-
-  // Probe bed height at position (x,y), returns the measured z value
-  static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageAndRetract, int verbose_level=1) {
-    // move to right place
-    do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
-    do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
-
-    #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-      if (retract_action & ProbeEngage) engage_z_probe();
-    #endif
-
-    run_z_probe();
-    float measured_z = current_position[Z_AXIS];
-
-    #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-      if (retract_action & ProbeRetract) retract_z_probe(z_before);
-    #endif
-
-    if (verbose_level > 2) {
-      SERIAL_PROTOCOLPGM(MSG_BED);
-      SERIAL_PROTOCOLPGM(" X: ");
-      SERIAL_PROTOCOL_F(x, 3);
-      SERIAL_PROTOCOLPGM(" Y: ");
-      SERIAL_PROTOCOL_F(y, 3);
-      SERIAL_PROTOCOLPGM(" Z: ");
-      SERIAL_PROTOCOL_F(measured_z, 3);
-      SERIAL_EOL;
-    }
-    return measured_z;
+#ifdef DELTA
+static void extrapolate_one_point(int x, int y, int xdir, int ydir) {
+  if (bed_level[x][y] != 0.0) {
+    return;  // Don't overwrite good values.
   }
+  float a = 2*bed_level[x+xdir][y] - bed_level[x+xdir*2][y];  // Left to right.
+  float b = 2*bed_level[x][y+ydir] - bed_level[x][y+ydir*2];  // Front to back.
+  float c = 2*bed_level[x+xdir][y+ydir] - bed_level[x+xdir*2][y+ydir*2];  // Diagonal.
+  float median = c;  // Median is robust (ignores outliers).
+  if (a < b) {
+    if (b < c) median = b;
+    if (c < a) median = a;
+  } else {  // b <= a
+    if (c < b) median = b;
+    if (a < c) median = a;
+  }
+  bed_level[x][y] = median;
+}
 
-  #ifdef DELTA
-
-    /**
-     * All DELTA leveling in the Marlin uses NONLINEAR_BED_LEVELING
-     */
-
-    static void extrapolate_one_point(int x, int y, int xdir, int ydir) {
-      if (bed_level[x][y] != 0.0) {
-        return;  // Don't overwrite good values.
-      }
-      float a = 2*bed_level[x+xdir][y] - bed_level[x+xdir*2][y];  // Left to right.
-      float b = 2*bed_level[x][y+ydir] - bed_level[x][y+ydir*2];  // Front to back.
-      float c = 2*bed_level[x+xdir][y+ydir] - bed_level[x+xdir*2][y+ydir*2];  // Diagonal.
-      float median = c;  // Median is robust (ignores outliers).
-      if (a < b) {
-        if (b < c) median = b;
-        if (c < a) median = a;
-      } else {  // b <= a
-        if (c < b) median = b;
-        if (a < c) median = a;
-      }
-      bed_level[x][y] = median;
+// Fill in the unprobed points (corners of circular print surface)
+// using linear extrapolation, away from the center.
+static void extrapolate_unprobed_bed_level() {
+  int half = (AUTO_BED_LEVELING_GRID_POINTS-1)/2;
+  for (int y = 0; y <= half; y++) {
+    for (int x = 0; x <= half; x++) {
+      if (x + y < 3) continue;
+      extrapolate_one_point(half-x, half-y, x>1?+1:0, y>1?+1:0);
+      extrapolate_one_point(half+x, half-y, x>1?-1:0, y>1?+1:0);
+      extrapolate_one_point(half-x, half+y, x>1?+1:0, y>1?-1:0);
+      extrapolate_one_point(half+x, half+y, x>1?-1:0, y>1?-1:0);
     }
+  }
+}
 
-    // Fill in the unprobed points (corners of circular print surface)
-    // using linear extrapolation, away from the center.
-    static void extrapolate_unprobed_bed_level() {
-      int half = (AUTO_BED_LEVELING_GRID_POINTS-1)/2;
-      for (int y = 0; y <= half; y++) {
-        for (int x = 0; x <= half; x++) {
-          if (x + y < 3) continue;
-          extrapolate_one_point(half-x, half-y, x>1?+1:0, y>1?+1:0);
-          extrapolate_one_point(half+x, half-y, x>1?-1:0, y>1?+1:0);
-          extrapolate_one_point(half-x, half+y, x>1?+1:0, y>1?-1:0);
-          extrapolate_one_point(half+x, half+y, x>1?-1:0, y>1?-1:0);
-        }
-      }
+// Print calibration results for plotting or manual frame adjustment.
+static void print_bed_level() {
+  for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
+    for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
+      SERIAL_PROTOCOL_F(bed_level[x][y], 2);
+      SERIAL_PROTOCOLPGM(" ");
     }
+    SERIAL_ECHOLN("");
+  }
+}
 
-    // Print calibration results for plotting or manual frame adjustment.
-    static void print_bed_level() {
-      for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
-        for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
-          SERIAL_PROTOCOL_F(bed_level[x][y], 2);
-          SERIAL_PROTOCOLPGM(" ");
-        }
-        SERIAL_ECHOLN("");
-      }
+// Reset calibration results to zero.
+void reset_bed_level() {
+  for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
+    for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
+      bed_level[x][y] = 0.0;
     }
+  }
+}
 
-    // Reset calibration results to zero.
-    void reset_bed_level() {
-      for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
-        for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
-          bed_level[x][y] = 0.0;
-        }
-      }
-    }
-
-  #endif // DELTA
+#endif // DELTA
 
 #endif // ENABLE_AUTO_BED_LEVELING
 
 static void homeaxis(int axis) {
-  #define HOMEAXIS_DO(LETTER) \
-    ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
+#define HOMEAXIS_DO(LETTER) \
+  ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
 
-  if (axis == X_AXIS ? HOMEAXIS_DO(X) :
-      axis == Y_AXIS ? HOMEAXIS_DO(Y) :
-      axis == Z_AXIS ? HOMEAXIS_DO(Z) : 0) {
-
-    int axis_home_dir;
-
-    #ifdef DUAL_X_CARRIAGE
-      if (axis == X_AXIS) axis_home_dir = x_home_dir(active_extruder);
-    #else
-      axis_home_dir = home_dir(axis);
-    #endif
+  if (axis==X_AXIS ? HOMEAXIS_DO(X) :
+      axis==Y_AXIS ? HOMEAXIS_DO(Y) :
+      axis==Z_AXIS ? HOMEAXIS_DO(Z) :
+      0) {
+    int axis_home_dir = home_dir(axis);
+#ifdef DUAL_X_CARRIAGE
+    if (axis == X_AXIS)
+      axis_home_dir = x_home_dir(active_extruder);
+#endif
 
     current_position[axis] = 0;
     sync_plan_position();
 
-    #ifndef Z_PROBE_SLED
-      // Engage Servo endstop if enabled
-      #ifdef SERVO_ENDSTOPS
-        #if SERVO_LEVELING
-          if (axis == Z_AXIS) {
-            engage_z_probe();
-          }
-          else
-        #endif // SERVO_LEVELING
 
-        if (servo_endstops[axis] > -1)
-          servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
-
-      #endif // SERVO_ENDSTOPS
-
-    #endif // Z_PROBE_SLED
-
-<<<<<<< HEAD
 #ifndef Z_PROBE_SLED
     // Engage Servo endstop if enabled and we are not using Z_PROBE_AND_ENDSTOP unless we are using Z_SAFE_HOMING
     #ifdef SERVO_ENDSTOPS && (defined (Z_SAFE_HOMING) || ! defined (Z_PROBE_AND_ENDSTOP))
@@ -1589,33 +1445,33 @@ static void homeaxis(int axis) {
       }
     #endif
 #endif // Z_PROBE_SLED
-=======
->>>>>>> MarlinFirmware/Development
     #ifdef Z_DUAL_ENDSTOPS
-      if (axis == Z_AXIS) In_Homing_Process(true);
+      if (axis==Z_AXIS) In_Homing_Process(true);
     #endif
-
     destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
     feedrate = homing_feedrate[axis];
-    line_to_destination();
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
     st_synchronize();
 
     current_position[axis] = 0;
     sync_plan_position();
     destination[axis] = -home_retract_mm(axis) * axis_home_dir;
-    line_to_destination();
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
     st_synchronize();
 
-    destination[axis] = 2 * home_retract_mm(axis) * axis_home_dir;
+    destination[axis] = 2*home_retract_mm(axis) * axis_home_dir;
 
     if (homing_bump_divisor[axis] >= 1)
-      feedrate = homing_feedrate[axis] / homing_bump_divisor[axis];
-    else {
-      feedrate = homing_feedrate[axis] / 10;
-      SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
+    {
+        feedrate = homing_feedrate[axis]/homing_bump_divisor[axis];
+    } 
+    else
+    {
+        feedrate = homing_feedrate[axis]/10;
+        SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less then 1");
     }
 
-    line_to_destination();
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
     st_synchronize();
     #ifdef Z_DUAL_ENDSTOPS
       if (axis==Z_AXIS)
@@ -1630,7 +1486,7 @@ static void homeaxis(int axis) {
           destination[axis] = fabs(z_endstop_adj);
           if (z_endstop_adj < 0) Lock_z_motor(true); else Lock_z2_motor(true);        
         }
-        line_to_destination();
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         st_synchronize();
         Lock_z_motor(false);
         Lock_z2_motor(false);
@@ -1643,7 +1499,7 @@ static void homeaxis(int axis) {
     if (endstop_adj[axis] * axis_home_dir < 0) {
       sync_plan_position();
       destination[axis] = endstop_adj[axis];
-      line_to_destination();
+      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
       st_synchronize();
     }
 #endif
@@ -1688,7 +1544,7 @@ void refresh_cmd_timeout(void)
       }
       plan_set_e_position(current_position[E_AXIS]);
       float oldFeedrate = feedrate;
-      feedrate = retract_feedrate * 60;
+      feedrate=retract_feedrate*60;
       retracted[active_extruder]=true;
       prepare_move();
       if(retract_zlift > 0.01) {
@@ -1724,8 +1580,8 @@ void refresh_cmd_timeout(void)
       }
       plan_set_e_position(current_position[E_AXIS]);
       float oldFeedrate = feedrate;
-      feedrate = retract_recover_feedrate * 60;
-      retracted[active_extruder] = false;
+      feedrate=retract_recover_feedrate*60;
+      retracted[active_extruder]=false;
       prepare_move();
       feedrate = oldFeedrate;
     }
@@ -1879,16 +1735,17 @@ inline void gcode_G4() {
  */
 inline void gcode_G28() {
   #ifdef ENABLE_AUTO_BED_LEVELING
-    plan_bed_level_matrix.set_to_identity();  //Reset the plane ("erase" all leveling data)
     #ifdef DELTA
       reset_bed_level();
+    #else
+      plan_bed_level_matrix.set_to_identity();  //Reset the plane ("erase" all leveling data)
     #endif
   #endif
 
   #if defined(MESH_BED_LEVELING)
     uint8_t mbl_was_active = mbl.active;
     mbl.active = 0;
-  #endif
+  #endif  // MESH_BED_LEVELING
 
   saved_feedrate = feedrate;
   saved_feedmultiply = feedmultiply;
@@ -1911,7 +1768,7 @@ inline void gcode_G28() {
 
     for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * Z_MAX_LENGTH;
     feedrate = 1.732 * homing_feedrate[X_AXIS];
-    line_to_destination();
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
     st_synchronize();
     endstops_hit_on_purpose();
 
@@ -1959,7 +1816,7 @@ inline void gcode_G28() {
         } else {
           feedrate *= sqrt(pow(max_length(X_AXIS) / max_length(Y_AXIS), 2) + 1);
         }
-        line_to_destination();
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         st_synchronize();
 
         axis_is_at_home(X_AXIS);
@@ -1967,7 +1824,7 @@ inline void gcode_G28() {
         sync_plan_position();
         destination[X_AXIS] = current_position[X_AXIS];
         destination[Y_AXIS] = current_position[Y_AXIS];
-        line_to_destination();
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
         feedrate = 0.0;
         st_synchronize();
         endstops_hit_on_purpose();
@@ -2035,7 +1892,7 @@ inline void gcode_G28() {
             #ifndef Z_PROBE_AND_ENDSTOP
             destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
             feedrate = max_feedrate[Z_AXIS];
-            line_to_destination();
+            plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
             st_synchronize();
             #endif
           #endif
@@ -2048,11 +1905,11 @@ inline void gcode_G28() {
           destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER);
           destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER);
           destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
-          feedrate = XY_TRAVEL_SPEED;
+          feedrate = XY_TRAVEL_SPEED / 60;
           current_position[Z_AXIS] = 0;
 
           sync_plan_position();
-          line_to_destination();
+          plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
           st_synchronize();
           current_position[X_AXIS] = destination[X_AXIS];
           current_position[Y_AXIS] = destination[Y_AXIS];
@@ -2074,7 +1931,7 @@ inline void gcode_G28() {
               plan_set_position(cpx, cpy, current_position[Z_AXIS], current_position[E_AXIS]);
               destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
               feedrate = max_feedrate[Z_AXIS];
-              line_to_destination();
+              plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
               st_synchronize();
               HOMEAXIS(Z);
             }
@@ -2127,7 +1984,7 @@ inline void gcode_G28() {
       destination[Z_AXIS] = current_position[Z_AXIS];
       destination[E_AXIS] = current_position[E_AXIS];
       feedrate = homing_feedrate[X_AXIS];
-      line_to_destination();
+      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
       st_synchronize();
       current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
       sync_plan_position();
@@ -2141,19 +1998,6 @@ inline void gcode_G28() {
   endstops_hit_on_purpose();
 }
 
-#if defined(MESH_BED_LEVELING) || defined(ENABLE_AUTO_BED_LEVELING)
-
-  // Check for known positions in X and Y
-  inline bool can_run_bed_leveling() {
-  	if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) return true;
-    LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
-    SERIAL_ECHO_START;
-    SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
-    return false;
-  }
-
-#endif // MESH_BED_LEVELING || ENABLE_AUTO_BED_LEVELING
-
 #ifdef MESH_BED_LEVELING
 
   /**
@@ -2168,10 +2012,6 @@ inline void gcode_G28() {
    *
    */
   inline void gcode_G29() {
-
-    // Prevent leveling without first homing in X and Y
-    if (!can_run_bed_leveling()) return;
-
     static int probe_point = -1;
     int state = 0;
     if (code_seen('S') || code_seen('s')) {
@@ -2288,8 +2128,13 @@ inline void gcode_G28() {
    */
   inline void gcode_G29() {
 
-    // Prevent leveling without first homing in X and Y
-    if (!can_run_bed_leveling()) return;
+    // Prevent user from running a G29 without first homing in X and Y
+    if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
+      LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
+      SERIAL_ECHO_START;
+      SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
+      return;
+    }
 
     int verbose_level = 1;
 
@@ -2371,15 +2216,16 @@ inline void gcode_G28() {
 
     st_synchronize();
 
-    if (!dryrun) {
-      // make sure the bed_level_rotation_matrix is identity or the planner will get it wrong
-      plan_bed_level_matrix.set_to_identity();
-
+    if (!dryrun)
+    {
       #ifdef DELTA
         reset_bed_level();
       #else //!DELTA
+
+        // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
         //vector_3 corrected_position = plan_get_position_mm();
         //corrected_position.debug("position before G29");
+        plan_bed_level_matrix.set_to_identity();
         vector_3 uncorrected_position = plan_get_position();
         //uncorrected_position.debug("position during G29");
         current_position[X_AXIS] = uncorrected_position.x;
@@ -2387,7 +2233,7 @@ inline void gcode_G28() {
         current_position[Z_AXIS] = uncorrected_position.z;
         sync_plan_position();
 
-      #endif // !DELTA
+      #endif
     }
     
     setup_for_endstop_move();
@@ -2448,12 +2294,13 @@ inline void gcode_G28() {
 
           // raise extruder
           float measured_z,
-                z_before = Z_RAISE_BETWEEN_PROBINGS + (probePointCounter ? current_position[Z_AXIS] : 0);
+                z_before = probePointCounter == 0 ? Z_RAISE_BEFORE_PROBING : current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS;
 
           #ifdef DELTA
             // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.
             float distance_from_center = sqrt(xProbe*xProbe + yProbe*yProbe);
-            if (distance_from_center > DELTA_PROBABLE_RADIUS) continue;
+            if (distance_from_center > DELTA_PROBABLE_RADIUS)
+              continue;
           #endif //DELTA
 
           // Enhanced G29 - Do not retract servo between probes
@@ -2481,11 +2328,6 @@ inline void gcode_G28() {
           #endif
 
           probePointCounter++;
-
-          manage_heater();
-          manage_inactivity();
-          lcd_update();
-
         } //xProbe
       } //yProbe
 
@@ -2572,14 +2414,16 @@ inline void gcode_G28() {
       if (verbose_level > 0)
         plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
 
-      if (!dryrun) {
-        // Correct the Z height difference from z-probe position and hotend tip position.
-        // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
-        // When the bed is uneven, this height must be corrected.
-        float x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER,
-              y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER,
-              z_tmp = current_position[Z_AXIS],
-              real_z = (float)st_get_position(Z_AXIS) / axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
+      // Correct the Z height difference from z-probe position and hotend tip position.
+      // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
+      // When the bed is uneven, this height must be corrected.
+      if (!dryrun)
+      {
+        float x_tmp, y_tmp, z_tmp, real_z;
+        real_z = float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
+        x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER;
+        y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER;
+        z_tmp = current_position[Z_AXIS];
 
         apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp);         //Apply the correction sending the probe offset
         current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS];   //The difference is added to current position and sent to planner.
@@ -3947,7 +3791,7 @@ inline void gcode_M221() {
       extruder_multiply[tmp_extruder] = sval;
     }
     else {
-      extruder_multiply[active_extruder] = sval;
+      extrudemultiply = sval;
     }
   }
 }
@@ -4384,7 +4228,7 @@ inline void gcode_M400() { st_synchronize(); }
     //SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
     //SERIAL_PROTOCOL(filament_width_meas);
     //SERIAL_PROTOCOLPGM("Extrusion ratio(%):");
-    //SERIAL_PROTOCOL(extruder_multiply[active_extruder]);
+    //SERIAL_PROTOCOL(extrudemultiply);
   }
 
   /**
@@ -4857,14 +4701,18 @@ void process_commands() {
       gcode_G28();
       break;
 
-    #if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
-      case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
+    #if defined(MESH_BED_LEVELING)
+      case 29: // G29 Handle mesh based leveling
         gcode_G29();
         break;
     #endif
 
     #ifdef ENABLE_AUTO_BED_LEVELING
 
+      case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
+        gcode_G29();
+        break;
+
       #ifndef Z_PROBE_SLED
 
         case 30: // G30 Single Z Probe
@@ -5559,72 +5407,69 @@ void prepare_move()
   
   #ifdef SCARA //for now same as delta-code
 
-    float difference[NUM_AXIS];
-    for (int8_t i = 0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i];
+float difference[NUM_AXIS];
+for (int8_t i=0; i < NUM_AXIS; i++) {
+  difference[i] = destination[i] - current_position[i];
+}
 
-    float cartesian_mm = sqrt(  sq(difference[X_AXIS]) +
-                                sq(difference[Y_AXIS]) +
-                                sq(difference[Z_AXIS]));
-    if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
-    if (cartesian_mm < 0.000001) { return; }
-    float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
-    int steps = max(1, int(scara_segments_per_second * seconds));
+float cartesian_mm = sqrt(  sq(difference[X_AXIS]) +
+              sq(difference[Y_AXIS]) +
+              sq(difference[Z_AXIS]));
+if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
+if (cartesian_mm < 0.000001) { return; }
+float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
+int steps = max(1, int(scara_segments_per_second * seconds));
+ //SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
+ //SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
+ //SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
+for (int s = 1; s <= steps; s++) {
+  float fraction = float(s) / float(steps);
+  for(int8_t i=0; i < NUM_AXIS; i++) {
+    destination[i] = current_position[i] + difference[i] * fraction;
+  }
 
-    //SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
-    //SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
-    //SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
-
-    for (int s = 1; s <= steps; s++) {
-      float fraction = float(s) / float(steps);
-      for(int8_t i = 0; i < NUM_AXIS; i++) {
-        destination[i] = current_position[i] + difference[i] * fraction;
-      }
   
-      calculate_delta(destination);
-      //SERIAL_ECHOPGM("destination[X_AXIS]="); SERIAL_ECHOLN(destination[X_AXIS]);
-      //SERIAL_ECHOPGM("destination[Y_AXIS]="); SERIAL_ECHOLN(destination[Y_AXIS]);
-      //SERIAL_ECHOPGM("destination[Z_AXIS]="); SERIAL_ECHOLN(destination[Z_AXIS]);
-      //SERIAL_ECHOPGM("delta[X_AXIS]="); SERIAL_ECHOLN(delta[X_AXIS]);
-      //SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
-      //SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
-
-      plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
-        destination[E_AXIS], feedrate*feedmultiply/60/100.0,
-        active_extruder);
-    }
-
-  #endif // SCARA
+  calculate_delta(destination);
+         //SERIAL_ECHOPGM("destination[X_AXIS]="); SERIAL_ECHOLN(destination[X_AXIS]);
+         //SERIAL_ECHOPGM("destination[Y_AXIS]="); SERIAL_ECHOLN(destination[Y_AXIS]);
+         //SERIAL_ECHOPGM("destination[Z_AXIS]="); SERIAL_ECHOLN(destination[Z_AXIS]);
+         //SERIAL_ECHOPGM("delta[X_AXIS]="); SERIAL_ECHOLN(delta[X_AXIS]);
+         //SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
+         //SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
+         
+  plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
+  destination[E_AXIS], feedrate*feedmultiply/60/100.0,
+  active_extruder);
+}
+#endif // SCARA
   
-  #ifdef DELTA
-
-    float difference[NUM_AXIS];
-    for (int8_t i=0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i];
-
-    float cartesian_mm = sqrt(sq(difference[X_AXIS]) +
-                              sq(difference[Y_AXIS]) +
-                              sq(difference[Z_AXIS]));
-    if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
-    if (cartesian_mm < 0.000001) return;
-    float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
-    int steps = max(1, int(delta_segments_per_second * seconds));
-
-    // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
-    // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
-    // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
-
-    for (int s = 1; s <= steps; s++) {
-      float fraction = float(s) / float(steps);
-      for (int8_t i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i] + difference[i] * fraction;
-      calculate_delta(destination);
-      #ifdef ENABLE_AUTO_BED_LEVELING
-        adjust_delta(destination);
-      #endif
-      plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
-                       destination[E_AXIS], feedrate*feedmultiply/60/100.0,
-                       active_extruder);
+#ifdef DELTA
+  float difference[NUM_AXIS];
+  for (int8_t i=0; i < NUM_AXIS; i++) {
+    difference[i] = destination[i] - current_position[i];
+  }
+  float cartesian_mm = sqrt(sq(difference[X_AXIS]) +
+                            sq(difference[Y_AXIS]) +
+                            sq(difference[Z_AXIS]));
+  if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
+  if (cartesian_mm < 0.000001) { return; }
+  float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
+  int steps = max(1, int(delta_segments_per_second * seconds));
+  // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
+  // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
+  // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
+  for (int s = 1; s <= steps; s++) {
+    float fraction = float(s) / float(steps);
+    for(int8_t i=0; i < NUM_AXIS; i++) {
+      destination[i] = current_position[i] + difference[i] * fraction;
     }
-
-  #endif // DELTA
+    calculate_delta(destination);
+    plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
+                     destination[E_AXIS], feedrate*feedmultiply/60/100.0,
+                     active_extruder);
+  }
+  
+#endif // DELTA
 
 #ifdef DUAL_X_CARRIAGE
   if (active_extruder_parked)
@@ -5670,13 +5515,13 @@ void prepare_move()
 #if ! (defined DELTA || defined SCARA)
   // Do not use feedmultiply for E or Z only moves
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
-    line_to_destination();
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
   } else {
 #if defined(MESH_BED_LEVELING)
-    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
+    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
     return;
 #else
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
 #endif  // MESH_BED_LEVELING
   }
 #endif // !(DELTA || SCARA)
diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index 63e99bd3aa9..89cd5e835c4 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -369,7 +369,7 @@ static void lcd_implementation_status_screen() {
       lcd_printPGM(PSTR("dia:"));
       lcd_print(ftostr12ns(filament_width_meas));
       lcd_printPGM(PSTR(" factor:"));
-      lcd_print(itostr3(volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
+      lcd_print(itostr3(extrudemultiply));
       lcd_print('%');
     }
   #endif
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index d98ef63d4df..786527d0d70 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -545,7 +545,7 @@ float junction_deviation = 0.1;
   block->steps[Z_AXIS] = labs(dz);
   block->steps[E_AXIS] = labs(de);
   block->steps[E_AXIS] *= volumetric_multiplier[active_extruder];
-  block->steps[E_AXIS] *= extruder_multiply[active_extruder];
+  block->steps[E_AXIS] *= extrudemultiply;
   block->steps[E_AXIS] /= 100;
   block->step_event_count = max(block->steps[X_AXIS], max(block->steps[Y_AXIS], max(block->steps[Z_AXIS], block->steps[E_AXIS])));
 
@@ -679,7 +679,7 @@ float junction_deviation = 0.1;
     delta_mm[Y_AXIS] = dy / axis_steps_per_unit[Y_AXIS];
   #endif
   delta_mm[Z_AXIS] = dz / axis_steps_per_unit[Z_AXIS];
-  delta_mm[E_AXIS] = (de / axis_steps_per_unit[E_AXIS]) * volumetric_multiplier[active_extruder] * extruder_multiply[active_extruder] / 100.0;
+  delta_mm[E_AXIS] = (de / axis_steps_per_unit[E_AXIS]) * volumetric_multiplier[active_extruder] * extrudemultiply / 100.0;
 
   if (block->steps[X_AXIS] <= dropsegments && block->steps[Y_AXIS] <= dropsegments && block->steps[Z_AXIS] <= dropsegments) {
     block->millimeters = fabs(delta_mm[E_AXIS]);
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index d38474bafd8..73c23ae9de1 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -515,36 +515,31 @@ ISR(TIMER1_COMPA_vect) {
     }
 
     if (TEST(out_bits, Z_AXIS)) {   // -direction
-
       Z_APPLY_DIR(INVERT_Z_DIR,0);
       count_direction[Z_AXIS] = -1;
-
-      if (check_endstops) {
-
-        #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0
-
-          #ifdef Z_DUAL_ENDSTOPS
-
-            bool z_min_endstop = READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING,
-                z2_min_endstop =
-                  #if defined(Z2_MIN_PIN) && Z2_MIN_PIN >= 0
-                    READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING
-                  #else
-                    z_min_endstop
-                  #endif
-                ;
-
-            bool z_min_both = z_min_endstop && old_z_min_endstop,
-                z2_min_both = z2_min_endstop && old_z2_min_endstop;
-            if ((z_min_both || z2_min_both) && current_block->steps[Z_AXIS] > 0) {
+      if (check_endstops) 
+      {
+        #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
+          #ifndef Z_DUAL_ENDSTOPS
+            UPDATE_ENDSTOP(z, Z, min, MIN);
+          #else
+            bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
+            #if defined(Z2_MIN_PIN) && Z2_MIN_PIN > -1
+              bool z2_min_endstop=(READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING);
+            #else
+              bool z2_min_endstop=z_min_endstop;
+            #endif
+            if(((z_min_endstop && old_z_min_endstop) || (z2_min_endstop && old_z2_min_endstop)) && (current_block->steps[Z_AXIS] > 0))
+            {
               endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-              endstop_z_hit = true;
-              if (!performing_homing || (performing_homing && z_min_both && z2_min_both)) //if not performing home or if both endstops were trigged during homing...
+              endstop_z_hit=true;
+              if (!(performing_homing) || ((performing_homing)&&(z_min_endstop && old_z_min_endstop)&&(z2_min_endstop && old_z2_min_endstop))) //if not performing home or if both endstops were trigged during homing...
+              {
                 step_events_completed = current_block->step_event_count;
+              } 
             }
             old_z_min_endstop = z_min_endstop;
             old_z2_min_endstop = z2_min_endstop;
-<<<<<<< HEAD
           #endif
         #endif
 
@@ -561,55 +556,37 @@ ISR(TIMER1_COMPA_vect) {
           old_z_probe_endstop = z_probe_endstop;
         #endif
       }
-=======
-
-          #else // !Z_DUAL_ENDSTOPS
-
-            UPDATE_ENDSTOP(z, Z, min, MIN);
-
-          #endif // !Z_DUAL_ENDSTOPS
-
-        #endif // Z_MIN_PIN
-
-      } // check_endstops
-
->>>>>>> MarlinFirmware/Development
     }
     else { // +direction
-
       Z_APPLY_DIR(!INVERT_Z_DIR,0);
       count_direction[Z_AXIS] = 1;
-
       if (check_endstops) {
-
         #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
-
-          #ifdef Z_DUAL_ENDSTOPS
-
-            bool z_max_endstop = READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING,
-                z2_max_endstop =
-                  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
-                    READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING
-                  #else
-                    z_max_endstop
-                  #endif
-                ;
-
-            bool z_max_both = z_max_endstop && old_z_max_endstop,
-                z2_max_both = z2_max_endstop && old_z2_max_endstop;
-            if ((z_max_both || z2_max_both) && current_block->steps[Z_AXIS] > 0) {
+          #ifndef Z_DUAL_ENDSTOPS
+            UPDATE_ENDSTOP(z, Z, max, MAX);
+          #else
+            bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING);
+            #if defined(Z2_MAX_PIN) && Z2_MAX_PIN > -1
+              bool z2_max_endstop=(READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING);
+            #else
+              bool z2_max_endstop=z_max_endstop;
+            #endif
+            if(((z_max_endstop && old_z_max_endstop) || (z2_max_endstop && old_z2_max_endstop)) && (current_block->steps[Z_AXIS] > 0))
+            {
               endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-              endstop_z_hit = true;
+              endstop_z_hit=true;
 
-             // if (z_max_both) SERIAL_ECHOLN("z_max_endstop = true");
-             // if (z2_max_both) SERIAL_ECHOLN("z2_max_endstop = true");
+//              if (z_max_endstop && old_z_max_endstop) SERIAL_ECHOLN("z_max_endstop = true");
+//              if (z2_max_endstop && old_z2_max_endstop) SERIAL_ECHOLN("z2_max_endstop = true");
 
-              if (!performing_homing || (performing_homing && z_max_both && z2_max_both)) //if not performing home or if both endstops were trigged during homing...
+            
+              if (!(performing_homing) || ((performing_homing)&&(z_max_endstop && old_z_max_endstop)&&(z2_max_endstop && old_z2_max_endstop))) //if not performing home or if both endstops were trigged during homing...
+              {
                 step_events_completed = current_block->step_event_count;
+              } 
             }
             old_z_max_endstop = z_max_endstop;
             old_z2_max_endstop = z2_max_endstop;
-<<<<<<< HEAD
           #endif
         #endif
 
@@ -626,34 +603,20 @@ ISR(TIMER1_COMPA_vect) {
         #endif
       }
     }
-=======
-
-          #else // !Z_DUAL_ENDSTOPS
-
-            UPDATE_ENDSTOP(z, Z, max, MAX);
-
-          #endif // !Z_DUAL_ENDSTOPS
-
-        #endif // Z_MAX_PIN
-
-      } // check_endstops
-
-    } // +direction
->>>>>>> MarlinFirmware/Development
 
     #ifndef ADVANCE
       if (TEST(out_bits, E_AXIS)) {  // -direction
         REV_E_DIR();
-        count_direction[E_AXIS] = -1;
+        count_direction[E_AXIS]=-1;
       }
       else { // +direction
         NORM_E_DIR();
-        count_direction[E_AXIS] = 1;
+        count_direction[E_AXIS]=1;
       }
     #endif //!ADVANCE
 
     // Take multiple steps per interrupt (For high speed moves)
-    for (int8_t i = 0; i < step_loops; i++) {
+    for (int8_t i=0; i < step_loops; i++) {
       #ifndef AT90USB
         MSerial.checkRx(); // Check for serial chars.
       #endif
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 58a66973f4f..c85f8e14dfb 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -485,7 +485,7 @@ static void lcd_tune_menu() {
     MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
   #endif
   MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
-  MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiply[active_extruder], 10, 999);
+  MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999);
   MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F0, &extruder_multiply[0], 10, 999);
   #if TEMP_SENSOR_1 != 0
     MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F1, &extruder_multiply[1], 10, 999);
diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h
index c21785ed25e..aaa55800acb 100644
--- a/Marlin/ultralcd_implementation_hitachi_HD44780.h
+++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h
@@ -624,7 +624,7 @@ static void lcd_implementation_status_screen()
 
 static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) {
   char c;
-  uint8_t n = LCD_WIDTH - 2;
+  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2);
   lcd.setCursor(0, row);
   lcd.print(sel ? pre_char : ' ');
   while ((c = pgm_read_byte(pstr)) && n > 0) {
@@ -633,11 +633,12 @@ static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const cha
   }
   while(n--) lcd.print(' ');
   lcd.print(post_char);
+  lcd.print(' ');
 }
 
 static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char* data) {
   char c;
-  uint8_t n = LCD_WIDTH - 2 - lcd_strlen(data);
+  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen(data);
   lcd.setCursor(0, row);
   lcd.print(sel ? pre_char : ' ');
   while ((c = pgm_read_byte(pstr)) && n > 0) {
@@ -650,7 +651,7 @@ static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t r
 }
 static void lcd_implementation_drawmenu_setting_edit_generic_P(bool sel, uint8_t row, const char* pstr, char pre_char, const char* data) {
   char c;
-  uint8_t n = LCD_WIDTH - 2 - lcd_strlen_P(data);
+  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen_P(data);
   lcd.setCursor(0, row);
   lcd.print(sel ? pre_char : ' ');
   while ((c = pgm_read_byte(pstr)) && n > 0) {
@@ -687,11 +688,11 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
   lcd.setCursor(1, 1);
   lcd_printPGM(pstr);
   lcd.print(':');
-  lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1);
+  lcd.setCursor(LCD_WIDTH - (LCD_WIDTH < 20 ? 0 : 1) - lcd_strlen(value), 1);
   lcd_print(value);
 }
 
-static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat, char post_char) {
+static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat) {
   char c;
   uint8_t n = LCD_WIDTH - concat;
   lcd.setCursor(0, row);
@@ -705,15 +706,14 @@ static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* ps
     filename++;
   }
   while (n--) lcd.print(' ');
-  lcd.print(post_char);
 }
 
 static void lcd_implementation_drawmenu_sdfile(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) {
-  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, ' ');
+  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 1);
 }
 
 static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) {
-  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, LCD_STR_FOLDER[0]);
+  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2);
 }
 
 #define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])

From 3175c70c796281e3aa3bf5df2300f405345fdf63 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Tue, 31 Mar 2015 00:11:11 -0500
Subject: [PATCH 22/83] Manually synching back up with
 MarlinFirmware/Development.

---
 Marlin/Conditionals.h  | 3 +++
 Marlin/Configuration.h | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/Marlin/Conditionals.h b/Marlin/Conditionals.h
index 62ea7ba54ad..5f626b9fbd1 100644
--- a/Marlin/Conditionals.h
+++ b/Marlin/Conditionals.h
@@ -185,6 +185,9 @@
       #define ENDSTOPPULLUP_YMIN
       #define ENDSTOPPULLUP_ZMIN
     #endif
+    #ifndef DISABLE_Z_PROBE_ENDSTOP
+      #define ENDSTOPPULL_ZPROBE
+    #endif
   #endif
 
   /**
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 481004f1d3a..82d7107456c 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -313,8 +313,8 @@ your extruder heater takes 2 minutes to hit the target on heating.
   // #define ENDSTOPPULLUP_XMIN
   // #define ENDSTOPPULLUP_YMIN
   // #define ENDSTOPPULLUP_ZMIN
+  // #define ENDSTOPPULLUP_ZPROBE
 #endif
->>>>>>> MarlinFirmware/Development
 
 // Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
 const bool X_MIN_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.

From ec1d9c0b8f87a0d76c1f54496b0e8584081dd099 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Tue, 31 Mar 2015 01:06:01 -0500
Subject: [PATCH 23/83] Use Z_PROBE_ENDSTOP_INVERTING when checking pin status.

---
 Marlin/stepper.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 73c23ae9de1..0dbc2a297b4 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -545,7 +545,7 @@ ISR(TIMER1_COMPA_vect) {
 
         #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
-          z_probe_endstop=(READ(Z_PROBE_PIN) != Z_MIN_ENDSTOP_INVERTING);
+          z_probe_endstop=(READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
           if(z_probe_endstop && old_z_probe_endstop)
           {
         	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
@@ -592,7 +592,7 @@ ISR(TIMER1_COMPA_vect) {
 
         #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
-          z_probe_endstop=(READ(Z_PROBE_PIN) != Z_MAX_ENDSTOP_INVERTING);
+          z_probe_endstop=(READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
           if(z_probe_endstop && old_z_probe_endstop)
           {
         	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];

From 17707e7479e943fa06965336b9fe380427d3060c Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Tue, 31 Mar 2015 02:56:41 -0500
Subject: [PATCH 24/83] Fixed Z_PROBE_PIN pullup bug. Documented some
 additional areas that should be addressed if Z_PROBE is fully separated from
 Z_MIN or Z_MAX. Fixed a documentation error in sanity checks. Servos start at
 0 not 1.

---
 Marlin/Conditionals.h  |   2 +-
 Marlin/Marlin_main.cpp | 977 ++++++++++++++++++++++++-----------------
 Marlin/SanityCheck.h   |   2 +-
 Marlin/stepper.cpp     |  13 +-
 4 files changed, 581 insertions(+), 413 deletions(-)

diff --git a/Marlin/Conditionals.h b/Marlin/Conditionals.h
index 5f626b9fbd1..413e2256290 100644
--- a/Marlin/Conditionals.h
+++ b/Marlin/Conditionals.h
@@ -186,7 +186,7 @@
       #define ENDSTOPPULLUP_ZMIN
     #endif
     #ifndef DISABLE_Z_PROBE_ENDSTOP
-      #define ENDSTOPPULL_ZPROBE
+      #define ENDSTOPPULLUP_ZPROBE
     #endif
   #endif
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 13905683a5b..0683c67e711 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -79,7 +79,7 @@
 // G4  - Dwell S<seconds> or P<milliseconds>
 // G10 - retract filament according to settings of M207
 // G11 - retract recover filament according to settings of M208
-// G28 - Home all Axis
+// G28 - Home one or more axes
 // G29 - Detailed Z-Probe, probes the bed at 3 or more points.  Will fail if you haven't homed yet.
 // G30 - Single Z Probe, probes bed at current XY location.
 // G31 - Dock sled (Z_PROBE_SLED only)
@@ -170,10 +170,10 @@
 // M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
 // M405 - Turn on Filament Sensor extrusion control.  Optional D<delay in cm> to set delay in centimeters between sensor and extruder
 // M406 - Turn off Filament Sensor extrusion control
-// M407 - Display measured filament diameter
+// M407 - Displays measured filament diameter
 // M500 - Store parameters in EEPROM
 // M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily).
-// M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
+// M502 - Revert to the default "factory settings".  You still need to store them in EEPROM afterwards if you want to.
 // M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings.
 // M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
 // M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
@@ -210,7 +210,6 @@ int homing_bump_divisor[] = HOMING_BUMP_DIVISOR;
 bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
 int feedmultiply = 100; //100->1 200->2
 int saved_feedmultiply;
-int extrudemultiply = 100; //100->1 200->2
 int extruder_multiply[EXTRUDERS] = ARRAY_BY_EXTRUDERS(100, 100, 100, 100);
 bool volumetric_enabled = false;
 float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA, DEFAULT_NOMINAL_FILAMENT_DIA);
@@ -273,7 +272,7 @@ int fanSpeed = 0;
 
 #endif // FWRETRACT
 
-#if defined(ULTIPANEL) && HAS_POWER_SWITCH
+#ifdef ULTIPANEL
   bool powersupply = 
     #ifdef PS_DEFAULT_OFF
       false
@@ -306,19 +305,19 @@ int fanSpeed = 0;
 #ifdef SCARA
   float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
   static float delta[3] = { 0, 0, 0 };		
-#endif        
+#endif
 
 bool cancel_heatup = false;
 
 #ifdef FILAMENT_SENSOR
   //Variables for Filament Sensor input
-  float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA;  //Set nominal filament width, can be changed with M404
-  bool filament_sensor = false;  //M405 turns on filament_sensor control, M406 turns it off
-  float filament_width_meas = DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter
+  float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA;  //Set nominal filament width, can be changed with M404
+  bool filament_sensor=false;  //M405 turns on filament_sensor control, M406 turns it off
+  float filament_width_meas=DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter
   signed char measurement_delay[MAX_MEASUREMENT_DELAY+1];  //ring buffer to delay measurement  store extruder factor after subtracting 100
-  int delay_index1 = 0;  //index into ring buffer
-  int delay_index2 = -1;  //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized
-  float delay_dist = 0; //delay distance counter
+  int delay_index1=0;  //index into ring buffer
+  int delay_index2=-1;  //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized
+  float delay_dist=0; //delay distance counter
   int meas_delay_cm = MEASUREMENT_DELAY_CM;  //distance delay setting
 #endif
 
@@ -477,8 +476,6 @@ bool enquecommand(const char *cmd)
   return true;
 }
 
-
-
 void setup_killpin()
 {
   #if defined(KILL_PIN) && KILL_PIN > -1
@@ -519,8 +516,8 @@ void setup_powerhold()
   #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
     OUT_WRITE(SUICIDE_PIN, HIGH);
   #endif
-  #if HAS_POWER_SWITCH
-    #ifdef PS_DEFAULT_OFF
+  #if defined(PS_ON_PIN) && PS_ON_PIN > -1
+    #if defined(PS_DEFAULT_OFF)
       OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
     #else
       OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE);
@@ -932,7 +929,7 @@ XYZ_CONSTS_FROM_CONFIG(signed char, home_dir,  HOME_DIR);
 
   static float x_home_pos(int extruder) {
     if (extruder == 0)
-    return base_home_pos(X_AXIS) + home_offset[X_AXIS];
+      return base_home_pos(X_AXIS) + home_offset[X_AXIS];
     else
       // In dual carriage mode the extruder offset provides an override of the
       // second X-carriage offset when homed - otherwise X2_HOME_POS is used.
@@ -961,15 +958,15 @@ static void axis_is_at_home(int axis) {
     if (axis == X_AXIS) {
       if (active_extruder != 0) {
         current_position[X_AXIS] = x_home_pos(active_extruder);
-        min_pos[X_AXIS] = X2_MIN_POS;
-        max_pos[X_AXIS] = max(extruder_offset[1][X_AXIS], X2_MAX_POS);
+                 min_pos[X_AXIS] = X2_MIN_POS;
+                 max_pos[X_AXIS] = max(extruder_offset[1][X_AXIS], X2_MAX_POS);
         return;
       }
       else if (dual_x_carriage_mode == DXC_DUPLICATION_MODE) {
-        current_position[X_AXIS] = base_home_pos(X_AXIS) + home_offset[X_AXIS];
-        min_pos[X_AXIS] = base_min_pos(X_AXIS) + home_offset[X_AXIS];
-        max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + home_offset[X_AXIS],
-                                max(extruder_offset[1][X_AXIS], X2_MAX_POS) - duplicate_extruder_x_offset);
+        float xoff = home_offset[X_AXIS];
+        current_position[X_AXIS] = base_home_pos(X_AXIS) + xoff;
+                 min_pos[X_AXIS] = base_min_pos(X_AXIS) + xoff;
+                 max_pos[X_AXIS] = min(base_max_pos(X_AXIS) + xoff, max(extruder_offset[1][X_AXIS], X2_MAX_POS) - duplicate_extruder_x_offset);
         return;
       }
     }
@@ -1023,178 +1020,189 @@ static void axis_is_at_home(int axis) {
 }
 
 /**
- * Shorthand to tell the planner our current position (in mm).
+ * Some planner shorthand inline functions
  */
+inline void line_to_current_position() {
+  plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
+}
+inline void line_to_z(float zPosition) {
+  plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
+}
+inline void line_to_destination() {
+  plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+}
 inline void sync_plan_position() {
   plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
 }
 
 #ifdef ENABLE_AUTO_BED_LEVELING
-#ifdef AUTO_BED_LEVELING_GRID
 
-#ifndef DELTA
-  static void set_bed_level_equation_lsq(double *plane_equation_coefficients) {
-    vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
-    planeNormal.debug("planeNormal");
-    plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
-    //bedLevel.debug("bedLevel");
+  #ifdef AUTO_BED_LEVELING_GRID
 
-    //plan_bed_level_matrix.debug("bed level before");
-    //vector_3 uncorrected_position = plan_get_position_mm();
-    //uncorrected_position.debug("position before");
+    #ifndef DELTA
 
-    vector_3 corrected_position = plan_get_position();
-    //corrected_position.debug("position after");
-    current_position[X_AXIS] = corrected_position.x;
-    current_position[Y_AXIS] = corrected_position.y;
-    current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
+      static void set_bed_level_equation_lsq(double *plane_equation_coefficients) {
+        vector_3 planeNormal = vector_3(-plane_equation_coefficients[0], -plane_equation_coefficients[1], 1);
+        planeNormal.debug("planeNormal");
+        plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
+        //bedLevel.debug("bedLevel");
 
-    sync_plan_position();
+        //plan_bed_level_matrix.debug("bed level before");
+        //vector_3 uncorrected_position = plan_get_position_mm();
+        //uncorrected_position.debug("position before");
+
+        vector_3 corrected_position = plan_get_position();
+        //corrected_position.debug("position after");
+        current_position[X_AXIS] = corrected_position.x;
+        current_position[Y_AXIS] = corrected_position.y;
+        current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
+
+        sync_plan_position();
+      }
+
+    #endif // !DELTA
+
+  #else // !AUTO_BED_LEVELING_GRID
+
+    static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) {
+
+      plan_bed_level_matrix.set_to_identity();
+
+      vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1);
+      vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2);
+      vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3);
+      vector_3 planeNormal = vector_3::cross(pt1 - pt2, pt3 - pt2).get_normal();
+
+      if (planeNormal.z < 0) {
+        planeNormal.x = -planeNormal.x;
+        planeNormal.y = -planeNormal.y;
+        planeNormal.z = -planeNormal.z;
+      }
+
+      plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
+
+      vector_3 corrected_position = plan_get_position();
+      current_position[X_AXIS] = corrected_position.x;
+      current_position[Y_AXIS] = corrected_position.y;
+      current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
+
+      sync_plan_position();
+    }
+
+  #endif // !AUTO_BED_LEVELING_GRID
+
+  static void run_z_probe() {
+
+    #ifdef DELTA
+
+      float start_z = current_position[Z_AXIS];
+      long start_steps = st_get_position(Z_AXIS);
+    
+      // move down slowly until you find the bed
+      feedrate = homing_feedrate[Z_AXIS] / 4;
+      destination[Z_AXIS] = -10;
+      prepare_move_raw();
+      st_synchronize();
+      endstops_hit_on_purpose();
+
+      // we have to let the planner know where we are right now as it is not where we said to go.
+      long stop_steps = st_get_position(Z_AXIS);
+      float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
+      current_position[Z_AXIS] = mm;
+      calculate_delta(current_position);
+      plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
+
+    #else // !DELTA
+
+      plan_bed_level_matrix.set_to_identity();
+      feedrate = homing_feedrate[Z_AXIS];
+
+      // move down until you find the bed
+      float zPosition = -10;
+      line_to_z(zPosition);
+      st_synchronize();
+
+      // we have to let the planner know where we are right now as it is not where we said to go.
+      zPosition = st_get_position_mm(Z_AXIS);
+      plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
+
+      // move up the retract distance
+      zPosition += home_retract_mm(Z_AXIS);
+      line_to_z(zPosition);
+      st_synchronize();
+      endstops_hit_on_purpose();
+
+      // move back down slowly to find bed
+      if (homing_bump_divisor[Z_AXIS] >= 1)
+        feedrate = homing_feedrate[Z_AXIS] / homing_bump_divisor[Z_AXIS];
+      else {
+        feedrate = homing_feedrate[Z_AXIS] / 10;
+        SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
+      }
+
+      zPosition -= home_retract_mm(Z_AXIS) * 2;
+      line_to_z(zPosition);
+      st_synchronize();
+      endstops_hit_on_purpose();
+
+      current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
+      // make sure the planner knows where we are as it may be a bit different than we last said to move to
+      sync_plan_position();
+
+    #endif // !DELTA
   }
-#endif
 
-#else // not AUTO_BED_LEVELING_GRID
-
-static void set_bed_level_equation_3pts(float z_at_pt_1, float z_at_pt_2, float z_at_pt_3) {
-
-    plan_bed_level_matrix.set_to_identity();
-
-    vector_3 pt1 = vector_3(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, z_at_pt_1);
-    vector_3 pt2 = vector_3(ABL_PROBE_PT_2_X, ABL_PROBE_PT_2_Y, z_at_pt_2);
-    vector_3 pt3 = vector_3(ABL_PROBE_PT_3_X, ABL_PROBE_PT_3_Y, z_at_pt_3);
-    vector_3 planeNormal = vector_3::cross(pt1 - pt2, pt3 - pt2).get_normal();
-
-    if (planeNormal.z < 0) {
-      planeNormal.x = -planeNormal.x;
-      planeNormal.y = -planeNormal.y;
-      planeNormal.z = -planeNormal.z;
-    }
-
-    plan_bed_level_matrix = matrix_3x3::create_look_at(planeNormal);
-
-    vector_3 corrected_position = plan_get_position();
-    current_position[X_AXIS] = corrected_position.x;
-    current_position[Y_AXIS] = corrected_position.y;
-    current_position[Z_AXIS] = zprobe_zoffset; // was: corrected_position.z
-
-    sync_plan_position();
-}
-
-#endif // AUTO_BED_LEVELING_GRID
-
-static void run_z_probe() {
-  #ifdef DELTA
-    
-    float start_z = current_position[Z_AXIS];
-    long start_steps = st_get_position(Z_AXIS);
-  
-    // move down slowly until you find the bed
-    feedrate = homing_feedrate[Z_AXIS] / 4;
-    destination[Z_AXIS] = -10;
-    prepare_move_raw();
-    st_synchronize();
-    endstops_hit_on_purpose();
-    
-    // we have to let the planner know where we are right now as it is not where we said to go.
-    long stop_steps = st_get_position(Z_AXIS);
-    float mm = start_z - float(start_steps - stop_steps) / axis_steps_per_unit[Z_AXIS];
-    current_position[Z_AXIS] = mm;
-    calculate_delta(current_position);
-    plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
-    
-  #else
-
-    plan_bed_level_matrix.set_to_identity();
-    feedrate = homing_feedrate[Z_AXIS];
-
-    // move down until you find the bed
-    float zPosition = -10;
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-
-        // we have to let the planner know where we are right now as it is not where we said to go.
-    zPosition = st_get_position_mm(Z_AXIS);
-    plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
-
-    // move up the retract distance
-    zPosition += home_retract_mm(Z_AXIS);
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-    endstops_hit_on_purpose();
-
-    // move back down slowly to find bed
-    if (homing_bump_divisor[Z_AXIS] >= 1) {
-      feedrate = homing_feedrate[Z_AXIS]/homing_bump_divisor[Z_AXIS];
-    } 
-    else {
-      feedrate = homing_feedrate[Z_AXIS]/10;
-      SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less then 1");
-    }
-
-    zPosition -= home_retract_mm(Z_AXIS) * 2;
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
-    endstops_hit_on_purpose();
-
-    current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
-    // make sure the planner knows where we are as it may be a bit different than we last said to move to
-    sync_plan_position();
-    
-  #endif
-}
-
-static void do_blocking_move_to(float x, float y, float z) {
+  static void do_blocking_move_to(float x, float y, float z) {
     float oldFeedRate = feedrate;
 
-#ifdef DELTA
+    #ifdef DELTA
 
-    feedrate = XY_TRAVEL_SPEED;
-    
-    destination[X_AXIS] = x;
-    destination[Y_AXIS] = y;
-    destination[Z_AXIS] = z;
-    prepare_move_raw();
-    st_synchronize();
+      feedrate = XY_TRAVEL_SPEED;
 
-#else
+      destination[X_AXIS] = x;
+      destination[Y_AXIS] = y;
+      destination[Z_AXIS] = z;
+      prepare_move_raw();
+      st_synchronize();
 
-    feedrate = homing_feedrate[Z_AXIS];
+    #else
 
-    current_position[Z_AXIS] = z;
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
+      feedrate = homing_feedrate[Z_AXIS];
 
-    feedrate = xy_travel_speed;
+      current_position[Z_AXIS] = z;
+      line_to_current_position();
+      st_synchronize();
 
-    current_position[X_AXIS] = x;
-    current_position[Y_AXIS] = y;
-    plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], feedrate/60, active_extruder);
-    st_synchronize();
+      feedrate = xy_travel_speed;
 
-#endif
+      current_position[X_AXIS] = x;
+      current_position[Y_AXIS] = y;
+      line_to_current_position();
+      st_synchronize();
+
+    #endif
 
     feedrate = oldFeedRate;
-}
+  }
 
-static void setup_for_endstop_move() {
+  static void setup_for_endstop_move() {
     saved_feedrate = feedrate;
     saved_feedmultiply = feedmultiply;
     feedmultiply = 100;
     previous_millis_cmd = millis();
-
     enable_endstops(true);
-}
-
-static void clean_up_after_endstop_move() {
-#ifdef ENDSTOPS_ONLY_FOR_HOMING
-    enable_endstops(false);
-#endif
+  }
 
+  static void clean_up_after_endstop_move() {
+    #ifdef ENDSTOPS_ONLY_FOR_HOMING
+      enable_endstops(false);
+    #endif
     feedrate = saved_feedrate;
     feedmultiply = saved_feedmultiply;
     previous_millis_cmd = millis();
-}
+  }
 
+<<<<<<< HEAD
 static void engage_z_probe() {
   // Engage Z Servo endstop if enabled
   #ifdef SERVO_ENDSTOPS
@@ -1229,6 +1237,9 @@ static void engage_z_probe() {
     
     st_synchronize();
     
+    // If Z_PROBE_AND_ENDSTOP is changed to completely break it's bonds from Z_MIN_ENDSTOP and become
+    // it's own unique entity, then the following logic will need to be modified
+    // so it only uses the Z_PROBE
     #if defined(Z_PROBE_AND_ENDSTOP)
     bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
     if (z_probe_endstop)
@@ -1242,13 +1253,59 @@ static void engage_z_probe() {
             SERIAL_ERROR_START;
             SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
             LCD_ALERTMESSAGEPGM("Err: ZPROBE");
+=======
+  static void engage_z_probe() {
+
+    #ifdef SERVO_ENDSTOPS
+
+      // Engage Z Servo endstop if enabled
+      if (servo_endstops[Z_AXIS] >= 0) {
+        #if SERVO_LEVELING
+          servos[servo_endstops[Z_AXIS]].attach(0);
+        #endif
+        servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2]);
+        #if SERVO_LEVELING
+          delay(PROBE_SERVO_DEACTIVATION_DELAY);
+          servos[servo_endstops[Z_AXIS]].detach();
+        #endif
+      }
+
+    #elif defined(Z_PROBE_ALLEN_KEY)
+
+      feedrate = homing_feedrate[X_AXIS];
+
+      // Move to the start position to initiate deployment
+      destination[X_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_X;
+      destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_Y;
+      destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_DEPLOY_Z;
+      prepare_move_raw();
+
+      // Home X to touch the belt
+      feedrate = homing_feedrate[X_AXIS]/10;
+      destination[X_AXIS] = 0;
+      prepare_move_raw();
+
+      // Home Y for safety
+      feedrate = homing_feedrate[X_AXIS]/2;
+      destination[Y_AXIS] = 0;
+      prepare_move_raw();
+
+      st_synchronize();
+
+      bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
+      if (z_min_endstop) {
+        if (!Stopped) {
+          SERIAL_ERROR_START;
+          SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
+          LCD_ALERTMESSAGEPGM("Err: ZPROBE");
+>>>>>>> MarlinFirmware/Development
         }
         Stop();
-    }
-  #endif
+      }
 
-}
+    #endif // Z_PROBE_ALLEN_KEY
 
+<<<<<<< HEAD
 static void retract_z_probe() {
   // Retract Z Servo endstop if enabled
   #ifdef SERVO_ENDSTOPS
@@ -1298,6 +1355,9 @@ static void retract_z_probe() {
     
     st_synchronize();
     
+    // If Z_PROBE_AND_ENDSTOP is changed to completely break it's bonds from Z_MIN_ENDSTOP and become
+    // it's own unique entity, then the following logic will need to be modified
+    // so it only uses the Z_PROBE
     #if defined(Z_PROBE_AND_ENDSTOP)
     bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
     if (z_probe_endstop)
@@ -1311,126 +1371,219 @@ static void retract_z_probe() {
             SERIAL_ERROR_START;
             SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
             LCD_ALERTMESSAGEPGM("Err: ZPROBE");
+=======
+  }
+
+  static void retract_z_probe(const float z_after=Z_RAISE_AFTER_PROBING) {
+
+    #ifdef SERVO_ENDSTOPS
+
+      // Retract Z Servo endstop if enabled
+      if (servo_endstops[Z_AXIS] >= 0) {
+
+        if (z_after > 0) {
+          do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_after);
+          st_synchronize();
+>>>>>>> MarlinFirmware/Development
+        }
+
+        #if SERVO_LEVELING
+          servos[servo_endstops[Z_AXIS]].attach(0);
+        #endif
+
+        servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2 + 1]);
+
+        #if SERVO_LEVELING
+          delay(PROBE_SERVO_DEACTIVATION_DELAY);
+          servos[servo_endstops[Z_AXIS]].detach();
+        #endif
+      }
+
+    #elif defined(Z_PROBE_ALLEN_KEY)
+
+      // Move up for safety
+      feedrate = homing_feedrate[X_AXIS];
+      destination[Z_AXIS] = current_position[Z_AXIS] + Z_RAISE_AFTER_PROBING;
+      prepare_move_raw();
+
+      // Move to the start position to initiate retraction
+      destination[X_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_X;
+      destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Y;
+      destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Z;
+      prepare_move_raw();
+
+      // Move the nozzle down to push the probe into retracted position
+      feedrate = homing_feedrate[Z_AXIS]/10;
+      destination[Z_AXIS] = current_position[Z_AXIS] - Z_PROBE_ALLEN_KEY_RETRACT_DEPTH;
+      prepare_move_raw();
+
+      // Move up for safety
+      feedrate = homing_feedrate[Z_AXIS]/2;
+      destination[Z_AXIS] = current_position[Z_AXIS] + Z_PROBE_ALLEN_KEY_RETRACT_DEPTH * 2;
+      prepare_move_raw();
+
+      // Home XY for safety
+      feedrate = homing_feedrate[X_AXIS]/2;
+      destination[X_AXIS] = 0;
+      destination[Y_AXIS] = 0;
+      prepare_move_raw();
+
+      st_synchronize();
+
+      // If Z_PROBE_AND_ENDSTOP is changed to completely break it's bonds from Z_MIN_ENDSTOP and become
+      // it's own unique entity, then the following logic will need to be modified
+      // so it only uses the Z_PROBE
+      bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
+      if (!z_min_endstop) {
+        if (!Stopped) {
+          SERIAL_ERROR_START;
+          SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
+          LCD_ALERTMESSAGEPGM("Err: ZPROBE");
         }
         Stop();
+      }
+
+    #endif
+
+  }
+
+  enum ProbeAction {
+    ProbeStay             = 0,
+    ProbeEngage           = BIT(0),
+    ProbeRetract          = BIT(1),
+    ProbeEngageAndRetract = (ProbeEngage | ProbeRetract)
+  };
+
+  // Probe bed height at position (x,y), returns the measured z value
+  static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageAndRetract, int verbose_level=1) {
+    // move to right place
+    do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
+    do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
+
+    #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
+      if (retract_action & ProbeEngage) engage_z_probe();
+    #endif
+
+    run_z_probe();
+    float measured_z = current_position[Z_AXIS];
+
+    #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
+      if (retract_action & ProbeRetract) retract_z_probe(z_before);
+    #endif
+
+    if (verbose_level > 2) {
+      SERIAL_PROTOCOLPGM(MSG_BED);
+      SERIAL_PROTOCOLPGM(" X: ");
+      SERIAL_PROTOCOL_F(x, 3);
+      SERIAL_PROTOCOLPGM(" Y: ");
+      SERIAL_PROTOCOL_F(y, 3);
+      SERIAL_PROTOCOLPGM(" Z: ");
+      SERIAL_PROTOCOL_F(measured_z, 3);
+      SERIAL_EOL;
     }
-  #endif
-
-}
-
-enum ProbeAction {
-  ProbeStay             = 0,
-  ProbeEngage           = BIT(0),
-  ProbeRetract          = BIT(1),
-  ProbeEngageAndRetract = (ProbeEngage | ProbeRetract)
-};
-
-/// Probe bed height at position (x,y), returns the measured z value
-static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageAndRetract, int verbose_level=1) {
-  // move to right place
-  do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
-  do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
-
-  #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-    if (retract_action & ProbeEngage) engage_z_probe();
-  #endif
-
-  run_z_probe();
-  float measured_z = current_position[Z_AXIS];
-
-  #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-    if (retract_action & ProbeRetract) retract_z_probe();
-  #endif
-
-  if (verbose_level > 2) {
-    SERIAL_PROTOCOLPGM(MSG_BED);
-    SERIAL_PROTOCOLPGM(" X: ");
-    SERIAL_PROTOCOL_F(x, 3);
-    SERIAL_PROTOCOLPGM(" Y: ");
-    SERIAL_PROTOCOL_F(y, 3);
-    SERIAL_PROTOCOLPGM(" Z: ");
-    SERIAL_PROTOCOL_F(measured_z, 3);
-    SERIAL_EOL;
+    return measured_z;
   }
-  return measured_z;
-}
 
-#ifdef DELTA
-static void extrapolate_one_point(int x, int y, int xdir, int ydir) {
-  if (bed_level[x][y] != 0.0) {
-    return;  // Don't overwrite good values.
-  }
-  float a = 2*bed_level[x+xdir][y] - bed_level[x+xdir*2][y];  // Left to right.
-  float b = 2*bed_level[x][y+ydir] - bed_level[x][y+ydir*2];  // Front to back.
-  float c = 2*bed_level[x+xdir][y+ydir] - bed_level[x+xdir*2][y+ydir*2];  // Diagonal.
-  float median = c;  // Median is robust (ignores outliers).
-  if (a < b) {
-    if (b < c) median = b;
-    if (c < a) median = a;
-  } else {  // b <= a
-    if (c < b) median = b;
-    if (a < c) median = a;
-  }
-  bed_level[x][y] = median;
-}
+  #ifdef DELTA
 
-// Fill in the unprobed points (corners of circular print surface)
-// using linear extrapolation, away from the center.
-static void extrapolate_unprobed_bed_level() {
-  int half = (AUTO_BED_LEVELING_GRID_POINTS-1)/2;
-  for (int y = 0; y <= half; y++) {
-    for (int x = 0; x <= half; x++) {
-      if (x + y < 3) continue;
-      extrapolate_one_point(half-x, half-y, x>1?+1:0, y>1?+1:0);
-      extrapolate_one_point(half+x, half-y, x>1?-1:0, y>1?+1:0);
-      extrapolate_one_point(half-x, half+y, x>1?+1:0, y>1?-1:0);
-      extrapolate_one_point(half+x, half+y, x>1?-1:0, y>1?-1:0);
+    /**
+     * All DELTA leveling in the Marlin uses NONLINEAR_BED_LEVELING
+     */
+
+    static void extrapolate_one_point(int x, int y, int xdir, int ydir) {
+      if (bed_level[x][y] != 0.0) {
+        return;  // Don't overwrite good values.
+      }
+      float a = 2*bed_level[x+xdir][y] - bed_level[x+xdir*2][y];  // Left to right.
+      float b = 2*bed_level[x][y+ydir] - bed_level[x][y+ydir*2];  // Front to back.
+      float c = 2*bed_level[x+xdir][y+ydir] - bed_level[x+xdir*2][y+ydir*2];  // Diagonal.
+      float median = c;  // Median is robust (ignores outliers).
+      if (a < b) {
+        if (b < c) median = b;
+        if (c < a) median = a;
+      } else {  // b <= a
+        if (c < b) median = b;
+        if (a < c) median = a;
+      }
+      bed_level[x][y] = median;
     }
-  }
-}
 
-// Print calibration results for plotting or manual frame adjustment.
-static void print_bed_level() {
-  for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
-    for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
-      SERIAL_PROTOCOL_F(bed_level[x][y], 2);
-      SERIAL_PROTOCOLPGM(" ");
+    // Fill in the unprobed points (corners of circular print surface)
+    // using linear extrapolation, away from the center.
+    static void extrapolate_unprobed_bed_level() {
+      int half = (AUTO_BED_LEVELING_GRID_POINTS-1)/2;
+      for (int y = 0; y <= half; y++) {
+        for (int x = 0; x <= half; x++) {
+          if (x + y < 3) continue;
+          extrapolate_one_point(half-x, half-y, x>1?+1:0, y>1?+1:0);
+          extrapolate_one_point(half+x, half-y, x>1?-1:0, y>1?+1:0);
+          extrapolate_one_point(half-x, half+y, x>1?+1:0, y>1?-1:0);
+          extrapolate_one_point(half+x, half+y, x>1?-1:0, y>1?-1:0);
+        }
+      }
     }
-    SERIAL_ECHOLN("");
-  }
-}
 
-// Reset calibration results to zero.
-void reset_bed_level() {
-  for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
-    for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
-      bed_level[x][y] = 0.0;
+    // Print calibration results for plotting or manual frame adjustment.
+    static void print_bed_level() {
+      for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
+        for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
+          SERIAL_PROTOCOL_F(bed_level[x][y], 2);
+          SERIAL_PROTOCOLPGM(" ");
+        }
+        SERIAL_ECHOLN("");
+      }
     }
-  }
-}
 
-#endif // DELTA
+    // Reset calibration results to zero.
+    void reset_bed_level() {
+      for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
+        for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
+          bed_level[x][y] = 0.0;
+        }
+      }
+    }
+
+  #endif // DELTA
 
 #endif // ENABLE_AUTO_BED_LEVELING
 
 static void homeaxis(int axis) {
-#define HOMEAXIS_DO(LETTER) \
-  ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
+  #define HOMEAXIS_DO(LETTER) \
+    ((LETTER##_MIN_PIN > -1 && LETTER##_HOME_DIR==-1) || (LETTER##_MAX_PIN > -1 && LETTER##_HOME_DIR==1))
 
-  if (axis==X_AXIS ? HOMEAXIS_DO(X) :
-      axis==Y_AXIS ? HOMEAXIS_DO(Y) :
-      axis==Z_AXIS ? HOMEAXIS_DO(Z) :
-      0) {
-    int axis_home_dir = home_dir(axis);
-#ifdef DUAL_X_CARRIAGE
-    if (axis == X_AXIS)
-      axis_home_dir = x_home_dir(active_extruder);
-#endif
+  if (axis == X_AXIS ? HOMEAXIS_DO(X) :
+      axis == Y_AXIS ? HOMEAXIS_DO(Y) :
+      axis == Z_AXIS ? HOMEAXIS_DO(Z) : 0) {
+
+    int axis_home_dir;
+
+    #ifdef DUAL_X_CARRIAGE
+      if (axis == X_AXIS) axis_home_dir = x_home_dir(active_extruder);
+    #else
+      axis_home_dir = home_dir(axis);
+    #endif
 
     current_position[axis] = 0;
     sync_plan_position();
 
+    #ifndef Z_PROBE_SLED
+      // Engage Servo endstop if enabled
+      #ifdef SERVO_ENDSTOPS
+        #if SERVO_LEVELING
+          if (axis == Z_AXIS) {
+            engage_z_probe();
+          }
+          else
+        #endif // SERVO_LEVELING
 
+        if (servo_endstops[axis] > -1)
+          servos[servo_endstops[axis]].write(servo_endstop_angles[axis * 2]);
+
+      #endif // SERVO_ENDSTOPS
+
+    #endif // Z_PROBE_SLED
+
+<<<<<<< HEAD
 #ifndef Z_PROBE_SLED
     // Engage Servo endstop if enabled and we are not using Z_PROBE_AND_ENDSTOP unless we are using Z_SAFE_HOMING
     #ifdef SERVO_ENDSTOPS && (defined (Z_SAFE_HOMING) || ! defined (Z_PROBE_AND_ENDSTOP))
@@ -1445,33 +1598,33 @@ static void homeaxis(int axis) {
       }
     #endif
 #endif // Z_PROBE_SLED
+=======
+>>>>>>> MarlinFirmware/Development
     #ifdef Z_DUAL_ENDSTOPS
-      if (axis==Z_AXIS) In_Homing_Process(true);
+      if (axis == Z_AXIS) In_Homing_Process(true);
     #endif
+
     destination[axis] = 1.5 * max_length(axis) * axis_home_dir;
     feedrate = homing_feedrate[axis];
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+    line_to_destination();
     st_synchronize();
 
     current_position[axis] = 0;
     sync_plan_position();
     destination[axis] = -home_retract_mm(axis) * axis_home_dir;
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+    line_to_destination();
     st_synchronize();
 
-    destination[axis] = 2*home_retract_mm(axis) * axis_home_dir;
+    destination[axis] = 2 * home_retract_mm(axis) * axis_home_dir;
 
     if (homing_bump_divisor[axis] >= 1)
-    {
-        feedrate = homing_feedrate[axis]/homing_bump_divisor[axis];
-    } 
-    else
-    {
-        feedrate = homing_feedrate[axis]/10;
-        SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less then 1");
+      feedrate = homing_feedrate[axis] / homing_bump_divisor[axis];
+    else {
+      feedrate = homing_feedrate[axis] / 10;
+      SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
     }
 
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+    line_to_destination();
     st_synchronize();
     #ifdef Z_DUAL_ENDSTOPS
       if (axis==Z_AXIS)
@@ -1486,7 +1639,7 @@ static void homeaxis(int axis) {
           destination[axis] = fabs(z_endstop_adj);
           if (z_endstop_adj < 0) Lock_z_motor(true); else Lock_z2_motor(true);        
         }
-        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+        line_to_destination();
         st_synchronize();
         Lock_z_motor(false);
         Lock_z2_motor(false);
@@ -1499,7 +1652,7 @@ static void homeaxis(int axis) {
     if (endstop_adj[axis] * axis_home_dir < 0) {
       sync_plan_position();
       destination[axis] = endstop_adj[axis];
-      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+      line_to_destination();
       st_synchronize();
     }
 #endif
@@ -1544,7 +1697,7 @@ void refresh_cmd_timeout(void)
       }
       plan_set_e_position(current_position[E_AXIS]);
       float oldFeedrate = feedrate;
-      feedrate=retract_feedrate*60;
+      feedrate = retract_feedrate * 60;
       retracted[active_extruder]=true;
       prepare_move();
       if(retract_zlift > 0.01) {
@@ -1580,8 +1733,8 @@ void refresh_cmd_timeout(void)
       }
       plan_set_e_position(current_position[E_AXIS]);
       float oldFeedrate = feedrate;
-      feedrate=retract_recover_feedrate*60;
-      retracted[active_extruder]=false;
+      feedrate = retract_recover_feedrate * 60;
+      retracted[active_extruder] = false;
       prepare_move();
       feedrate = oldFeedrate;
     }
@@ -1735,17 +1888,16 @@ inline void gcode_G4() {
  */
 inline void gcode_G28() {
   #ifdef ENABLE_AUTO_BED_LEVELING
+    plan_bed_level_matrix.set_to_identity();  //Reset the plane ("erase" all leveling data)
     #ifdef DELTA
       reset_bed_level();
-    #else
-      plan_bed_level_matrix.set_to_identity();  //Reset the plane ("erase" all leveling data)
     #endif
   #endif
 
   #if defined(MESH_BED_LEVELING)
     uint8_t mbl_was_active = mbl.active;
     mbl.active = 0;
-  #endif  // MESH_BED_LEVELING
+  #endif
 
   saved_feedrate = feedrate;
   saved_feedmultiply = feedmultiply;
@@ -1768,7 +1920,7 @@ inline void gcode_G28() {
 
     for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * Z_MAX_LENGTH;
     feedrate = 1.732 * homing_feedrate[X_AXIS];
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+    line_to_destination();
     st_synchronize();
     endstops_hit_on_purpose();
 
@@ -1816,7 +1968,7 @@ inline void gcode_G28() {
         } else {
           feedrate *= sqrt(pow(max_length(X_AXIS) / max_length(Y_AXIS), 2) + 1);
         }
-        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+        line_to_destination();
         st_synchronize();
 
         axis_is_at_home(X_AXIS);
@@ -1824,7 +1976,7 @@ inline void gcode_G28() {
         sync_plan_position();
         destination[X_AXIS] = current_position[X_AXIS];
         destination[Y_AXIS] = current_position[Y_AXIS];
-        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+        line_to_destination();
         feedrate = 0.0;
         st_synchronize();
         endstops_hit_on_purpose();
@@ -1891,7 +2043,7 @@ inline void gcode_G28() {
           #if defined(Z_RAISE_BEFORE_HOMING) && Z_RAISE_BEFORE_HOMING > 0
             destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
             feedrate = max_feedrate[Z_AXIS];
-            plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
+            line_to_destination();
             st_synchronize();
           #endif
           HOMEAXIS(Z);
@@ -1903,11 +2055,11 @@ inline void gcode_G28() {
           destination[X_AXIS] = round(Z_SAFE_HOMING_X_POINT - X_PROBE_OFFSET_FROM_EXTRUDER);
           destination[Y_AXIS] = round(Z_SAFE_HOMING_Y_POINT - Y_PROBE_OFFSET_FROM_EXTRUDER);
           destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
-          feedrate = XY_TRAVEL_SPEED / 60;
+          feedrate = XY_TRAVEL_SPEED;
           current_position[Z_AXIS] = 0;
 
           sync_plan_position();
-          plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
+          line_to_destination();
           st_synchronize();
           current_position[X_AXIS] = destination[X_AXIS];
           current_position[Y_AXIS] = destination[Y_AXIS];
@@ -1929,7 +2081,7 @@ inline void gcode_G28() {
               plan_set_position(cpx, cpy, current_position[Z_AXIS], current_position[E_AXIS]);
               destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
               feedrate = max_feedrate[Z_AXIS];
-              plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
+              line_to_destination();
               st_synchronize();
               HOMEAXIS(Z);
             }
@@ -1982,7 +2134,7 @@ inline void gcode_G28() {
       destination[Z_AXIS] = current_position[Z_AXIS];
       destination[E_AXIS] = current_position[E_AXIS];
       feedrate = homing_feedrate[X_AXIS];
-      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate, active_extruder);
+      line_to_destination();
       st_synchronize();
       current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
       sync_plan_position();
@@ -1996,6 +2148,19 @@ inline void gcode_G28() {
   endstops_hit_on_purpose();
 }
 
+#if defined(MESH_BED_LEVELING) || defined(ENABLE_AUTO_BED_LEVELING)
+
+  // Check for known positions in X and Y
+  inline bool can_run_bed_leveling() {
+  	if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) return true;
+    LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
+    SERIAL_ECHO_START;
+    SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
+    return false;
+  }
+
+#endif // MESH_BED_LEVELING || ENABLE_AUTO_BED_LEVELING
+
 #ifdef MESH_BED_LEVELING
 
   /**
@@ -2010,6 +2175,10 @@ inline void gcode_G28() {
    *
    */
   inline void gcode_G29() {
+
+    // Prevent leveling without first homing in X and Y
+    if (!can_run_bed_leveling()) return;
+
     static int probe_point = -1;
     int state = 0;
     if (code_seen('S') || code_seen('s')) {
@@ -2126,13 +2295,8 @@ inline void gcode_G28() {
    */
   inline void gcode_G29() {
 
-    // Prevent user from running a G29 without first homing in X and Y
-    if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
-      LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
-      SERIAL_ECHO_START;
-      SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
-      return;
-    }
+    // Prevent leveling without first homing in X and Y
+    if (!can_run_bed_leveling()) return;
 
     int verbose_level = 1;
 
@@ -2214,16 +2378,15 @@ inline void gcode_G28() {
 
     st_synchronize();
 
-    if (!dryrun)
-    {
+    if (!dryrun) {
+      // make sure the bed_level_rotation_matrix is identity or the planner will get it wrong
+      plan_bed_level_matrix.set_to_identity();
+
       #ifdef DELTA
         reset_bed_level();
       #else //!DELTA
-
-        // make sure the bed_level_rotation_matrix is identity or the planner will get it incorectly
         //vector_3 corrected_position = plan_get_position_mm();
         //corrected_position.debug("position before G29");
-        plan_bed_level_matrix.set_to_identity();
         vector_3 uncorrected_position = plan_get_position();
         //uncorrected_position.debug("position during G29");
         current_position[X_AXIS] = uncorrected_position.x;
@@ -2231,7 +2394,7 @@ inline void gcode_G28() {
         current_position[Z_AXIS] = uncorrected_position.z;
         sync_plan_position();
 
-      #endif
+      #endif // !DELTA
     }
     
     setup_for_endstop_move();
@@ -2292,13 +2455,12 @@ inline void gcode_G28() {
 
           // raise extruder
           float measured_z,
-                z_before = probePointCounter == 0 ? Z_RAISE_BEFORE_PROBING : current_position[Z_AXIS] + Z_RAISE_BETWEEN_PROBINGS;
+                z_before = Z_RAISE_BETWEEN_PROBINGS + (probePointCounter ? current_position[Z_AXIS] : 0);
 
           #ifdef DELTA
             // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.
             float distance_from_center = sqrt(xProbe*xProbe + yProbe*yProbe);
-            if (distance_from_center > DELTA_PROBABLE_RADIUS)
-              continue;
+            if (distance_from_center > DELTA_PROBABLE_RADIUS) continue;
           #endif //DELTA
 
           // Enhanced G29 - Do not retract servo between probes
@@ -2326,6 +2488,11 @@ inline void gcode_G28() {
           #endif
 
           probePointCounter++;
+
+          manage_heater();
+          manage_inactivity();
+          lcd_update();
+
         } //xProbe
       } //yProbe
 
@@ -2412,16 +2579,14 @@ inline void gcode_G28() {
       if (verbose_level > 0)
         plan_bed_level_matrix.debug(" \n\nBed Level Correction Matrix:");
 
-      // Correct the Z height difference from z-probe position and hotend tip position.
-      // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
-      // When the bed is uneven, this height must be corrected.
-      if (!dryrun)
-      {
-        float x_tmp, y_tmp, z_tmp, real_z;
-        real_z = float(st_get_position(Z_AXIS)) / axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
-        x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER;
-        y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER;
-        z_tmp = current_position[Z_AXIS];
+      if (!dryrun) {
+        // Correct the Z height difference from z-probe position and hotend tip position.
+        // The Z height on homing is measured by Z-Probe, but the probe is quite far from the hotend.
+        // When the bed is uneven, this height must be corrected.
+        float x_tmp = current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER,
+              y_tmp = current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER,
+              z_tmp = current_position[Z_AXIS],
+              real_z = (float)st_get_position(Z_AXIS) / axis_steps_per_unit[Z_AXIS];  //get the real Z (since the auto bed leveling is already correcting the plane)
 
         apply_rotation_xyz(plan_bed_level_matrix, x_tmp, y_tmp, z_tmp);         //Apply the correction sending the probe offset
         current_position[Z_AXIS] = z_tmp - real_z + current_position[Z_AXIS];   //The difference is added to current position and sent to planner.
@@ -2757,11 +2922,13 @@ inline void gcode_M42() {
   } // code_seen('S')
 }
 
-
+// If Z_PROBE_AND_ENDSTOP is changed to completely break it's bonds from Z_MIN_ENDSTOP and become
+// it's own unique entity, then the following logic will need to be modified
+// so it only uses the Z_PROBE
 #if defined(ENABLE_AUTO_BED_LEVELING) && defined(Z_PROBE_REPEATABILITY_TEST)
 
-  #if Z_MIN_PIN == -1
-    #error "You must have a Z_MIN endstop in order to enable calculation of Z-Probe repeatability."
+  #if (Z_MIN_PIN == -1) && (! defined (Z_PROBE_PIN) || Z_PROBE_PIN == -1)
+    #error "You must have a Z_MIN or Z_PROBE endstop in order to enable calculation of Z-Probe repeatability."
   #endif
 
   /**
@@ -3267,7 +3434,7 @@ inline void gcode_M140() {
   if (code_seen('S')) setTargetBed(code_value());
 }
 
-#if HAS_POWER_SWITCH
+#if defined(PS_ON_PIN) && PS_ON_PIN > -1
 
   /**
    * M80: Turn on Power Supply
@@ -3289,12 +3456,10 @@ inline void gcode_M140() {
     #endif
   }
 
-#endif // HAS_POWER_SWITCH
+#endif // PS_ON_PIN
 
 /**
- * M81: Turn off Power, including Power Supply, if there is one.
- *
- *      This code should ALWAYS be available for EMERGENCY SHUTDOWN!
+ * M81: Turn off Power Supply
  */
 inline void gcode_M81() {
   disable_heater();
@@ -3309,19 +3474,16 @@ inline void gcode_M81() {
   #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
     st_synchronize();
     suicide();
-  #elif HAS_POWER_SWITCH
+  #elif defined(PS_ON_PIN) && PS_ON_PIN > -1
     OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
   #endif
   #ifdef ULTIPANEL
-    #if HAS_POWER_SWITCH
-      powersupply = false;
-    #endif
+    powersupply = false;
     LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF ".");
     lcd_update();
   #endif
 }
 
-
 /**
  * M82: Set E codes absolute (default)
  */
@@ -3490,7 +3652,7 @@ inline void gcode_M119() {
     SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
     SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
   #endif
-  #if defined(Z_PROBE_PIN) && Z_PROBE_PIN >-1
+  #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
     SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
     SERIAL_PROTOCOLLN(((READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
   #endif
@@ -3794,7 +3956,7 @@ inline void gcode_M221() {
       extruder_multiply[tmp_extruder] = sval;
     }
     else {
-      extrudemultiply = sval;
+      extruder_multiply[active_extruder] = sval;
     }
   }
 }
@@ -4231,7 +4393,7 @@ inline void gcode_M400() { st_synchronize(); }
     //SERIAL_PROTOCOLPGM("Filament dia (measured mm):");
     //SERIAL_PROTOCOL(filament_width_meas);
     //SERIAL_PROTOCOLPGM("Extrusion ratio(%):");
-    //SERIAL_PROTOCOL(extrudemultiply);
+    //SERIAL_PROTOCOL(extruder_multiply[active_extruder]);
   }
 
   /**
@@ -4704,18 +4866,14 @@ void process_commands() {
       gcode_G28();
       break;
 
-    #if defined(MESH_BED_LEVELING)
-      case 29: // G29 Handle mesh based leveling
+    #if defined(ENABLE_AUTO_BED_LEVELING) || defined(MESH_BED_LEVELING)
+      case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
         gcode_G29();
         break;
     #endif
 
     #ifdef ENABLE_AUTO_BED_LEVELING
 
-      case 29: // G29 Detailed Z-Probe, probes the bed at 3 or more points.
-        gcode_G29();
-        break;
-
       #ifndef Z_PROBE_SLED
 
         case 30: // G30 Single Z Probe
@@ -4862,15 +5020,15 @@ void process_commands() {
         #endif //HEATER_2_PIN
       #endif //BARICUDA
 
-      #if HAS_POWER_SWITCH
+      #if defined(PS_ON_PIN) && PS_ON_PIN > -1
 
         case 80: // M80 - Turn on Power Supply
           gcode_M80();
           break;
 
-      #endif // HAS_POWER_SWITCH
+      #endif // PS_ON_PIN
 
-      case 81: // M81 - Turn off Power, including Power Supply, if possible
+      case 81: // M81 - Turn off Power Supply
         gcode_M81();
         break;
 
@@ -5410,69 +5568,72 @@ void prepare_move()
   
   #ifdef SCARA //for now same as delta-code
 
-float difference[NUM_AXIS];
-for (int8_t i=0; i < NUM_AXIS; i++) {
-  difference[i] = destination[i] - current_position[i];
-}
+    float difference[NUM_AXIS];
+    for (int8_t i = 0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i];
 
-float cartesian_mm = sqrt(  sq(difference[X_AXIS]) +
-              sq(difference[Y_AXIS]) +
-              sq(difference[Z_AXIS]));
-if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
-if (cartesian_mm < 0.000001) { return; }
-float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
-int steps = max(1, int(scara_segments_per_second * seconds));
- //SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
- //SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
- //SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
-for (int s = 1; s <= steps; s++) {
-  float fraction = float(s) / float(steps);
-  for(int8_t i=0; i < NUM_AXIS; i++) {
-    destination[i] = current_position[i] + difference[i] * fraction;
-  }
+    float cartesian_mm = sqrt(  sq(difference[X_AXIS]) +
+                                sq(difference[Y_AXIS]) +
+                                sq(difference[Z_AXIS]));
+    if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
+    if (cartesian_mm < 0.000001) { return; }
+    float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
+    int steps = max(1, int(scara_segments_per_second * seconds));
 
+    //SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
+    //SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
+    //SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
+
+    for (int s = 1; s <= steps; s++) {
+      float fraction = float(s) / float(steps);
+      for(int8_t i = 0; i < NUM_AXIS; i++) {
+        destination[i] = current_position[i] + difference[i] * fraction;
+      }
   
-  calculate_delta(destination);
-         //SERIAL_ECHOPGM("destination[X_AXIS]="); SERIAL_ECHOLN(destination[X_AXIS]);
-         //SERIAL_ECHOPGM("destination[Y_AXIS]="); SERIAL_ECHOLN(destination[Y_AXIS]);
-         //SERIAL_ECHOPGM("destination[Z_AXIS]="); SERIAL_ECHOLN(destination[Z_AXIS]);
-         //SERIAL_ECHOPGM("delta[X_AXIS]="); SERIAL_ECHOLN(delta[X_AXIS]);
-         //SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
-         //SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
-         
-  plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
-  destination[E_AXIS], feedrate*feedmultiply/60/100.0,
-  active_extruder);
-}
-#endif // SCARA
-  
-#ifdef DELTA
-  float difference[NUM_AXIS];
-  for (int8_t i=0; i < NUM_AXIS; i++) {
-    difference[i] = destination[i] - current_position[i];
-  }
-  float cartesian_mm = sqrt(sq(difference[X_AXIS]) +
-                            sq(difference[Y_AXIS]) +
-                            sq(difference[Z_AXIS]));
-  if (cartesian_mm < 0.000001) { cartesian_mm = abs(difference[E_AXIS]); }
-  if (cartesian_mm < 0.000001) { return; }
-  float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
-  int steps = max(1, int(delta_segments_per_second * seconds));
-  // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
-  // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
-  // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
-  for (int s = 1; s <= steps; s++) {
-    float fraction = float(s) / float(steps);
-    for(int8_t i=0; i < NUM_AXIS; i++) {
-      destination[i] = current_position[i] + difference[i] * fraction;
+      calculate_delta(destination);
+      //SERIAL_ECHOPGM("destination[X_AXIS]="); SERIAL_ECHOLN(destination[X_AXIS]);
+      //SERIAL_ECHOPGM("destination[Y_AXIS]="); SERIAL_ECHOLN(destination[Y_AXIS]);
+      //SERIAL_ECHOPGM("destination[Z_AXIS]="); SERIAL_ECHOLN(destination[Z_AXIS]);
+      //SERIAL_ECHOPGM("delta[X_AXIS]="); SERIAL_ECHOLN(delta[X_AXIS]);
+      //SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
+      //SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
+
+      plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
+        destination[E_AXIS], feedrate*feedmultiply/60/100.0,
+        active_extruder);
     }
-    calculate_delta(destination);
-    plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
-                     destination[E_AXIS], feedrate*feedmultiply/60/100.0,
-                     active_extruder);
-  }
+
+  #endif // SCARA
   
-#endif // DELTA
+  #ifdef DELTA
+
+    float difference[NUM_AXIS];
+    for (int8_t i=0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i];
+
+    float cartesian_mm = sqrt(sq(difference[X_AXIS]) +
+                              sq(difference[Y_AXIS]) +
+                              sq(difference[Z_AXIS]));
+    if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
+    if (cartesian_mm < 0.000001) return;
+    float seconds = 6000 * cartesian_mm / feedrate / feedmultiply;
+    int steps = max(1, int(delta_segments_per_second * seconds));
+
+    // SERIAL_ECHOPGM("mm="); SERIAL_ECHO(cartesian_mm);
+    // SERIAL_ECHOPGM(" seconds="); SERIAL_ECHO(seconds);
+    // SERIAL_ECHOPGM(" steps="); SERIAL_ECHOLN(steps);
+
+    for (int s = 1; s <= steps; s++) {
+      float fraction = float(s) / float(steps);
+      for (int8_t i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i] + difference[i] * fraction;
+      calculate_delta(destination);
+      #ifdef ENABLE_AUTO_BED_LEVELING
+        adjust_delta(destination);
+      #endif
+      plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS],
+                       destination[E_AXIS], feedrate*feedmultiply/60/100.0,
+                       active_extruder);
+    }
+
+  #endif // DELTA
 
 #ifdef DUAL_X_CARRIAGE
   if (active_extruder_parked)
@@ -5518,13 +5679,13 @@ for (int s = 1; s <= steps; s++) {
 #if ! (defined DELTA || defined SCARA)
   // Do not use feedmultiply for E or Z only moves
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate/60, active_extruder);
+    line_to_destination();
   } else {
 #if defined(MESH_BED_LEVELING)
-    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
+    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
     return;
 #else
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], feedrate*feedmultiply/60/100.0, active_extruder);
+    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
 #endif  // MESH_BED_LEVELING
   }
 #endif // !(DELTA || SCARA)
@@ -5844,17 +6005,19 @@ void kill()
   disable_e2();
   disable_e3();
 
-  #if HAS_POWER_SWITCH
-    pinMode(PS_ON_PIN, INPUT);
-  #endif
-
+#if defined(PS_ON_PIN) && PS_ON_PIN > -1
+  pinMode(PS_ON_PIN,INPUT);
+#endif
   SERIAL_ERROR_START;
   SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
   LCD_ALERTMESSAGEPGM(MSG_KILLED);
   
   // FMC small patch to update the LCD before ending
   sei();   // enable interrupts
-  for (int i = 5; i--; lcd_update()) delay(200); // Wait a short time
+  for ( int i=5; i--; lcd_update())
+  {
+     delay(200);
+  }
   cli();   // disable interrupts
   suicide();
   while(1) { /* Intentionally left empty */ } // Wait for reset
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 1427da21274..10b1d30cce4 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -116,7 +116,7 @@
         #error You must have at least 1 servo defined for NUM_SERVOS to use Z_PROBE_AND_ENDSTOP
       #endif
       #ifndef SERVO_ENDSTOPS
-        #error You must have SERVO_ENDSTOPS defined and have the Z index set to at least 1 to use Z_PROBE_AND_ENDSTOP
+        #error You must have SERVO_ENDSTOPS defined and have the Z index set to at least 0 or above to use Z_PROBE_AND_ENDSTOP
       #endif
       #ifndef SERVO_ENDSTOP_ANGLES
         #error You must have SERVO_ENDSTOP_ANGLES defined for Z Extend and Retract to use Z_PROBE_AND_ENSTOP
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 0dbc2a297b4..6bd82cc68ef 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -76,6 +76,7 @@ volatile long endstops_stepsTotal, endstops_stepsDone;
 static volatile bool endstop_x_hit = false;
 static volatile bool endstop_y_hit = false;
 static volatile bool endstop_z_hit = false;
+static volatile bool endstop_z_probe_hit = false;
 
 #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
   bool abort_on_endstop_hit = false;
@@ -258,11 +259,11 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
 #define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~BIT(OCIE1A)
 
 void endstops_hit_on_purpose() {
-  endstop_x_hit = endstop_y_hit = endstop_z_hit = false;
+  endstop_x_hit = endstop_y_hit = endstop_z_hit = endstop_z_probe_hit = false;
 }
 
 void checkHitEndstops() {
-  if (endstop_x_hit || endstop_y_hit || endstop_z_hit) {
+  if (endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_z_probe_hit) {
     SERIAL_ECHO_START;
     SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT);
     if (endstop_x_hit) {
@@ -277,6 +278,10 @@ void checkHitEndstops() {
       SERIAL_ECHOPAIR(" Z:", (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
       LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Z");
     }
+    if (endstop_z_probe_hit) {
+    	SERIAL_ECHOPAIR(" Z_PROBE:", (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
+    	LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "ZP");
+    }
     SERIAL_EOL;
 
     endstops_hit_on_purpose();
@@ -549,7 +554,7 @@ ISR(TIMER1_COMPA_vect) {
           if(z_probe_endstop && old_z_probe_endstop)
           {
         	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-        	  endstop_z_hit=true;
+        	  endstop_z_probe_hit=true;
 
 //        	  if (z_probe_endstop && old_z_probe_endstop) SERIAL_ECHOLN("z_probe_endstop = true");
           }
@@ -596,7 +601,7 @@ ISR(TIMER1_COMPA_vect) {
           if(z_probe_endstop && old_z_probe_endstop)
           {
         	  endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-        	  endstop_z_hit=true;
+        	  endstop_z_probe_hit=true;
 //        	  if (z_probe_endstop && old_z_probe_endstop) SERIAL_ECHOLN("z_probe_endstop = true");
           }
           old_z_probe_endstop = z_probe_endstop;

From a508d835dbee8a180d506c85076c7671a66791fa Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 02:14:55 -0500
Subject: [PATCH 25/83] Changed Z_PROBE_AND_ENDSTOP to Z_PROBE_ENDSTOP. Updated
 documentation in Configuration.h. Cleaned up and commented some code relating
 to Z_PROBE_ENDSTOP. Separated Z_MIN_ENDSTOP and Z_PROBE_ENDSTOP completely.

---
 Marlin/Configuration.h | 22 ++++++++++++----------
 Marlin/Marlin_main.cpp | 18 +++++++++++-------
 Marlin/SanityCheck.h   | 31 ++++++++++++++++---------------
 Marlin/pins_RAMPS_13.h |  2 +-
 Marlin/stepper.cpp     | 16 +++++++++-------
 5 files changed, 49 insertions(+), 40 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 2ca9fa231c5..3d6bd50c26c 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -335,7 +335,7 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
 //#define DISABLE_MIN_ENDSTOPS
 // If you want to enable the Z Probe pin, but disable its use, uncomment the line below.
 // This only affects a Z Probe Endstop if you have separate Z min endstop as well and have
-// activated Z_PROBE_AND_ENDSTOP below. If you are using the Z Min endstop on your Z Probe,
+// activated Z_PROBE_ENDSTOP below. If you are using the Z Min endstop on your Z Probe,
 // this has no effect.
 //#define DISABLE_Z_PROBE_ENDSTOP
 
@@ -500,17 +500,19 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
 
   #endif
 
-// Support for concurrent and seperate Z Probe and Z min endstop use.
-// Added by Chris Roadfeldt 3-28-2015
-// If you would like to use both a Z Probe and a Z min endstop at the same time, uncomment #define Z_PROBE_AND_ENDSTOP below
-// You will want to disable Z_SAFE_HOMING above as you will still use the Z min endstop for homing.
-// In order to use this, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
-// RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board for the signal.
+// Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+// If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+// If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+// WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+// To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+// If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+// RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+// for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
 // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
-// D32 is currently selected in the RAMPS 1.3/1.4 pin file. Update the pins.h file for your control board to make use of this. Not doing so nullifies Z_PROBE_AND_ENDSTOP
-// WARNING: Setting the wrong pin may have unexpected and disastrous outcomes. Use with caution and do your homework.
+// D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+// WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
 
-//  #define Z_PROBE_AND_ENDSTOP
+//  #define Z_PROBE_ENDSTOP
 
 #endif // ENABLE_AUTO_BED_LEVELING
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index d95ad890942..98a4df1a3f0 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1240,7 +1240,7 @@ inline void sync_plan_position() {
 
       st_synchronize();
 
-    #if defined(Z_PROBE_AND_ENDSTOP)
+    #if defined(Z_PROBE_ENDSTOP)
       bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
       if (z_probe_endstop) {
     #else
@@ -1314,7 +1314,7 @@ inline void sync_plan_position() {
 
       st_synchronize();
 
-    #if defined(Z_PROBE_AND_ENDSTOP)
+    #if defined(Z_PROBE_ENDSTOP)
       bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
       if (z_probe_endstop) {
     #else
@@ -2805,13 +2805,17 @@ inline void gcode_M42() {
   } // code_seen('S')
 }
 
-// If Z_PROBE_AND_ENDSTOP is changed to completely break it's bonds from Z_MIN_ENDSTOP and become
-// it's own unique entity, then the following logic will need to be modified
-// so it only uses the Z_PROBE
 #if defined(ENABLE_AUTO_BED_LEVELING) && defined(Z_PROBE_REPEATABILITY_TEST)
 
-  #if (Z_MIN_PIN == -1) && (! defined (Z_PROBE_PIN) || Z_PROBE_PIN == -1)
-    #error "You must have a Z_MIN or Z_PROBE endstop in order to enable calculation of Z-Probe repeatability."
+  // This is redudant since the SanityCheck.h already checks for a valid Z_PROBE_PIN, but here for clarity.
+  #if defined (Z_PROBE_ENDSTOP)
+    #if (! defined (Z_PROBE_PIN) || Z_PROBE_PIN == -1)
+      #error "You must have a Z_PROBE_PIN defined in order to enable calculation of Z-Probe repeatability."
+    #endif
+  #else
+    #if (Z_MIN_PIN == -1) &&
+      #error "You must have a Z_MIN_PIN defined in order to enable calculation of Z-Probe repeatability."
+    #endif
   #endif
 
   /**
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 4d4153a97fa..cac7c55e0c9 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -103,26 +103,27 @@
     #endif
 
     /**
-     * Require a Z Probe Pin if Z_PROBE_AND_ENDSTOP is enabled.
+     * Require a Z Probe Pin if Z_PROBE_ENDSTOP is enabled.
      */
-    #if defined(Z_PROBE_AND_ENDSTOP)
+    #if defined(Z_PROBE_ENDSTOP)
       #ifndef Z_PROBE_PIN
-        #error You must have a Z_PROBE_PIN defined in your pins_XXXX.h file if you enable Z_PROBE_AND_ENDSTOP
+        #error You must have a Z_PROBE_PIN defined in your pins_XXXX.h file if you enable Z_PROBE_ENDSTOP
       #endif
       #if Z_PROBE_PIN == -1
-        #error You must set Z_PROBE_PIN to a valid pin if you enable Z_PROBE_AND_ENDSTOP
+        #error You must set Z_PROBE_PIN to a valid pin if you enable Z_PROBE_ENDSTOP
       #endif
-      #ifndef NUM_SERVOS
-        #error You must have NUM_SERVOS defined and there must be at least 1 configured to use Z_PROBE_AND_ENDSTOP
-      #endif
-      #if defined(NUM_SERVOS) && NUM_SERVOS < 1
-        #error You must have at least 1 servo defined for NUM_SERVOS to use Z_PROBE_AND_ENDSTOP
-      #endif
-      #ifndef SERVO_ENDSTOPS
-        #error You must have SERVO_ENDSTOPS defined and have the Z index set to at least 0 or above to use Z_PROBE_AND_ENDSTOP
-      #endif
-      #ifndef SERVO_ENDSTOP_ANGLES
-        #error You must have SERVO_ENDSTOP_ANGLES defined for Z Extend and Retract to use Z_PROBE_AND_ENSTOP
+// Forcing Servo definitions can break some hall effect sensor setups. Leaving these here for further comment.
+//      #ifndef NUM_SERVOS
+//        #error You must have NUM_SERVOS defined and there must be at least 1 configured to use Z_PROBE_ENDSTOP
+//      #endif
+//      #if defined(NUM_SERVOS) && NUM_SERVOS < 1
+//        #error You must have at least 1 servo defined for NUM_SERVOS to use Z_PROBE_ENDSTOP
+//      #endif
+//      #ifndef SERVO_ENDSTOPS
+//        #error You must have SERVO_ENDSTOPS defined and have the Z index set to at least 0 or above to use Z_PROBE_ENDSTOP
+//      #endif
+//      #ifndef SERVO_ENDSTOP_ANGLES
+//        #error You must have SERVO_ENDSTOP_ANGLES defined for Z Extend and Retract to use Z_PROBE_AND_ENSTOP
       #endif
     #endif
     /**
diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h
index 3ca12dd1568..11ecddeda2a 100644
--- a/Marlin/pins_RAMPS_13.h
+++ b/Marlin/pins_RAMPS_13.h
@@ -62,7 +62,7 @@
   #define FILWIDTH_PIN        5
 #endif
 
-#if defined(Z_PROBE_AND_ENDSTOP)
+#if defined(Z_PROBE_ENDSTOP)
   // Define a pin to use as the signal pin on Arduino for the Z_PROBE endstop.
  #define Z_PROBE_PIN 32
 #endif
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 58029c8ccd6..0fb4d8a6726 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -76,7 +76,7 @@ volatile long endstops_stepsTotal, endstops_stepsDone;
 static volatile bool endstop_x_hit = false;
 static volatile bool endstop_y_hit = false;
 static volatile bool endstop_z_hit = false;
-static volatile bool endstop_z_probe_hit = false;
+static volatile bool endstop_z_probe_hit = false; // Leaving this in even if Z_PROBE_ENDSTOP isn't defined, keeps code below cleaner. #ifdef it and usage below to save space.
 
 #ifdef ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED
   bool abort_on_endstop_hit = false;
@@ -113,7 +113,7 @@ static volatile bool endstop_z_probe_hit = false;
   #endif
 #endif
 
-#ifdef Z_PROBE_AND_ENDSTOP
+#ifdef Z_PROBE_ENDSTOP // No need to check for valid pin, SanityCheck.h already does this.
 static bool old_z_probe_endstop = false;
 #endif
 
@@ -259,11 +259,11 @@ volatile signed char count_direction[NUM_AXIS] = { 1, 1, 1, 1 };
 #define DISABLE_STEPPER_DRIVER_INTERRUPT() TIMSK1 &= ~BIT(OCIE1A)
 
 void endstops_hit_on_purpose() {
-  endstop_x_hit = endstop_y_hit = endstop_z_hit = endstop_z_probe_hit = false;
+  endstop_x_hit = endstop_y_hit = endstop_z_hit = endstop_z_probe_hit = false; // #ifdef endstop_z_probe_hit = to save space if needed.
 }
 
 void checkHitEndstops() {
-  if (endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_z_probe_hit) {
+  if (endstop_x_hit || endstop_y_hit || endstop_z_hit || endstop_z_probe_hit) { // #ifdef || endstop_z_probe_hit to save space if needed.
     SERIAL_ECHO_START;
     SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT);
     if (endstop_x_hit) {
@@ -278,10 +278,12 @@ void checkHitEndstops() {
       SERIAL_ECHOPAIR(" Z:", (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
       LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "Z");
     }
+    #ifdef Z_PROBE_ENDSTOP
     if (endstop_z_probe_hit) {
     	SERIAL_ECHOPAIR(" Z_PROBE:", (float)endstops_trigsteps[Z_AXIS] / axis_steps_per_unit[Z_AXIS]);
     	LCD_MESSAGEPGM(MSG_ENDSTOPS_HIT "ZP");
     }
+    #endif
     SERIAL_EOL;
 
     endstops_hit_on_purpose();
@@ -550,7 +552,7 @@ ISR(TIMER1_COMPA_vect) {
           #endif
         #endif
 
-        #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
+        #ifdef Z_PROBE_ENDSTOP
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
           z_probe_endstop=(READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
           if(z_probe_endstop && old_z_probe_endstop)
@@ -597,7 +599,7 @@ ISR(TIMER1_COMPA_vect) {
           #endif
         #endif
 
-        #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
+        #ifdef Z_PROBE_ENDSTOP
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
           z_probe_endstop=(READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
           if(z_probe_endstop && old_z_probe_endstop)
@@ -972,7 +974,7 @@ void st_init() {
     #endif
   #endif  
   
-#if defined(Z_PROBE_PIN) && Z_PROBE_PIN >= 0
+#if (defined(Z_PROBE_PIN) && Z_PROBE_PIN >= 0) && defined(Z_PROBE_ENDSTOP) // Check for Z_PROBE_ENDSTOP so we don't pull a pin high unless it's to be used.
   SET_INPUT(Z_PROBE_PIN);
   #ifdef ENDSTOPPULLUP_ZPROBE
     WRITE(Z_PROBE_PIN,HIGH);

From a57862e29f03e3a1f8dd2f8aa1ff588aa3bbf889 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 11:40:24 -0500
Subject: [PATCH 26/83] Cleaning up code in prep for merge with upstream.

---
 Marlin/Configuration.h                        |   1 -
 Marlin/Marlin.h                               |   1 -
 Marlin/Marlin_main.cpp                        |  83 +++++++------
 Marlin/dogm_lcd_implementation.h              |   2 +-
 Marlin/planner.cpp                            |   4 +-
 Marlin/stepper.cpp                            | 116 +++++++++++-------
 Marlin/ultralcd.cpp                           |   2 +-
 .../ultralcd_implementation_hitachi_HD44780.h |  16 +--
 8 files changed, 125 insertions(+), 100 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 3d6bd50c26c..f23b1e45b29 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -330,7 +330,6 @@ const bool X_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 const bool Y_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
 const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic of the endstop.
-
 //#define DISABLE_MAX_ENDSTOPS
 //#define DISABLE_MIN_ENDSTOPS
 // If you want to enable the Z Probe pin, but disable its use, uncomment the line below.
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 336e771fd95..e0441714b19 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -231,7 +231,6 @@ void refresh_cmd_timeout(void);
 extern float homing_feedrate[];
 extern bool axis_relative_modes[];
 extern int feedmultiply;
-extern int extrudemultiply; // Sets extrude multiply factor (in percent) for all extruders
 extern bool volumetric_enabled;
 extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
 extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 8c463d91d29..5bc239d4703 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -170,10 +170,10 @@
 // M404 - N<dia in mm> Enter the nominal filament width (3mm, 1.75mm ) or will display nominal filament width without parameters
 // M405 - Turn on Filament Sensor extrusion control.  Optional D<delay in cm> to set delay in centimeters between sensor and extruder
 // M406 - Turn off Filament Sensor extrusion control
-// M407 - Displays measured filament diameter
+// M407 - Display measured filament diameter
 // M500 - Store parameters in EEPROM
 // M501 - Read parameters from EEPROM (if you need reset them after you changed them temporarily).
-// M502 - Revert to the default "factory settings".  You still need to store them in EEPROM afterwards if you want to.
+// M502 - Revert to the default "factory settings". You still need to store them in EEPROM afterwards if you want to.
 // M503 - Print the current settings (from memory not from EEPROM). Use S0 to leave off headings.
 // M540 - Use S[0|1] to enable or disable the stop SD card print on endstop hit (requires ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
 // M600 - Pause for filament change X[pos] Y[pos] Z[relative lift] E[initial retract] L[later retract distance for removal]
@@ -272,7 +272,7 @@ int fanSpeed = 0;
 
 #endif // FWRETRACT
 
-#ifdef ULTIPANEL
+#if defined(ULTIPANEL) && HAS_POWER_SWITCH
   bool powersupply = 
     #ifdef PS_DEFAULT_OFF
       false
@@ -311,13 +311,13 @@ bool cancel_heatup = false;
 
 #ifdef FILAMENT_SENSOR
   //Variables for Filament Sensor input
-  float filament_width_nominal=DEFAULT_NOMINAL_FILAMENT_DIA;  //Set nominal filament width, can be changed with M404
-  bool filament_sensor=false;  //M405 turns on filament_sensor control, M406 turns it off
-  float filament_width_meas=DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter
+  float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA;  //Set nominal filament width, can be changed with M404
+  bool filament_sensor = false;  //M405 turns on filament_sensor control, M406 turns it off
+  float filament_width_meas = DEFAULT_MEASURED_FILAMENT_DIA; //Stores the measured filament diameter
   signed char measurement_delay[MAX_MEASUREMENT_DELAY+1];  //ring buffer to delay measurement  store extruder factor after subtracting 100
-  int delay_index1=0;  //index into ring buffer
-  int delay_index2=-1;  //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized
-  float delay_dist=0; //delay distance counter
+  int delay_index1 = 0;  //index into ring buffer
+  int delay_index2 = -1;  //index into ring buffer - set to -1 on startup to indicate ring buffer needs to be initialized
+  float delay_dist = 0; //delay distance counter
   int meas_delay_cm = MEASUREMENT_DELAY_CM;  //distance delay setting
 #endif
 
@@ -516,8 +516,8 @@ void setup_powerhold()
   #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
     OUT_WRITE(SUICIDE_PIN, HIGH);
   #endif
-  #if defined(PS_ON_PIN) && PS_ON_PIN > -1
-    #if defined(PS_DEFAULT_OFF)
+  #if HAS_POWER_SWITCH
+    #ifdef PS_DEFAULT_OFF
       OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
     #else
       OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE);
@@ -1100,7 +1100,7 @@ inline void sync_plan_position() {
   static void run_z_probe() {
 
     #ifdef DELTA
-
+    
       float start_z = current_position[Z_AXIS];
       long start_steps = st_get_position(Z_AXIS);
     
@@ -1153,7 +1153,7 @@ inline void sync_plan_position() {
       current_position[Z_AXIS] = st_get_position_mm(Z_AXIS);
       // make sure the planner knows where we are as it may be a bit different than we last said to move to
       sync_plan_position();
-
+      
     #endif // !DELTA
   }
 
@@ -1163,7 +1163,7 @@ inline void sync_plan_position() {
     #ifdef DELTA
 
       feedrate = XY_TRAVEL_SPEED;
-
+      
       destination[X_AXIS] = x;
       destination[Y_AXIS] = y;
       destination[Z_AXIS] = z;
@@ -1237,12 +1237,12 @@ inline void sync_plan_position() {
       feedrate = homing_feedrate[X_AXIS]/10;
       destination[X_AXIS] = 0;
       prepare_move_raw();
-
+      
       // Home Y for safety
       feedrate = homing_feedrate[X_AXIS]/2;
       destination[Y_AXIS] = 0;
       prepare_move_raw();
-
+      
       st_synchronize();
 
     #if defined(Z_PROBE_ENDSTOP)
@@ -1250,7 +1250,7 @@ inline void sync_plan_position() {
       if (z_probe_endstop) {
     #else
       bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-      if (!z_min_endstop) {
+      if (z_min_endstop) {
     #endif
         if (!Stopped) {
           SERIAL_ERROR_START;
@@ -1261,7 +1261,7 @@ inline void sync_plan_position() {
       }
 
     #endif // Z_PROBE_ALLEN_KEY
-      
+
   }
 
   static void retract_z_probe() {
@@ -1279,9 +1279,9 @@ inline void sync_plan_position() {
         #if SERVO_LEVELING
           servos[servo_endstops[Z_AXIS]].attach(0);
         #endif
-          
-          servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2 + 1]);
-          
+
+        servos[servo_endstops[Z_AXIS]].write(servo_endstop_angles[Z_AXIS * 2 + 1]);
+
         #if SERVO_LEVELING
           delay(PROBE_SERVO_DEACTIVATION_DELAY);
           servos[servo_endstops[Z_AXIS]].detach();
@@ -1305,23 +1305,23 @@ inline void sync_plan_position() {
       feedrate = homing_feedrate[Z_AXIS]/10;
       destination[Z_AXIS] = current_position[Z_AXIS] - Z_PROBE_ALLEN_KEY_RETRACT_DEPTH;
       prepare_move_raw();
-
+      
       // Move up for safety
       feedrate = homing_feedrate[Z_AXIS]/2;
       destination[Z_AXIS] = current_position[Z_AXIS] + Z_PROBE_ALLEN_KEY_RETRACT_DEPTH * 2;
       prepare_move_raw();
-
+      
       // Home XY for safety
       feedrate = homing_feedrate[X_AXIS]/2;
       destination[X_AXIS] = 0;
       destination[Y_AXIS] = 0;
       prepare_move_raw();
-
+      
       st_synchronize();
 
     #if defined(Z_PROBE_ENDSTOP)
       bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
-      if (z_probe_endstop) {
+      if (!z_probe_endstop) {
     #else
       bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
       if (!z_min_endstop) {
@@ -3319,7 +3319,7 @@ inline void gcode_M140() {
   if (code_seen('S')) setTargetBed(code_value());
 }
 
-#if defined(PS_ON_PIN) && PS_ON_PIN > -1
+#if HAS_POWER_SWITCH
 
   /**
    * M80: Turn on Power Supply
@@ -3341,10 +3341,12 @@ inline void gcode_M140() {
     #endif
   }
 
-#endif // PS_ON_PIN
+#endif // HAS_POWER_SWITCH
 
 /**
- * M81: Turn off Power Supply
+ * M81: Turn off Power, including Power Supply, if there is one.
+ *
+ *      This code should ALWAYS be available for EMERGENCY SHUTDOWN!
  */
 inline void gcode_M81() {
   disable_heater();
@@ -3359,16 +3361,19 @@ inline void gcode_M81() {
   #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
     st_synchronize();
     suicide();
-  #elif defined(PS_ON_PIN) && PS_ON_PIN > -1
+  #elif HAS_POWER_SWITCH
     OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP);
   #endif
   #ifdef ULTIPANEL
-    powersupply = false;
+    #if HAS_POWER_SWITCH
+      powersupply = false;
+    #endif
     LCD_MESSAGEPGM(MACHINE_NAME " " MSG_OFF ".");
     lcd_update();
   #endif
 }
 
+
 /**
  * M82: Set E codes absolute (default)
  */
@@ -4903,15 +4908,15 @@ void process_commands() {
         #endif //HEATER_2_PIN
       #endif //BARICUDA
 
-      #if defined(PS_ON_PIN) && PS_ON_PIN > -1
+      #if HAS_POWER_SWITCH
 
         case 80: // M80 - Turn on Power Supply
           gcode_M80();
           break;
 
-      #endif // PS_ON_PIN
+      #endif // HAS_POWER_SWITCH
 
-      case 81: // M81 - Turn off Power Supply
+      case 81: // M81 - Turn off Power, including Power Supply, if possible
         gcode_M81();
         break;
 
@@ -5882,19 +5887,17 @@ void kill()
   disable_e2();
   disable_e3();
 
-#if defined(PS_ON_PIN) && PS_ON_PIN > -1
-  pinMode(PS_ON_PIN,INPUT);
-#endif
+  #if HAS_POWER_SWITCH
+    pinMode(PS_ON_PIN, INPUT);
+  #endif
+
   SERIAL_ERROR_START;
   SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
   LCD_ALERTMESSAGEPGM(MSG_KILLED);
   
   // FMC small patch to update the LCD before ending
   sei();   // enable interrupts
-  for ( int i=5; i--; lcd_update())
-  {
-     delay(200);
-  }
+  for (int i = 5; i--; lcd_update()) delay(200); // Wait a short time
   cli();   // disable interrupts
   suicide();
   while(1) { /* Intentionally left empty */ } // Wait for reset
diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index 89cd5e835c4..63e99bd3aa9 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -369,7 +369,7 @@ static void lcd_implementation_status_screen() {
       lcd_printPGM(PSTR("dia:"));
       lcd_print(ftostr12ns(filament_width_meas));
       lcd_printPGM(PSTR(" factor:"));
-      lcd_print(itostr3(extrudemultiply));
+      lcd_print(itostr3(volumetric_multiplier[FILAMENT_SENSOR_EXTRUDER_NUM]));
       lcd_print('%');
     }
   #endif
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index 786527d0d70..d98ef63d4df 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -545,7 +545,7 @@ float junction_deviation = 0.1;
   block->steps[Z_AXIS] = labs(dz);
   block->steps[E_AXIS] = labs(de);
   block->steps[E_AXIS] *= volumetric_multiplier[active_extruder];
-  block->steps[E_AXIS] *= extrudemultiply;
+  block->steps[E_AXIS] *= extruder_multiply[active_extruder];
   block->steps[E_AXIS] /= 100;
   block->step_event_count = max(block->steps[X_AXIS], max(block->steps[Y_AXIS], max(block->steps[Z_AXIS], block->steps[E_AXIS])));
 
@@ -679,7 +679,7 @@ float junction_deviation = 0.1;
     delta_mm[Y_AXIS] = dy / axis_steps_per_unit[Y_AXIS];
   #endif
   delta_mm[Z_AXIS] = dz / axis_steps_per_unit[Z_AXIS];
-  delta_mm[E_AXIS] = (de / axis_steps_per_unit[E_AXIS]) * volumetric_multiplier[active_extruder] * extrudemultiply / 100.0;
+  delta_mm[E_AXIS] = (de / axis_steps_per_unit[E_AXIS]) * volumetric_multiplier[active_extruder] * extruder_multiply[active_extruder] / 100.0;
 
   if (block->steps[X_AXIS] <= dropsegments && block->steps[Y_AXIS] <= dropsegments && block->steps[Z_AXIS] <= dropsegments) {
     block->millimeters = fabs(delta_mm[E_AXIS]);
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 0fb4d8a6726..5c01e2f154b 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -524,33 +524,43 @@ ISR(TIMER1_COMPA_vect) {
     }
 
     if (TEST(out_bits, Z_AXIS)) {   // -direction
+
       Z_APPLY_DIR(INVERT_Z_DIR,0);
       count_direction[Z_AXIS] = -1;
-      if (check_endstops) 
-      {
-        #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
-          #ifndef Z_DUAL_ENDSTOPS
-            UPDATE_ENDSTOP(z, Z, min, MIN);
-          #else
-            bool z_min_endstop=(READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-            #if defined(Z2_MIN_PIN) && Z2_MIN_PIN > -1
-              bool z2_min_endstop=(READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING);
-            #else
-              bool z2_min_endstop=z_min_endstop;
-            #endif
-            if(((z_min_endstop && old_z_min_endstop) || (z2_min_endstop && old_z2_min_endstop)) && (current_block->steps[Z_AXIS] > 0))
-            {
+
+      if (check_endstops) {
+
+        #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0
+
+          #ifdef Z_DUAL_ENDSTOPS
+
+            bool z_min_endstop = READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING,
+                z2_min_endstop =
+                  #if defined(Z2_MIN_PIN) && Z2_MIN_PIN >= 0
+                    READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING
+                  #else
+                    z_min_endstop
+                  #endif
+                ;
+
+            bool z_min_both = z_min_endstop && old_z_min_endstop,
+                z2_min_both = z2_min_endstop && old_z2_min_endstop;
+            if ((z_min_both || z2_min_both) && current_block->steps[Z_AXIS] > 0) {
               endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-              endstop_z_hit=true;
-              if (!(performing_homing) || ((performing_homing)&&(z_min_endstop && old_z_min_endstop)&&(z2_min_endstop && old_z2_min_endstop))) //if not performing home or if both endstops were trigged during homing...
-              {
+              endstop_z_hit = true;
+              if (!performing_homing || (performing_homing && z_min_both && z2_min_both)) //if not performing home or if both endstops were trigged during homing...
                 step_events_completed = current_block->step_event_count;
-              } 
             }
             old_z_min_endstop = z_min_endstop;
             old_z2_min_endstop = z2_min_endstop;
-          #endif
-        #endif
+
+          #else // !Z_DUAL_ENDSTOPS
+
+            UPDATE_ENDSTOP(z, Z, min, MIN);
+
+          #endif // !Z_DUAL_ENDSTOPS
+
+        #endif // Z_MIN_PIN
 
         #ifdef Z_PROBE_ENDSTOP
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
@@ -564,41 +574,53 @@ ISR(TIMER1_COMPA_vect) {
           }
           old_z_probe_endstop = z_probe_endstop;
         #endif
-      }
+        
+      } // check_endstops
+
     }
     else { // +direction
+
       Z_APPLY_DIR(!INVERT_Z_DIR,0);
       count_direction[Z_AXIS] = 1;
+
       if (check_endstops) {
+
         #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
-          #ifndef Z_DUAL_ENDSTOPS
-            UPDATE_ENDSTOP(z, Z, max, MAX);
-          #else
-            bool z_max_endstop=(READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING);
-            #if defined(Z2_MAX_PIN) && Z2_MAX_PIN > -1
-              bool z2_max_endstop=(READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING);
-            #else
-              bool z2_max_endstop=z_max_endstop;
-            #endif
-            if(((z_max_endstop && old_z_max_endstop) || (z2_max_endstop && old_z2_max_endstop)) && (current_block->steps[Z_AXIS] > 0))
-            {
+
+          #ifdef Z_DUAL_ENDSTOPS
+
+            bool z_max_endstop = READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING,
+                z2_max_endstop =
+                  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
+                    READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING
+                  #else
+                    z_max_endstop
+                  #endif
+                ;
+
+            bool z_max_both = z_max_endstop && old_z_max_endstop,
+                z2_max_both = z2_max_endstop && old_z2_max_endstop;
+            if ((z_max_both || z2_max_both) && current_block->steps[Z_AXIS] > 0) {
               endstops_trigsteps[Z_AXIS] = count_position[Z_AXIS];
-              endstop_z_hit=true;
+              endstop_z_hit = true;
 
-//              if (z_max_endstop && old_z_max_endstop) SERIAL_ECHOLN("z_max_endstop = true");
-//              if (z2_max_endstop && old_z2_max_endstop) SERIAL_ECHOLN("z2_max_endstop = true");
+             // if (z_max_both) SERIAL_ECHOLN("z_max_endstop = true");
+             // if (z2_max_both) SERIAL_ECHOLN("z2_max_endstop = true");
 
-            
-              if (!(performing_homing) || ((performing_homing)&&(z_max_endstop && old_z_max_endstop)&&(z2_max_endstop && old_z2_max_endstop))) //if not performing home or if both endstops were trigged during homing...
-              {
+              if (!performing_homing || (performing_homing && z_max_both && z2_max_both)) //if not performing home or if both endstops were trigged during homing...
                 step_events_completed = current_block->step_event_count;
-              } 
             }
             old_z_max_endstop = z_max_endstop;
             old_z2_max_endstop = z2_max_endstop;
-          #endif
-        #endif
 
+          #else // !Z_DUAL_ENDSTOPS
+
+            UPDATE_ENDSTOP(z, Z, max, MAX);
+
+          #endif // !Z_DUAL_ENDSTOPS
+
+        #endif // Z_MAX_PIN
+        
         #ifdef Z_PROBE_ENDSTOP
           UPDATE_ENDSTOP(z, Z, probe, PROBE);
           z_probe_endstop=(READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
@@ -610,22 +632,24 @@ ISR(TIMER1_COMPA_vect) {
           }
           old_z_probe_endstop = z_probe_endstop;
         #endif
-      }
-    }
+
+      } // check_endstops
+
+    } // +direction
 
     #ifndef ADVANCE
       if (TEST(out_bits, E_AXIS)) {  // -direction
         REV_E_DIR();
-        count_direction[E_AXIS]=-1;
+        count_direction[E_AXIS] = -1;
       }
       else { // +direction
         NORM_E_DIR();
-        count_direction[E_AXIS]=1;
+        count_direction[E_AXIS] = 1;
       }
     #endif //!ADVANCE
 
     // Take multiple steps per interrupt (For high speed moves)
-    for (int8_t i=0; i < step_loops; i++) {
+    for (int8_t i = 0; i < step_loops; i++) {
       #ifndef AT90USB
         MSerial.checkRx(); // Check for serial chars.
       #endif
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index a9930fc1437..d2a2e6faaf4 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -491,7 +491,7 @@ static void lcd_tune_menu() {
     MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_BED, &target_temperature_bed, 0, BED_MAXTEMP - 15);
   #endif
   MENU_MULTIPLIER_ITEM_EDIT(int3, MSG_FAN_SPEED, &fanSpeed, 0, 255);
-  MENU_ITEM_EDIT(int3, MSG_FLOW, &extrudemultiply, 10, 999);
+  MENU_ITEM_EDIT(int3, MSG_FLOW, &extruder_multiply[active_extruder], 10, 999);
   MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F0, &extruder_multiply[0], 10, 999);
   #if TEMP_SENSOR_1 != 0
     MENU_ITEM_EDIT(int3, MSG_FLOW MSG_F1, &extruder_multiply[1], 10, 999);
diff --git a/Marlin/ultralcd_implementation_hitachi_HD44780.h b/Marlin/ultralcd_implementation_hitachi_HD44780.h
index 583cde662f9..4819e3e00b1 100644
--- a/Marlin/ultralcd_implementation_hitachi_HD44780.h
+++ b/Marlin/ultralcd_implementation_hitachi_HD44780.h
@@ -624,7 +624,7 @@ static void lcd_implementation_status_screen()
 
 static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char post_char) {
   char c;
-  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2);
+  uint8_t n = LCD_WIDTH - 2;
   lcd.setCursor(0, row);
   lcd.print(sel ? pre_char : ' ');
   while ((c = pgm_read_byte(pstr)) && n > 0) {
@@ -633,12 +633,11 @@ static void lcd_implementation_drawmenu_generic(bool sel, uint8_t row, const cha
   }
   while(n--) lcd.print(' ');
   lcd.print(post_char);
-  lcd.print(' ');
 }
 
 static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t row, const char* pstr, char pre_char, char* data) {
   char c;
-  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen(data);
+  uint8_t n = LCD_WIDTH - 2 - lcd_strlen(data);
   lcd.setCursor(0, row);
   lcd.print(sel ? pre_char : ' ');
   while ((c = pgm_read_byte(pstr)) && n > 0) {
@@ -651,7 +650,7 @@ static void lcd_implementation_drawmenu_setting_edit_generic(bool sel, uint8_t r
 }
 static void lcd_implementation_drawmenu_setting_edit_generic_P(bool sel, uint8_t row, const char* pstr, char pre_char, const char* data) {
   char c;
-  uint8_t n = LCD_WIDTH - 1 - (LCD_WIDTH < 20 ? 1 : 2) - lcd_strlen_P(data);
+  uint8_t n = LCD_WIDTH - 2 - lcd_strlen_P(data);
   lcd.setCursor(0, row);
   lcd.print(sel ? pre_char : ' ');
   while ((c = pgm_read_byte(pstr)) && n > 0) {
@@ -688,11 +687,11 @@ void lcd_implementation_drawedit(const char* pstr, char* value) {
   lcd.setCursor(1, 1);
   lcd_printPGM(pstr);
   lcd.print(':');
-  lcd.setCursor(LCD_WIDTH - (LCD_WIDTH < 20 ? 0 : 1) - lcd_strlen(value), 1);
+  lcd.setCursor(LCD_WIDTH - lcd_strlen(value), 1);
   lcd_print(value);
 }
 
-static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat) {
+static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename, uint8_t concat, char post_char) {
   char c;
   uint8_t n = LCD_WIDTH - concat;
   lcd.setCursor(0, row);
@@ -706,14 +705,15 @@ static void lcd_implementation_drawmenu_sd(bool sel, uint8_t row, const char* ps
     filename++;
   }
   while (n--) lcd.print(' ');
+  lcd.print(post_char);
 }
 
 static void lcd_implementation_drawmenu_sdfile(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) {
-  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 1);
+  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, ' ');
 }
 
 static void lcd_implementation_drawmenu_sddirectory(bool sel, uint8_t row, const char* pstr, const char* filename, char* longFilename) {
-  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2);
+  lcd_implementation_drawmenu_sd(sel, row, pstr, filename, longFilename, 2, LCD_STR_FOLDER[0]);
 }
 
 #define lcd_implementation_drawmenu_back(sel, row, pstr, data) lcd_implementation_drawmenu_generic(sel, row, pstr, LCD_STR_UPLEVEL[0], LCD_STR_UPLEVEL[0])

From bb41edc2efa05160bf7e0d972b84ad7eb3de1617 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 12:13:25 -0500
Subject: [PATCH 27/83] Fixed extra #endif

---
 Marlin/SanityCheck.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index cac7c55e0c9..6c0c9fd09eb 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -124,7 +124,7 @@
 //      #endif
 //      #ifndef SERVO_ENDSTOP_ANGLES
 //        #error You must have SERVO_ENDSTOP_ANGLES defined for Z Extend and Retract to use Z_PROBE_AND_ENSTOP
-      #endif
+//      #endif
     #endif
     /**
      * Check if Probe_Offset * Grid Points is greater than Probing Range

From 2966ae2022c51449c02fe76eaf2a470c003d26af Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 13:32:25 -0500
Subject: [PATCH 28/83] Fix Z_PROBE_PING not declared, allows code to compile
 if Z_PROBE_ENDSTOP is not used.

---
 Marlin/pins.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/pins.h b/Marlin/pins.h
index 6db56e9f428..0d63298869a 100644
--- a/Marlin/pins.h
+++ b/Marlin/pins.h
@@ -187,7 +187,7 @@
   #define Z_MIN_PIN          -1
 #endif
 
-#ifdef DISABLE_Z_PROBE_ENDSTOP
+#if defined (DISABLE_Z_PROBE_ENDSTOP) || ! defined (Z_PROBE_ENDSTOP) // Allow code to compile regardless of Z_PROBE_ENDSTOP setting.
   #define Z_PROBE_PIN        -1
 #endif
 

From 26dc80bf2d53409387b5915580c9f5534ed8b4c6 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 13:47:17 -0500
Subject: [PATCH 29/83] Typo fixed...

---
 Marlin/Marlin_main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 5bc239d4703..456cfb0a4ea 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2811,7 +2811,7 @@ inline void gcode_M42() {
       #error "You must have a Z_PROBE_PIN defined in order to enable calculation of Z-Probe repeatability."
     #endif
   #else
-    #if (Z_MIN_PIN == -1) &&
+    #if (Z_MIN_PIN == -1)
       #error "You must have a Z_MIN_PIN defined in order to enable calculation of Z-Probe repeatability."
     #endif
   #endif

From 916f59e35f1408a65b68267d0b2ec9d62ccb31b4 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 19:22:05 -0500
Subject: [PATCH 30/83] Spaces not tabs in language.h. Catch unlikely but
 possible error and head crash when using Z_PROBE_REPEATABILITY_TEST

---
 Marlin/SanityCheck.h | 2 +-
 Marlin/language.h    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 6c0c9fd09eb..09d1ca3b652 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -93,7 +93,7 @@
      * Require a Z Min pin
      */
     #if Z_MIN_PIN == -1
-      #if Z_PROBE_PIN == -1
+      #if Z_PROBE_PIN == -1 || (! defined (Z_PROBE_ENDSTOP) || defined (DISABLE_Z_PROBE_ENDSTOP)) // It's possible for someone to set a ping for the Z Probe, but not enable it.
         #ifdef Z_PROBE_REPEATABILITY_TEST
           #error You must have a Z_MIN or Z_PROBE endstop to enable Z_PROBE_REPEATABILITY_TEST.
         #else
diff --git a/Marlin/language.h b/Marlin/language.h
index f4a2d2610a2..4a4698c90f1 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -138,7 +138,7 @@
 #define MSG_Z_MIN                           "z_min: "
 #define MSG_Z_MAX                           "z_max: "
 #define MSG_Z2_MAX                          "z2_max: "
-#define MSG_Z_PROBE							"z_probe: "
+#define MSG_Z_PROBE                         "z_probe: "
 #define MSG_M119_REPORT                     "Reporting endstop status"
 #define MSG_ENDSTOP_HIT                     "TRIGGERED"
 #define MSG_ENDSTOP_OPEN                    "open"

From 59994bd519303ad6f205229ba7d926a57833e4d2 Mon Sep 17 00:00:00 2001
From: Chris Roadfeldt <chris@roadfeldt.com>
Date: Wed, 1 Apr 2015 19:24:42 -0500
Subject: [PATCH 31/83] Not doing network admin work, pin not ping... :)

---
 Marlin/SanityCheck.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 09d1ca3b652..8ea9b2e3d07 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -93,7 +93,7 @@
      * Require a Z Min pin
      */
     #if Z_MIN_PIN == -1
-      #if Z_PROBE_PIN == -1 || (! defined (Z_PROBE_ENDSTOP) || defined (DISABLE_Z_PROBE_ENDSTOP)) // It's possible for someone to set a ping for the Z Probe, but not enable it.
+      #if Z_PROBE_PIN == -1 || (! defined (Z_PROBE_ENDSTOP) || defined (DISABLE_Z_PROBE_ENDSTOP)) // It's possible for someone to set a pin for the Z Probe, but not enable it.
         #ifdef Z_PROBE_REPEATABILITY_TEST
           #error You must have a Z_MIN or Z_PROBE endstop to enable Z_PROBE_REPEATABILITY_TEST.
         #else

From e96df6763048bf21dbd71ed1742e34ac0854d53e Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 2 Apr 2015 05:10:14 -0700
Subject: [PATCH 32/83] Clarify thermal_runaway_protection

- Add comments documenting `thermal_runaway_protection`
- Add an enum for the thermal runaway states
- Add macros for temperature helper functions
- Fix a glitch with the z probe sled in homeaxis
---
 Marlin/Marlin_main.cpp |  59 ++++++++--------
 Marlin/planner.cpp     |   4 +-
 Marlin/temperature.cpp | 152 +++++++++++++++++++----------------------
 Marlin/temperature.h   |  46 +++++--------
 4 files changed, 118 insertions(+), 143 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6b41be6179f..24d9f0d477f 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1460,7 +1460,7 @@ static void homeaxis(int axis) {
     sync_plan_position();
 
     // Engage Servo endstop if enabled
-    #ifdef SERVO_ENDSTOPS && !defined(Z_PROBE_SLED)
+    #if defined(SERVO_ENDSTOPS) && !defined(Z_PROBE_SLED)
 
       #if SERVO_LEVELING
         if (axis == Z_AXIS) engage_z_probe(); else
@@ -2781,7 +2781,7 @@ inline void gcode_M42() {
       }
     }
 
-    #if defined(FAN_PIN) && FAN_PIN > -1
+    #if HAS_FAN
       if (pin_number == FAN_PIN) fanSpeed = pin_status;
     #endif
 
@@ -3067,17 +3067,17 @@ inline void gcode_M104() {
 inline void gcode_M105() {
   if (setTargetedHotend(105)) return;
 
-  #if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
+  #if HAS_TEMP_0
     SERIAL_PROTOCOLPGM("ok T:");
     SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1);
     SERIAL_PROTOCOLPGM(" /");
     SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1);
-    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+    #if HAS_TEMP_BED
       SERIAL_PROTOCOLPGM(" B:");
       SERIAL_PROTOCOL_F(degBed(),1);
       SERIAL_PROTOCOLPGM(" /");
       SERIAL_PROTOCOL_F(degTargetBed(),1);
-    #endif //TEMP_BED_PIN
+    #endif
     for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
       SERIAL_PROTOCOLPGM(" T");
       SERIAL_PROTOCOL(cur_extruder);
@@ -3108,7 +3108,7 @@ inline void gcode_M105() {
   #endif
 
   #ifdef SHOW_TEMP_ADC_VALUES
-    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+    #if HAS_TEMP_BED
       SERIAL_PROTOCOLPGM("    ADC B:");
       SERIAL_PROTOCOL_F(degBed(),1);
       SERIAL_PROTOCOLPGM("C->");
@@ -3124,10 +3124,10 @@ inline void gcode_M105() {
     }
   #endif
 
-  SERIAL_PROTOCOLLN("");
+  SERIAL_EOL;
 }
 
-#if defined(FAN_PIN) && FAN_PIN > -1
+#if HAS_FAN
 
   /**
    * M106: Set Fan Speed
@@ -3139,7 +3139,7 @@ inline void gcode_M105() {
    */
   inline void gcode_M107() { fanSpeed = 0; }
 
-#endif //FAN_PIN
+#endif // HAS_FAN
 
 /**
  * M109: Wait for extruder(s) to reach temperature
@@ -3197,10 +3197,10 @@ inline void gcode_M109() {
             SERIAL_PROTOCOLLN( timetemp );
           }
           else {
-            SERIAL_PROTOCOLLN( "?" );
+            SERIAL_PROTOCOLLNPGM("?");
           }
         #else
-          SERIAL_PROTOCOLLN("");
+          SERIAL_EOL;
         #endif
         timetemp = millis();
       }
@@ -3223,7 +3223,7 @@ inline void gcode_M109() {
   starttime = previous_millis_cmd = millis();
 }
 
-#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+#if HAS_TEMP_BED
 
   /**
    * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
@@ -3251,7 +3251,7 @@ inline void gcode_M109() {
         SERIAL_PROTOCOL((int)active_extruder);
         SERIAL_PROTOCOLPGM(" B:");
         SERIAL_PROTOCOL_F(degBed(), 1);
-        SERIAL_PROTOCOLLN("");
+        SERIAL_EOL;
       }
       manage_heater();
       manage_inactivity();
@@ -3452,27 +3452,26 @@ inline void gcode_M114() {
   SERIAL_PROTOCOLPGM(" Z:");
   SERIAL_PROTOCOL(float(st_get_position(Z_AXIS))/axis_steps_per_unit[Z_AXIS]);
 
-  SERIAL_PROTOCOLLN("");
+  SERIAL_EOL;
 
   #ifdef SCARA
     SERIAL_PROTOCOLPGM("SCARA Theta:");
     SERIAL_PROTOCOL(delta[X_AXIS]);
     SERIAL_PROTOCOLPGM("   Psi+Theta:");
     SERIAL_PROTOCOL(delta[Y_AXIS]);
-    SERIAL_PROTOCOLLN("");
+    SERIAL_EOL;
     
     SERIAL_PROTOCOLPGM("SCARA Cal - Theta:");
     SERIAL_PROTOCOL(delta[X_AXIS]+home_offset[X_AXIS]);
     SERIAL_PROTOCOLPGM("   Psi+Theta (90):");
     SERIAL_PROTOCOL(delta[Y_AXIS]-delta[X_AXIS]-90+home_offset[Y_AXIS]);
-    SERIAL_PROTOCOLLN("");
+    SERIAL_EOL;
     
     SERIAL_PROTOCOLPGM("SCARA step Cal - Theta:");
     SERIAL_PROTOCOL(delta[X_AXIS]/90*axis_steps_per_unit[X_AXIS]);
     SERIAL_PROTOCOLPGM("   Psi+Theta:");
     SERIAL_PROTOCOL((delta[Y_AXIS]-delta[X_AXIS])/90*axis_steps_per_unit[Y_AXIS]);
-    SERIAL_PROTOCOLLN("");
-    SERIAL_PROTOCOLLN("");
+    SERIAL_EOL; SERIAL_EOL;
   #endif
 }
 
@@ -3915,7 +3914,7 @@ inline void gcode_M226() {
       SERIAL_PROTOCOL(servo_index);
       SERIAL_PROTOCOL(": ");
       SERIAL_PROTOCOL(servos[servo_index].read());
-      SERIAL_PROTOCOLLN("");
+      SERIAL_EOL;
     }
   }
 
@@ -3983,7 +3982,7 @@ inline void gcode_M226() {
         //Kc does not have scaling applied above, or in resetting defaults
         SERIAL_PROTOCOL(PID_PARAM(Kc, e));
       #endif
-      SERIAL_PROTOCOLLN("");    
+      SERIAL_EOL;    
     }
     else {
       SERIAL_ECHO_START;
@@ -4008,7 +4007,7 @@ inline void gcode_M226() {
     SERIAL_PROTOCOL(unscalePID_i(bedKi));
     SERIAL_PROTOCOL(" d:");
     SERIAL_PROTOCOL(unscalePID_d(bedKd));
-    SERIAL_PROTOCOLLN("");
+    SERIAL_EOL;
   }
 
 #endif // PIDTEMPBED
@@ -4058,7 +4057,7 @@ inline void gcode_M226() {
     if (code_seen('C')) lcd_setcontrast(code_value_long() & 0x3F);
     SERIAL_PROTOCOLPGM("lcd contrast value: ");
     SERIAL_PROTOCOL(lcd_contrast);
-    SERIAL_PROTOCOLLN("");
+    SERIAL_EOL;
   }
 
 #endif // DOGLCD
@@ -4331,7 +4330,7 @@ inline void gcode_M503() {
         zprobe_zoffset = -value; // compare w/ line 278 of ConfigurationStore.cpp
         SERIAL_ECHO_START;
         SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " " MSG_OK);
-        SERIAL_PROTOCOLLN("");
+        SERIAL_EOL;
       }
       else {
         SERIAL_ECHO_START;
@@ -4340,14 +4339,14 @@ inline void gcode_M503() {
         SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MIN);
         SERIAL_ECHOPGM(MSG_Z_MAX);
         SERIAL_ECHO(Z_PROBE_OFFSET_RANGE_MAX);
-        SERIAL_PROTOCOLLN("");
+        SERIAL_EOL;
       }
     }
     else {
       SERIAL_ECHO_START;
       SERIAL_ECHOLNPGM(MSG_ZPROBE_ZOFFSET " : ");
       SERIAL_ECHO(-zprobe_zoffset);
-      SERIAL_PROTOCOLLN("");
+      SERIAL_EOL;
     }
   }
 
@@ -4852,20 +4851,20 @@ void process_commands() {
         gcode_M109();
         break;
 
-      #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+      #if HAS_TEMP_BED
         case 190: // M190 - Wait for bed heater to reach target.
           gcode_M190();
           break;
-      #endif //TEMP_BED_PIN
+      #endif // HAS_TEMP_BED
 
-      #if defined(FAN_PIN) && FAN_PIN > -1
+      #if HAS_FAN
         case 106: //M106 Fan On
           gcode_M106();
           break;
         case 107: //M107 Fan Off
           gcode_M107();
           break;
-      #endif //FAN_PIN
+      #endif // HAS_FAN
 
       #ifdef BARICUDA
         // PWM for HEATER_1_PIN
@@ -5704,7 +5703,7 @@ void handle_status_leds(void) {
        max_temp = max(max_temp, degHotend(cur_extruder));
        max_temp = max(max_temp, degTargetHotend(cur_extruder));
     }
-    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+    #if HAS_TEMP_BED
       max_temp = max(max_temp, degTargetBed());
       max_temp = max(max_temp, degBed());
     #endif
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index d98ef63d4df..1dcbc96af7d 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -427,7 +427,7 @@ void check_axes_activity() {
     disable_e3();
   }
 
-  #if defined(FAN_PIN) && FAN_PIN > -1 // HAS_FAN
+  #if HAS_FAN
     #ifdef FAN_KICKSTART_TIME
       static unsigned long fan_kick_end;
       if (tail_fan_speed) {
@@ -447,7 +447,7 @@ void check_axes_activity() {
     #else
       analogWrite(FAN_PIN, tail_fan_speed);
     #endif //!FAN_SOFT_PWM
-  #endif //FAN_PIN > -1
+  #endif // HAS_FAN
 
   #ifdef AUTOTEMP
     getHighESpeed();
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index b59ff29df00..2442ad206a8 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1,5 +1,5 @@
 /*
-  temperature.c - temperature control
+  temperature.cpp - temperature control
   Part of Marlin
   
  Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
@@ -16,18 +16,7 @@
  
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- This firmware is a mashup between Sprinter and grbl.
-  (https://github.com/kliment/Sprinter)
-  (https://github.com/simen/grbl/tree)
- 
- It has preliminary support for Matthew Roberts advance algorithm 
-    http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
-
- */
-
+*/
 
 #include "Marlin.h"
 #include "ultralcd.h"
@@ -87,14 +76,15 @@ unsigned char soft_pwm_bed;
 #define HAS_HEATER_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0)
 #define HAS_BED_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_BED_PERIOD) && THERMAL_RUNAWAY_PROTECTION_BED_PERIOD > 0 && TEMP_SENSOR_BED != 0)
 #if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
+  enum TRState { TRInactive, TRFirstHeating, TRStable };
   static bool thermal_runaway = false;
-  void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
+  void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
   #if HAS_HEATER_THERMAL_PROTECTION
-    static int thermal_runaway_state_machine[4]; // = {0,0,0,0};
+    static TRState thermal_runaway_state_machine[4] = { TRInactive, TRInactive, TRInactive, TRInactive };
     static unsigned long thermal_runaway_timer[4]; // = {0,0,0,0};
   #endif
   #if HAS_BED_THERMAL_PROTECTION
-    static int thermal_runaway_bed_state_machine;
+    static TRState thermal_runaway_bed_state_machine = { TRInactive, TRInactive, TRInactive, TRInactive };
     static unsigned long thermal_runaway_bed_timer;
   #endif
 #endif
@@ -238,7 +228,7 @@ void PID_autotune(float temp, int extruder, int ncycles)
     soft_pwm[extruder] = bias = d = PID_MAX / 2;
 
   // PID Tuning loop
-  for(;;) {
+  for (;;) {
 
     unsigned long ms = millis();
 
@@ -609,7 +599,7 @@ void manage_heater() {
   // Loop through all extruders
   for (int e = 0; e < EXTRUDERS; e++) {
 
-    #if defined (THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0
+    #if HAS_HEATER_THERMAL_PROTECTION
       thermal_runaway_protection(&thermal_runaway_state_machine[e], &thermal_runaway_timer[e], current_temperature[e], target_temperature[e], e, THERMAL_RUNAWAY_PROTECTION_PERIOD, THERMAL_RUNAWAY_PROTECTION_HYSTERESIS);
     #endif
 
@@ -637,7 +627,7 @@ void manage_heater() {
         disable_heater();
         _temp_error(0, PSTR(MSG_EXTRUDER_SWITCHED_OFF), PSTR(MSG_ERR_REDUNDANT_TEMP));
       }
-    #endif //TEMP_SENSOR_1_AS_REDUNDANT
+    #endif // TEMP_SENSOR_1_AS_REDUNDANT
 
   } // Extruders Loop
 
@@ -1014,69 +1004,69 @@ void setWatch() {
 }
 
 #if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
-void thermal_runaway_protection(int *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc)
-{
-/*
-      SERIAL_ECHO_START;
-      SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:");
-      SERIAL_ECHO(heater_id);
-      SERIAL_ECHO(" ;  State:");
-      SERIAL_ECHO(*state);
-      SERIAL_ECHO(" ;  Timer:");
-      SERIAL_ECHO(*timer);
-      SERIAL_ECHO(" ;  Temperature:");
-      SERIAL_ECHO(temperature);
-      SERIAL_ECHO(" ;  Target Temp:");
-      SERIAL_ECHO(target_temperature);
-      SERIAL_ECHOLN("");    
-*/
-  if ((target_temperature == 0) || thermal_runaway)
-  {
-    *state = 0;
-    *timer = 0;
-    return;
-  }
-  switch (*state)
-  {
-    case 0: // "Heater Inactive" state
-      if (target_temperature > 0) *state = 1;
-      break;
-    case 1: // "First Heating" state
-      if (temperature >= target_temperature) *state = 2;
-      break;
-    case 2: // "Temperature Stable" state
-    {
-      unsigned long ms = millis();
-      if (temperature >= (target_temperature - hysteresis_degc))
-      {
-        *timer = ms;
-      } 
-      else if ( (ms - *timer) > ((unsigned long) period_seconds) * 1000)
-      {
-        SERIAL_ERROR_START;
-        SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
-        SERIAL_ERRORLN((int)heater_id);
-        LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY); // translatable
-        thermal_runaway = true;
-        while(1)
-        {
-          disable_heater();
-          disable_x();
-          disable_y();
-          disable_z();
-          disable_e0();
-          disable_e1();
-          disable_e2();
-          disable_e3();
-          manage_heater();
-          lcd_update();
-        }
-      }
-    } break;
-  }
-}
-#endif //THERMAL_RUNAWAY_PROTECTION_PERIOD
 
+  void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
+    /*
+        SERIAL_ECHO_START;
+        SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:");
+        SERIAL_ECHO(heater_id);
+        SERIAL_ECHO(" ;  State:");
+        SERIAL_ECHO(*state);
+        SERIAL_ECHO(" ;  Timer:");
+        SERIAL_ECHO(*timer);
+        SERIAL_ECHO(" ;  Temperature:");
+        SERIAL_ECHO(temperature);
+        SERIAL_ECHO(" ;  Target Temp:");
+        SERIAL_ECHO(target_temperature);
+        SERIAL_ECHOLN("");    
+    */
+    if (target_temperature == 0 || thermal_runaway) {
+      *state = TRInactive;
+      *timer = 0;
+      return;
+    }
+
+    switch (*state) {
+      // Inactive state waits for a target temperature, then 
+      case TRInactive:
+        if (target_temperature > 0) *state = TRFirstHeating;
+        break;
+      // When first heating, wait for the temperature to be reached then go to Stable state
+      case TRFirstHeating:
+        if (temperature >= target_temperature) *state = TRStable;
+        break;
+      // While the temperature is stable watch for a bad temperature
+      case TRStable:
+      {
+        // Whenever the current temperature is over the target (-hysteresis) restart the timer
+        if (temperature >= target_temperature - hysteresis_degc) {
+          *timer = millis();
+        }
+        // If the timer goes too long without a reset, trigger shutdown
+        else if (millis() > *timer + period_seconds * 1000UL) {
+          SERIAL_ERROR_START;
+          SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
+          SERIAL_ERRORLN((int)heater_id);
+          LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
+          thermal_runaway = true;
+          for (;;) {
+            disable_heater();
+            disable_x();
+            disable_y();
+            disable_z();
+            disable_e0();
+            disable_e1();
+            disable_e2();
+            disable_e3();
+            manage_heater();
+            lcd_update();
+          }
+        }
+      } break;
+    }
+  }
+
+#endif // HAS_HEATER_THERMAL_PROTECTION
 
 void disable_heater() {
   for (int i=0; i<EXTRUDERS; i++) setTargetHotend(0, i);
diff --git a/Marlin/temperature.h b/Marlin/temperature.h
index 79146a35565..d5cde2448ab 100644
--- a/Marlin/temperature.h
+++ b/Marlin/temperature.h
@@ -18,8 +18,8 @@
   along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef temperature_h
-#define temperature_h 
+#ifndef TEMPERATURE_H
+#define TEMPERATURE_H 
 
 #include "Marlin.h"
 #include "planner.h"
@@ -105,40 +105,27 @@ FORCE_INLINE bool isHeatingBed() { return target_temperature_bed > current_tempe
 FORCE_INLINE bool isCoolingHotend(uint8_t extruder) { return target_temperature[extruder] < current_temperature[extruder]; }
 FORCE_INLINE bool isCoolingBed() { return target_temperature_bed < current_temperature_bed; }
 
-#define degHotend0() degHotend(0)
-#define degTargetHotend0() degTargetHotend(0)
-#define setTargetHotend0(_celsius) setTargetHotend((_celsius), 0)
-#define isHeatingHotend0() isHeatingHotend(0)
-#define isCoolingHotend0() isCoolingHotend(0)
+#define HOTEND_ROUTINES(NR) \
+  FORCE_INLINE float degHotend##NR() { return degHotend(NR); } \
+  FORCE_INLINE float degTargetHotend##NR() { return degTargetHotend(NR); } \
+  FORCE_INLINE void setTargetHotend##NR(const float c) { setTargetHotend(c, NR); } \
+  FORCE_INLINE bool isHeatingHotend##NR() { return isHeatingHotend(NR); } \
+  FORCE_INLINE bool isCoolingHotend##NR() { return isCoolingHotend(NR); }
+HOTEND_ROUTINES(0);
 #if EXTRUDERS > 1
-  #define degHotend1() degHotend(1)
-  #define degTargetHotend1() degTargetHotend(1)
-  #define setTargetHotend1(_celsius) setTargetHotend((_celsius), 1)
-  #define isHeatingHotend1() isHeatingHotend(1)
-  #define isCoolingHotend1() isCoolingHotend(1)
+  HOTEND_ROUTINES(1);
 #else
-  #define setTargetHotend1(_celsius) do{}while(0)
+  #define setTargetHotend1(c) do{}while(0)
 #endif
 #if EXTRUDERS > 2
-  #define degHotend2() degHotend(2)
-  #define degTargetHotend2() degTargetHotend(2)
-  #define setTargetHotend2(_celsius) setTargetHotend((_celsius), 2)
-  #define isHeatingHotend2() isHeatingHotend(2)
-  #define isCoolingHotend2() isCoolingHotend(2)
+  HOTEND_ROUTINES(2);
 #else
-  #define setTargetHotend2(_celsius) do{}while(0)
+  #define setTargetHotend2(c) do{}while(0)
 #endif
 #if EXTRUDERS > 3
-  #define degHotend3() degHotend(3)
-  #define degTargetHotend3() degTargetHotend(3)
-  #define setTargetHotend3(_celsius) setTargetHotend((_celsius), 3)
-  #define isHeatingHotend3() isHeatingHotend(3)
-  #define isCoolingHotend3() isCoolingHotend(3)
+  HOTEND_ROUTINES(3);
 #else
-  #define setTargetHotend3(_celsius) do{}while(0)
-#endif
-#if EXTRUDERS > 4
-  #error Invalid number of extruders
+  #define setTargetHotend3(c) do{}while(0)
 #endif
 
 int getHeaterPower(int heater);
@@ -161,5 +148,4 @@ FORCE_INLINE void autotempShutdown() {
   #endif
 }
 
-
-#endif
+#endif // TEMPERATURE_H

From 23cd54755f1e4ec63d3507a990e3f37d59216729 Mon Sep 17 00:00:00 2001
From: AnHardt <github@kitelab.de>
Date: Thu, 2 Apr 2015 14:50:31 +0200
Subject: [PATCH 33/83] Fix typo in Marlin_main.cpp

related to current_position[Z_AXIS] and retract_zlift.

'+ =' -> '+='

Fix for #1786
---
 Marlin/Marlin_main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6b41be6179f..3eda508593e 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1592,7 +1592,7 @@ void refresh_cmd_timeout(void) { previous_millis_cmd = millis(); }
     else {
 
       if (retract_zlift > 0.01) {
-        current_position[Z_AXIS] + =retract_zlift;
+        current_position[Z_AXIS] += retract_zlift;
         #ifdef DELTA
           sync_plan_position_delta();
         #else

From c756b4cf0798c35ee5b64c52cc0f3782cedbde44 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 2 Apr 2015 06:11:03 -0700
Subject: [PATCH 34/83] Comment tweak

---
 Marlin/temperature.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 2442ad206a8..5a8da940646 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1027,7 +1027,7 @@ void setWatch() {
     }
 
     switch (*state) {
-      // Inactive state waits for a target temperature, then 
+      // Inactive state waits for a target temperature to be set
       case TRInactive:
         if (target_temperature > 0) *state = TRFirstHeating;
         break;

From 34c7d45879e20a0fd5d48c53ddf98f6ed342c1c5 Mon Sep 17 00:00:00 2001
From: Richard Wackerbarth <rkw@dataplex.net>
Date: Fri, 6 Feb 2015 10:30:43 -0600
Subject: [PATCH 35/83] Hook for Auto-generated Build Version

The automatic versioning system extracts a
build version number from the SCM system

That versioning information is written to the file
_Version.h, a file that is NOT preserved in the SCM.

If such a file will be present,
we include it here to utilize the parameters
that are defined therein.
---
 Marlin/language.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Marlin/language.h b/Marlin/language.h
index 10ef445d837..690b0b11d0c 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -36,6 +36,10 @@
   #define LANGUAGE_INCLUDE GENERATE_LANGUAGE_INCLUDE(en)
 #endif
 
+#ifdef HAS_AUTOMATIC_VERSIONING
+  #include "_Version.h"
+#endif
+
 #define PROTOCOL_VERSION "1.0"
 #define FIRMWARE_URL "https://github.com/MarlinFirmware/Marlin"
 

From a33e20b27d32b816e5fbad9877e6879bfa185cb2 Mon Sep 17 00:00:00 2001
From: Richard Wackerbarth <rkw@dataplex.net>
Date: Fri, 6 Feb 2015 09:58:04 -0600
Subject: [PATCH 36/83] Adjust per-project .gitignore

Refer to http://git-scm.com/docs/gitignore
to see why this is appropriate
---
 .gitignore | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/.gitignore b/.gitignore
index cd72efb10d2..380a0285068 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,12 @@
+// Our automatic versioning scheme generates the following file
+// NEVER put it in the repository
+_Version.h
+
+// All of the following OS, IDE and compiler generated file
+// references should be moved from this file
+// They are needed, but they belong in your global .gitignore
+// rather than in a per-project file such as this
+
 *.o
 applet/
 *~

From f4599143ebdaf05d12528e1fedaf3e51f413c274 Mon Sep 17 00:00:00 2001
From: Richard Wackerbarth <rkw@dataplex.net>
Date: Fri, 6 Feb 2015 10:17:17 -0600
Subject: [PATCH 37/83] Allow M115 to better reflect the build

---
 Marlin/language.h | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/Marlin/language.h b/Marlin/language.h
index 690b0b11d0c..77c4f36d41f 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -41,7 +41,6 @@
 #endif
 
 #define PROTOCOL_VERSION "1.0"
-#define FIRMWARE_URL "https://github.com/MarlinFirmware/Marlin"
 
 #if MB(ULTIMAKER)|| MB(ULTIMAKER_OLD)|| MB(ULTIMAIN_2)
   #undef FIRMWARE_URL
@@ -69,13 +68,28 @@
   #define MACHINE_NAME "HEPHESTOS"
   #undef FIRMWARE_URL
   #define FIRMWARE_URL "http://www.bq.com/gb/downloads-prusa-i3-hephestos.html"
-#else // Default firmware set to Mendel
-  #define MACHINE_NAME "Mendel"
+#else
+  #ifndef MACHINE_NAME
+    #define MACHINE_NAME "Mendel"
+  #endif
 #endif
 
 #ifdef CUSTOM_MENDEL_NAME
+  #warning CUSTOM_MENDEL_NAME deprecated - use CUSTOM_MACHINE_NAME
+  #define CUSTOM_MACHINE_NAME CUSTOM_MENDEL_NAME
+#endif
+
+#ifdef CUSTOM_MACHINE_NAME
   #undef MACHINE_NAME
-  #define MACHINE_NAME CUSTOM_MENDEL_NAME
+  #define MACHINE_NAME CUSTOM_MACHINE_NAME
+#endif
+
+#ifndef FIRMWARE_URL
+  #define FIRMWARE_URL "https://github.com/MarlinFirmware/Marlin"
+#endif
+
+#ifndef BUILD_VERSION
+  #define BUILD_VERSION "V1; Sprinter/grbl mashup for gen6"
 #endif
 
 #ifndef MACHINE_UUID
@@ -126,7 +140,7 @@
 #define MSG_HEATING_COMPLETE                "Heating done."
 #define MSG_BED_HEATING                     "Bed Heating."
 #define MSG_BED_DONE                        "Bed done."
-#define MSG_M115_REPORT                     "FIRMWARE_NAME:Marlin V1; Sprinter/grbl mashup for gen6 FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n"
+#define MSG_M115_REPORT                     "FIRMWARE_NAME:Marlin " BUILD_VERSION " FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID "\n"
 #define MSG_COUNT_X                         " Count X: "
 #define MSG_ERR_KILLED                      "Printer halted. kill() called!"
 #define MSG_ERR_STOPPED                     "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"

From ccdaea51babd46fca1351affdaa8168438731fc7 Mon Sep 17 00:00:00 2001
From: Richard Wackerbarth <rkw@dataplex.net>
Date: Thu, 2 Apr 2015 08:15:55 -0500
Subject: [PATCH 38/83] Add KosselPro

---
 Marlin/boards.h   | 1 +
 Marlin/language.h | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/Marlin/boards.h b/Marlin/boards.h
index a8c980097d0..8a60f011d57 100644
--- a/Marlin/boards.h
+++ b/Marlin/boards.h
@@ -37,6 +37,7 @@
 #define BOARD_BRAINWAVE         82   // Brainwave (AT90USB646)
 #define BOARD_SAV_MKI           83   // SAV Mk-I (AT90USB1286)
 #define BOARD_TEENSY2           84   // Teensy++2.0 (AT90USB1286) - CLI compile: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84  make
+#define BOARD_BRAINWAVE_PRO     85   // Brainwave Pro (AT90USB1286)
 #define BOARD_GEN3_PLUS         9    // Gen3+
 #define BOARD_GEN3_MONOLITHIC   22   // Gen3 Monolithic Electronics
 #define BOARD_MEGATRONICS       70   // Megatronics
diff --git a/Marlin/language.h b/Marlin/language.h
index 77c4f36d41f..5b7c22f45b9 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -68,6 +68,11 @@
   #define MACHINE_NAME "HEPHESTOS"
   #undef FIRMWARE_URL
   #define FIRMWARE_URL "http://www.bq.com/gb/downloads-prusa-i3-hephestos.html"
+#elif MB(BRAINWAVE_PRO)
+  #define MACHINE_NAME "Kossel Pro"
+  #ifndef FIRMWARE_URL
+    #define FIRMWARE_URL "https://github.com/OpenBeamUSA/Marlin/"
+  #endif
 #else
   #ifndef MACHINE_NAME
     #define MACHINE_NAME "Mendel"

From 8f620de0ff8e0bd07d86bd1937fb77a68b701fa1 Mon Sep 17 00:00:00 2001
From: Richard Wackerbarth <rkw@dataplex.net>
Date: Wed, 11 Feb 2015 09:00:33 -0600
Subject: [PATCH 39/83] Actually activate Automatic Versioning

---
 .../Arduino_1.5.x/hardware/marlin/avr/platform.local.txt         | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 ArduinoAddons/Arduino_1.5.x/hardware/marlin/avr/platform.local.txt

diff --git a/ArduinoAddons/Arduino_1.5.x/hardware/marlin/avr/platform.local.txt b/ArduinoAddons/Arduino_1.5.x/hardware/marlin/avr/platform.local.txt
new file mode 100644
index 00000000000..ff2ad5d22c6
--- /dev/null
+++ b/ArduinoAddons/Arduino_1.5.x/hardware/marlin/avr/platform.local.txt
@@ -0,0 +1 @@
+compiler.cpp.extra_flags=-DHAS_AUTOMATIC_VERSIONING

From 581b2aae043bd0c1c9e13d003739756e6305b001 Mon Sep 17 00:00:00 2001
From: Wurstnase <tonnhofer@gmail.com>
Date: Fri, 3 Apr 2015 16:11:32 +0200
Subject: [PATCH 40/83] fix feedrate for homing z

max_feedrate is in mm/s. line_to_destination needs a feedrate in mm/min because there is feedrate/60.
---
 Marlin/Marlin_main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6b41be6179f..daa78b40dcf 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1950,7 +1950,7 @@ inline void gcode_G28() {
               current_position[Z_AXIS] = 0;
               plan_set_position(cpx, cpy, 0, current_position[E_AXIS]);
               destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
-              feedrate = max_feedrate[Z_AXIS];
+              feedrate = max_feedrate[Z_AXIS] * 60;  // max_feedrate is in mm/s. line_to_destination is feedrate/60.
               line_to_destination();
               st_synchronize();
               HOMEAXIS(Z);

From 45565b680dce05481d4510c61e12c61b15a21457 Mon Sep 17 00:00:00 2001
From: Wurstnase <tonnhofer@gmail.com>
Date: Fri, 3 Apr 2015 18:01:28 +0200
Subject: [PATCH 41/83] second wrong feedrate

---
 Marlin/Marlin_main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index daa78b40dcf..266812581b0 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1817,7 +1817,7 @@ inline void gcode_G28() {
       // Raise Z before homing any other axes
       if (home_all_axis || homeZ) {
         destination[Z_AXIS] = -Z_RAISE_BEFORE_HOMING * home_dir(Z_AXIS);    // Set destination away from bed
-        feedrate = max_feedrate[Z_AXIS];
+        feedrate = max_feedrate[Z_AXIS] * 60;
         line_to_destination();
         st_synchronize();
       }

From 0e8182bbf2f0ac2c3340b7d89e6b77fa2f55f292 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 15:31:35 -0700
Subject: [PATCH 42/83] Additional pin tests, cleanup

---
 Marlin/Conditionals.h                         |  93 +-
 Marlin/Configuration.h                        |   4 +-
 Marlin/ConfigurationStore.cpp                 |   4 +-
 Marlin/Configuration_adv.h                    |   6 +-
 Marlin/Marlin.h                               |  18 +-
 Marlin/Marlin_main.cpp                        | 802 +++++++++---------
 Marlin/SanityCheck.h                          |  24 +-
 Marlin/configurator/config/Configuration.h    |   2 +-
 .../configurator/config/Configuration_adv.h   |   6 +-
 Marlin/dogm_lcd_implementation.h              |   2 +-
 .../Felix/Configuration.h                     |   2 +-
 .../Felix/Configuration_DUAL.h                |   2 +-
 .../Felix/Configuration_adv.h                 |   6 +-
 .../Hephestos/Configuration.h                 |   2 +-
 .../Hephestos/Configuration_adv.h             |   6 +-
 .../K8200/Configuration.h                     |   2 +-
 .../K8200/Configuration_adv.h                 |   6 +-
 .../SCARA/Configuration.h                     |   2 +-
 .../SCARA/Configuration_adv.h                 |   6 +-
 .../WITBOX/Configuration.h                    |   2 +-
 .../WITBOX/Configuration_adv.h                |   6 +-
 .../delta/generic/Configuration.h             |  10 +-
 .../delta/generic/Configuration_adv.h         |   6 +-
 .../delta/kossel_mini/Configuration.h         |  10 +-
 .../delta/kossel_mini/Configuration_adv.h     |   6 +-
 .../makibox/Configuration.h                   |   2 +-
 .../makibox/Configuration_adv.h               |   6 +-
 .../tvrrug/Round2/Configuration.h             |   2 +-
 .../tvrrug/Round2/Configuration_adv.h         |   6 +-
 Marlin/mesh_bed_leveling.h                    |   2 +-
 Marlin/planner.cpp                            |  10 +-
 Marlin/stepper.cpp                            | 116 +--
 Marlin/temperature.h                          |   2 +-
 Marlin/ultralcd.h                             |  16 +-
 34 files changed, 612 insertions(+), 585 deletions(-)

diff --git a/Marlin/Conditionals.h b/Marlin/Conditionals.h
index c7e20847245..1093e7081ae 100644
--- a/Marlin/Conditionals.h
+++ b/Marlin/Conditionals.h
@@ -10,6 +10,8 @@
 
 #ifndef CONFIGURATION_LCD // Get the LCD defines which are needed first
 
+  #define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0)
+
   #define CONFIGURATION_LCD
 
   #if defined(MAKRPANEL)
@@ -276,7 +278,7 @@
     #define PS_ON_AWAKE  HIGH
     #define PS_ON_ASLEEP LOW
   #endif
-  #define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && defined(PS_ON_PIN) && PS_ON_PIN >= 0)
+  #define HAS_POWER_SWITCH (POWER_SUPPLY > 0 && PIN_EXISTS(PS_ON))
 
   /**
    * Temp Sensor defines
@@ -347,25 +349,80 @@
   #endif
 
   /**
-   * Shorthand for pin tests, for temperature.cpp
+   * Shorthand for pin tests, used wherever needed
    */
-  #define HAS_TEMP_0 (defined(TEMP_0_PIN) && TEMP_0_PIN >= 0 && TEMP_SENSOR_0 != 0 && TEMP_SENSOR_0 != -2)
-  #define HAS_TEMP_1 (defined(TEMP_1_PIN) && TEMP_1_PIN >= 0 && TEMP_SENSOR_1 != 0)
-  #define HAS_TEMP_2 (defined(TEMP_2_PIN) && TEMP_2_PIN >= 0 && TEMP_SENSOR_2 != 0)
-  #define HAS_TEMP_3 (defined(TEMP_3_PIN) && TEMP_3_PIN >= 0 && TEMP_SENSOR_3 != 0)
-  #define HAS_TEMP_BED (defined(TEMP_BED_PIN) && TEMP_BED_PIN >= 0 && TEMP_SENSOR_BED != 0)
-  #define HAS_FILAMENT_SENSOR (defined(FILAMENT_SENSOR) && defined(FILWIDTH_PIN) && FILWIDTH_PIN >= 0)
-  #define HAS_HEATER_0 (defined(HEATER_0_PIN) && HEATER_0_PIN >= 0)
-  #define HAS_HEATER_1 (defined(HEATER_1_PIN) && HEATER_1_PIN >= 0)
-  #define HAS_HEATER_2 (defined(HEATER_2_PIN) && HEATER_2_PIN >= 0)
-  #define HAS_HEATER_3 (defined(HEATER_3_PIN) && HEATER_3_PIN >= 0)
-  #define HAS_HEATER_BED (defined(HEATER_BED_PIN) && HEATER_BED_PIN >= 0)
-  #define HAS_AUTO_FAN_0 (defined(EXTRUDER_0_AUTO_FAN_PIN) && EXTRUDER_0_AUTO_FAN_PIN >= 0)
-  #define HAS_AUTO_FAN_1 (defined(EXTRUDER_1_AUTO_FAN_PIN) && EXTRUDER_1_AUTO_FAN_PIN >= 0)
-  #define HAS_AUTO_FAN_2 (defined(EXTRUDER_2_AUTO_FAN_PIN) && EXTRUDER_2_AUTO_FAN_PIN >= 0)
-  #define HAS_AUTO_FAN_3 (defined(EXTRUDER_3_AUTO_FAN_PIN) && EXTRUDER_3_AUTO_FAN_PIN >= 0)
+  #define HAS_TEMP_0 (PIN_EXISTS(TEMP_0) && TEMP_SENSOR_0 != 0 && TEMP_SENSOR_0 != -2)
+  #define HAS_TEMP_1 (PIN_EXISTS(TEMP_1) && TEMP_SENSOR_1 != 0)
+  #define HAS_TEMP_2 (PIN_EXISTS(TEMP_2) && TEMP_SENSOR_2 != 0)
+  #define HAS_TEMP_3 (PIN_EXISTS(TEMP_3) && TEMP_SENSOR_3 != 0)
+  #define HAS_TEMP_BED (PIN_EXISTS(TEMP_BED) && TEMP_SENSOR_BED != 0)
+  #define HAS_HEATER_0 (PIN_EXISTS(HEATER_0))
+  #define HAS_HEATER_1 (PIN_EXISTS(HEATER_1))
+  #define HAS_HEATER_2 (PIN_EXISTS(HEATER_2))
+  #define HAS_HEATER_3 (PIN_EXISTS(HEATER_3))
+  #define HAS_HEATER_BED (PIN_EXISTS(HEATER_BED))
+  #define HAS_AUTO_FAN_0 (PIN_EXISTS(EXTRUDER_0_AUTO_FAN))
+  #define HAS_AUTO_FAN_1 (PIN_EXISTS(EXTRUDER_1_AUTO_FAN))
+  #define HAS_AUTO_FAN_2 (PIN_EXISTS(EXTRUDER_2_AUTO_FAN))
+  #define HAS_AUTO_FAN_3 (PIN_EXISTS(EXTRUDER_3_AUTO_FAN))
   #define HAS_AUTO_FAN (HAS_AUTO_FAN_0 || HAS_AUTO_FAN_1 || HAS_AUTO_FAN_2 || HAS_AUTO_FAN_3)
-  #define HAS_FAN (defined(FAN_PIN) && FAN_PIN >= 0)
+  #define HAS_FAN (PIN_EXISTS(FAN))
+  #define HAS_CONTROLLERFAN (PIN_EXISTS(CONTROLLERFAN))
+  #define HAS_SERVO_0 (PIN_EXISTS(SERVO0))
+  #define HAS_SERVO_1 (PIN_EXISTS(SERVO1))
+  #define HAS_SERVO_2 (PIN_EXISTS(SERVO2))
+  #define HAS_SERVO_3 (PIN_EXISTS(SERVO3))
+  #define HAS_FILAMENT_SENSOR (defined(FILAMENT_SENSOR) && PIN_EXISTS(FILWIDTH))
+  #define HAS_FILRUNOUT (PIN_EXISTS(FILRUNOUT))
+  #define HAS_HOME (PIN_EXISTS(HOME))
+  #define HAS_KILL (PIN_EXISTS(KILL))
+  #define HAS_SUICIDE (PIN_EXISTS(SUICIDE))
+  #define HAS_PHOTOGRAPH (PIN_EXISTS(PHOTOGRAPH))
+  #define HAS_X_MIN (PIN_EXISTS(X_MIN))
+  #define HAS_X_MAX (PIN_EXISTS(X_MAX))
+  #define HAS_Y_MIN (PIN_EXISTS(Y_MIN))
+  #define HAS_Y_MAX (PIN_EXISTS(Y_MAX))
+  #define HAS_Z_MIN (PIN_EXISTS(Z_MIN))
+  #define HAS_Z_MAX (PIN_EXISTS(Z_MAX))
+  #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN))
+  #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
+  #define HAS_SOLENOID_1 (PIN_EXISTS(SOL1))
+  #define HAS_SOLENOID_2 (PIN_EXISTS(SOL2))
+  #define HAS_SOLENOID_3 (PIN_EXISTS(SOL3))
+  #define HAS_MICROSTEPS (PIN_EXISTS(X_MS1))
+  #define HAS_MICROSTEPS_E0 (PIN_EXISTS(E0_MS1))
+  #define HAS_MICROSTEPS_E1 (PIN_EXISTS(E1_MS1))
+  #define HAS_MICROSTEPS_E2 (PIN_EXISTS(E2_MS1))
+  #define HAS_X_ENABLE (PIN_EXISTS(X_ENABLE))
+  #define HAS_X2_ENABLE (PIN_EXISTS(X2_ENABLE))
+  #define HAS_Y_ENABLE (PIN_EXISTS(Y_ENABLE))
+  #define HAS_Y2_ENABLE (PIN_EXISTS(Y2_ENABLE))
+  #define HAS_Z_ENABLE (PIN_EXISTS(Z_ENABLE))
+  #define HAS_Z2_ENABLE (PIN_EXISTS(Z2_ENABLE))
+  #define HAS_E0_ENABLE (PIN_EXISTS(E0_ENABLE))
+  #define HAS_E1_ENABLE (PIN_EXISTS(E1_ENABLE))
+  #define HAS_E2_ENABLE (PIN_EXISTS(E2_ENABLE))
+  #define HAS_E3_ENABLE (PIN_EXISTS(E3_ENABLE))
+  #define HAS_X_DIR (PIN_EXISTS(X_DIR))
+  #define HAS_X2_DIR (PIN_EXISTS(X2_DIR))
+  #define HAS_Y_DIR (PIN_EXISTS(Y_DIR))
+  #define HAS_Y2_DIR (PIN_EXISTS(Y2_DIR))
+  #define HAS_Z_DIR (PIN_EXISTS(Z_DIR))
+  #define HAS_Z2_DIR (PIN_EXISTS(Z2_DIR))
+  #define HAS_E0_DIR (PIN_EXISTS(E0_DIR))
+  #define HAS_E1_DIR (PIN_EXISTS(E1_DIR))
+  #define HAS_E2_DIR (PIN_EXISTS(E2_DIR))
+  #define HAS_E3_DIR (PIN_EXISTS(E3_DIR))
+  #define HAS_X_STEP (PIN_EXISTS(X_STEP))
+  #define HAS_X2_STEP (PIN_EXISTS(X2_STEP))
+  #define HAS_Y_STEP (PIN_EXISTS(Y_STEP))
+  #define HAS_Y2_STEP (PIN_EXISTS(Y2_STEP))
+  #define HAS_Z_STEP (PIN_EXISTS(Z_STEP))
+  #define HAS_Z2_STEP (PIN_EXISTS(Z2_STEP))
+  #define HAS_E0_STEP (PIN_EXISTS(E0_STEP))
+  #define HAS_E1_STEP (PIN_EXISTS(E1_STEP))
+  #define HAS_E2_STEP (PIN_EXISTS(E2_STEP))
+  #define HAS_E3_STEP (PIN_EXISTS(E3_STEP))
 
   /**
    * Helper Macros for heaters and extruder fan
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index a984923ea2c..748a3914c0c 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -387,7 +387,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
@@ -670,7 +670,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // Data from: http://www.doc-diy.net/photo/rc-1_hacked/
 // #define PHOTOGRAPH_PIN     23
 
-// SF send wrong arc g-codes when using Arc Point as fillet procedure
+// SkeinForge sends the wrong arc g-codes when using Arc Point as fillet procedure
 //#define SF_ARC_FIX
 
 // Support for the BariCUDA Paste Extruder.
diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp
index b1da94a3006..f82e83fc446 100644
--- a/Marlin/ConfigurationStore.cpp
+++ b/Marlin/ConfigurationStore.cpp
@@ -78,7 +78,7 @@
 #include "ultralcd.h"
 #include "ConfigurationStore.h"
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
    #include "mesh_bed_leveling.h"
 #endif  // MESH_BED_LEVELING
 
@@ -308,7 +308,7 @@ void Config_RetrieveSettings() {
 
     uint8_t mesh_num_x = 0;
     uint8_t mesh_num_y = 0;
-    #if defined(MESH_BED_LEVELING)
+    #ifdef MESH_BED_LEVELING
       EEPROM_READ_VAR(i, mbl.active);
       EEPROM_READ_VAR(i, mesh_num_x);
       EEPROM_READ_VAR(i, mesh_num_y);
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index d689ac47f89..4ed188946d8 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 2
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 2
 #define HOMING_BUMP_DIVISOR {2, 2, 4}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index e0441714b19..1f295a65a50 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -110,11 +110,10 @@ void process_commands();
 
 void manage_inactivity(bool ignore_stepper_queue=false);
 
-#if defined(DUAL_X_CARRIAGE) && defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1 \
-    && defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1
+#if defined(DUAL_X_CARRIAGE) && HAS_X_ENABLE && HAS_X2_ENABLE
   #define  enable_x() do { X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); } while (0)
   #define disable_x() do { X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; } while (0)
-#elif defined(X_ENABLE_PIN) && X_ENABLE_PIN > -1
+#elif HAS_X_ENABLE
   #define  enable_x() X_ENABLE_WRITE( X_ENABLE_ON)
   #define disable_x() { X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }
 #else
@@ -122,7 +121,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_x() ;
 #endif
 
-#if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN > -1
+#if HAS_Y_ENABLE
   #ifdef Y_DUAL_STEPPER_DRIVERS
     #define  enable_y() { Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }
     #define disable_y() { Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }
@@ -135,7 +134,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_y() ;
 #endif
 
-#if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN > -1
+#if HAS_Z_ENABLE
   #ifdef Z_DUAL_STEPPER_DRIVERS
     #define  enable_z() { Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }
     #define disable_z() { Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }
@@ -148,7 +147,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_z() ;
 #endif
 
-#if defined(E0_ENABLE_PIN) && (E0_ENABLE_PIN > -1)
+#if HAS_E0_ENABLE
   #define enable_e0() E0_ENABLE_WRITE(E_ENABLE_ON)
   #define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON)
 #else
@@ -156,7 +155,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_e0() /* nothing */
 #endif
 
-#if (EXTRUDERS > 1) && defined(E1_ENABLE_PIN) && (E1_ENABLE_PIN > -1)
+#if (EXTRUDERS > 1) && HAS_E1_ENABLE
   #define enable_e1() E1_ENABLE_WRITE(E_ENABLE_ON)
   #define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON)
 #else
@@ -164,7 +163,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_e1() /* nothing */
 #endif
 
-#if (EXTRUDERS > 2) && defined(E2_ENABLE_PIN) && (E2_ENABLE_PIN > -1)
+#if (EXTRUDERS > 2) && HAS_E2_ENABLE
   #define enable_e2() E2_ENABLE_WRITE(E_ENABLE_ON)
   #define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON)
 #else
@@ -172,7 +171,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_e2() /* nothing */
 #endif
 
-#if (EXTRUDERS > 3) && defined(E3_ENABLE_PIN) && (E3_ENABLE_PIN > -1)
+#if (EXTRUDERS > 3) && HAS_E3_ENABLE
   #define enable_e3() E3_ENABLE_WRITE(E_ENABLE_ON)
   #define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON)
 #else
@@ -194,7 +193,6 @@ void get_coordinates();
     void adjust_delta(float cartesian[3]);
   #endif
   extern float delta[3];
-  void prepare_move_raw();
 #endif
 #ifdef SCARA
   void calculate_delta(float cartesian[3]);
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6b41be6179f..13484c986c1 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -36,11 +36,11 @@
   #endif
 #endif // ENABLE_AUTO_BED_LEVELING
 
-#define SERVO_LEVELING defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0
+#define SERVO_LEVELING (defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0)
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #include "mesh_bed_leveling.h"
-#endif  // MESH_BED_LEVELING
+#endif
 
 #include "ultralcd.h"
 #include "planner.h"
@@ -298,6 +298,7 @@ int fanSpeed = 0;
   float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
   float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
   #ifdef ENABLE_AUTO_BED_LEVELING
+    int delta_grid_spacing[2] = { 0, 0 };
     float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS];
   #endif
 #endif
@@ -422,26 +423,24 @@ void serial_echopair_P(const char *s_P, unsigned long v)
 
 //Injects the next command from the pending sequence of commands, when possible
 //Return false if and only if no command was pending
-static bool drain_queued_commands_P()
-{
-  char cmd[30];
-  if(!queued_commands_P)
-    return false;
+static bool drain_queued_commands_P() {
+  if (!queued_commands_P) return false;
+
   // Get the next 30 chars from the sequence of gcodes to run
-  strncpy_P(cmd, queued_commands_P, sizeof(cmd)-1);
-  cmd[sizeof(cmd)-1]= 0;
+  char cmd[30];
+  strncpy_P(cmd, queued_commands_P, sizeof(cmd) - 1);
+  cmd[sizeof(cmd) - 1] = '\0';
+
   // Look for the end of line, or the end of sequence
-  size_t i= 0;
+  size_t i = 0;
   char c;
-  while( (c= cmd[i]) && c!='\n' )
-    ++i; // look for the end of this gcode command
-  cmd[i]= 0;
-  if(enquecommand(cmd)) // buffer was not full (else we will retry later)
-  {
-    if(c)
-      queued_commands_P+= i+1; // move to next command
+  while((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command
+  cmd[i] = '\0';
+  if (enquecommand(cmd)) {        // buffer was not full (else we will retry later)
+    if (c)
+      queued_commands_P += i + 1; // move to next command
     else
-      queued_commands_P= NULL; // will have no more commands in the sequence
+      queued_commands_P = NULL;   // will have no more commands in the sequence
   }
   return true;
 }
@@ -449,10 +448,9 @@ static bool drain_queued_commands_P()
 //Record one or many commands to run from program memory.
 //Aborts the current queue, if any.
 //Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards
-void enquecommands_P(const char* pgcode)
-{
-    queued_commands_P= pgcode;
-    drain_queued_commands_P(); // first command exectuted asap (when possible)
+void enquecommands_P(const char* pgcode) {
+    queued_commands_P = pgcode;
+    drain_queued_commands_P(); // first command executed asap (when possible)
 }
 
 //adds a single command to the main command buffer, from RAM
@@ -478,42 +476,42 @@ bool enquecommand(const char *cmd)
 
 void setup_killpin()
 {
-  #if defined(KILL_PIN) && KILL_PIN > -1
+  #if HAS_KILL
     SET_INPUT(KILL_PIN);
-    WRITE(KILL_PIN,HIGH);
+    WRITE(KILL_PIN, HIGH);
   #endif
 }
 
 void setup_filrunoutpin()
 {
-#if defined(FILRUNOUT_PIN) && FILRUNOUT_PIN > -1
-   pinMode(FILRUNOUT_PIN,INPUT);
-   #if defined(ENDSTOPPULLUP_FIL_RUNOUT)
-      WRITE(FILLRUNOUT_PIN,HIGH);
-   #endif
-#endif
+  #if HAS_FILRUNOUT
+    pinMode(FILRUNOUT_PIN, INPUT);
+    #ifdef ENDSTOPPULLUP_FIL_RUNOUT
+      WRITE(FILLRUNOUT_PIN, HIGH);
+    #endif
+  #endif
 }
 
 // Set home pin
 void setup_homepin(void)
 {
-#if defined(HOME_PIN) && HOME_PIN > -1
-   SET_INPUT(HOME_PIN);
-   WRITE(HOME_PIN,HIGH);
-#endif
+  #if HAS_HOME
+    SET_INPUT(HOME_PIN);
+    WRITE(HOME_PIN, HIGH);
+  #endif
 }
 
 
 void setup_photpin()
 {
-  #if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1
+  #if HAS_PHOTOGRAPH
     OUT_WRITE(PHOTOGRAPH_PIN, LOW);
   #endif
 }
 
 void setup_powerhold()
 {
-  #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
+  #if HAS_SUICIDE
     OUT_WRITE(SUICIDE_PIN, HIGH);
   #endif
   #if HAS_POWER_SWITCH
@@ -527,37 +525,31 @@ void setup_powerhold()
 
 void suicide()
 {
-  #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
+  #if HAS_SUICIDE
     OUT_WRITE(SUICIDE_PIN, LOW);
   #endif
 }
 
 void servo_init()
 {
-  #if (NUM_SERVOS >= 1) && defined(SERVO0_PIN) && (SERVO0_PIN > -1)
+  #if NUM_SERVOS >= 1 && HAS_SERVO_0
     servos[0].attach(SERVO0_PIN);
   #endif
-  #if (NUM_SERVOS >= 2) && defined(SERVO1_PIN) && (SERVO1_PIN > -1)
+  #if NUM_SERVOS >= 2 && HAS_SERVO_1
     servos[1].attach(SERVO1_PIN);
   #endif
-  #if (NUM_SERVOS >= 3) && defined(SERVO2_PIN) && (SERVO2_PIN > -1)
+  #if NUM_SERVOS >= 3 && HAS_SERVO_2
     servos[2].attach(SERVO2_PIN);
   #endif
-  #if (NUM_SERVOS >= 4) && defined(SERVO3_PIN) && (SERVO3_PIN > -1)
+  #if NUM_SERVOS >= 4 && HAS_SERVO_3
     servos[3].attach(SERVO3_PIN);
   #endif
-  #if (NUM_SERVOS >= 5)
-    #error "TODO: enter initalisation code for more servos"
-  #endif
 
   // Set position of Servo Endstops that are defined
   #ifdef SERVO_ENDSTOPS
-  for(int8_t i = 0; i < 3; i++)
-  {
-    if(servo_endstops[i] > -1) {
+  for (int i = 0; i < 3; i++)
+    if (servo_endstops[i] >= 0)
       servos[servo_endstops[i]].write(servo_endstop_angles[i * 2 + 1]);
-    }
-  }
   #endif
 
   #if SERVO_LEVELING
@@ -624,7 +616,7 @@ void setup()
   lcd_init();
   _delay_ms(1000);  // wait 1sec to display the splash screen
 
-  #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
+  #if HAS_CONTROLLERFAN
     SET_OUTPUT(CONTROLLERFAN_PIN); //Set pin used for driver cooling fan
   #endif
 
@@ -648,47 +640,37 @@ void setup()
 }
 
 
-void loop()
-{
-  if(buflen < (BUFSIZE-1))
-    get_command();
+void loop() {
+  if (buflen < BUFSIZE - 1) get_command();
+
   #ifdef SDSUPPORT
-  card.checkautostart(false);
+    card.checkautostart(false);
   #endif
-  if(buflen)
-  {
+
+  if (buflen) {
     #ifdef SDSUPPORT
-      if(card.saving)
-      {
-        if(strstr_P(cmdbuffer[bufindr], PSTR("M29")) == NULL)
-        {
+      if (card.saving) {
+        if (strstr_P(cmdbuffer[bufindr], PSTR("M29")) == NULL) {
           card.write_command(cmdbuffer[bufindr]);
-          if(card.logging)
-          {
+          if (card.logging)
             process_commands();
-          }
           else
-          {
             SERIAL_PROTOCOLLNPGM(MSG_OK);
-          }
         }
-        else
-        {
+        else {
           card.closefile();
           SERIAL_PROTOCOLLNPGM(MSG_FILE_SAVED);
         }
       }
       else
-      {
         process_commands();
-      }
     #else
       process_commands();
-    #endif //SDSUPPORT
-    buflen = (buflen-1);
-    bufindr = (bufindr + 1)%BUFSIZE;
+    #endif // SDSUPPORT
+    buflen--;
+    bufindr = (bufindr + 1) % BUFSIZE;
   }
-  //check heater every n milliseconds
+  // Check heater every n milliseconds
   manage_heater();
   manage_inactivity();
   checkHitEndstops();
@@ -697,7 +679,7 @@ void loop()
 
 void get_command()
 {
-  if(drain_queued_commands_P()) // priority is given to non-serial commands
+  if (drain_queued_commands_P()) // priority is given to non-serial commands
     return;
   
   while( MYSERIAL.available() > 0  && buflen < BUFSIZE) {
@@ -916,7 +898,7 @@ XYZ_CONSTS_FROM_CONFIG(float, base_min_pos,    MIN_POS);
 XYZ_CONSTS_FROM_CONFIG(float, base_max_pos,    MAX_POS);
 XYZ_CONSTS_FROM_CONFIG(float, base_home_pos,   HOME_POS);
 XYZ_CONSTS_FROM_CONFIG(float, max_length,      MAX_LENGTH);
-XYZ_CONSTS_FROM_CONFIG(float, home_retract_mm, HOME_RETRACT_MM);
+XYZ_CONSTS_FROM_CONFIG(float, home_bump_mm, HOME_BUMP_MM);
 XYZ_CONSTS_FROM_CONFIG(signed char, home_dir,  HOME_DIR);
 
 #ifdef DUAL_X_CARRIAGE
@@ -1019,6 +1001,8 @@ static void axis_is_at_home(int axis) {
   #endif
 }
 
+inline void refresh_cmd_timeout() { previous_millis_cmd = millis(); }
+
 /**
  * Some planner shorthand inline functions
  */
@@ -1043,6 +1027,18 @@ inline void sync_plan_position() {
 
 #ifdef ENABLE_AUTO_BED_LEVELING
 
+  #ifdef DELTA
+    /**
+     * Calculate delta, start a line, and set current_position to destination
+     */
+    void prepare_move_raw() {
+      refresh_cmd_timeout();
+      calculate_delta(destination);
+      plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
+      for (int i = 0; i < NUM_AXIS; i++) current_position[i] = destination[i];
+    }
+  #endif
+
   #ifdef AUTO_BED_LEVELING_GRID
 
     #ifndef DELTA
@@ -1132,7 +1128,7 @@ inline void sync_plan_position() {
       plan_set_position(current_position[X_AXIS], current_position[Y_AXIS], zPosition, current_position[E_AXIS]);
 
       // move up the retract distance
-      zPosition += home_retract_mm(Z_AXIS);
+      zPosition += home_bump_mm(Z_AXIS);
       line_to_z(zPosition);
       st_synchronize();
       endstops_hit_on_purpose(); // clear endstop hit flags
@@ -1145,7 +1141,7 @@ inline void sync_plan_position() {
         SERIAL_ECHOLN("Warning: The Homing Bump Feedrate Divisor cannot be less than 1");
       }
 
-      zPosition -= home_retract_mm(Z_AXIS) * 2;
+      zPosition -= home_bump_mm(Z_AXIS) * 2;
       line_to_z(zPosition);
       st_synchronize();
       endstops_hit_on_purpose(); // clear endstop hit flags
@@ -1157,6 +1153,9 @@ inline void sync_plan_position() {
     #endif // !DELTA
   }
 
+  /**
+   * 
+   */
   static void do_blocking_move_to(float x, float y, float z) {
     float oldFeedRate = feedrate;
 
@@ -1194,7 +1193,7 @@ inline void sync_plan_position() {
     saved_feedrate = feedrate;
     saved_feedmultiply = feedmultiply;
     feedmultiply = 100;
-    previous_millis_cmd = millis();
+    refresh_cmd_timeout();
     enable_endstops(true);
   }
 
@@ -1204,10 +1203,10 @@ inline void sync_plan_position() {
     #endif
     feedrate = saved_feedrate;
     feedmultiply = saved_feedmultiply;
-    previous_millis_cmd = millis();
+    refresh_cmd_timeout();
   }
 
-  static void engage_z_probe() {
+  static void deploy_z_probe() {
 
     #ifdef SERVO_ENDSTOPS
 
@@ -1259,7 +1258,7 @@ inline void sync_plan_position() {
 
   }
 
-  static void retract_z_probe() {
+  static void stow_z_probe() {
 
     #ifdef SERVO_ENDSTOPS
 
@@ -1291,19 +1290,19 @@ inline void sync_plan_position() {
       prepare_move_raw();
 
       // Move to the start position to initiate retraction
-      destination[X_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_X;
-      destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Y;
-      destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_RETRACT_Z;
+      destination[X_AXIS] = Z_PROBE_ALLEN_KEY_STOW_X;
+      destination[Y_AXIS] = Z_PROBE_ALLEN_KEY_STOW_Y;
+      destination[Z_AXIS] = Z_PROBE_ALLEN_KEY_STOW_Z;
       prepare_move_raw();
 
       // Move the nozzle down to push the probe into retracted position
       feedrate = homing_feedrate[Z_AXIS]/10;
-      destination[Z_AXIS] = current_position[Z_AXIS] - Z_PROBE_ALLEN_KEY_RETRACT_DEPTH;
+      destination[Z_AXIS] = current_position[Z_AXIS] - Z_PROBE_ALLEN_KEY_STOW_DEPTH;
       prepare_move_raw();
       
       // Move up for safety
       feedrate = homing_feedrate[Z_AXIS]/2;
-      destination[Z_AXIS] = current_position[Z_AXIS] + Z_PROBE_ALLEN_KEY_RETRACT_DEPTH * 2;
+      destination[Z_AXIS] = current_position[Z_AXIS] + Z_PROBE_ALLEN_KEY_STOW_DEPTH * 2;
       prepare_move_raw();
       
       // Home XY for safety
@@ -1342,7 +1341,7 @@ inline void sync_plan_position() {
     do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
 
     #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-      if (retract_action & ProbeEngage) engage_z_probe();
+      if (retract_action & ProbeEngage) deploy_z_probe();
     #endif
 
     run_z_probe();
@@ -1356,7 +1355,7 @@ inline void sync_plan_position() {
     #endif
 
     #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-      if (retract_action & ProbeRetract) retract_z_probe();
+      if (retract_action & ProbeRetract) stow_z_probe();
     #endif
 
     if (verbose_level > 2) {
@@ -1460,10 +1459,10 @@ static void homeaxis(int axis) {
     sync_plan_position();
 
     // Engage Servo endstop if enabled
-    #ifdef SERVO_ENDSTOPS && !defined(Z_PROBE_SLED)
+    #if defined(SERVO_ENDSTOPS) && !defined(Z_PROBE_SLED)
 
       #if SERVO_LEVELING
-        if (axis == Z_AXIS) engage_z_probe(); else
+        if (axis == Z_AXIS) deploy_z_probe(); else
       #endif
         {
           if (servo_endstops[axis] > -1)
@@ -1486,8 +1485,8 @@ static void homeaxis(int axis) {
     current_position[axis] = 0;
     sync_plan_position();
 
-    // Move away from the endstop by the axis HOME_RETRACT_MM
-    destination[axis] = -home_retract_mm(axis) * axis_home_dir;
+    // Move away from the endstop by the axis HOME_BUMP_MM
+    destination[axis] = -home_bump_mm(axis) * axis_home_dir;
     line_to_destination();
     st_synchronize();
 
@@ -1500,7 +1499,7 @@ static void homeaxis(int axis) {
     }
 
     // Move slowly towards the endstop until triggered
-    destination[axis] = 2 * home_retract_mm(axis) * axis_home_dir;
+    destination[axis] = 2 * home_bump_mm(axis) * axis_home_dir;
     line_to_destination();
     st_synchronize();
 
@@ -1554,14 +1553,12 @@ static void homeaxis(int axis) {
     #endif
 
     #if SERVO_LEVELING && !defined(Z_PROBE_SLED)
-      if (axis == Z_AXIS) retract_z_probe();
+      if (axis == Z_AXIS) stow_z_probe();
     #endif
 
   }
 }
 
-void refresh_cmd_timeout(void) { previous_millis_cmd = millis(); }
-
 #ifdef FWRETRACT
 
   void retract(bool retracting, bool swapretract = false) {
@@ -1701,9 +1698,9 @@ inline void gcode_G4() {
   if (code_seen('S')) codenum = code_value_long() * 1000; // seconds to wait
 
   st_synchronize();
-  previous_millis_cmd = millis();
+  refresh_cmd_timeout();
   codenum += previous_millis_cmd;  // keep track of when we started waiting
-  while(millis() < codenum) {
+  while (millis() < codenum) {
     manage_heater();
     manage_inactivity();
     lcd_update();
@@ -1753,14 +1750,17 @@ inline void gcode_G4() {
  *  Zn  Home Z, setting Z to n + home_offset[Z_AXIS]
  */
 inline void gcode_G28() {
+
+  // For auto bed leveling, clear the level matrix
   #ifdef ENABLE_AUTO_BED_LEVELING
-    plan_bed_level_matrix.set_to_identity();  //Reset the plane ("erase" all leveling data)
+    plan_bed_level_matrix.set_to_identity();
     #ifdef DELTA
       reset_bed_level();
     #endif
   #endif
 
-  #if defined(MESH_BED_LEVELING)
+  // For manual bed leveling deactivate the matrix temporarily
+  #ifdef MESH_BED_LEVELING
     uint8_t mbl_was_active = mbl.active;
     mbl.active = 0;
   #endif
@@ -1768,7 +1768,7 @@ inline void gcode_G28() {
   saved_feedrate = feedrate;
   saved_feedmultiply = feedmultiply;
   feedmultiply = 100;
-  previous_millis_cmd = millis();
+  refresh_cmd_timeout();
 
   enable_endstops(true);
 
@@ -1780,10 +1780,11 @@ inline void gcode_G28() {
     // A delta can only safely home all axis at the same time
     // all axis have to home at the same time
 
-    // Move all carriages up together until the first endstop is hit.
+    // Pretend the current position is 0,0,0
     for (int i = X_AXIS; i <= Z_AXIS; i++) current_position[i] = 0;
     sync_plan_position();
 
+    // Move all carriages up together until the first endstop is hit.
     for (int i = X_AXIS; i <= Z_AXIS; i++) destination[i] = 3 * Z_MAX_LENGTH;
     feedrate = 1.732 * homing_feedrate[X_AXIS];
     line_to_destination();
@@ -1994,14 +1995,12 @@ inline void gcode_G28() {
     enable_endstops(false);
   #endif
 
-  #if defined(MESH_BED_LEVELING)
+  // For manual leveling move back to 0,0
+  #ifdef MESH_BED_LEVELING
     if (mbl_was_active) {
       current_position[X_AXIS] = mbl.get_x(0);
       current_position[Y_AXIS] = mbl.get_y(0);
-      destination[X_AXIS] = current_position[X_AXIS];
-      destination[Y_AXIS] = current_position[Y_AXIS];
-      destination[Z_AXIS] = current_position[Z_AXIS];
-      destination[E_AXIS] = current_position[E_AXIS];
+      for (int i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i];
       feedrate = homing_feedrate[X_AXIS];
       line_to_destination();
       st_synchronize();
@@ -2013,25 +2012,14 @@ inline void gcode_G28() {
 
   feedrate = saved_feedrate;
   feedmultiply = saved_feedmultiply;
-  previous_millis_cmd = millis();
+  refresh_cmd_timeout();
   endstops_hit_on_purpose(); // clear endstop hit flags
 }
 
-#if defined(MESH_BED_LEVELING) || defined(ENABLE_AUTO_BED_LEVELING)
-
-  // Check for known positions in X and Y
-  inline bool can_run_bed_leveling() {
-  	if (axis_known_position[X_AXIS] && axis_known_position[Y_AXIS]) return true;
-    LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
-    SERIAL_ECHO_START;
-    SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
-    return false;
-  }
-
-#endif // MESH_BED_LEVELING || ENABLE_AUTO_BED_LEVELING
-
 #ifdef MESH_BED_LEVELING
 
+  enum MeshLevelingState { MeshReport, MeshStart, MeshNext };
+
   /**
    * G29: Mesh-based Z-Probe, probes a grid and produces a
    *      mesh to compensate for variable bed height
@@ -2045,81 +2033,82 @@ inline void gcode_G28() {
    */
   inline void gcode_G29() {
 
-    // Prevent leveling without first homing in X and Y
-    if (!can_run_bed_leveling()) return;
-
     static int probe_point = -1;
-    int state = 0;
-    if (code_seen('S') || code_seen('s')) {
-      state = code_value_long();
-      if (state < 0 || state > 2) {
-        SERIAL_PROTOCOLPGM("S out of range (0-2).\n");
-        return;
-      }
+    MeshLevelingState state = code_seen('S') || code_seen('s') ? (MeshLevelingState)code_value_long() : MeshReport;
+    if (state < 0 || state > 2) {
+      SERIAL_PROTOCOLLNPGM("S out of range (0-2).");
+      return;
     }
 
-    if (state == 0) { // Dump mesh_bed_leveling
-      if (mbl.active) {
-        SERIAL_PROTOCOLPGM("Num X,Y: ");
-        SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
-        SERIAL_PROTOCOLPGM(",");
-        SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
-        SERIAL_PROTOCOLPGM("\nZ search height: ");
-        SERIAL_PROTOCOL(MESH_HOME_SEARCH_Z);
-        SERIAL_PROTOCOLPGM("\nMeasured points:\n");              
-        for (int y=0; y<MESH_NUM_Y_POINTS; y++) {
-          for (int x=0; x<MESH_NUM_X_POINTS; x++) {
-            SERIAL_PROTOCOLPGM("  ");              
-            SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
+    switch(state) {
+      case MeshReport:
+        if (mbl.active) {
+          SERIAL_PROTOCOLPGM("Num X,Y: ");
+          SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
+          SERIAL_PROTOCOLPGM(",");
+          SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
+          SERIAL_PROTOCOLPGM("\nZ search height: ");
+          SERIAL_PROTOCOL(MESH_HOME_SEARCH_Z);
+          SERIAL_PROTOCOLLNPGM("\nMeasured points:");
+          for (int y = 0; y < MESH_NUM_Y_POINTS; y++) {
+            for (int x = 0; x < MESH_NUM_X_POINTS; x++) {
+              SERIAL_PROTOCOLPGM("  ");
+              SERIAL_PROTOCOL_F(mbl.z_values[y][x], 5);
+            }
+            SERIAL_EOL;
           }
-          SERIAL_EOL;
         }
-      } else {
-        SERIAL_PROTOCOLPGM("Mesh bed leveling not active.\n");
-      }
+        else
+          SERIAL_PROTOCOLLNPGM("Mesh bed leveling not active.");
+        break;
 
-    } else if (state == 1) { // Begin probing mesh points
+      case MeshStart:
+        mbl.reset();
+        probe_point = 0;
+        enquecommands_P(PSTR("G28\nG29 S2"));
+        break;
 
-      mbl.reset();
-      probe_point = 0;
-      enquecommands_P(PSTR("G28"));
-      enquecommands_P(PSTR("G29 S2"));
+      case MeshNext:
+        if (probe_point < 0) {
+          SERIAL_PROTOCOLLNPGM("Start mesh probing with \"G29 S1\" first.");
+          return;
+        }
+        int ix, iy;
+        if (probe_point == 0) {
+          // Set Z to a positive value before recording the first Z.
+          current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
+          sync_plan_position();
+        }
+        else {
+          // For others, save the Z of the previous point, then raise Z again.
+          ix = (probe_point - 1) % MESH_NUM_X_POINTS;
+          iy = (probe_point - 1) / MESH_NUM_X_POINTS;
+          if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // zig-zag
+          mbl.set_z(ix, iy, current_position[Z_AXIS]);
+          current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
+          plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
+          st_synchronize();
+        }
+        // Is there another point to sample? Move there.
+        if (probe_point < MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS) {
+          ix = probe_point % MESH_NUM_X_POINTS;
+          iy = probe_point / MESH_NUM_X_POINTS;
+          if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // zig-zag
+          current_position[X_AXIS] = mbl.get_x(ix);
+          current_position[Y_AXIS] = mbl.get_y(iy);
+          plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
+          st_synchronize();
+          probe_point++;
+        }
+        else {
+          // After recording the last point, activate the mbl and home
+          SERIAL_PROTOCOLLNPGM("Mesh probing done.");
+          probe_point = -1;
+          mbl.active = 1;
+          enquecommands_P(PSTR("G28"));
+        }
 
-    } else if (state == 2) { // Goto next point
-
-      if (probe_point < 0) {
-        SERIAL_PROTOCOLPGM("Start mesh probing with \"G29 S1\" first.\n");
-        return;
-      }
-      int ix, iy;
-      if (probe_point == 0) {
-        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
-        sync_plan_position();
-      } else {
-        ix = (probe_point-1) % MESH_NUM_X_POINTS;
-        iy = (probe_point-1) / MESH_NUM_X_POINTS;
-        if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // zig-zag
-        mbl.set_z(ix, iy, current_position[Z_AXIS]);
-        current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
-        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
-        st_synchronize();
-      }
-      if (probe_point == MESH_NUM_X_POINTS * MESH_NUM_Y_POINTS) {
-        SERIAL_PROTOCOLPGM("Mesh probing done.\n");
-        probe_point = -1;
-        mbl.active = 1;
-        enquecommands_P(PSTR("G28"));
-        return;
-      }
-      ix = probe_point % MESH_NUM_X_POINTS;
-      iy = probe_point / MESH_NUM_X_POINTS;
-      if (iy & 1) ix = (MESH_NUM_X_POINTS - 1) - ix; // zig-zag
-      current_position[X_AXIS] = mbl.get_x(ix);
-      current_position[Y_AXIS] = mbl.get_y(iy);
-      plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], homing_feedrate[X_AXIS]/60, active_extruder);
-      st_synchronize();
-      probe_point++;
-    }
+    } // switch(state)
   }
 
 #elif defined(ENABLE_AUTO_BED_LEVELING)
@@ -2164,21 +2153,22 @@ inline void gcode_G28() {
    */
   inline void gcode_G29() {
 
-    // Prevent leveling without first homing in X and Y
-    if (!can_run_bed_leveling()) return;
-
-    int verbose_level = 1;
-
-    if (code_seen('V') || code_seen('v')) {
-      verbose_level = code_value_long();
-      if (verbose_level < 0 || verbose_level > 4) {
-        SERIAL_PROTOCOLPGM("?(V)erbose Level is implausible (0-4).\n");
-        return;
-      }
+    // Don't allow auto-leveling without homing first
+    if (!axis_known_position[X_AXIS] || !axis_known_position[Y_AXIS]) {
+      LCD_MESSAGEPGM(MSG_POSITION_UNKNOWN);
+      SERIAL_ECHO_START;
+      SERIAL_ECHOLNPGM(MSG_POSITION_UNKNOWN);
+      return;
     }
 
-    bool dryrun = code_seen('D') || code_seen('d');
-    bool engage_probe_for_each_reading = code_seen('E') || code_seen('e');
+    int verbose_level = code_seen('V') || code_seen('v') ? code_value_long() : 1;
+    if (verbose_level < 0 || verbose_level > 4) {
+      SERIAL_ECHOLNPGM("?(V)erbose Level is implausible (0-4).");
+      return;
+    }
+
+    bool dryrun = code_seen('D') || code_seen('d'),
+         engage_probe_for_each_reading = code_seen('E') || code_seen('e');
 
     #ifdef AUTO_BED_LEVELING_GRID
 
@@ -2188,7 +2178,7 @@ inline void gcode_G28() {
 
       if (verbose_level > 0) {
         SERIAL_PROTOCOLPGM("G29 Auto Bed Leveling\n");
-        if (dryrun) SERIAL_ECHOLN("Running in DRY-RUN mode");
+        if (dryrun) SERIAL_ECHOLNPGM("Running in DRY-RUN mode");
       }
 
       int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS;
@@ -2241,7 +2231,7 @@ inline void gcode_G28() {
     #ifdef Z_PROBE_SLED
       dock_sled(false); // engage (un-dock) the probe
     #elif defined(Z_PROBE_ALLEN_KEY) //|| defined(SERVO_LEVELING)
-      engage_z_probe();
+      deploy_z_probe();
     #endif
 
     st_synchronize();
@@ -2464,7 +2454,7 @@ inline void gcode_G28() {
     #ifdef Z_PROBE_SLED
       dock_sled(true, -SLED_DOCKING_OFFSET); // dock the probe, correcting for over-travel
     #elif defined(Z_PROBE_ALLEN_KEY) //|| defined(SERVO_LEVELING)
-      retract_z_probe();
+      stow_z_probe();
     #endif
 
     #ifdef Z_PROBE_END_SCRIPT
@@ -2476,7 +2466,7 @@ inline void gcode_G28() {
   #ifndef Z_PROBE_SLED
 
     inline void gcode_G30() {
-      engage_z_probe(); // Engage Z Servo endstop if available
+      deploy_z_probe(); // Engage Z Servo endstop if available
       st_synchronize();
       // TODO: make sure the bed_level_rotation_matrix is identity or the planner will get set incorectly
       setup_for_endstop_move();
@@ -2494,7 +2484,7 @@ inline void gcode_G28() {
       SERIAL_EOL;
 
       clean_up_after_endstop_move();
-      retract_z_probe(); // Retract Z Servo endstop if available
+      stow_z_probe(); // Retract Z Servo endstop if available
     }
 
   #endif //!Z_PROBE_SLED
@@ -2554,7 +2544,7 @@ inline void gcode_G92() {
 
     lcd_ignore_click();
     st_synchronize();
-    previous_millis_cmd = millis();
+    refresh_cmd_timeout();
     if (codenum > 0) {
       codenum += previous_millis_cmd;  // keep track of when we started waiting
       while(millis() < codenum && !lcd_clicked()) {
@@ -2781,7 +2771,7 @@ inline void gcode_M42() {
       }
     }
 
-    #if defined(FAN_PIN) && FAN_PIN > -1
+    #if HAS_FAN
       if (pin_number == FAN_PIN) fanSpeed = pin_status;
     #endif
 
@@ -2915,7 +2905,7 @@ inline void gcode_M42() {
     // Then retrace the right amount and use that in subsequent probes
     //
 
-    engage_z_probe();
+    deploy_z_probe();
 
     setup_for_endstop_move();
     run_z_probe();
@@ -2930,7 +2920,7 @@ inline void gcode_M42() {
     st_synchronize();
     current_position[Z_AXIS] = Z_current = st_get_position_mm(Z_AXIS);
 
-    if (engage_probe_for_each_reading) retract_z_probe();
+    if (engage_probe_for_each_reading) stow_z_probe();
 
     for (uint16_t n=0; n < n_samples; n++) {
 
@@ -2973,7 +2963,7 @@ inline void gcode_M42() {
       } // n_legs
 
       if (engage_probe_for_each_reading)  {
-        engage_z_probe(); 
+        deploy_z_probe(); 
         delay(1000);
       }
 
@@ -3020,13 +3010,13 @@ inline void gcode_M42() {
       st_synchronize();
 
       if (engage_probe_for_each_reading) {
-        retract_z_probe();
+        stow_z_probe();
         delay(1000);
       }
     }
 
     if (!engage_probe_for_each_reading) {
-      retract_z_probe();
+      stow_z_probe();
       delay(1000);
     }
 
@@ -3067,17 +3057,17 @@ inline void gcode_M104() {
 inline void gcode_M105() {
   if (setTargetedHotend(105)) return;
 
-  #if defined(TEMP_0_PIN) && TEMP_0_PIN > -1
+  #if HAS_TEMP_0
     SERIAL_PROTOCOLPGM("ok T:");
     SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1);
     SERIAL_PROTOCOLPGM(" /");
     SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1);
-    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+    #if HAS_TEMP_BED
       SERIAL_PROTOCOLPGM(" B:");
       SERIAL_PROTOCOL_F(degBed(),1);
       SERIAL_PROTOCOLPGM(" /");
       SERIAL_PROTOCOL_F(degTargetBed(),1);
-    #endif //TEMP_BED_PIN
+    #endif // HAS_TEMP_BED
     for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
       SERIAL_PROTOCOLPGM(" T");
       SERIAL_PROTOCOL(cur_extruder);
@@ -3086,7 +3076,7 @@ inline void gcode_M105() {
       SERIAL_PROTOCOLPGM(" /");
       SERIAL_PROTOCOL_F(degTargetHotend(cur_extruder),1);
     }
-  #else
+  #else // !HAS_TEMP_0
     SERIAL_ERROR_START;
     SERIAL_ERRORLNPGM(MSG_ERR_NO_THERMISTORS);
   #endif
@@ -3108,7 +3098,7 @@ inline void gcode_M105() {
   #endif
 
   #ifdef SHOW_TEMP_ADC_VALUES
-    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+    #if HAS_TEMP_BED
       SERIAL_PROTOCOLPGM("    ADC B:");
       SERIAL_PROTOCOL_F(degBed(),1);
       SERIAL_PROTOCOLPGM("C->");
@@ -3127,7 +3117,7 @@ inline void gcode_M105() {
   SERIAL_PROTOCOLLN("");
 }
 
-#if defined(FAN_PIN) && FAN_PIN > -1
+#if HAS_FAN
 
   /**
    * M106: Set Fan Speed
@@ -3220,10 +3210,11 @@ inline void gcode_M109() {
     }
 
   LCD_MESSAGEPGM(MSG_HEATING_COMPLETE);
-  starttime = previous_millis_cmd = millis();
+  refresh_cmd_timeout();
+  starttime = previous_millis_cmd;
 }
 
-#if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+#if HAS_TEMP_BED
 
   /**
    * M190: Sxxx Wait for bed current temp to reach target temp. Waits only when heating
@@ -3258,10 +3249,10 @@ inline void gcode_M109() {
       lcd_update();
     }
     LCD_MESSAGEPGM(MSG_BED_DONE);
-    previous_millis_cmd = millis();
+    refresh_cmd_timeout();
   }
 
-#endif // TEMP_BED_PIN > -1
+#endif // HAS_TEMP_BED
 
 /**
  * M112: Emergency Stop
@@ -3272,7 +3263,7 @@ inline void gcode_M112() {
 
 #ifdef BARICUDA
 
-  #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
+  #if HAS_HEATER_1
     /**
      * M126: Heater 1 valve open
      */
@@ -3283,7 +3274,7 @@ inline void gcode_M112() {
     inline void gcode_M127() { ValvePressure = 0; }
   #endif
 
-  #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
+  #if HAS_HEATER_2
     /**
      * M128: Heater 2 valve open
      */
@@ -3314,7 +3305,7 @@ inline void gcode_M140() {
     // If you have a switch on suicide pin, this is useful
     // if you want to start another print with suicide feature after
     // a print without suicide...
-    #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
+    #if HAS_SUICIDE
       OUT_WRITE(SUICIDE_PIN, HIGH);
     #endif
 
@@ -3342,7 +3333,7 @@ inline void gcode_M81() {
   finishAndDisableSteppers();
   fanSpeed = 0;
   delay(1000); // Wait 1 second before switching off
-  #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1
+  #if HAS_SUICIDE
     st_synchronize();
     suicide();
   #elif HAS_POWER_SWITCH
@@ -3498,31 +3489,31 @@ inline void gcode_M117() {
  */
 inline void gcode_M119() {
   SERIAL_PROTOCOLLN(MSG_M119_REPORT);
-  #if defined(X_MIN_PIN) && X_MIN_PIN > -1
+  #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));
   #endif
-  #if defined(X_MAX_PIN) && X_MAX_PIN > -1
+  #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));
   #endif
-  #if defined(Y_MIN_PIN) && Y_MIN_PIN > -1
+  #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));
   #endif
-  #if defined(Y_MAX_PIN) && Y_MAX_PIN > -1
+  #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));
   #endif
-  #if defined(Z_MIN_PIN) && Z_MIN_PIN > -1
+  #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));
   #endif
-  #if defined(Z_MAX_PIN) && Z_MAX_PIN > -1
+  #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));
   #endif
-  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN > -1
+  #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));
   #endif
@@ -4013,7 +4004,7 @@ inline void gcode_M226() {
 
 #endif // PIDTEMPBED
 
-#if defined(CHDK) || (defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1)
+#if defined(CHDK) || HAS_PHOTOGRAPH
 
   /**
    * M240: Trigger a camera by emulating a Canon RC-1
@@ -4026,7 +4017,7 @@ inline void gcode_M226() {
        chdkHigh = millis();
        chdkActive = true;
      
-    #elif defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1
+    #elif HAS_PHOTOGRAPH
 
       const uint8_t NUM_PULSES = 16;
       const float PULSE_LENGTH = 0.01524;
@@ -4044,7 +4035,7 @@ inline void gcode_M226() {
         _delay_ms(PULSE_LENGTH);
       }
 
-    #endif // !CHDK && PHOTOGRAPH_PIN > -1
+    #endif // !CHDK && HAS_PHOTOGRAPH
   }
 
 #endif // CHDK || PHOTOGRAPH_PIN
@@ -4165,17 +4156,17 @@ inline void gcode_M303() {
       case 0:
         OUT_WRITE(SOL0_PIN, HIGH);
         break;
-        #if defined(SOL1_PIN) && SOL1_PIN > -1
+        #if HAS_SOLENOID_1
           case 1:
             OUT_WRITE(SOL1_PIN, HIGH);
             break;
         #endif
-        #if defined(SOL2_PIN) && SOL2_PIN > -1
+        #if HAS_SOLENOID_2
           case 2:
             OUT_WRITE(SOL2_PIN, HIGH);
             break;
         #endif
-        #if defined(SOL3_PIN) && SOL3_PIN > -1
+        #if HAS_SOLENOID_3
           case 3:
             OUT_WRITE(SOL3_PIN, HIGH);
             break;
@@ -4218,11 +4209,11 @@ inline void gcode_M400() { st_synchronize(); }
   /**
    * M401: Engage Z Servo endstop if available
    */
-  inline void gcode_M401() { engage_z_probe(); }
+  inline void gcode_M401() { deploy_z_probe(); }
   /**
    * M402: Retract Z Servo endstop if enabled
    */
-  inline void gcode_M402() { retract_z_probe(); }
+  inline void gcode_M402() { stow_z_probe(); }
 
 #endif
 
@@ -4232,7 +4223,7 @@ inline void gcode_M400() { st_synchronize(); }
    * M404: Display or set the nominal filament width (3mm, 1.75mm ) W<3.0>
    */
   inline void gcode_M404() {
-    #if FILWIDTH_PIN > -1
+    #if HAS_FILWIDTH
       if (code_seen('W')) {
         filament_width_nominal = code_value();
       }
@@ -4555,22 +4546,21 @@ inline void gcode_M907() {
 
 #endif // HAS_DIGIPOTSS
 
-// M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
-inline void gcode_M350() {
-  #if defined(X_MS1_PIN) && X_MS1_PIN > -1
+#if HAS_MICROSTEPS
+
+  // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
+  inline void gcode_M350() {
     if(code_seen('S')) for(int i=0;i<=4;i++) microstep_mode(i,code_value());
     for(int i=0;i<NUM_AXIS;i++) if(code_seen(axis_codes[i])) microstep_mode(i,(uint8_t)code_value());
     if(code_seen('B')) microstep_mode(4,code_value());
     microstep_readings();
-  #endif
-}
+  }
 
-/**
- * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z E B
- *       S# determines MS1 or MS2, X# sets the pin high/low.
- */
-inline void gcode_M351() {
-  #if defined(X_MS1_PIN) && X_MS1_PIN > -1
+  /**
+   * M351: Toggle MS1 MS2 pins directly with axis codes X Y Z E B
+   *       S# determines MS1 or MS2, X# sets the pin high/low.
+   */
+  inline void gcode_M351() {
     if (code_seen('S')) switch(code_value_long()) {
       case 1:
         for(int i=0;i<NUM_AXIS;i++) if (code_seen(axis_codes[i])) microstep_ms(i, code_value(), -1);
@@ -4582,8 +4572,9 @@ inline void gcode_M351() {
         break;
     }
     microstep_readings();
-  #endif
-}
+  }
+
+#endif // HAS_MICROSTEPS
 
 /**
  * M999: Restart after being stopped
@@ -4695,6 +4686,7 @@ inline void gcode_T() {
 
 /**
  * Process Commands and dispatch them to handlers
+ * This is called from the main loop()
  */
 void process_commands() {
   if (code_seen('G')) {
@@ -4852,42 +4844,42 @@ void process_commands() {
         gcode_M109();
         break;
 
-      #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+      #if HAS_TEMP_BED
         case 190: // M190 - Wait for bed heater to reach target.
           gcode_M190();
           break;
-      #endif //TEMP_BED_PIN
+      #endif // HAS_TEMP_BED
 
-      #if defined(FAN_PIN) && FAN_PIN > -1
+      #if HAS_FAN
         case 106: //M106 Fan On
           gcode_M106();
           break;
         case 107: //M107 Fan Off
           gcode_M107();
           break;
-      #endif //FAN_PIN
+      #endif // HAS_FAN
 
       #ifdef BARICUDA
         // PWM for HEATER_1_PIN
-        #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1
+        #if HAS_HEATER_1
           case 126: // M126 valve open
             gcode_M126();
             break;
           case 127: // M127 valve closed
             gcode_M127();
             break;
-        #endif //HEATER_1_PIN
+        #endif // HAS_HEATER_1
 
         // PWM for HEATER_2_PIN
-        #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1
+        #if HAS_HEATER_2
           case 128: // M128 valve open
             gcode_M128();
             break;
           case 129: // M129 valve closed
             gcode_M129();
             break;
-        #endif //HEATER_2_PIN
-      #endif //BARICUDA
+        #endif // HAS_HEATER_2
+      #endif // BARICUDA
 
       #if HAS_POWER_SWITCH
 
@@ -5035,7 +5027,7 @@ void process_commands() {
           break;
       #endif // PIDTEMPBED
 
-      #if defined(CHDK) || (defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1)
+      #if defined(CHDK) || HAS_PHOTOGRAPH
         case 240: // M240  Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/
           gcode_M240();
           break;
@@ -5153,13 +5145,17 @@ void process_commands() {
           break;
       #endif // HAS_DIGIPOTSS
 
-      case 350: // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
-        gcode_M350();
-        break;
+      #if HAS_MICROSTEPS
 
-      case 351: // M351 Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low.
-        gcode_M351();
-        break;
+        case 350: // M350 Set microstepping mode. Warning: Steps per unit remains unchanged. S code sets stepping mode for all drivers.
+          gcode_M350();
+          break;
+
+        case 351: // M351 Toggle MS1 MS2 pins directly, S# determines MS1 or MS2, X# sets the pin high/low.
+          gcode_M351();
+          break;
+
+      #endif // HAS_MICROSTEPS
 
       case 999: // M999: Restart after being Stopped
         gcode_M999();
@@ -5181,8 +5177,7 @@ void process_commands() {
   ClearToSend();
 }
 
-void FlushSerialRequestResend()
-{
+void FlushSerialRequestResend() {
   //char cmdbuffer[bufindr][100]="Resend:";
   MYSERIAL.flush();
   SERIAL_PROTOCOLPGM(MSG_RESEND);
@@ -5190,13 +5185,11 @@ void FlushSerialRequestResend()
   ClearToSend();
 }
 
-void ClearToSend()
-{
-  previous_millis_cmd = millis();
+void ClearToSend() {
+  refresh_cmd_timeout();
   #ifdef SDSUPPORT
-  if(fromsd[bufindr])
-    return;
-  #endif //SDSUPPORT
+    if (fromsd[bufindr]) return;
+  #endif
   SERIAL_PROTOCOLLNPGM(MSG_OK);
 }
 
@@ -5213,29 +5206,18 @@ void get_coordinates() {
   }
 }
 
-void get_arc_coordinates()
-{
-#ifdef SF_ARC_FIX
-   bool relative_mode_backup = relative_mode;
-   relative_mode = true;
-#endif
-   get_coordinates();
-#ifdef SF_ARC_FIX
-   relative_mode=relative_mode_backup;
-#endif
+void get_arc_coordinates() {
+  #ifdef SF_ARC_FIX
+    bool relative_mode_backup = relative_mode;
+    relative_mode = true;
+  #endif
+    get_coordinates();
+  #ifdef SF_ARC_FIX
+    relative_mode = relative_mode_backup;
+  #endif
 
-   if(code_seen('I')) {
-     offset[0] = code_value();
-   }
-   else {
-     offset[0] = 0.0;
-   }
-   if(code_seen('J')) {
-     offset[1] = code_value();
-   }
-   else {
-     offset[1] = 0.0;
-   }
+  offset[0] = code_seen('I') ? code_value() : 0;
+  offset[1] = code_seen('J') ? code_value() : 0;
 }
 
 void clamp_to_software_endstops(float target[3])
@@ -5299,7 +5281,6 @@ void clamp_to_software_endstops(float target[3])
   #ifdef ENABLE_AUTO_BED_LEVELING
 
     // Adjust print surface height by linear interpolation over the bed_level array.
-    int delta_grid_spacing[2] = { 0, 0 };
     void adjust_delta(float cartesian[3]) {
       if (delta_grid_spacing[0] == 0 || delta_grid_spacing[1] == 0) return; // G29 not done!
 
@@ -5339,16 +5320,9 @@ void clamp_to_software_endstops(float target[3])
     }
   #endif // ENABLE_AUTO_BED_LEVELING
 
-  void prepare_move_raw() {
-    previous_millis_cmd = millis();
-    calculate_delta(destination);
-    plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
-    for (int i = 0; i < NUM_AXIS; i++) current_position[i] = destination[i];
-  }
-
 #endif // DELTA
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
 
   #if !defined(MIN)
     #define MIN(_v1, _v2) (((_v1) < (_v2)) ? (_v1) : (_v2))
@@ -5427,7 +5401,7 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
 
 void prepare_move() {
   clamp_to_software_endstops(destination);
-  previous_millis_cmd = millis();
+  refresh_cmd_timeout();
   
   #ifdef SCARA //for now same as delta-code
 
@@ -5544,7 +5518,7 @@ void prepare_move() {
   if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
     line_to_destination();
   } else {
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
     mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
     return;
 #else
@@ -5570,16 +5544,10 @@ void prepare_arc_move(char isclockwise) {
   for(int8_t i=0; i < NUM_AXIS; i++) {
     current_position[i] = destination[i];
   }
-  previous_millis_cmd = millis();
+  refresh_cmd_timeout();
 }
 
-#if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
-
-#if defined(FAN_PIN)
-  #if CONTROLLERFAN_PIN == FAN_PIN
-    #error "You cannot set CONTROLLERFAN_PIN equal to FAN_PIN"
-  #endif
-#endif
+#if HAS_CONTROLLERFAN
 
 unsigned long lastMotor = 0; // Last time a motor was turned on
 unsigned long lastMotorCheck = 0; // Last time the state was checked
@@ -5592,7 +5560,7 @@ void controllerFan() {
       || E0_ENABLE_READ == E_ENABLE_ON // If any of the drivers are enabled...
       #if EXTRUDERS > 1
         || E1_ENABLE_READ == E_ENABLE_ON
-        #if defined(X2_ENABLE_PIN) && X2_ENABLE_PIN > -1
+        #if HAS_X2_ENABLE
           || X2_ENABLE_READ == X_ENABLE_ON
         #endif
         #if EXTRUDERS > 2
@@ -5704,7 +5672,7 @@ void handle_status_leds(void) {
        max_temp = max(max_temp, degHotend(cur_extruder));
        max_temp = max(max_temp, degTargetHotend(cur_extruder));
     }
-    #if defined(TEMP_BED_PIN) && TEMP_BED_PIN > -1
+    #if HAS_TEMP_BED
       max_temp = max(max_temp, degTargetBed());
       max_temp = max(max_temp, degBed());
     #endif
@@ -5724,134 +5692,120 @@ void handle_status_leds(void) {
 }
 #endif
 
-void manage_inactivity(bool ignore_stepper_queue/*=false*/) //default argument set in Marlin.h
-{
-  
-#if defined(KILL_PIN) && KILL_PIN > -1
-  static int killCount = 0;   // make the inactivity button a bit less responsive
-   const int KILL_DELAY = 750;
-#endif
+void disable_all_axes() {
+  disable_x();
+  disable_y();
+  disable_z();
+  disable_e0();
+  disable_e1();
+  disable_e2();
+  disable_e3();
+}
 
-#if defined(FILRUNOUT_PIN) && FILRUNOUT_PIN > -1
-    if(card.sdprinting) {
-      if(!(READ(FILRUNOUT_PIN))^FIL_RUNOUT_INVERTING)
-      filrunout();        }
-#endif
-
-#if defined(HOME_PIN) && HOME_PIN > -1
-   static int homeDebounceCount = 0;   // poor man's debouncing count
-   const int HOME_DEBOUNCE_DELAY = 750;
-#endif
-   
+/**
+ * 
+ */
+void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
   
-  if(buflen < (BUFSIZE-1))
-    get_command();
+  #if HAS_KILL
+    static int killCount = 0;   // make the inactivity button a bit less responsive
+    const int KILL_DELAY = 750;
+  #endif
+
+  #if HAS_FILRUNOUT
+    if (card.sdprinting && !(READ(FILRUNOUT_PIN) ^ FIL_RUNOUT_INVERTING))
+      filrunout();
+  #endif
+
+  #if HAS_HOME
+    static int homeDebounceCount = 0;   // poor man's debouncing count
+    const int HOME_DEBOUNCE_DELAY = 750;
+  #endif
+
+  if (buflen < BUFSIZE - 1) get_command();
+
+  unsigned long ms = millis();
+
+  if (max_inactive_time && ms > previous_millis_cmd + max_inactive_time) kill();
+
+  if (stepper_inactive_time && ms > previous_millis_cmd + stepper_inactive_time
+      && !ignore_stepper_queue && !blocks_queued())
+    disable_all_axes();
 
-  if( (millis() - previous_millis_cmd) >  max_inactive_time )
-    if(max_inactive_time)
-      kill();
-  if(stepper_inactive_time)  {
-    if( (millis() - previous_millis_cmd) >  stepper_inactive_time )
-    {
-      if(blocks_queued() == false && ignore_stepper_queue == false) {
-        disable_x();
-        disable_y();
-        disable_z();
-        disable_e0();
-        disable_e1();
-        disable_e2();
-        disable_e3();
-      }
-    }
-  }
-  
   #ifdef CHDK //Check if pin should be set to LOW after M240 set it to HIGH
-    if (chdkActive && (millis() - chdkHigh > CHDK_DELAY))
-    {
+    if (chdkActive && ms > chdkHigh + CHDK_DELAY) {
       chdkActive = false;
       WRITE(CHDK, LOW);
     }
   #endif
-  
-  #if defined(KILL_PIN) && KILL_PIN > -1
+
+  #if HAS_KILL
     
     // Check if the kill button was pressed and wait just in case it was an accidental
     // key kill key press
     // -------------------------------------------------------------------------------
-    if( 0 == READ(KILL_PIN) )
-    {
+    if (!READ(KILL_PIN))
        killCount++;
-    }
     else if (killCount > 0)
-    {
        killCount--;
-    }
+
     // Exceeded threshold and we can confirm that it was not accidental
     // KILL the machine
     // ----------------------------------------------------------------
-    if ( killCount >= KILL_DELAY)
-    {
-       kill();
+    if (killCount >= KILL_DELAY) kill();
+  #endif
+
+  #if HAS_HOME
+    // Check to see if we have to home, use poor man's debouncer
+    // ---------------------------------------------------------
+    if (!READ(HOME_PIN)) {
+      if (!homeDebounceCount) {
+        enquecommands_P(PSTR("G28"));
+        LCD_ALERTMESSAGEPGM(MSG_AUTO_HOME);
+      }
+      if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
+        homeDebounceCount++;
+      else
+        homeDebounceCount = 0;
+    }
+  #endif
+    
+  #if HAS_CONTROLLERFAN
+    controllerFan(); //Check if fan should be turned on to cool stepper drivers down
+  #endif
+
+  #ifdef EXTRUDER_RUNOUT_PREVENT
+    if (ms > previous_millis_cmd + EXTRUDER_RUNOUT_SECONDS * 1000)
+    if (degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP) {
+      bool oldstatus = E0_ENABLE_READ;
+      enable_e0();
+      float oldepos = current_position[E_AXIS], oldedes = destination[E_AXIS];
+      plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS],
+                      destination[E_AXIS] + EXTRUDER_RUNOUT_EXTRUDE * EXTRUDER_RUNOUT_ESTEPS / axis_steps_per_unit[E_AXIS],
+                      EXTRUDER_RUNOUT_SPEED / 60. * EXTRUDER_RUNOUT_ESTEPS / axis_steps_per_unit[E_AXIS], active_extruder);
+      current_position[E_AXIS] = oldepos;
+      destination[E_AXIS] = oldedes;
+      plan_set_e_position(oldepos);
+      previous_millis_cmd = ms; // refresh_cmd_timeout()
+      st_synchronize();
+      E0_ENABLE_WRITE(oldstatus);
     }
   #endif
 
-#if defined(HOME_PIN) && HOME_PIN > -1
-    // Check to see if we have to home, use poor man's debouncer
-    // ---------------------------------------------------------
-    if ( 0 == READ(HOME_PIN) )
-    {
-       if (homeDebounceCount == 0)
-       {
-          enquecommands_P((PSTR("G28")));
-          homeDebounceCount++;
-          LCD_ALERTMESSAGEPGM(MSG_AUTO_HOME);
-       }
-       else if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
-       {
-          homeDebounceCount++;
-       }
-       else
-       {
-          homeDebounceCount = 0;
-       }
-    }
-#endif
-    
-  #if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
-    controllerFan(); //Check if fan should be turned on to cool stepper drivers down
-  #endif
-  #ifdef EXTRUDER_RUNOUT_PREVENT
-    if( (millis() - previous_millis_cmd) >  EXTRUDER_RUNOUT_SECONDS*1000 )
-    if(degHotend(active_extruder)>EXTRUDER_RUNOUT_MINTEMP)
-    {
-     bool oldstatus=E0_ENABLE_READ;
-     enable_e0();
-     float oldepos=current_position[E_AXIS];
-     float oldedes=destination[E_AXIS];
-     plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS],
-                      destination[E_AXIS]+EXTRUDER_RUNOUT_EXTRUDE*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS],
-                      EXTRUDER_RUNOUT_SPEED/60.*EXTRUDER_RUNOUT_ESTEPS/axis_steps_per_unit[E_AXIS], active_extruder);
-     current_position[E_AXIS]=oldepos;
-     destination[E_AXIS]=oldedes;
-     plan_set_e_position(oldepos);
-     previous_millis_cmd=millis();
-     st_synchronize();
-     E0_ENABLE_WRITE(oldstatus);
-    }
-  #endif
-  #if defined(DUAL_X_CARRIAGE)
+  #ifdef DUAL_X_CARRIAGE
     // handle delayed move timeout
-    if (delayed_move_time != 0 && (millis() - delayed_move_time) > 1000 && Stopped == false)
-    {
+    if (delayed_move_time && ms > delayed_move_time + 1000 && !Stopped) {
       // travel moves have been received so enact them
       delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
-      memcpy(destination,current_position,sizeof(destination));
+      memcpy(destination,current_position, sizeof(destination));
       prepare_move();
     }
   #endif
+
   #ifdef TEMP_STAT_LEDS
-      handle_status_leds();
+    handle_status_leds();
   #endif
+
   check_axes_activity();
 }
 
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index 8c05f83bc91..e072c7d731e 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -56,7 +56,7 @@
   #if EXTRUDERS > 1
 
     #if EXTRUDERS > 4
-      #error The maximum number of EXTRUDERS is 4.
+      #error The maximum number of EXTRUDERS in Marlin is 4.
     #endif
 
     #ifdef TEMP_SENSOR_1_AS_REDUNDANT
@@ -77,6 +77,13 @@
 
   #endif // EXTRUDERS > 1
 
+  /**
+   * Limited number of servos
+   */
+  #if NUM_SERVOS > 4
+    #error The maximum number of SERVOS in Marlin is 4.
+  #endif
+
   /**
    * Required LCD language
    */
@@ -209,9 +216,9 @@
    */
   #ifdef DUAL_X_CARRIAGE
     #if EXTRUDERS == 1 || defined(COREXY) \
-        || !defined(X2_ENABLE_PIN) || !defined(X2_STEP_PIN) || !defined(X2_DIR_PIN) \
+        || !HAS_X2_ENABLE || !HAS_X2_STEP || !HAS_X2_DIR \
         || !defined(X2_HOME_POS) || !defined(X2_MIN_POS) || !defined(X2_MAX_POS) \
-        || !defined(X_MAX_PIN) || X_MAX_PIN < 0
+        || !HAS_X_MAX
       #error Missing or invalid definitions for DUAL_X_CARRIAGE mode.
     #endif
     #if X_HOME_DIR != -1 || X2_HOME_DIR != 1
@@ -234,6 +241,10 @@
     #endif
   #endif
 
+  #if HAS_FAN && CONTROLLERFAN_PIN == FAN_PIN
+    #error You cannot set CONTROLLERFAN_PIN equal to FAN_PIN
+  #endif
+
   /**
    * Test required HEATER defines
    */
@@ -254,4 +265,11 @@
     #error HEATER_0_PIN not defined for this board
   #endif
 
+  /**
+   * Warnings for old configurations
+   */
+  #ifdef X_HOME_RETRACT_MM
+    #error [XYZ]_HOME_RETRACT_MM settings have been renamed [XYZ]_HOME_BUMP_MM
+  #endif
+
 #endif //SANITYCHECK_H
diff --git a/Marlin/configurator/config/Configuration.h b/Marlin/configurator/config/Configuration.h
index 7868e8e815e..3e1a56dc4ae 100644
--- a/Marlin/configurator/config/Configuration.h
+++ b/Marlin/configurator/config/Configuration.h
@@ -412,7 +412,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/configurator/config/Configuration_adv.h b/Marlin/configurator/config/Configuration_adv.h
index 21b30580c8f..8acdeb969cc 100644
--- a/Marlin/configurator/config/Configuration_adv.h
+++ b/Marlin/configurator/config/Configuration_adv.h
@@ -189,9 +189,9 @@
 // @section homing
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 2
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 2
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index 63e99bd3aa9..c057e56425c 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -300,7 +300,7 @@ static void lcd_implementation_status_screen() {
   // Fan
   lcd_setFont(FONT_STATUSMENU);
   u8g.setPrintPos(104,27);
-  #if defined(FAN_PIN) && FAN_PIN > -1
+  #if HAS_FAN
     int per = ((fanSpeed + 1) * 100) / 256;
     if (per) {
 
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index 1cc50246a80..4c835382325 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -364,7 +364,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/Felix/Configuration_DUAL.h b/Marlin/example_configurations/Felix/Configuration_DUAL.h
index 956e2dc472f..a0ecacd9279 100644
--- a/Marlin/example_configurations/Felix/Configuration_DUAL.h
+++ b/Marlin/example_configurations/Felix/Configuration_DUAL.h
@@ -364,7 +364,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/Felix/Configuration_adv.h b/Marlin/example_configurations/Felix/Configuration_adv.h
index 9bbd515caf9..d60eb529630 100644
--- a/Marlin/example_configurations/Felix/Configuration_adv.h
+++ b/Marlin/example_configurations/Felix/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 3
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 3
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index 594295a3e1f..e6622234614 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -387,7 +387,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/Hephestos/Configuration_adv.h b/Marlin/example_configurations/Hephestos/Configuration_adv.h
index bac3b571a73..0529df9bebd 100644
--- a/Marlin/example_configurations/Hephestos/Configuration_adv.h
+++ b/Marlin/example_configurations/Hephestos/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 2
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 2
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index c17e419c7bf..854367af82f 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -392,7 +392,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/K8200/Configuration_adv.h b/Marlin/example_configurations/K8200/Configuration_adv.h
index 9bbd515caf9..d60eb529630 100644
--- a/Marlin/example_configurations/K8200/Configuration_adv.h
+++ b/Marlin/example_configurations/K8200/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 3
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 3
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index 96fef00cfe5..15fde93f835 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -416,7 +416,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/SCARA/Configuration_adv.h b/Marlin/example_configurations/SCARA/Configuration_adv.h
index 7b00532e49e..5145b166853 100644
--- a/Marlin/example_configurations/SCARA/Configuration_adv.h
+++ b/Marlin/example_configurations/SCARA/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 3
-#define Y_HOME_RETRACT_MM 3
-#define Z_HOME_RETRACT_MM 3
+#define X_HOME_BUMP_MM 3
+#define Y_HOME_BUMP_MM 3
+#define Z_HOME_BUMP_MM 3
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 190270e853f..5bccb9827b6 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -386,7 +386,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/WITBOX/Configuration_adv.h b/Marlin/example_configurations/WITBOX/Configuration_adv.h
index 965ecbf40b0..ab480dd6351 100644
--- a/Marlin/example_configurations/WITBOX/Configuration_adv.h
+++ b/Marlin/example_configurations/WITBOX/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 2
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 2
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index 4aeb5d55f47..1403ddd2ddd 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -414,7 +414,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
@@ -507,10 +507,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
     #define Z_PROBE_ALLEN_KEY_DEPLOY_Y DELTA_PRINTABLE_RADIUS
     #define Z_PROBE_ALLEN_KEY_DEPLOY_Z 100
     
-    #define Z_PROBE_ALLEN_KEY_RETRACT_X     -64
-    #define Z_PROBE_ALLEN_KEY_RETRACT_Y     56
-    #define Z_PROBE_ALLEN_KEY_RETRACT_Z     23
-    #define Z_PROBE_ALLEN_KEY_RETRACT_DEPTH 20
+    #define Z_PROBE_ALLEN_KEY_STOW_X     -64
+    #define Z_PROBE_ALLEN_KEY_STOW_Y     56
+    #define Z_PROBE_ALLEN_KEY_STOW_Z     23
+    #define Z_PROBE_ALLEN_KEY_STOW_DEPTH 20
   #endif
   
   //If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk
diff --git a/Marlin/example_configurations/delta/generic/Configuration_adv.h b/Marlin/example_configurations/delta/generic/Configuration_adv.h
index abecacec227..501cd814d22 100644
--- a/Marlin/example_configurations/delta/generic/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/generic/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 5 // deltas need the same for all three axis
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axis
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index edb7ff5261a..420dfa9e4cc 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -414,7 +414,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
@@ -511,10 +511,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
     #define Z_PROBE_ALLEN_KEY_DEPLOY_Y DELTA_PRINTABLE_RADIUS
     #define Z_PROBE_ALLEN_KEY_DEPLOY_Z 100
     
-    #define Z_PROBE_ALLEN_KEY_RETRACT_X     -64
-    #define Z_PROBE_ALLEN_KEY_RETRACT_Y     56
-    #define Z_PROBE_ALLEN_KEY_RETRACT_Z     23
-    #define Z_PROBE_ALLEN_KEY_RETRACT_DEPTH 20
+    #define Z_PROBE_ALLEN_KEY_STOW_X     -64
+    #define Z_PROBE_ALLEN_KEY_STOW_Y     56
+    #define Z_PROBE_ALLEN_KEY_STOW_Z     23
+    #define Z_PROBE_ALLEN_KEY_STOW_DEPTH 20
   #endif
   
   //If defined, the Probe servo will be turned on only during movement and then turned off to avoid jerk
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
index b255000bce9..c402064bfeb 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 5 // deltas need the same for all three axis
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 5 // deltas need the same for all three axis
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index a3e8fd08857..55e26ebf8ba 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -384,7 +384,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/makibox/Configuration_adv.h b/Marlin/example_configurations/makibox/Configuration_adv.h
index 5e0e6ef4d82..3db90efcff8 100644
--- a/Marlin/example_configurations/makibox/Configuration_adv.h
+++ b/Marlin/example_configurations/makibox/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 2
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 2
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 7ffff335340..6b781b7a45b 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -386,7 +386,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 // #define MANUAL_BED_LEVELING  // Add display menu option for bed leveling
 // #define MESH_BED_LEVELING    // Enable mesh bed leveling
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #define MESH_MIN_X 10
   #define MESH_MAX_X (X_MAX_POS - MESH_MIN_X)
   #define MESH_MIN_Y 10
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
index bbf7dc00535..2ecf75951ac 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration_adv.h
@@ -175,9 +175,9 @@
 #endif //DUAL_X_CARRIAGE
 
 //homing hits the endstop, then retracts by this distance, before it tries to slowly bump again:
-#define X_HOME_RETRACT_MM 5
-#define Y_HOME_RETRACT_MM 5
-#define Z_HOME_RETRACT_MM 1
+#define X_HOME_BUMP_MM 5
+#define Y_HOME_BUMP_MM 5
+#define Z_HOME_BUMP_MM 1
 #define HOMING_BUMP_DIVISOR {10, 10, 20}  // Re-Bump Speed Divisor (Divides the Homing Feedrate)
 //#define QUICK_HOME  //if this is defined, if both x and y are to be homed, a diagonal move will be performed initially.
 
diff --git a/Marlin/mesh_bed_leveling.h b/Marlin/mesh_bed_leveling.h
index b6c4ed5b007..bf7275e5c34 100644
--- a/Marlin/mesh_bed_leveling.h
+++ b/Marlin/mesh_bed_leveling.h
@@ -1,6 +1,6 @@
 #include "Marlin.h"
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
 
   #define MESH_X_DIST ((MESH_MAX_X - MESH_MIN_X)/(MESH_NUM_X_POINTS - 1))
   #define MESH_Y_DIST ((MESH_MAX_Y - MESH_MIN_Y)/(MESH_NUM_Y_POINTS - 1))
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index d98ef63d4df..d7d33c170e2 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -58,7 +58,7 @@
 #include "ultralcd.h"
 #include "language.h"
 
-#if defined(MESH_BED_LEVELING)
+#ifdef MESH_BED_LEVELING
   #include "mesh_bed_leveling.h"
 #endif  // MESH_BED_LEVELING
 
@@ -427,7 +427,7 @@ void check_axes_activity() {
     disable_e3();
   }
 
-  #if defined(FAN_PIN) && FAN_PIN > -1 // HAS_FAN
+  #if HAS_FAN
     #ifdef FAN_KICKSTART_TIME
       static unsigned long fan_kick_end;
       if (tail_fan_speed) {
@@ -447,17 +447,17 @@ void check_axes_activity() {
     #else
       analogWrite(FAN_PIN, tail_fan_speed);
     #endif //!FAN_SOFT_PWM
-  #endif //FAN_PIN > -1
+  #endif // HAS_FAN
 
   #ifdef AUTOTEMP
     getHighESpeed();
   #endif
 
   #ifdef BARICUDA
-    #if defined(HEATER_1_PIN) && HEATER_1_PIN > -1 // HAS_HEATER_1
+    #if HAS_HEATER_1
       analogWrite(HEATER_1_PIN,tail_valve_pressure);
     #endif
-    #if defined(HEATER_2_PIN) && HEATER_2_PIN > -1 // HAS_HEATER_2
+    #if HAS_HEATER_2
       analogWrite(HEATER_2_PIN,tail_e_to_p_pressure);
     #endif
   #endif
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index a7dba4659ec..a9a428c0e2c 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -85,29 +85,29 @@ static volatile bool endstop_z_hit = false;
   int motor_current_setting[3] = DEFAULT_PWM_MOTOR_CURRENT;
 #endif
 
-#if defined(X_MIN_PIN) && X_MIN_PIN >= 0
+#if HAS_X_MIN
   static bool old_x_min_endstop = false;
 #endif
-#if defined(X_MAX_PIN) && X_MAX_PIN >= 0
+#if HAS_X_MAX
   static bool old_x_max_endstop = false;
 #endif
-#if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0
+#if HAS_Y_MIN
   static bool old_y_min_endstop = false;
 #endif
-#if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
+#if HAS_Y_MAX
   static bool old_y_max_endstop = false;
 #endif
-#if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0
+#if HAS_Z_MIN
   static bool old_z_min_endstop = false;
 #endif
-#if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
+#if HAS_Z_MAX
   static bool old_z_max_endstop = false;
 #endif
 #ifdef Z_DUAL_ENDSTOPS
-  #if defined(Z2_MIN_PIN) && Z2_MIN_PIN >= 0
+  #if HAS_Z2_MIN
     static bool old_z2_min_endstop = false;
   #endif
-  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
+  #if HAS_Z2_MAX
     static bool old_z2_max_endstop = false;
   #endif
 #endif
@@ -472,7 +472,7 @@ ISR(TIMER1_COMPA_vect) {
               if ((current_block->active_extruder == 0 && X_HOME_DIR == -1) || (current_block->active_extruder != 0 && X2_HOME_DIR == -1))
             #endif          
               {
-                #if defined(X_MIN_PIN) && X_MIN_PIN >= 0
+                #if HAS_X_MIN
                   UPDATE_ENDSTOP(x, X, min, MIN);
                 #endif
               }
@@ -483,7 +483,7 @@ ISR(TIMER1_COMPA_vect) {
               if ((current_block->active_extruder == 0 && X_HOME_DIR == 1) || (current_block->active_extruder != 0 && X2_HOME_DIR == 1))
             #endif
               {
-                #if defined(X_MAX_PIN) && X_MAX_PIN >= 0
+                #if HAS_X_MAX
                   UPDATE_ENDSTOP(x, X, max, MAX);
                 #endif
               }
@@ -498,12 +498,12 @@ ISR(TIMER1_COMPA_vect) {
           if (TEST(out_bits, Y_AXIS))   // -direction
       #endif
           { // -direction
-            #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0
+            #if HAS_Y_MIN
               UPDATE_ENDSTOP(y, Y, min, MIN);
             #endif
           }
           else { // +direction
-            #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
+            #if HAS_Y_MAX
               UPDATE_ENDSTOP(y, Y, max, MAX);
             #endif
           }
@@ -519,13 +519,13 @@ ISR(TIMER1_COMPA_vect) {
 
       if (check_endstops) {
 
-        #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0
+        #if HAS_Z_MIN
 
           #ifdef Z_DUAL_ENDSTOPS
 
             bool z_min_endstop = READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING,
                 z2_min_endstop =
-                  #if defined(Z2_MIN_PIN) && Z2_MIN_PIN >= 0
+                  #if HAS_Z2_MIN
                     READ(Z2_MIN_PIN) != Z2_MIN_ENDSTOP_INVERTING
                   #else
                     z_min_endstop
@@ -561,13 +561,13 @@ ISR(TIMER1_COMPA_vect) {
 
       if (check_endstops) {
 
-        #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
+        #if HAS_Z_MAX
 
           #ifdef Z_DUAL_ENDSTOPS
 
             bool z_max_endstop = READ(Z_MAX_PIN) != Z_MAX_ENDSTOP_INVERTING,
                 z2_max_endstop =
-                  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
+                  #if HAS_Z2_MAX
                     READ(Z2_MAX_PIN) != Z2_MAX_ENDSTOP_INVERTING
                   #else
                     z_max_endstop
@@ -835,127 +835,127 @@ void st_init() {
   #endif
   
   // Initialize Dir Pins
-  #if defined(X_DIR_PIN) && X_DIR_PIN >= 0
+  #if HAS_X_DIR
     X_DIR_INIT;
   #endif
-  #if defined(X2_DIR_PIN) && X2_DIR_PIN >= 0
+  #if HAS_X2_DIR
     X2_DIR_INIT;
   #endif
-  #if defined(Y_DIR_PIN) && Y_DIR_PIN >= 0
+  #if HAS_Y_DIR
     Y_DIR_INIT;
-    #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_DIR_PIN) && Y2_DIR_PIN >= 0
+    #if defined(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_DIR
       Y2_DIR_INIT;
     #endif
   #endif
-  #if defined(Z_DIR_PIN) && Z_DIR_PIN >= 0
+  #if HAS_Z_DIR
     Z_DIR_INIT;
-    #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_DIR_PIN) && Z2_DIR_PIN >= 0
+    #if defined(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_DIR
       Z2_DIR_INIT;
     #endif
   #endif
-  #if defined(E0_DIR_PIN) && E0_DIR_PIN >= 0
+  #if HAS_E0_DIR
     E0_DIR_INIT;
   #endif
-  #if defined(E1_DIR_PIN) && E1_DIR_PIN >= 0
+  #if HAS_E1_DIR
     E1_DIR_INIT;
   #endif
-  #if defined(E2_DIR_PIN) && E2_DIR_PIN >= 0
+  #if HAS_E2_DIR
     E2_DIR_INIT;
   #endif
-  #if defined(E3_DIR_PIN) && E3_DIR_PIN >= 0
+  #if HAS_E3_DIR
     E3_DIR_INIT;
   #endif
 
   //Initialize Enable Pins - steppers default to disabled.
 
-  #if defined(X_ENABLE_PIN) && X_ENABLE_PIN >= 0
+  #if HAS_X_ENABLE
     X_ENABLE_INIT;
     if (!X_ENABLE_ON) X_ENABLE_WRITE(HIGH);
   #endif
-  #if defined(X2_ENABLE_PIN) && X2_ENABLE_PIN >= 0
+  #if HAS_X2_ENABLE
     X2_ENABLE_INIT;
     if (!X_ENABLE_ON) X2_ENABLE_WRITE(HIGH);
   #endif
-  #if defined(Y_ENABLE_PIN) && Y_ENABLE_PIN >= 0
+  #if HAS_Y_ENABLE
     Y_ENABLE_INIT;
     if (!Y_ENABLE_ON) Y_ENABLE_WRITE(HIGH);
 	
-	#if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_ENABLE_PIN) && Y2_ENABLE_PIN >= 0
+	#if defined(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_ENABLE
 	  Y2_ENABLE_INIT;
 	  if (!Y_ENABLE_ON) Y2_ENABLE_WRITE(HIGH);
 	#endif
   #endif
-  #if defined(Z_ENABLE_PIN) && Z_ENABLE_PIN >= 0
+  #if HAS_Z_ENABLE
     Z_ENABLE_INIT;
     if (!Z_ENABLE_ON) Z_ENABLE_WRITE(HIGH);
 
-    #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_ENABLE_PIN) && Z2_ENABLE_PIN >= 0
+    #if defined(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_ENABLE
       Z2_ENABLE_INIT;
       if (!Z_ENABLE_ON) Z2_ENABLE_WRITE(HIGH);
     #endif
   #endif
-  #if defined(E0_ENABLE_PIN) && E0_ENABLE_PIN >= 0
+  #if HAS_E0_ENABLE
     E0_ENABLE_INIT;
     if (!E_ENABLE_ON) E0_ENABLE_WRITE(HIGH);
   #endif
-  #if defined(E1_ENABLE_PIN) && E1_ENABLE_PIN >= 0
+  #if HAS_E1_ENABLE
     E1_ENABLE_INIT;
     if (!E_ENABLE_ON) E1_ENABLE_WRITE(HIGH);
   #endif
-  #if defined(E2_ENABLE_PIN) && E2_ENABLE_PIN >= 0
+  #if HAS_E2_ENABLE
     E2_ENABLE_INIT;
     if (!E_ENABLE_ON) E2_ENABLE_WRITE(HIGH);
   #endif
-  #if defined(E3_ENABLE_PIN) && E3_ENABLE_PIN >= 0
+  #if HAS_E3_ENABLE
     E3_ENABLE_INIT;
     if (!E_ENABLE_ON) E3_ENABLE_WRITE(HIGH);
   #endif
 
   //endstops and pullups
 
-  #if defined(X_MIN_PIN) && X_MIN_PIN >= 0
+  #if HAS_X_MIN
     SET_INPUT(X_MIN_PIN);
     #ifdef ENDSTOPPULLUP_XMIN
       WRITE(X_MIN_PIN,HIGH);
     #endif
   #endif
 
-  #if defined(Y_MIN_PIN) && Y_MIN_PIN >= 0
+  #if HAS_Y_MIN
     SET_INPUT(Y_MIN_PIN);
     #ifdef ENDSTOPPULLUP_YMIN
       WRITE(Y_MIN_PIN,HIGH);
     #endif
   #endif
 
-  #if defined(Z_MIN_PIN) && Z_MIN_PIN >= 0
+  #if HAS_Z_MIN
     SET_INPUT(Z_MIN_PIN);
     #ifdef ENDSTOPPULLUP_ZMIN
       WRITE(Z_MIN_PIN,HIGH);
     #endif
   #endif
 
-  #if defined(X_MAX_PIN) && X_MAX_PIN >= 0
+  #if HAS_X_MAX
     SET_INPUT(X_MAX_PIN);
     #ifdef ENDSTOPPULLUP_XMAX
       WRITE(X_MAX_PIN,HIGH);
     #endif
   #endif
 
-  #if defined(Y_MAX_PIN) && Y_MAX_PIN >= 0
+  #if HAS_Y_MAX
     SET_INPUT(Y_MAX_PIN);
     #ifdef ENDSTOPPULLUP_YMAX
       WRITE(Y_MAX_PIN,HIGH);
     #endif
   #endif
 
-  #if defined(Z_MAX_PIN) && Z_MAX_PIN >= 0
+  #if HAS_Z_MAX
     SET_INPUT(Z_MAX_PIN);
     #ifdef ENDSTOPPULLUP_ZMAX
       WRITE(Z_MAX_PIN,HIGH);
     #endif
   #endif
 
-  #if defined(Z2_MAX_PIN) && Z2_MAX_PIN >= 0
+  #if HAS_Z2_MAX
     SET_INPUT(Z2_MAX_PIN);
     #ifdef ENDSTOPPULLUP_ZMAX
       WRITE(Z2_MAX_PIN,HIGH);
@@ -970,36 +970,36 @@ void st_init() {
   #define E_AXIS_INIT(NUM) AXIS_INIT(e## NUM, E## NUM, E)
 
   // Initialize Step Pins
-  #if defined(X_STEP_PIN) && X_STEP_PIN >= 0
+  #if HAS_X_STEP
     AXIS_INIT(x, X, X);
   #endif
-  #if defined(X2_STEP_PIN) && X2_STEP_PIN >= 0
+  #if HAS_X2_STEP
     AXIS_INIT(x, X2, X);
   #endif
-  #if defined(Y_STEP_PIN) && Y_STEP_PIN >= 0
-    #if defined(Y_DUAL_STEPPER_DRIVERS) && defined(Y2_STEP_PIN) && Y2_STEP_PIN >= 0
+  #if HAS_Y_STEP
+    #if defined(Y_DUAL_STEPPER_DRIVERS) && HAS_Y2_STEP
       Y2_STEP_INIT;
       Y2_STEP_WRITE(INVERT_Y_STEP_PIN);
     #endif
     AXIS_INIT(y, Y, Y);
   #endif
-  #if defined(Z_STEP_PIN) && Z_STEP_PIN >= 0
-    #if defined(Z_DUAL_STEPPER_DRIVERS) && defined(Z2_STEP_PIN) && Z2_STEP_PIN >= 0
+  #if HAS_Z_STEP
+    #if defined(Z_DUAL_STEPPER_DRIVERS) && HAS_Z2_STEP
       Z2_STEP_INIT;
       Z2_STEP_WRITE(INVERT_Z_STEP_PIN);
     #endif
     AXIS_INIT(z, Z, Z);
   #endif
-  #if defined(E0_STEP_PIN) && E0_STEP_PIN >= 0
+  #if HAS_E0_STEP
     E_AXIS_INIT(0);
   #endif
-  #if defined(E1_STEP_PIN) && E1_STEP_PIN >= 0
+  #if HAS_E1_STEP
     E_AXIS_INIT(1);
   #endif
-  #if defined(E2_STEP_PIN) && E2_STEP_PIN >= 0
+  #if HAS_E2_STEP
     E_AXIS_INIT(2);
   #endif
-  #if defined(E3_STEP_PIN) && E3_STEP_PIN >= 0
+  #if HAS_E3_STEP
     E_AXIS_INIT(3);
   #endif
 
@@ -1220,12 +1220,12 @@ void digipot_current(uint8_t driver, int current) {
 }
 
 void microstep_init() {
-  #if defined(E1_MS1_PIN) && E1_MS1_PIN >= 0
+  #if HAS_MICROSTEPS_E1
     pinMode(E1_MS1_PIN,OUTPUT);
-    pinMode(E1_MS2_PIN,OUTPUT); 
+    pinMode(E1_MS2_PIN,OUTPUT);
   #endif
 
-  #if defined(X_MS1_PIN) && X_MS1_PIN >= 0
+  #if HAS_MICROSTEPS
     pinMode(X_MS1_PIN,OUTPUT);
     pinMode(X_MS2_PIN,OUTPUT);  
     pinMode(Y_MS1_PIN,OUTPUT);
@@ -1246,7 +1246,7 @@ void microstep_ms(uint8_t driver, int8_t ms1, int8_t ms2) {
     case 1: digitalWrite(Y_MS1_PIN, ms1); break;
     case 2: digitalWrite(Z_MS1_PIN, ms1); break;
     case 3: digitalWrite(E0_MS1_PIN, ms1); break;
-    #if defined(E1_MS1_PIN) && E1_MS1_PIN >= 0
+    #if HAS_MICROSTEPS_E1
       case 4: digitalWrite(E1_MS1_PIN, ms1); break;
     #endif
   }
@@ -1285,7 +1285,7 @@ void microstep_readings() {
   SERIAL_PROTOCOLPGM("E0: ");
   SERIAL_PROTOCOL(digitalRead(E0_MS1_PIN));
   SERIAL_PROTOCOLLN(digitalRead(E0_MS2_PIN));
-  #if defined(E1_MS1_PIN) && E1_MS1_PIN >= 0
+  #if HAS_MICROSTEPS_E1
     SERIAL_PROTOCOLPGM("E1: ");
     SERIAL_PROTOCOL(digitalRead(E1_MS1_PIN));
     SERIAL_PROTOCOLLN(digitalRead(E1_MS2_PIN));
diff --git a/Marlin/temperature.h b/Marlin/temperature.h
index 79146a35565..a6ea1b7d1c0 100644
--- a/Marlin/temperature.h
+++ b/Marlin/temperature.h
@@ -53,7 +53,7 @@ extern float current_temperature_bed;
   extern float redundant_temperature;
 #endif
 
-#if defined(CONTROLLERFAN_PIN) && CONTROLLERFAN_PIN > -1
+#if HAS_CONTROLLERFAN
   extern unsigned char soft_pwm_bed;
 #endif
 
diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h
index a89c2620647..fe4f5976802 100644
--- a/Marlin/ultralcd.h
+++ b/Marlin/ultralcd.h
@@ -64,14 +64,14 @@
 
     #define LCD_CLICKED (buttons&EN_C)
     #ifdef REPRAPWORLD_KEYPAD
-  	  #define EN_REPRAPWORLD_KEYPAD_F3 BIT(BLEN_REPRAPWORLD_KEYPAD_F3)
-  	  #define EN_REPRAPWORLD_KEYPAD_F2 BIT(BLEN_REPRAPWORLD_KEYPAD_F2)
-  	  #define EN_REPRAPWORLD_KEYPAD_F1 BIT(BLEN_REPRAPWORLD_KEYPAD_F1)
-  	  #define EN_REPRAPWORLD_KEYPAD_UP BIT(BLEN_REPRAPWORLD_KEYPAD_UP)
-  	  #define EN_REPRAPWORLD_KEYPAD_RIGHT BIT(BLEN_REPRAPWORLD_KEYPAD_RIGHT)
-  	  #define EN_REPRAPWORLD_KEYPAD_MIDDLE BIT(BLEN_REPRAPWORLD_KEYPAD_MIDDLE)
-  	  #define EN_REPRAPWORLD_KEYPAD_DOWN BIT(BLEN_REPRAPWORLD_KEYPAD_DOWN)
-  	  #define EN_REPRAPWORLD_KEYPAD_LEFT BIT(BLEN_REPRAPWORLD_KEYPAD_LEFT)
+  	  #define EN_REPRAPWORLD_KEYPAD_F3 (BIT(BLEN_REPRAPWORLD_KEYPAD_F3))
+  	  #define EN_REPRAPWORLD_KEYPAD_F2 (BIT(BLEN_REPRAPWORLD_KEYPAD_F2))
+  	  #define EN_REPRAPWORLD_KEYPAD_F1 (BIT(BLEN_REPRAPWORLD_KEYPAD_F1))
+  	  #define EN_REPRAPWORLD_KEYPAD_UP (BIT(BLEN_REPRAPWORLD_KEYPAD_UP))
+  	  #define EN_REPRAPWORLD_KEYPAD_RIGHT (BIT(BLEN_REPRAPWORLD_KEYPAD_RIGHT))
+  	  #define EN_REPRAPWORLD_KEYPAD_MIDDLE (BIT(BLEN_REPRAPWORLD_KEYPAD_MIDDLE))
+  	  #define EN_REPRAPWORLD_KEYPAD_DOWN (BIT(BLEN_REPRAPWORLD_KEYPAD_DOWN))
+  	  #define EN_REPRAPWORLD_KEYPAD_LEFT (BIT(BLEN_REPRAPWORLD_KEYPAD_LEFT))
 
   	  #define LCD_CLICKED ((buttons&EN_C) || (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F1))
   	  #define REPRAPWORLD_KEYPAD_MOVE_Z_UP (buttons_reprapworld_keypad&EN_REPRAPWORLD_KEYPAD_F2)

From 6b919e14c1d2986c9d7cd884322fc1b3ad3a5efc Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 15:45:41 -0700
Subject: [PATCH 43/83] Group all universal variables

---
 Marlin/Marlin_main.cpp | 176 +++++++++++++++++------------------------
 1 file changed, 74 insertions(+), 102 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index cc7ac87aa8b..f82408e5f1b 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -202,10 +202,6 @@
 #endif
 
 float homing_feedrate[] = HOMING_FEEDRATE;
-#ifdef ENABLE_AUTO_BED_LEVELING
-  int xy_travel_speed = XY_TRAVEL_SPEED;
-  float zprobe_zoffset = -Z_PROBE_OFFSET_FROM_EXTRUDER;
-#endif
 int homing_bump_divisor[] = HOMING_BUMP_DIVISOR;
 bool axis_relative_modes[] = AXIS_RELATIVE_MODES;
 int feedmultiply = 100; //100->1 200->2
@@ -216,15 +212,49 @@ float filament_size[EXTRUDERS] = ARRAY_BY_EXTRUDERS(DEFAULT_NOMINAL_FILAMENT_DIA
 float volumetric_multiplier[EXTRUDERS] = ARRAY_BY_EXTRUDERS(1.0, 1.0, 1.0, 1.0);
 float current_position[NUM_AXIS] = { 0.0 };
 float home_offset[3] = { 0 };
-#ifdef DELTA
-  float endstop_adj[3] = { 0 };
-#elif defined(Z_DUAL_ENDSTOPS)
-  float z_endstop_adj = 0;
-#endif
-
 float min_pos[3] = { X_MIN_POS, Y_MIN_POS, Z_MIN_POS };
 float max_pos[3] = { X_MAX_POS, Y_MAX_POS, Z_MAX_POS };
 bool axis_known_position[3] = { false };
+uint8_t active_extruder = 0;
+int fanSpeed = 0;
+bool cancel_heatup = false;
+const char errormagic[] PROGMEM = "Error:";
+const char echomagic[] PROGMEM = "echo:";
+const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
+static float destination[NUM_AXIS] = { 0 };
+static float offset[3] = { 0 };
+static float feedrate = 1500.0, next_feedrate, saved_feedrate;
+static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
+static bool relative_mode = false;  //Determines Absolute or Relative Coordinates
+static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
+static int bufindr = 0;
+static int bufindw = 0;
+static int buflen = 0;
+static char serial_char;
+static int serial_count = 0;
+static boolean comment_mode = false;
+static char *strchr_pointer; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.)
+const char* queued_commands_P= NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */
+const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
+// Inactivity shutdown
+static unsigned long previous_millis_cmd = 0;
+static unsigned long max_inactive_time = 0;
+static unsigned long stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l;
+unsigned long starttime = 0; ///< Print job start time
+unsigned long stoptime = 0;  ///< Print job stop time
+static uint8_t tmp_extruder;
+bool Stopped = false;
+bool CooldownNoWait = true;
+bool target_direction;
+
+#ifdef ENABLE_AUTO_BED_LEVELING
+  int xy_travel_speed = XY_TRAVEL_SPEED;
+  float zprobe_zoffset = -Z_PROBE_OFFSET_FROM_EXTRUDER;
+#endif
+
+#if defined(Z_DUAL_ENDSTOPS) && !defined(DELTA)
+  float z_endstop_adj = 0;
+#endif
 
 // Extruder offsets
 #if EXTRUDERS > 1
@@ -243,9 +273,6 @@ bool axis_known_position[3] = { false };
   };
 #endif
 
-uint8_t active_extruder = 0;
-int fanSpeed = 0;
-
 #ifdef SERVO_ENDSTOPS
   int servo_endstops[] = SERVO_ENDSTOPS;
   int servo_endstop_angles[] = SERVO_ENDSTOP_ANGLES;
@@ -282,33 +309,36 @@ int fanSpeed = 0;
   ;
 #endif
 
-#ifdef DELTA
-  float delta[3] = { 0, 0, 0 };
-  #define SIN_60 0.8660254037844386
-  #define COS_60 0.5
-  // these are the default values, can be overriden with M665
-  float delta_radius = DELTA_RADIUS;
-  float delta_tower1_x = -SIN_60 * delta_radius; // front left tower
-  float delta_tower1_y = -COS_60 * delta_radius;     
-  float delta_tower2_x =  SIN_60 * delta_radius; // front right tower
-  float delta_tower2_y = -COS_60 * delta_radius;     
-  float delta_tower3_x = 0;                      // back middle tower
-  float delta_tower3_y = delta_radius;
-  float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
-  float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
-  float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
-  #ifdef ENABLE_AUTO_BED_LEVELING
-    int delta_grid_spacing[2] = { 0, 0 };
-    float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS];
+#if defined(DELTA) || defined(SCARA)
+  static float delta[3] = { 0, 0, 0 };    
+  #ifdef DELTA
+    #define SIN_60 0.8660254037844386
+    #define COS_60 0.5
+    float endstop_adj[3] = { 0 };
+    // these are the default values, can be overriden with M665
+    float delta_radius = DELTA_RADIUS;
+    float delta_tower1_x = -SIN_60 * delta_radius; // front left tower
+    float delta_tower1_y = -COS_60 * delta_radius;     
+    float delta_tower2_x =  SIN_60 * delta_radius; // front right tower
+    float delta_tower2_y = -COS_60 * delta_radius;     
+    float delta_tower3_x = 0;                      // back middle tower
+    float delta_tower3_y = delta_radius;
+    float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
+    float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
+    float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
+    #ifdef ENABLE_AUTO_BED_LEVELING
+      int delta_grid_spacing[2] = { 0, 0 };
+      float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS];
+    #endif
   #endif
-#endif
 
-#ifdef SCARA
-  float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
-  static float delta[3] = { 0, 0, 0 };		
-#endif
+  #ifdef SCARA
+    float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
+  #endif
 
-bool cancel_heatup = false;
+#elif !defined(DELTA)
+  static bool home_all_axis = true;
+#endif
 
 #ifdef FILAMENT_SENSOR
   //Variables for Filament Sensor input
@@ -326,67 +356,21 @@ bool cancel_heatup = false;
    static bool filrunoutEnqued = false;
 #endif
 
-const char errormagic[] PROGMEM = "Error:";
-const char echomagic[] PROGMEM = "echo:";
-
-const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
-static float destination[NUM_AXIS] = { 0 };
-
-static float offset[3] = { 0 };
-
-#ifndef DELTA
-  static bool home_all_axis = true;
-#endif
-
-static float feedrate = 1500.0, next_feedrate, saved_feedrate;
-static long gcode_N, gcode_LastN, Stopped_gcode_LastN = 0;
-
-static bool relative_mode = false;  //Determines Absolute or Relative Coordinates
-
-static char cmdbuffer[BUFSIZE][MAX_CMD_SIZE];
 #ifdef SDSUPPORT
   static bool fromsd[BUFSIZE];
 #endif
-static int bufindr = 0;
-static int bufindw = 0;
-static int buflen = 0;
-
-static char serial_char;
-static int serial_count = 0;
-static boolean comment_mode = false;
-static char *strchr_pointer; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.)
-
-const char* queued_commands_P= NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */
-
-const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
-
-// Inactivity shutdown
-static unsigned long previous_millis_cmd = 0;
-static unsigned long max_inactive_time = 0;
-static unsigned long stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l;
-
-unsigned long starttime = 0; ///< Print job start time
-unsigned long stoptime = 0;  ///< Print job stop time
-
-static uint8_t tmp_extruder;
-
-
-bool Stopped = false;
 
 #if NUM_SERVOS > 0
   Servo servos[NUM_SERVOS];
 #endif
 
-bool CooldownNoWait = true;
-bool target_direction;
-
 #ifdef CHDK
   unsigned long chdkHigh = 0;
   boolean chdkActive = false;
 #endif
 
 //===========================================================================
-//=============================Routines======================================
+//================================ Functions ================================
 //===========================================================================
 
 void get_arc_coordinates();
@@ -5707,21 +5691,11 @@ void disable_all_axes() {
  */
 void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
   
-  #if HAS_KILL
-    static int killCount = 0;   // make the inactivity button a bit less responsive
-    const int KILL_DELAY = 750;
-  #endif
-
   #if HAS_FILRUNOUT
     if (card.sdprinting && !(READ(FILRUNOUT_PIN) ^ FIL_RUNOUT_INVERTING))
       filrunout();
   #endif
 
-  #if HAS_HOME
-    static int homeDebounceCount = 0;   // poor man's debouncing count
-    const int HOME_DEBOUNCE_DELAY = 750;
-  #endif
-
   if (buflen < BUFSIZE - 1) get_command();
 
   unsigned long ms = millis();
@@ -5744,6 +5718,8 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
     // Check if the kill button was pressed and wait just in case it was an accidental
     // key kill key press
     // -------------------------------------------------------------------------------
+    static int killCount = 0;   // make the inactivity button a bit less responsive
+    const int KILL_DELAY = 750;
     if (!READ(KILL_PIN))
        killCount++;
     else if (killCount > 0)
@@ -5758,6 +5734,8 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
   #if HAS_HOME
     // Check to see if we have to home, use poor man's debouncer
     // ---------------------------------------------------------
+    static int homeDebounceCount = 0;   // poor man's debouncing count
+    const int HOME_DEBOUNCE_DELAY = 750;
     if (!READ(HOME_PIN)) {
       if (!homeDebounceCount) {
         enquecommands_P(PSTR("G28"));
@@ -5797,7 +5775,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
     if (delayed_move_time && ms > delayed_move_time + 1000 && !Stopped) {
       // travel moves have been received so enact them
       delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
-      memcpy(destination,current_position, sizeof(destination));
+      memcpy(destination, current_position, sizeof(destination));
       prepare_move();
     }
   #endif
@@ -5814,13 +5792,7 @@ void kill()
   cli(); // Stop interrupts
   disable_heater();
 
-  disable_x();
-  disable_y();
-  disable_z();
-  disable_e0();
-  disable_e1();
-  disable_e2();
-  disable_e3();
+  disable_all_axes();
 
   #if HAS_POWER_SWITCH
     pinMode(PS_ON_PIN, INPUT);

From 424d5495e46b7cb3f59ab631b44d8b395e7b1753 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 16:38:05 -0700
Subject: [PATCH 44/83] Add PIDTEMPBED to EEPROM

---
 Marlin/ConfigurationStore.cpp | 87 ++++++++++++++++++++++++++---------
 Marlin/temperature.h          |  2 +-
 2 files changed, 65 insertions(+), 24 deletions(-)

diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp
index b1da94a3006..3ed585f823d 100644
--- a/Marlin/ConfigurationStore.cpp
+++ b/Marlin/ConfigurationStore.cpp
@@ -3,7 +3,21 @@
  *
  * Configuration and EEPROM storage
  *
- * V16 EEPROM Layout:
+ * IMPORTANT:  Whenever there are changes made to the variables stored in EEPROM
+ * in the functions below, also increment the version number. This makes sure that
+ * the default values are used whenever there is a change to the data, to prevent
+ * wrong data being written to the variables.
+ *
+ * ALSO: Variables in the Store and Retrieve sections must be in the same order.
+ *       If a feature is disabled, some data must still be written that, when read,
+ *       either sets a Sane Default, or results in No Change to the existing value.
+ *
+ */
+
+#define EEPROM_VERSION "V19"
+
+/**
+ * V19 EEPROM Layout:
  *
  *  ver
  *  axis_steps_per_unit (x4)
@@ -47,6 +61,9 @@
  *  Kp[2], Ki[2], Kd[2], Kc[2]
  *  Kp[3], Ki[3], Kd[3], Kc[3]
  *
+ * PIDTEMPBED:
+ *  bedKp, bedKi, bedKd
+ *
  * DOGLCD:
  *  lcd_contrast
  *
@@ -111,15 +128,6 @@ void _EEPROM_readData(int &pos, uint8_t* value, uint8_t size) {
 
 #define EEPROM_OFFSET 100
 
-
-// IMPORTANT:  Whenever there are changes made to the variables stored in EEPROM
-// in the functions below, also increment the version number. This makes sure that
-// the default values are used whenever there is a change to the data, to prevent
-// wrong data being written to the variables.
-// ALSO:  always make sure the variables in the Store and retrieve sections are in the same order.
-
-#define EEPROM_VERSION "V18"
-
 #ifdef EEPROM_SETTINGS
 
 void Config_StoreSettings()  {
@@ -194,7 +202,6 @@ void Config_StoreSettings()  {
   EEPROM_WRITE_VAR(i, absPreheatHPBTemp);
   EEPROM_WRITE_VAR(i, absPreheatFanSpeed);
 
-
   for (int e = 0; e < 4; e++) {
 
     #ifdef PIDTEMP
@@ -209,12 +216,10 @@ void Config_StoreSettings()  {
           EEPROM_WRITE_VAR(i, dummy);
         #endif
       }
-      else {
-    #else // !PIDTEMP
-      {
+      else
     #endif // !PIDTEMP
-
-        dummy = DUMMY_PID_VALUE;
+      {
+        dummy = DUMMY_PID_VALUE; // When read, will not change the existing value
         EEPROM_WRITE_VAR(i, dummy);
         dummy = 0.0f;
         for (int q = 3; q--;) EEPROM_WRITE_VAR(i, dummy);
@@ -222,6 +227,14 @@ void Config_StoreSettings()  {
 
   } // Extruders Loop
 
+  #ifndef PIDTEMPBED
+    float bedKp = DUMMY_PID_VALUE, bedKi = DUMMY_PID_VALUE, bedKd = DUMMY_PID_VALUE;
+  #endif
+
+  EEPROM_WRITE_VAR(i, bedKp);
+  EEPROM_WRITE_VAR(i, bedKi);
+  EEPROM_WRITE_VAR(i, bedKd);
+
   #ifndef DOGLCD
     int lcd_contrast = 32;
   #endif
@@ -364,7 +377,7 @@ void Config_RetrieveSettings() {
 
     #ifdef PIDTEMP
       for (int e = 0; e < 4; e++) { // 4 = max extruders currently supported by Marlin
-        EEPROM_READ_VAR(i, dummy);
+        EEPROM_READ_VAR(i, dummy); // Kp
         if (e < EXTRUDERS && dummy != DUMMY_PID_VALUE) {
           // do not need to scale PID values as the values in EEPROM are already scaled
           PID_PARAM(Kp, e) = dummy;
@@ -385,6 +398,20 @@ void Config_RetrieveSettings() {
       for (int q=16; q--;) EEPROM_READ_VAR(i, dummy);  // 4x Kp, Ki, Kd, Kc
     #endif // !PIDTEMP
 
+    #ifndef PIDTEMPBED
+      float bedKp, bedKi, bedKd;
+    #endif
+
+    EEPROM_READ_VAR(i, dummy); // bedKp
+    if (dummy != DUMMY_PID_VALUE) {
+      bedKp = dummy;
+      EEPROM_READ_VAR(i, bedKi);
+      EEPROM_READ_VAR(i, bedKd);
+    }
+    else {
+      for (int q=2; q--;) EEPROM_READ_VAR(i, dummy); // bedKi, bedKd
+    }
+
     #ifndef DOGLCD
       int lcd_contrast;
     #endif
@@ -517,6 +544,12 @@ void Config_ResetDefault() {
     updatePID();
   #endif // PIDTEMP
 
+  #ifdef PIDTEMPBED
+    bedKp = DEFAULT_bedKp;
+    bedKi = scalePID_i(DEFAULT_bedKi);
+    bedKd = scalePID_d(DEFAULT_bedKd);
+  #endif
+
   #ifdef FWRETRACT
     autoretract_enabled = false;
     retract_length = RETRACT_LENGTH;
@@ -660,17 +693,25 @@ void Config_PrintSettings(bool forReplay) {
     SERIAL_EOL;  
   #endif // DELTA
 
-  #ifdef PIDTEMP
+  #if defined(PIDTEMP) || defined(PIDTEMPBED)
     SERIAL_ECHO_START;
     if (!forReplay) {
       SERIAL_ECHOLNPGM("PID settings:");
       SERIAL_ECHO_START;
     }
-    SERIAL_ECHOPAIR("   M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echos values for E0
-    SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0)));
-    SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0)));
-    SERIAL_EOL;
-  #endif // PIDTEMP
+    #ifdef PIDTEMP
+      SERIAL_ECHOPAIR("   M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echos values for E0
+      SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0)));
+      SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0)));
+      SERIAL_EOL;
+    #endif
+    #ifdef PIDTEMPBED
+      SERIAL_ECHOPAIR("   M304 P", bedKp); // for compatibility with hosts, only echos values for E0
+      SERIAL_ECHOPAIR(" I", unscalePID_i(bedKi));
+      SERIAL_ECHOPAIR(" D", unscalePID_d(bedKd));
+      SERIAL_EOL;
+    #endif
+  #endif
 
   #ifdef FWRETRACT
 
diff --git a/Marlin/temperature.h b/Marlin/temperature.h
index 79146a35565..eb080ea4c9d 100644
--- a/Marlin/temperature.h
+++ b/Marlin/temperature.h
@@ -72,11 +72,11 @@ extern float current_temperature_bed;
   float unscalePID_d(float d);
 
 #endif
+
 #ifdef PIDTEMPBED
   extern float bedKp,bedKi,bedKd;
 #endif
   
-  
 #ifdef BABYSTEPPING
   extern volatile int babystepsTodo[3];
 #endif

From 007a4bd4217831a37bfcce3c0eb0c58c639afb2e Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 16:41:58 -0700
Subject: [PATCH 45/83] Adjust spacing in view function

---
 Marlin/ConfigurationStore.cpp | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/Marlin/ConfigurationStore.cpp b/Marlin/ConfigurationStore.cpp
index 3ed585f823d..eacd7ea1231 100644
--- a/Marlin/ConfigurationStore.cpp
+++ b/Marlin/ConfigurationStore.cpp
@@ -699,14 +699,17 @@ void Config_PrintSettings(bool forReplay) {
       SERIAL_ECHOLNPGM("PID settings:");
       SERIAL_ECHO_START;
     }
+    #if defined(PIDTEMP) && defined(PIDTEMPBED)
+      SERIAL_EOL;
+    #endif
     #ifdef PIDTEMP
-      SERIAL_ECHOPAIR("   M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echos values for E0
+      SERIAL_ECHOPAIR("  M301 P", PID_PARAM(Kp, 0)); // for compatibility with hosts, only echos values for E0
       SERIAL_ECHOPAIR(" I", unscalePID_i(PID_PARAM(Ki, 0)));
       SERIAL_ECHOPAIR(" D", unscalePID_d(PID_PARAM(Kd, 0)));
       SERIAL_EOL;
     #endif
     #ifdef PIDTEMPBED
-      SERIAL_ECHOPAIR("   M304 P", bedKp); // for compatibility with hosts, only echos values for E0
+      SERIAL_ECHOPAIR("  M304 P", bedKp); // for compatibility with hosts, only echos values for E0
       SERIAL_ECHOPAIR(" I", unscalePID_i(bedKi));
       SERIAL_ECHOPAIR(" D", unscalePID_d(bedKd));
       SERIAL_EOL;
@@ -720,7 +723,7 @@ void Config_PrintSettings(bool forReplay) {
       SERIAL_ECHOLNPGM("Retract: S=Length (mm) F:Speed (mm/m) Z: ZLift (mm)");
       SERIAL_ECHO_START;
     }
-    SERIAL_ECHOPAIR("   M207 S", retract_length);
+    SERIAL_ECHOPAIR("  M207 S", retract_length);
     SERIAL_ECHOPAIR(" F", retract_feedrate*60);
     SERIAL_ECHOPAIR(" Z", retract_zlift);
     SERIAL_EOL;
@@ -729,7 +732,7 @@ void Config_PrintSettings(bool forReplay) {
       SERIAL_ECHOLNPGM("Recover: S=Extra length (mm) F:Speed (mm/m)");
       SERIAL_ECHO_START;
     }
-    SERIAL_ECHOPAIR("   M208 S", retract_recover_length);
+    SERIAL_ECHOPAIR("  M208 S", retract_recover_length);
     SERIAL_ECHOPAIR(" F", retract_recover_feedrate*60);
     SERIAL_EOL;
     SERIAL_ECHO_START;
@@ -737,7 +740,7 @@ void Config_PrintSettings(bool forReplay) {
       SERIAL_ECHOLNPGM("Auto-Retract: S=0 to disable, 1 to interpret extrude-only moves as retracts or recoveries");
       SERIAL_ECHO_START;
     }
-    SERIAL_ECHOPAIR("   M209 S", (unsigned long)(autoretract_enabled ? 1 : 0));
+    SERIAL_ECHOPAIR("  M209 S", (unsigned long)(autoretract_enabled ? 1 : 0));
     SERIAL_EOL;
 
     #if EXTRUDERS > 1
@@ -761,20 +764,20 @@ void Config_PrintSettings(bool forReplay) {
       SERIAL_ECHOLNPGM("Filament settings:");
       SERIAL_ECHO_START;
     }
-    SERIAL_ECHOPAIR("   M200 D", filament_size[0]);
+    SERIAL_ECHOPAIR("  M200 D", filament_size[0]);
     SERIAL_EOL;
 
     #if EXTRUDERS > 1
       SERIAL_ECHO_START;
-      SERIAL_ECHOPAIR("   M200 T1 D", filament_size[1]);
+      SERIAL_ECHOPAIR("  M200 T1 D", filament_size[1]);
       SERIAL_EOL;
       #if EXTRUDERS > 2
         SERIAL_ECHO_START;
-        SERIAL_ECHOPAIR("   M200 T2 D", filament_size[2]);
+        SERIAL_ECHOPAIR("  M200 T2 D", filament_size[2]);
         SERIAL_EOL;
         #if EXTRUDERS > 3
           SERIAL_ECHO_START;
-          SERIAL_ECHOPAIR("   M200 T3 D", filament_size[3]);
+          SERIAL_ECHOPAIR("  M200 T3 D", filament_size[3]);
           SERIAL_EOL;
         #endif
       #endif
@@ -793,7 +796,7 @@ void Config_PrintSettings(bool forReplay) {
         SERIAL_ECHOLNPGM("Z-Probe Offset (mm):");
         SERIAL_ECHO_START;
       }
-      SERIAL_ECHOPAIR("   M", (unsigned long)CUSTOM_M_CODE_SET_Z_PROBE_OFFSET);
+      SERIAL_ECHOPAIR("  M", (unsigned long)CUSTOM_M_CODE_SET_Z_PROBE_OFFSET);
       SERIAL_ECHOPAIR(" Z", -zprobe_zoffset);
     #else
       if (!forReplay) {

From 92119d0f7d3ac8f20499585328e52d671556efca Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 16:46:56 -0700
Subject: [PATCH 46/83] Static delta[] for SCARA

---
 Marlin/Marlin_main.cpp | 52 ++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 27 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index f82408e5f1b..113c06e18af 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -309,37 +309,35 @@ bool target_direction;
   ;
 #endif
 
-#if defined(DELTA) || defined(SCARA)
-  static float delta[3] = { 0, 0, 0 };    
-  #ifdef DELTA
-    #define SIN_60 0.8660254037844386
-    #define COS_60 0.5
-    float endstop_adj[3] = { 0 };
-    // these are the default values, can be overriden with M665
-    float delta_radius = DELTA_RADIUS;
-    float delta_tower1_x = -SIN_60 * delta_radius; // front left tower
-    float delta_tower1_y = -COS_60 * delta_radius;     
-    float delta_tower2_x =  SIN_60 * delta_radius; // front right tower
-    float delta_tower2_y = -COS_60 * delta_radius;     
-    float delta_tower3_x = 0;                      // back middle tower
-    float delta_tower3_y = delta_radius;
-    float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
-    float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
-    float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
-    #ifdef ENABLE_AUTO_BED_LEVELING
-      int delta_grid_spacing[2] = { 0, 0 };
-      float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS];
-    #endif
+#ifdef DELTA
+  float delta[3] = { 0 };
+  #define SIN_60 0.8660254037844386
+  #define COS_60 0.5
+  float endstop_adj[3] = { 0 };
+  // these are the default values, can be overriden with M665
+  float delta_radius = DELTA_RADIUS;
+  float delta_tower1_x = -SIN_60 * delta_radius; // front left tower
+  float delta_tower1_y = -COS_60 * delta_radius;     
+  float delta_tower2_x =  SIN_60 * delta_radius; // front right tower
+  float delta_tower2_y = -COS_60 * delta_radius;     
+  float delta_tower3_x = 0;                      // back middle tower
+  float delta_tower3_y = delta_radius;
+  float delta_diagonal_rod = DELTA_DIAGONAL_ROD;
+  float delta_diagonal_rod_2 = sq(delta_diagonal_rod);
+  float delta_segments_per_second = DELTA_SEGMENTS_PER_SECOND;
+  #ifdef ENABLE_AUTO_BED_LEVELING
+    int delta_grid_spacing[2] = { 0, 0 };
+    float bed_level[AUTO_BED_LEVELING_GRID_POINTS][AUTO_BED_LEVELING_GRID_POINTS];
   #endif
-
-  #ifdef SCARA
-    float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
-  #endif
-
-#elif !defined(DELTA)
+#else
   static bool home_all_axis = true;
 #endif
 
+#ifdef SCARA
+  static float delta[3] = { 0 };
+  float axis_scaling[3] = { 1, 1, 1 };    // Build size scaling, default to 1
+#endif
+
 #ifdef FILAMENT_SENSOR
   //Variables for Filament Sensor input
   float filament_width_nominal = DEFAULT_NOMINAL_FILAMENT_DIA;  //Set nominal filament width, can be changed with M404

From a469d796e16368beef2f5f8e5fbd1aa26e4238bd Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 18:14:57 -0700
Subject: [PATCH 47/83] Add cleanups needed for #1772

---
 Marlin/Conditionals.h                         |  1 +
 Marlin/Configuration.h                        | 24 ++++++++---------
 Marlin/Marlin_main.cpp                        | 26 +++++++++----------
 Marlin/configurator/config/Configuration.h    | 14 ++++++++++
 .../Felix/Configuration.h                     | 14 ++++++++++
 .../Felix/Configuration_DUAL.h                | 14 ++++++++++
 .../Hephestos/Configuration.h                 | 14 ++++++++++
 .../K8200/Configuration.h                     | 14 ++++++++++
 .../SCARA/Configuration.h                     | 14 ++++++++++
 .../WITBOX/Configuration.h                    | 14 ++++++++++
 .../delta/generic/Configuration.h             | 14 ++++++++++
 .../delta/kossel_mini/Configuration.h         | 14 ++++++++++
 .../makibox/Configuration.h                   | 14 ++++++++++
 .../tvrrug/Round2/Configuration.h             | 14 ++++++++++
 14 files changed, 180 insertions(+), 25 deletions(-)

diff --git a/Marlin/Conditionals.h b/Marlin/Conditionals.h
index 8e50deee575..5d3213e0e35 100644
--- a/Marlin/Conditionals.h
+++ b/Marlin/Conditionals.h
@@ -389,6 +389,7 @@
   #define HAS_Z_MAX (PIN_EXISTS(Z_MAX))
   #define HAS_Z2_MIN (PIN_EXISTS(Z2_MIN))
   #define HAS_Z2_MAX (PIN_EXISTS(Z2_MAX))
+  #define HAS_Z_PROBE (PIN_EXISTS(Z_PROBE))
   #define HAS_SOLENOID_1 (PIN_EXISTS(SOL1))
   #define HAS_SOLENOID_2 (PIN_EXISTS(SOL2))
   #define HAS_SOLENOID_3 (PIN_EXISTS(SOL3))
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 4dd2d1020c6..321c25f97cd 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -499,19 +499,19 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
 
   #endif
 
-// Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
-// If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
-// If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
-// WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-// To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
-// If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
-// RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
-// for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
-// The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
-// D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
-// WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
 
-//  #define Z_PROBE_ENDSTOP
+  //#define Z_PROBE_ENDSTOP
 
 #endif // ENABLE_AUTO_BED_LEVELING
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index e5261e85c16..f9a1ed60bae 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1226,13 +1226,14 @@ inline void sync_plan_position() {
       
       st_synchronize();
 
-    #if defined(Z_PROBE_ENDSTOP)
+    #ifdef Z_PROBE_ENDSTOP
       bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
-      if (z_probe_endstop) {
+      if (z_probe_endstop)
     #else
       bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-      if (z_min_endstop) {
+      if (z_min_endstop)
     #endif
+      {
         if (!Stopped) {
           SERIAL_ERROR_START;
           SERIAL_ERRORLNPGM("Z-Probe failed to engage!");
@@ -1300,13 +1301,14 @@ inline void sync_plan_position() {
       
       st_synchronize();
 
-    #if defined(Z_PROBE_ENDSTOP)
+    #ifdef Z_PROBE_ENDSTOP
       bool z_probe_endstop = (READ(Z_PROBE_PIN) != Z_PROBE_ENDSTOP_INVERTING);
-      if (!z_probe_endstop) {
+      if (!z_probe_endstop)
     #else
       bool z_min_endstop = (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING);
-      if (!z_min_endstop) {
+      if (!z_min_endstop)
     #endif
+      {
         if (!Stopped) {
           SERIAL_ERROR_START;
           SERIAL_ERRORLNPGM("Z-Probe failed to retract!");
@@ -2778,14 +2780,12 @@ inline void gcode_M42() {
 #if defined(ENABLE_AUTO_BED_LEVELING) && defined(Z_PROBE_REPEATABILITY_TEST)
 
   // This is redudant since the SanityCheck.h already checks for a valid Z_PROBE_PIN, but here for clarity.
-  #if defined (Z_PROBE_ENDSTOP)
-    #if (! defined (Z_PROBE_PIN) || Z_PROBE_PIN == -1)
+  #ifdef Z_PROBE_ENDSTOP
+    #if !HAS_Z_PROBE
       #error "You must have a Z_PROBE_PIN defined in order to enable calculation of Z-Probe repeatability."
     #endif
-  #else
-    #if (Z_MIN_PIN == -1)
-      #error "You must have a Z_MIN_PIN defined in order to enable calculation of Z-Probe repeatability."
-    #endif
+  #elif !HAS_Z_MIN
+    #error "You must have a Z_MIN_PIN defined in order to enable calculation of Z-Probe repeatability."
   #endif
 
   /**
@@ -3515,7 +3515,7 @@ inline void gcode_M119() {
     SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
     SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
   #endif
-  #if defined(Z_PROBE_PIN) && Z_PROBE_PIN > -1
+  #if HAS_Z_PROBE
     SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
     SERIAL_PROTOCOLLN(((READ(Z_PROBE_PIN)^Z_PROBE_ENDSTOP_INVERTING)?MSG_ENDSTOP_HIT:MSG_ENDSTOP_OPEN));
   #endif
diff --git a/Marlin/configurator/config/Configuration.h b/Marlin/configurator/config/Configuration.h
index 3e1a56dc4ae..3d9f6342442 100644
--- a/Marlin/configurator/config/Configuration.h
+++ b/Marlin/configurator/config/Configuration.h
@@ -519,6 +519,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index 4c835382325..7f0b03049e9 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -469,6 +469,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/Felix/Configuration_DUAL.h b/Marlin/example_configurations/Felix/Configuration_DUAL.h
index a0ecacd9279..fbb1445148e 100644
--- a/Marlin/example_configurations/Felix/Configuration_DUAL.h
+++ b/Marlin/example_configurations/Felix/Configuration_DUAL.h
@@ -469,6 +469,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index e6622234614..3665760210f 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -492,6 +492,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index 854367af82f..7ddf21e2b21 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -497,6 +497,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index 15fde93f835..a00a7b6e93e 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -521,6 +521,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 5bccb9827b6..902985f31a6 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -491,6 +491,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index 1403ddd2ddd..699b8a3b419 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -537,6 +537,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index 420dfa9e4cc..2e4ebb386c8 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -541,6 +541,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index 55e26ebf8ba..5c8e1d87db0 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -489,6 +489,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 6b781b7a45b..12bab57e374 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -491,6 +491,20 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
 
   #endif
 
+  // Support for a dedicated Z PROBE endstop separate from the Z MIN endstop.
+  // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
+  // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
+  // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
+  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
+  // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
+  // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
+  // The D32 pin in Aux 4 on RAMPS maps to the Arduino D32 pin. Z_PROBE_PIN is setting the pin to use on the Arduino. Since the D32 pin on the RAMPS maps to D32 on Arduino, this works.
+  // D32 is currently selected in the RAMPS 1.3/1.4 pin file. All other boards will need changes to the respective pins_XXXXX.h file.
+  // WARNING: Setting the wrong pin may have unexpected and potentially disastrous outcomes. Use with caution and do your homework.
+
+  //#define Z_PROBE_ENDSTOP
+
 #endif // ENABLE_AUTO_BED_LEVELING
 
 

From 1ad5fb11781a661263e789a382bdee84b41e7f8c Mon Sep 17 00:00:00 2001
From: quillford <quillford@users.noreply.github.com>
Date: Fri, 3 Apr 2015 18:36:01 -0700
Subject: [PATCH 48/83] Fixed README typos

---
 README.md | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 2ecb9d8e8a6..8d06c080de0 100644
--- a/README.md
+++ b/README.md
@@ -18,8 +18,8 @@
 ## Quick Information
 
 This is a firmware for reprap single-processor electronics setups.
-It also works on the Ultimaker PCB. It supports printing from SD card+Folders, and look-ahead trajectory planning.
-This firmware is a mashup between [Sprinter](https://github.com/kliment/Sprinter), [grbl](https://github.com/simen/grbl) and many original parts.
+It also works on the Ultimaker PCB. It supports printing from SD card+Folders and look-ahead trajectory planning.
+This firmware is a mashup between [Sprinter](https://github.com/kliment/Sprinter), [grbl](https://github.com/simen/grbl), and many original parts.
 
 ## Current Status: Bug Fixing
 
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__IRC:__ #marlin-firmware @freenode ([WebChat Client](https://webchat.freenode.net/?channels=marlin-firmware)
+__IRC:__ #marlin-firmware @freenode ([WebChat Client](https://webchat.freenode.net/?channels=marlin-firmware))
 
 ## Credits
 
@@ -41,8 +41,8 @@ The current Marlin dev team consists of:
  - [@daid](https://github.com/daid)
 
 Sprinters lead developers are Kliment and caru.
-Grbls lead developer is Simen Svale Skogsrud.
-Sonney Jeon (Chamnit) improved some parts of grbl
+Grbl's lead developer is Simen Svale Skogsrud.
+Sonney Jeon (Chamnit) improved some parts of grbl.
 A fork by bkubicek for the Ultimaker was merged.
 
 More features have been added by:

From abd7fc36b68796413ca421a3e9d30bec93a7cdcf Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 18:54:55 -0700
Subject: [PATCH 49/83] Fix probe height at G28 start

---
 Marlin/Marlin_main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index f9a1ed60bae..f160f07a4d5 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2306,7 +2306,7 @@ inline void gcode_G28() {
 
           // raise extruder
           float measured_z,
-                z_before = Z_RAISE_BETWEEN_PROBINGS + (probePointCounter ? current_position[Z_AXIS] : 0);
+                z_before = probePointCounter ? Z_RAISE_BETWEEN_PROBINGS + current_position[Z_AXIS] : Z_RAISE_BEFORE_PROBING;
 
           #ifdef DELTA
             // Avoid probing the corners (outside the round or hexagon print surface) on a delta printer.

From b98ebd517ea548df393fc0617cdfba9edd16ee19 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 19:25:22 -0700
Subject: [PATCH 50/83] disable / enable_all_steppers functions

---
 Marlin/Marlin.h        |  3 +++
 Marlin/Marlin_main.cpp | 24 ++++++++++++++----------
 Marlin/planner.cpp     |  6 +++---
 Marlin/stepper.cpp     |  8 +-------
 Marlin/temperature.cpp |  8 +-------
 5 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 1f295a65a50..363a5e50036 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -179,6 +179,9 @@ void manage_inactivity(bool ignore_stepper_queue=false);
   #define disable_e3() /* nothing */
 #endif
 
+void enable_all_steppers();
+void disable_all_steppers();
+
 enum AxisEnum {X_AXIS=0, Y_AXIS=1, A_AXIS=0, B_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
 //X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
 
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index a21fcbd741d..8f8e69c85f0 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2569,13 +2569,7 @@ inline void gcode_G92() {
  */
 inline void gcode_M17() {
   LCD_MESSAGEPGM(MSG_NO_MOVE);
-  enable_x();
-  enable_y();
-  enable_z();
-  enable_e0();
-  enable_e1();
-  enable_e2();
-  enable_e3();
+  enable_all_steppers();
 }
 
 #ifdef SDSUPPORT
@@ -5695,7 +5689,17 @@ void handle_status_leds(void) {
 }
 #endif
 
-void disable_all_axes() {
+void enable_all_steppers() {
+  enable_x();
+  enable_y();
+  enable_z();
+  enable_e0();
+  enable_e1();
+  enable_e2();
+  enable_e3();
+}
+
+void disable_all_steppers() {
   disable_x();
   disable_y();
   disable_z();
@@ -5723,7 +5727,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
 
   if (stepper_inactive_time && ms > previous_millis_cmd + stepper_inactive_time
       && !ignore_stepper_queue && !blocks_queued())
-    disable_all_axes();
+    disable_all_steppers();
 
   #ifdef CHDK //Check if pin should be set to LOW after M240 set it to HIGH
     if (chdkActive && ms > chdkHigh + CHDK_DELAY) {
@@ -5811,7 +5815,7 @@ void kill()
   cli(); // Stop interrupts
   disable_heater();
 
-  disable_all_axes();
+  disable_all_steppers();
 
   #if HAS_POWER_SWITCH
     pinMode(PS_ON_PIN, INPUT);
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index d7d33c170e2..8d8d2e3c4eb 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -614,7 +614,7 @@ float junction_deviation = 0.1;
         #if EXTRUDERS > 1
           case 1:
             enable_e1();
-            g_uc_extruder_last_move[1] = BLOCK_BUFFER_SIZE*2;
+            g_uc_extruder_last_move[1] = BLOCK_BUFFER_SIZE * 2;
             if (g_uc_extruder_last_move[0] == 0) disable_e0();
             #if EXTRUDERS > 2
               if (g_uc_extruder_last_move[2] == 0) disable_e2();
@@ -626,7 +626,7 @@ float junction_deviation = 0.1;
           #if EXTRUDERS > 2
             case 2:
               enable_e2();
-              g_uc_extruder_last_move[2] = BLOCK_BUFFER_SIZE*2;
+              g_uc_extruder_last_move[2] = BLOCK_BUFFER_SIZE * 2;
               if (g_uc_extruder_last_move[0] == 0) disable_e0();
               if (g_uc_extruder_last_move[1] == 0) disable_e1();
               #if EXTRUDERS > 3
@@ -636,7 +636,7 @@ float junction_deviation = 0.1;
             #if EXTRUDERS > 3
               case 3:
                 enable_e3();
-                g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE*2;
+                g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE * 2;
                 if (g_uc_extruder_last_move[0] == 0) disable_e0();
                 if (g_uc_extruder_last_move[1] == 0) disable_e1();
                 if (g_uc_extruder_last_move[2] == 0) disable_e2();
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 6f12bc9b22c..ba4a4e9671d 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -1127,13 +1127,7 @@ long st_get_position(uint8_t axis) {
 
 void finishAndDisableSteppers() {
   st_synchronize();
-  disable_x();
-  disable_y();
-  disable_z();
-  disable_e0();
-  disable_e1();
-  disable_e2();
-  disable_e3();
+  disable_all_steppers();
 }
 
 void quickStop() {
diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 5a8da940646..4afb8dc09af 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1051,13 +1051,7 @@ void setWatch() {
           thermal_runaway = true;
           for (;;) {
             disable_heater();
-            disable_x();
-            disable_y();
-            disable_z();
-            disable_e0();
-            disable_e1();
-            disable_e2();
-            disable_e3();
+            disable_all_steppers();
             manage_heater();
             lcd_update();
           }

From 528e32a1d4fe035fc7d4ac239c4f3443173f1c13 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 19:34:55 -0700
Subject: [PATCH 51/83] Fix timeout in thermal_runaway when temperature is set
 higher

---
 Marlin/temperature.cpp | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 4afb8dc09af..8b70ae393c7 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1006,6 +1006,9 @@ void setWatch() {
 #if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
 
   void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
+
+    static int tr_target_temperature = 0;
+
     /*
         SERIAL_ECHO_START;
         SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:");
@@ -1029,19 +1032,27 @@ void setWatch() {
     switch (*state) {
       // Inactive state waits for a target temperature to be set
       case TRInactive:
-        if (target_temperature > 0) *state = TRFirstHeating;
+        if (target_temperature > 0) {
+          *state = TRFirstHeating;
+          tr_target_temperature = target_temperature;
+        }
         break;
       // When first heating, wait for the temperature to be reached then go to Stable state
       case TRFirstHeating:
-        if (temperature >= target_temperature) *state = TRStable;
+        if (temperature >= tr_target_temperature) *state = TRStable;
         break;
       // While the temperature is stable watch for a bad temperature
       case TRStable:
       {
-        // Whenever the current temperature is over the target (-hysteresis) restart the timer
-        if (temperature >= target_temperature - hysteresis_degc) {
-          *timer = millis();
+        // If the target temperature changes, restart
+        if (tr_target_temperature != target_temperature) {
+          *state = TRInactive;
+          break;
         }
+
+        // If the temperature is over the target (-hysteresis) restart the timer
+        if (temperature >= tr_target_temperature - hysteresis_degc) *timer = millis();
+
         // If the timer goes too long without a reset, trigger shutdown
         else if (millis() > *timer + period_seconds * 1000UL) {
           SERIAL_ERROR_START;
@@ -1060,7 +1071,7 @@ void setWatch() {
     }
   }
 
-#endif // HAS_HEATER_THERMAL_PROTECTION
+#endif // HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
 
 void disable_heater() {
   for (int i=0; i<EXTRUDERS; i++) setTargetHotend(0, i);

From 9ba55baa5bd4964797d62a3df24ebfdf15013da0 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 19:42:40 -0700
Subject: [PATCH 52/83] Track target temperature separately for each heater

---
 Marlin/temperature.cpp | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 8b70ae393c7..c0e427a6557 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -646,7 +646,7 @@ void manage_heater() {
   #if TEMP_SENSOR_BED != 0
   
     #if HAS_BED_THERMAL_PROTECTION
-      thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, 9, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS);
+      thermal_runaway_protection(&thermal_runaway_bed_state_machine, &thermal_runaway_bed_timer, current_temperature_bed, target_temperature_bed, -1, THERMAL_RUNAWAY_PROTECTION_BED_PERIOD, THERMAL_RUNAWAY_PROTECTION_BED_HYSTERESIS);
     #endif
 
     #ifdef PIDTEMPBED
@@ -1007,21 +1007,21 @@ void setWatch() {
 
   void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
 
-    static int tr_target_temperature = 0;
+    static int tr_target_temperature[EXTRUDERS+1];
 
     /*
         SERIAL_ECHO_START;
-        SERIAL_ECHO("Thermal Thermal Runaway Running. Heater ID:");
-        SERIAL_ECHO(heater_id);
-        SERIAL_ECHO(" ;  State:");
-        SERIAL_ECHO(*state);
-        SERIAL_ECHO(" ;  Timer:");
-        SERIAL_ECHO(*timer);
-        SERIAL_ECHO(" ;  Temperature:");
-        SERIAL_ECHO(temperature);
-        SERIAL_ECHO(" ;  Target Temp:");
-        SERIAL_ECHO(target_temperature);
-        SERIAL_ECHOLN("");    
+        SERIAL_ECHOPGM("Thermal Thermal Runaway Running. Heater ID: ");
+        if (heater_id < 0) SERIAL_ECHOPGM("bed"); else SERIAL_ECHOPGM(heater_id);
+        SERIAL_ECHOPGM(" ;  State:");
+        SERIAL_ECHOPGM(*state);
+        SERIAL_ECHOPGM(" ;  Timer:");
+        SERIAL_ECHOPGM(*timer);
+        SERIAL_ECHOPGM(" ;  Temperature:");
+        SERIAL_ECHOPGM(temperature);
+        SERIAL_ECHOPGM(" ;  Target Temp:");
+        SERIAL_ECHOPGM(target_temperature);
+        SERIAL_EOL;
     */
     if (target_temperature == 0 || thermal_runaway) {
       *state = TRInactive;
@@ -1029,35 +1029,37 @@ void setWatch() {
       return;
     }
 
+    int heater_index = heater_id >= 0 ? heater_id : EXTRUDERS;
+
     switch (*state) {
       // Inactive state waits for a target temperature to be set
       case TRInactive:
         if (target_temperature > 0) {
           *state = TRFirstHeating;
-          tr_target_temperature = target_temperature;
+          tr_target_temperature[heater_index] = target_temperature;
         }
         break;
       // When first heating, wait for the temperature to be reached then go to Stable state
       case TRFirstHeating:
-        if (temperature >= tr_target_temperature) *state = TRStable;
+        if (temperature >= tr_target_temperature[heater_index]) *state = TRStable;
         break;
       // While the temperature is stable watch for a bad temperature
       case TRStable:
       {
         // If the target temperature changes, restart
-        if (tr_target_temperature != target_temperature) {
+        if (tr_target_temperature[heater_index] != target_temperature) {
           *state = TRInactive;
           break;
         }
 
         // If the temperature is over the target (-hysteresis) restart the timer
-        if (temperature >= tr_target_temperature - hysteresis_degc) *timer = millis();
+        if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc) *timer = millis();
 
         // If the timer goes too long without a reset, trigger shutdown
         else if (millis() > *timer + period_seconds * 1000UL) {
           SERIAL_ERROR_START;
           SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
-          SERIAL_ERRORLN((int)heater_id);
+          if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id);
           LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
           thermal_runaway = true;
           for (;;) {

From 84e4edaea76546c250750b275cd586c1d165464f Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 19:52:00 -0700
Subject: [PATCH 53/83] Add M48 comment for #1794

---
 Marlin/Marlin_main.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 8f8e69c85f0..bc6ea3c137b 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -110,6 +110,7 @@
 //        Call gcode file : "M32 P !filename#" and return to caller file after finishing (similar to #include).
 //        The '#' is necessary when calling from within sd files, as it stops buffer prereading
 // M42  - Change pin status via gcode Use M42 Px Sy to set pin x to value y, when omitting Px the onboard led will be used.
+// M48  - Measure Z_Probe repeatability. M48 [n # of points] [X position] [Y position] [V_erboseness #] [E_ngage Probe] [L # of legs of travel]
 // M80  - Turn on Power Supply
 // M81  - Turn off Power Supply
 // M82  - Set E codes absolute (default)

From e0d4368cb50730f130851729a18b4ac4b64fe7d9 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 20:45:24 -0700
Subject: [PATCH 54/83] Minor code cleanup, move NUM_AXIS out of config

---
 Marlin/Configuration.h                        |  6 ++-
 Marlin/Marlin.h                               | 45 ++++++++++++-------
 Marlin/configurator/config/Configuration.h    |  6 ++-
 .../Felix/Configuration.h                     |  6 ++-
 .../Felix/Configuration_DUAL.h                |  6 ++-
 .../Hephestos/Configuration.h                 |  6 ++-
 .../K8200/Configuration.h                     |  6 ++-
 .../SCARA/Configuration.h                     |  6 ++-
 .../WITBOX/Configuration.h                    |  6 ++-
 .../delta/generic/Configuration.h             |  6 ++-
 .../delta/kossel_mini/Configuration.h         |  6 ++-
 .../makibox/Configuration.h                   |  6 ++-
 .../tvrrug/Round2/Configuration.h             |  6 ++-
 Marlin/planner.cpp                            |  6 +--
 14 files changed, 80 insertions(+), 43 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 321c25f97cd..5d9586808a7 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -529,8 +529,10 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 1f295a65a50..6a0f21f3b88 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -93,18 +93,15 @@ void serial_echopair_P(const char *s_P, double v);
 void serial_echopair_P(const char *s_P, unsigned long v);
 
 
-//Things to write to serial from Program memory. Saves 400 to 2k of RAM.
-FORCE_INLINE void serialprintPGM(const char *str)
-{
-  char ch=pgm_read_byte(str);
-  while(ch)
-  {
+// Things to write to serial from Program memory. Saves 400 to 2k of RAM.
+FORCE_INLINE void serialprintPGM(const char *str) {
+  char ch = pgm_read_byte(str);
+  while(ch) {
     MYSERIAL.write(ch);
-    ch=pgm_read_byte(++str);
+    ch = pgm_read_byte(++str);
   }
 }
 
-
 void get_command();
 void process_commands();
 
@@ -148,7 +145,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
 #endif
 
 #if HAS_E0_ENABLE
-  #define enable_e0() E0_ENABLE_WRITE(E_ENABLE_ON)
+  #define enable_e0()  E0_ENABLE_WRITE( E_ENABLE_ON)
   #define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON)
 #else
   #define enable_e0()  /* nothing */
@@ -156,7 +153,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
 #endif
 
 #if (EXTRUDERS > 1) && HAS_E1_ENABLE
-  #define enable_e1() E1_ENABLE_WRITE(E_ENABLE_ON)
+  #define enable_e1()  E1_ENABLE_WRITE( E_ENABLE_ON)
   #define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON)
 #else
   #define enable_e1()  /* nothing */
@@ -164,7 +161,7 @@ void manage_inactivity(bool ignore_stepper_queue=false);
 #endif
 
 #if (EXTRUDERS > 2) && HAS_E2_ENABLE
-  #define enable_e2() E2_ENABLE_WRITE(E_ENABLE_ON)
+  #define enable_e2()  E2_ENABLE_WRITE( E_ENABLE_ON)
   #define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON)
 #else
   #define enable_e2()  /* nothing */
@@ -172,15 +169,25 @@ void manage_inactivity(bool ignore_stepper_queue=false);
 #endif
 
 #if (EXTRUDERS > 3) && HAS_E3_ENABLE
-  #define enable_e3() E3_ENABLE_WRITE(E_ENABLE_ON)
+  #define enable_e3()  E3_ENABLE_WRITE( E_ENABLE_ON)
   #define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON)
 #else
   #define enable_e3()  /* nothing */
   #define disable_e3() /* nothing */
 #endif
 
+/**
+ * The axis order in all axis related arrays is X, Y, Z, E
+ */
+#define NUM_AXIS 4
+
+/**
+ * Axis indices as enumerated constants
+ *
+ * A_AXIS and B_AXIS are used by COREXY printers
+ * X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
+ */
 enum AxisEnum {X_AXIS=0, Y_AXIS=1, A_AXIS=0, B_AXIS=1, Z_AXIS=2, E_AXIS=3, X_HEAD=4, Y_HEAD=5};
-//X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship between X_AXIS and X Head movement, like CoreXY bots.
 
 void FlushSerialRequestResend();
 void ClearToSend();
@@ -224,7 +231,7 @@ void refresh_cmd_timeout(void);
 #ifndef CRITICAL_SECTION_START
   #define CRITICAL_SECTION_START  unsigned char _sreg = SREG; cli();
   #define CRITICAL_SECTION_END    SREG = _sreg;
-#endif //CRITICAL_SECTION_START
+#endif
 
 extern float homing_feedrate[];
 extern bool axis_relative_modes[];
@@ -233,8 +240,9 @@ extern bool volumetric_enabled;
 extern int extruder_multiply[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
 extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
 extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
-extern float current_position[NUM_AXIS] ;
+extern float current_position[NUM_AXIS];
 extern float home_offset[3];
+
 #ifdef DELTA
   extern float endstop_adj[3];
   extern float delta_radius;
@@ -242,18 +250,23 @@ extern float home_offset[3];
   extern float delta_segments_per_second;
   void recalc_delta_settings(float radius, float diagonal_rod);
 #elif defined(Z_DUAL_ENDSTOPS)
-extern float z_endstop_adj;
+  extern float z_endstop_adj;
 #endif
+
 #ifdef SCARA
   extern float axis_scaling[3];  // Build size scaling
 #endif
+
 extern float min_pos[3];
 extern float max_pos[3];
 extern bool axis_known_position[3];
+
 #ifdef ENABLE_AUTO_BED_LEVELING
   extern float zprobe_zoffset;
 #endif
+
 extern int fanSpeed;
+
 #ifdef BARICUDA
   extern int ValvePressure;
   extern int EtoPPressure;
diff --git a/Marlin/configurator/config/Configuration.h b/Marlin/configurator/config/Configuration.h
index 3d9f6342442..ca0b2d0791e 100644
--- a/Marlin/configurator/config/Configuration.h
+++ b/Marlin/configurator/config/Configuration.h
@@ -553,8 +553,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
 
 // @section movement
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index 7f0b03049e9..dfd79a0d971 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -499,8 +499,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/Felix/Configuration_DUAL.h b/Marlin/example_configurations/Felix/Configuration_DUAL.h
index fbb1445148e..98dea404bf0 100644
--- a/Marlin/example_configurations/Felix/Configuration_DUAL.h
+++ b/Marlin/example_configurations/Felix/Configuration_DUAL.h
@@ -499,8 +499,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index 3665760210f..7eceefb9869 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -522,8 +522,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {2000, 2000, 150, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index 7ddf21e2b21..3a6aea9b1dd 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -527,8 +527,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index a00a7b6e93e..2616f155fd1 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -551,8 +551,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   #define MANUAL_Z_HOME_POS 0.1  // Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {40*60, 40*60, 10*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 902985f31a6..d7d32d0881a 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -521,8 +521,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {120*60, 120*60, 7.2*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index 699b8a3b419..ac13788b22d 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -566,8 +566,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   #define MANUAL_Z_HOME_POS 250 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 
 // delta homing speeds must be the same on xyz
 #define HOMING_FEEDRATE {200*60, 200*60, 200*60, 0}  // set the homing speeds (mm/min)
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index 2e4ebb386c8..38f5023552b 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -570,8 +570,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
   #define MANUAL_Z_HOME_POS 250 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 
 // delta homing speeds must be the same on xyz
 #define HOMING_FEEDRATE {200*60, 200*60, 200*60, 0}  // set the homing speeds (mm/min)
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index 5c8e1d87db0..24c3e5b4d8a 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -519,8 +519,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {1500, 1500, 120, 0}  // set the homing speeds (mm/min)   ***** MakiBox A6 *****
 
 // default settings
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 12bab57e374..649046b880c 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -521,8 +521,10 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   //#define MANUAL_Z_HOME_POS 402 // For delta: Distance between nozzle and print surface after homing.
 #endif
 
-//// MOVEMENT SETTINGS
-#define NUM_AXIS 4 // The axis order in all axis related arrays is X, Y, Z, E
+/**
+ * MOVEMENT SETTINGS
+ */
+
 #define HOMING_FEEDRATE {50*60, 50*60, 4*60, 0}  // set the homing speeds (mm/min)
 
 // default settings
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index d7d33c170e2..8d8d2e3c4eb 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -614,7 +614,7 @@ float junction_deviation = 0.1;
         #if EXTRUDERS > 1
           case 1:
             enable_e1();
-            g_uc_extruder_last_move[1] = BLOCK_BUFFER_SIZE*2;
+            g_uc_extruder_last_move[1] = BLOCK_BUFFER_SIZE * 2;
             if (g_uc_extruder_last_move[0] == 0) disable_e0();
             #if EXTRUDERS > 2
               if (g_uc_extruder_last_move[2] == 0) disable_e2();
@@ -626,7 +626,7 @@ float junction_deviation = 0.1;
           #if EXTRUDERS > 2
             case 2:
               enable_e2();
-              g_uc_extruder_last_move[2] = BLOCK_BUFFER_SIZE*2;
+              g_uc_extruder_last_move[2] = BLOCK_BUFFER_SIZE * 2;
               if (g_uc_extruder_last_move[0] == 0) disable_e0();
               if (g_uc_extruder_last_move[1] == 0) disable_e1();
               #if EXTRUDERS > 3
@@ -636,7 +636,7 @@ float junction_deviation = 0.1;
             #if EXTRUDERS > 3
               case 3:
                 enable_e3();
-                g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE*2;
+                g_uc_extruder_last_move[3] = BLOCK_BUFFER_SIZE * 2;
                 if (g_uc_extruder_last_move[0] == 0) disable_e0();
                 if (g_uc_extruder_last_move[1] == 0) disable_e1();
                 if (g_uc_extruder_last_move[2] == 0) disable_e2();

From 1e5c18bb148f84f2bcb2f38bf0ce53b62148bdb3 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 21:43:30 -0700
Subject: [PATCH 55/83] Add code_value_short and SERIAL_CHAR

---
 Marlin/Marlin.h         |  22 ++---
 Marlin/MarlinSerial.cpp |   3 +-
 Marlin/Marlin_main.cpp  | 195 +++++++++++++++++++++-------------------
 Marlin/cardreader.cpp   |  12 +--
 Marlin/vector_3.cpp     |   4 +-
 5 files changed, 122 insertions(+), 114 deletions(-)

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 6a0f21f3b88..1ea5ba57f2b 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -62,31 +62,33 @@
   #define MYSERIAL MSerial
 #endif
 
-#define SERIAL_PROTOCOL(x) (MYSERIAL.print(x))
-#define SERIAL_PROTOCOL_F(x,y) (MYSERIAL.print(x,y))
-#define SERIAL_PROTOCOLPGM(x) (serialprintPGM(PSTR(x)))
-#define SERIAL_PROTOCOLLN(x) (MYSERIAL.print(x),MYSERIAL.write('\n'))
-#define SERIAL_PROTOCOLLNPGM(x) (serialprintPGM(PSTR(x)),MYSERIAL.write('\n'))
+#define SERIAL_CHAR(x) MYSERIAL.write(x)
+#define SERIAL_EOL SERIAL_CHAR('\n')
+
+#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x)
+#define SERIAL_PROTOCOL(x) MYSERIAL.print(x)
+#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y)
+#define SERIAL_PROTOCOLPGM(x) serialprintPGM(PSTR(x))
+#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x),MYSERIAL.write('\n'); }while(0)
+#define SERIAL_PROTOCOLLNPGM(x) do{ serialprintPGM(PSTR(x)),MYSERIAL.write('\n'); }while(0)
 
 
 extern const char errormagic[] PROGMEM;
 extern const char echomagic[] PROGMEM;
 
-#define SERIAL_ERROR_START (serialprintPGM(errormagic))
+#define SERIAL_ERROR_START serialprintPGM(errormagic)
 #define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
 #define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
 #define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
 #define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
 
-#define SERIAL_ECHO_START (serialprintPGM(echomagic))
+#define SERIAL_ECHO_START serialprintPGM(echomagic)
 #define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
 #define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
 #define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
 #define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
 
-#define SERIAL_ECHOPAIR(name,value) (serial_echopair_P(PSTR(name),(value)))
-
-#define SERIAL_EOL MYSERIAL.write('\n')
+#define SERIAL_ECHOPAIR(name,value) do{ serial_echopair_P(PSTR(name),(value)); }while(0)
 
 void serial_echopair_P(const char *s_P, float v);
 void serial_echopair_P(const char *s_P, double v);
diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp
index d8477b6db1d..fcba93256bc 100644
--- a/Marlin/MarlinSerial.cpp
+++ b/Marlin/MarlinSerial.cpp
@@ -268,8 +268,7 @@ void MarlinSerial::printFloat(double number, uint8_t digits) {
   print(int_part);
 
   // Print the decimal point, but only if there are digits beyond
-  if (digits > 0)
-    print("."); 
+  if (digits > 0) print('.');
 
   // Extract digits from the remainder one at a time
   while (digits-- > 0) {
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index f160f07a4d5..566f6c65fab 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -242,7 +242,7 @@ static unsigned long max_inactive_time = 0;
 static unsigned long stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l;
 unsigned long starttime = 0; ///< Print job start time
 unsigned long stoptime = 0;  ///< Print job stop time
-static uint8_t tmp_extruder;
+static uint8_t target_extruder;
 bool Stopped = false;
 bool CooldownNoWait = true;
 bool target_direction;
@@ -856,7 +856,9 @@ float code_value() {
   return ret;
 }
 
-long code_value_long() { return (strtol(strchr_pointer + 1, NULL, 10)); }
+long code_value_long() { return strtol(strchr_pointer + 1, NULL, 10); }
+
+int16_t code_value_short() { return (int16_t)strtol(strchr_pointer + 1, NULL, 10); }
 
 bool code_seen(char code) {
   strchr_pointer = strchr(cmdbuffer[bufindr], code);
@@ -1409,9 +1411,9 @@ inline void sync_plan_position() {
       for (int y = 0; y < AUTO_BED_LEVELING_GRID_POINTS; y++) {
         for (int x = 0; x < AUTO_BED_LEVELING_GRID_POINTS; x++) {
           SERIAL_PROTOCOL_F(bed_level[x][y], 2);
-          SERIAL_PROTOCOLPGM(" ");
+          SERIAL_PROTOCOLCHAR(' ');
         }
-        SERIAL_ECHOLN("");
+        SERIAL_EOL;
       }
     }
 
@@ -1684,7 +1686,7 @@ inline void gcode_G2_G3(bool clockwise) {
  * G4: Dwell S<seconds> or P<milliseconds>
  */
 inline void gcode_G4() {
-  unsigned long codenum=0;
+  unsigned long codenum = 0;
 
   LCD_MESSAGEPGM(MSG_DWELL);
 
@@ -1710,7 +1712,7 @@ inline void gcode_G4() {
   inline void gcode_G10_G11(bool doRetract=false) {
     #if EXTRUDERS > 1
       if (doRetract) {
-        retracted_swap[active_extruder] = (code_seen('S') && code_value_long() == 1); // checks for swap retract argument
+        retracted_swap[active_extruder] = (code_seen('S') && code_value_short() == 1); // checks for swap retract argument
       }
     #endif
     retract(doRetract
@@ -2028,7 +2030,7 @@ inline void gcode_G28() {
   inline void gcode_G29() {
 
     static int probe_point = -1;
-    MeshLevelingState state = code_seen('S') || code_seen('s') ? (MeshLevelingState)code_value_long() : MeshReport;
+    MeshLevelingState state = code_seen('S') || code_seen('s') ? (MeshLevelingState)code_value_short() : MeshReport;
     if (state < 0 || state > 2) {
       SERIAL_PROTOCOLLNPGM("S out of range (0-2).");
       return;
@@ -2039,7 +2041,7 @@ inline void gcode_G28() {
         if (mbl.active) {
           SERIAL_PROTOCOLPGM("Num X,Y: ");
           SERIAL_PROTOCOL(MESH_NUM_X_POINTS);
-          SERIAL_PROTOCOLPGM(",");
+          SERIAL_PROTOCOLCHAR(',');
           SERIAL_PROTOCOL(MESH_NUM_Y_POINTS);
           SERIAL_PROTOCOLPGM("\nZ search height: ");
           SERIAL_PROTOCOL(MESH_HOME_SEARCH_Z);
@@ -2155,7 +2157,7 @@ inline void gcode_G28() {
       return;
     }
 
-    int verbose_level = code_seen('V') || code_seen('v') ? code_value_long() : 1;
+    int verbose_level = code_seen('V') || code_seen('v') ? code_value_short() : 1;
     if (verbose_level < 0 || verbose_level > 4) {
       SERIAL_ECHOLNPGM("?(V)erbose Level is implausible (0-4).");
       return;
@@ -2177,19 +2179,19 @@ inline void gcode_G28() {
 
       int auto_bed_leveling_grid_points = AUTO_BED_LEVELING_GRID_POINTS;
       #ifndef DELTA
-        if (code_seen('P')) auto_bed_leveling_grid_points = code_value_long();
+        if (code_seen('P')) auto_bed_leveling_grid_points = code_value_short();
         if (auto_bed_leveling_grid_points < 2) {
           SERIAL_PROTOCOLPGM("?Number of probed (P)oints is implausible (2 minimum).\n");
           return;
         }
       #endif
 
-      xy_travel_speed = code_seen('S') ? code_value_long() : XY_TRAVEL_SPEED;
+      xy_travel_speed = code_seen('S') ? code_value_short() : XY_TRAVEL_SPEED;
 
-      int left_probe_bed_position = code_seen('L') ? code_value_long() : LEFT_PROBE_BED_POSITION,
-          right_probe_bed_position = code_seen('R') ? code_value_long() : RIGHT_PROBE_BED_POSITION,
-          front_probe_bed_position = code_seen('F') ? code_value_long() : FRONT_PROBE_BED_POSITION,
-          back_probe_bed_position = code_seen('B') ? code_value_long() : BACK_PROBE_BED_POSITION;
+      int left_probe_bed_position = code_seen('L') ? code_value_short() : LEFT_PROBE_BED_POSITION,
+          right_probe_bed_position = code_seen('R') ? code_value_short() : RIGHT_PROBE_BED_POSITION,
+          front_probe_bed_position = code_seen('F') ? code_value_short() : FRONT_PROBE_BED_POSITION,
+          back_probe_bed_position = code_seen('B') ? code_value_short() : BACK_PROBE_BED_POSITION;
 
       bool left_out_l = left_probe_bed_position < MIN_PROBE_X,
            left_out = left_out_l || left_probe_bed_position > right_probe_bed_position - MIN_PROBE_EDGE,
@@ -2393,7 +2395,7 @@ inline void gcode_G28() {
               if (diff >= 0.0)
                 SERIAL_PROTOCOLPGM(" +");   // Include + for column alignment
               else
-                SERIAL_PROTOCOLPGM(" ");
+                SERIAL_PROTOCOLCHAR(' ');
               SERIAL_PROTOCOL_F(diff, 5);
             } // xx
             SERIAL_EOL;
@@ -2517,11 +2519,11 @@ inline void gcode_G92() {
     unsigned long codenum = 0;
     bool hasP = false, hasS = false;
     if (code_seen('P')) {
-      codenum = code_value(); // milliseconds to wait
+      codenum = code_value_short(); // milliseconds to wait
       hasP = codenum > 0;
     }
     if (code_seen('S')) {
-      codenum = code_value() * 1000; // seconds to wait
+      codenum = code_value_short() * 1000UL; // seconds to wait
       hasS = codenum > 0;
     }
     char* starpos = strchr(src, '*');
@@ -2633,7 +2635,7 @@ inline void gcode_M17() {
    */
   inline void gcode_M26() {
     if (card.cardOK && code_seen('S'))
-      card.setIndex(code_value_long());
+      card.setIndex(code_value_short());
   }
 
   /**
@@ -2724,7 +2726,7 @@ inline void gcode_M31() {
       card.openFile(namestartpos, true, !call_procedure);
 
       if (code_seen('S') && strchr_pointer < namestartpos) // "S" (must occur _before_ the filename!)
-        card.setIndex(code_value_long());
+        card.setIndex(code_value_short());
 
       card.startFileprint();
       if (!call_procedure)
@@ -2752,11 +2754,11 @@ inline void gcode_M31() {
  */
 inline void gcode_M42() {
   if (code_seen('S')) {
-    int pin_status = code_value(),
+    int pin_status = code_value_short(),
         pin_number = LED_PIN;
 
     if (code_seen('P') && pin_status >= 0 && pin_status <= 255)
-      pin_number = code_value();
+      pin_number = code_value_short();
 
     for (int8_t i = 0; i < (int8_t)(sizeof(sensitive_pins) / sizeof(*sensitive_pins)); i++) {
       if (sensitive_pins[i] == pin_number) {
@@ -2815,7 +2817,7 @@ inline void gcode_M42() {
     int verbose_level = 1, n_samples = 10, n_legs = 0;
     
     if (code_seen('V') || code_seen('v')) {
-      verbose_level = code_value();
+      verbose_level = code_value_short();
       if (verbose_level < 0 || verbose_level > 4 ) {
         SERIAL_PROTOCOLPGM("?Verbose Level not plausible (0-4).\n");
         return;
@@ -2826,7 +2828,7 @@ inline void gcode_M42() {
       SERIAL_PROTOCOLPGM("M48 Z-Probe Repeatability test\n");
 
     if (code_seen('P') || code_seen('p') || code_seen('n')) { // `n` for legacy support only - please use `P`!
-      n_samples = code_value();
+      n_samples = code_value_short();
       if (n_samples < 4 || n_samples > 50) {
         SERIAL_PROTOCOLPGM("?Sample size not plausible (4-50).\n");
         return;
@@ -2859,7 +2861,7 @@ inline void gcode_M42() {
     }
 
     if (code_seen('L') || code_seen('l')) {
-      n_legs = code_value();
+      n_legs = code_value_short();
       if (n_legs == 1) n_legs = 2;
       if (n_legs < 0 || n_legs > 15) {
         SERIAL_PROTOCOLPGM("?Number of legs in movement not plausible (0-15).\n");
@@ -3041,12 +3043,15 @@ inline void gcode_M42() {
 inline void gcode_M104() {
   if (setTargetedHotend(104)) return;
 
-  if (code_seen('S')) setTargetHotend(code_value(), tmp_extruder);
-  #ifdef DUAL_X_CARRIAGE
-    if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0)
-      setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset);
-  #endif
-  setWatch();
+  if (code_seen('S')) {
+    float temp = code_value();
+    setTargetHotend(temp, target_extruder);
+    #ifdef DUAL_X_CARRIAGE
+      if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0)
+        setTargetHotend1(temp == 0.0 ? 0.0 : temp + duplicate_extruder_temp_offset);
+    #endif
+    setWatch();
+  }
 }
 
 /**
@@ -3057,9 +3062,9 @@ inline void gcode_M105() {
 
   #if HAS_TEMP_0
     SERIAL_PROTOCOLPGM("ok T:");
-    SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1);
+    SERIAL_PROTOCOL_F(degHotend(target_extruder),1);
     SERIAL_PROTOCOLPGM(" /");
-    SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder),1);
+    SERIAL_PROTOCOL_F(degTargetHotend(target_extruder),1);
     #if HAS_TEMP_BED
       SERIAL_PROTOCOLPGM(" B:");
       SERIAL_PROTOCOL_F(degBed(),1);
@@ -3069,7 +3074,7 @@ inline void gcode_M105() {
     for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
       SERIAL_PROTOCOLPGM(" T");
       SERIAL_PROTOCOL(cur_extruder);
-      SERIAL_PROTOCOLPGM(":");
+      SERIAL_PROTOCOLCHAR(':');
       SERIAL_PROTOCOL_F(degHotend(cur_extruder),1);
       SERIAL_PROTOCOLPGM(" /");
       SERIAL_PROTOCOL_F(degTargetHotend(cur_extruder),1);
@@ -3081,16 +3086,16 @@ inline void gcode_M105() {
 
   SERIAL_PROTOCOLPGM(" @:");
   #ifdef EXTRUDER_WATTS
-    SERIAL_PROTOCOL((EXTRUDER_WATTS * getHeaterPower(tmp_extruder))/127);
-    SERIAL_PROTOCOLPGM("W");
+    SERIAL_PROTOCOL((EXTRUDER_WATTS * getHeaterPower(target_extruder))/127);
+    SERIAL_PROTOCOLCHAR('W');
   #else
-    SERIAL_PROTOCOL(getHeaterPower(tmp_extruder));
+    SERIAL_PROTOCOL(getHeaterPower(target_extruder));
   #endif
 
   SERIAL_PROTOCOLPGM(" B@:");
   #ifdef BED_WATTS
     SERIAL_PROTOCOL((BED_WATTS * getHeaterPower(-1))/127);
-    SERIAL_PROTOCOLPGM("W");
+    SERIAL_PROTOCOLCHAR('W');
   #else
     SERIAL_PROTOCOL(getHeaterPower(-1));
   #endif
@@ -3105,7 +3110,7 @@ inline void gcode_M105() {
     for (int8_t cur_extruder = 0; cur_extruder < EXTRUDERS; ++cur_extruder) {
       SERIAL_PROTOCOLPGM("  T");
       SERIAL_PROTOCOL(cur_extruder);
-      SERIAL_PROTOCOLPGM(":");
+      SERIAL_PROTOCOLCHAR(':');
       SERIAL_PROTOCOL_F(degHotend(cur_extruder),1);
       SERIAL_PROTOCOLPGM("C->");
       SERIAL_PROTOCOL_F(rawHotendTemp(cur_extruder)/OVERSAMPLENR,0);
@@ -3120,7 +3125,7 @@ inline void gcode_M105() {
   /**
    * M106: Set Fan Speed
    */
-  inline void gcode_M106() { fanSpeed = code_seen('S') ? constrain(code_value(), 0, 255) : 255; }
+  inline void gcode_M106() { fanSpeed = code_seen('S') ? constrain(code_value_short(), 0, 255) : 255; }
 
   /**
    * M107: Fan Off
@@ -3139,10 +3144,11 @@ inline void gcode_M109() {
 
   CooldownNoWait = code_seen('S');
   if (CooldownNoWait || code_seen('R')) {
-    setTargetHotend(code_value(), tmp_extruder);
+    float temp = code_value();
+    setTargetHotend(temp, target_extruder);
     #ifdef DUAL_X_CARRIAGE
-      if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && tmp_extruder == 0)
-        setTargetHotend1(code_value() == 0.0 ? 0.0 : code_value() + duplicate_extruder_temp_offset);
+      if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && target_extruder == 0)
+        setTargetHotend1(temp == 0.0 ? 0.0 : temp + duplicate_extruder_temp_offset);
     #endif
   }
 
@@ -3158,7 +3164,7 @@ inline void gcode_M109() {
   unsigned long timetemp = millis();
 
   /* See if we are heating up or cooling down */
-  target_direction = isHeatingHotend(tmp_extruder); // true if heating, false if cooling
+  target_direction = isHeatingHotend(target_extruder); // true if heating, false if cooling
 
   cancel_heatup = false;
 
@@ -3169,15 +3175,15 @@ inline void gcode_M109() {
     while((!cancel_heatup)&&((residencyStart == -1) ||
           (residencyStart >= 0 && (((unsigned int) (millis() - residencyStart)) < (TEMP_RESIDENCY_TIME * 1000UL)))) )
   #else
-    while ( target_direction ? (isHeatingHotend(tmp_extruder)) : (isCoolingHotend(tmp_extruder)&&(CooldownNoWait==false)) )
+    while ( target_direction ? (isHeatingHotend(target_extruder)) : (isCoolingHotend(target_extruder)&&(CooldownNoWait==false)) )
   #endif //TEMP_RESIDENCY_TIME
 
     { // while loop
       if (millis() > timetemp + 1000UL) { //Print temp & remaining time every 1s while waiting
         SERIAL_PROTOCOLPGM("T:");
-        SERIAL_PROTOCOL_F(degHotend(tmp_extruder),1);
+        SERIAL_PROTOCOL_F(degHotend(target_extruder),1);
         SERIAL_PROTOCOLPGM(" E:");
-        SERIAL_PROTOCOL((int)tmp_extruder);
+        SERIAL_PROTOCOL((int)target_extruder);
         #ifdef TEMP_RESIDENCY_TIME
           SERIAL_PROTOCOLPGM(" W:");
           if (residencyStart > -1) {
@@ -3198,9 +3204,9 @@ inline void gcode_M109() {
       #ifdef TEMP_RESIDENCY_TIME
         // start/restart the TEMP_RESIDENCY_TIME timer whenever we reach target temp for the first time
         // or when current temp falls outside the hysteresis after target temp was reached
-        if ((residencyStart == -1 &&  target_direction && (degHotend(tmp_extruder) >= (degTargetHotend(tmp_extruder)-TEMP_WINDOW))) ||
-            (residencyStart == -1 && !target_direction && (degHotend(tmp_extruder) <= (degTargetHotend(tmp_extruder)+TEMP_WINDOW))) ||
-            (residencyStart > -1 && labs(degHotend(tmp_extruder) - degTargetHotend(tmp_extruder)) > TEMP_HYSTERESIS) )
+        if ((residencyStart == -1 &&  target_direction && (degHotend(target_extruder) >= (degTargetHotend(target_extruder)-TEMP_WINDOW))) ||
+            (residencyStart == -1 && !target_direction && (degHotend(target_extruder) <= (degTargetHotend(target_extruder)+TEMP_WINDOW))) ||
+            (residencyStart > -1 && labs(degHotend(target_extruder) - degTargetHotend(target_extruder)) > TEMP_HYSTERESIS) )
         {
           residencyStart = millis();
         }
@@ -3538,9 +3544,9 @@ inline void gcode_M121() { enable_endstops(true); }
    */
   inline void gcode_M150() {
     SendColors(
-      code_seen('R') ? (byte)code_value() : 0,
-      code_seen('U') ? (byte)code_value() : 0,
-      code_seen('B') ? (byte)code_value() : 0
+      code_seen('R') ? (byte)code_value_short() : 0,
+      code_seen('U') ? (byte)code_value_short() : 0,
+      code_seen('B') ? (byte)code_value_short() : 0
     );
   }
 
@@ -3552,9 +3558,9 @@ inline void gcode_M121() { enable_endstops(true); }
  *       D<millimeters>
  */
 inline void gcode_M200() {
-  tmp_extruder = active_extruder;
+  int tmp_extruder = active_extruder;
   if (code_seen('T')) {
-    tmp_extruder = code_value();
+    tmp_extruder = code_value_short();
     if (tmp_extruder >= EXTRUDERS) {
       SERIAL_ECHO_START;
       SERIAL_ECHO(MSG_M200_INVALID_EXTRUDER);
@@ -3625,27 +3631,23 @@ inline void gcode_M203() {
  *  Also sets minimum segment time in ms (B20000) to prevent buffer under-runs and M20 minimum feedrate
  */
 inline void gcode_M204() {
-  if (code_seen('S'))   // Kept for legacy compatibility. Should NOT BE USED for new developments.
-  {
+  if (code_seen('S')) {  // Kept for legacy compatibility. Should NOT BE USED for new developments.
     acceleration = code_value();
     travel_acceleration = acceleration;
-    SERIAL_ECHOPAIR("Setting Printing and Travelling Acceleration: ", acceleration );
+    SERIAL_ECHOPAIR("Setting Print and Travel Acceleration: ", acceleration );
     SERIAL_EOL;
   }
-  if (code_seen('P'))
-  {
+  if (code_seen('P')) {
     acceleration = code_value();
-    SERIAL_ECHOPAIR("Setting Printing Acceleration: ", acceleration );
+    SERIAL_ECHOPAIR("Setting Print Acceleration: ", acceleration );
     SERIAL_EOL;
   }
-  if (code_seen('R'))
-  {
+  if (code_seen('R')) {
     retract_acceleration = code_value();
     SERIAL_ECHOPAIR("Setting Retract Acceleration: ", retract_acceleration );
     SERIAL_EOL;
   }
-  if (code_seen('T'))
-  {
+  if (code_seen('T')) {
     travel_acceleration = code_value();
     SERIAL_ECHOPAIR("Setting Travel Acceleration: ", travel_acceleration );
     SERIAL_EOL;
@@ -3748,7 +3750,7 @@ inline void gcode_M206() {
    */
   inline void gcode_M209() {
     if (code_seen('S')) {
-      int t = code_value();
+      int t = code_value_short();
       switch(t) {
         case 0:
           autoretract_enabled = false;
@@ -3777,23 +3779,23 @@ inline void gcode_M206() {
   inline void gcode_M218() {
     if (setTargetedHotend(218)) return;
 
-    if (code_seen('X')) extruder_offset[X_AXIS][tmp_extruder] = code_value();
-    if (code_seen('Y')) extruder_offset[Y_AXIS][tmp_extruder] = code_value();
+    if (code_seen('X')) extruder_offset[X_AXIS][target_extruder] = code_value();
+    if (code_seen('Y')) extruder_offset[Y_AXIS][target_extruder] = code_value();
 
     #ifdef DUAL_X_CARRIAGE
-      if (code_seen('Z')) extruder_offset[Z_AXIS][tmp_extruder] = code_value();
+      if (code_seen('Z')) extruder_offset[Z_AXIS][target_extruder] = code_value();
     #endif
 
     SERIAL_ECHO_START;
     SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
-    for (tmp_extruder = 0; tmp_extruder < EXTRUDERS; tmp_extruder++) {
-      SERIAL_ECHO(" ");
-      SERIAL_ECHO(extruder_offset[X_AXIS][tmp_extruder]);
-      SERIAL_ECHO(",");
-      SERIAL_ECHO(extruder_offset[Y_AXIS][tmp_extruder]);
+    for (int e = 0; e < EXTRUDERS; e++) {
+      SERIAL_CHAR(' ');
+      SERIAL_ECHO(extruder_offset[X_AXIS][e]);
+      SERIAL_CHAR(',');
+      SERIAL_ECHO(extruder_offset[Y_AXIS][e]);
       #ifdef DUAL_X_CARRIAGE
-        SERIAL_ECHO(",");
-        SERIAL_ECHO(extruder_offset[Z_AXIS][tmp_extruder]);
+        SERIAL_CHAR(',');
+        SERIAL_ECHO(extruder_offset[Z_AXIS][e]);
       #endif
     }
     SERIAL_EOL;
@@ -3816,7 +3818,7 @@ inline void gcode_M221() {
     int sval = code_value();
     if (code_seen('T')) {
       if (setTargetedHotend(221)) return;
-      extruder_multiply[tmp_extruder] = sval;
+      extruder_multiply[target_extruder] = sval;
     }
     else {
       extruder_multiply[active_extruder] = sval;
@@ -4047,7 +4049,7 @@ inline void gcode_M226() {
    * M250: Read and optionally set the LCD contrast
    */
   inline void gcode_M250() {
-    if (code_seen('C')) lcd_setcontrast(code_value_long() & 0x3F);
+    if (code_seen('C')) lcd_setcontrast(code_value_short() & 0x3F);
     SERIAL_PROTOCOLPGM("lcd contrast value: ");
     SERIAL_PROTOCOL(lcd_contrast);
     SERIAL_PROTOCOLLN("");
@@ -4073,8 +4075,8 @@ inline void gcode_M226() {
  *       C<cycles>
  */
 inline void gcode_M303() {
-  int e = code_seen('E') ? code_value_long() : 0;
-  int c = code_seen('C') ? code_value_long() : 5;
+  int e = code_seen('E') ? code_value_short() : 0;
+  int c = code_seen('C') ? code_value_short() : 5;
   float temp = code_seen('S') ? code_value() : (e < 0 ? 70.0 : 150.0);
   PID_autotune(temp, e, c);
 }
@@ -4483,13 +4485,13 @@ inline void gcode_M503() {
         if (code_seen('R')) duplicate_extruder_temp_offset = code_value();
         SERIAL_ECHO_START;
         SERIAL_ECHOPGM(MSG_HOTEND_OFFSET);
-        SERIAL_ECHO(" ");
+        SERIAL_CHAR(' ');
         SERIAL_ECHO(extruder_offset[X_AXIS][0]);
-        SERIAL_ECHO(",");
+        SERIAL_CHAR(',');
         SERIAL_ECHO(extruder_offset[Y_AXIS][0]);
-        SERIAL_ECHO(" ");
+        SERIAL_CHAR(' ');
         SERIAL_ECHO(duplicate_extruder_x_offset);
-        SERIAL_ECHO(",");
+        SERIAL_CHAR(',');
         SERIAL_ECHOLN(extruder_offset[Y_AXIS][1]);
         break;
       case DXC_FULL_CONTROL_MODE:
@@ -4562,7 +4564,7 @@ inline void gcode_M907() {
    *       S# determines MS1 or MS2, X# sets the pin high/low.
    */
   inline void gcode_M351() {
-    if (code_seen('S')) switch(code_value_long()) {
+    if (code_seen('S')) switch(code_value_short()) {
       case 1:
         for(int i=0;i<NUM_AXIS;i++) if (code_seen(axis_codes[i])) microstep_ms(i, code_value(), -1);
         if (code_seen('B')) microstep_ms(4, code_value(), -1);
@@ -4588,21 +4590,26 @@ inline void gcode_M999() {
 }
 
 inline void gcode_T() {
-  tmp_extruder = code_value();
+  int tmp_extruder = code_value();
   if (tmp_extruder >= EXTRUDERS) {
     SERIAL_ECHO_START;
-    SERIAL_ECHO("T");
+    SERIAL_CHAR('T');
     SERIAL_ECHO(tmp_extruder);
     SERIAL_ECHOLN(MSG_INVALID_EXTRUDER);
   }
   else {
+    target_extruder = tmp_extruder;
+
     #if EXTRUDERS > 1
       bool make_move = false;
     #endif
+
     if (code_seen('F')) {
+
       #if EXTRUDERS > 1
         make_move = true;
       #endif
+
       next_feedrate = code_value();
       if (next_feedrate > 0.0) feedrate = next_feedrate;
     }
@@ -4692,7 +4699,7 @@ inline void gcode_T() {
 void process_commands() {
   if (code_seen('G')) {
 
-    int gCode = code_value_long();
+    int gCode = code_value_short();
 
     switch(gCode) {
 
@@ -4767,7 +4774,7 @@ void process_commands() {
   }
 
   else if (code_seen('M')) {
-    switch( code_value_long() ) {
+    switch(code_value_short()) {
       #ifdef ULTIPANEL
         case 0: // M0 - Unconditional stop - Wait for user button press on LCD
         case 1: // M1 - Conditional stop - Wait for user button press on LCD
@@ -5922,10 +5929,10 @@ void setPwmFrequency(uint8_t pin, int val)
 #endif //FAST_PWM_FAN
 
 bool setTargetedHotend(int code){
-  tmp_extruder = active_extruder;
-  if(code_seen('T')) {
-    tmp_extruder = code_value();
-    if(tmp_extruder >= EXTRUDERS) {
+  target_extruder = active_extruder;
+  if (code_seen('T')) {
+    target_extruder = code_value_short();
+    if (target_extruder >= EXTRUDERS) {
       SERIAL_ECHO_START;
       switch(code){
         case 104:
@@ -5944,7 +5951,7 @@ bool setTargetedHotend(int code){
           SERIAL_ECHO(MSG_M221_INVALID_EXTRUDER);
           break;
       }
-      SERIAL_ECHOLN(tmp_extruder);
+      SERIAL_ECHOLN(target_extruder);
       return true;
     }
   }
diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp
index fae6c1be690..877b72b9277 100644
--- a/Marlin/cardreader.cpp
+++ b/Marlin/cardreader.cpp
@@ -249,7 +249,7 @@ void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/)
         if (!myDir.open(curDir, subdirname, O_READ)) {
           SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
           SERIAL_PROTOCOL(subdirname);
-          SERIAL_PROTOCOLLNPGM(".");
+          SERIAL_PROTOCOLCHAR('.');
           return;
         }
         else {
@@ -287,14 +287,14 @@ void CardReader::openFile(char* name, bool read, bool replace_current/*=true*/)
     else {
       SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
       SERIAL_PROTOCOL(fname);
-      SERIAL_PROTOCOLLNPGM(".");
+      SERIAL_PROTOCOLCHAR('.');
     }
   }
   else { //write
     if (!file.open(curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
       SERIAL_PROTOCOLPGM(MSG_SD_OPEN_FILE_FAIL);
       SERIAL_PROTOCOL(fname);
-      SERIAL_PROTOCOLLNPGM(".");
+      SERIAL_PROTOCOLCHAR('.');
     }
     else {
       saving = true;
@@ -330,7 +330,7 @@ void CardReader::removeFile(char* name) {
         if (!myDir.open(curDir, subdirname, O_READ)) {
           SERIAL_PROTOCOLPGM("open failed, File: ");
           SERIAL_PROTOCOL(subdirname);
-          SERIAL_PROTOCOLLNPGM(".");
+          SERIAL_PROTOCOLCHAR('.');
           return;
         }
         else {
@@ -360,7 +360,7 @@ void CardReader::removeFile(char* name) {
   else {
     SERIAL_PROTOCOLPGM("Deletion failed, File: ");
     SERIAL_PROTOCOL(fname);
-    SERIAL_PROTOCOLLNPGM(".");
+    SERIAL_PROTOCOLCHAR('.');
   }
 }
 
@@ -368,7 +368,7 @@ void CardReader::getStatus() {
   if (cardOK) {
     SERIAL_PROTOCOLPGM(MSG_SD_PRINTING_BYTE);
     SERIAL_PROTOCOL(sdpos);
-    SERIAL_PROTOCOLPGM("/");
+    SERIAL_PROTOCOLCHAR('/');
     SERIAL_PROTOCOLLN(filesize);
   }
   else {
diff --git a/Marlin/vector_3.cpp b/Marlin/vector_3.cpp
index 243f0838f00..9eb3465fbf3 100644
--- a/Marlin/vector_3.cpp
+++ b/Marlin/vector_3.cpp
@@ -125,9 +125,9 @@ void matrix_3x3::debug(const char title[]) {
   int count = 0;
   for(int i=0; i<3; i++) {
     for(int j=0; j<3; j++) {
-      if (matrix[count] >= 0.0) SERIAL_PROTOCOLPGM("+");
+      if (matrix[count] >= 0.0) SERIAL_PROTOCOLCHAR('+');
       SERIAL_PROTOCOL_F(matrix[count], 6);
-      SERIAL_PROTOCOLPGM(" ");
+      SERIAL_PROTOCOLCHAR(' ');
       count++;
     }
     SERIAL_EOL;

From fc3c76fc1641370ee76a564299592e283cbcd0c0 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 22:04:42 -0700
Subject: [PATCH 56/83] Fix #1800

---
 Marlin/temperature.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index c0e427a6557..0cddd087849 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -84,7 +84,7 @@ unsigned char soft_pwm_bed;
     static unsigned long thermal_runaway_timer[4]; // = {0,0,0,0};
   #endif
   #if HAS_BED_THERMAL_PROTECTION
-    static TRState thermal_runaway_bed_state_machine = { TRInactive, TRInactive, TRInactive, TRInactive };
+    static TRState thermal_runaway_bed_state_machine = TRInactive;
     static unsigned long thermal_runaway_bed_timer;
   #endif
 #endif

From a6ba40ae487d6b204690a7ac967debb1f2c8eb1a Mon Sep 17 00:00:00 2001
From: Natealus <natealus@hotmail.com>
Date: Fri, 3 Apr 2015 23:09:31 -0600
Subject: [PATCH 57/83] Compiling error temperature.cpp with multiple extruders
 defined

It wouldn't compile because of this line in temperature.cpp it turns out
it was just a stray ( that didn't line up with the previous lines so I
just made it in line with the rest and it compiled fine.
---
 Marlin/temperature.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index c0e427a6557..ddd9ae3b948 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1556,7 +1556,7 @@ ISR(TIMER0_COMPB_vect) {
       #else
         #define GE2 >=
       #endif
-      if (current_temperature_raw[2] GE2 (maxttemp_raw[2]) max_temp_error(2);
+      if (current_temperature_raw[2] GE2 maxttemp_raw[2]) max_temp_error(2);
       if (minttemp_raw[2] GE2 current_temperature_raw[2]) min_temp_error(2);
     #endif // TEMP_SENSOR_2
 

From 8680b515b00ab4bccb07883ba0be65f960a06973 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 22:12:49 -0700
Subject: [PATCH 58/83] Fix missing tmp_extruder -> target_extruder

---
 Marlin/Marlin_main.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index ba37b42e912..d67f65367c3 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3059,9 +3059,9 @@ inline void gcode_M105() {
     SERIAL_PROTOCOLPGM("ok");
     #if HAS_TEMP_0
       SERIAL_PROTOCOLPGM(" T:");
-      SERIAL_PROTOCOL_F(degHotend(tmp_extruder), 1);
+      SERIAL_PROTOCOL_F(degHotend(target_extruder), 1);
       SERIAL_PROTOCOLPGM(" /");
-      SERIAL_PROTOCOL_F(degTargetHotend(tmp_extruder), 1);
+      SERIAL_PROTOCOL_F(degTargetHotend(target_extruder), 1);
     #endif
     #if HAS_TEMP_BED
       SERIAL_PROTOCOLPGM(" B:");

From ab11f90da0284686a1c6de5cf26357e0c53391ab Mon Sep 17 00:00:00 2001
From: Natealus <natealus@hotmail.com>
Date: Fri, 3 Apr 2015 23:14:03 -0600
Subject: [PATCH 59/83] Z_PROBE_ENDSTOP Pin for Azteeg X3 Pro

Just a simple #ifdef Z_PROBE_ENDSTOP to define the pin for it. Also has
a couple commented lines for switching Z_MIN_PIN if needed.
---
 Marlin/pins_AZTEEG_X3_PRO.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Marlin/pins_AZTEEG_X3_PRO.h b/Marlin/pins_AZTEEG_X3_PRO.h
index 0cdc7160107..d76874a09ac 100644
--- a/Marlin/pins_AZTEEG_X3_PRO.h
+++ b/Marlin/pins_AZTEEG_X3_PRO.h
@@ -34,7 +34,12 @@
   #define Z_MAX_PIN          18
  #endif
 //
-
+ #ifdef Z_PROBE_ENDSTOP
+//#undef Z_MIN_PIN
+//#define Z_MIN_PIN        15
+  #define Z_PROBE_PIN      19
+ #endif
+//
 #define E2_STEP_PIN        23
 #define E2_DIR_PIN         25
 #define E2_ENABLE_PIN      40

From c065da52ec81ea66b0d62a282474db195bc38e18 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 22:54:48 -0700
Subject: [PATCH 60/83] Spacing and spelling

---
 Marlin/Configuration.h                                 |  2 +-
 Marlin/MarlinSerial.cpp                                |  5 ++---
 Marlin/MarlinSerial.h                                  |  4 ++--
 Marlin/Marlin_main.cpp                                 |  6 +++---
 Marlin/SanityCheck.h                                   |  2 +-
 Marlin/Servo.h                                         |  2 +-
 Marlin/configurator/config/Configuration.h             |  2 +-
 Marlin/example_configurations/Felix/Configuration.h    |  2 +-
 .../example_configurations/Felix/Configuration_DUAL.h  |  2 +-
 .../example_configurations/Hephestos/Configuration.h   |  2 +-
 Marlin/example_configurations/K8200/Configuration.h    |  2 +-
 Marlin/example_configurations/SCARA/Configuration.h    |  2 +-
 Marlin/example_configurations/WITBOX/Configuration.h   |  2 +-
 .../delta/generic/Configuration.h                      |  2 +-
 .../delta/kossel_mini/Configuration.h                  |  2 +-
 Marlin/example_configurations/makibox/Configuration.h  |  2 +-
 .../tvrrug/Round2/Configuration.h                      |  2 +-
 Marlin/fastio.h                                        | 10 +++++-----
 Marlin/pins.h                                          |  9 ++++++---
 Marlin/pins_RAMPS_13.h                                 |  6 +++---
 20 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 5d9586808a7..8d3e75dae9b 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -503,7 +503,7 @@ const bool Z_PROBE_ENDSTOP_INVERTING = false; // set to true to invert the logic
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp
index fcba93256bc..dc36e14c6c9 100644
--- a/Marlin/MarlinSerial.cpp
+++ b/Marlin/MarlinSerial.cpp
@@ -287,7 +287,6 @@ MarlinSerial MSerial;
 #endif // !AT90USB
 
 // For AT90USB targets use the UART for BT interfacing
-#if defined(AT90USB) && defined (BTENABLED)
-   HardwareSerial bt;
+#if defined(AT90USB) && defined(BTENABLED)
+  HardwareSerial bt;
 #endif
-
diff --git a/Marlin/MarlinSerial.h b/Marlin/MarlinSerial.h
index b56880c23f6..dbad3fd7626 100644
--- a/Marlin/MarlinSerial.h
+++ b/Marlin/MarlinSerial.h
@@ -153,8 +153,8 @@ extern MarlinSerial MSerial;
 #endif // !AT90USB
 
 // Use the UART for BT in AT90USB configurations
-#if defined(AT90USB) && defined (BTENABLED)
-   extern HardwareSerial bt;
+#if defined(AT90USB) && defined(BTENABLED)
+  extern HardwareSerial bt;
 #endif
 
 #endif
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index d67f65367c3..d0b959cd79a 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2776,13 +2776,13 @@ inline void gcode_M42() {
 
 #if defined(ENABLE_AUTO_BED_LEVELING) && defined(Z_PROBE_REPEATABILITY_TEST)
 
-  // This is redudant since the SanityCheck.h already checks for a valid Z_PROBE_PIN, but here for clarity.
+  // This is redundant since the SanityCheck.h already checks for a valid Z_PROBE_PIN, but here for clarity.
   #ifdef Z_PROBE_ENDSTOP
     #if !HAS_Z_PROBE
-      #error "You must have a Z_PROBE_PIN defined in order to enable calculation of Z-Probe repeatability."
+      #error You must define Z_PROBE_PIN to enable Z-Probe repeatability calculation.
     #endif
   #elif !HAS_Z_MIN
-    #error "You must have a Z_MIN_PIN defined in order to enable calculation of Z-Probe repeatability."
+    #error You must define Z_MIN_PIN to enable Z-Probe repeatability calculation.
   #endif
 
   /**
diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index c7552b9c0d5..d92938c1d35 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -100,7 +100,7 @@
      * Require a Z Min pin
      */
     #if Z_MIN_PIN == -1
-      #if Z_PROBE_PIN == -1 || (! defined (Z_PROBE_ENDSTOP) || defined (DISABLE_Z_PROBE_ENDSTOP)) // It's possible for someone to set a pin for the Z Probe, but not enable it.
+      #if Z_PROBE_PIN == -1 || (!defined(Z_PROBE_ENDSTOP) || defined(DISABLE_Z_PROBE_ENDSTOP)) // It's possible for someone to set a pin for the Z Probe, but not enable it.
         #ifdef Z_PROBE_REPEATABILITY_TEST
           #error You must have a Z_MIN or Z_PROBE endstop to enable Z_PROBE_REPEATABILITY_TEST.
         #else
diff --git a/Marlin/Servo.h b/Marlin/Servo.h
index bbdf6bf0ab0..682a3b37981 100644
--- a/Marlin/Servo.h
+++ b/Marlin/Servo.h
@@ -123,7 +123,7 @@ class Servo {
     int read();                        // returns current pulse width as an angle between 0 and 180 degrees
     int readMicroseconds();            // returns current pulse width in microseconds for this servo (was read_us() in first release)
     bool attached();                   // return true if this servo is attached, otherwise false
-    #if defined (ENABLE_AUTO_BED_LEVELING) && (PROBE_SERVO_DEACTIVATION_DELAY > 0)
+    #if defined(ENABLE_AUTO_BED_LEVELING) && PROBE_SERVO_DEACTIVATION_DELAY > 0
       int pin;                           // store the hardware pin of the servo
     #endif
   private:
diff --git a/Marlin/configurator/config/Configuration.h b/Marlin/configurator/config/Configuration.h
index ca0b2d0791e..5b0960fdd42 100644
--- a/Marlin/configurator/config/Configuration.h
+++ b/Marlin/configurator/config/Configuration.h
@@ -523,7 +523,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index dfd79a0d971..72d716989be 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -473,7 +473,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/Felix/Configuration_DUAL.h b/Marlin/example_configurations/Felix/Configuration_DUAL.h
index 98dea404bf0..e6683b4e811 100644
--- a/Marlin/example_configurations/Felix/Configuration_DUAL.h
+++ b/Marlin/example_configurations/Felix/Configuration_DUAL.h
@@ -473,7 +473,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index 7eceefb9869..ac101be4d36 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -496,7 +496,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index 3a6aea9b1dd..6d743e9379b 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -501,7 +501,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index 2616f155fd1..f126ab99bc1 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -525,7 +525,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index d7d32d0881a..265f73fce15 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -495,7 +495,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index ac13788b22d..3218d2d9d75 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -541,7 +541,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index 38f5023552b..489dca6d58a 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -545,7 +545,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = false; // set to true to invert the logic o
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index 24c3e5b4d8a..45350960f8c 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -493,7 +493,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index 649046b880c..2c98a310fb4 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -495,7 +495,7 @@ const bool Z_MAX_ENDSTOP_INVERTING = true; // set to true to invert the logic of
   // If you would like to use both a Z PROBE and a Z MIN endstop together or just a Z PROBE with a custom pin, uncomment #define Z_PROBE_ENDSTOP and read the instructions below.
   // If you want to still use the Z min endstop for homing, disable Z_SAFE_HOMING above. Eg; to park the head outside the bed area when homing with G28.
   // WARNING: The Z MIN endstop will need to set properly as it would without a Z PROBE to prevent head crashes and premature stopping during a print.
-  // To use a separte Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
+  // To use a separate Z PROBE endstop, you must have a Z_PROBE_PIN defined in the pins.h file for your control board.
   // If you are using a servo based Z PROBE, you will need to enable NUM_SERVOS, SERVO_ENDSTOPS and SERVO_ENDSTOPS_ANGLES in the R/C Servo below.
   // RAMPS 1.3/1.4 boards may be able to use the 5V, Ground and the D32 pin in the Aux 4 section of the RAMPS board. Use 5V for powered sensors, otherwise connect to ground and D32
   // for normally closed configuration and 5V and D32 for normally open configurations. Normally closed configuration is advised and assumed.
diff --git a/Marlin/fastio.h b/Marlin/fastio.h
index 3087e87f2a3..0e3b34d2551 100644
--- a/Marlin/fastio.h
+++ b/Marlin/fastio.h
@@ -91,7 +91,7 @@
 	added as necessary or if I feel like it- not a comprehensive list!
 */
 
-#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega328P__)
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
 // UART
 #define	RXD					DIO0
 #define	TXD					DIO1
@@ -426,7 +426,7 @@ pins
 #define PD7_PWM			NULL
 #endif	/*	_AVR_ATmega{168,328,328P}__ */
 
-#if defined (__AVR_ATmega644__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || defined (__AVR_ATmega1284P__)
+#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
 // UART
 #define	RXD					DIO8
 #define	TXD					DIO9
@@ -929,7 +929,7 @@ pins
 #define PD7_PWM			OCR2A
 #endif	/*	_AVR_ATmega{644,644P,644PA}__ */
 
-#if defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
+#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
 // UART
 #define	RXD					DIO0
 #define	TXD					DIO1
@@ -2024,7 +2024,7 @@ pins
 
 #endif
 
-#if defined (__AVR_AT90USB1287__) || defined (__AVR_AT90USB1286__) || defined (__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
+#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
 // SPI
 #define	SCK					DIO9
 #define	MISO				DIO11
@@ -3322,7 +3322,7 @@ Teensy   28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17
 #endif // __AVR_AT90usbxxx__
 
 
-#if defined (__AVR_ATmega1281__) || defined (__AVR_ATmega2561__)
+#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
 // UART
 #define	RXD					DIO0
 #define	TXD					DIO1
diff --git a/Marlin/pins.h b/Marlin/pins.h
index 0d63298869a..0d9ae221c53 100644
--- a/Marlin/pins.h
+++ b/Marlin/pins.h
@@ -187,7 +187,7 @@
   #define Z_MIN_PIN          -1
 #endif
 
-#if defined (DISABLE_Z_PROBE_ENDSTOP) || ! defined (Z_PROBE_ENDSTOP) // Allow code to compile regardless of Z_PROBE_ENDSTOP setting.
+#if defined(DISABLE_Z_PROBE_ENDSTOP) || !defined(Z_PROBE_ENDSTOP) // Allow code to compile regardless of Z_PROBE_ENDSTOP setting.
   #define Z_PROBE_PIN        -1
 #endif
 
@@ -220,8 +220,11 @@
   #define Z_MIN_PIN          -1
 #endif
 
-#define SENSITIVE_PINS { 0, 1, X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, Z_PROBE_PIN, PS_ON_PIN, \
-                        HEATER_BED_PIN, FAN_PIN, \
+#define SENSITIVE_PINS { 0, 1,
+                        X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, \
+                        Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, \
+                        Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, Z_PROBE_PIN, \
+                        PS_ON_PIN, HEATER_BED_PIN, FAN_PIN, \
                         _E0_PINS _E1_PINS _E2_PINS _E3_PINS \
                         analogInputToDigitalPin(TEMP_BED_PIN) \
                        }
diff --git a/Marlin/pins_RAMPS_13.h b/Marlin/pins_RAMPS_13.h
index 11ecddeda2a..2708117d04d 100644
--- a/Marlin/pins_RAMPS_13.h
+++ b/Marlin/pins_RAMPS_13.h
@@ -62,12 +62,12 @@
   #define FILWIDTH_PIN        5
 #endif
 
-#if defined(Z_PROBE_ENDSTOP)
+#ifdef Z_PROBE_ENDSTOP
   // Define a pin to use as the signal pin on Arduino for the Z_PROBE endstop.
- #define Z_PROBE_PIN 32
+  #define Z_PROBE_PIN 32
 #endif
 
-#if defined(FILAMENT_RUNOUT_SENSOR)
+#ifdef FILAMENT_RUNOUT_SENSOR
   // define digital pin 4 for the filament runout sensor. Use the RAMPS 1.4 digital input 4 on the servos connector
   #define FILRUNOUT_PIN        4
 #endif

From 09350841416fdf32c3486258242c35d703db0861 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Fri, 3 Apr 2015 23:42:50 -0700
Subject: [PATCH 61/83] Fix manage_inactivity

- Document `manage_inactivity` function
- Allow `EXTRUDER_RUNOUT_PREVENT` to work with all extruders
- Use faster `memcpy` for copying coordinates
---
 Marlin/Marlin_main.cpp | 195 ++++++++++++++++++++++++-----------------
 1 file changed, 117 insertions(+), 78 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index d0b959cd79a..29ac686ef54 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1009,6 +1009,8 @@ inline void sync_plan_position() {
     plan_set_position(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], current_position[E_AXIS]);
   }
 #endif
+inline void set_current_to_destination() { memcpy(current_position, destination, sizeof(current_position)); }
+inline void set_destination_to_current() { memcpy(destination, current_position, sizeof(destination)); }
 
 #ifdef ENABLE_AUTO_BED_LEVELING
 
@@ -1020,7 +1022,7 @@ inline void sync_plan_position() {
       refresh_cmd_timeout();
       calculate_delta(destination);
       plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
-      for (int i = 0; i < NUM_AXIS; i++) current_position[i] = destination[i];
+      set_current_to_destination();
     }
   #endif
 
@@ -1564,7 +1566,7 @@ static void homeaxis(int axis) {
 
     float oldFeedrate = feedrate;
 
-    for (int i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i];
+    set_destination_to_current();
 
     if (retracting) {
 
@@ -1769,7 +1771,7 @@ inline void gcode_G28() {
 
   enable_endstops(true);
 
-  for (int i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i]; // includes E_AXIS
+  set_destination_to_current();
 
   feedrate = 0.0;
 
@@ -1997,7 +1999,7 @@ inline void gcode_G28() {
     if (mbl_was_active) {
       current_position[X_AXIS] = mbl.get_x(0);
       current_position[Y_AXIS] = mbl.get_y(0);
-      for (int i = 0; i < NUM_AXIS; i++) destination[i] = current_position[i];
+      set_destination_to_current();
       feedrate = homing_feedrate[X_AXIS];
       line_to_destination();
       st_synchronize();
@@ -4613,7 +4615,7 @@ inline void gcode_T() {
     #if EXTRUDERS > 1
       if (tmp_extruder != active_extruder) {
         // Save current position to return to after applying extruder offset
-        memcpy(destination, current_position, sizeof(destination));
+        set_destination_to_current();
         #ifdef DUAL_X_CARRIAGE
           if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE && Stopped == false &&
                 (delayed_move_time != 0 || current_position[X_AXIS] != x_home_pos(active_extruder))) {
@@ -5338,9 +5340,7 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
 {
   if (!mbl.active) {
     plan_buffer_line(x, y, z, e, feed_rate, extruder);
-    for(int8_t i=0; i < NUM_AXIS; i++) {
-      current_position[i] = destination[i];
-    }
+    set_current_to_destination();
     return;
   }
   int pix = mbl.select_x_index(current_position[X_AXIS]);
@@ -5354,9 +5354,7 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
   if (pix == ix && piy == iy) {
     // Start and end on same mesh square
     plan_buffer_line(x, y, z, e, feed_rate, extruder);
-    for(int8_t i=0; i < NUM_AXIS; i++) {
-      current_position[i] = destination[i];
-    }
+    set_current_to_destination();
     return;
   }
   float nx, ny, ne, normalized_dist;
@@ -5387,9 +5385,7 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
   } else {
     // Already split on a border
     plan_buffer_line(x, y, z, e, feed_rate, extruder);
-    for(int8_t i=0; i < NUM_AXIS; i++) {
-      current_position[i] = destination[i];
-    }
+    set_current_to_destination();
     return;
   }
   // Do the split and look for more borders
@@ -5477,64 +5473,58 @@ void prepare_move() {
 
   #endif // DELTA
 
-#ifdef DUAL_X_CARRIAGE
-  if (active_extruder_parked)
-  {
-    if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0)
-    {
-      // move duplicate extruder into correct duplication position.
-      plan_set_position(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
-      plan_buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset, current_position[Y_AXIS], current_position[Z_AXIS],
-          current_position[E_AXIS], max_feedrate[X_AXIS], 1);
-      sync_plan_position();
-      st_synchronize();
-      extruder_duplication_enabled = true;
-      active_extruder_parked = false;
-    }
-    else if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE) // handle unparking of head
-    {
-      if (current_position[E_AXIS] == destination[E_AXIS])
-      {
-        // this is a travel move - skit it but keep track of current position (so that it can later
-        // be used as start of first non-travel move)
-        if (delayed_move_time != 0xFFFFFFFFUL)
-        {
-          memcpy(current_position, destination, sizeof(current_position));
-          if (destination[Z_AXIS] > raised_parked_position[Z_AXIS])
-            raised_parked_position[Z_AXIS] = destination[Z_AXIS];
-          delayed_move_time = millis();
-          return;
-        }
+  #ifdef DUAL_X_CARRIAGE
+    if (active_extruder_parked) {
+      if (dual_x_carriage_mode == DXC_DUPLICATION_MODE && active_extruder == 0) {
+        // move duplicate extruder into correct duplication position.
+        plan_set_position(inactive_extruder_x_pos, current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS]);
+        plan_buffer_line(current_position[X_AXIS] + duplicate_extruder_x_offset, current_position[Y_AXIS], current_position[Z_AXIS],
+            current_position[E_AXIS], max_feedrate[X_AXIS], 1);
+        sync_plan_position();
+        st_synchronize();
+        extruder_duplication_enabled = true;
+        active_extruder_parked = false;
+      }
+      else if (dual_x_carriage_mode == DXC_AUTO_PARK_MODE) { // handle unparking of head
+        if (current_position[E_AXIS] == destination[E_AXIS]) {
+          // this is a travel move - skit it but keep track of current position (so that it can later
+          // be used as start of first non-travel move)
+          if (delayed_move_time != 0xFFFFFFFFUL) {
+            set_current_to_destination();
+            if (destination[Z_AXIS] > raised_parked_position[Z_AXIS])
+              raised_parked_position[Z_AXIS] = destination[Z_AXIS];
+            delayed_move_time = millis();
+            return;
+          }
+        }
+        delayed_move_time = 0;
+        // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
+        plan_buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS],    current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder);
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS],
+            current_position[E_AXIS], min(max_feedrate[X_AXIS],max_feedrate[Y_AXIS]), active_extruder);
+        plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS],
+            current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder);
+        active_extruder_parked = false;
       }
-      delayed_move_time = 0;
-      // unpark extruder: 1) raise, 2) move into starting XY position, 3) lower
-      plan_buffer_line(raised_parked_position[X_AXIS], raised_parked_position[Y_AXIS], raised_parked_position[Z_AXIS],    current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder);
-      plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], raised_parked_position[Z_AXIS],
-          current_position[E_AXIS], min(max_feedrate[X_AXIS],max_feedrate[Y_AXIS]), active_extruder);
-      plan_buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS],
-          current_position[E_AXIS], max_feedrate[Z_AXIS], active_extruder);
-      active_extruder_parked = false;
     }
-  }
-#endif //DUAL_X_CARRIAGE
+  #endif // DUAL_X_CARRIAGE
 
-#if !defined(DELTA) && !defined(SCARA)
-  // Do not use feedmultiply for E or Z only moves
-  if( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
-    line_to_destination();
-  } else {
-#ifdef MESH_BED_LEVELING
-    mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
-    return;
-#else
-    plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
-#endif  // MESH_BED_LEVELING
-  }
-#endif // !(DELTA || SCARA)
+  #if !defined(DELTA) && !defined(SCARA)
+    // Do not use feedmultiply for E or Z only moves
+    if ( (current_position[X_AXIS] == destination [X_AXIS]) && (current_position[Y_AXIS] == destination [Y_AXIS])) {
+      line_to_destination();
+    }
+    else {
+      #ifdef MESH_BED_LEVELING
+        mesh_plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
+        return;
+      #else
+        plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS], (feedrate/60)*(feedmultiply/100.0), active_extruder);
+      #endif  // MESH_BED_LEVELING
+    }
+  #endif // !(DELTA || SCARA)
 
-  for(int8_t i=0; i < NUM_AXIS; i++) {
-    current_position[i] = destination[i];
-  }
+  set_current_to_destination();
 }
 
 void prepare_arc_move(char isclockwise) {
@@ -5546,9 +5536,7 @@ void prepare_arc_move(char isclockwise) {
   // As far as the parser is concerned, the position is now == target. In reality the
   // motion control system might still be processing the action and the real tool position
   // in any intermediate location.
-  for(int8_t i=0; i < NUM_AXIS; i++) {
-    current_position[i] = destination[i];
-  }
+  set_current_to_destination();
   refresh_cmd_timeout();
 }
 
@@ -5718,7 +5706,16 @@ void disable_all_steppers() {
 }
 
 /**
- * 
+ * Manage several activities:
+ *  - Check for Filament Runout
+ *  - Keep the command buffer full
+ *  - Check for maximum inactive time between commands
+ *  - Check for maximum inactive time between stepper commands
+ *  - Check if pin CHDK needs to go LOW
+ *  - Check for KILL button held down
+ *  - Check for HOME button held down
+ *  - Check if cooling fan needs to be switched on
+ *  - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
  */
 void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
   
@@ -5737,7 +5734,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
       && !ignore_stepper_queue && !blocks_queued())
     disable_all_steppers();
 
-  #ifdef CHDK //Check if pin should be set to LOW after M240 set it to HIGH
+  #ifdef CHDK // Check if pin should be set to LOW after M240 set it to HIGH
     if (chdkActive && ms > chdkHigh + CHDK_DELAY) {
       chdkActive = false;
       WRITE(CHDK, LOW);
@@ -5780,14 +5777,37 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
   #endif
     
   #if HAS_CONTROLLERFAN
-    controllerFan(); //Check if fan should be turned on to cool stepper drivers down
+    controllerFan(); // Check if fan should be turned on to cool stepper drivers down
   #endif
 
   #ifdef EXTRUDER_RUNOUT_PREVENT
     if (ms > previous_millis_cmd + EXTRUDER_RUNOUT_SECONDS * 1000)
     if (degHotend(active_extruder) > EXTRUDER_RUNOUT_MINTEMP) {
-      bool oldstatus = E0_ENABLE_READ;
-      enable_e0();
+      bool oldstatus;
+      switch(active_extruder) {
+        case 0:
+          oldstatus = E0_ENABLE_READ;
+          enable_e0();
+          break;
+        #if EXTRUDERS > 1
+          case 1:
+            oldstatus = E1_ENABLE_READ;
+            enable_e1();
+            break;
+          #if EXTRUDERS > 2
+            case 2:
+              oldstatus = E2_ENABLE_READ;
+              enable_e2();
+              break;
+            #if EXTRUDERS > 3
+              case 3:
+                oldstatus = E3_ENABLE_READ;
+                enable_e3();
+                break;
+            #endif
+          #endif
+        #endif
+      }
       float oldepos = current_position[E_AXIS], oldedes = destination[E_AXIS];
       plan_buffer_line(destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS],
                       destination[E_AXIS] + EXTRUDER_RUNOUT_EXTRUDE * EXTRUDER_RUNOUT_ESTEPS / axis_steps_per_unit[E_AXIS],
@@ -5797,7 +5817,26 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
       plan_set_e_position(oldepos);
       previous_millis_cmd = ms; // refresh_cmd_timeout()
       st_synchronize();
-      E0_ENABLE_WRITE(oldstatus);
+      switch(active_extruder) {
+        case 0:
+          E0_ENABLE_WRITE(oldstatus);
+          break;
+        #if EXTRUDERS > 1
+          case 1:
+            E1_ENABLE_WRITE(oldstatus);
+            break;
+          #if EXTRUDERS > 2
+            case 2:
+              E2_ENABLE_WRITE(oldstatus);
+              break;
+            #if EXTRUDERS > 3
+              case 3:
+                E3_ENABLE_WRITE(oldstatus);
+                break;
+            #endif
+          #endif
+        #endif
+      }
     }
   #endif
 
@@ -5806,7 +5845,7 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
     if (delayed_move_time && ms > delayed_move_time + 1000 && !Stopped) {
       // travel moves have been received so enact them
       delayed_move_time = 0xFFFFFFFFUL; // force moves to be done
-      memcpy(destination, current_position, sizeof(destination));
+      set_destination_to_current();
       prepare_move();
     }
   #endif

From 2d099a2c7076221670243f14a88655caf6827fcf Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sat, 4 Apr 2015 03:35:16 -0700
Subject: [PATCH 62/83] Fix missing backslash in macro

---
 Marlin/pins.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/pins.h b/Marlin/pins.h
index 0d9ae221c53..e5af0af1797 100644
--- a/Marlin/pins.h
+++ b/Marlin/pins.h
@@ -220,7 +220,7 @@
   #define Z_MIN_PIN          -1
 #endif
 
-#define SENSITIVE_PINS { 0, 1,
+#define SENSITIVE_PINS { 0, 1, \
                         X_STEP_PIN, X_DIR_PIN, X_ENABLE_PIN, X_MIN_PIN, X_MAX_PIN, \
                         Y_STEP_PIN, Y_DIR_PIN, Y_ENABLE_PIN, Y_MIN_PIN, Y_MAX_PIN, \
                         Z_STEP_PIN, Z_DIR_PIN, Z_ENABLE_PIN, Z_MIN_PIN, Z_MAX_PIN, Z_PROBE_PIN, \

From 6f06d33be5f4812ae7e37baedb953e1adcb32504 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sat, 4 Apr 2015 03:47:25 -0700
Subject: [PATCH 63/83] Fix missing refresh_cmd_timeout function

---
 Marlin/Marlin.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 182540bbd5a..55ed637f2c5 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -227,7 +227,7 @@ void enquecommands_P(const char *cmd); //put one or many ASCII commands at the e
 void prepare_arc_move(char isclockwise);
 void clamp_to_software_endstops(float target[3]);
 
-void refresh_cmd_timeout(void);
+void refresh_cmd_timeout();
 
 #ifdef FAST_PWM_FAN
   void setPwmFrequency(uint8_t pin, int val);

From 4119738e69b0bf66be570df78ebc49558ccf8861 Mon Sep 17 00:00:00 2001
From: Richard Wackerbarth <rkw@dataplex.net>
Date: Sat, 4 Apr 2015 05:41:02 -0500
Subject: [PATCH 64/83] Deferring default definition made #undef unnecessary

---
 Marlin/language.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/Marlin/language.h b/Marlin/language.h
index 48daddb5859..3fe7afd2ede 100644
--- a/Marlin/language.h
+++ b/Marlin/language.h
@@ -43,14 +43,12 @@
 #define PROTOCOL_VERSION "1.0"
 
 #if MB(ULTIMAKER)|| MB(ULTIMAKER_OLD)|| MB(ULTIMAIN_2)
-  #undef FIRMWARE_URL
   #define MACHINE_NAME "Ultimaker"
   #define FIRMWARE_URL "http://firmware.ultimaker.com"
 #elif MB(RUMBA)
   #define MACHINE_NAME "Rumba"
 #elif MB(3DRAG)
   #define MACHINE_NAME "3Drag"
-  #undef FIRMWARE_URL
   #define FIRMWARE_URL "http://3dprint.elettronicain.it/"
 #elif MB(K8200)
   #define MACHINE_NAME "K8200"
@@ -58,15 +56,12 @@
   #define MACHINE_NAME "Makibox"
 #elif MB(SAV_MKI)
   #define MACHINE_NAME "SAV MkI"
-  #undef FIRMWARE_URL
   #define FIRMWARE_URL "https://github.com/fmalpartida/Marlin/tree/SAV-MkI-config"
 #elif MB(WITBOX)
   #define MACHINE_NAME "WITBOX"
-  #undef FIRMWARE_URL
   #define FIRMWARE_URL "http://www.bq.com/gb/downloads-witbox.html"
 #elif MB(HEPHESTOS)
   #define MACHINE_NAME "HEPHESTOS"
-  #undef FIRMWARE_URL
   #define FIRMWARE_URL "http://www.bq.com/gb/downloads-prusa-i3-hephestos.html"
 #elif MB(BRAINWAVE_PRO)
   #define MACHINE_NAME "Kossel Pro"

From 61f839436113f0c9f9dbac4dc29039323b899009 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sat, 4 Apr 2015 05:01:16 -0700
Subject: [PATCH 65/83] Compare indices instead of floats for probe actions

---
 Marlin/Marlin.h        |  3 ++-
 Marlin/Marlin_main.cpp | 49 ++++++++++++++++++++----------------------
 Marlin/ultralcd.cpp    |  5 ++---
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index 55ed637f2c5..36e054eec0e 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -227,7 +227,8 @@ void enquecommands_P(const char *cmd); //put one or many ASCII commands at the e
 void prepare_arc_move(char isclockwise);
 void clamp_to_software_endstops(float target[3]);
 
-void refresh_cmd_timeout();
+extern unsigned long previous_millis_cmd;
+inline void refresh_cmd_timeout() { previous_millis_cmd = millis(); }
 
 #ifdef FAST_PWM_FAN
   void setPwmFrequency(uint8_t pin, int val);
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 29ac686ef54..7736acb507c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -238,7 +238,7 @@ static char *strchr_pointer; ///< A pointer to find chars in the command string
 const char* queued_commands_P= NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */
 const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
 // Inactivity shutdown
-static unsigned long previous_millis_cmd = 0;
+unsigned long previous_millis_cmd = 0;
 static unsigned long max_inactive_time = 0;
 static unsigned long stepper_inactive_time = DEFAULT_STEPPER_DEACTIVE_TIME*1000l;
 unsigned long starttime = 0; ///< Print job start time
@@ -986,8 +986,6 @@ static void axis_is_at_home(int axis) {
   #endif
 }
 
-inline void refresh_cmd_timeout() { previous_millis_cmd = millis(); }
-
 /**
  * Some planner shorthand inline functions
  */
@@ -1327,20 +1325,20 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
   }
 
   enum ProbeAction {
-    ProbeStay             = 0,
-    ProbeEngage           = BIT(0),
-    ProbeRetract          = BIT(1),
-    ProbeEngageAndRetract = (ProbeEngage | ProbeRetract)
+    ProbeStay          = 0,
+    ProbeDeploy        = BIT(0),
+    ProbeStow          = BIT(1),
+    ProbeDeployAndStow = (ProbeDeploy | ProbeStow)
   };
 
   // Probe bed height at position (x,y), returns the measured z value
-  static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeEngageAndRetract, int verbose_level=1) {
+  static float probe_pt(float x, float y, float z_before, ProbeAction retract_action=ProbeDeployAndStow, int verbose_level=1) {
     // move to right place
     do_blocking_move_to(current_position[X_AXIS], current_position[Y_AXIS], z_before);
     do_blocking_move_to(x - X_PROBE_OFFSET_FROM_EXTRUDER, y - Y_PROBE_OFFSET_FROM_EXTRUDER, current_position[Z_AXIS]);
 
     #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-      if (retract_action & ProbeEngage) deploy_z_probe();
+      if (retract_action & ProbeDeploy) deploy_z_probe();
     #endif
 
     run_z_probe();
@@ -1354,7 +1352,7 @@ inline void set_destination_to_current() { memcpy(destination, current_position,
     #endif
 
     #if !defined(Z_PROBE_SLED) && !defined(Z_PROBE_ALLEN_KEY)
-      if (retract_action & ProbeRetract) stow_z_probe();
+      if (retract_action & ProbeStow) stow_z_probe();
     #endif
 
     if (verbose_level > 2) {
@@ -2167,7 +2165,7 @@ inline void gcode_G28() {
     }
 
     bool dryrun = code_seen('D') || code_seen('d'),
-         engage_probe_for_each_reading = code_seen('E') || code_seen('e');
+         deploy_probe_for_each_reading = code_seen('E') || code_seen('e');
 
     #ifdef AUTO_BED_LEVELING_GRID
 
@@ -2319,14 +2317,13 @@ inline void gcode_G28() {
             if (distance_from_center > DELTA_PROBABLE_RADIUS) continue;
           #endif //DELTA
 
-          // Enhanced G29 - Do not retract servo between probes
           ProbeAction act;
-          if (engage_probe_for_each_reading)
-            act = ProbeEngageAndRetract;
-          else if (yProbe == front_probe_bed_position && xCount == 0)
-            act = ProbeEngage;
-          else if (yProbe == front_probe_bed_position + (yGridSpacing * (auto_bed_leveling_grid_points - 1)) && xCount == auto_bed_leveling_grid_points - 1)
-            act = ProbeRetract;
+          if (deploy_probe_for_each_reading) // G29 E - Stow between probes
+            act = ProbeDeployAndStow;
+          else if (yCount == 0 && xCount == 0)
+            act = ProbeDeploy;
+          else if (yCount == auto_bed_leveling_grid_points - 1 && xCount == auto_bed_leveling_grid_points - 1)
+            act = ProbeStow;
           else
             act = ProbeStay;
 
@@ -2417,10 +2414,10 @@ inline void gcode_G28() {
 
       // Actions for each probe
       ProbeAction p1, p2, p3;
-      if (engage_probe_for_each_reading)
-        p1 = p2 = p3 = ProbeEngageAndRetract;
+      if (deploy_probe_for_each_reading)
+        p1 = p2 = p3 = ProbeDeployAndStow;
       else
-        p1 = ProbeEngage, p2 = ProbeStay, p3 = ProbeRetract;
+        p1 = ProbeDeploy, p2 = ProbeStay, p3 = ProbeStow;
 
       // Probe at 3 arbitrary points
       float z_at_pt_1 = probe_pt(ABL_PROBE_PT_1_X, ABL_PROBE_PT_1_Y, Z_RAISE_BEFORE_PROBING, p1, verbose_level),
@@ -2839,7 +2836,7 @@ inline void gcode_M42() {
            Z_start_location = Z_current + Z_RAISE_BEFORE_PROBING,
            ext_position = st_get_position_mm(E_AXIS);
 
-    bool engage_probe_for_each_reading = code_seen('E') || code_seen('e');
+    bool deploy_probe_for_each_reading = code_seen('E') || code_seen('e');
 
     if (code_seen('X') || code_seen('x')) {
       X_probe_location = code_value() - X_PROBE_OFFSET_FROM_EXTRUDER;
@@ -2917,7 +2914,7 @@ inline void gcode_M42() {
     st_synchronize();
     current_position[Z_AXIS] = Z_current = st_get_position_mm(Z_AXIS);
 
-    if (engage_probe_for_each_reading) stow_z_probe();
+    if (deploy_probe_for_each_reading) stow_z_probe();
 
     for (uint16_t n=0; n < n_samples; n++) {
 
@@ -2959,7 +2956,7 @@ inline void gcode_M42() {
 
       } // n_legs
 
-      if (engage_probe_for_each_reading)  {
+      if (deploy_probe_for_each_reading)  {
         deploy_z_probe(); 
         delay(1000);
       }
@@ -3006,13 +3003,13 @@ inline void gcode_M42() {
       plan_buffer_line(X_probe_location, Y_probe_location, Z_start_location, current_position[E_AXIS], homing_feedrate[Z_AXIS]/60, active_extruder);
       st_synchronize();
 
-      if (engage_probe_for_each_reading) {
+      if (deploy_probe_for_each_reading) {
         stow_z_probe();
         delay(1000);
       }
     }
 
-    if (!engage_probe_for_each_reading) {
+    if (!deploy_probe_for_each_reading) {
       stow_z_probe();
       delay(1000);
     }
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index d2a2e6faaf4..8aada85b039 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1789,7 +1789,7 @@ char *ftostr52(const float &x) {
   return conv;
 }
 
-#if defined(MANUAL_BED_LEVELING)
+#ifdef MANUAL_BED_LEVELING
 static int _lcd_level_bed_position;
 static void _lcd_level_bed()
 {
@@ -1849,8 +1849,7 @@ static void _lcd_level_bed_homing()
     lcd_goto_menu(_lcd_level_bed);
   }
 }
-static void lcd_level_bed()
-{
+static void lcd_level_bed() {
   axis_known_position[X_AXIS] = false;
   axis_known_position[Y_AXIS] = false;
   axis_known_position[Z_AXIS] = false;

From 1836aa2615f59fd54af7ed28750f4af113817573 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:02:58 +0200
Subject: [PATCH 66/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 8d06c080de0..c5d3256e4c3 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__IRC:__ #marlin-firmware @freenode ([WebChat Client](https://webchat.freenode.net/?channels=marlin-firmware))
+__Google Hangout:__ https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua
 
 ## Credits
 

From 2f189be2e4773e3b8a6f9c7f55ab382cd166e1e9 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:07:20 +0200
Subject: [PATCH 67/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c5d3256e4c3..406d9676304 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__Google Hangout:__ https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua
+__Google Hangout:__ <a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"></a>
 
 ## Credits
 

From 506a42338b83047ef41f3ed6086d6ee6b5f263e9 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:07:59 +0200
Subject: [PATCH 68/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 406d9676304..e65da083b93 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__Google Hangout:__ <a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"></a>
+__Google Hangout:__ (a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"></a>)
 
 ## Credits
 

From a5e92639875ff99be969abcf760f415b444dc774 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:08:30 +0200
Subject: [PATCH 69/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index e65da083b93..563daaa76a0 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__Google Hangout:__ (a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"></a>)
+__Google Hangout:__ (<a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"></a>)
 
 ## Credits
 

From 20a047b8c5d8a40c78b1b38c931b38bc25af9249 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:09:39 +0200
Subject: [PATCH 70/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 563daaa76a0..808c23082a5 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__Google Hangout:__ (<a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"></a>)
+__Google Hangout:__ "https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"
 
 ## Credits
 

From f39e5988a32e993ab388f5e6afb7a9bc4013b153 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:09:59 +0200
Subject: [PATCH 71/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 808c23082a5..c5d3256e4c3 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__Google Hangout:__ "https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank"
+__Google Hangout:__ https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua
 
 ## Credits
 

From cabd713610830a8427433edc8ff403f18a844a01 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 14:12:36 +0200
Subject: [PATCH 72/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c5d3256e4c3..9f02a90cc83 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ We are actively looking for testers. So please try the current development versi
 
 ## Contact
 
-__Google Hangout:__ https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua
+__Google Hangout:__ <a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahikg6tmwao3kua" target="_blank">Hagnout</a>
 
 ## Credits
 

From f9dbd73652b79913032f4cfb4748563bb1ad7242 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sat, 4 Apr 2015 05:25:53 -0700
Subject: [PATCH 73/83] Fix tr_target_temperature type - float!

---
 Marlin/temperature.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 1e3c2b66385..07af7ee752a 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1007,7 +1007,7 @@ void setWatch() {
 
   void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
 
-    static int tr_target_temperature[EXTRUDERS+1];
+    static float tr_target_temperature[EXTRUDERS+1];
 
     /*
         SERIAL_ECHO_START;
@@ -1053,18 +1053,18 @@ void setWatch() {
         }
 
         // If the temperature is over the target (-hysteresis) restart the timer
-        if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc) *timer = millis();
-
-        // If the timer goes too long without a reset, trigger shutdown
+        if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc) {
+          *timer = millis();
+        } // If the timer goes too long without a reset, trigger shutdown
         else if (millis() > *timer + period_seconds * 1000UL) {
           SERIAL_ERROR_START;
           SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
           if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id);
           LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
           thermal_runaway = true;
+          disable_heater();
+          disable_all_steppers();
           for (;;) {
-            disable_heater();
-            disable_all_steppers();
             manage_heater();
             lcd_update();
           }

From 60f8e0386fef5358a51bb5dc1a9b1bad261b74cd Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sat, 4 Apr 2015 05:45:36 -0700
Subject: [PATCH 74/83] More thermal runaway states

---
 Marlin/temperature.cpp | 61 +++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 33 deletions(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 07af7ee752a..1bdb7fdbeec 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -76,15 +76,14 @@ unsigned char soft_pwm_bed;
 #define HAS_HEATER_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_PERIOD) && THERMAL_RUNAWAY_PROTECTION_PERIOD > 0)
 #define HAS_BED_THERMAL_PROTECTION (defined(THERMAL_RUNAWAY_PROTECTION_BED_PERIOD) && THERMAL_RUNAWAY_PROTECTION_BED_PERIOD > 0 && TEMP_SENSOR_BED != 0)
 #if HAS_HEATER_THERMAL_PROTECTION || HAS_BED_THERMAL_PROTECTION
-  enum TRState { TRInactive, TRFirstHeating, TRStable };
-  static bool thermal_runaway = false;
+  enum TRState { TRReset, TRInactive, TRFirstHeating, TRStable, TRRunaway };
   void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc);
   #if HAS_HEATER_THERMAL_PROTECTION
-    static TRState thermal_runaway_state_machine[4] = { TRInactive, TRInactive, TRInactive, TRInactive };
+    static TRState thermal_runaway_state_machine[4] = { TRReset, TRReset, TRReset, TRReset };
     static unsigned long thermal_runaway_timer[4]; // = {0,0,0,0};
   #endif
   #if HAS_BED_THERMAL_PROTECTION
-    static TRState thermal_runaway_bed_state_machine = TRInactive;
+    static TRState thermal_runaway_bed_state_machine = TRReset;
     static unsigned long thermal_runaway_bed_timer;
   #endif
 #endif
@@ -1007,7 +1006,7 @@ void setWatch() {
 
   void thermal_runaway_protection(TRState *state, unsigned long *timer, float temperature, float target_temperature, int heater_id, int period_seconds, int hysteresis_degc) {
 
-    static float tr_target_temperature[EXTRUDERS+1];
+    static float tr_target_temperature[EXTRUDERS+1] = { 0.0 };
 
     /*
         SERIAL_ECHO_START;
@@ -1023,20 +1022,23 @@ void setWatch() {
         SERIAL_ECHOPGM(target_temperature);
         SERIAL_EOL;
     */
-    if (target_temperature == 0 || thermal_runaway) {
-      *state = TRInactive;
-      *timer = 0;
-      return;
-    }
+
+    // If the target temperature changes, restart
+    if (tr_target_temperature[heater_index] != target_temperature)
+      *state = TRReset;
 
     int heater_index = heater_id >= 0 ? heater_id : EXTRUDERS;
 
     switch (*state) {
+      case TRReset:
+        *timer = 0;
+        *state = TRInactive;
+        break;
       // Inactive state waits for a target temperature to be set
       case TRInactive:
         if (target_temperature > 0) {
-          *state = TRFirstHeating;
           tr_target_temperature[heater_index] = target_temperature;
+          *state = TRFirstHeating;
         }
         break;
       // When first heating, wait for the temperature to be reached then go to Stable state
@@ -1045,31 +1047,24 @@ void setWatch() {
         break;
       // While the temperature is stable watch for a bad temperature
       case TRStable:
-      {
-        // If the target temperature changes, restart
-        if (tr_target_temperature[heater_index] != target_temperature) {
-          *state = TRInactive;
-          break;
-        }
-
         // If the temperature is over the target (-hysteresis) restart the timer
-        if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc) {
+        if (temperature >= tr_target_temperature[heater_index] - hysteresis_degc)
           *timer = millis();
-        } // If the timer goes too long without a reset, trigger shutdown
-        else if (millis() > *timer + period_seconds * 1000UL) {
-          SERIAL_ERROR_START;
-          SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
-          if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id);
-          LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
-          thermal_runaway = true;
-          disable_heater();
-          disable_all_steppers();
-          for (;;) {
-            manage_heater();
-            lcd_update();
-          }
+          // If the timer goes too long without a reset, trigger shutdown
+        else if (millis() > *timer + period_seconds * 1000UL)
+          *state = TRRunaway;
+        break;
+      case TRRunaway:
+        SERIAL_ERROR_START;
+        SERIAL_ERRORLNPGM(MSG_THERMAL_RUNAWAY_STOP);
+        if (heater_id < 0) SERIAL_ERRORLNPGM("bed"); else SERIAL_ERRORLN(heater_id);
+        LCD_ALERTMESSAGEPGM(MSG_THERMAL_RUNAWAY);
+        disable_heater();
+        disable_all_steppers();
+        for (;;) {
+          manage_heater();
+          lcd_update();
         }
-      } break;
     }
   }
 

From bf5dbb90c4beb708a5f3f2d4d0985fe97733e710 Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 15:06:13 +0200
Subject: [PATCH 75/83] Update README.md

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 9f02a90cc83..970a32b82bb 100644
--- a/README.md
+++ b/README.md
@@ -37,8 +37,8 @@ __Google Hangout:__ <a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahik
 
 The current Marlin dev team consists of:
 
- - Erik van der Zalm ([@ErikZalm](https://github.com/ErikZalm))
- - [@daid](https://github.com/daid)
+ - Scott Lahteine ([@thinkyhead])
+ - 
 
 Sprinters lead developers are Kliment and caru.
 Grbl's lead developer is Simen Svale Skogsrud.

From 3d014922285d2ab361342d58a057967e2966c42f Mon Sep 17 00:00:00 2001
From: Bo Herrmannsen <bo.herrmannsen@gmail.com>
Date: Sat, 4 Apr 2015 15:07:36 +0200
Subject: [PATCH 76/83] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 970a32b82bb..d2ff347d6f2 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ __Google Hangout:__ <a href="https://plus.google.com/hangouts/_/g2wp5duzb2y6ahik
 
 The current Marlin dev team consists of:
 
- - Scott Lahteine ([@thinkyhead])
+ - Scott Lahteine [@thinkyhead]
  - 
 
 Sprinters lead developers are Kliment and caru.

From b0f198c153774aed21807e8464429b5231933249 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Sat, 4 Apr 2015 06:18:08 -0700
Subject: [PATCH 77/83] heater_index above its use

---
 Marlin/temperature.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Marlin/temperature.cpp b/Marlin/temperature.cpp
index 1bdb7fdbeec..28e1afb7cef 100644
--- a/Marlin/temperature.cpp
+++ b/Marlin/temperature.cpp
@@ -1023,12 +1023,12 @@ void setWatch() {
         SERIAL_EOL;
     */
 
+    int heater_index = heater_id >= 0 ? heater_id : EXTRUDERS;
+
     // If the target temperature changes, restart
     if (tr_target_temperature[heater_index] != target_temperature)
       *state = TRReset;
 
-    int heater_index = heater_id >= 0 ? heater_id : EXTRUDERS;
-
     switch (*state) {
       case TRReset:
         *timer = 0;

From 4cb7dfc546c826c1f06555a7ed1f45b9ad7e140e Mon Sep 17 00:00:00 2001
From: AnHardt <github@kitelab.de>
Date: Sat, 4 Apr 2015 17:34:28 +0200
Subject: [PATCH 78/83] Move the 'alive dot' in every displayloop

Result see: https://www.youtube.com/watch?v=tdu7J0i-c4g
Loop is executed several times per display update.
---
 Marlin/dogm_lcd_implementation.h | 4 ++--
 Marlin/ultralcd.cpp              | 9 ++++++---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index c057e56425c..81234c0f013 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -318,9 +318,9 @@ static void lcd_implementation_status_screen() {
   lcd_setFont(FONT_STATUSMENU);
 
   #ifdef USE_SMALL_INFOFONT
-    u8g.drawBox(0,30,128,10);
+    u8g.drawBox(0,30,127,10);
   #else
-    u8g.drawBox(0,30,128,9);
+    u8g.drawBox(0,30,127,9);
   #endif
   u8g.setColorIndex(0); // white on black
   u8g.setPrintPos(2,XYZ_BASELINE);
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 8aada85b039..64b91f6999d 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1299,6 +1299,8 @@ void lcd_update() {
     }
   #endif//CARDINSERTED
 
+  static uint8_t dotcounter = 63;
+  
   uint32_t ms = millis();
   if (ms > lcd_next_update_millis) {
 
@@ -1362,11 +1364,12 @@ void lcd_update() {
       blink++;     // Variable for fan animation and alive dot
       u8g.firstPage();
       do {
+        if (!dotcounter) dotcounter = 63;
         lcd_setFont(FONT_MENU);
         u8g.setPrintPos(125, 0);
-        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
-        u8g.drawPixel(127, 63); // draw alive dot
-        u8g.setColorIndex(1); // black on white
+//        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
+        u8g.drawPixel(127, dotcounter--); // draw alive dot
+//        u8g.setColorIndex(1); // black on white
         (*currentMenu)();
         if (!lcdDrawUpdate) break; // Terminate display update, when nothing new to draw. This must be done before the last dogm.next()
       } while( u8g.nextPage() );

From 6d4b3f0d6a668f6c038c16cf9587f424f2968778 Mon Sep 17 00:00:00 2001
From: AnHardt <github@kitelab.de>
Date: Sat, 4 Apr 2015 17:49:39 +0200
Subject: [PATCH 79/83] Move the condition before the loop

Result see: https://youtu.be/AEnBzdu9_tk
Dot is moving not so fast -> less executed loops.
---
 Marlin/ultralcd.cpp | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 64b91f6999d..1c124a00627 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1363,16 +1363,18 @@ void lcd_update() {
     #ifdef DOGLCD  // Changes due to different driver architecture of the DOGM display
       blink++;     // Variable for fan animation and alive dot
       u8g.firstPage();
-      do {
-        if (!dotcounter) dotcounter = 63;
-        lcd_setFont(FONT_MENU);
-        u8g.setPrintPos(125, 0);
-//        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
-        u8g.drawPixel(127, dotcounter--); // draw alive dot
-//        u8g.setColorIndex(1); // black on white
-        (*currentMenu)();
-        if (!lcdDrawUpdate) break; // Terminate display update, when nothing new to draw. This must be done before the last dogm.next()
-      } while( u8g.nextPage() );
+      (*currentMenu)();
+      if (lcdDrawUpdate) {
+        do {
+          if (!dotcounter) dotcounter = 63;
+          lcd_setFont(FONT_MENU);
+          u8g.setPrintPos(125, 0);
+  //        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
+          u8g.drawPixel(127, dotcounter--); // draw alive dot
+  //        u8g.setColorIndex(1); // black on white
+          (*currentMenu)();
+        } while( u8g.nextPage() );
+      }
     #else
       (*currentMenu)();
     #endif

From 6361404b91dcf8ba657b1f1e16d9717a8e280ae6 Mon Sep 17 00:00:00 2001
From: AnHardt <github@kitelab.de>
Date: Sat, 4 Apr 2015 17:56:13 +0200
Subject: [PATCH 80/83] Testloop cleanup

Shifted condition should still be in.
---
 Marlin/dogm_lcd_implementation.h | 4 ++--
 Marlin/ultralcd.cpp              | 9 +++------
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index 81234c0f013..c057e56425c 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -318,9 +318,9 @@ static void lcd_implementation_status_screen() {
   lcd_setFont(FONT_STATUSMENU);
 
   #ifdef USE_SMALL_INFOFONT
-    u8g.drawBox(0,30,127,10);
+    u8g.drawBox(0,30,128,10);
   #else
-    u8g.drawBox(0,30,127,9);
+    u8g.drawBox(0,30,128,9);
   #endif
   u8g.setColorIndex(0); // white on black
   u8g.setPrintPos(2,XYZ_BASELINE);
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 1c124a00627..a3413bfbef6 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1299,8 +1299,6 @@ void lcd_update() {
     }
   #endif//CARDINSERTED
 
-  static uint8_t dotcounter = 63;
-  
   uint32_t ms = millis();
   if (ms > lcd_next_update_millis) {
 
@@ -1366,12 +1364,11 @@ void lcd_update() {
       (*currentMenu)();
       if (lcdDrawUpdate) {
         do {
-          if (!dotcounter) dotcounter = 63;
           lcd_setFont(FONT_MENU);
           u8g.setPrintPos(125, 0);
-  //        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
-          u8g.drawPixel(127, dotcounter--); // draw alive dot
-  //        u8g.setColorIndex(1); // black on white
+          if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
+          u8g.drawPixel(127, 63); // draw alive dot
+          u8g.setColorIndex(1); // black on white
           (*currentMenu)();
         } while( u8g.nextPage() );
       }

From 418d22d7b3d7099aa3aeea79c3e901cb0e5a7f31 Mon Sep 17 00:00:00 2001
From: AnHardt <github@kitelab.de>
Date: Sat, 4 Apr 2015 18:33:36 +0200
Subject: [PATCH 81/83] Revert "Testloop cleanup"

This reverts commit 6361404b91dcf8ba657b1f1e16d9717a8e280ae6.
---
 Marlin/dogm_lcd_implementation.h | 4 ++--
 Marlin/ultralcd.cpp              | 9 ++++++---
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index c057e56425c..81234c0f013 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -318,9 +318,9 @@ static void lcd_implementation_status_screen() {
   lcd_setFont(FONT_STATUSMENU);
 
   #ifdef USE_SMALL_INFOFONT
-    u8g.drawBox(0,30,128,10);
+    u8g.drawBox(0,30,127,10);
   #else
-    u8g.drawBox(0,30,128,9);
+    u8g.drawBox(0,30,127,9);
   #endif
   u8g.setColorIndex(0); // white on black
   u8g.setPrintPos(2,XYZ_BASELINE);
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index a3413bfbef6..1c124a00627 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1299,6 +1299,8 @@ void lcd_update() {
     }
   #endif//CARDINSERTED
 
+  static uint8_t dotcounter = 63;
+  
   uint32_t ms = millis();
   if (ms > lcd_next_update_millis) {
 
@@ -1364,11 +1366,12 @@ void lcd_update() {
       (*currentMenu)();
       if (lcdDrawUpdate) {
         do {
+          if (!dotcounter) dotcounter = 63;
           lcd_setFont(FONT_MENU);
           u8g.setPrintPos(125, 0);
-          if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
-          u8g.drawPixel(127, 63); // draw alive dot
-          u8g.setColorIndex(1); // black on white
+  //        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
+          u8g.drawPixel(127, dotcounter--); // draw alive dot
+  //        u8g.setColorIndex(1); // black on white
           (*currentMenu)();
         } while( u8g.nextPage() );
       }

From 340d165a9cb87dfbfbacc680989717c79b5bdffe Mon Sep 17 00:00:00 2001
From: AnHardt <github@kitelab.de>
Date: Sat, 4 Apr 2015 22:02:24 +0200
Subject: [PATCH 82/83] Reduce display updates for dogm displays

In 'if (encoderPastThreshold || LCD_CLICKED)' lcdDrawUpdate was not set.

'lcd_status_update_delay'-loop was not effective in  function
lcd_status_screen().
The loop prevented the update of the status screen but not the displays
update.
Shifted the loop into lcd_update().
---
 Marlin/dogm_lcd_implementation.h |  4 ++--
 Marlin/ultralcd.cpp              | 37 ++++++++++++++------------------
 2 files changed, 18 insertions(+), 23 deletions(-)

diff --git a/Marlin/dogm_lcd_implementation.h b/Marlin/dogm_lcd_implementation.h
index 81234c0f013..c057e56425c 100644
--- a/Marlin/dogm_lcd_implementation.h
+++ b/Marlin/dogm_lcd_implementation.h
@@ -318,9 +318,9 @@ static void lcd_implementation_status_screen() {
   lcd_setFont(FONT_STATUSMENU);
 
   #ifdef USE_SMALL_INFOFONT
-    u8g.drawBox(0,30,127,10);
+    u8g.drawBox(0,30,128,10);
   #else
-    u8g.drawBox(0,30,127,9);
+    u8g.drawBox(0,30,128,9);
   #endif
   u8g.setColorIndex(0); // white on black
   u8g.setPrintPos(2,XYZ_BASELINE);
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index 1c124a00627..034adc3942e 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -262,8 +262,7 @@ static void lcd_goto_menu(menuFunc_t menu, const uint32_t encoder=0, const bool
 }
 
 /* Main status screen. It's up to the implementation specific part to show what is needed. As this is very display dependent */
-static void lcd_status_screen()
-{
+static void lcd_status_screen() {
 	encoderRateMultiplierEnabled = false;
 
   #ifdef LCD_PROGRESS_BAR
@@ -296,15 +295,7 @@ static void lcd_status_screen()
     #endif
   #endif //LCD_PROGRESS_BAR
 
-  if (lcd_status_update_delay)
-    lcd_status_update_delay--;
-  else
-    lcdDrawUpdate = 1;
-
-  if (lcdDrawUpdate) {
     lcd_implementation_status_screen();
-    lcd_status_update_delay = 10;   /* redraw the main screen every second. This is easier then trying keep track of all things that change on the screen */
-  }
 
 #ifdef ULTIPANEL
 
@@ -1298,8 +1289,6 @@ void lcd_update() {
       }
     }
   #endif//CARDINSERTED
-
-  static uint8_t dotcounter = 63;
   
   uint32_t ms = millis();
   if (ms > lcd_next_update_millis) {
@@ -1351,27 +1340,33 @@ void lcd_update() {
             } // encoderRateMultiplierEnabled
           #endif //ENCODER_RATE_MULTIPLIER
 
-          lcdDrawUpdate = 1;
           encoderPosition += (encoderDiff * encoderMultiplier) / ENCODER_PULSES_PER_STEP;
           encoderDiff = 0;
         }
         timeoutToStatus = ms + LCD_TIMEOUT_TO_STATUS;
+        lcdDrawUpdate = 1;
       }
-
     #endif //ULTIPANEL
 
+    if (currentMenu == lcd_status_screen) {
+      if (!lcd_status_update_delay) {
+        lcdDrawUpdate = 1;
+        lcd_status_update_delay = 10;   /* redraw the main screen every second. This is easier then trying keep track of all things that change on the screen */
+      }
+      else {
+        lcd_status_update_delay--;
+      }
+    }
     #ifdef DOGLCD  // Changes due to different driver architecture of the DOGM display
-      blink++;     // Variable for fan animation and alive dot
-      u8g.firstPage();
-      (*currentMenu)();
       if (lcdDrawUpdate) {
+        blink++;     // Variable for fan animation and alive dot
+        u8g.firstPage();
         do {
-          if (!dotcounter) dotcounter = 63;
           lcd_setFont(FONT_MENU);
           u8g.setPrintPos(125, 0);
-  //        if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
-          u8g.drawPixel(127, dotcounter--); // draw alive dot
-  //        u8g.setColorIndex(1); // black on white
+          if (blink % 2) u8g.setColorIndex(1); else u8g.setColorIndex(0); // Set color for the alive dot
+          u8g.drawPixel(127, 63); // draw alive dot
+          u8g.setColorIndex(1); // black on white
           (*currentMenu)();
         } while( u8g.nextPage() );
       }

From b02a55e60fb95b92f61cf92db6a34ffeac061aba Mon Sep 17 00:00:00 2001
From: quillford <quillford@users.noreply.github.com>
Date: Sat, 4 Apr 2015 15:26:35 -0700
Subject: [PATCH 83/83] Fixed scara directions

Config said for a delta instead of for a scara
---
 Marlin/Configuration.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 8d3e75dae9b..871d69ccb7b 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -31,7 +31,7 @@ Here are some standard links for getting your machine calibrated:
 //===========================================================================
 //============================= SCARA Printer ===============================
 //===========================================================================
-// For a Delta printer replace the configuration files with the files in the
+// For a Scara printer replace the configuration files with the files in the
 // example_configurations/SCARA directory.
 //