Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interruptible PLR #25395

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 49 additions & 38 deletions Marlin/src/feature/powerloss.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -352,20 +360,31 @@ 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
const celsius_t bt = info.target_temperature_bed;
if (bt) {
// Restore the bed temperature
sprintf_P(cmd, PSTR("M190S%i"), bt);
gcode.process_subcommands_now(cmd);
PROCESS_SUBCOMMANDS_NOW(cmd);
}
#endif

Expand All @@ -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
Expand All @@ -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

Expand All @@ -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)

Expand All @@ -417,26 +436,26 @@ 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

#if HOMING_Z_DOWN
// 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)
Expand All @@ -447,37 +466,37 @@ 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

#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
// 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
#if DISABLED(NO_VOLUMETRICS)
#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
Expand All @@ -489,18 +508,18 @@ 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

// 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
Expand All @@ -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
Expand All @@ -531,37 +550,37 @@ 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
sprintf_P(cmd, PSTR("G1X%sY%sF3000"),
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);
Expand All @@ -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)
Expand Down