Fix M32 P subroutine handling
This commit is contained in:
parent
9f8b4c5ee8
commit
e0d367f1fb
4 changed files with 64 additions and 43 deletions
|
@ -361,19 +361,25 @@ inline void get_serial_commands() {
|
||||||
|| ((sd_char == '#' || sd_char == ':') && !sd_comment_mode)
|
|| ((sd_char == '#' || sd_char == ':') && !sd_comment_mode)
|
||||||
) {
|
) {
|
||||||
if (card_eof) {
|
if (card_eof) {
|
||||||
SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
|
|
||||||
card.printingHasFinished();
|
card.printingHasFinished();
|
||||||
#if ENABLED(PRINTER_EVENT_LEDS)
|
|
||||||
LCD_MESSAGEPGM(MSG_INFO_COMPLETED_PRINTS);
|
if (card.sdprinting)
|
||||||
set_led_color(0, 255, 0); // Green
|
sd_count = 0; // If a sub-file was printing, continue from call point
|
||||||
#if HAS_RESUME_CONTINUE
|
else {
|
||||||
enqueue_and_echo_commands_P(PSTR("M0")); // end of the queue!
|
SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
|
||||||
#else
|
#if ENABLED(PRINTER_EVENT_LEDS)
|
||||||
safe_delay(1000);
|
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
|
#endif
|
||||||
set_led_color(0, 0, 0); // OFF
|
card.checkautostart(true);
|
||||||
#endif
|
}
|
||||||
card.checkautostart(true);
|
|
||||||
}
|
}
|
||||||
else if (n == -1) {
|
else if (n == -1) {
|
||||||
SERIAL_ERROR_START();
|
SERIAL_ERROR_START();
|
||||||
|
|
|
@ -124,19 +124,23 @@ void GcodeSuite::M30() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* M32: Select file and start SD Print
|
* 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() {
|
void GcodeSuite::M32() {
|
||||||
if (IS_SD_PRINTING)
|
if (card.sdprinting) stepper.synchronize();
|
||||||
stepper.synchronize();
|
|
||||||
|
|
||||||
char* namestartpos = parser.string_arg;
|
|
||||||
const bool call_procedure = parser.boolval('P');
|
|
||||||
|
|
||||||
if (card.cardOK) {
|
if (card.cardOK) {
|
||||||
card.openFile(namestartpos, true, call_procedure);
|
const bool call_procedure = parser.boolval('P');
|
||||||
|
|
||||||
if (parser.seenval('S'))
|
card.openFile(parser.string_arg, true, call_procedure);
|
||||||
card.setIndex(parser.value_long());
|
|
||||||
|
if (parser.seenval('S')) card.setIndex(parser.value_long());
|
||||||
|
|
||||||
card.startFileprint();
|
card.startFileprint();
|
||||||
|
|
||||||
|
|
|
@ -310,26 +310,33 @@ void CardReader::openLogFile(char* name) {
|
||||||
openFile(name, false);
|
openFile(name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::getAbsFilename(char *t) {
|
void appendAtom(SdFile &file, char *& dst, uint8_t &cnt) {
|
||||||
uint8_t cnt = 0;
|
file.getFilename(dst);
|
||||||
*t = '/'; t++; cnt++;
|
while (*dst && cnt < MAXPATHNAMELENGTH) { dst++; cnt++; }
|
||||||
for (uint8_t i = 0; i < workDirDepth; i++) {
|
if (cnt < MAXPATHNAMELENGTH) { *dst = '/'; dst++; cnt++; }
|
||||||
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 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;
|
if (!cardOK) return;
|
||||||
|
|
||||||
uint8_t doing = 0;
|
uint8_t doing = 0;
|
||||||
if (isFileOpen()) { //replacing current file by new file, or subfile call
|
if (isFileOpen()) { // Replacing current file or doing a subroutine
|
||||||
if (push_current) {
|
if (subcall) {
|
||||||
if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) {
|
if (file_subcall_ctr > SD_PROCEDURE_DEPTH - 1) {
|
||||||
SERIAL_ERROR_START();
|
SERIAL_ERROR_START();
|
||||||
SERIAL_ERRORPGM("trying to call sub-gcode files with too many levels. MAX level is:");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store current filename and position
|
// Store current filename (based on workDirParents) and position
|
||||||
getAbsFilename(proc_filenames[file_subcall_ctr]);
|
getAbsFilename(proc_filenames[file_subcall_ctr]);
|
||||||
|
filespos[file_subcall_ctr] = sdpos;
|
||||||
|
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", name);
|
SERIAL_ECHOPAIR("SUBROUTINE CALL target:\"", name);
|
||||||
SERIAL_ECHOPAIR("\" parent:\"", proc_filenames[file_subcall_ctr]);
|
SERIAL_ECHOPAIR("\" parent:\"", proc_filenames[file_subcall_ctr]);
|
||||||
SERIAL_ECHOLNPAIR("\" pos", sdpos);
|
SERIAL_ECHOLNPAIR("\" pos", sdpos);
|
||||||
filespos[file_subcall_ctr] = sdpos;
|
|
||||||
file_subcall_ctr++;
|
file_subcall_ctr++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
doing = 1;
|
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;
|
doing = 2;
|
||||||
file_subcall_ctr = 0; // Reset procedure depth in case user cancels print while in procedure
|
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) {
|
void CardReader::chdir(const char * relpath) {
|
||||||
SdFile newfile;
|
SdFile newDir;
|
||||||
SdFile *parent = &root;
|
SdFile *parent = &root;
|
||||||
|
|
||||||
if (workDir.isOpen()) parent = &workDir;
|
if (workDir.isOpen()) parent = &workDir;
|
||||||
|
|
||||||
if (!newfile.open(*parent, relpath, O_READ)) {
|
if (!newDir.open(*parent, relpath, O_READ)) {
|
||||||
SERIAL_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR);
|
SERIAL_ECHOPGM(MSG_SD_CANT_ENTER_SUBDIR);
|
||||||
SERIAL_ECHOLN(relpath);
|
SERIAL_ECHOLN(relpath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
workDir = newDir;
|
||||||
if (workDirDepth < MAX_DIR_DEPTH)
|
if (workDirDepth < MAX_DIR_DEPTH)
|
||||||
workDirParents[workDirDepth++] = *parent;
|
workDirParents[workDirDepth++] = workDir;
|
||||||
workDir = newfile;
|
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
presort();
|
presort();
|
||||||
#endif
|
#endif
|
||||||
|
@ -621,8 +632,8 @@ void CardReader::chdir(const char * relpath) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CardReader::updir() {
|
void CardReader::updir() {
|
||||||
if (workDirDepth > 0) {
|
if (workDirDepth > 0) { // At least 1 dir has been saved
|
||||||
workDir = workDirParents[--workDirDepth];
|
workDir = --workDirDepth ? workDirParents[workDirDepth] : root; // Use parent, or root if none
|
||||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||||
presort();
|
presort();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
// device is available soon after a reset.
|
// device is available soon after a reset.
|
||||||
|
|
||||||
void checkautostart(bool x);
|
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 openLogFile(char* name);
|
||||||
void removeFile(const char * const name);
|
void removeFile(const char * const name);
|
||||||
void closefile(bool store_location=false);
|
void closefile(bool store_location=false);
|
||||||
|
|
Reference in a new issue