From 05fca752d6d7b88b7697dd5273b6f0428655f3d5 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Tue, 1 May 2018 01:01:02 -0500
Subject: [PATCH] Clean up autostart handling

---
 Marlin/src/Marlin.cpp        | 12 +++----
 Marlin/src/gcode/queue.cpp   |  1 -
 Marlin/src/lcd/ultralcd.cpp  | 13 ++++----
 Marlin/src/sd/cardreader.cpp | 62 ++++++++++++++++++------------------
 Marlin/src/sd/cardreader.h   | 13 +++-----
 5 files changed, 46 insertions(+), 55 deletions(-)

diff --git a/Marlin/src/Marlin.cpp b/Marlin/src/Marlin.cpp
index 6c9ded576..870d133f7 100644
--- a/Marlin/src/Marlin.cpp
+++ b/Marlin/src/Marlin.cpp
@@ -894,19 +894,17 @@ void setup() {
  *
  *  - Save or log commands to SD
  *  - Process available commands (if not saving)
- *  - Call heater manager
- *  - Call inactivity manager
  *  - Call endstop manager
- *  - Call LCD update
+ *  - Call inactivity manager
  */
 void loop() {
 
-  #if ENABLED(SDSUPPORT)
-    card.checkautostart(false);
-  #endif
-
   for (;;) {
 
+    #if ENABLED(SDSUPPORT)
+      card.checkautostart();
+    #endif
+
     #if ENABLED(SDSUPPORT) && ENABLED(ULTIPANEL)
       if (abort_sd_printing) {
         abort_sd_printing = false;
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index a8f5e62da..7e92579ee 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -458,7 +458,6 @@ inline void get_serial_commands() {
                 leds.set_off();
               #endif
             #endif // PRINTER_EVENT_LEDS
-            card.checkautostart(true);
           }
         }
         else if (n == -1) {
diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp
index 5000f7c2e..965a94dc6 100644
--- a/Marlin/src/lcd/ultralcd.cpp
+++ b/Marlin/src/lcd/ultralcd.cpp
@@ -1814,11 +1814,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
 
   #if ENABLED(SDSUPPORT) && ENABLED(MENU_ADDAUTOSTART)
 
-    void lcd_autostart_sd() {
-      card.autostart_index = 0;
-      card.setroot();
-      card.checkautostart(true);
-    }
+    void lcd_autostart_sd() { card.beginautostart(); }
 
   #endif
 
@@ -5131,9 +5127,12 @@ void lcd_update() {
       lcd_sd_status = sd_status;
 
       if (sd_status) {
-        safe_delay(1000); // some boards need a delay or the LCD won't show the new status
+        safe_delay(500); // Some boards need a delay to get settled
         card.initsd();
-        if (old_sd_status != 2) LCD_MESSAGEPGM(MSG_SD_INSERTED);
+        if (old_sd_status == 2)
+          card.beginautostart();  // Initial boot
+        else
+          LCD_MESSAGEPGM(MSG_SD_INSERTED);
       }
       else {
         card.release();
diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp
index 42696c28a..e8c63bcf6 100644
--- a/Marlin/src/sd/cardreader.cpp
+++ b/Marlin/src/sd/cardreader.cpp
@@ -62,15 +62,13 @@ CardReader::CardReader() {
   workDirDepth = 0;
   ZERO(workDirParents);
 
-  autostart_stilltocheck = true; //the SD start is delayed, because otherwise the serial cannot answer fast enough to make contact with the host software.
-  autostart_index = 0;
+  // Disable autostart until card is initialized
+  autostart_index = -1;
 
   //power to SD reader
   #if SDPOWER > -1
     OUT_WRITE(SDPOWER, HIGH);
-  #endif // SDPOWER
-
-  next_autostart_ms = millis() + 5000;
+  #endif
 }
 
 char *createFilename(char *buffer, const dir_t &p) { //buffer > 12characters
@@ -607,40 +605,42 @@ void CardReader::write_command(char *buf) {
   }
 }
 
-void CardReader::checkautostart(bool force) {
-  if (!force && (!autostart_stilltocheck || PENDING(millis(), next_autostart_ms)))
-    return;
-
-  autostart_stilltocheck = false;
+//
+// Run the next autostart file. Called:
+// - On boot after successful card init
+// - After finishing the previous autostart file
+// - From the LCD command to run the autostart file
+//
 
-  if (!cardOK) {
-    initsd();
-    if (!cardOK) return; // fail
-  }
-
-  char autoname[10];
-  sprintf_P(autoname, PSTR("auto%i.g"), autostart_index);
-  for (int8_t i = 0; i < (int8_t)strlen(autoname); i++) autoname[i] = tolower(autoname[i]);
+void CardReader::checkautostart() {
 
-  dir_t p;
+  if (autostart_index < 0 || sdprinting) return;
 
-  root.rewind();
+  if (!cardOK) initsd();
 
-  bool found = false;
-  while (root.readDir(p, NULL) > 0) {
-    for (int8_t i = (int8_t)strlen((char*)p.name); i--;) p.name[i] = tolower(p.name[i]);
-    if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) {
-      openAndPrintFile(autoname);
-      found = true;
+  if (cardOK) {
+    char autoname[10];
+    sprintf_P(autoname, PSTR("auto%i.g"), autostart_index);
+    dir_t p;
+    root.rewind();
+    while (root.readDir(p, NULL) > 0) {
+      for (int8_t i = (int8_t)strlen((char*)p.name); i--;) p.name[i] = tolower(p.name[i]);
+      if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) {
+        openAndPrintFile(autoname);
+        autostart_index++;
+        return;
+      }
     }
   }
-  if (!found)
-    autostart_index = -1;
-  else
-    autostart_index++;
+  autostart_index = -1;
+}
+
+void CardReader::beginautostart() {
+  autostart_index = 0;
+  setroot();
 }
 
-void CardReader::closefile(bool store_location) {
+void CardReader::closefile(const bool store_location) {
   file.sync();
   file.close();
   saving = logging = false;
diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h
index a66c69887..624bef4a2 100644
--- a/Marlin/src/sd/cardreader.h
+++ b/Marlin/src/sd/cardreader.h
@@ -39,16 +39,14 @@ public:
 
   void initsd();
   void write_command(char *buf);
-  // Files auto[0-9].g on the sd card are performed in sequence.
-  // This is to delay autostart and hence the initialisation of
-  // the sd card to some seconds after the normal init, so the
-  // device is available soon after a reset.
 
-  void checkautostart(bool x);
+  void beginautostart();
+  void checkautostart();
+
   void openFile(char* name, const bool read, const bool subcall=false);
   void openLogFile(char* name);
   void removeFile(const char * const name);
-  void closefile(bool store_location=false);
+  void closefile(const bool store_location=false);
   void release();
   void openAndPrintFile(const char *name);
   void startFileprint();
@@ -212,9 +210,6 @@ private:
   char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
   uint32_t filesize, sdpos;
 
-  millis_t next_autostart_ms;
-  bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
-
   LsAction lsAction; //stored for recursion.
   uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
   char* diveDirName;