Skip to content

Commit dfec3a2

Browse files
committed
🚸 Interruptible PLR (MarlinFirmware#25395)
1 parent c694370 commit dfec3a2

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

Marlin/src/feature/powerloss.cpp

+49-38
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@ PrintJobRecovery recovery;
7878
#define POWER_LOSS_RETRACT_LEN 0
7979
#endif
8080

81+
// Allow power-loss recovery to be aborted
82+
#define PLR_CAN_ABORT
83+
#if ENABLED(PLR_CAN_ABORT)
84+
#define PROCESS_SUBCOMMANDS_NOW(cmd) do { if (card.flag.abort_sd_printing) return; gcode.process_subcommands_now(cmd); }while(0)
85+
#else
86+
#define PROCESS_SUBCOMMANDS_NOW(cmd) gcode.process_subcommands_now(cmd)
87+
#endif
88+
8189
/**
8290
* Clear the recovery info
8391
*/
@@ -352,20 +360,31 @@ void PrintJobRecovery::resume() {
352360
// Apply the dry-run flag if enabled
353361
if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN;
354362

363+
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
364+
struct OnExit {
365+
uint8_t old_flags;
366+
OnExit() {
367+
old_flags = marlin_debug_flags;
368+
marlin_debug_flags |= MARLIN_DEBUG_ECHO;
369+
}
370+
~OnExit() { marlin_debug_flags = old_flags; }
371+
} on_exit;
372+
#endif
373+
355374
// Restore cold extrusion permission
356375
TERN_(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude = info.flag.allow_cold_extrusion);
357376

358377
#if HAS_LEVELING
359378
// Make sure leveling is off before any G92 and G28
360-
gcode.process_subcommands_now(F("M420 S0 Z0"));
379+
PROCESS_SUBCOMMANDS_NOW(F("M420S0"));
361380
#endif
362381

363382
#if HAS_HEATED_BED
364383
const celsius_t bt = info.target_temperature_bed;
365384
if (bt) {
366385
// Restore the bed temperature
367386
sprintf_P(cmd, PSTR("M190S%i"), bt);
368-
gcode.process_subcommands_now(cmd);
387+
PROCESS_SUBCOMMANDS_NOW(cmd);
369388
}
370389
#endif
371390

@@ -376,10 +395,10 @@ void PrintJobRecovery::resume() {
376395
if (et) {
377396
#if HAS_MULTI_HOTEND
378397
sprintf_P(cmd, PSTR("T%iS"), e);
379-
gcode.process_subcommands_now(cmd);
398+
PROCESS_SUBCOMMANDS_NOW(cmd);
380399
#endif
381400
sprintf_P(cmd, PSTR("M109S%i"), et);
382-
gcode.process_subcommands_now(cmd);
401+
PROCESS_SUBCOMMANDS_NOW(cmd);
383402
}
384403
}
385404
#endif
@@ -393,7 +412,7 @@ void PrintJobRecovery::resume() {
393412
// establish the current position as best we can.
394413
//
395414

396-
gcode.process_subcommands_now(F("G92.9E0")); // Reset E to 0
415+
PROCESS_SUBCOMMANDS_NOW(F("G92.9E0")); // Reset E to 0
397416

398417
#if Z_HOME_TO_MAX
399418

@@ -404,7 +423,7 @@ void PrintJobRecovery::resume() {
404423
"G28R0\n" // Home all axes (no raise)
405424
"G1Z%sF1200" // Move Z down to (raised) height
406425
), dtostrf(z_now, 1, 3, str_1));
407-
gcode.process_subcommands_now(cmd);
426+
PROCESS_SUBCOMMANDS_NOW(cmd);
408427

409428
#elif DISABLED(BELTPRINTER)
410429

@@ -417,26 +436,26 @@ void PrintJobRecovery::resume() {
417436
#if !HOMING_Z_DOWN
418437
// Set Z to the real position
419438
sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 3, str_1));
420-
gcode.process_subcommands_now(cmd);
439+
PROCESS_SUBCOMMANDS_NOW(cmd);
421440
#endif
422441

423442
// Does Z need to be raised now? It should be raised before homing XY.
424443
if (z_raised > z_now) {
425444
z_now = z_raised;
426445
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1));
427-
gcode.process_subcommands_now(cmd);
446+
PROCESS_SUBCOMMANDS_NOW(cmd);
428447
}
429448

430449
// Home XY with no Z raise
431-
gcode.process_subcommands_now(F("G28R0XY")); // No raise during G28
450+
PROCESS_SUBCOMMANDS_NOW(F("G28R0XY")); // No raise during G28
432451

433452
#endif
434453

435454
#if HOMING_Z_DOWN
436455
// Move to a safe XY position and home Z while avoiding the print.
437456
const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy);
438457
sprintf_P(cmd, PSTR("G1X%sY%sF1000\nG28HZ"), dtostrf(p.x, 1, 3, str_1), dtostrf(p.y, 1, 3, str_2));
439-
gcode.process_subcommands_now(cmd);
458+
PROCESS_SUBCOMMANDS_NOW(cmd);
440459
#endif
441460

442461
// Mark all axes as having been homed (no effect on current_position)
@@ -447,37 +466,37 @@ void PrintJobRecovery::resume() {
447466
// Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option.
448467
// TODO: Add a G28 parameter to leave leveling disabled.
449468
sprintf_P(cmd, PSTR("M420S%cZ%s"), '0' + (char)info.flag.leveling, dtostrf(info.fade, 1, 1, str_1));
450-
gcode.process_subcommands_now(cmd);
469+
PROCESS_SUBCOMMANDS_NOW(cmd);
451470

452471
#if !HOMING_Z_DOWN
453472
// The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9.
454473
sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 1, str_1));
455-
gcode.process_subcommands_now(cmd);
474+
PROCESS_SUBCOMMANDS_NOW(cmd);
456475
#endif
457476
#endif
458477

459478
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
460479
// Z was homed down to the bed, so move up to the raised height.
461480
z_now = z_raised;
462481
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1));
463-
gcode.process_subcommands_now(cmd);
482+
PROCESS_SUBCOMMANDS_NOW(cmd);
464483
#endif
465484

466485
// Recover volumetric extrusion state
467486
#if DISABLED(NO_VOLUMETRICS)
468487
#if HAS_MULTI_EXTRUDER
469488
EXTRUDER_LOOP() {
470489
sprintf_P(cmd, PSTR("M200T%iD%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1));
471-
gcode.process_subcommands_now(cmd);
490+
PROCESS_SUBCOMMANDS_NOW(cmd);
472491
}
473492
if (!info.flag.volumetric_enabled) {
474493
sprintf_P(cmd, PSTR("M200T%iD0"), info.active_extruder);
475-
gcode.process_subcommands_now(cmd);
494+
PROCESS_SUBCOMMANDS_NOW(cmd);
476495
}
477496
#else
478497
if (info.flag.volumetric_enabled) {
479498
sprintf_P(cmd, PSTR("M200D%s"), dtostrf(info.filament_size[0], 1, 3, str_1));
480-
gcode.process_subcommands_now(cmd);
499+
PROCESS_SUBCOMMANDS_NOW(cmd);
481500
}
482501
#endif
483502
#endif
@@ -489,18 +508,18 @@ void PrintJobRecovery::resume() {
489508
if (et) {
490509
#if HAS_MULTI_HOTEND
491510
sprintf_P(cmd, PSTR("T%iS"), e);
492-
gcode.process_subcommands_now(cmd);
511+
PROCESS_SUBCOMMANDS_NOW(cmd);
493512
#endif
494513
sprintf_P(cmd, PSTR("M109S%i"), et);
495-
gcode.process_subcommands_now(cmd);
514+
PROCESS_SUBCOMMANDS_NOW(cmd);
496515
}
497516
}
498517
#endif
499518

500519
// Restore the previously active tool (with no_move)
501520
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND
502521
sprintf_P(cmd, PSTR("T%i S"), info.active_extruder);
503-
gcode.process_subcommands_now(cmd);
522+
PROCESS_SUBCOMMANDS_NOW(cmd);
504523
#endif
505524

506525
// Restore print cooling fan speeds
@@ -509,7 +528,7 @@ void PrintJobRecovery::resume() {
509528
const int f = info.fan_speed[i];
510529
if (f) {
511530
sprintf_P(cmd, PSTR("M106P%iS%i"), i, f);
512-
gcode.process_subcommands_now(cmd);
531+
PROCESS_SUBCOMMANDS_NOW(cmd);
513532
}
514533
}
515534
#endif
@@ -531,37 +550,37 @@ void PrintJobRecovery::resume() {
531550

532551
// Un-retract if there was a retract at outage
533552
#if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0
534-
gcode.process_subcommands_now(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN)));
553+
PROCESS_SUBCOMMANDS_NOW(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN)));
535554
#endif
536555

537556
// Additional purge on resume if configured
538557
#if POWER_LOSS_PURGE_LEN
539558
sprintf_P(cmd, PSTR("G1F3000E%d"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN));
540-
gcode.process_subcommands_now(cmd);
559+
PROCESS_SUBCOMMANDS_NOW(cmd);
541560
#endif
542561

543562
#if ENABLED(NOZZLE_CLEAN_FEATURE)
544-
gcode.process_subcommands_now(F("G12"));
563+
PROCESS_SUBCOMMANDS_NOW(F("G12"));
545564
#endif
546565

547566
// Move back over to the saved XY
548567
sprintf_P(cmd, PSTR("G1X%sY%sF3000"),
549568
dtostrf(info.current_position.x, 1, 3, str_1),
550569
dtostrf(info.current_position.y, 1, 3, str_2)
551570
);
552-
gcode.process_subcommands_now(cmd);
571+
PROCESS_SUBCOMMANDS_NOW(cmd);
553572

554573
// Move back down to the saved Z for printing
555574
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_print, 1, 3, str_1));
556-
gcode.process_subcommands_now(cmd);
575+
PROCESS_SUBCOMMANDS_NOW(cmd);
557576

558577
// Restore the feedrate
559578
sprintf_P(cmd, PSTR("G1F%d"), info.feedrate);
560-
gcode.process_subcommands_now(cmd);
579+
PROCESS_SUBCOMMANDS_NOW(cmd);
561580

562581
// Restore E position with G92.9
563582
sprintf_P(cmd, PSTR("G92.9E%s"), dtostrf(info.current_position.e, 1, 3, str_1));
564-
gcode.process_subcommands_now(cmd);
583+
PROCESS_SUBCOMMANDS_NOW(cmd);
565584

566585
TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat);
567586
TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset);
@@ -573,22 +592,14 @@ void PrintJobRecovery::resume() {
573592
// Relative axis modes
574593
gcode.axis_relative = info.axis_relative;
575594

576-
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
577-
const uint8_t old_flags = marlin_debug_flags;
578-
marlin_debug_flags |= MARLIN_DEBUG_ECHO;
579-
#endif
580-
581595
// Continue to apply PLR when a file is resumed!
582596
enable(true);
583597

584598
// Resume the SD file from the last position
585-
char *fn = info.sd_filename;
586-
sprintf_P(cmd, M23_STR, fn);
587-
gcode.process_subcommands_now(cmd);
599+
sprintf_P(cmd, M23_STR, &info.sd_filename[0]);
600+
PROCESS_SUBCOMMANDS_NOW(cmd);
588601
sprintf_P(cmd, PSTR("M24S%ldT%ld"), resume_sdpos, info.print_job_elapsed);
589-
gcode.process_subcommands_now(cmd);
590-
591-
TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags = old_flags);
602+
PROCESS_SUBCOMMANDS_NOW(cmd);
592603
}
593604

594605
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)

0 commit comments

Comments
 (0)