Fix and improve POWER_LOSS_RECOVERY (#11187)
This commit is contained in:
parent
e0ab8acf19
commit
1a0f4dedad
|
@ -897,7 +897,7 @@ void setup() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
do_print_job_recovery();
|
check_print_job_recovery();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(USE_WATCHDOG) // Reinit watchdog after HAL_get_reset_source call
|
#if ENABLED(USE_WATCHDOG) // Reinit watchdog after HAL_get_reset_source call
|
||||||
|
@ -937,6 +937,9 @@ void loop() {
|
||||||
for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
|
for (uint8_t i = 0; i < FAN_COUNT; i++) fanSpeeds[i] = 0;
|
||||||
#endif
|
#endif
|
||||||
wait_for_heatup = false;
|
wait_for_heatup = false;
|
||||||
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
card.removeJobRecoveryFile();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif // SDSUPPORT && ULTIPANEL
|
#endif // SDSUPPORT && ULTIPANEL
|
||||||
|
|
||||||
|
|
|
@ -43,14 +43,14 @@ job_recovery_info_t job_recovery_info;
|
||||||
JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
|
JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
|
||||||
uint8_t job_recovery_commands_count; //=0
|
uint8_t job_recovery_commands_count; //=0
|
||||||
char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
||||||
|
// Extern
|
||||||
// Private
|
extern uint8_t active_extruder, commands_in_queue, cmd_queue_index_r;
|
||||||
static char sd_filename[MAXPATHNAMELENGTH];
|
|
||||||
|
|
||||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
void debug_print_job_recovery(const bool recovery) {
|
void debug_print_job_recovery(const bool recovery) {
|
||||||
SERIAL_PROTOCOLPAIR("valid_head:", (int)job_recovery_info.valid_head);
|
SERIAL_PROTOCOLLNPGM("---- Job Recovery Info ----");
|
||||||
SERIAL_PROTOCOLLNPAIR(" valid_foot:", (int)job_recovery_info.valid_foot);
|
SERIAL_PROTOCOLPAIR("valid_head:", int(job_recovery_info.valid_head));
|
||||||
|
SERIAL_PROTOCOLLNPAIR(" valid_foot:", int(job_recovery_info.valid_foot));
|
||||||
if (job_recovery_info.valid_head) {
|
if (job_recovery_info.valid_head) {
|
||||||
if (job_recovery_info.valid_head == job_recovery_info.valid_foot) {
|
if (job_recovery_info.valid_head == job_recovery_info.valid_foot) {
|
||||||
SERIAL_PROTOCOLPGM("current_position: ");
|
SERIAL_PROTOCOLPGM("current_position: ");
|
||||||
|
@ -60,6 +60,11 @@ static char sd_filename[MAXPATHNAMELENGTH];
|
||||||
}
|
}
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
SERIAL_PROTOCOLLNPAIR("feedrate: ", job_recovery_info.feedrate);
|
SERIAL_PROTOCOLLNPAIR("feedrate: ", job_recovery_info.feedrate);
|
||||||
|
|
||||||
|
#if HOTENDS > 1
|
||||||
|
SERIAL_PROTOCOLLNPAIR("active_hotend: ", int(job_recovery_info.active_hotend));
|
||||||
|
#endif
|
||||||
|
|
||||||
SERIAL_PROTOCOLPGM("target_temperature: ");
|
SERIAL_PROTOCOLPGM("target_temperature: ");
|
||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() {
|
||||||
SERIAL_PROTOCOL(job_recovery_info.target_temperature[e]);
|
SERIAL_PROTOCOL(job_recovery_info.target_temperature[e]);
|
||||||
|
@ -84,8 +89,8 @@ static char sd_filename[MAXPATHNAMELENGTH];
|
||||||
SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
|
SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
|
||||||
SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
|
SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
|
||||||
#endif
|
#endif
|
||||||
SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", job_recovery_info.cmd_queue_index_r);
|
SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", int(job_recovery_info.cmd_queue_index_r));
|
||||||
SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", job_recovery_info.commands_in_queue);
|
SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", int(job_recovery_info.commands_in_queue));
|
||||||
if (recovery)
|
if (recovery)
|
||||||
for (uint8_t i = 0; i < job_recovery_commands_count; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_commands[i]);
|
for (uint8_t i = 0; i < job_recovery_commands_count; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_commands[i]);
|
||||||
else
|
else
|
||||||
|
@ -97,15 +102,17 @@ static char sd_filename[MAXPATHNAMELENGTH];
|
||||||
else
|
else
|
||||||
SERIAL_PROTOCOLLNPGM("INVALID DATA");
|
SERIAL_PROTOCOLLNPGM("INVALID DATA");
|
||||||
}
|
}
|
||||||
|
SERIAL_PROTOCOLLNPGM("---------------------------");
|
||||||
}
|
}
|
||||||
#endif // DEBUG_POWER_LOSS_RECOVERY
|
#endif // DEBUG_POWER_LOSS_RECOVERY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for Print Job Recovery
|
* Check for Print Job Recovery during setup()
|
||||||
* If the file has a saved state, populate the job_recovery_commands queue
|
*
|
||||||
|
* If a saved state exists, populate job_recovery_commands with
|
||||||
|
* commands to restore the machine state and continue the file.
|
||||||
*/
|
*/
|
||||||
void do_print_job_recovery() {
|
void check_print_job_recovery() {
|
||||||
//if (job_recovery_commands_count > 0) return;
|
|
||||||
memset(&job_recovery_info, 0, sizeof(job_recovery_info));
|
memset(&job_recovery_info, 0, sizeof(job_recovery_info));
|
||||||
ZERO(job_recovery_commands);
|
ZERO(job_recovery_commands);
|
||||||
|
|
||||||
|
@ -114,7 +121,7 @@ void do_print_job_recovery() {
|
||||||
if (card.cardOK) {
|
if (card.cardOK) {
|
||||||
|
|
||||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
SERIAL_PROTOCOLLNPAIR("Init job recovery info. Size: ", (int)sizeof(job_recovery_info));
|
SERIAL_PROTOCOLLNPAIR("Init job recovery info. Size: ", int(sizeof(job_recovery_info)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (card.jobRecoverFileExists()) {
|
if (card.jobRecoverFileExists()) {
|
||||||
|
@ -134,7 +141,9 @@ void do_print_job_recovery() {
|
||||||
strcpy_P(job_recovery_commands[ind++], PSTR("G92.0 Z0")); // Ensure Z is equal to 0
|
strcpy_P(job_recovery_commands[ind++], PSTR("G92.0 Z0")); // Ensure Z is equal to 0
|
||||||
strcpy_P(job_recovery_commands[ind++], PSTR("G1 Z2")); // Raise Z by 2mm (we hope!)
|
strcpy_P(job_recovery_commands[ind++], PSTR("G1 Z2")); // Raise Z by 2mm (we hope!)
|
||||||
strcpy_P(job_recovery_commands[ind++], PSTR("G28 R0"
|
strcpy_P(job_recovery_commands[ind++], PSTR("G28 R0"
|
||||||
#if !IS_KINEMATIC
|
#if ENABLED(MARLIN_DEV_MODE)
|
||||||
|
" S"
|
||||||
|
#elif !IS_KINEMATIC
|
||||||
" X Y" // Home X and Y for Cartesian
|
" X Y" // Home X and Y for Cartesian
|
||||||
#endif
|
#endif
|
||||||
));
|
));
|
||||||
|
@ -142,10 +151,12 @@ void do_print_job_recovery() {
|
||||||
char str_1[16], str_2[16];
|
char str_1[16], str_2[16];
|
||||||
|
|
||||||
#if HAS_LEVELING
|
#if HAS_LEVELING
|
||||||
|
if (job_recovery_info.fade || job_recovery_info.leveling) {
|
||||||
// Restore leveling state before G92 sets Z
|
// Restore leveling state before G92 sets Z
|
||||||
// This ensures the steppers correspond to the native Z
|
// This ensures the steppers correspond to the native Z
|
||||||
dtostrf(job_recovery_info.fade, 1, 1, str_1);
|
dtostrf(job_recovery_info.fade, 1, 1, str_1);
|
||||||
sprintf_P(job_recovery_commands[ind++], PSTR("M420 S%i Z%s"), int(job_recovery_info.leveling), str_1);
|
sprintf_P(job_recovery_commands[ind++], PSTR("M420 S%i Z%s"), int(job_recovery_info.leveling), str_1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
|
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
|
||||||
|
@ -157,23 +168,21 @@ void do_print_job_recovery() {
|
||||||
);
|
);
|
||||||
sprintf_P(job_recovery_commands[ind++], PSTR("G92.0 Z%s E%s"), str_1, str_2); // Current Z + 2 and E
|
sprintf_P(job_recovery_commands[ind++], PSTR("G92.0 Z%s E%s"), str_1, str_2); // Current Z + 2 and E
|
||||||
|
|
||||||
strcpy_P(job_recovery_commands[ind++], PSTR("M117 Continuing..."));
|
uint8_t r = job_recovery_info.cmd_queue_index_r, c = job_recovery_info.commands_in_queue;
|
||||||
|
while (c--) {
|
||||||
uint8_t r = job_recovery_info.cmd_queue_index_r;
|
|
||||||
while (job_recovery_info.commands_in_queue) {
|
|
||||||
strcpy(job_recovery_commands[ind++], job_recovery_info.command_queue[r]);
|
strcpy(job_recovery_commands[ind++], job_recovery_info.command_queue[r]);
|
||||||
job_recovery_info.commands_in_queue--;
|
|
||||||
r = (r + 1) % BUFSIZE;
|
r = (r + 1) % BUFSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (job_recovery_info.sd_filename[0] == '/') job_recovery_info.sd_filename[0] = ' ';
|
||||||
|
sprintf_P(job_recovery_commands[ind++], PSTR("M23 %s"), job_recovery_info.sd_filename);
|
||||||
|
sprintf_P(job_recovery_commands[ind++], PSTR("M24 S%ld T%ld"), job_recovery_info.sdpos, job_recovery_info.print_job_elapsed);
|
||||||
|
|
||||||
job_recovery_commands_count = ind;
|
job_recovery_commands_count = ind;
|
||||||
|
|
||||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
debug_print_job_recovery(true);
|
debug_print_job_recovery(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
card.openFile(job_recovery_info.sd_filename, true);
|
|
||||||
card.setIndex(job_recovery_info.sdpos);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (job_recovery_info.valid_head != job_recovery_info.valid_foot)
|
if (job_recovery_info.valid_head != job_recovery_info.valid_foot)
|
||||||
|
@ -213,6 +222,11 @@ void save_job_recovery_info() {
|
||||||
// Machine state
|
// Machine state
|
||||||
COPY(job_recovery_info.current_position, current_position);
|
COPY(job_recovery_info.current_position, current_position);
|
||||||
job_recovery_info.feedrate = feedrate_mm_s;
|
job_recovery_info.feedrate = feedrate_mm_s;
|
||||||
|
|
||||||
|
#if HOTENDS > 1
|
||||||
|
job_recovery_info.active_hotend = active_extruder;
|
||||||
|
#endif
|
||||||
|
|
||||||
COPY(job_recovery_info.target_temperature, thermalManager.target_temperature);
|
COPY(job_recovery_info.target_temperature, thermalManager.target_temperature);
|
||||||
|
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
|
@ -240,14 +254,14 @@ void save_job_recovery_info() {
|
||||||
COPY(job_recovery_info.command_queue, command_queue);
|
COPY(job_recovery_info.command_queue, command_queue);
|
||||||
|
|
||||||
// Elapsed print job time
|
// Elapsed print job time
|
||||||
job_recovery_info.print_job_elapsed = print_job_timer.duration() * 1000UL;
|
job_recovery_info.print_job_elapsed = print_job_timer.duration();
|
||||||
|
|
||||||
// SD file position
|
// SD file position
|
||||||
card.getAbsFilename(job_recovery_info.sd_filename);
|
card.getAbsFilename(job_recovery_info.sd_filename);
|
||||||
job_recovery_info.sdpos = card.getIndex();
|
job_recovery_info.sdpos = card.getIndex();
|
||||||
|
|
||||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
SERIAL_PROTOCOLLNPGM("Saving job_recovery_info");
|
SERIAL_PROTOCOLLNPGM("Saving...");
|
||||||
debug_print_job_recovery(false);
|
debug_print_job_recovery(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,11 @@ typedef struct {
|
||||||
|
|
||||||
// Machine state
|
// Machine state
|
||||||
float current_position[NUM_AXIS], feedrate;
|
float current_position[NUM_AXIS], feedrate;
|
||||||
|
|
||||||
|
#if HOTENDS > 1
|
||||||
|
uint8_t active_hotend;
|
||||||
|
#endif
|
||||||
|
|
||||||
int16_t target_temperature[HOTENDS];
|
int16_t target_temperature[HOTENDS];
|
||||||
|
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
|
@ -74,20 +79,21 @@ extern job_recovery_info_t job_recovery_info;
|
||||||
enum JobRecoveryPhase : unsigned char {
|
enum JobRecoveryPhase : unsigned char {
|
||||||
JOB_RECOVERY_IDLE,
|
JOB_RECOVERY_IDLE,
|
||||||
JOB_RECOVERY_MAYBE,
|
JOB_RECOVERY_MAYBE,
|
||||||
JOB_RECOVERY_YES
|
JOB_RECOVERY_YES,
|
||||||
|
JOB_RECOVERY_DONE
|
||||||
};
|
};
|
||||||
extern JobRecoveryPhase job_recovery_phase;
|
extern JobRecoveryPhase job_recovery_phase;
|
||||||
|
|
||||||
#if HAS_LEVELING
|
#if HAS_LEVELING
|
||||||
#define APPEND_CMD_COUNT 7
|
#define APPEND_CMD_COUNT 9
|
||||||
#else
|
#else
|
||||||
#define APPEND_CMD_COUNT 5
|
#define APPEND_CMD_COUNT 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
extern char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
||||||
extern uint8_t job_recovery_commands_count;
|
extern uint8_t job_recovery_commands_count;
|
||||||
|
|
||||||
void do_print_job_recovery();
|
void check_print_job_recovery();
|
||||||
void save_job_recovery_info();
|
void save_job_recovery_info();
|
||||||
|
|
||||||
#endif // _POWER_LOSS_RECOVERY_H_
|
#endif // _POWER_LOSS_RECOVERY_H_
|
||||||
|
|
|
@ -496,7 +496,7 @@ inline void get_serial_commands() {
|
||||||
if (job_recovery_commands_count) {
|
if (job_recovery_commands_count) {
|
||||||
if (_enqueuecommand(job_recovery_commands[job_recovery_commands_index])) {
|
if (_enqueuecommand(job_recovery_commands[job_recovery_commands_index])) {
|
||||||
++job_recovery_commands_index;
|
++job_recovery_commands_index;
|
||||||
if (!--job_recovery_commands_count) job_recovery_phase = JOB_RECOVERY_IDLE;
|
if (!--job_recovery_commands_count) job_recovery_phase = JOB_RECOVERY_DONE;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,9 @@ void GcodeSuite::M22() { card.release(); }
|
||||||
* M23: Open a file
|
* M23: Open a file
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M23() {
|
void GcodeSuite::M23() {
|
||||||
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
card.removeJobRecoveryFile();
|
||||||
|
#endif
|
||||||
// Simplify3D includes the size, so zero out all spaces (#7227)
|
// Simplify3D includes the size, so zero out all spaces (#7227)
|
||||||
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
|
for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
|
||||||
card.openFile(parser.string_arg, true);
|
card.openFile(parser.string_arg, true);
|
||||||
|
@ -81,15 +84,21 @@ void GcodeSuite::M23() {
|
||||||
* M24: Start or Resume SD Print
|
* M24: Start or Resume SD Print
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M24() {
|
void GcodeSuite::M24() {
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
|
||||||
card.removeJobRecoveryFile();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(PARK_HEAD_ON_PAUSE)
|
#if ENABLED(PARK_HEAD_ON_PAUSE)
|
||||||
resume_print();
|
resume_print();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
if (parser.seenval('S')) card.setIndex(parser.value_long());
|
||||||
|
#endif
|
||||||
|
|
||||||
card.startFileprint();
|
card.startFileprint();
|
||||||
|
|
||||||
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
if (parser.seenval('T'))
|
||||||
|
print_job_timer.resume(parser.value_long());
|
||||||
|
else
|
||||||
|
#endif
|
||||||
print_job_timer.start();
|
print_job_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -666,6 +666,9 @@
|
||||||
#ifndef MSG_STOP_PRINT
|
#ifndef MSG_STOP_PRINT
|
||||||
#define MSG_STOP_PRINT _UxGT("Stop print")
|
#define MSG_STOP_PRINT _UxGT("Stop print")
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef MSG_POWER_LOSS_RECOVERY
|
||||||
|
#define MSG_POWER_LOSS_RECOVERY _UxGT("Power-Loss Recovery")
|
||||||
|
#endif
|
||||||
#ifndef MSG_CARD_MENU
|
#ifndef MSG_CARD_MENU
|
||||||
#define MSG_CARD_MENU _UxGT("Print from SD")
|
#define MSG_CARD_MENU _UxGT("Print from SD")
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -873,17 +873,13 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
abort_sd_printing = true;
|
abort_sd_printing = true;
|
||||||
lcd_setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
|
lcd_setstatusPGM(PSTR(MSG_PRINT_ABORTED), -1);
|
||||||
lcd_return_to_status();
|
lcd_return_to_status();
|
||||||
|
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
|
||||||
card.removeJobRecoveryFile();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SDSUPPORT
|
#endif // SDSUPPORT
|
||||||
|
|
||||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
|
||||||
static void lcd_sdcard_recover_job() {
|
static void lcd_power_loss_recovery_resume() {
|
||||||
char cmd[20];
|
char cmd[20];
|
||||||
|
|
||||||
// Return to status now
|
// Return to status now
|
||||||
|
@ -891,45 +887,65 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
|
|
||||||
// Turn leveling off and home
|
// Turn leveling off and home
|
||||||
enqueue_and_echo_commands_P(PSTR("M420 S0\nG28"
|
enqueue_and_echo_commands_P(PSTR("M420 S0\nG28"
|
||||||
#if !IS_KINEMATIC
|
#if ENABLED(MARLIN_DEV_MODE)
|
||||||
|
" S"
|
||||||
|
#elif !IS_KINEMATIC
|
||||||
" X Y"
|
" X Y"
|
||||||
#endif
|
#endif
|
||||||
));
|
));
|
||||||
|
|
||||||
#if HAS_HEATED_BED
|
#if HAS_HEATED_BED
|
||||||
|
const int16_t bt = job_recovery_info.target_temperature_bed;
|
||||||
|
if (bt) {
|
||||||
// Restore the bed temperature
|
// Restore the bed temperature
|
||||||
sprintf_P(cmd, PSTR("M190 S%i"), job_recovery_info.target_temperature_bed);
|
sprintf_P(cmd, PSTR("M190 S%i"), bt);
|
||||||
enqueue_and_echo_command(cmd);
|
enqueue_and_echo_command(cmd);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Restore all hotend temperatures
|
// Restore all hotend temperatures
|
||||||
HOTEND_LOOP() {
|
HOTEND_LOOP() {
|
||||||
sprintf_P(cmd, PSTR("M109 S%i"), job_recovery_info.target_temperature[e]);
|
const int16_t et = job_recovery_info.target_temperature[e];
|
||||||
|
if (et) {
|
||||||
|
#if HOTENDS > 1
|
||||||
|
sprintf_P(cmd, PSTR("T%i"), e);
|
||||||
|
enqueue_and_echo_command(cmd);
|
||||||
|
#endif
|
||||||
|
sprintf_P(cmd, PSTR("M109 S%i"), et);
|
||||||
enqueue_and_echo_command(cmd);
|
enqueue_and_echo_command(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HOTENDS > 1
|
||||||
|
sprintf_P(cmd, PSTR("T%i"), job_recovery_info.active_hotend);
|
||||||
|
enqueue_and_echo_command(cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Restore print cooling fan speeds
|
// Restore print cooling fan speeds
|
||||||
for (uint8_t i = 0; i < FAN_COUNT; i++) {
|
for (uint8_t i = 0; i < FAN_COUNT; i++) {
|
||||||
sprintf_P(cmd, PSTR("M106 P%i S%i"), i, job_recovery_info.fanSpeeds[i]);
|
int16_t f = job_recovery_info.fanSpeeds[i];
|
||||||
|
if (f) {
|
||||||
|
sprintf_P(cmd, PSTR("M106 P%i S%i"), i, f);
|
||||||
enqueue_and_echo_command(cmd);
|
enqueue_and_echo_command(cmd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start draining the job recovery command queue
|
// Start draining the job recovery command queue
|
||||||
job_recovery_phase = JOB_RECOVERY_YES;
|
job_recovery_phase = JOB_RECOVERY_YES;
|
||||||
|
}
|
||||||
|
|
||||||
// Resume the print job timer
|
static void lcd_power_loss_recovery_cancel() {
|
||||||
if (job_recovery_info.print_job_elapsed)
|
card.removeJobRecoveryFile();
|
||||||
print_job_timer.resume(job_recovery_info.print_job_elapsed);
|
card.autostart_index = 0;
|
||||||
|
lcd_return_to_status();
|
||||||
// Start getting commands from SD
|
|
||||||
card.startFileprint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lcd_job_recovery_menu() {
|
static void lcd_job_recovery_menu() {
|
||||||
defer_return_to_status = true;
|
defer_return_to_status = true;
|
||||||
START_MENU();
|
START_MENU();
|
||||||
MENU_ITEM(function, MSG_RESUME_PRINT, lcd_sdcard_recover_job);
|
STATIC_ITEM(MSG_POWER_LOSS_RECOVERY);
|
||||||
MENU_ITEM(function, MSG_STOP_PRINT, lcd_sdcard_stop);
|
MENU_ITEM(function, MSG_RESUME_PRINT, lcd_power_loss_recovery_resume);
|
||||||
|
MENU_ITEM(function, MSG_STOP_PRINT, lcd_power_loss_recovery_cancel);
|
||||||
END_MENU();
|
END_MENU();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -541,9 +541,13 @@ void CardReader::checkautostart() {
|
||||||
|
|
||||||
if (!cardOK) initsd();
|
if (!cardOK) initsd();
|
||||||
|
|
||||||
if (cardOK) {
|
if (cardOK
|
||||||
|
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||||
|
&& !jobRecoverFileExists() // Don't run auto#.g when a resume file exists
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
char autoname[10];
|
char autoname[10];
|
||||||
sprintf_P(autoname, PSTR("auto%i.g"), autostart_index);
|
sprintf_P(autoname, PSTR("auto%i.g"), int(autostart_index));
|
||||||
dir_t p;
|
dir_t p;
|
||||||
root.rewind();
|
root.rewind();
|
||||||
while (root.readDir(&p, NULL) > 0) {
|
while (root.readDir(&p, NULL) > 0) {
|
||||||
|
@ -990,20 +994,24 @@ void CardReader::printingHasFinished() {
|
||||||
SERIAL_PROTOCOLCHAR('.');
|
SERIAL_PROTOCOLCHAR('.');
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
}
|
}
|
||||||
else
|
else if (!read)
|
||||||
SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, job_recovery_file_name);
|
SERIAL_PROTOCOLLNPAIR(MSG_SD_WRITE_TO_FILE, job_recovery_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::closeJobRecoveryFile() { jobRecoveryFile.close(); }
|
void CardReader::closeJobRecoveryFile() { jobRecoveryFile.close(); }
|
||||||
|
|
||||||
bool CardReader::jobRecoverFileExists() {
|
bool CardReader::jobRecoverFileExists() {
|
||||||
return jobRecoveryFile.open(&root, job_recovery_file_name, O_READ);
|
const bool exists = jobRecoveryFile.open(&root, job_recovery_file_name, O_READ);
|
||||||
|
if (exists) jobRecoveryFile.close();
|
||||||
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t CardReader::saveJobRecoveryInfo() {
|
int16_t CardReader::saveJobRecoveryInfo() {
|
||||||
jobRecoveryFile.seekSet(0);
|
jobRecoveryFile.seekSet(0);
|
||||||
const int16_t ret = jobRecoveryFile.write(&job_recovery_info, sizeof(job_recovery_info));
|
const int16_t ret = jobRecoveryFile.write(&job_recovery_info, sizeof(job_recovery_info));
|
||||||
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
if (ret == -1) SERIAL_PROTOCOLLNPGM("Power-loss file write failed.");
|
if (ret == -1) SERIAL_PROTOCOLLNPGM("Power-loss file write failed.");
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,14 +1021,17 @@ void CardReader::printingHasFinished() {
|
||||||
|
|
||||||
void CardReader::removeJobRecoveryFile() {
|
void CardReader::removeJobRecoveryFile() {
|
||||||
job_recovery_info.valid_head = job_recovery_info.valid_foot = job_recovery_commands_count = 0;
|
job_recovery_info.valid_head = job_recovery_info.valid_foot = job_recovery_commands_count = 0;
|
||||||
const bool success = jobRecoveryFile.remove(&root, job_recovery_file_name);
|
if (jobRecoverFileExists()) {
|
||||||
|
closefile();
|
||||||
|
removeFile(job_recovery_file_name);
|
||||||
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
||||||
SERIAL_PROTOCOLPGM("Power-loss file delete");
|
SERIAL_PROTOCOLPGM("Power-loss file delete");
|
||||||
serialprintPGM(success ? PSTR("d.\n") : PSTR(" failed.\n"));
|
serialprintPGM(jobRecoverFileExists() ? PSTR(" failed.\n") : PSTR("d.\n"));
|
||||||
#else
|
#else
|
||||||
UNUSED(success);
|
UNUSED(success);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // POWER_LOSS_RECOVERY
|
#endif // POWER_LOSS_RECOVERY
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ public:
|
||||||
public:
|
public:
|
||||||
bool saving, logging, sdprinting, cardOK, filenameIsDir;
|
bool saving, logging, sdprinting, cardOK, filenameIsDir;
|
||||||
char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH];
|
char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH];
|
||||||
int autostart_index;
|
int8_t autostart_index;
|
||||||
private:
|
private:
|
||||||
SdFile root, workDir, workDirParents[MAX_DIR_DEPTH];
|
SdFile root, workDir, workDirParents[MAX_DIR_DEPTH];
|
||||||
uint8_t workDirDepth;
|
uint8_t workDirDepth;
|
||||||
|
|
Loading…
Reference in a new issue