From cbdbeb3e697b4100fac7bc0b8724fa24c2f176ae Mon Sep 17 00:00:00 2001
From: Roxy-3D <Roxy-3D@users.noreply.github.com>
Date: Wed, 17 Jan 2018 22:51:19 -0600
Subject: [PATCH] PronterFace M105 work around (#9227)

PronterFace keeps sending M105 requests during long operations like G29 P1, G29 P2, G29 P4 and G26. The serial buffer fills up before the operation is complete. The problem is, a corrupted command gets executed. It is very typical for the M105 to turn into a M1 (actually... M1M105 is typical).

This causes the printer to say "Click to resume..."

This is a temporary fix until we figure out the correct way to resolve the issue.

More work needed for G26.
---
 Marlin/G26_Mesh_Validation_Tool.cpp            | 12 +++++++++++-
 Marlin/MarlinSerial.cpp                        |  2 +-
 .../FolgerTech/i3-2020/Configuration_adv.h     |  2 +-
 Marlin/ubl.h                                   | 18 +++++++++---------
 Marlin/ubl_G29.cpp                             | 14 ++++++++++----
 5 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/Marlin/G26_Mesh_Validation_Tool.cpp b/Marlin/G26_Mesh_Validation_Tool.cpp
index 3f18f5a225d..8a3bd7bcd27 100644
--- a/Marlin/G26_Mesh_Validation_Tool.cpp
+++ b/Marlin/G26_Mesh_Validation_Tool.cpp
@@ -34,6 +34,7 @@
   #include "temperature.h"
   #include "ultralcd.h"
   #include "gcode.h"
+  #include "serial.h"
   #include "bitmap_flags.h"
 
   #if ENABLED(MESH_BED_LEVELING)
@@ -499,6 +500,9 @@
               SERIAL_EOL();
             }
             idle();
+            MYSERIAL.flush();  // G26 takes a long time to complete.   PronterFace can
+                               // over run the serial character buffer with M105's without
+                               // this fix
           }
       #if ENABLED(ULTRA_LCD)
         }
@@ -521,8 +525,11 @@
         SERIAL_EOL();
       }
       idle();
-    }
 
+      MYSERIAL.flush();  // G26 takes a long time to complete.   PronterFace can
+                         // over run the serial character buffer with M105's without
+                         // this fix
+    }
     #if ENABLED(ULTRA_LCD)
       lcd_reset_status();
       lcd_quick_feedback(true);
@@ -820,6 +827,9 @@
         if (look_for_lines_to_connect())
           goto LEAVE;
       }
+      MYSERIAL.flush();  // G26 takes a long time to complete.   PronterFace can
+                         // over run the serial character buffer with M105's without
+                         // this fix
     } while (--g26_repeats && location.x_index >= 0 && location.y_index >= 0);
 
     LEAVE:
diff --git a/Marlin/MarlinSerial.cpp b/Marlin/MarlinSerial.cpp
index 896db69ce12..91a0eab7068 100644
--- a/Marlin/MarlinSerial.cpp
+++ b/Marlin/MarlinSerial.cpp
@@ -385,7 +385,7 @@
     // reading rx_buffer_head and updating rx_buffer_tail, the previous rx_buffer_head
     // may be written to rx_buffer_tail, making the buffer appear full rather than empty.
     CRITICAL_SECTION_START;
-      rx_buffer.head = rx_buffer.tail;
+      rx_buffer.head = rx_buffer.tail = 0;
     CRITICAL_SECTION_END;
 
     #if ENABLED(SERIAL_XON_XOFF)
diff --git a/Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h
index 051afa3d3e0..9b36dbd12fc 100644
--- a/Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h
+++ b/Marlin/example_configurations/FolgerTech/i3-2020/Configuration_adv.h
@@ -1562,7 +1562,7 @@
  * Fully assembled MAX7219 boards can be found on the internet for under $2(US).
  * For example, see https://www.ebay.com/sch/i.html?_nkw=332349290049
  */
-//#define MAX7219_DEBUG
+#define MAX7219_DEBUG
 #if ENABLED(MAX7219_DEBUG)
 //#define MAX7219_CLK_PIN   64  // on RAMPS       // Configuration of the 3 pins to control the display
 //#define MAX7219_DIN_PIN   57  // on RAMPS
diff --git a/Marlin/ubl.h b/Marlin/ubl.h
index db134c9ef2d..b5ddb05ad0c 100644
--- a/Marlin/ubl.h
+++ b/Marlin/ubl.h
@@ -92,14 +92,14 @@
         static void move_z_with_encoder(const float &multiplier);
         static float measure_point_with_encoder();
         static float measure_business_card_thickness(const float);
-        static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool);
-        static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map);
+        static void manually_probe_remaining_mesh(const float&, const float&, const float&, const float&, const bool) _O0;
+        static void fine_tune_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map) _O0;
       #endif
 
-      static bool g29_parameter_parsing();
+      static bool g29_parameter_parsing() _O0;
       static void find_mean_mesh_height();
       static void shift_mesh_height();
-      static void probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest);
+      static void probe_entire_mesh(const float &rx, const float &ry, const bool do_ubl_mesh_map, const bool stow_probe, bool do_furthest) _O0;
       static void tilt_mesh_based_on_3pts(const float &z1, const float &z2, const float &z3);
       static void tilt_mesh_based_on_probed_grid(const bool do_ubl_mesh_map);
       static void g29_what_command();
@@ -114,16 +114,16 @@
       static void report_state();
       static void save_ubl_active_state_and_disable();
       static void restore_ubl_active_state_and_leave();
-      static void display_map(const int);
-      static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16]);
-      static mesh_index_pair find_furthest_invalid_mesh_point();
+      static void display_map(const int) _O0;
+      static mesh_index_pair find_closest_mesh_point_of_type(const MeshPointType, const float&, const float&, const bool, uint16_t[16]) _O0;
+      static mesh_index_pair find_furthest_invalid_mesh_point() _O0;
       static void reset();
       static void invalidate();
       static void set_all_mesh_points_to_value(const float);
       static bool sanity_check();
 
-      static void G29() _O0;                          // O0 for no optimization
-      static void smart_fill_wlsf(const float &) _O2; // O2 gives smaller code than Os on A2560
+      static void G29() _O0;                      // O0 for no optimization
+      static void smart_fill_wlsf(const float &); // O2 gives smaller code than Os on A2560
       static int8_t storage_slot;
 
       static float z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
diff --git a/Marlin/ubl_G29.cpp b/Marlin/ubl_G29.cpp
index a047a81dab7..7d9fb017671 100644
--- a/Marlin/ubl_G29.cpp
+++ b/Marlin/ubl_G29.cpp
@@ -32,6 +32,7 @@
   #include "stepper.h"
   #include "planner.h"
   #include "gcode.h"
+  #include "serial.h"
   #include "bitmap_flags.h"
 
   #include <math.h>
@@ -451,10 +452,8 @@
               SERIAL_PROTOCOL(g29_y_pos);
               SERIAL_PROTOCOLLNPGM(").\n");
             }
-SERIAL_ECHO("Going into probe_entire_mesh()\n");
             probe_entire_mesh(g29_x_pos + X_PROBE_OFFSET_FROM_EXTRUDER, g29_y_pos + Y_PROBE_OFFSET_FROM_EXTRUDER,
                               parser.seen('T'), parser.seen('E'), parser.seen('U'));
-SERIAL_ECHO("Back from probe_entire_mesh()\n");
             break;
 
         #endif // HAS_BED_PROBE
@@ -579,7 +578,6 @@ SERIAL_ECHO("Back from probe_entire_mesh()\n");
 
         case 6: shift_mesh_height(); break;
       }
-SERIAL_ECHO("at end of if (parser.seen('P')) {\n");
     }
 
     //
@@ -796,7 +794,9 @@ SERIAL_ECHO("at end of if (parser.seen('P')) {\n");
           const float measured_z = probe_pt(rawx, rawy, stow_probe, g29_verbose_level); // TODO: Needs error handling
           z_values[location.x_index][location.y_index] = measured_z;
         }
-
+        MYSERIAL.flush();  // G29 P2's take a long time to complete.   PronterFace can
+                           // over run the serial character buffer with M105's without
+                           // this fix
       } while (location.x_index >= 0 && --max_iterations);
 
       STOW_PROBE();
@@ -1037,6 +1037,9 @@ SERIAL_ECHO("at end of if (parser.seen('P')) {\n");
           SERIAL_PROTOCOL_F(z_values[location.x_index][location.y_index], 6);
           SERIAL_EOL();
         }
+        MYSERIAL.flush();  // G29 P2's take a long time to complete.   PronterFace can
+                           // over run the serial character buffer with M105's without
+                           // this fix
       } while (location.x_index >= 0 && location.y_index >= 0);
 
       if (do_ubl_mesh_map) display_map(g29_map_type);  // show user where we're probing
@@ -1548,6 +1551,9 @@ SERIAL_ECHO("at end of if (parser.seen('P')) {\n");
             do_blocking_move_to_z(h_offset + new_z); // Move the nozzle as the point is edited
           #endif
           idle();
+          MYSERIAL.flush();  // G29 P2's take a long time to complete.   PronterFace can
+                             // over run the serial character buffer with M105's without
+                             // this fix
         } while (!is_lcd_clicked());
 
         if (!lcd_map_control) lcd_return_to_status();