From 71be210795831ac1b478f7bfff09c33bd8a24499 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <thinkyhead@users.noreply.github.com>
Date: Thu, 21 Jan 2021 03:40:07 -0600
Subject: [PATCH] Move some MarlinCore and MarlinUI code (#20832)

---
 Marlin/src/MarlinCore.cpp                     | 118 ++++--------------
 Marlin/src/MarlinCore.h                       |  13 --
 Marlin/src/feature/e_parser.h                 |   1 -
 Marlin/src/feature/encoder_i2c.cpp            |   2 +
 Marlin/src/feature/pause.cpp                  |  47 ++-----
 Marlin/src/feature/pause.h                    |   6 +-
 Marlin/src/feature/runout.cpp                 |   3 +-
 Marlin/src/feature/runout.h                   |   8 +-
 Marlin/src/feature/twibus.cpp                 |  10 ++
 Marlin/src/feature/twibus.h                   |  13 ++
 Marlin/src/gcode/control/M108_M112_M410.cpp   |   3 +-
 Marlin/src/gcode/control/M226.cpp             |   2 +
 Marlin/src/gcode/control/M42.cpp              |   4 +
 Marlin/src/gcode/feature/i2c/M260_M261.cpp    |   2 +-
 Marlin/src/gcode/feature/pause/M125.cpp       |   9 +-
 Marlin/src/gcode/feature/pause/M600.cpp       |   9 +-
 Marlin/src/gcode/feature/pause/M701_M702.cpp  |  13 +-
 Marlin/src/gcode/gcode.cpp                    |  32 ++++-
 Marlin/src/gcode/gcode.h                      |   2 +
 Marlin/src/gcode/queue.cpp                    |   1 +
 Marlin/src/gcode/sd/M1001.cpp                 |   2 +-
 Marlin/src/lcd/dogm/marlinui_DOGM.cpp         |   2 +
 Marlin/src/lcd/dwin/e3v2/rotary_encoder.h     |   1 -
 .../anycubic_i3mega/anycubic_i3mega_lcd.cpp   |   4 +-
 Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h   |   5 +-
 .../extui/lib/mks_ui/tft_multi_language.cpp   |   2 -
 .../src/lcd/extui/lib/mks_ui/wifi_module.cpp  |   4 +
 Marlin/src/lcd/marlinui.cpp                   |   2 +-
 Marlin/src/lcd/marlinui.h                     |  25 ++--
 Marlin/src/lcd/menu/menu_configuration.cpp    |   2 +
 Marlin/src/lcd/menu/menu_delta_calibrate.cpp  |   2 +
 Marlin/src/lcd/menu/menu_filament.cpp         |   4 +-
 Marlin/src/lcd/menu/menu_motion.cpp           |   2 +
 Marlin/src/module/endstops.cpp                |   1 -
 Marlin/src/module/motion.cpp                  |  13 +-
 Marlin/src/module/motion.h                    |   2 +
 Marlin/src/module/probe.cpp                   |   2 +-
 Marlin/src/module/temperature.cpp             |  11 +-
 38 files changed, 178 insertions(+), 206 deletions(-)

diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index f994e2e32cd..20cbb35386b 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -43,6 +43,7 @@
 #include <math.h>
 
 #include "core/utility.h"
+
 #include "module/motion.h"
 #include "module/planner.h"
 #include "module/endstops.h"
@@ -57,6 +58,7 @@
 #include "gcode/parser.h"
 #include "gcode/queue.h"
 
+#include "feature/pause.h"
 #include "sd/cardreader.h"
 
 #include "lcd/marlinui.h"
@@ -139,7 +141,6 @@
 
 #if ENABLED(EXPERIMENTAL_I2CBUS)
   #include "feature/twibus.h"
-  TWIBus i2c;
 #endif
 
 #if ENABLED(I2C_POSITION_ENCODERS)
@@ -173,10 +174,6 @@
   #include "feature/bedlevel/bedlevel.h"
 #endif
 
-#if BOTH(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_NO_STEPPER_TIMEOUT)
-  #include "feature/pause.h"
-#endif
-
 #if ENABLED(GCODE_REPEAT_MARKERS)
   #include "feature/repeat.h"
 #endif
@@ -267,40 +264,12 @@ bool wait_for_heatup = true;
 
 #endif
 
-#if PIN_EXISTS(CHDK)
-  extern millis_t chdk_timeout;
-#endif
-
-#if ENABLED(I2C_POSITION_ENCODERS)
-  I2CPositionEncodersMgr I2CPEM;
-#endif
-
 /**
  * ***************************************************************************
  * ******************************** FUNCTIONS ********************************
  * ***************************************************************************
  */
 
-void setup_killpin() {
-  #if HAS_KILL
-    #if KILL_PIN_STATE
-      SET_INPUT_PULLDOWN(KILL_PIN);
-    #else
-      SET_INPUT_PULLUP(KILL_PIN);
-    #endif
-  #endif
-}
-
-void setup_powerhold() {
-  #if HAS_SUICIDE
-    OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
-  #endif
-  #if ENABLED(PSU_CONTROL)
-    powersupply_on = ENABLED(PSU_DEFAULT_OFF);
-    if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
-  #endif
-}
-
 /**
  * Stepper Reset (RigidBoard, et.al.)
  */
@@ -309,18 +278,6 @@ void setup_powerhold() {
   void enableStepperDrivers()  { SET_INPUT(STEPPER_RESET_PIN); }      // Set to input, allowing pullups to pull the pin high
 #endif
 
-#if ENABLED(EXPERIMENTAL_I2CBUS) && I2C_SLAVE_ADDRESS > 0
-
-  void i2c_on_receive(int bytes) { // just echo all bytes received to serial
-    i2c.receive(bytes);
-  }
-
-  void i2c_on_request() {          // just send dummy data for now
-    i2c.reply("Hello World!\n");
-  }
-
-#endif
-
 /**
  * Sensitive pin test for M42, M226
  */
@@ -342,17 +299,6 @@ bool pin_is_protected(const pin_t pin) {
 
 #pragma GCC diagnostic pop
 
-void protected_pin_err() {
-  SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN);
-}
-
-void quickstop_stepper() {
-  planner.quick_stop();
-  planner.synchronize();
-  set_current_from_steppers_for_axis(ALL_AXES);
-  sync_plan_position();
-}
-
 void enable_e_steppers() {
   #define _ENA_E(N) ENABLE_AXIS_E##N();
   REPEAT(E_STEPPERS, _ENA_E)
@@ -389,41 +335,6 @@ void disable_all_steppers() {
   TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
 }
 
-#if ENABLED(G29_RETRY_AND_RECOVER)
-
-  void event_probe_failure() {
-    #ifdef ACTION_ON_G29_FAILURE
-      host_action(PSTR(ACTION_ON_G29_FAILURE));
-    #endif
-    #ifdef G29_FAILURE_COMMANDS
-      gcode.process_subcommands_now_P(PSTR(G29_FAILURE_COMMANDS));
-    #endif
-    #if ENABLED(G29_HALT_ON_FAILURE)
-      #ifdef ACTION_ON_CANCEL
-        host_action_cancel();
-      #endif
-      kill(GET_TEXT(MSG_LCD_PROBING_FAILED));
-    #endif
-  }
-
-  void event_probe_recover() {
-    TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, PSTR("G29 Retrying"), DISMISS_STR));
-    #ifdef ACTION_ON_G29_RECOVER
-      host_action(PSTR(ACTION_ON_G29_RECOVER));
-    #endif
-    #ifdef G29_RECOVER_COMMANDS
-      gcode.process_subcommands_now_P(PSTR(G29_RECOVER_COMMANDS));
-    #endif
-  }
-
-#endif
-
-#if ENABLED(ADVANCED_PAUSE_FEATURE)
-  #include "feature/pause.h"
-#else
-  constexpr bool did_pause_print = false;
-#endif
-
 /**
  * A Print Job exists when the timer is running or SD printing
  */
@@ -511,8 +422,8 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
 
   // Prevent steppers timing-out in the middle of M600
   // unless PAUSE_PARK_NO_STEPPER_TIMEOUT is disabled
-  const bool parked_or_ignoring = ignore_stepper_queue ||
-     (BOTH(ADVANCED_PAUSE_FEATURE, PAUSE_PARK_NO_STEPPER_TIMEOUT) && did_pause_print);
+  const bool parked_or_ignoring = ignore_stepper_queue
+                               || TERN0(PAUSE_PARK_NO_STEPPER_TIMEOUT, did_pause_print);
 
   // Reset both the M18/M84 activity timeout and the M85 max 'kill' timeout
   if (parked_or_ignoring) gcode.reset_stepper_timeout(ms);
@@ -550,6 +461,7 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
   }
 
   #if PIN_EXISTS(CHDK) // Check if pin should be set to LOW (after M240 set it HIGH)
+    extern millis_t chdk_timeout;
     if (chdk_timeout && ELAPSED(ms, chdk_timeout)) {
       chdk_timeout = 0;
       WRITE(CHDK_PIN, LOW);
@@ -1038,13 +950,29 @@ void setup() {
     SETUP_RUN(recovery.setup());
   #endif
 
-  SETUP_RUN(setup_killpin());
+  #if HAS_KILL
+    SETUP_LOG("KILL_PIN");
+    #if KILL_PIN_STATE
+      SET_INPUT_PULLDOWN(KILL_PIN);
+    #else
+      SET_INPUT_PULLUP(KILL_PIN);
+    #endif
+  #endif
 
   #if HAS_TMC220x
     SETUP_RUN(tmc_serial_begin());
   #endif
 
-  SETUP_RUN(setup_powerhold());
+  #if HAS_SUICIDE
+    SETUP_LOG("SUICIDE_PIN")
+    OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
+  #endif
+
+  #if ENABLED(PSU_CONTROL)
+    SETUP_LOG("PSU_CONTROL");
+    powersupply_on = ENABLED(PSU_DEFAULT_OFF);
+    if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
+  #endif
 
   #if HAS_STEPPER_RESET
     SETUP_RUN(disableStepperDrivers());
diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h
index 908636e9677..f5bdbed535e 100644
--- a/Marlin/src/MarlinCore.h
+++ b/Marlin/src/MarlinCore.h
@@ -37,11 +37,6 @@ void stop();
 void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep=false));
 inline void idle_no_sleep() { idle(TERN_(ADVANCED_PAUSE_FEATURE, true)); }
 
-#if ENABLED(EXPERIMENTAL_I2CBUS)
-  #include "feature/twibus.h"
-  extern TWIBus i2c;
-#endif
-
 #if ENABLED(G38_PROBE_TARGET)
   extern uint8_t G38_move;          // Flag to tell the ISR that G38 is in progress, and the type
   extern bool G38_did_trigger;      // Flag from the ISR to indicate the endstop changed
@@ -59,8 +54,6 @@ void disable_all_steppers();
 void kill(PGM_P const lcd_error=nullptr, PGM_P const lcd_component=nullptr, const bool steppers_off=false);
 void minkill(const bool steppers_off=false);
 
-void quickstop_stepper();
-
 // Global State of the firmware
 enum MarlinState : uint8_t {
   MF_INITIALIZING =  0,
@@ -103,7 +96,6 @@ extern bool wait_for_heatup;
 #endif
 
 bool pin_is_protected(const pin_t pin);
-void protected_pin_err();
 
 #if HAS_SUICIDE
   inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_INVERTING); }
@@ -116,11 +108,6 @@ void protected_pin_err();
   inline bool kill_state() { return READ(KILL_PIN) == KILL_PIN_STATE; }
 #endif
 
-#if ENABLED(G29_RETRY_AND_RECOVER)
-  void event_probe_recover();
-  void event_probe_failure();
-#endif
-
 extern const char NUL_STR[], M112_KILL_STR[], G28_STR[], M21_STR[], M23_STR[], M24_STR[],
                   SP_A_STR[], SP_B_STR[], SP_C_STR[],
                   SP_P_STR[], SP_T_STR[], SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[],
diff --git a/Marlin/src/feature/e_parser.h b/Marlin/src/feature/e_parser.h
index a4c07de465d..659e516787f 100644
--- a/Marlin/src/feature/e_parser.h
+++ b/Marlin/src/feature/e_parser.h
@@ -33,7 +33,6 @@
 
 // External references
 extern bool wait_for_user, wait_for_heatup;
-void quickstop_stepper();
 
 class EmergencyParser {
 
diff --git a/Marlin/src/feature/encoder_i2c.cpp b/Marlin/src/feature/encoder_i2c.cpp
index dda165edf7e..fa3cf1503f4 100644
--- a/Marlin/src/feature/encoder_i2c.cpp
+++ b/Marlin/src/feature/encoder_i2c.cpp
@@ -41,6 +41,8 @@
 
 #include <Wire.h>
 
+I2CPositionEncodersMgr I2CPEM;
+
 void I2CPositionEncoder::init(const uint8_t address, const AxisEnum axis) {
   encoderAxis = axis;
   i2cAddress = address;
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index c8265a154fb..5ab4f2b146b 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -137,10 +137,7 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P
       thermalManager.setTargetHotend(thermalManager.extrude_min_temp, active_extruder);
   #endif
 
-  #if HAS_LCD_MENU
-    lcd_pause_show_message(PAUSE_MESSAGE_HEATING, mode);
-  #endif
-  UNUSED(mode);
+  ui.pause_show_message(PAUSE_MESSAGE_HEATING, mode); UNUSED(mode);
 
   if (wait) return thermalManager.wait_for_hotend(active_extruder);
 
@@ -181,19 +178,13 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
   DEBUG_SECTION(lf, "load_filament", true);
   DEBUG_ECHOLNPAIR("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", int(max_beep_count), " showlcd:", int(show_lcd), " pauseforuser:", int(pause_for_user), " pausemode:", int(mode) DXC_SAY);
 
-  UNUSED(show_lcd);
-
   if (!ensure_safe_temperature(false, mode)) {
-    #if HAS_LCD_MENU
-      if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS, mode);
-    #endif
+    if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_STATUS, mode);
     return false;
   }
 
   if (pause_for_user) {
-    #if HAS_LCD_MENU
-      if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_INSERT, mode);
-    #endif
+    if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_INSERT, mode);
     SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_INSERT));
 
     first_impatient_beep(max_beep_count);
@@ -217,9 +208,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
     }
   }
 
-  #if HAS_LCD_MENU
-    if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_LOAD, mode);
-  #endif
+  if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_LOAD, mode);
 
   #if ENABLED(DUAL_X_CARRIAGE)
     const int8_t saved_ext        = active_extruder;
@@ -250,9 +239,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
 
   #if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE)
 
-    #if HAS_LCD_MENU
-      if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_PURGE);
-    #endif
+    if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE);
 
     TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purging..."), CONTINUE_STR));
     TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired_P(PSTR("Filament Purging...")));
@@ -266,9 +253,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
     do {
       if (purge_length > 0) {
         // "Wait for filament purge"
-        #if HAS_LCD_MENU
-          if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_PURGE);
-        #endif
+        if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE);
 
         // Extrude filament to get into hotend
         unscaled_e_move(purge_length, ADVANCED_PAUSE_PURGE_FEEDRATE);
@@ -281,7 +266,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
           // Show "Purge More" / "Resume" menu and wait for reply
           KEEPALIVE_STATE(PAUSED_FOR_USER);
           wait_for_user = false;
-          lcd_pause_show_message(PAUSE_MESSAGE_OPTION);
+          ui.pause_show_message(PAUSE_MESSAGE_OPTION);
           while (pause_menu_response == PAUSE_RESPONSE_WAIT_FOR) idle_no_sleep();
         }
       #endif
@@ -330,22 +315,16 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/,
     #endif
   );
 
-  UNUSED(show_lcd);
-
   #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
     constexpr float mix_multiplier = 1.0;
   #endif
 
   if (!ensure_safe_temperature(false, mode)) {
-    #if HAS_LCD_MENU
-      if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_STATUS);
-    #endif
+    if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_STATUS);
     return false;
   }
 
-  #if HAS_LCD_MENU
-    if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_UNLOAD, mode);
-  #endif
+  if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_UNLOAD, mode);
 
   // Retract filament
   unscaled_e_move(-(FILAMENT_UNLOAD_PURGE_RETRACT) * mix_multiplier, (PAUSE_PARK_RETRACT_FEEDRATE) * mix_multiplier);
@@ -479,7 +458,7 @@ void show_continue_prompt(const bool is_reload) {
   DEBUG_SECTION(scp, "pause_print", true);
   DEBUG_ECHOLNPAIR("... is_reload:", int(is_reload));
 
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING));
+  ui.pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING);
   SERIAL_ECHO_START();
   serialprintPGM(is_reload ? PSTR(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : PSTR(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n"));
 }
@@ -520,7 +499,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
     // Wait for the user to press the button to re-heat the nozzle, then
     // re-heat the nozzle, re-show the continue prompt, restart idle timers, start over
     if (nozzle_timed_out) {
-      TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_HEAT));
+      ui.pause_show_message(PAUSE_MESSAGE_HEAT);
       SERIAL_ECHO_MSG(_PMSG(STR_FILAMENT_CHANGE_HEAT));
 
       TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_USER_CONTINUE, GET_TEXT(MSG_HEATER_TIMEOUT), GET_TEXT(MSG_REHEAT)));
@@ -614,7 +593,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
     thermalManager.wait_for_hotend(active_extruder, false);
   }
 
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_RESUME));
+  ui.pause_show_message(PAUSE_MESSAGE_RESUME);
 
   // Check Temperature before moving hotend
   ensure_safe_temperature();
@@ -653,7 +632,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
   // Write PLR now to update the z axis value
   TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
 
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS));
+  ui.pause_show_message(PAUSE_MESSAGE_STATUS);
 
   #ifdef ACTION_ON_RESUMED
     host_action_resumed();
diff --git a/Marlin/src/feature/pause.h b/Marlin/src/feature/pause.h
index c69ed73546e..7e58d4564eb 100644
--- a/Marlin/src/feature/pause.h
+++ b/Marlin/src/feature/pause.h
@@ -101,4 +101,8 @@ bool unload_filament(const float &unload_length, const bool show_lcd=false, cons
   #endif
 );
 
-#endif // ADVANCED_PAUSE_FEATURE
+#else // !ADVANCED_PAUSE_FEATURE
+
+  constexpr uint8_t did_pause_print = 0;
+
+#endif // !ADVANCED_PAUSE_FEATURE
diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp
index 50e18e52ef0..be769d2dc82 100644
--- a/Marlin/src/feature/runout.cpp
+++ b/Marlin/src/feature/runout.cpp
@@ -59,6 +59,7 @@ bool FilamentMonitorBase::enabled = true,
 // Filament Runout event handler
 //
 #include "../MarlinCore.h"
+#include "../feature/pause.h"
 #include "../gcode/queue.h"
 
 #if ENABLED(HOST_ACTION_COMMANDS)
@@ -71,7 +72,7 @@ bool FilamentMonitorBase::enabled = true,
 
 void event_filament_runout() {
 
-  if (TERN0(ADVANCED_PAUSE_FEATURE, did_pause_print)) return;  // Action already in progress. Purge triggered repeated runout.
+  if (did_pause_print) return;  // Action already in progress. Purge triggered repeated runout.
 
   #if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
     if (migration.in_progress) {
diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h
index 09443e6e2b2..4b93d01eb7a 100644
--- a/Marlin/src/feature/runout.h
+++ b/Marlin/src/feature/runout.h
@@ -118,9 +118,7 @@ class TFilamentMonitor : public FilamentMonitorBase {
 
     // Give the response a chance to update its counter.
     static inline void run() {
-      if ( enabled && !filament_ran_out
-        && (printingIsActive() || TERN0(ADVANCED_PAUSE_FEATURE, did_pause_print))
-      ) {
+      if (enabled && !filament_ran_out && (printingIsActive() || did_pause_print)) {
         TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here
         response.run();
         sensor.run();
@@ -343,9 +341,7 @@ class FilamentSensorBase {
       }
 
       static inline void block_completed(const block_t* const b) {
-        if (b->steps.x || b->steps.y || b->steps.z
-          || TERN0(ADVANCED_PAUSE_FEATURE, did_pause_print) // Allow pause purge move to re-trigger runout state
-        ) {
+        if (b->steps.x || b->steps.y || b->steps.z || did_pause_print) { // Allow pause purge move to re-trigger runout state
           // Only trigger on extrusion with XYZ movement to allow filament change and retract/recover.
           const uint8_t e = b->extruder;
           const int32_t steps = b->steps.e;
diff --git a/Marlin/src/feature/twibus.cpp b/Marlin/src/feature/twibus.cpp
index 3cc20579ac5..855a3188d10 100644
--- a/Marlin/src/feature/twibus.cpp
+++ b/Marlin/src/feature/twibus.cpp
@@ -28,6 +28,8 @@
 
 #include <Wire.h>
 
+TWIBus i2c;
+
 TWIBus::TWIBus() {
   #if I2C_SLAVE_ADDRESS == 0
     Wire.begin();                  // No address joins the BUS as the master
@@ -155,6 +157,14 @@ void TWIBus::flush() {
     reset();
   }
 
+  void i2c_on_receive(int bytes) { // just echo all bytes received to serial
+    i2c.receive(bytes);
+  }
+
+  void i2c_on_request() {          // just send dummy data for now
+    i2c.reply("Hello World!\n");
+  }
+
 #endif
 
 #if ENABLED(DEBUG_TWIBUS)
diff --git a/Marlin/src/feature/twibus.h b/Marlin/src/feature/twibus.h
index 82aa9aa16a2..59391534824 100644
--- a/Marlin/src/feature/twibus.h
+++ b/Marlin/src/feature/twibus.h
@@ -31,6 +31,17 @@
 typedef void (*twiReceiveFunc_t)(int bytes);
 typedef void (*twiRequestFunc_t)();
 
+/**
+ * For a light i2c protocol that runs on two boards running Marlin see:
+ * See https://github.com/MarlinFirmware/Marlin/issues/4776#issuecomment-246262879
+ */
+#if I2C_SLAVE_ADDRESS > 0
+
+  void i2c_on_receive(int bytes); // Demo i2c onReceive handler
+  void i2c_on_request();          // Demo i2c onRequest handler
+
+#endif
+
 #define TWIBUS_BUFFER_SIZE 32
 
 /**
@@ -238,3 +249,5 @@ class TWIBus {
       static inline void debug(const char[], uint8_t) {}
     #endif
 };
+
+extern TWIBus i2c;
diff --git a/Marlin/src/gcode/control/M108_M112_M410.cpp b/Marlin/src/gcode/control/M108_M112_M410.cpp
index df145d5d11c..f86874acec2 100644
--- a/Marlin/src/gcode/control/M108_M112_M410.cpp
+++ b/Marlin/src/gcode/control/M108_M112_M410.cpp
@@ -25,7 +25,8 @@
 #if DISABLED(EMERGENCY_PARSER)
 
 #include "../gcode.h"
-#include "../../MarlinCore.h" // for wait_for_heatup, kill, quickstop_stepper
+#include "../../MarlinCore.h" // for wait_for_heatup, kill
+#include "../../module/motion.h" // for quickstop_stepper
 
 /**
  * M108: Stop the waiting for heaters in M109, M190, M303. Does not affect the target temperature.
diff --git a/Marlin/src/gcode/control/M226.cpp b/Marlin/src/gcode/control/M226.cpp
index ad717e614d8..63f022e82bd 100644
--- a/Marlin/src/gcode/control/M226.cpp
+++ b/Marlin/src/gcode/control/M226.cpp
@@ -28,6 +28,8 @@
 #include "../../MarlinCore.h" // for pin_is_protected and idle()
 #include "../../module/stepper.h"
 
+void protected_pin_err();
+
 /**
  * M226: Wait until the specified pin reaches the state required (M226 P<pin> S<state>)
  */
diff --git a/Marlin/src/gcode/control/M42.cpp b/Marlin/src/gcode/control/M42.cpp
index c635c06ec63..6ef8455e0b5 100644
--- a/Marlin/src/gcode/control/M42.cpp
+++ b/Marlin/src/gcode/control/M42.cpp
@@ -31,6 +31,10 @@
   #include "../../module/temperature.h"
 #endif
 
+void protected_pin_err() {
+  SERIAL_ERROR_MSG(STR_ERR_PROTECTED_PIN);
+}
+
 /**
  * M42: Change pin status via GCode
  *
diff --git a/Marlin/src/gcode/feature/i2c/M260_M261.cpp b/Marlin/src/gcode/feature/i2c/M260_M261.cpp
index 526d9101e1c..438d1527f5f 100644
--- a/Marlin/src/gcode/feature/i2c/M260_M261.cpp
+++ b/Marlin/src/gcode/feature/i2c/M260_M261.cpp
@@ -26,7 +26,7 @@
 
 #include "../../gcode.h"
 
-#include "../../../MarlinCore.h" // for i2c
+#include "../../../feature/twibus.h"
 
 /**
  * M260: Send data to a I2C slave device
diff --git a/Marlin/src/gcode/feature/pause/M125.cpp b/Marlin/src/gcode/feature/pause/M125.cpp
index b1d76e83ae9..9391b8661b2 100644
--- a/Marlin/src/gcode/feature/pause/M125.cpp
+++ b/Marlin/src/gcode/feature/pause/M125.cpp
@@ -27,13 +27,10 @@
 #include "../../gcode.h"
 #include "../../parser.h"
 #include "../../../feature/pause.h"
+#include "../../../lcd/marlinui.h"
 #include "../../../module/motion.h"
-#include "../../../sd/cardreader.h"
 #include "../../../module/printcounter.h"
-
-#if HAS_LCD_MENU
-  #include "../../../lcd/marlinui.h"
-#endif
+#include "../../../sd/cardreader.h"
 
 #if ENABLED(POWER_LOSS_RECOVERY)
   #include "../../../feature/powerloss.h"
@@ -76,7 +73,7 @@ void GcodeSuite::M125() {
 
   const bool sd_printing = TERN0(SDSUPPORT, IS_SD_PRINTING());
 
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT));
+  ui.pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT);
 
   // If possible, show an LCD prompt with the 'P' flag
   const bool show_lcd = TERN0(HAS_LCD_MENU, parser.boolval('P'));
diff --git a/Marlin/src/gcode/feature/pause/M600.cpp b/Marlin/src/gcode/feature/pause/M600.cpp
index db8bc93a9f8..1c282f2052c 100644
--- a/Marlin/src/gcode/feature/pause/M600.cpp
+++ b/Marlin/src/gcode/feature/pause/M600.cpp
@@ -28,15 +28,12 @@
 #include "../../../feature/pause.h"
 #include "../../../module/motion.h"
 #include "../../../module/printcounter.h"
+#include "../../../lcd/marlinui.h"
 
 #if HAS_MULTI_EXTRUDER
   #include "../../../module/tool_change.h"
 #endif
 
-#if HAS_LCD_MENU
-  #include "../../../lcd/marlinui.h"
-#endif
-
 #if ENABLED(MMU2_MENUS)
   #include "../../../lcd/menu/menu_mmu2.h"
 #endif
@@ -96,8 +93,8 @@ void GcodeSuite::M600() {
   #endif
 
   // Show initial "wait for start" message
-  #if HAS_LCD_MENU && DISABLED(MMU2_MENUS)
-    lcd_pause_show_message(PAUSE_MESSAGE_CHANGING, PAUSE_MODE_PAUSE_PRINT, target_extruder);
+  #if DISABLED(MMU2_MENUS)
+    ui.pause_show_message(PAUSE_MESSAGE_CHANGING, PAUSE_MODE_PAUSE_PRINT, target_extruder);
   #endif
 
   #if ENABLED(HOME_BEFORE_FILAMENT_CHANGE)
diff --git a/Marlin/src/gcode/feature/pause/M701_M702.cpp b/Marlin/src/gcode/feature/pause/M701_M702.cpp
index a889da8aeaa..9a2b7749366 100644
--- a/Marlin/src/gcode/feature/pause/M701_M702.cpp
+++ b/Marlin/src/gcode/feature/pause/M701_M702.cpp
@@ -29,15 +29,12 @@
 #include "../../../module/motion.h"
 #include "../../../module/temperature.h"
 #include "../../../feature/pause.h"
+#include "../../../lcd/marlinui.h"
 
 #if HAS_MULTI_EXTRUDER
   #include "../../../module/tool_change.h"
 #endif
 
-#if HAS_LCD_MENU
-  #include "../../../lcd/marlinui.h"
-#endif
-
 #if HAS_PRUSA_MMU2
   #include "../../../feature/mmu/mmu2.h"
 #endif
@@ -82,7 +79,7 @@ void GcodeSuite::M701() {
   if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
 
   // Show initial "wait for load" message
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_LOAD, PAUSE_MODE_LOAD_FILAMENT, target_extruder));
+  ui.pause_show_message(PAUSE_MESSAGE_LOAD, PAUSE_MODE_LOAD_FILAMENT, target_extruder);
 
   #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU)
     // Change toolhead if specified
@@ -128,7 +125,7 @@ void GcodeSuite::M701() {
   TERN_(MIXING_EXTRUDER, mixer.T(old_mixing_tool)); // Restore original mixing tool
 
   // Show status screen
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS));
+  ui.pause_show_message(PAUSE_MESSAGE_STATUS);
 }
 
 /**
@@ -180,7 +177,7 @@ void GcodeSuite::M702() {
   if (parser.seenval('Z')) park_point.z = parser.linearval('Z');
 
   // Show initial "wait for unload" message
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_UNLOAD, PAUSE_MODE_UNLOAD_FILAMENT, target_extruder));
+  ui.pause_show_message(PAUSE_MESSAGE_UNLOAD, PAUSE_MODE_UNLOAD_FILAMENT, target_extruder);
 
   #if HAS_MULTI_EXTRUDER && (HAS_PRUSA_MMU1 || !HAS_MMU)
     // Change toolhead if specified
@@ -232,7 +229,7 @@ void GcodeSuite::M702() {
   TERN_(MIXING_EXTRUDER, mixer.T(old_mixing_tool)); // Restore original mixing tool
 
   // Show status screen
-  TERN_(HAS_LCD_MENU, lcd_pause_show_message(PAUSE_MESSAGE_STATUS));
+  ui.pause_show_message(PAUSE_MESSAGE_STATUS);
 }
 
 #endif // ADVANCED_PAUSE_FEATURE
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 90a0b0ded00..88607b4081c 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -61,7 +61,7 @@ GcodeSuite gcode;
   #include "../feature/password/password.h"
 #endif
 
-#include "../MarlinCore.h" // for idle()
+#include "../MarlinCore.h" // for idle, kill
 
 // Inactivity shutdown
 millis_t GcodeSuite::previous_move_ms = 0,
@@ -209,6 +209,31 @@ void GcodeSuite::dwell(millis_t time) {
  */
 #if BOTH(HAS_LEVELING, G29_RETRY_AND_RECOVER)
 
+  void GcodeSuite::event_probe_recover() {
+    TERN_(HOST_PROMPT_SUPPORT, host_prompt_do(PROMPT_INFO, PSTR("G29 Retrying"), DISMISS_STR));
+    #ifdef ACTION_ON_G29_RECOVER
+      host_action(PSTR(ACTION_ON_G29_RECOVER));
+    #endif
+    #ifdef G29_RECOVER_COMMANDS
+      process_subcommands_now_P(PSTR(G29_RECOVER_COMMANDS));
+    #endif
+  }
+
+  void GcodeSuite::event_probe_failure() {
+    #ifdef ACTION_ON_G29_FAILURE
+      host_action(PSTR(ACTION_ON_G29_FAILURE));
+    #endif
+    #ifdef G29_FAILURE_COMMANDS
+      process_subcommands_now_P(PSTR(G29_FAILURE_COMMANDS));
+    #endif
+    #if ENABLED(G29_HALT_ON_FAILURE)
+      #ifdef ACTION_ON_CANCEL
+        host_action_cancel();
+      #endif
+      kill(GET_TEXT(MSG_LCD_PROBING_FAILED));
+    #endif
+  }
+
   #ifndef G29_MAX_RETRIES
     #define G29_MAX_RETRIES 0
   #endif
@@ -216,7 +241,10 @@ void GcodeSuite::dwell(millis_t time) {
   void GcodeSuite::G29_with_retry() {
     uint8_t retries = G29_MAX_RETRIES;
     while (G29()) { // G29 should return true for failed probes ONLY
-      if (retries--) event_probe_recover();
+      if (retries) {
+        event_probe_recover();
+        --retries;
+      }
       else {
         event_probe_failure();
         return;
diff --git a/Marlin/src/gcode/gcode.h b/Marlin/src/gcode/gcode.h
index 9453eecd946..2b7589662e4 100644
--- a/Marlin/src/gcode/gcode.h
+++ b/Marlin/src/gcode/gcode.h
@@ -452,6 +452,8 @@ private:
 
   #if HAS_LEVELING
     #if ENABLED(G29_RETRY_AND_RECOVER)
+      static void event_probe_failure();
+      static void event_probe_recover();
       static void G29_with_retry();
       #define G29_TYPE bool
     #else
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 98fe91db407..8197205edac 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -31,6 +31,7 @@ GCodeQueue queue;
 
 #include "../lcd/marlinui.h"
 #include "../sd/cardreader.h"
+#include "../module/motion.h"
 #include "../module/planner.h"
 #include "../module/temperature.h"
 #include "../MarlinCore.h"
diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp
index 406cd074c3c..cba0e51af16 100644
--- a/Marlin/src/gcode/sd/M1001.cpp
+++ b/Marlin/src/gcode/sd/M1001.cpp
@@ -44,7 +44,7 @@
 #endif
 
 #if HAS_LEDS_OFF_FLAG
-  #include "../../MarlinCore.h" // for wait_for_user_response
+  #include "../../MarlinCore.h" // for wait_for_user_response()
   #include "../../feature/leds/printer_event_leds.h"
 #endif
 
diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp
index c7c5908b36b..1ab76a208dc 100644
--- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp
@@ -544,6 +544,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
 
       // Put Relevant Text on Display
 
+      extern const char X_LBL[], Y_LBL[], Z_LBL[];
+
       // Show X and Y positions at top of screen
       u8g.setColorIndex(1);
       if (PAGE_UNDER(7)) {
diff --git a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h
index bbba753a0ba..7de80dfe01c 100644
--- a/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h
+++ b/Marlin/src/lcd/dwin/e3v2/rotary_encoder.h
@@ -30,7 +30,6 @@
   ****************************************************************************/
 
 #include "../../../inc/MarlinConfig.h"
-#include "../../../MarlinCore.h"
 
 /*********************** Encoder Set ***********************/
 
diff --git a/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp
index a3f7c42a5ca..baf2da63581 100644
--- a/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp
+++ b/Marlin/src/lcd/extui/lib/anycubic_i3mega/anycubic_i3mega_lcd.cpp
@@ -27,8 +27,8 @@
 #include "../../ui_api.h"
 
 #include "../../../../libs/numtostr.h"
-#include "../../../../module/motion.h"  // for A20 read printing speed feedrate_percentage
-#include "../../../../MarlinCore.h"     // for quickstop_stepper, disable_steppers, G28_STR
+#include "../../../../module/motion.h"  // for quickstop_stepper, A20 read printing speed, feedrate_percentage
+#include "../../../../MarlinCore.h"     // for disable_steppers, G28_STR
 #include "../../../../inc/MarlinConfig.h"
 
 // command sending macro's with debugging capability
diff --git a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h
index ee536ea2190..88c119566cc 100644
--- a/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h
+++ b/Marlin/src/lcd/extui/lib/dgus/DGUSDisplay.h
@@ -25,7 +25,8 @@
 
 #include "../../../../inc/MarlinConfigPre.h"
 
-#include "../../../../MarlinCore.h"
+#include <stdlib.h>    // size_t
+
 #if HAS_BED_PROBE
   #include "../../../../module/probe.h"
 #endif
@@ -96,7 +97,7 @@ private:
   static void WritePGM(const char str[], uint8_t len);
   static void ProcessRx();
 
-  static inline uint16_t swap16(const uint16_t value) { return (value & 0xffU) << 8U | (value >> 8U); }
+  static inline uint16_t swap16(const uint16_t value) { return (value & 0xFFU) << 8U | (value >> 8U); }
   static rx_datagram_state_t rx_datagram_state;
   static uint8_t rx_datagram_len;
   static bool Initialized, no_reentrance;
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp
index 7db5e805619..28c90486d09 100644
--- a/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp
+++ b/Marlin/src/lcd/extui/lib/mks_ui/tft_multi_language.cpp
@@ -23,8 +23,6 @@
 
 #if HAS_TFT_LVGL_UI
 
-#include "../../../../MarlinCore.h"
-
 #include "draw_ui.h"
 #include "tft_multi_language.h"
 
diff --git a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp
index 1f8676126c8..fa01b7196fb 100644
--- a/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp
+++ b/Marlin/src/lcd/extui/lib/mks_ui/wifi_module.cpp
@@ -39,6 +39,10 @@
 #include "../../../../module/planner.h"
 #include "../../../../module/servo.h"
 #include "../../../../module/probe.h"
+
+#if DISABLED(EMERGENCY_PARSER)
+  #include "../../../../module/motion.h"
+#endif
 #if ENABLED(POWER_LOSS_RECOVERY)
   #include "../../../../feature/powerloss.h"
 #endif
diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp
index d13c8e409de..25f3903ddc2 100644
--- a/Marlin/src/lcd/marlinui.cpp
+++ b/Marlin/src/lcd/marlinui.cpp
@@ -1516,7 +1516,7 @@ void MarlinUI::update() {
     LCD_MESSAGEPGM(MSG_PRINT_PAUSED);
 
     #if ENABLED(PARK_HEAD_ON_PAUSE)
-      TERN_(HAS_WIRED_LCD, lcd_pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT)); // Show message immediately to let user know about pause in progress
+      pause_show_message(PAUSE_MESSAGE_PARKING, PAUSE_MODE_PAUSE_PRINT); // Show message immediately to let user know about pause in progress
       queue.inject_P(PSTR("M25 P\nM24"));
     #elif ENABLED(SDSUPPORT)
       queue.inject_P(PSTR("M25"));
diff --git a/Marlin/src/lcd/marlinui.h b/Marlin/src/lcd/marlinui.h
index 95a521d5dd8..2e55c9ad1d2 100644
--- a/Marlin/src/lcd/marlinui.h
+++ b/Marlin/src/lcd/marlinui.h
@@ -51,15 +51,13 @@
   #include "../module/printcounter.h"
 #endif
 
+#if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE)
+  #include "../feature/pause.h"
+  #include "../module/motion.h" // for active_extruder
+#endif
+
 #if HAS_WIRED_LCD
 
-  #include "../MarlinCore.h"
-
-  #if ENABLED(ADVANCED_PAUSE_FEATURE)
-    #include "../feature/pause.h"
-    #include "../module/motion.h" // for active_extruder
-  #endif
-
   enum LCDViewAction : uint8_t {
     LCDVIEW_NONE,
     LCDVIEW_REDRAW_NOW,
@@ -87,12 +85,6 @@
     typedef void (*screenFunc_t)();
     typedef void (*menuAction_t)();
 
-    #if ENABLED(ADVANCED_PAUSE_FEATURE)
-      void lcd_pause_show_message(const PauseMessage message,
-                                  const PauseMode mode=PAUSE_MODE_SAME,
-                                  const uint8_t extruder=active_extruder);
-    #endif
-
     #if ENABLED(AUTO_BED_LEVELING_UBL)
       void lcd_mesh_edit_setup(const float &initial);
       float lcd_mesh_edit();
@@ -506,6 +498,13 @@ public:
 
   #endif
 
+  #if BOTH(HAS_LCD_MENU, ADVANCED_PAUSE_FEATURE)
+    static void pause_show_message(const PauseMessage message, const PauseMode mode=PAUSE_MODE_SAME, const uint8_t extruder=active_extruder);
+  #else
+    static inline void _pause_show_message() {}
+    #define pause_show_message(...) _pause_show_message()
+  #endif
+
   //
   // EEPROM: Reset / Init / Load / Store
   //
diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp
index 7b95f435baa..39752a6fe5a 100644
--- a/Marlin/src/lcd/menu/menu_configuration.cpp
+++ b/Marlin/src/lcd/menu/menu_configuration.cpp
@@ -161,6 +161,8 @@ void menu_advanced_settings();
   #include "../../module/motion.h"
   #include "../../gcode/queue.h"
 
+  extern const char G28_STR[];
+
   void menu_tool_offsets() {
 
     auto _recalc_offsets = []{
diff --git a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp
index 4efcb7c8ede..7411bb1ac21 100644
--- a/Marlin/src/lcd/menu/menu_delta_calibrate.cpp
+++ b/Marlin/src/lcd/menu/menu_delta_calibrate.cpp
@@ -53,6 +53,7 @@ void _man_probe_pt(const xy_pos_t &xy) {
 
 #if ENABLED(DELTA_AUTO_CALIBRATION)
 
+  #include "../../MarlinCore.h" // for wait_for_user_response()
   #include "../../gcode/gcode.h"
 
   #if ENABLED(HOST_PROMPT_SUPPORT)
@@ -81,6 +82,7 @@ void _man_probe_pt(const xy_pos_t &xy) {
   }
 
   void _lcd_delta_calibrate_home() {
+    extern const char G28_STR[];
     queue.inject_P(G28_STR);
     ui.goto_screen(_lcd_calibrate_homing);
   }
diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp
index 7bd12bde17b..19601d678e0 100644
--- a/Marlin/src/lcd/menu/menu_filament.cpp
+++ b/Marlin/src/lcd/menu/menu_filament.cpp
@@ -107,6 +107,8 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) {
  */
 #if E_STEPPERS > 1 || ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
 
+  bool printingIsPaused();
+
   void menu_change_filament() {
     // Say "filament change" when no print is active
     editable.int8 = printingIsPaused() ? PAUSE_MODE_PAUSE_PRINT : PAUSE_MODE_CHANGE_FILAMENT;
@@ -315,7 +317,7 @@ FORCE_INLINE screenFunc_t ap_message_screen(const PauseMessage message) {
   return nullptr;
 }
 
-void lcd_pause_show_message(
+void MarlinUI::pause_show_message(
   const PauseMessage message,
   const PauseMode mode/*=PAUSE_MODE_SAME*/,
   const uint8_t extruder/*=active_extruder*/
diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp
index ecc378b6076..5206cf4fe84 100644
--- a/Marlin/src/lcd/menu/menu_motion.cpp
+++ b/Marlin/src/lcd/menu/menu_motion.cpp
@@ -51,6 +51,8 @@
   float manual_move_e_origin = 0;
 #endif
 
+extern const char G28_STR[];
+
 //
 // "Motion" > "Move Axis" submenu
 //
diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp
index b1c7c1c5851..b9d2c1cdf56 100644
--- a/Marlin/src/module/endstops.cpp
+++ b/Marlin/src/module/endstops.cpp
@@ -27,7 +27,6 @@
 #include "endstops.h"
 #include "stepper.h"
 
-#include "../MarlinCore.h"
 #include "../sd/cardreader.h"
 #include "temperature.h"
 #include "../lcd/marlinui.h"
diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp
index 99853f24df1..f7fc66b27af 100644
--- a/Marlin/src/module/motion.cpp
+++ b/Marlin/src/module/motion.cpp
@@ -236,8 +236,17 @@ void report_current_position_projected() {
 }
 
 /**
- * sync_plan_position
- *
+ * Run out the planner buffer and re-sync the current
+ * position from the last-updated stepper positions.
+ */
+void quickstop_stepper() {
+  planner.quick_stop();
+  planner.synchronize();
+  set_current_from_steppers_for_axis(ALL_AXES);
+  sync_plan_position();
+}
+
+/**
  * Set the planner/stepper positions directly from current_position with
  * no kinematic translation. Used for homing axes and cartesian/core syncing.
  */
diff --git a/Marlin/src/module/motion.h b/Marlin/src/module/motion.h
index 9352a4e4e6a..887da1aa188 100644
--- a/Marlin/src/module/motion.h
+++ b/Marlin/src/module/motion.h
@@ -212,6 +212,8 @@ void report_current_position_projected();
 void get_cartesian_from_steppers();
 void set_current_from_steppers_for_axis(const AxisEnum axis);
 
+void quickstop_stepper();
+
 /**
  * sync_plan_position
  *
diff --git a/Marlin/src/module/probe.cpp b/Marlin/src/module/probe.cpp
index cc5c5e88152..94c409eb721 100644
--- a/Marlin/src/module/probe.cpp
+++ b/Marlin/src/module/probe.cpp
@@ -38,7 +38,7 @@
 #include "../gcode/gcode.h"
 #include "../lcd/marlinui.h"
 
-#include "../MarlinCore.h" // for stop(), disable_e_steppers
+#include "../MarlinCore.h" // for stop(), disable_e_steppers(), wait_for_user_response()
 
 #if HAS_LEVELING
   #include "../feature/bedlevel/bedlevel.h"
diff --git a/Marlin/src/module/temperature.cpp b/Marlin/src/module/temperature.cpp
index c15270f5ebc..00a048736a6 100644
--- a/Marlin/src/module/temperature.cpp
+++ b/Marlin/src/module/temperature.cpp
@@ -27,14 +27,17 @@
 // Useful when debugging thermocouples
 //#define IGNORE_THERMOCOUPLE_ERRORS
 
+#include "../MarlinCore.h"
+#include "../HAL/shared/Delay.h"
+#include "../lcd/marlinui.h"
+
 #include "temperature.h"
 #include "endstops.h"
-
-#include "../MarlinCore.h"
 #include "planner.h"
-#include "../HAL/shared/Delay.h"
 
-#include "../lcd/marlinui.h"
+#if ENABLED(EMERGENCY_PARSER)
+  #include "motion.h"
+#endif
 
 #if ENABLED(DWIN_CREALITY_LCD)
   #include "../lcd/dwin/e3v2/dwin.h"