From b331077c32c6126732486a7d5ff56751df3ace91 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Wed, 28 Sep 2016 14:05:50 -0500
Subject: [PATCH 01/13] Use stepper.get_axis_position_degrees

---
 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 fea989ec56..d6045438a3 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -5380,8 +5380,8 @@ static void report_current_position() {
   stepper.report_positions();
 
   #if IS_SCARA
-    SERIAL_PROTOCOLPAIR("SCARA Theta:", stepper.get_axis_position_mm(A_AXIS));
-    SERIAL_PROTOCOLLNPAIR("   Psi+Theta:", stepper.get_axis_position_mm(B_AXIS));
+    SERIAL_PROTOCOLPAIR("SCARA Theta:", stepper.get_axis_position_degrees(A_AXIS));
+    SERIAL_PROTOCOLLNPAIR("   Psi+Theta:", stepper.get_axis_position_degrees(B_AXIS));
     SERIAL_EOL;
   #endif
 }

From 2febd8ec82fb65d3e3a0a0fc669b445895cddba7 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Wed, 28 Sep 2016 14:01:59 -0500
Subject: [PATCH 02/13] Double-touch debugging

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

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index d6045438a3..2eec565212 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2027,6 +2027,12 @@ static void clean_up_after_endstop_or_probe_move() {
       // Do a first probe at the fast speed
       do_probe_move(-(Z_MAX_LENGTH) - 10, Z_PROBE_SPEED_FAST);
 
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
+        float first_probe_z = current_position[Z_AXIS];
+        if (DEBUGGING(LEVELING))
+          SERIAL_ECHOPAIR("1st Probe Z:", first_probe_z);
+      #endif
+
       // move up by the bump distance
       do_blocking_move_to_z(current_position[Z_AXIS] + home_bump_mm(Z_AXIS), MMM_TO_MMS(Z_PROBE_SPEED_FAST));
 
@@ -2047,6 +2053,13 @@ static void clean_up_after_endstop_or_probe_move() {
       if (DEBUGGING(LEVELING)) DEBUG_POS("<<< run_z_probe", current_position);
     #endif
 
+    // Debug: compare probe heights
+    #if ENABLED(PROBE_DOUBLE_TOUCH) && ENABLED(DEBUG_LEVELING_FEATURE)
+      if (DEBUGGING(LEVELING)) {
+        SERIAL_ECHOPAIR("2nd Probe Z:", current_position[Z_AXIS]);
+        SERIAL_ECHOLNPAIR(" Discrepancy:", first_probe_z - current_position[Z_AXIS]);
+      }
+    #endif
     return current_position[Z_AXIS];
   }
 

From ecf7cdde655160c9ac8a60377f7e3e5550a16550 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Wed, 28 Sep 2016 14:01:29 -0500
Subject: [PATCH 03/13] Augment planner/stepper getters/setters

---
 Marlin/enum.h      |  2 ++
 Marlin/planner.cpp | 13 +++++++------
 Marlin/planner.h   | 10 +++++-----
 Marlin/stepper.cpp |  6 ++++++
 Marlin/stepper.h   |  1 +
 5 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/Marlin/enum.h b/Marlin/enum.h
index 18db5a6f5f..713f3b64c0 100644
--- a/Marlin/enum.h
+++ b/Marlin/enum.h
@@ -23,6 +23,8 @@
 #ifndef __ENUM_H__
 #define __ENUM_H__
 
+#include "MarlinConfig.h"
+
 /**
  * Axis indices as enumerated constants
  *
diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp
index c55770e256..5d54f14fad 100644
--- a/Marlin/planner.cpp
+++ b/Marlin/planner.cpp
@@ -1201,7 +1201,8 @@ void Planner::buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, float fr_mm_s, co
 } // buffer_line()
 
 /**
- * Directly set the planner XYZ position (hence the stepper positions).
+ * Directly set the planner XYZ position (and stepper positions)
+ * converting mm (or angles for SCARA) into steps.
  *
  * On CORE machines stepper ABC will be translated from the given XYZ.
  */
@@ -1229,12 +1230,12 @@ void Planner::sync_from_steppers() {
 }
 
 /**
- * Directly set the planner E position (hence the stepper E position).
+ * Setters for planner position (also setting stepper position).
  */
-void Planner::set_e_position_mm(const float& e) {
-  position[E_AXIS] = lround(e * axis_steps_per_mm[E_AXIS]);
-  stepper.set_e_position(position[E_AXIS]);
-  previous_speed[E_AXIS] = 0.0;
+void Planner::set_position_mm(const AxisEnum axis, const float& v) {
+  position[axis] = lround(v * axis_steps_per_mm[axis]);
+  stepper.set_position(axis, v);
+  previous_speed[axis] = 0.0;
 }
 
 // Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
diff --git a/Marlin/planner.h b/Marlin/planner.h
index 499f9eb529..c198f083aa 100644
--- a/Marlin/planner.h
+++ b/Marlin/planner.h
@@ -33,6 +33,7 @@
 #define PLANNER_H
 
 #include "types.h"
+#include "enum.h"
 #include "MarlinConfig.h"
 
 #if HAS_ABL
@@ -242,17 +243,16 @@ class Planner {
      * Clears previous speed values.
      */
     static void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float& e);
+    static void set_position_mm(const AxisEnum axis, const float& v);
+
+    static FORCE_INLINE void set_z_position_mm(const float& z) { set_position_mm(Z_AXIS, z); }
+    static FORCE_INLINE void set_e_position_mm(const float& e) { set_position_mm(E_AXIS, e); }
 
     /**
      * Sync from the stepper positions. (e.g., after an interrupted move)
      */
     static void sync_from_steppers();
 
-    /**
-     * Set the E position (mm) of the planner (and the E stepper)
-     */
-    static void set_e_position_mm(const float& e);
-
     /**
      * Does the buffer have any blocks queued?
      */
diff --git a/Marlin/stepper.cpp b/Marlin/stepper.cpp
index 06183a7f5f..7674bd2dbe 100644
--- a/Marlin/stepper.cpp
+++ b/Marlin/stepper.cpp
@@ -970,6 +970,12 @@ void Stepper::set_position(const long& x, const long& y, const long& z, const lo
   CRITICAL_SECTION_END;
 }
 
+void Stepper::set_position(const AxisEnum &axis, const long& v) {
+  CRITICAL_SECTION_START;
+  count_position[axis] = v;
+  CRITICAL_SECTION_END;
+}
+
 void Stepper::set_e_position(const long& e) {
   CRITICAL_SECTION_START;
   count_position[E_AXIS] = e;
diff --git a/Marlin/stepper.h b/Marlin/stepper.h
index a1c62fe941..3e31f82d19 100644
--- a/Marlin/stepper.h
+++ b/Marlin/stepper.h
@@ -189,6 +189,7 @@ class Stepper {
     // Set the current position in steps
     //
     static void set_position(const long& x, const long& y, const long& z, const long& e);
+    static void set_position(const AxisEnum& a, const long& v);
     static void set_e_position(const long& e);
 
     //

From 510ef5d14a901675282d91b72ef5c988e4927e74 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 00:59:06 -0500
Subject: [PATCH 04/13] Standard function to turn bed leveling on/off

---
 Marlin/Marlin_main.cpp | 75 ++++++++++++++++++++++++++++++++----------
 1 file changed, 57 insertions(+), 18 deletions(-)

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 2eec565212..14bd1d8a61 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2132,30 +2132,69 @@ static void clean_up_after_endstop_or_probe_move() {
 
 #endif // HAS_BED_PROBE
 
-#if HAS_ABL
-
+#if PLANNER_LEVELING
   /**
-   * Reset calibration results to zero.
+   * Turn bed leveling on or off, fixing the current
+   * position as-needed.
    *
-   * TODO: Proper functions to disable / enable
-   *       bed leveling via a flag, correcting the
-   *       current position in each case.
+   * Disable: Current position = physical position
+   *  Enable: Current position = "unleveled" physical position
    */
-  void reset_bed_level() {
-    planner.abl_enabled = false;
-    #if ENABLED(DEBUG_LEVELING_FEATURE)
-      if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level");
-    #endif
-    #if ABL_PLANAR
-      planner.bed_level_matrix.set_to_identity();
-    #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
-      for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++)
-        for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++)
-          bed_level_grid[x][y] = 1000.0;
+  void set_bed_leveling_enabled(bool enable=true) {
+    #if ENABLED(MESH_BED_LEVELING)
+
+      if (!enable && mbl.active())
+        current_position[Z_AXIS] +=
+          mbl.get_z(RAW_CURRENT_POSITION(X_AXIS), RAW_CURRENT_POSITION(Y_AXIS)) - (MESH_HOME_SEARCH_Z);
+
+      mbl.set_active(enable && mbl.has_mesh()); // was set_has_mesh(). Is this not correct?
+
+    #elif HAS_ABL
+
+      if (enable != planner.abl_enabled) {
+        planner.abl_enabled = !planner.abl_enabled;
+        if (!planner.abl_enabled)
+          set_current_from_steppers_for_axis(
+            #if ABL_PLANAR
+              ALL_AXES
+            #else
+              Z_AXIS
+            #endif
+          );
+        else
+          planner.unapply_leveling(current_position);
+      }
+
     #endif
   }
 
-#endif // HAS_ABL
+
+  /**
+   * Reset calibration results to zero.
+   */
+  void reset_bed_level() {
+    #if ENABLED(MESH_BED_LEVELING)
+      if (mbl.has_mesh()) {
+        set_bed_leveling_enabled(false);
+        mbl.reset();
+        mbl.set_has_mesh(false);
+      }
+    #else
+      planner.abl_enabled = false;
+      #if ENABLED(DEBUG_LEVELING_FEATURE)
+        if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("reset_bed_level");
+      #endif
+      #if ABL_PLANAR
+        planner.bed_level_matrix.set_to_identity();
+      #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
+        for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++)
+          for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++)
+            bed_level_grid[x][y] = 1000.0;
+      #endif
+    #endif
+  }
+
+#endif // PLANNER_LEVELING
 
 #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
 

From 850e38d01389789a433f8c652a1c1cb1a6318f8d Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:00:34 -0500
Subject: [PATCH 05/13] G30 will only disable bed leveling

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

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 14bd1d8a61..2006c2801c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -4097,13 +4097,13 @@ inline void gcode_G28() {
    */
   inline void gcode_G30() {
 
-    #if HAS_ABL
-      reset_bed_level();
+    // Disable leveling so the planner won't mess with us
+    #if PLANNER_LEVELING
+      set_bed_leveling_enabled(false);
     #endif
 
     setup_for_endstop_or_probe_move();
 
-    // TODO: clear the leveling matrix or the planner will be set incorrectly
     float measured_z = probe_pt(current_position[X_AXIS] + X_PROBE_OFFSET_FROM_EXTRUDER,
                                 current_position[Y_AXIS] + Y_PROBE_OFFSET_FROM_EXTRUDER,
                                 true, 1);

From d06661051434937660d274cd32863dfaadd4f763 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:01:38 -0500
Subject: [PATCH 06/13] Patch up bilinear_z_offset

---
 Marlin/Conditionals_post.h |  7 +++++-
 Marlin/Marlin_main.cpp     | 44 +++++++++++++++++++++++++-------------
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h
index a7a8a6ccea..85da6c3a12 100644
--- a/Marlin/Conditionals_post.h
+++ b/Marlin/Conditionals_post.h
@@ -648,8 +648,13 @@
   #define ABL_GRID   (ENABLED(AUTO_BED_LEVELING_LINEAR) || ENABLED(AUTO_BED_LEVELING_BILINEAR))
   #define HAS_ABL    (ABL_PLANAR || ABL_GRID)
 
-  #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
   #define PLANNER_LEVELING      (HAS_ABL || ENABLED(MESH_BED_LEVELING))
+  #define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
+
+  #if HAS_PROBING_PROCEDURE
+    #define PROBE_BED_WIDTH abs(RIGHT_PROBE_BED_POSITION - (LEFT_PROBE_BED_POSITION))
+    #define PROBE_BED_HEIGHT abs(BACK_PROBE_BED_POSITION - (FRONT_PROBE_BED_POSITION))
+  #endif
 
   /**
    * Buzzer/Speaker
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 2006c2801c..ff7bc4abc1 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -7997,36 +7997,50 @@ void ok_to_send() {
           ratio_y = y / bilinear_grid_spacing[Y_AXIS];
 
     // Whole unit is the grid box index
-    int gridx = constrain(int(ratio_x), 0, ABL_GRID_POINTS_X - 2),
-        gridy = constrain(int(ratio_y), 0, ABL_GRID_POINTS_Y - 2);
+    const int gridx = constrain(floor(ratio_x), 0, ABL_GRID_POINTS_X - 2),
+              gridy = constrain(floor(ratio_y), 0, ABL_GRID_POINTS_Y - 2),
+              nextx = gridx + (x < PROBE_BED_WIDTH ? 1 : 0),
+              nexty = gridy + (y < PROBE_BED_HEIGHT ? 1 : 0);
 
     // Subtract whole to get the ratio within the grid box
-    ratio_x -= gridx, ratio_y -= gridy;
+    ratio_x = constrain(ratio_x - gridx, 0.0, 1.0);
+    ratio_y = constrain(ratio_y - gridy, 0.0, 1.0);
 
-          // Z at the box corners
-    const float z1 = bed_level_grid[gridx][gridy],         // left-front
-                z2 = bed_level_grid[gridx][gridy + 1],     // left-back
-                z3 = bed_level_grid[gridx + 1][gridy],     // right-front
-                z4 = bed_level_grid[gridx + 1][gridy + 1], // right-back
+    // Z at the box corners
+    const float z1 = bed_level_grid[gridx][gridy],  // left-front
+                z2 = bed_level_grid[gridx][nexty],  // left-back
+                z3 = bed_level_grid[nextx][gridy],  // right-front
+                z4 = bed_level_grid[nextx][nexty],  // right-back
 
+                // Bilinear interpolate
                 L = z1 + (z2 - z1) * ratio_y,   // Linear interp. LF -> LB
-                R = z3 + (z4 - z3) * ratio_y;   // Linear interp. RF -> RB
+                R = z3 + (z4 - z3) * ratio_y,   // Linear interp. RF -> RB
+                offset = L + ratio_x * (R - L);
 
     /*
-      SERIAL_ECHOPAIR("gridx=", gridx);
-      SERIAL_ECHOPAIR(" gridy=", gridy);
+    static float last_offset = 0;
+    if (fabs(last_offset - offset) > 0.2) {
+      SERIAL_ECHOPGM("Sudden Shift at ");
+      SERIAL_ECHOPAIR("x=", x);
+      SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[X_AXIS]);
+      SERIAL_ECHOLNPAIR(" -> gridx=", gridx);
+      SERIAL_ECHOPAIR(" y=", y);
+      SERIAL_ECHOPAIR(" / ", bilinear_grid_spacing[Y_AXIS]);
+      SERIAL_ECHOLNPAIR(" -> gridy=", gridy);
       SERIAL_ECHOPAIR(" ratio_x=", ratio_x);
-      SERIAL_ECHOPAIR(" ratio_y=", ratio_y);
+      SERIAL_ECHOLNPAIR(" ratio_y=", ratio_y);
       SERIAL_ECHOPAIR(" z1=", z1);
       SERIAL_ECHOPAIR(" z2=", z2);
       SERIAL_ECHOPAIR(" z3=", z3);
-      SERIAL_ECHOPAIR(" z4=", z4);
+      SERIAL_ECHOLNPAIR(" z4=", z4);
       SERIAL_ECHOPAIR(" L=", L);
       SERIAL_ECHOPAIR(" R=", R);
-      SERIAL_ECHOPAIR(" offset=", L + ratio_x * (R - L));
+      SERIAL_ECHOLNPAIR(" offset=", offset);
+    }
+    last_offset = offset;
     //*/
 
-    return L + ratio_x * (R - L);
+    return offset;
   }
 
 #endif // AUTO_BED_LEVELING_BILINEAR

From e8f2604a6f13213858148164f5fc5f8b4993f974 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:02:14 -0500
Subject: [PATCH 07/13] Patch print_bed_level numbering

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

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index ff7bc4abc1..fdc32f2c1c 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -2212,7 +2212,7 @@ static void clean_up_after_endstop_or_probe_move() {
         if (y < 10) SERIAL_CHAR(' ');
         SERIAL_ECHO((int)y);
         SERIAL_CHAR(ydir ? (ydir > 0 ? '+' : '-') : ' ');
-        SERIAL_CHAR(']');
+        SERIAL_ECHOLN(']');
       }
     #endif
     if (bed_level_grid[x][y] < 999.0) {
@@ -2299,7 +2299,7 @@ static void clean_up_after_endstop_or_probe_move() {
    */
   static void print_bed_level() {
     SERIAL_ECHOPGM("Bilinear Leveling Grid:\n ");
-    for (uint8_t x = 1; x < ABL_GRID_POINTS_X + 1; x++) {
+    for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) {
       SERIAL_PROTOCOLPGM("    ");
       if (x < 10) SERIAL_PROTOCOLCHAR(' ');
       SERIAL_PROTOCOL((int)x);
@@ -2307,7 +2307,7 @@ static void clean_up_after_endstop_or_probe_move() {
     SERIAL_EOL;
     for (uint8_t y = 0; y < ABL_GRID_POINTS_Y; y++) {
       if (y < 9) SERIAL_PROTOCOLCHAR(' ');
-      SERIAL_PROTOCOL(y + 1);
+      SERIAL_PROTOCOL(y);
       for (uint8_t x = 0; x < ABL_GRID_POINTS_X; x++) {
         SERIAL_PROTOCOLCHAR(' ');
         float offset = bed_level_grid[x][y];

From 06790977c4dc8fc2e1e43cdc9d83b903c6780777 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:02:54 -0500
Subject: [PATCH 08/13] Use updated position methods

---
 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 fdc32f2c1c..9500eb41b4 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3706,8 +3706,8 @@ inline void gcode_G28() {
       get_cartesian_from_steppers();
       memcpy(current_position, cartes, sizeof(cartes));
 
-      // Inform the planner about the new coordinates
-      SYNC_PLAN_POSITION_KINEMATIC();
+      // Sync the planner to where the steppers stopped
+      planner.sync_from_steppers();
     }
 
     setup_for_endstop_or_probe_move();

From 56cf674150ac0cde5c3346612c35cd5538579217 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:03:28 -0500
Subject: [PATCH 09/13] M420 can now enable/disable ABL

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

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 9500eb41b4..527ea51c2a 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -225,7 +225,7 @@
  * M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR)
  * M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR)
  * M410 - Quickstop. Abort all planned moves.
- * M420 - Enable/Disable Mesh Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING)
+ * M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL)
  * M421 - Set a single Z coordinate in the Mesh Leveling grid. X<units> Y<units> Z<units> (Requires MESH_BED_LEVELING)
  * M428 - Set the home_offset based on the current_position. Nearest edge applies.
  * M500 - Store parameters in EEPROM. (Requires EEPROM_SETTINGS)
@@ -6312,12 +6312,14 @@ void quickstop_stepper() {
   SYNC_PLAN_POSITION_KINEMATIC();
 }
 
-#if ENABLED(MESH_BED_LEVELING)
-
+#if PLANNER_LEVELING
   /**
-   * M420: Enable/Disable Mesh Bed Leveling
+   * M420: Enable/Disable Bed Leveling
    */
-  inline void gcode_M420() { if (code_seen('S')) mbl.set_has_mesh(code_value_bool()); }
+  inline void gcode_M420() { if (code_seen('S')) set_bed_leveling_enabled(code_value_bool()); }
+#endif
+
+#if ENABLED(MESH_BED_LEVELING)
 
   /**
    * M421: Set a single Mesh Bed Leveling Z coordinate
@@ -7343,11 +7345,11 @@ void process_next_command() {
         gcode_G28();
         break;
 
-      #if HAS_ABL || ENABLED(MESH_BED_LEVELING)
+      #if PLANNER_LEVELING
         case 29: // G29 Detailed Z probe, probes the bed at 3 or more points.
           gcode_G29();
           break;
-      #endif // HAS_ABL
+      #endif // PLANNER_LEVELING
 
       #if HAS_BED_PROBE
 

From 81b8c9f8ec2f6d94433e5b5640c29fc8ed3f7ace Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:17:16 -0500
Subject: [PATCH 10/13] Add XY parameters to G29 for mesh dimensions

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

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 527ea51c2a..f04d410043 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3635,24 +3635,31 @@ inline void gcode_G28() {
 
     #if ABL_GRID
 
-      #if ABL_PLANAR
-        bool do_topography_map = verbose_level > 2 || code_seen('T');
-      #endif
-
       if (verbose_level > 0) {
         SERIAL_PROTOCOLLNPGM("G29 Auto Bed Leveling");
         if (dryrun) SERIAL_PROTOCOLLNPGM("Running in DRY-RUN mode");
       }
 
-      int abl_grid_points_x = ABL_GRID_POINTS_X,
-          abl_grid_points_y = ABL_GRID_POINTS_Y;
-
       #if ABL_PLANAR
+
+        bool do_topography_map = verbose_level > 2 || code_seen('T');
+
+        // X and Y specify points in each direction, overriding the default
+        // These values may be saved with the completed mesh
+        int abl_grid_points_x = code_seen('X') ? code_value_int() : ABL_GRID_POINTS_X,
+            abl_grid_points_y = code_seen('Y') ? code_value_int() : ABL_GRID_POINTS_Y;
+
         if (code_seen('P')) abl_grid_points_x = abl_grid_points_y = code_value_int();
-        if (abl_grid_points_x < 2) {
-          SERIAL_PROTOCOLLNPGM("?Number of probed (P)oints is implausible (2 minimum).");
+
+        if (abl_grid_points_x < 2 || abl_grid_points_y < 2) {
+          SERIAL_PROTOCOLLNPGM("?Number of probe points is implausible (2 minimum).");
           return;
         }
+
+      #else
+
+         const int abl_grid_points_x = ABL_GRID_POINTS_X, abl_grid_points_y = ABL_GRID_POINTS_Y;
+
       #endif
 
       xy_probe_feedrate_mm_s = MMM_TO_MMS(code_seen('S') ? code_value_linear_units() : XY_PROBE_SPEED);

From c8c57e59fc4653a0aa377ba22f16b98eaa0f68ac Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:18:37 -0500
Subject: [PATCH 11/13] Patch the end of G29 to sync plan position

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

diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index f04d410043..73a9f89749 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3710,8 +3710,7 @@ inline void gcode_G28() {
     if (!dryrun) {
       // Re-orient the current position without leveling
       // based on where the steppers are positioned.
-      get_cartesian_from_steppers();
-      memcpy(current_position, cartes, sizeof(cartes));
+      set_current_from_steppers_for_axis(ALL_AXES);
 
       // Sync the planner to where the steppers stopped
       planner.sync_from_steppers();
@@ -4051,9 +4050,6 @@ inline void gcode_G28() {
         #if ENABLED(DEBUG_LEVELING_FEATURE)
           if (DEBUGGING(LEVELING)) DEBUG_POS("G29 corrected XYZ", current_position);
         #endif
-
-        SYNC_PLAN_POSITION_KINEMATIC();
-        abl_should_enable = true;
       }
 
     #elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
@@ -4063,14 +4059,13 @@ inline void gcode_G28() {
           if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR("G29 uncorrected Z:", current_position[Z_AXIS]);
         #endif
 
+        // Unapply the offset because it is going to be immediately applied
+        // and cause compensation movement in Z
         current_position[Z_AXIS] -= bilinear_z_offset(current_position);
 
         #if ENABLED(DEBUG_LEVELING_FEATURE)
           if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPAIR(" corrected Z:", current_position[Z_AXIS]);
         #endif
-
-        SYNC_PLAN_POSITION_KINEMATIC();
-        abl_should_enable = true;
       }
 
     #endif // ABL_PLANAR
@@ -4093,6 +4088,9 @@ inline void gcode_G28() {
 
     // Auto Bed Leveling is complete! Enable if possible.
     planner.abl_enabled = dryrun ? abl_should_enable : true;
+
+    if (planner.abl_enabled)
+      SYNC_PLAN_POSITION_KINEMATIC();
   }
 
 #endif // HAS_ABL

From 2d2c9bdf92d840fd5ed474d0107257f18453c50b Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:19:59 -0500
Subject: [PATCH 12/13] Add PROBE_Y_FIRST option for probe order

---
 Marlin/Configuration.h                        |  3 ++
 Marlin/Marlin_main.cpp                        | 44 +++++++++++++------
 .../Cartesio/Configuration.h                  |  3 ++
 .../Felix/Configuration.h                     |  3 ++
 .../Felix/DUAL/Configuration.h                |  3 ++
 .../Hephestos/Configuration.h                 |  3 ++
 .../Hephestos_2/Configuration.h               |  3 ++
 .../K8200/Configuration.h                     |  3 ++
 .../K8400/Configuration.h                     |  3 ++
 .../K8400/Dual-head/Configuration.h           |  3 ++
 .../RepRapWorld/Megatronics/Configuration.h   |  3 ++
 .../RigidBot/Configuration.h                  |  3 ++
 .../SCARA/Configuration.h                     |  3 ++
 .../TAZ4/Configuration.h                      |  3 ++
 .../WITBOX/Configuration.h                    |  3 ++
 .../adafruit/ST7565/Configuration.h           |  3 ++
 .../delta/biv2.5/Configuration.h              |  3 ++
 .../delta/generic/Configuration.h             |  3 ++
 .../delta/kossel_mini/Configuration.h         |  3 ++
 .../delta/kossel_pro/Configuration.h          |  3 ++
 .../delta/kossel_xl/Configuration.h           |  3 ++
 .../makibox/Configuration.h                   |  3 ++
 .../tvrrug/Round2/Configuration.h             |  3 ++
 23 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 53af44709e..79e091dc51 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -789,6 +789,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 73a9f89749..39bbb59055 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -3771,30 +3771,48 @@ inline void gcode_G28() {
 
       #endif // AUTO_BED_LEVELING_LINEAR
 
-      bool zig = abl_grid_points_y & 1; //always end at [RIGHT_PROBE_BED_POSITION, BACK_PROBE_BED_POSITION]
+      #if ENABLED(PROBE_Y_FIRST)
+        #define PR_OUTER_VAR xCount
+        #define PR_OUTER_END abl_grid_points_x
+        #define PR_INNER_VAR yCount
+        #define PR_INNER_END abl_grid_points_y
+      #else
+        #define PR_OUTER_VAR yCount
+        #define PR_OUTER_END abl_grid_points_y
+        #define PR_INNER_VAR xCount
+        #define PR_INNER_END abl_grid_points_x
+      #endif
 
-      for (uint8_t yCount = 0; yCount < abl_grid_points_y; yCount++) {
-        float yBase = front_probe_bed_position + yGridSpacing * yCount;
-        yProbe = floor(yBase + (yBase < 0 ? 0 : 0.5));
+      #if ENABLED(MAKERARM_SCARA)
+        bool zig = true;
+      #else
+        bool zig = PR_OUTER_END & 1; //always end at [RIGHT_PROBE_BED_POSITION, BACK_PROBE_BED_POSITION]
+      #endif
 
-        int8_t xStart, xStop, xInc;
+      for (uint8_t PR_OUTER_VAR = 0; PR_OUTER_VAR < PR_OUTER_END; PR_OUTER_VAR++) {
+
+        int8_t inStart, inStop, inInc;
 
         if (zig) {
-          xStart = 0;
-          xStop = abl_grid_points_x;
-          xInc = 1;
+          inStart = 0;
+          inStop = PR_INNER_END;
+          inInc = 1;
         }
         else {
-          xStart = abl_grid_points_x - 1;
-          xStop = -1;
-          xInc = -1;
+          inStart = PR_INNER_END - 1;
+          inStop = -1;
+          inInc = -1;
         }
 
         zig = !zig;
 
-        for (int8_t xCount = xStart; xCount != xStop; xCount += xInc) {
-          float xBase = left_probe_bed_position + xGridSpacing * xCount;
+        for (int8_t PR_INNER_VAR = inStart; PR_INNER_VAR != inStop; PR_INNER_VAR += inInc) {
+
+          float xBase = left_probe_bed_position + xGridSpacing * xCount,
+                yBase = front_probe_bed_position + yGridSpacing * yCount;
+
           xProbe = floor(xBase + (xBase < 0 ? 0 : 0.5));
+          yProbe = floor(yBase + (yBase < 0 ? 0 : 0.5));
 
           #if ENABLED(AUTO_BED_LEVELING_LINEAR)
             indexIntoAB[xCount][yCount] = ++probePointCounter;
diff --git a/Marlin/example_configurations/Cartesio/Configuration.h b/Marlin/example_configurations/Cartesio/Configuration.h
index df5249e11c..c796a696e7 100644
--- a/Marlin/example_configurations/Cartesio/Configuration.h
+++ b/Marlin/example_configurations/Cartesio/Configuration.h
@@ -789,6 +789,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/Felix/Configuration.h b/Marlin/example_configurations/Felix/Configuration.h
index 7eb6fa2c94..252493abd5 100644
--- a/Marlin/example_configurations/Felix/Configuration.h
+++ b/Marlin/example_configurations/Felix/Configuration.h
@@ -772,6 +772,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/Felix/DUAL/Configuration.h b/Marlin/example_configurations/Felix/DUAL/Configuration.h
index 062f97311c..c1d4524f8b 100644
--- a/Marlin/example_configurations/Felix/DUAL/Configuration.h
+++ b/Marlin/example_configurations/Felix/DUAL/Configuration.h
@@ -770,6 +770,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/Hephestos/Configuration.h b/Marlin/example_configurations/Hephestos/Configuration.h
index 6114fb40a8..8b6d00334c 100644
--- a/Marlin/example_configurations/Hephestos/Configuration.h
+++ b/Marlin/example_configurations/Hephestos/Configuration.h
@@ -781,6 +781,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/Hephestos_2/Configuration.h b/Marlin/example_configurations/Hephestos_2/Configuration.h
index e034ca6618..4fab4a3de8 100644
--- a/Marlin/example_configurations/Hephestos_2/Configuration.h
+++ b/Marlin/example_configurations/Hephestos_2/Configuration.h
@@ -783,6 +783,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/K8200/Configuration.h b/Marlin/example_configurations/K8200/Configuration.h
index a1e191674f..ffcdedf7e1 100644
--- a/Marlin/example_configurations/K8200/Configuration.h
+++ b/Marlin/example_configurations/K8200/Configuration.h
@@ -806,6 +806,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/K8400/Configuration.h b/Marlin/example_configurations/K8400/Configuration.h
index 961127a630..fed16b97a4 100644
--- a/Marlin/example_configurations/K8400/Configuration.h
+++ b/Marlin/example_configurations/K8400/Configuration.h
@@ -789,6 +789,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/K8400/Dual-head/Configuration.h b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
index f7725822e6..5584181ffc 100644
--- a/Marlin/example_configurations/K8400/Dual-head/Configuration.h
+++ b/Marlin/example_configurations/K8400/Dual-head/Configuration.h
@@ -789,6 +789,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
index 24ccf1fee6..b88108134a 100644
--- a/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
+++ b/Marlin/example_configurations/RepRapWorld/Megatronics/Configuration.h
@@ -789,6 +789,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/RigidBot/Configuration.h b/Marlin/example_configurations/RigidBot/Configuration.h
index eb2775715e..58352cb995 100644
--- a/Marlin/example_configurations/RigidBot/Configuration.h
+++ b/Marlin/example_configurations/RigidBot/Configuration.h
@@ -787,6 +787,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/SCARA/Configuration.h b/Marlin/example_configurations/SCARA/Configuration.h
index dbba6bcaa7..9afd49d19e 100644
--- a/Marlin/example_configurations/SCARA/Configuration.h
+++ b/Marlin/example_configurations/SCARA/Configuration.h
@@ -804,6 +804,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/TAZ4/Configuration.h b/Marlin/example_configurations/TAZ4/Configuration.h
index c68ddfd6dd..04045dde9c 100644
--- a/Marlin/example_configurations/TAZ4/Configuration.h
+++ b/Marlin/example_configurations/TAZ4/Configuration.h
@@ -810,6 +810,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/WITBOX/Configuration.h b/Marlin/example_configurations/WITBOX/Configuration.h
index 75f206f521..e48e1bb8b5 100644
--- a/Marlin/example_configurations/WITBOX/Configuration.h
+++ b/Marlin/example_configurations/WITBOX/Configuration.h
@@ -781,6 +781,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/adafruit/ST7565/Configuration.h b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
index 474a88cfa7..a83aca8614 100644
--- a/Marlin/example_configurations/adafruit/ST7565/Configuration.h
+++ b/Marlin/example_configurations/adafruit/ST7565/Configuration.h
@@ -789,6 +789,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/delta/biv2.5/Configuration.h b/Marlin/example_configurations/delta/biv2.5/Configuration.h
index 0de779f819..78207fea3d 100644
--- a/Marlin/example_configurations/delta/biv2.5/Configuration.h
+++ b/Marlin/example_configurations/delta/biv2.5/Configuration.h
@@ -881,6 +881,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h
index cc55f62dd9..45b9a8f147 100644
--- a/Marlin/example_configurations/delta/generic/Configuration.h
+++ b/Marlin/example_configurations/delta/generic/Configuration.h
@@ -875,6 +875,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
index e570ac9b70..608a9bf260 100644
--- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h
@@ -878,6 +878,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
index 4562647c3d..4a07b9bb54 100644
--- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h
@@ -879,6 +879,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
index 5b6389dfd9..242a7db472 100644
--- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h
+++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h
@@ -881,6 +881,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/makibox/Configuration.h b/Marlin/example_configurations/makibox/Configuration.h
index 76d4049b0a..2808750af2 100644
--- a/Marlin/example_configurations/makibox/Configuration.h
+++ b/Marlin/example_configurations/makibox/Configuration.h
@@ -792,6 +792,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.
diff --git a/Marlin/example_configurations/tvrrug/Round2/Configuration.h b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
index bdc2630f34..b75fe0b846 100644
--- a/Marlin/example_configurations/tvrrug/Round2/Configuration.h
+++ b/Marlin/example_configurations/tvrrug/Round2/Configuration.h
@@ -785,6 +785,9 @@
   // The Z probe minimum outer margin (to validate G29 parameters).
   #define MIN_PROBE_EDGE 10
 
+  // Probe along the Y axis, advancing X after each column
+  //#define PROBE_Y_FIRST
+
 #elif ENABLED(AUTO_BED_LEVELING_3POINT)
 
   // 3 arbitrary points to probe.

From d234bc160ec195589a419f271997c04d629ebb20 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <sourcetree@thinkyhead.com>
Date: Thu, 29 Sep 2016 01:39:40 -0500
Subject: [PATCH 13/13] Require Arduino 1.6.8 to compile

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

diff --git a/Marlin/SanityCheck.h b/Marlin/SanityCheck.h
index dee708ab02..d14eda6356 100644
--- a/Marlin/SanityCheck.h
+++ b/Marlin/SanityCheck.h
@@ -30,8 +30,8 @@
  * Due to the high number of issues related with old versions of Arduino IDE
  * we now prevent Marlin from compiling with older toolkits.
  */
-#if !defined(ARDUINO) || ARDUINO < 10600
-  #error "Versions of Arduino IDE prior to 1.6.0 are no longer supported, please update your toolkit."
+#if !defined(ARDUINO) || ARDUINO < 10608
+  #error "Versions of Arduino IDE prior to 1.6.8 are no longer supported, please update your toolkit."
 #endif
 
 /**