@@ -78,6 +78,14 @@ PrintJobRecovery recovery;
78
78
#define POWER_LOSS_RETRACT_LEN 0
79
79
#endif
80
80
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
+
81
89
/* *
82
90
* Clear the recovery info
83
91
*/
@@ -345,27 +353,34 @@ void PrintJobRecovery::write() {
345
353
*/
346
354
void PrintJobRecovery::resume () {
347
355
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
+
348
366
char cmd[MAX_CMD_SIZE+16 ], str_1[16 ], str_2[16 ];
349
367
350
368
const uint32_t resume_sdpos = info.sdpos ; // Get here before the stepper ISR overwrites it
351
369
352
- // Apply the dry-run flag if enabled
353
- if (info.flag .dryrun ) marlin_debug_flags |= MARLIN_DEBUG_DRYRUN;
354
-
355
370
// Restore cold extrusion permission
356
371
TERN_ (PREVENT_COLD_EXTRUSION, thermalManager.allow_cold_extrude = info.flag .allow_cold_extrusion );
357
372
358
373
#if HAS_LEVELING
359
374
// 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 " ));
361
376
#endif
362
377
363
378
#if HAS_HEATED_BED
364
379
const celsius_t bt = info.target_temperature_bed ;
365
380
if (bt) {
366
381
// Restore the bed temperature
367
382
sprintf_P (cmd, PSTR (" M190S%i" ), bt);
368
- gcode. process_subcommands_now (cmd);
383
+ PROCESS_SUBCOMMANDS_NOW (cmd);
369
384
}
370
385
#endif
371
386
@@ -376,10 +391,10 @@ void PrintJobRecovery::resume() {
376
391
if (et) {
377
392
#if HAS_MULTI_HOTEND
378
393
sprintf_P (cmd, PSTR (" T%iS" ), e);
379
- gcode. process_subcommands_now (cmd);
394
+ PROCESS_SUBCOMMANDS_NOW (cmd);
380
395
#endif
381
396
sprintf_P (cmd, PSTR (" M109S%i" ), et);
382
- gcode. process_subcommands_now (cmd);
397
+ PROCESS_SUBCOMMANDS_NOW (cmd);
383
398
}
384
399
}
385
400
#endif
@@ -393,7 +408,7 @@ void PrintJobRecovery::resume() {
393
408
// establish the current position as best we can.
394
409
//
395
410
396
- gcode. process_subcommands_now (F (" G92.9E0" )); // Reset E to 0
411
+ PROCESS_SUBCOMMANDS_NOW (F (" G92.9E0" )); // Reset E to 0
397
412
398
413
#if Z_HOME_TO_MAX
399
414
@@ -404,7 +419,7 @@ void PrintJobRecovery::resume() {
404
419
" G28R0\n " // Home all axes (no raise)
405
420
" G1Z%sF1200" // Move Z down to (raised) height
406
421
), dtostrf (z_now, 1 , 3 , str_1));
407
- gcode. process_subcommands_now (cmd);
422
+ PROCESS_SUBCOMMANDS_NOW (cmd);
408
423
409
424
#elif DISABLED(BELTPRINTER)
410
425
@@ -417,26 +432,26 @@ void PrintJobRecovery::resume() {
417
432
#if !HOMING_Z_DOWN
418
433
// Set Z to the real position
419
434
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);
421
436
#endif
422
437
423
438
// Does Z need to be raised now? It should be raised before homing XY.
424
439
if (z_raised > z_now) {
425
440
z_now = z_raised;
426
441
sprintf_P (cmd, PSTR (" G1Z%sF600" ), dtostrf (z_now, 1 , 3 , str_1));
427
- gcode. process_subcommands_now (cmd);
442
+ PROCESS_SUBCOMMANDS_NOW (cmd);
428
443
}
429
444
430
445
// 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
432
447
433
448
#endif
434
449
435
450
#if HOMING_Z_DOWN
436
451
// Move to a safe XY position and home Z while avoiding the print.
437
452
const xy_pos_t p = xy_pos_t (POWER_LOSS_ZHOME_POS) TERN_ (HOMING_Z_WITH_PROBE, - probe.offset_xy );
438
453
sprintf_P (cmd, PSTR (" G1X%sY%sF1000\n G28HZ" ), 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);
440
455
#endif
441
456
442
457
// Mark all axes as having been homed (no effect on current_position)
@@ -447,37 +462,37 @@ void PrintJobRecovery::resume() {
447
462
// Leveling may already be enabled due to the ENABLE_LEVELING_AFTER_G28 option.
448
463
// TODO: Add a G28 parameter to leave leveling disabled.
449
464
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);
451
466
452
467
#if !HOMING_Z_DOWN
453
468
// The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9.
454
469
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);
456
471
#endif
457
472
#endif
458
473
459
474
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
460
475
// Z was homed down to the bed, so move up to the raised height.
461
476
z_now = z_raised;
462
477
sprintf_P (cmd, PSTR (" G1Z%sF600" ), dtostrf (z_now, 1 , 3 , str_1));
463
- gcode. process_subcommands_now (cmd);
478
+ PROCESS_SUBCOMMANDS_NOW (cmd);
464
479
#endif
465
480
466
481
// Recover volumetric extrusion state
467
482
#if DISABLED(NO_VOLUMETRICS)
468
483
#if HAS_MULTI_EXTRUDER
469
484
EXTRUDER_LOOP () {
470
485
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);
472
487
}
473
488
if (!info.flag .volumetric_enabled ) {
474
489
sprintf_P (cmd, PSTR (" M200T%iD0" ), info.active_extruder );
475
- gcode. process_subcommands_now (cmd);
490
+ PROCESS_SUBCOMMANDS_NOW (cmd);
476
491
}
477
492
#else
478
493
if (info.flag .volumetric_enabled ) {
479
494
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);
481
496
}
482
497
#endif
483
498
#endif
@@ -489,18 +504,18 @@ void PrintJobRecovery::resume() {
489
504
if (et) {
490
505
#if HAS_MULTI_HOTEND
491
506
sprintf_P (cmd, PSTR (" T%iS" ), e);
492
- gcode. process_subcommands_now (cmd);
507
+ PROCESS_SUBCOMMANDS_NOW (cmd);
493
508
#endif
494
509
sprintf_P (cmd, PSTR (" M109S%i" ), et);
495
- gcode. process_subcommands_now (cmd);
510
+ PROCESS_SUBCOMMANDS_NOW (cmd);
496
511
}
497
512
}
498
513
#endif
499
514
500
515
// Restore the previously active tool (with no_move)
501
516
#if HAS_MULTI_EXTRUDER || HAS_MULTI_HOTEND
502
517
sprintf_P (cmd, PSTR (" T%i S" ), info.active_extruder );
503
- gcode. process_subcommands_now (cmd);
518
+ PROCESS_SUBCOMMANDS_NOW (cmd);
504
519
#endif
505
520
506
521
// Restore print cooling fan speeds
@@ -509,7 +524,7 @@ void PrintJobRecovery::resume() {
509
524
const int f = info.fan_speed [i];
510
525
if (f) {
511
526
sprintf_P (cmd, PSTR (" M106P%iS%i" ), i, f);
512
- gcode. process_subcommands_now (cmd);
527
+ PROCESS_SUBCOMMANDS_NOW (cmd);
513
528
}
514
529
}
515
530
#endif
@@ -531,37 +546,37 @@ void PrintJobRecovery::resume() {
531
546
532
547
// Un-retract if there was a retract at outage
533
548
#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)));
535
550
#endif
536
551
537
552
// Additional purge on resume if configured
538
553
#if POWER_LOSS_PURGE_LEN
539
554
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);
541
556
#endif
542
557
543
558
#if ENABLED(NOZZLE_CLEAN_FEATURE)
544
- gcode. process_subcommands_now (F (" G12" ));
559
+ PROCESS_SUBCOMMANDS_NOW (F (" G12" ));
545
560
#endif
546
561
547
562
// Move back over to the saved XY
548
563
sprintf_P (cmd, PSTR (" G1X%sY%sF3000" ),
549
564
dtostrf (info.current_position .x , 1 , 3 , str_1),
550
565
dtostrf (info.current_position .y , 1 , 3 , str_2)
551
566
);
552
- gcode. process_subcommands_now (cmd);
567
+ PROCESS_SUBCOMMANDS_NOW (cmd);
553
568
554
569
// Move back down to the saved Z for printing
555
570
sprintf_P (cmd, PSTR (" G1Z%sF600" ), dtostrf (z_print, 1 , 3 , str_1));
556
- gcode. process_subcommands_now (cmd);
571
+ PROCESS_SUBCOMMANDS_NOW (cmd);
557
572
558
573
// Restore the feedrate
559
574
sprintf_P (cmd, PSTR (" G1F%d" ), info.feedrate );
560
- gcode. process_subcommands_now (cmd);
575
+ PROCESS_SUBCOMMANDS_NOW (cmd);
561
576
562
577
// Restore E position with G92.9
563
578
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);
565
580
566
581
TERN_ (GCODE_REPEAT_MARKERS, repeat = info.stored_repeat );
567
582
TERN_ (HAS_HOME_OFFSET, home_offset = info.home_offset );
@@ -573,22 +588,15 @@ void PrintJobRecovery::resume() {
573
588
// Relative axis modes
574
589
gcode.axis_relative = info.axis_relative ;
575
590
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
-
581
591
// Continue to apply PLR when a file is resumed!
582
592
enable (true );
583
593
584
594
// Resume the SD file from the last position
585
595
char *fn = info.sd_filename ;
586
596
sprintf_P (cmd, M23_STR, fn);
587
- gcode. process_subcommands_now (cmd);
597
+ PROCESS_SUBCOMMANDS_NOW (cmd);
588
598
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);
592
600
}
593
601
594
602
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
0 commit comments