Skip to content

Commit

Permalink
🚸 Interruptible PLR
Browse files Browse the repository at this point in the history
  • Loading branch information
thinkyhead committed Feb 17, 2023
1 parent 38e6330 commit 1035d66
Showing 1 changed file with 47 additions and 39 deletions.
86 changes: 47 additions & 39 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 @@ -345,27 +353,34 @@ void PrintJobRecovery::write() {
*/
void PrintJobRecovery::resume() {

struct OnExit {
uint8_t old_flags;
OnExit() {
old_flags = marlin_debug_flags;
if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN;
TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags |= MARLIN_DEBUG_ECHO);
}
~OnExit() { marlin_debug_flags = old_flags; }
} on_exit;

char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16];

const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it

// Apply the dry-run flag if enabled
if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN;

// 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 +391,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 +408,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 +419,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 +432,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 +462,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 +504,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 +524,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 +546,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 +588,15 @@ 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);
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

0 comments on commit 1035d66

Please sign in to comment.