|
@@ -43,14 +43,14 @@ job_recovery_info_t job_recovery_info;
|
43
|
43
|
JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
|
44
|
44
|
uint8_t job_recovery_commands_count; //=0
|
45
|
45
|
char job_recovery_commands[BUFSIZE + APPEND_CMD_COUNT][MAX_CMD_SIZE];
|
46
|
|
-
|
47
|
|
-// Private
|
48
|
|
-static char sd_filename[MAXPATHNAMELENGTH];
|
|
46
|
+// Extern
|
|
47
|
+extern uint8_t active_extruder, commands_in_queue, cmd_queue_index_r;
|
49
|
48
|
|
50
|
49
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
51
|
50
|
void debug_print_job_recovery(const bool recovery) {
|
52
|
|
- SERIAL_PROTOCOLPAIR("valid_head:", (int)job_recovery_info.valid_head);
|
53
|
|
- SERIAL_PROTOCOLLNPAIR(" valid_foot:", (int)job_recovery_info.valid_foot);
|
|
51
|
+ SERIAL_PROTOCOLLNPGM("---- Job Recovery Info ----");
|
|
52
|
+ SERIAL_PROTOCOLPAIR("valid_head:", int(job_recovery_info.valid_head));
|
|
53
|
+ SERIAL_PROTOCOLLNPAIR(" valid_foot:", int(job_recovery_info.valid_foot));
|
54
|
54
|
if (job_recovery_info.valid_head) {
|
55
|
55
|
if (job_recovery_info.valid_head == job_recovery_info.valid_foot) {
|
56
|
56
|
SERIAL_PROTOCOLPGM("current_position: ");
|
|
@@ -60,6 +60,11 @@ static char sd_filename[MAXPATHNAMELENGTH];
|
60
|
60
|
}
|
61
|
61
|
SERIAL_EOL();
|
62
|
62
|
SERIAL_PROTOCOLLNPAIR("feedrate: ", job_recovery_info.feedrate);
|
|
63
|
+
|
|
64
|
+ #if HOTENDS > 1
|
|
65
|
+ SERIAL_PROTOCOLLNPAIR("active_hotend: ", int(job_recovery_info.active_hotend));
|
|
66
|
+ #endif
|
|
67
|
+
|
63
|
68
|
SERIAL_PROTOCOLPGM("target_temperature: ");
|
64
|
69
|
HOTEND_LOOP() {
|
65
|
70
|
SERIAL_PROTOCOL(job_recovery_info.target_temperature[e]);
|
|
@@ -84,8 +89,8 @@ static char sd_filename[MAXPATHNAMELENGTH];
|
84
|
89
|
SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
|
85
|
90
|
SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
|
86
|
91
|
#endif
|
87
|
|
- SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", job_recovery_info.cmd_queue_index_r);
|
88
|
|
- SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", job_recovery_info.commands_in_queue);
|
|
92
|
+ SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", int(job_recovery_info.cmd_queue_index_r));
|
|
93
|
+ SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", int(job_recovery_info.commands_in_queue));
|
89
|
94
|
if (recovery)
|
90
|
95
|
for (uint8_t i = 0; i < job_recovery_commands_count; i++) SERIAL_PROTOCOLLNPAIR("> ", job_recovery_commands[i]);
|
91
|
96
|
else
|
|
@@ -97,15 +102,17 @@ static char sd_filename[MAXPATHNAMELENGTH];
|
97
|
102
|
else
|
98
|
103
|
SERIAL_PROTOCOLLNPGM("INVALID DATA");
|
99
|
104
|
}
|
|
105
|
+ SERIAL_PROTOCOLLNPGM("---------------------------");
|
100
|
106
|
}
|
101
|
107
|
#endif // DEBUG_POWER_LOSS_RECOVERY
|
102
|
108
|
|
103
|
109
|
/**
|
104
|
|
- * Check for Print Job Recovery
|
105
|
|
- * If the file has a saved state, populate the job_recovery_commands queue
|
|
110
|
+ * Check for Print Job Recovery during setup()
|
|
111
|
+ *
|
|
112
|
+ * If a saved state exists, populate job_recovery_commands with
|
|
113
|
+ * commands to restore the machine state and continue the file.
|
106
|
114
|
*/
|
107
|
|
-void do_print_job_recovery() {
|
108
|
|
- //if (job_recovery_commands_count > 0) return;
|
|
115
|
+void check_print_job_recovery() {
|
109
|
116
|
memset(&job_recovery_info, 0, sizeof(job_recovery_info));
|
110
|
117
|
ZERO(job_recovery_commands);
|
111
|
118
|
|
|
@@ -114,7 +121,7 @@ void do_print_job_recovery() {
|
114
|
121
|
if (card.cardOK) {
|
115
|
122
|
|
116
|
123
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
117
|
|
- SERIAL_PROTOCOLLNPAIR("Init job recovery info. Size: ", (int)sizeof(job_recovery_info));
|
|
124
|
+ SERIAL_PROTOCOLLNPAIR("Init job recovery info. Size: ", int(sizeof(job_recovery_info)));
|
118
|
125
|
#endif
|
119
|
126
|
|
120
|
127
|
if (card.jobRecoverFileExists()) {
|
|
@@ -134,7 +141,9 @@ void do_print_job_recovery() {
|
134
|
141
|
strcpy_P(job_recovery_commands[ind++], PSTR("G92.0 Z0")); // Ensure Z is equal to 0
|
135
|
142
|
strcpy_P(job_recovery_commands[ind++], PSTR("G1 Z2")); // Raise Z by 2mm (we hope!)
|
136
|
143
|
strcpy_P(job_recovery_commands[ind++], PSTR("G28 R0"
|
137
|
|
- #if !IS_KINEMATIC
|
|
144
|
+ #if ENABLED(MARLIN_DEV_MODE)
|
|
145
|
+ " S"
|
|
146
|
+ #elif !IS_KINEMATIC
|
138
|
147
|
" X Y" // Home X and Y for Cartesian
|
139
|
148
|
#endif
|
140
|
149
|
));
|
|
@@ -142,10 +151,12 @@ void do_print_job_recovery() {
|
142
|
151
|
char str_1[16], str_2[16];
|
143
|
152
|
|
144
|
153
|
#if HAS_LEVELING
|
145
|
|
- // Restore leveling state before G92 sets Z
|
146
|
|
- // This ensures the steppers correspond to the native Z
|
147
|
|
- dtostrf(job_recovery_info.fade, 1, 1, str_1);
|
148
|
|
- sprintf_P(job_recovery_commands[ind++], PSTR("M420 S%i Z%s"), int(job_recovery_info.leveling), str_1);
|
|
154
|
+ if (job_recovery_info.fade || job_recovery_info.leveling) {
|
|
155
|
+ // Restore leveling state before G92 sets Z
|
|
156
|
+ // This ensures the steppers correspond to the native Z
|
|
157
|
+ dtostrf(job_recovery_info.fade, 1, 1, str_1);
|
|
158
|
+ sprintf_P(job_recovery_commands[ind++], PSTR("M420 S%i Z%s"), int(job_recovery_info.leveling), str_1);
|
|
159
|
+ }
|
149
|
160
|
#endif
|
150
|
161
|
|
151
|
162
|
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
|
|
@@ -157,23 +168,21 @@ void do_print_job_recovery() {
|
157
|
168
|
);
|
158
|
169
|
sprintf_P(job_recovery_commands[ind++], PSTR("G92.0 Z%s E%s"), str_1, str_2); // Current Z + 2 and E
|
159
|
170
|
|
160
|
|
- strcpy_P(job_recovery_commands[ind++], PSTR("M117 Continuing..."));
|
161
|
|
-
|
162
|
|
- uint8_t r = job_recovery_info.cmd_queue_index_r;
|
163
|
|
- while (job_recovery_info.commands_in_queue) {
|
|
171
|
+ uint8_t r = job_recovery_info.cmd_queue_index_r, c = job_recovery_info.commands_in_queue;
|
|
172
|
+ while (c--) {
|
164
|
173
|
strcpy(job_recovery_commands[ind++], job_recovery_info.command_queue[r]);
|
165
|
|
- job_recovery_info.commands_in_queue--;
|
166
|
174
|
r = (r + 1) % BUFSIZE;
|
167
|
175
|
}
|
168
|
176
|
|
|
177
|
+ if (job_recovery_info.sd_filename[0] == '/') job_recovery_info.sd_filename[0] = ' ';
|
|
178
|
+ sprintf_P(job_recovery_commands[ind++], PSTR("M23 %s"), job_recovery_info.sd_filename);
|
|
179
|
+ sprintf_P(job_recovery_commands[ind++], PSTR("M24 S%ld T%ld"), job_recovery_info.sdpos, job_recovery_info.print_job_elapsed);
|
|
180
|
+
|
169
|
181
|
job_recovery_commands_count = ind;
|
170
|
182
|
|
171
|
183
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
172
|
184
|
debug_print_job_recovery(true);
|
173
|
185
|
#endif
|
174
|
|
-
|
175
|
|
- card.openFile(job_recovery_info.sd_filename, true);
|
176
|
|
- card.setIndex(job_recovery_info.sdpos);
|
177
|
186
|
}
|
178
|
187
|
else {
|
179
|
188
|
if (job_recovery_info.valid_head != job_recovery_info.valid_foot)
|
|
@@ -213,6 +222,11 @@ void save_job_recovery_info() {
|
213
|
222
|
// Machine state
|
214
|
223
|
COPY(job_recovery_info.current_position, current_position);
|
215
|
224
|
job_recovery_info.feedrate = feedrate_mm_s;
|
|
225
|
+
|
|
226
|
+ #if HOTENDS > 1
|
|
227
|
+ job_recovery_info.active_hotend = active_extruder;
|
|
228
|
+ #endif
|
|
229
|
+
|
216
|
230
|
COPY(job_recovery_info.target_temperature, thermalManager.target_temperature);
|
217
|
231
|
|
218
|
232
|
#if HAS_HEATED_BED
|
|
@@ -240,14 +254,14 @@ void save_job_recovery_info() {
|
240
|
254
|
COPY(job_recovery_info.command_queue, command_queue);
|
241
|
255
|
|
242
|
256
|
// Elapsed print job time
|
243
|
|
- job_recovery_info.print_job_elapsed = print_job_timer.duration() * 1000UL;
|
|
257
|
+ job_recovery_info.print_job_elapsed = print_job_timer.duration();
|
244
|
258
|
|
245
|
259
|
// SD file position
|
246
|
260
|
card.getAbsFilename(job_recovery_info.sd_filename);
|
247
|
261
|
job_recovery_info.sdpos = card.getIndex();
|
248
|
262
|
|
249
|
263
|
#if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
|
250
|
|
- SERIAL_PROTOCOLLNPGM("Saving job_recovery_info");
|
|
264
|
+ SERIAL_PROTOCOLLNPGM("Saving...");
|
251
|
265
|
debug_print_job_recovery(false);
|
252
|
266
|
#endif
|
253
|
267
|
|