From 6d7d8c7c75e36034f9d8dcfd68090fb0819b0ac4 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Mon, 19 Apr 2021 13:31:30 +0300 Subject: [PATCH 1/7] Do not show hidden/system dirs with M20 L --- Firmware/cardreader.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 673e88c1..6f25330e 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -80,8 +80,12 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m for (position = parent.curPosition(); parent.readDir(p, longFilename) > 0; position = parent.curPosition()) { if (recursionCnt > MAX_DIR_DEPTH) return; + uint8_t pn0 = p.name[0]; + if (pn0 == DIR_NAME_FREE) break; + if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; + if (longFilename[0] == '.') continue; + if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue; else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint - // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -117,11 +121,6 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m puts_P(PSTR("DIR_EXIT")); } else { - uint8_t pn0 = p.name[0]; - if (pn0 == DIR_NAME_FREE) break; - if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; - if (longFilename[0] == '.') continue; - if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue; filenameIsDir = DIR_IS_SUBDIR(&p); if (!filenameIsDir && (p.name[8] != 'G' || p.name[9] == '~')) continue; switch (lsAction) { From b16e1e5235d8aab365ad2b5725049b7e2374dc11 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Mon, 19 Apr 2021 13:54:43 +0300 Subject: [PATCH 2/7] Invert size and LFN in M20 L output --- Firmware/cardreader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 6f25330e..c5900a7c 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -133,12 +133,14 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m createFilename(filename, p); SERIAL_PROTOCOL(prepend); SERIAL_PROTOCOL(filename); + MYSERIAL.write(' '); + SERIAL_PROTOCOL(p.fileSize); if (lsAction == LS_SerialPrint_LFN) - printf_P(PSTR("\"%s\" "), LONGEST_FILENAME); + printf_P(PSTR(" \"%s\""), LONGEST_FILENAME); - SERIAL_PROTOCOLLN(p.fileSize); + SERIAL_PROTOCOLLN(); manage_heater(); break; From 2129bcf315dd6a8038c6d0eef0c4c7fa15b06112 Mon Sep 17 00:00:00 2001 From: Voinea Dragos Date: Mon, 19 Apr 2021 14:48:50 +0300 Subject: [PATCH 3/7] M20 T --- Firmware/Marlin_main.cpp | 6 +++-- Firmware/cardreader.cpp | 53 ++++++++++++++++++++-------------------- Firmware/cardreader.h | 18 +++++++++++--- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 68933093..f46c6a53 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5744,11 +5744,13 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) - `L` - Reports ling filenames instead of just short filenames. Requires host software parsing. */ case 20: + { KEEPALIVE_STATE(NOT_BUSY); // do not send busy messages during listing. Inhibits the output of manage_heater() SERIAL_PROTOCOLLNRPGM(_N("Begin file list"));////MSG_BEGIN_FILE_LIST - card.ls(code_seen('L')); + struct CardReader::ls_param params = {.LFN = code_seen('L'), .timestamp = code_seen('T')}; + card.ls(params); SERIAL_PROTOCOLLNRPGM(_N("End file list"));////MSG_END_FILE_LIST - break; + } break; /*! ### M21 - Init SD card M21: Initialize SD card diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index c5900a7c..37c9ade9 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -61,10 +61,9 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +* LS_Count - Add +1 to nrFiles for every file within the parent +* LS_GetFilename - Get the filename of the file indexed by nrFiles +* LS_SerialPrint - Print the full path and size of each file to serial output -+* LS_SerialPrint_LFN - Print the full path, long filename and size of each file to serial output +*/ -void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/) { +void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/, LsAction lsAction, struct ls_param *lsParams) { static uint8_t recursionCnt = 0; // RAII incrementer for the recursionCnt class _incrementer @@ -85,7 +84,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; if (longFilename[0] == '.') continue; if (!DIR_IS_FILE_OR_SUBDIR(&p) || (p.attributes & DIR_ATT_HIDDEN)) continue; - else if (DIR_IS_SUBDIR(&p) && lsAction != LS_Count && lsAction != LS_GetFilename) { // If the entry is a directory and the action is LS_SerialPrint + if (DIR_IS_SUBDIR(&p) && lsAction == LS_SerialPrint) { // If the entry is a directory and the action is LS_SerialPrint // Get the short name for the item, which we know is a folder char lfilename[FILENAME_LENGTH]; createFilename(lfilename, p); @@ -103,21 +102,19 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m // Get a new directory object using the full path // and dive recursively into it. - if (lsAction == LS_SerialPrint_LFN) + if (lsParams->LFN) printf_P(PSTR("DIR_ENTER: %s \"%s\"\n"), path, longFilename[0] ? longFilename : lfilename); SdFile dir; if (!dir.open(parent, lfilename, O_READ)) { - if (lsAction == LS_SerialPrint || lsAction == LS_SerialPrint_LFN) { - //SERIAL_ECHO_START(); - //SERIAL_ECHOPGM(_i("Cannot open subdir"));////MSG_SD_CANT_OPEN_SUBDIR - //SERIAL_ECHOLN(lfilename); - } + //SERIAL_ECHO_START(); + //SERIAL_ECHOPGM(_i("Cannot open subdir"));////MSG_SD_CANT_OPEN_SUBDIR + //SERIAL_ECHOLN(lfilename); } - lsDive(path, dir); + lsDive(path, dir, NULL, lsAction, lsParams); // close() is done automatically by destructor of SdFile - if (lsAction == LS_SerialPrint_LFN) + if (lsParams->LFN) puts_P(PSTR("DIR_EXIT")); } else { @@ -128,7 +125,6 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m nrFiles++; break; - case LS_SerialPrint_LFN: case LS_SerialPrint: createFilename(filename, p); SERIAL_PROTOCOL(prepend); @@ -137,7 +133,18 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m MYSERIAL.write(' '); SERIAL_PROTOCOL(p.fileSize); - if (lsAction == LS_SerialPrint_LFN) + if (lsParams->timestamp) + { + crmodDate = p.lastWriteDate; + crmodTime = p.lastWriteTime; + if( crmodDate < p.creationDate || ( crmodDate == p.creationDate && crmodTime < p.creationTime ) ){ + crmodDate = p.creationDate; + crmodTime = p.creationTime; + } + printf_P(PSTR(" %#lx"), ((uint32_t)crmodDate << 16) | crmodTime); + } + + if (lsParams->LFN) printf_P(PSTR(" \"%s\""), LONGEST_FILENAME); SERIAL_PROTOCOLLN(); @@ -182,14 +189,10 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m } // while readDir } -void CardReader::ls(bool printLFN) +void CardReader::ls(struct ls_param params) { - lsAction = printLFN ? LS_SerialPrint_LFN : LS_SerialPrint; - //if(lsAction==LS_Count) - //nrFiles=0; - root.rewind(); - lsDive("",root); + lsDive("",root, NULL, LS_SerialPrint, ¶ms); } @@ -696,38 +699,34 @@ void CardReader::closefile(bool store_location) void CardReader::getfilename(uint16_t nr, const char * const match/*=NULL*/) { curDir=&workDir; - lsAction=LS_GetFilename; nrFiles=nr; curDir->rewind(); - lsDive("",*curDir,match); + lsDive("",*curDir,match, LS_GetFilename); } void CardReader::getfilename_simple(uint32_t position, const char * const match/*=NULL*/) { curDir = &workDir; - lsAction = LS_GetFilename; nrFiles = 0; curDir->seekSet(position); - lsDive("", *curDir, match); + lsDive("", *curDir, match, LS_GetFilename); } void CardReader::getfilename_next(uint32_t position, const char * const match/*=NULL*/) { curDir = &workDir; - lsAction = LS_GetFilename; nrFiles = 1; curDir->seekSet(position); - lsDive("", *curDir, match); + lsDive("", *curDir, match, LS_GetFilename); } uint16_t CardReader::getnrfilenames() { curDir=&workDir; - lsAction=LS_Count; nrFiles=0; curDir->rewind(); - lsDive("",*curDir); + lsDive("",*curDir, NULL, LS_Count); //SERIAL_ECHOLN(nrFiles); return nrFiles; } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 47343e23..7eba0f51 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -8,12 +8,23 @@ #define MAX_DIR_DEPTH 6 #include "SdFile.h" -enum LsAction {LS_SerialPrint,LS_SerialPrint_LFN,LS_Count,LS_GetFilename}; class CardReader { public: CardReader(); + enum LsAction : uint8_t + { + LS_SerialPrint, + LS_Count, + LS_GetFilename, + }; + struct ls_param + { + bool LFN : 1; + bool timestamp : 1; + } __attribute__((packed)); + void initsd(); void write_command(char *buf); void write_command_no_newline(char *buf); @@ -43,7 +54,7 @@ public: uint16_t getWorkDirDepth(); - void ls(bool printLFN); + void ls(struct ls_param params); bool chdir(const char * relpath, bool doPresort); void updir(); void setroot(bool doPresort); @@ -122,12 +133,11 @@ private: 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. int16_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; bool diveSubfolder (const char *&fileName); - void lsDive(const char *prepend, SdFile parent, const char * const match=NULL); + void lsDive(const char *prepend, SdFile parent, const char * const match=NULL, LsAction lsAction = LS_GetFilename, struct ls_param *lsParams = NULL); #ifdef SDCARD_SORT_ALPHA void flush_presort(); #endif From 7011014abb9d49bd270a6ea257c8209be7c64969 Mon Sep 17 00:00:00 2001 From: "D.R.racer" Date: Tue, 20 Apr 2021 06:50:37 +0200 Subject: [PATCH 4/7] Save 16 bytes - pass ls_param by value to functions ... as ls_param is a 1-byte structure it is more conservative to pass it to functions by value than by a pointer --- Firmware/Marlin_main.cpp | 6 ++---- Firmware/cardreader.cpp | 14 +++++++------- Firmware/cardreader.h | 6 ++++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index f46c6a53..6c8c423c 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5744,13 +5744,11 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) - `L` - Reports ling filenames instead of just short filenames. Requires host software parsing. */ case 20: - { KEEPALIVE_STATE(NOT_BUSY); // do not send busy messages during listing. Inhibits the output of manage_heater() SERIAL_PROTOCOLLNRPGM(_N("Begin file list"));////MSG_BEGIN_FILE_LIST - struct CardReader::ls_param params = {.LFN = code_seen('L'), .timestamp = code_seen('T')}; - card.ls(params); + card.ls(CardReader::ls_param(code_seen('L'), code_seen('T'))); SERIAL_PROTOCOLLNRPGM(_N("End file list"));////MSG_END_FILE_LIST - } break; + break; /*! ### M21 - Init SD card M21: Initialize SD card diff --git a/Firmware/cardreader.cpp b/Firmware/cardreader.cpp index 37c9ade9..a86c49e1 100644 --- a/Firmware/cardreader.cpp +++ b/Firmware/cardreader.cpp @@ -63,7 +63,7 @@ char *createFilename(char *buffer,const dir_t &p) //buffer>12characters +* LS_SerialPrint - Print the full path and size of each file to serial output +*/ -void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/, LsAction lsAction, struct ls_param *lsParams) { +void CardReader::lsDive(const char *prepend, SdFile parent, const char * const match/*=NULL*/, LsAction lsAction, ls_param lsParams) { static uint8_t recursionCnt = 0; // RAII incrementer for the recursionCnt class _incrementer @@ -102,7 +102,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m // Get a new directory object using the full path // and dive recursively into it. - if (lsParams->LFN) + if (lsParams.LFN) printf_P(PSTR("DIR_ENTER: %s \"%s\"\n"), path, longFilename[0] ? longFilename : lfilename); SdFile dir; @@ -114,7 +114,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m lsDive(path, dir, NULL, lsAction, lsParams); // close() is done automatically by destructor of SdFile - if (lsParams->LFN) + if (lsParams.LFN) puts_P(PSTR("DIR_EXIT")); } else { @@ -133,7 +133,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m MYSERIAL.write(' '); SERIAL_PROTOCOL(p.fileSize); - if (lsParams->timestamp) + if (lsParams.timestamp) { crmodDate = p.lastWriteDate; crmodTime = p.lastWriteTime; @@ -144,7 +144,7 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m printf_P(PSTR(" %#lx"), ((uint32_t)crmodDate << 16) | crmodTime); } - if (lsParams->LFN) + if (lsParams.LFN) printf_P(PSTR(" \"%s\""), LONGEST_FILENAME); SERIAL_PROTOCOLLN(); @@ -189,10 +189,10 @@ void CardReader::lsDive(const char *prepend, SdFile parent, const char * const m } // while readDir } -void CardReader::ls(struct ls_param params) +void CardReader::ls(ls_param params) { root.rewind(); - lsDive("",root, NULL, LS_SerialPrint, ¶ms); + lsDive("",root, NULL, LS_SerialPrint, params); } diff --git a/Firmware/cardreader.h b/Firmware/cardreader.h index 7eba0f51..c6e55428 100644 --- a/Firmware/cardreader.h +++ b/Firmware/cardreader.h @@ -23,6 +23,8 @@ public: { bool LFN : 1; bool timestamp : 1; + inline ls_param():LFN(0), timestamp(0) { } + inline ls_param(bool LFN, bool timestamp):LFN(LFN), timestamp(timestamp) { } } __attribute__((packed)); void initsd(); @@ -54,7 +56,7 @@ public: uint16_t getWorkDirDepth(); - void ls(struct ls_param params); + void ls(ls_param params); bool chdir(const char * relpath, bool doPresort); void updir(); void setroot(bool doPresort); @@ -137,7 +139,7 @@ private: char* diveDirName; bool diveSubfolder (const char *&fileName); - void lsDive(const char *prepend, SdFile parent, const char * const match=NULL, LsAction lsAction = LS_GetFilename, struct ls_param *lsParams = NULL); + void lsDive(const char *prepend, SdFile parent, const char * const match=NULL, LsAction lsAction = LS_GetFilename, ls_param lsParams = ls_param()); #ifdef SDCARD_SORT_ALPHA void flush_presort(); #endif From 1c0383c48f21235f1c707b59d8494ea053d9449a Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Apr 2021 09:03:22 +0300 Subject: [PATCH 5/7] Add capability report for extended M20 --- Firmware/Marlin_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 6c8c423c..ed855fdc 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3964,6 +3964,7 @@ static void extended_capabilities_report() // AUTOREPORT_POSITION (M114) cap_line(PSTR("AUTOREPORT_POSITION"), ENABLED(AUTO_REPORT)); //@todo Update RepRap cap + cap_line(PSTR("EXTENDED_M20"), 1); } #endif //EXTENDED_CAPABILITIES_REPORT From c4b70b82f35d27e85b2ee54e67fcce06f0a84dcb Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Apr 2021 09:13:38 +0300 Subject: [PATCH 6/7] Document M20 T parameter --- Firmware/Marlin_main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index ed855fdc..3f8154d8 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -5740,9 +5740,10 @@ if(eSoundMode!=e_SOUND_MODE_SILENT) ### M20 - SD Card file list M20: List SD card #### Usage - M20 [ L ] + M20 [ L | T ] #### Parameters - - `L` - Reports ling filenames instead of just short filenames. Requires host software parsing. + - `T` - Report timestamps as well. The value is one uint32_t encoded as hex. Requires host software parsing (Cap:EXTENDED_M20). + - `L` - Reports long filenames instead of just short filenames. Requires host software parsing (Cap:EXTENDED_M20). */ case 20: KEEPALIVE_STATE(NOT_BUSY); // do not send busy messages during listing. Inhibits the output of manage_heater() From 7d82cab1253653d3c33d8b1618454dd9f8349ab6 Mon Sep 17 00:00:00 2001 From: Alex Voinea Date: Tue, 20 Apr 2021 09:16:56 +0300 Subject: [PATCH 7/7] Update doxygen --- Firmware/Marlin_main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/Marlin_main.cpp b/Firmware/Marlin_main.cpp index 3f8154d8..f391159b 100755 --- a/Firmware/Marlin_main.cpp +++ b/Firmware/Marlin_main.cpp @@ -3963,8 +3963,9 @@ static void extended_capabilities_report() #endif //FANCHECK and TACH_0 or TACH_1 // AUTOREPORT_POSITION (M114) cap_line(PSTR("AUTOREPORT_POSITION"), ENABLED(AUTO_REPORT)); - //@todo Update RepRap cap + // EXTENDED_M20 (support for L and T parameters) cap_line(PSTR("EXTENDED_M20"), 1); + //@todo Update RepRap cap } #endif //EXTENDED_CAPABILITIES_REPORT