From 34f7142323080aac77444894b7bd3dfd64b0e752 Mon Sep 17 00:00:00 2001
From: Sola <42537573+solawc@users.noreply.github.com>
Date: Sat, 10 Apr 2021 04:29:59 +0800
Subject: [PATCH] Fix manual move with MKS H43 (#21511)

Co-authored-by: Scott Lahteine <github@thinkyhead.com>
---
 Marlin/src/gcode/gcode.cpp                    |  4 ++
 Marlin/src/gcode/gcode.h                      |  4 ++
 .../lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp |  6 +--
 .../lcd/extui/lib/dgus/mks/DGUSDisplayDef.h   |  2 +-
 .../extui/lib/dgus/mks/DGUSScreenHandler.cpp  | 54 ++++++++++++++-----
 5 files changed, 52 insertions(+), 18 deletions(-)

diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index cdf11e870b2..574e93aeccc 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -977,6 +977,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
         case 1001: M1001(); break;                                // M1001: [INTERNAL] Handle SD completion
       #endif
 
+      #if ENABLED(DGUS_LCD_UI_MKS)
+        case 1002: M1002(); break;                                // M1002: [INTERNAL] Tool-change and Relative E Move
+      #endif
+
       #if ENABLED(MAX7219_GCODE)
         case 7219: M7219(); break;                                // M7219: Set LEDs, columns, and rows
       #endif
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 7ea2489584a..977fc8bfd80 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -1069,6 +1069,10 @@ private:
     static void M1001();
   #endif
 
+  #if ENABLED(DGUS_LCD_UI_MKS)
+    static void M1002();
+  #endif
+
   #if ENABLED(MAX7219_GCODE)
     static void M7219();
   #endif
diff --git a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp
index 355565ae5aa..911965b9ae9 100644
--- a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp
+++ b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.cpp
@@ -45,7 +45,7 @@
 
 uint16_t manualMoveStep = 1;
 uint16_t distanceFilament = 10;
-uint16_t FilamentSpeed = 25;
+uint16_t filamentSpeed_mm_s = 25;
 float ZOffset_distance = 0.1;
 float mesh_adj_distance = 0.01;
 float Z_distance = 0.1;
@@ -555,7 +555,7 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
       VPHELPER(VP_LOAD_Filament, nullptr, &ScreenHandler.MKS_FilamentLoad, nullptr),
       VPHELPER(VP_UNLOAD_Filament, nullptr, &ScreenHandler.MKS_FilamentUnLoad, nullptr),
       VPHELPER(VP_Filament_distance, &distanceFilament, &ScreenHandler.GetManualFilament, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
-      VPHELPER(VP_Filament_speed, &FilamentSpeed, &ScreenHandler.GetManualFilamentSpeed, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
+      VPHELPER(VP_Filament_speed, &filamentSpeed_mm_s, &ScreenHandler.GetManualFilamentSpeed, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
     #endif
   #endif
 
@@ -569,7 +569,7 @@ const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
 
     #if ENABLED(DGUS_FILAMENT_LOADUNLOAD)
       VPHELPER(VP_Filament_distance, &distanceFilament, &ScreenHandler.GetManualFilament, ScreenHandler.DGUSLCD_SendFloatAsIntValueToDisplay<0>),
-      VPHELPER(VP_Filament_speed, &FilamentSpeed, &ScreenHandler.GetManualFilamentSpeed, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
+      VPHELPER(VP_Filament_speed, &filamentSpeed_mm_s, &ScreenHandler.GetManualFilamentSpeed, ScreenHandler.DGUSLCD_SendWordValueToDisplay),
     #endif
 
     #if ENABLED(PIDTEMP)
diff --git a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.h b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.h
index ac0a482edea..f174f38d960 100644
--- a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.h
+++ b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSDisplayDef.h
@@ -37,7 +37,7 @@
 
 extern uint16_t manualMoveStep;
 extern uint16_t distanceFilament;
-extern uint16_t FilamentSpeed;
+extern uint16_t filamentSpeed_mm_s;
 extern float    ZOffset_distance;
 extern float    mesh_adj_distance;
 extern float    Z_distance;
diff --git a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp
index b507c1ec3eb..e6e2af42ebe 100644
--- a/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp
+++ b/Marlin/src/lcd/extui/lib/dgus/mks/DGUSScreenHandler.cpp
@@ -840,7 +840,7 @@ void DGUSScreenHandler::HandleManualMove(DGUS_VP_Variable &var, void *val_ptr) {
     // buf[4] = axiscode;
 
     char buf[6];
-    sprintf(buf,"G28 %c",axiscode);
+    sprintf(buf, "G28 %c", axiscode);
     //DEBUG_ECHOPAIR(" ", buf);
     queue.enqueue_one_now(buf);
     //DEBUG_ECHOLNPGM(" ✓");
@@ -1190,17 +1190,18 @@ void DGUSScreenHandler::GetManualFilamentSpeed(DGUS_VP_Variable &var, void *val_
 
   uint16_t value_len = swap16(*(uint16_t*)val_ptr);
 
-  DEBUG_ECHOLNPAIR_F("FilamentSpeed value:", value_len);
+  DEBUG_ECHOLNPAIR_F("filamentSpeed_mm_s value:", value_len);
 
-  FilamentSpeed = value_len;
+  filamentSpeed_mm_s = value_len;
 
   skipVP = var.VP; // don't overwrite value the next update time as the display might autoincrement in parallel
 }
 
 void DGUSScreenHandler::MKS_FilamentLoadUnload(DGUS_VP_Variable &var, void *val_ptr, const int filamentDir) {
   #if EITHER(HAS_MULTI_HOTEND, SINGLENOZZLE)
-    char buf[40];
     uint8_t swap_tool = 0;
+  #else
+    constexpr uint8_t swap_tool = 1; // T0 (or none at all)
   #endif
 
   #if HAS_HOTEND
@@ -1215,9 +1216,8 @@ void DGUSScreenHandler::MKS_FilamentLoadUnload(DGUS_VP_Variable &var, void *val_
     default: break;
     case 0:
       #if HAS_HOTEND
-        if (thermalManager.tooColdToExtrude(0)) {
+        if (thermalManager.tooColdToExtrude(0))
           hotend_too_cold = 1;
-        }
         else {
           #if EITHER(HAS_MULTI_HOTEND, SINGLENOZZLE)
             swap_tool = 1;
@@ -1243,15 +1243,41 @@ void DGUSScreenHandler::MKS_FilamentLoadUnload(DGUS_VP_Variable &var, void *val_
     }
   #endif
 
+  if (swap_tool) {
+    char buf[30];
+    snprintf_P(buf, 30
+      #if EITHER(HAS_MULTI_HOTEND, SINGLENOZZLE)
+        , PSTR("M1002T%cE%dF%d"), char('0' + swap_tool - 1)
+      #else
+        , PSTR("M1002E%dF%d")
+      #endif
+      , (int)distanceFilament * filamentDir, filamentSpeed_mm_s * 60
+    );
+    queue.inject(buf);
+  }
+}
+
+/**
+ * M1002: Do a tool-change and relative move for MKS_FilamentLoadUnload
+ *        within the G-code execution window for best concurrency.
+ */
+void GcodeSuite::M1002() {
   #if EITHER(HAS_MULTI_HOTEND, SINGLENOZZLE)
-    if (swap_tool) {
-      queue.enqueue_now_P(swap_tool == 2 ? PSTR("T1") : PSTR("T0"));
-      queue.enqueue_now_P(PSTR("G91"));
-      snprintf_P(buf, 40, PSTR("G1 E%d F%d"), (int)distanceFilament * filamentDir, FilamentSpeed * 60);
-      queue.enqueue_one_now(buf);
-      queue.enqueue_now_P(PSTR("G90"));
-    }
+  {
+    char buf[3];
+    sprintf_P(buf, PSTR("T%c"), char('0' + parser.intval('T')));
+    process_subcommands_now(buf);
+  }
   #endif
+
+  const uint8_t old_axis_relative = axis_relative;
+  set_e_relative(true); // M83
+  {
+    char buf[20];
+    snprintf_P(buf, 20, PSTR("G1E%dF%d"), parser.intval('E'), parser.intval('F'));
+    process_subcommands_now(buf);
+  }
+  axis_relative = old_axis_relative;
 }
 
 void DGUSScreenHandler::MKS_FilamentLoad(DGUS_VP_Variable &var, void *val_ptr) {
@@ -1445,7 +1471,7 @@ void DGUSScreenHandler::LanguagePInit() {
 void DGUSScreenHandler::DGUS_ExtrudeLoadInit(void) {
   ex_filament.ex_length           = distanceFilament;
   ex_filament.ex_load_unload_flag = 0;
-  ex_filament.ex_need_time        = FilamentSpeed;
+  ex_filament.ex_need_time        = filamentSpeed_mm_s;
   ex_filament.ex_speed            = 0;
   ex_filament.ex_status           = EX_NONE;
   ex_filament.ex_tick_end         = 0;