diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 2825f4d4f2..1037f823f6 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -78,6 +78,14 @@ PrintJobRecovery recovery; #define POWER_LOSS_RETRACT_LEN 0 #endif +// Allow power-loss recovery to be aborted +#define PLR_CAN_ABORT +#if ENABLED(PLR_CAN_ABORT) + #define PROCESS_SUBCOMMANDS_NOW(cmd) do { if (card.flag.abort_sd_printing) return; gcode.process_subcommands_now(cmd); }while(0) +#else + #define PROCESS_SUBCOMMANDS_NOW(cmd) gcode.process_subcommands_now(cmd) +#endif + /** * Clear the recovery info */ @@ -352,12 +360,23 @@ void PrintJobRecovery::resume() { // Apply the dry-run flag if enabled if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN; + #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) + struct OnExit { + uint8_t old_flags; + OnExit() { + old_flags = marlin_debug_flags; + marlin_debug_flags |= MARLIN_DEBUG_ECHO; + } + ~OnExit() { marlin_debug_flags = old_flags; } + } on_exit; + #endif + // Restore cold extrusion permission TERN_(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude = info.flag.allow_cold_extrusion); #if HAS_LEVELING // Make sure leveling is off before any G92 and G28 - gcode.process_subcommands_now(F("M420 S0 Z0")); + PROCESS_SUBCOMMANDS_NOW(F("M420S0")); #endif #if HAS_HEATED_BED @@ -365,7 +384,7 @@ void PrintJobRecovery::resume() { if (bt) { // Restore the bed temperature sprintf_P(cmd, PSTR("M190S%i"), bt); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } #endif @@ -376,10 +395,10 @@ void PrintJobRecovery::resume() { if (et) { #if HAS_MULTI_HOTEND sprintf_P(cmd, PSTR("T%iS"), e); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif sprintf_P(cmd, PSTR("M109S%i"), et); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } } #endif @@ -393,7 +412,7 @@ void PrintJobRecovery::resume() { // establish the current position as best we can. // - gcode.process_subcommands_now(F("G92.9E0")); // Reset E to 0 + PROCESS_SUBCOMMANDS_NOW(F("G92.9E0")); // Reset E to 0 #if Z_HOME_TO_MAX @@ -404,7 +423,7 @@ void PrintJobRecovery::resume() { "G28R0\n" // Home all axes (no raise) "G1Z%sF1200" // Move Z down to (raised) height ), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #elif DISABLED(BELTPRINTER) @@ -417,18 +436,18 @@ void PrintJobRecovery::resume() { #if !HOMING_Z_DOWN // Set Z to the real position sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif // Does Z need to be raised now? It should be raised before homing XY. if (z_raised > z_now) { z_now = z_raised; sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } // Home XY with no Z raise - gcode.process_subcommands_now(F("G28R0XY")); // No raise during G28 + PROCESS_SUBCOMMANDS_NOW(F("G28R0XY")); // No raise during G28 #endif @@ -436,7 +455,7 @@ void PrintJobRecovery::resume() { // Move to a safe XY position and home Z while avoiding the print. const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy); sprintf_P(cmd, PSTR("G1X%sY%sF1000\nG28HZ"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif // Mark all axes as having been homed (no effect on current_position) @@ -447,12 +466,12 @@ void PrintJobRecovery::resume() { // Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option. // TODO: Add a G28 parameter to leave leveling disabled. sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #if !HOMING_Z_DOWN // The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9. sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 1, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif #endif @@ -460,7 +479,7 @@ void PrintJobRecovery::resume() { // Z was homed down to the bed, so move up to the raised height. z_now = z_raised; sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif // Recover volumetric extrusion state @@ -468,16 +487,16 @@ void PrintJobRecovery::resume() { #if HAS_MULTI_EXTRUDER EXTRUDER_LOOP() { sprintf_P(cmd, PSTR("M200T%iD%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } if (!info.flag.volumetric_enabled) { sprintf_P(cmd, PSTR("M200T%iD0"), info.active_extruder); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } #else if (info.flag.volumetric_enabled) { sprintf_P(cmd, PSTR("M200D%s"), dtostrf(info.filament_size[0], 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } #endif #endif @@ -489,10 +508,10 @@ void PrintJobRecovery::resume() { if (et) { #if HAS_MULTI_HOTEND sprintf_P(cmd, PSTR("T%iS"), e); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif sprintf_P(cmd, PSTR("M109S%i"), et); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } } #endif @@ -500,7 +519,7 @@ void PrintJobRecovery::resume() { // Restore the previously active tool (with no_move) #if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND sprintf_P(cmd, PSTR("T%i S"), info.active_extruder); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif // Restore print cooling fan speeds @@ -509,7 +528,7 @@ void PrintJobRecovery::resume() { const int f = info.fan_speed[i]; if (f) { sprintf_P(cmd, PSTR("M106P%iS%i"), i, f); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); } } #endif @@ -531,17 +550,17 @@ void PrintJobRecovery::resume() { // Un-retract if there was a retract at outage #if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0 - gcode.process_subcommands_now(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN))); + PROCESS_SUBCOMMANDS_NOW(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN))); #endif // Additional purge on resume if configured #if POWER_LOSS_PURGE_LEN sprintf_P(cmd, PSTR("G1F3000E%d"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); #endif #if ENABLED(NOZZLE_CLEAN_FEATURE) - gcode.process_subcommands_now(F("G12")); + PROCESS_SUBCOMMANDS_NOW(F("G12")); #endif // Move back over to the saved XY @@ -549,19 +568,19 @@ void PrintJobRecovery::resume() { dtostrf(info.current_position.x, 1, 3, str_1), dtostrf(info.current_position.y, 1, 3, str_2) ); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); // Move back down to the saved Z for printing sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_print, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); // Restore the feedrate sprintf_P(cmd, PSTR("G1F%d"), info.feedrate); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); // Restore E position with G92.9 sprintf_P(cmd, PSTR("G92.9E%s"), dtostrf(info.current_position.e, 1, 3, str_1)); - gcode.process_subcommands_now(cmd); + PROCESS_SUBCOMMANDS_NOW(cmd); TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat); TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset); @@ -573,22 +592,14 @@ void PrintJobRecovery::resume() { // Relative axis modes gcode.axis_relative = info.axis_relative; - #if ENABLED(DEBUG_POWER_LOSS_RECOVERY) - const uint8_t old_flags = marlin_debug_flags; - marlin_debug_flags |= MARLIN_DEBUG_ECHO; - #endif - // Continue to apply PLR when a file is resumed! enable(true); // Resume the SD file from the last position - char *fn = info.sd_filename; - sprintf_P(cmd, M23_STR, fn); - gcode.process_subcommands_now(cmd); + sprintf_P(cmd, M23_STR, &info.sd_filename[0]); + PROCESS_SUBCOMMANDS_NOW(cmd); sprintf_P(cmd, PSTR("M24S%ldT%ld"), resume_sdpos, info.print_job_elapsed); - gcode.process_subcommands_now(cmd); - - TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags = old_flags); + PROCESS_SUBCOMMANDS_NOW(cmd); } #if ENABLED(DEBUG_POWER_LOSS_RECOVERY)