Skip to content

Commit 1035d66

Browse files
committed
🚸 Interruptible PLR
1 parent 38e6330 commit 1035d66

File tree

1 file changed

+47
-39
lines changed

1 file changed

+47
-39
lines changed

Marlin/src/feature/powerloss.cpp

+47-39
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
*/
@@ -345,27 +353,34 @@ void PrintJobRecovery::write() {
345353
*/
346354
void PrintJobRecovery::resume() {
347355

356+
struct OnExit {
357+
uint8_t old_flags;
358+
OnExit() {
359+
old_flags = marlin_debug_flags;
360+
if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN;
361+
TERN_(DEBUG_POWER_LOSS_RECOVERY, marlin_debug_flags |= MARLIN_DEBUG_ECHO);
362+
}
363+
~OnExit() { marlin_debug_flags = old_flags; }
364+
} on_exit;
365+
348366
char cmd[MAX_CMD_SIZE+16], str_1[16], str_2[16];
349367

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

352-
// Apply the dry-run flag if enabled
353-
if (info.flag.dryrun) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN;
354-
355370
// Restore cold extrusion permission
356371
TERN_(PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude = info.flag.allow_cold_extrusion);
357372

358373
#if HAS_LEVELING
359374
// Make sure leveling is off before any G92 and G28
360-
gcode.process_subcommands_now(F("M420 S0 Z0"));
375+
PROCESS_SUBCOMMANDS_NOW(F("M420S0"));
361376
#endif
362377

363378
#if HAS_HEATED_BED
364379
const celsius_t bt = info.target_temperature_bed;
365380
if (bt) {
366381
// Restore the bed temperature
367382
sprintf_P(cmd, PSTR("M190S%i"), bt);
368-
gcode.process_subcommands_now(cmd);
383+
PROCESS_SUBCOMMANDS_NOW(cmd);
369384
}
370385
#endif
371386

@@ -376,10 +391,10 @@ void PrintJobRecovery::resume() {
376391
if (et) {
377392
#if HAS_MULTI_HOTEND
378393
sprintf_P(cmd, PSTR("T%iS"), e);
379-
gcode.process_subcommands_now(cmd);
394+
PROCESS_SUBCOMMANDS_NOW(cmd);
380395
#endif
381396
sprintf_P(cmd, PSTR("M109S%i"), et);
382-
gcode.process_subcommands_now(cmd);
397+
PROCESS_SUBCOMMANDS_NOW(cmd);
383398
}
384399
}
385400
#endif
@@ -393,7 +408,7 @@ void PrintJobRecovery::resume() {
393408
// establish the current position as best we can.
394409
//
395410

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

398413
#if Z_HOME_TO_MAX
399414

@@ -404,7 +419,7 @@ void PrintJobRecovery::resume() {
404419
"G28R0\n" // Home all axes (no raise)
405420
"G1Z%sF1200" // Move Z down to (raised) height
406421
), dtostrf(z_now, 1, 3, str_1));
407-
gcode.process_subcommands_now(cmd);
422+
PROCESS_SUBCOMMANDS_NOW(cmd);
408423

409424
#elif DISABLED(BELTPRINTER)
410425

@@ -417,26 +432,26 @@ void PrintJobRecovery::resume() {
417432
#if !HOMING_Z_DOWN
418433
// Set Z to the real position
419434
sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 3, str_1));
420-
gcode.process_subcommands_now(cmd);
435+
PROCESS_SUBCOMMANDS_NOW(cmd);
421436
#endif
422437

423438
// Does Z need to be raised now? It should be raised before homing XY.
424439
if (z_raised > z_now) {
425440
z_now = z_raised;
426441
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1));
427-
gcode.process_subcommands_now(cmd);
442+
PROCESS_SUBCOMMANDS_NOW(cmd);
428443
}
429444

430445
// Home XY with no Z raise
431-
gcode.process_subcommands_now(F("G28R0XY")); // No raise during G28
446+
PROCESS_SUBCOMMANDS_NOW(F("G28R0XY")); // No raise during G28
432447

433448
#endif
434449

435450
#if HOMING_Z_DOWN
436451
// Move to a safe XY position and home Z while avoiding the print.
437452
const xy_pos_t p = xy_pos_t(POWER_LOSS_ZHOME_POS) TERN_(HOMING_Z_WITH_PROBE, - probe.offset_xy);
438453
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);
454+
PROCESS_SUBCOMMANDS_NOW(cmd);
440455
#endif
441456

442457
// Mark all axes as having been homed (no effect on current_position)
@@ -447,37 +462,37 @@ void PrintJobRecovery::resume() {
447462
// Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option.
448463
// TODO: Add a G28 parameter to leave leveling disabled.
449464
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);
465+
PROCESS_SUBCOMMANDS_NOW(cmd);
451466

452467
#if !HOMING_Z_DOWN
453468
// The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9.
454469
sprintf_P(cmd, PSTR("G92.9Z%s"), dtostrf(z_now, 1, 1, str_1));
455-
gcode.process_subcommands_now(cmd);
470+
PROCESS_SUBCOMMANDS_NOW(cmd);
456471
#endif
457472
#endif
458473

459474
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
460475
// Z was homed down to the bed, so move up to the raised height.
461476
z_now = z_raised;
462477
sprintf_P(cmd, PSTR("G1Z%sF600"), dtostrf(z_now, 1, 3, str_1));
463-
gcode.process_subcommands_now(cmd);
478+
PROCESS_SUBCOMMANDS_NOW(cmd);
464479
#endif
465480

466481
// Recover volumetric extrusion state
467482
#if DISABLED(NO_VOLUMETRICS)
468483
#if HAS_MULTI_EXTRUDER
469484
EXTRUDER_LOOP() {
470485
sprintf_P(cmd, PSTR("M200T%iD%s"), e, dtostrf(info.filament_size[e], 1, 3, str_1));
471-
gcode.process_subcommands_now(cmd);
486+
PROCESS_SUBCOMMANDS_NOW(cmd);
472487
}
473488
if (!info.flag.volumetric_enabled) {
474489
sprintf_P(cmd, PSTR("M200T%iD0"), info.active_extruder);
475-
gcode.process_subcommands_now(cmd);
490+
PROCESS_SUBCOMMANDS_NOW(cmd);
476491
}
477492
#else
478493
if (info.flag.volumetric_enabled) {
479494
sprintf_P(cmd, PSTR("M200D%s"), dtostrf(info.filament_size[0], 1, 3, str_1));
480-
gcode.process_subcommands_now(cmd);
495+
PROCESS_SUBCOMMANDS_NOW(cmd);
481496
}
482497
#endif
483498
#endif
@@ -489,18 +504,18 @@ void PrintJobRecovery::resume() {
489504
if (et) {
490505
#if HAS_MULTI_HOTEND
491506
sprintf_P(cmd, PSTR("T%iS"), e);
492-
gcode.process_subcommands_now(cmd);
507+
PROCESS_SUBCOMMANDS_NOW(cmd);
493508
#endif
494509
sprintf_P(cmd, PSTR("M109S%i"), et);
495-
gcode.process_subcommands_now(cmd);
510+
PROCESS_SUBCOMMANDS_NOW(cmd);
496511
}
497512
}
498513
#endif
499514

500515
// Restore the previously active tool (with no_move)
501516
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND
502517
sprintf_P(cmd, PSTR("T%i S"), info.active_extruder);
503-
gcode.process_subcommands_now(cmd);
518+
PROCESS_SUBCOMMANDS_NOW(cmd);
504519
#endif
505520

506521
// Restore print cooling fan speeds
@@ -509,7 +524,7 @@ void PrintJobRecovery::resume() {
509524
const int f = info.fan_speed[i];
510525
if (f) {
511526
sprintf_P(cmd, PSTR("M106P%iS%i"), i, f);
512-
gcode.process_subcommands_now(cmd);
527+
PROCESS_SUBCOMMANDS_NOW(cmd);
513528
}
514529
}
515530
#endif
@@ -531,37 +546,37 @@ void PrintJobRecovery::resume() {
531546

532547
// Un-retract if there was a retract at outage
533548
#if ENABLED(BACKUP_POWER_SUPPLY) && POWER_LOSS_RETRACT_LEN > 0
534-
gcode.process_subcommands_now(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN)));
549+
PROCESS_SUBCOMMANDS_NOW(F("G1F3000E" STRINGIFY(POWER_LOSS_RETRACT_LEN)));
535550
#endif
536551

537552
// Additional purge on resume if configured
538553
#if POWER_LOSS_PURGE_LEN
539554
sprintf_P(cmd, PSTR("G1F3000E%d"), (POWER_LOSS_PURGE_LEN) + (POWER_LOSS_RETRACT_LEN));
540-
gcode.process_subcommands_now(cmd);
555+
PROCESS_SUBCOMMANDS_NOW(cmd);
541556
#endif
542557

543558
#if ENABLED(NOZZLE_CLEAN_FEATURE)
544-
gcode.process_subcommands_now(F("G12"));
559+
PROCESS_SUBCOMMANDS_NOW(F("G12"));
545560
#endif
546561

547562
// Move back over to the saved XY
548563
sprintf_P(cmd, PSTR("G1X%sY%sF3000"),
549564
dtostrf(info.current_position.x, 1, 3, str_1),
550565
dtostrf(info.current_position.y, 1, 3, str_2)
551566
);
552-
gcode.process_subcommands_now(cmd);
567+
PROCESS_SUBCOMMANDS_NOW(cmd);
553568

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

558573
// Restore the feedrate
559574
sprintf_P(cmd, PSTR("G1F%d"), info.feedrate);
560-
gcode.process_subcommands_now(cmd);
575+
PROCESS_SUBCOMMANDS_NOW(cmd);
561576

562577
// Restore E position with G92.9
563578
sprintf_P(cmd, PSTR("G92.9E%s"), dtostrf(info.current_position.e, 1, 3, str_1));
564-
gcode.process_subcommands_now(cmd);
579+
PROCESS_SUBCOMMANDS_NOW(cmd);
565580

566581
TERN_(GCODE_REPEAT_MARKERS, repeat = info.stored_repeat);
567582
TERN_(HAS_HOME_OFFSET, home_offset = info.home_offset);
@@ -573,22 +588,15 @@ void PrintJobRecovery::resume() {
573588
// Relative axis modes
574589
gcode.axis_relative = info.axis_relative;
575590

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-
581591
// Continue to apply PLR when a file is resumed!
582592
enable(true);
583593

584594
// Resume the SD file from the last position
585595
char *fn = info.sd_filename;
586596
sprintf_P(cmd, M23_STR, fn);
587-
gcode.process_subcommands_now(cmd);
597+
PROCESS_SUBCOMMANDS_NOW(cmd);
588598
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);
599+
PROCESS_SUBCOMMANDS_NOW(cmd);
592600
}
593601

594602
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)

0 commit comments

Comments
 (0)