From e0d367f1fb12c57eca03df7994eeee629c0fea50 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Wed, 15 Nov 2017 00:15:57 -0600 Subject: [PATCH] Fix M32 P subroutine handling --- Marlin/src/gcode/queue.cpp | 28 ++++++---- .../src/gcode/sdcard/M20-M30_M32-M34_M928.cpp | 20 ++++--- Marlin/src/sd/cardreader.cpp | 53 +++++++++++-------- Marlin/src/sd/cardreader.h | 2 +- 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 9f104ce801..54614bc25e 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -361,19 +361,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(); diff --git a/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp b/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp index 001783585f..566a880103 100644 --- a/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp +++ b/Marlin/src/gcode/sdcard/M20-M30_M32-M34_M928.cpp @@ -124,19 +124,23 @@ void GcodeSuite::M30() { /** * 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 + * */ void GcodeSuite::M32() { - if (IS_SD_PRINTING) - 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'); + + card.openFile(parser.string_arg, true, call_procedure); - if (parser.seenval('S')) - card.setIndex(parser.value_long()); + if (parser.seenval('S')) card.setIndex(parser.value_long()); card.startFileprint(); diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index b68911d0c0..663b788321 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -310,26 +310,33 @@ void CardReader::openLogFile(char* name) { openFile(name, false); } +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::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. + *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; } - if (cnt < MAXPATHNAMELENGTH - (FILENAME_LENGTH)) - file.getFilename(t); - else - t[0] = 0; + *t = '\0'; } -void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { +void CardReader::openFile(char* name, const bool read, const bool subcall/*=false*/) { if (!cardOK) return; uint8_t doing = 0; - if (isFileOpen()) { //replacing current file by new file, or subfile call - 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:"); @@ -338,20 +345,24 @@ void CardReader::openFile(char* name, bool read, bool push_current/*=false*/) { return; } - // Store current filename and position + // Store current filename (based on workDirParents) and position getAbsFilename(proc_filenames[file_subcall_ctr]); + filespos[file_subcall_ctr] = sdpos; SERIAL_ECHO_START(); SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", name); SERIAL_ECHOPAIR("\" parent:\"", proc_filenames[file_subcall_ctr]); SERIAL_ECHOLNPAIR("\" pos", sdpos); - filespos[file_subcall_ctr] = sdpos; file_subcall_ctr++; } 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 } @@ -600,20 +611,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 @@ -621,8 +632,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/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index 1a9a6c1115..5d10e34a68 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -41,7 +41,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);