Browse Source

Ensure proper SD print completion (#16967)

Scott Lahteine 4 years ago
parent
commit
5071fe82ab
No account linked to committer's email address

+ 72
- 8
Marlin/src/MarlinCore.cpp View File

390
 
390
 
391
 #if ENABLED(SDSUPPORT)
391
 #if ENABLED(SDSUPPORT)
392
 
392
 
393
-  void abortSDPrinting() {
394
-    card.stopSDPrint(
393
+  inline void abortSDPrinting() {
394
+    card.endFilePrint(
395
       #if SD_RESORT
395
       #if SD_RESORT
396
         true
396
         true
397
       #endif
397
       #endif
412
     #endif
412
     #endif
413
   }
413
   }
414
 
414
 
415
-#endif
415
+  #if ENABLED(PRINTER_EVENT_LEDS)
416
+    #include "feature/leds/printer_event_leds.h"
417
+  #endif
418
+
419
+  inline void finishSDPrinting() {
420
+    bool did_state = true;
421
+    switch (card.sdprinting_done_state) {
422
+
423
+      #if ENABLED(PRINTER_EVENT_LEDS)
424
+        case 1:
425
+          printerEventLEDs.onPrintCompleted();  // Change LED color for Print Completed
426
+          break;
427
+      #endif
428
+
429
+      #if HAS_RESUME_CONTINUE                   // Display "Click to Continue..."
430
+        case 2:
431
+          did_state = queue.enqueue_P(PSTR("M0 S"
432
+            #if HAS_LCD_MENU
433
+              "1800"                            // ...for 30 minutes with LCD
434
+            #else
435
+              "60"                              // ...for 1 minute with no LCD
436
+            #endif
437
+          ));
438
+          break;
439
+      #endif
440
+
441
+      case 3: print_job_timer.stop(); break;
442
+
443
+      case 4:
444
+        did_state = print_job_timer.duration() < 60 || queue.enqueue_P(PSTR("M31"));
445
+        break;
446
+
447
+      case 5:
448
+        #if ENABLED(POWER_LOSS_RECOVERY)
449
+          recovery.purge();
450
+        #endif
451
+
452
+        #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
453
+          planner.finish_and_disable();
454
+        #endif
455
+
456
+        #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
457
+          ui.set_progress_done();
458
+        #endif
459
+
460
+        #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE)
461
+          ui.reselect_last_file();
462
+        #endif
463
+
464
+        SERIAL_ECHOLNPGM(MSG_FILE_PRINTED);
465
+
466
+      default:
467
+        did_state = false;
468
+        card.sdprinting_done_state = 0;
469
+    }
470
+    if (did_state) ++card.sdprinting_done_state;
471
+  }
472
+
473
+#endif // SDSUPPORT
416
 
474
 
417
 /**
475
 /**
418
- * Manage several activities:
476
+ * Minimal management of Marlin's core activities:
419
  *  - Check for Filament Runout
477
  *  - Check for Filament Runout
420
  *  - Keep the command buffer full
478
  *  - Keep the command buffer full
421
  *  - Check for maximum inactive time between commands
479
  *  - Check for maximum inactive time between commands
1122
 /**
1180
 /**
1123
  * The main Marlin program loop
1181
  * The main Marlin program loop
1124
  *
1182
  *
1125
- *  - Save or log commands to SD
1126
- *  - Process available commands (if not saving)
1127
- *  - Call endstop manager
1128
- *  - Call inactivity manager
1183
+ *  - Call idle() to handle all tasks between G-code commands
1184
+ *      Note that no G-codes from the queue can be executed during idle()
1185
+ *      but many G-codes can be called directly anytime like macros.
1186
+ *  - Check whether SD card auto-start is needed now.
1187
+ *  - Check whether SD print finishing is needed now.
1188
+ *  - Run one G-code command from the immediate or main command queue
1189
+ *    and open up one space. Commands in the main queue may come from sd
1190
+ *    card, host, or by direct injection. The queue will continue to fill
1191
+ *    as long as idle() or manage_inactivity() are being called.
1129
  */
1192
  */
1130
 void loop() {
1193
 void loop() {
1131
   do {
1194
   do {
1135
     #if ENABLED(SDSUPPORT)
1198
     #if ENABLED(SDSUPPORT)
1136
       card.checkautostart();
1199
       card.checkautostart();
1137
       if (card.flag.abort_sd_printing) abortSDPrinting();
1200
       if (card.flag.abort_sd_printing) abortSDPrinting();
1201
+      if (card.sdprinting_done_state) finishSDPrinting();
1138
     #endif
1202
     #endif
1139
 
1203
 
1140
     queue.advance();
1204
     queue.advance();

+ 13
- 30
Marlin/src/gcode/queue.cpp View File

512
 #if ENABLED(SDSUPPORT)
512
 #if ENABLED(SDSUPPORT)
513
 
513
 
514
   /**
514
   /**
515
-   * Get commands from the SD Card until the command buffer is full
516
-   * or until the end of the file is reached. The special character '#'
517
-   * can also interrupt buffering.
515
+   * Get lines from the SD Card until the command buffer is full
516
+   * or until the end of the file is reached. Because this method
517
+   * always receives complete command-lines, they can go directly
518
+   * into the main command queue.
518
    */
519
    */
519
   inline void GCodeQueue::get_sdcard_commands() {
520
   inline void GCodeQueue::get_sdcard_commands() {
520
     static uint8_t sd_input_state = PS_NORMAL;
521
     static uint8_t sd_input_state = PS_NORMAL;
527
       const int16_t n = card.get();
528
       const int16_t n = card.get();
528
       card_eof = card.eof();
529
       card_eof = card.eof();
529
       if (n < 0 && !card_eof) { SERIAL_ERROR_MSG(MSG_SD_ERR_READ); continue; }
530
       if (n < 0 && !card_eof) { SERIAL_ERROR_MSG(MSG_SD_ERR_READ); continue; }
531
+
530
       const char sd_char = (char)n;
532
       const char sd_char = (char)n;
531
-      if (sd_char == '\n' || sd_char == '\r' || card_eof) {
533
+      const bool is_eol = sd_char == '\n' || sd_char == '\r';
534
+      if (is_eol || card_eof) {
532
 
535
 
533
         // Reset stream state, terminate the buffer, and commit a non-empty command
536
         // Reset stream state, terminate the buffer, and commit a non-empty command
537
+        if (!is_eol && sd_count) ++sd_count;          // End of file with no newline
534
         if (!process_line_done(sd_input_state, command_buffer[index_w], sd_count)) {
538
         if (!process_line_done(sd_input_state, command_buffer[index_w], sd_count)) {
535
-          _commit_command(false);                     // Can handle last line missing a newline terminator
539
+          _commit_command(false);
536
           #if ENABLED(POWER_LOSS_RECOVERY)
540
           #if ENABLED(POWER_LOSS_RECOVERY)
537
-            recovery.cmd_sdpos = card.getIndex();     // Prime for the next _commit_command
541
+            recovery.cmd_sdpos = card.getIndex();     // Prime for the NEXT _commit_command
538
           #endif
542
           #endif
539
         }
543
         }
540
 
544
 
541
-        if (card_eof) {
542
-
543
-          card.fileHasFinished();                     // Handle end of file reached
544
-
545
-          if (!IS_SD_PRINTING()) {                    // Was it the main job file?
546
-            SERIAL_ECHOLNPGM(MSG_FILE_PRINTED);       // Tell the host the file is printed.
547
-            #if ENABLED(PRINTER_EVENT_LEDS)
548
-              printerEventLEDs.onPrintCompleted();    // Change LED color for Print Completed
549
-              #if HAS_RESUME_CONTINUE
550
-                enqueue_now_P(PSTR("M0 S"             // Display "Click to Continue..."
551
-                  #if HAS_LCD_MENU
552
-                    "1800"                            // ...for 30 minutes with LCD
553
-                  #else
554
-                    "60"                              // ...for 1 minute with no LCD
555
-                  #endif
556
-                ));
557
-              #endif
558
-            #endif
559
-          }
560
-        }
545
+        if (card_eof) card.fileHasFinished();         // Handle end of file reached
561
       }
546
       }
562
       else
547
       else
563
         process_stream_char(sd_char, sd_input_state, command_buffer[index_w], sd_count);
548
         process_stream_char(sd_char, sd_input_state, command_buffer[index_w], sd_count);
633
   #endif // SDSUPPORT
618
   #endif // SDSUPPORT
634
 
619
 
635
   // The queue may be reset by a command handler or by code invoked by idle() within a handler
620
   // The queue may be reset by a command handler or by code invoked by idle() within a handler
636
-  if (length) {
637
-    --length;
638
-    if (++index_r >= BUFSIZE) index_r = 0;
639
-  }
621
+  --length;
622
+  if (++index_r >= BUFSIZE) index_r = 0;
640
 
623
 
641
 }
624
 }

+ 6
- 0
Marlin/src/gcode/queue.h View File

117
    */
117
    */
118
   static void flush_and_request_resend();
118
   static void flush_and_request_resend();
119
 
119
 
120
+  /**
121
+   * Attempt to enqueue a single G-code command
122
+   * and return 'true' if successful.
123
+   */
124
+  FORCE_INLINE static bool enqueue_P(const char* cmd) { return _enqueue(cmd); }
125
+
120
 private:
126
 private:
121
 
127
 
122
   static uint8_t index_w;  // Ring buffer write position
128
   static uint8_t index_w;  // Ring buffer write position

+ 1
- 1
Marlin/src/lcd/menu/menu.cpp View File

324
   if (should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, sync_message);
324
   if (should_draw()) MenuItem_static::draw(LCD_HEIGHT >= 4, sync_message);
325
   if (no_reentry) return;
325
   if (no_reentry) return;
326
   // Make this the current handler till all moves are done
326
   // Make this the current handler till all moves are done
327
-  no_reentry = true;
328
   const screenFunc_t old_screen = currentScreen;
327
   const screenFunc_t old_screen = currentScreen;
329
   goto_screen(_synchronize);
328
   goto_screen(_synchronize);
329
+  no_reentry = true;
330
   planner.synchronize(); // idle() is called until moves complete
330
   planner.synchronize(); // idle() is called until moves complete
331
   no_reentry = false;
331
   no_reentry = false;
332
   goto_screen(old_screen);
332
   goto_screen(old_screen);

+ 1
- 1
Marlin/src/module/endstops.cpp View File

403
 
403
 
404
     #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
404
     #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
405
       if (planner.abort_on_endstop_hit) {
405
       if (planner.abort_on_endstop_hit) {
406
-        card.stopSDPrint();
406
+        card.endFilePrint();
407
         quickstop_stepper();
407
         quickstop_stepper();
408
         thermalManager.disable_all_heaters();
408
         thermalManager.disable_all_heaters();
409
         print_job_timer.stop();
409
         print_job_timer.stop();

+ 10
- 26
Marlin/src/sd/cardreader.cpp View File

28
 
28
 
29
 #include "../MarlinCore.h"
29
 #include "../MarlinCore.h"
30
 #include "../lcd/ultralcd.h"
30
 #include "../lcd/ultralcd.h"
31
-#include "../module/planner.h"
31
+#include "../module/planner.h"        // for synchronize
32
 #include "../module/printcounter.h"
32
 #include "../module/printcounter.h"
33
 #include "../core/language.h"
33
 #include "../core/language.h"
34
 #include "../gcode/queue.h"
34
 #include "../gcode/queue.h"
49
 // public:
49
 // public:
50
 
50
 
51
 card_flags_t CardReader::flag;
51
 card_flags_t CardReader::flag;
52
+uint8_t CardReader::sdprinting_done_state;
52
 char CardReader::filename[FILENAME_LENGTH], CardReader::longFilename[LONG_FILENAME_LENGTH];
53
 char CardReader::filename[FILENAME_LENGTH], CardReader::longFilename[LONG_FILENAME_LENGTH];
53
 int8_t CardReader::autostart_index;
54
 int8_t CardReader::autostart_index;
54
 
55
 
379
 }
380
 }
380
 
381
 
381
 void CardReader::release() {
382
 void CardReader::release() {
382
-  stopSDPrint();
383
+  endFilePrint();
383
   flag.mounted = false;
384
   flag.mounted = false;
384
 }
385
 }
385
 
386
 
401
   }
402
   }
402
 }
403
 }
403
 
404
 
404
-void CardReader::stopSDPrint(
405
+void CardReader::endFilePrint(
405
   #if SD_RESORT
406
   #if SD_RESORT
406
     const bool re_sort/*=false*/
407
     const bool re_sort/*=false*/
407
   #endif
408
   #endif
501
       break;
502
       break;
502
   }
503
   }
503
 
504
 
504
-  stopSDPrint();
505
+  endFilePrint();
505
 
506
 
506
   SdFile *curDir;
507
   SdFile *curDir;
507
   const char * const fname = diveToFile(true, curDir, path);
508
   const char * const fname = diveToFile(true, curDir, path);
529
   announceOpen(2, path);
530
   announceOpen(2, path);
530
   file_subcall_ctr = 0;
531
   file_subcall_ctr = 0;
531
 
532
 
532
-  stopSDPrint();
533
+  endFilePrint();
533
 
534
 
534
   SdFile *curDir;
535
   SdFile *curDir;
535
   const char * const fname = diveToFile(false, curDir, path);
536
   const char * const fname = diveToFile(false, curDir, path);
554
 void CardReader::removeFile(const char * const name) {
555
 void CardReader::removeFile(const char * const name) {
555
   if (!isMounted()) return;
556
   if (!isMounted()) return;
556
 
557
 
557
-  //stopSDPrint();
558
+  //endFilePrint();
558
 
559
 
559
   SdFile *curDir;
560
   SdFile *curDir;
560
   const char * const fname = diveToFile(false, curDir, name);
561
   const char * const fname = diveToFile(false, curDir, name);
937
           bool didSwap = false;
938
           bool didSwap = false;
938
           uint8_t o1 = sort_order[0];
939
           uint8_t o1 = sort_order[0];
939
           #if DISABLED(SDSORT_USES_RAM)
940
           #if DISABLED(SDSORT_USES_RAM)
940
-            selectFileByIndex(o1);                // Pre-fetch the first entry and save it
941
+            selectFileByIndex(o1);              // Pre-fetch the first entry and save it
941
             strcpy(name1, longest_filename());  // so the loop only needs one fetch
942
             strcpy(name1, longest_filename());  // so the loop only needs one fetch
942
             #if HAS_FOLDER_SORTING
943
             #if HAS_FOLDER_SORTING
943
               bool dir1 = flag.filenameIsDir;
944
               bool dir1 = flag.filenameIsDir;
1073
     startFileprint();
1074
     startFileprint();
1074
   }
1075
   }
1075
   else {
1076
   else {
1076
-    stopSDPrint();
1077
-
1078
-    #if ENABLED(POWER_LOSS_RECOVERY)
1079
-      recovery.purge();
1080
-    #endif
1081
-
1082
-    #if ENABLED(SD_FINISHED_STEPPERRELEASE) && defined(SD_FINISHED_RELEASECOMMAND)
1083
-      planner.finish_and_disable();
1084
-    #endif
1085
-
1086
-    print_job_timer.stop();
1087
-    queue.enqueue_now_P(print_job_timer.duration() > 60 ? PSTR("M31") : PSTR("M117"));
1077
+    endFilePrint();
1088
 
1078
 
1089
     #if ENABLED(SDCARD_SORT_ALPHA)
1079
     #if ENABLED(SDCARD_SORT_ALPHA)
1090
       presort();
1080
       presort();
1091
     #endif
1081
     #endif
1092
 
1082
 
1093
-    #if ENABLED(LCD_SET_PROGRESS_MANUALLY)
1094
-      ui.set_progress_done();
1095
-    #endif
1096
-
1097
-    #if ENABLED(SD_REPRINT_LAST_SELECTED_FILE)
1098
-      ui.reselect_last_file();
1099
-    #endif
1083
+    sdprinting_done_state = 1;
1100
   }
1084
   }
1101
 }
1085
 }
1102
 
1086
 

+ 3
- 2
Marlin/src/sd/cardreader.h View File

49
 
49
 
50
 class CardReader {
50
 class CardReader {
51
 public:
51
 public:
52
+  static uint8_t sdprinting_done_state;
52
   static card_flags_t flag;                         // Flags (above)
53
   static card_flags_t flag;                         // Flags (above)
53
   static char filename[FILENAME_LENGTH],            // DOS 8.3 filename of the selected item
54
   static char filename[FILENAME_LENGTH],            // DOS 8.3 filename of the selected item
54
               longFilename[LONG_FILENAME_LENGTH];   // Long name of the selected item
55
               longFilename[LONG_FILENAME_LENGTH];   // Long name of the selected item
108
   static void openAndPrintFile(const char *name);   // (working directory)
109
   static void openAndPrintFile(const char *name);   // (working directory)
109
   static void fileHasFinished();
110
   static void fileHasFinished();
110
   static void getAbsFilename(char *dst);
111
   static void getAbsFilename(char *dst);
111
-  static void startFileprint();
112
   static void printFilename();
112
   static void printFilename();
113
-  static void stopSDPrint(
113
+  static void startFileprint();
114
+  static void endFilePrint(
114
     #if SD_RESORT
115
     #if SD_RESORT
115
       const bool re_sort=false
116
       const bool re_sort=false
116
     #endif
117
     #endif

Loading…
Cancel
Save