diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index ed4efcfc2d..ec62ca85a3 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -1276,19 +1276,25 @@ inline void get_serial_commands() { || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode) ) { if (card_eof) { - SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); + card.printingHasFinished(); - #if ENABLED(PRINTER_EVENT_LEDS) - LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS); - set_led_color(0, 255, 0); // Green - #if HAS_RESUME_CONTINUE - enqueue_and_echo_commands_P(PSTR("M0")); // end of the queue! - #else - safe_delay(1000); + + if (card.sdprinting) + sd_count = 0; // If a sub-file was printing, continue from call point + else { + SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED); + #if ENABLED(PRINTER_EVENT_LEDS) + LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS); + set_led_color(0, 255, 0); // Green + #if HAS_RESUME_CONTINUE + enqueue_and_echo_commands_P(PSTR("M0")); // end of the queue! + #else + safe_delay(1000); + #endif + set_led_color(0, 0, 0); // OFF #endif - set_led_color(0, 0, 0); // OFF - #endif - card.checkautostart(true); + card.checkautostart(true); + } } else if (n == -1) { SERIAL_ERROR_START(); @@ -6897,19 +6903,23 @@ inline void gcode_M31() { /** * M32: Select file and start SD Print + * + * Examples: + * + * M32 !PATH/TO/FILE.GCO# ; Start FILE.GCO + * M32 P !PATH/TO/FILE.GCO# ; Start FILE.GCO as a procedure + * M32 S60 !PATH/TO/FILE.GCO# ; Start FILE.GCO at byte 60 + * */ inline void gcode_M32() { - if (card.sdprinting) - stepper.synchronize(); - - char* namestartpos = parser.string_arg; - const bool call_procedure = parser.boolval('P'); + if (card.sdprinting) stepper.synchronize(); if (card.cardOK) { - card.openFile(namestartpos, true, call_procedure); + const bool call_procedure = parser.boolval('P'); - if (parser.seenval('S')) - card.setIndex(parser.value_long()); + card.openFile(parser.string_arg, true, call_procedure); + + if (parser.seenval('S')) card.setIndex(parser.value_long()); card.startFileprint(); diff --git a/Marlin/cardreader.cpp b/Marlin/cardreader.cpp index 37f87447a7..9728961e73 100644 --- a/Marlin/cardreader.cpp +++ b/Marlin/cardreader.cpp @@ -302,26 +302,33 @@ void CardReader::openLogFile(char* name) { openFile(name, false); } -void CardReader::getAbsFilename(char *t) { - uint8_t cnt = 0; - *t = '/'; t++; cnt++; - for (uint8_t i = 0; i < workDirDepth; i++) { - workDirParents[i].getFilename(t); //SDBaseFile.getfilename! - while (*t && cnt < MAXPATHNAMELENGTH) { t++; cnt++; } //crawl counter forward. - } - if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH)) - file.getFilename(t); - else - t[0] = 0; +void appendAtom(SdFile &file, char *& dst, uint8_t &cnt) { + file.getFilename(dst); + while (*dst && cnt < MAXPATHNAMELENGTH) { dst++; cnt++; } + if (cnt < MAXPATHNAMELENGTH) { *dst = '/'; dst++; cnt++; } } -void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { +void CardReader::getAbsFilename(char *t) { + *t++ = '/'; // Root folder + uint8_t cnt = 1; + + for (uint8_t i = 0; i < workDirDepth; i++) // Loop to current work dir + appendAtom(workDirParents[i], t, cnt); + + if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH)) { + appendAtom(file, t, cnt); + --t; + } + *t = '\0'; +} + +void CardReader::openFile(char* name, const bool read, const bool subcall/*=false*/) { if (!cardOK) return; uint8_t doing = 0; - if (push_current) { if (isFileOpen()) { // Replacing current file or doing a subroutine + if (subcall) { if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) { SERIAL_ERROR_START(); SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:"); @@ -343,7 +350,11 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { else doing = 1; } - else { // Opening fresh file + else if (subcall) { // Returning from a subcall? + SERIAL_ECHO_START(); + SERIAL_ECHOLNPGM("END SUBROUTINE"); + } + else { // Opening fresh file doing = 2; file_subcall_ctr = 0; // Reset procedure depth in case user cancels print while in procedure } @@ -592,20 +603,20 @@ uint16_t CardReader::getnrfilenames() { } void CardReader::chdir(const char * relpath) { - SdFile newfile; + SdFile newDir; SdFile *parent = &root; if (workDir.isOpen()) parent = &workDir; - if (!newfile.open(*parent, relpath, O_READ)) { + if (!newDir.open(*parent, relpath, O_READ)) { SERIAL_ECHO_START(); SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR); SERIAL_ECHOLN(relpath); } else { + workDir = newDir; if (workDirDepth < MAX_DIR_DEPTH) - workDirParents[workDirDepth++] = *parent; - workDir = newfile; + workDirParents[workDirDepth++] = workDir; #if ENABLED(SDCARD_SORT_ALPHA) presort(); #endif @@ -613,8 +624,8 @@ void CardReader::chdir(const char * relpath) { } void CardReader::updir() { - if (workDirDepth > 0) { - workDir = workDirParents[--workDirDepth]; + if (workDirDepth > 0) { // At least 1 dir has been saved + workDir = --workDirDepth ? workDirParents[workDirDepth] : root; // Use parent, or root if none #if ENABLED(SDCARD_SORT_ALPHA) presort(); #endif diff --git a/Marlin/cardreader.h b/Marlin/cardreader.h index c56a850a1e..3feb5d55f4 100644 --- a/Marlin/cardreader.h +++ b/Marlin/cardreader.h @@ -45,7 +45,7 @@ public: // device is available soon after a reset. void checkautostart(bool x); - void openFile(char* name, bool read, bool push_current=false); + 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);