|
|
@ -161,7 +161,7 @@ CardReader::CardReader() { |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
flag.sdprinting = flag.mounted = flag.saving = flag.logging = false; |
|
|
|
flag.sdprinting = flag.sdprintdone = flag.mounted = flag.saving = flag.logging = false; |
|
|
|
filesize = sdpos = 0; |
|
|
|
|
|
|
|
TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); |
|
|
@ -379,7 +379,7 @@ void CardReader::ls() { |
|
|
|
//
|
|
|
|
// Echo the DOS 8.3 filename (and long filename, if any)
|
|
|
|
//
|
|
|
|
void CardReader::printFilename() { |
|
|
|
void CardReader::printSelectedFilename() { |
|
|
|
if (file.isOpen()) { |
|
|
|
char dosFilename[FILENAME_LENGTH]; |
|
|
|
file.getDosName(dosFilename); |
|
|
@ -487,9 +487,9 @@ void CardReader::manage_media() { |
|
|
|
void CardReader::release() { |
|
|
|
// Card removed while printing? Abort!
|
|
|
|
if (IS_SD_PRINTING()) |
|
|
|
card.flag.abort_sd_printing = true; |
|
|
|
abortFilePrintSoon(); |
|
|
|
else |
|
|
|
endFilePrint(); |
|
|
|
endFilePrintNow(); |
|
|
|
|
|
|
|
flag.mounted = false; |
|
|
|
flag.workDirIsRoot = true; |
|
|
@ -516,9 +516,10 @@ void CardReader::openAndPrintFile(const char *name) { |
|
|
|
* since you cannot browse files during active printing. |
|
|
|
* Used by M24 and anywhere Start / Resume applies. |
|
|
|
*/ |
|
|
|
void CardReader::startFileprint() { |
|
|
|
void CardReader::startOrResumeFilePrinting() { |
|
|
|
if (isMounted()) { |
|
|
|
flag.sdprinting = true; |
|
|
|
flag.sdprintdone = false; |
|
|
|
TERN_(SD_RESORT, flush_presort()); |
|
|
|
} |
|
|
|
} |
|
|
@ -526,14 +527,19 @@ void CardReader::startFileprint() { |
|
|
|
//
|
|
|
|
// Run tasks upon finishing or aborting a file print.
|
|
|
|
//
|
|
|
|
void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { |
|
|
|
void CardReader::endFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { |
|
|
|
TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0); |
|
|
|
TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting); |
|
|
|
flag.sdprinting = flag.abort_sd_printing = false; |
|
|
|
flag.abort_sd_printing = false; |
|
|
|
if (isFileOpen()) file.close(); |
|
|
|
TERN_(SD_RESORT, if (re_sort) presort()); |
|
|
|
} |
|
|
|
|
|
|
|
void CardReader::abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) { |
|
|
|
flag.sdprinting = flag.sdprintdone = false; |
|
|
|
endFilePrintNow(TERN_(SD_RESORT, re_sort)); |
|
|
|
} |
|
|
|
|
|
|
|
void CardReader::openLogFile(const char * const path) { |
|
|
|
flag.logging = DISABLED(SDCARD_READONLY); |
|
|
|
IF_DISABLED(SDCARD_READONLY, openFileWrite(path)); |
|
|
@ -542,7 +548,7 @@ void CardReader::openLogFile(const char * const path) { |
|
|
|
//
|
|
|
|
// Get the root-relative DOS path of the selected file
|
|
|
|
//
|
|
|
|
void CardReader::getAbsFilename(char *dst) { |
|
|
|
void CardReader::getAbsFilenameInCWD(char *dst) { |
|
|
|
*dst++ = '/'; |
|
|
|
uint8_t cnt = 1; |
|
|
|
|
|
|
@ -608,7 +614,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ |
|
|
|
} |
|
|
|
|
|
|
|
// Store current filename (based on workDirParents) and position
|
|
|
|
getAbsFilename(proc_filenames[file_subcall_ctr]); |
|
|
|
getAbsFilenameInCWD(proc_filenames[file_subcall_ctr]); |
|
|
|
filespos[file_subcall_ctr] = sdpos; |
|
|
|
|
|
|
|
// For sub-procedures say 'SUBROUTINE CALL target: "..." parent: "..." pos12345'
|
|
|
@ -623,7 +629,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
endFilePrint(); |
|
|
|
abortFilePrintNow(); |
|
|
|
|
|
|
|
SdFile *diveDir; |
|
|
|
const char * const fname = diveToFile(true, diveDir, path); |
|
|
@ -659,7 +665,7 @@ void CardReader::openFileWrite(const char * const path) { |
|
|
|
announceOpen(2, path); |
|
|
|
TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0); |
|
|
|
|
|
|
|
endFilePrint(); |
|
|
|
abortFilePrintNow(); |
|
|
|
|
|
|
|
SdFile *diveDir; |
|
|
|
const char * const fname = diveToFile(false, diveDir, path); |
|
|
@ -712,7 +718,7 @@ bool CardReader::fileExists(const char * const path) { |
|
|
|
void CardReader::removeFile(const char * const name) { |
|
|
|
if (!isMounted()) return; |
|
|
|
|
|
|
|
//endFilePrint();
|
|
|
|
//abortFilePrintNow();
|
|
|
|
|
|
|
|
SdFile *curDir; |
|
|
|
const char * const fname = diveToFile(false, curDir, name); |
|
|
@ -856,6 +862,9 @@ uint16_t CardReader::countFilesInWorkDir() { |
|
|
|
/**
|
|
|
|
* Dive to the given DOS 8.3 file path, with optional echo of the dive paths. |
|
|
|
* |
|
|
|
* On entry: |
|
|
|
* - The workDir points to the last-set navigation target by cd, cdup, cdroot, or diveToFile(true, ...) |
|
|
|
* |
|
|
|
* On exit: |
|
|
|
* - Your curDir pointer contains an SdFile reference to the file's directory. |
|
|
|
* - If update_cwd was 'true' the workDir now points to the file's directory. |
|
|
@ -865,6 +874,8 @@ uint16_t CardReader::countFilesInWorkDir() { |
|
|
|
* A nullptr result indicates an unrecoverable error. |
|
|
|
*/ |
|
|
|
const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, const char * const path, const bool echo/*=false*/) { |
|
|
|
DEBUG_SECTION(est, "diveToFile", true); |
|
|
|
|
|
|
|
// Track both parent and subfolder
|
|
|
|
static SdFile newDir1, newDir2; |
|
|
|
SdFile *sub = &newDir1, *startDir; |
|
|
@ -872,12 +883,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons |
|
|
|
// Parsing the path string
|
|
|
|
const char *item_name_adr = path; |
|
|
|
|
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'"); |
|
|
|
DEBUG_ECHOLNPAIR(" path = '", path, "'"); |
|
|
|
|
|
|
|
if (path[0] == '/') { // Starting at the root directory?
|
|
|
|
diveDir = &root; |
|
|
|
item_name_adr++; |
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir)); |
|
|
|
DEBUG_ECHOLNPAIR(" CWD to root: ", hex_address((void*)diveDir)); |
|
|
|
if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
|
|
|
|
} |
|
|
|
else |
|
|
@ -885,7 +896,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons |
|
|
|
|
|
|
|
startDir = diveDir; |
|
|
|
|
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: startDir = ", hex_address((void*)startDir)); |
|
|
|
DEBUG_ECHOLNPAIR(" startDir = ", hex_address((void*)startDir)); |
|
|
|
|
|
|
|
while (item_name_adr) { |
|
|
|
// Find next subdirectory delimiter
|
|
|
@ -902,7 +913,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons |
|
|
|
|
|
|
|
if (echo) SERIAL_ECHOLN(dosSubdirname); |
|
|
|
|
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub)); |
|
|
|
DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub)); |
|
|
|
|
|
|
|
// Open diveDir (closing first)
|
|
|
|
sub->close(); |
|
|
@ -914,24 +925,24 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons |
|
|
|
|
|
|
|
// Close diveDir if not at starting-point
|
|
|
|
if (diveDir != startDir) { |
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: closing diveDir: ", hex_address((void*)diveDir)); |
|
|
|
DEBUG_ECHOLNPAIR(" closing diveDir: ", hex_address((void*)diveDir)); |
|
|
|
diveDir->close(); |
|
|
|
} |
|
|
|
|
|
|
|
// diveDir now subDir
|
|
|
|
diveDir = sub; |
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: diveDir = sub: ", hex_address((void*)diveDir)); |
|
|
|
DEBUG_ECHOLNPAIR(" diveDir = sub: ", hex_address((void*)diveDir)); |
|
|
|
|
|
|
|
// Update workDirParents and workDirDepth
|
|
|
|
if (update_cwd) { |
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: update_cwd"); |
|
|
|
DEBUG_ECHOLNPAIR(" update_cwd"); |
|
|
|
if (workDirDepth < MAX_DIR_DEPTH) |
|
|
|
workDirParents[workDirDepth++] = *diveDir; |
|
|
|
} |
|
|
|
|
|
|
|
// Point sub at the other scratch object
|
|
|
|
sub = (diveDir != &newDir1) ? &newDir1 : &newDir2; |
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: swapping sub = ", hex_address((void*)sub)); |
|
|
|
DEBUG_ECHOLNPAIR(" swapping sub = ", hex_address((void*)sub)); |
|
|
|
|
|
|
|
// Next path atom address
|
|
|
|
item_name_adr = name_end + 1; |
|
|
@ -939,11 +950,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons |
|
|
|
|
|
|
|
if (update_cwd) { |
|
|
|
workDir = *diveDir; |
|
|
|
DEBUG_ECHOLNPAIR("diveToFile: final workDir = ", hex_address((void*)diveDir)); |
|
|
|
DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)diveDir)); |
|
|
|
flag.workDirIsRoot = (workDirDepth == 0); |
|
|
|
TERN_(SDCARD_SORT_ALPHA, presort()); |
|
|
|
} |
|
|
|
|
|
|
|
DEBUG_ECHOLNPAIR(" returning string ", item_name_adr ?: "nullptr"); |
|
|
|
return item_name_adr; |
|
|
|
} |
|
|
|
|
|
|
@ -1225,21 +1237,21 @@ uint16_t CardReader::get_num_Files() { |
|
|
|
// Return from procedure or close out the Print Job
|
|
|
|
//
|
|
|
|
void CardReader::fileHasFinished() { |
|
|
|
planner.synchronize(); |
|
|
|
file.close(); |
|
|
|
|
|
|
|
#if HAS_MEDIA_SUBCALLS |
|
|
|
if (file_subcall_ctr > 0) { // Resume calling file after closing procedure
|
|
|
|
file_subcall_ctr--; |
|
|
|
openFileRead(proc_filenames[file_subcall_ctr], 2); // 2 = Returning from sub-procedure
|
|
|
|
setIndex(filespos[file_subcall_ctr]); |
|
|
|
startFileprint(); |
|
|
|
startOrResumeFilePrinting(); |
|
|
|
return; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
endFilePrint(TERN_(SD_RESORT, true)); |
|
|
|
marlin_state = MF_SD_COMPLETE; |
|
|
|
endFilePrintNow(TERN_(SD_RESORT, true)); |
|
|
|
|
|
|
|
flag.sdprintdone = true; // Stop getting bytes from the SD card
|
|
|
|
marlin_state = MF_SD_COMPLETE; // Tell Marlin to enqueue M1001 soon
|
|
|
|
} |
|
|
|
|
|
|
|
#if ENABLED(AUTO_REPORT_SD_STATUS) |
|
|
|