|  |  |  | @@ -29,6 +29,8 @@ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #if ENABLED(ADVANCED_PAUSE_FEATURE) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | //#define DEBUG_PAUSE_RESUME | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #include "../MarlinCore.h" | 
		
	
		
			
				|  |  |  |  | #include "../gcode/gcode.h" | 
		
	
		
			
				|  |  |  |  | #include "../module/motion.h" | 
		
	
	
		
			
				
					
					|  |  |  | @@ -62,6 +64,9 @@ | 
		
	
		
			
				|  |  |  |  | #include "../libs/nozzle.h" | 
		
	
		
			
				|  |  |  |  | #include "pause.h" | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | #define DEBUG_OUT ENABLED(DEBUG_PAUSE_RESUME) | 
		
	
		
			
				|  |  |  |  | #include "../core/debug_out.h" | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | // private: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | static xyze_pos_t resume_position; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -120,26 +125,33 @@ fil_change_settings_t fc_settings[EXTRUDERS]; | 
		
	
		
			
				|  |  |  |  |  * Returns 'true' if heating was completed, 'false' for abort | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=PAUSE_MODE_SAME) { | 
		
	
		
			
				|  |  |  |  |   DEBUG_SECTION(est, "ensure_safe_temperature", true); | 
		
	
		
			
				|  |  |  |  |   DEBUG_ECHOLNPAIR("... wait:", int(wait), " mode:", int(mode)); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) | 
		
	
		
			
				|  |  |  |  |     thermalManager.setTargetHotend(thermalManager.extrude_min_temp, active_extruder); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   #if HAS_LCD_MENU | 
		
	
		
			
				|  |  |  |  |     lcd_pause_show_message(PAUSE_MESSAGE_HEATING, mode); | 
		
	
		
			
				|  |  |  |  |   #endif | 
		
	
		
			
				|  |  |  |  |   UNUSED(mode); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (wait) | 
		
	
		
			
				|  |  |  |  |     return thermalManager.wait_for_hotend(active_extruder); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   wait_for_heatup = true; // Allow interruption by Emergency Parser M108 | 
		
	
		
			
				|  |  |  |  |   while (wait_for_heatup && ABS(thermalManager.degHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > TEMP_WINDOW) | 
		
	
		
			
				|  |  |  |  |     idle(); | 
		
	
		
			
				|  |  |  |  |   wait_for_heatup = false; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   #if ENABLED(PREVENT_COLD_EXTRUSION) | 
		
	
		
			
				|  |  |  |  |     // A user can cancel wait-for-heating with M108 | 
		
	
		
			
				|  |  |  |  |     if (!DEBUGGING(DRYRUN) && thermalManager.targetTooColdToExtrude(active_extruder)) { | 
		
	
		
			
				|  |  |  |  |       SERIAL_ECHO_MSG(STR_ERR_HOTEND_TOO_COLD); | 
		
	
		
			
				|  |  |  |  |       return false; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |   #endif | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   #if HAS_LCD_MENU | 
		
	
		
			
				|  |  |  |  |     lcd_pause_show_message(PAUSE_MESSAGE_HEATING, mode); | 
		
	
		
			
				|  |  |  |  |   #else | 
		
	
		
			
				|  |  |  |  |     UNUSED(mode); | 
		
	
		
			
				|  |  |  |  |   #endif | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (wait) | 
		
	
		
			
				|  |  |  |  |     return thermalManager.wait_for_hotend(active_extruder); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   while (ABS(thermalManager.degHotend(active_extruder) - thermalManager.degTargetHotend(active_extruder)) > TEMP_WINDOW) | 
		
	
		
			
				|  |  |  |  |     idle(); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   return true; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -160,7 +172,10 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l | 
		
	
		
			
				|  |  |  |  |                    const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/ | 
		
	
		
			
				|  |  |  |  |                    DXC_ARGS | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  |   TERN(HAS_LCD_MENU,,UNUSED(show_lcd)); | 
		
	
		
			
				|  |  |  |  |   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 | 
		
	
	
		
			
				
					
					|  |  |  | @@ -292,7 +307,14 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, | 
		
	
		
			
				|  |  |  |  |                        , const float &mix_multiplier/*=1.0*/ | 
		
	
		
			
				|  |  |  |  |                      #endif | 
		
	
		
			
				|  |  |  |  | ) { | 
		
	
		
			
				|  |  |  |  |   TERN(HAS_LCD_MENU,,UNUSED(show_lcd)); | 
		
	
		
			
				|  |  |  |  |   DEBUG_SECTION(uf, "unload_filament", true); | 
		
	
		
			
				|  |  |  |  |   DEBUG_ECHOLNPAIR("... unloadlen:", unload_length, " showlcd:", int(show_lcd), " mode:", int(mode) | 
		
	
		
			
				|  |  |  |  |     #if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) | 
		
	
		
			
				|  |  |  |  |       , " mixmult:", mix_multiplier | 
		
	
		
			
				|  |  |  |  |     #endif | 
		
	
		
			
				|  |  |  |  |   ); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   UNUSED(show_lcd); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   #if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER) | 
		
	
		
			
				|  |  |  |  |     constexpr float mix_multiplier = 1.0; | 
		
	
	
		
			
				
					
					|  |  |  | @@ -358,7 +380,10 @@ bool unload_filament(const float &unload_length, const bool show_lcd/*=false*/, | 
		
	
		
			
				|  |  |  |  | uint8_t did_pause_print = 0; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | bool pause_print(const float &retract, const xyz_pos_t &park_point, const float &unload_length/*=0*/, const bool show_lcd/*=false*/ DXC_ARGS) { | 
		
	
		
			
				|  |  |  |  |   TERN(HAS_LCD_MENU,,UNUSED(show_lcd)); | 
		
	
		
			
				|  |  |  |  |   DEBUG_SECTION(pp, "pause_print", true); | 
		
	
		
			
				|  |  |  |  |   DEBUG_ECHOLNPAIR("... retract:", retract, " park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", int(show_lcd) DXC_SAY); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   UNUSED(show_lcd); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   if (did_pause_print) return false; // already paused | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -449,12 +474,18 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | 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)); | 
		
	
		
			
				|  |  |  |  |   SERIAL_ECHO_START(); | 
		
	
		
			
				|  |  |  |  |   serialprintPGM(is_reload ? PSTR(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : PSTR(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n")); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) { | 
		
	
		
			
				|  |  |  |  |   DEBUG_SECTION(wfc, "wait_for_confirmation", true); | 
		
	
		
			
				|  |  |  |  |   DEBUG_ECHOLNPAIR("... is_reload:", is_reload, " maxbeep:", int(max_beep_count) DXC_SAY); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   bool nozzle_timed_out = false; | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   show_continue_prompt(is_reload); | 
		
	
	
		
			
				
					
					|  |  |  | @@ -551,6 +582,9 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep | 
		
	
		
			
				|  |  |  |  |  * - Resume the current SD print job, if any | 
		
	
		
			
				|  |  |  |  |  */ | 
		
	
		
			
				|  |  |  |  | void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_length/*=0*/, const float &purge_length/*=ADVANCED_PAUSE_PURGE_LENGTH*/, const int8_t max_beep_count/*=0*/, int16_t targetTemp/*=0*/ DXC_ARGS) { | 
		
	
		
			
				|  |  |  |  |   DEBUG_SECTION(rp, "resume_print", true); | 
		
	
		
			
				|  |  |  |  |   DEBUG_ECHOLNPAIR("... slowlen:", slow_load_length, " fastlen:", fast_load_length, " purgelen:", purge_length, " maxbeep:", int(max_beep_count), " targetTemp:", targetTemp DXC_SAY); | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |   /* | 
		
	
		
			
				|  |  |  |  |   SERIAL_ECHOLNPAIR( | 
		
	
		
			
				|  |  |  |  |     "start of resume_print()\ndual_x_carriage_mode:", dual_x_carriage_mode, | 
		
	
	
		
			
				
					
					|  |  |  |   |