From e24d5f931518fd6644d5d50dcce908e903550963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Mi=C5=9Bkiewicz?= Date: Fri, 26 Aug 2022 00:14:54 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20M20=5FTIMESTAMP=5FSUPPORT=20(#24679?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Scott Lahteine --- Marlin/Configuration_adv.h | 1 + Marlin/src/gcode/sd/M20.cpp | 21 ++++++----- Marlin/src/inc/Conditionals_adv.h | 2 +- Marlin/src/sd/cardreader.cpp | 50 +++++++++++++++----------- Marlin/src/sd/cardreader.h | 15 +++----- buildroot/tests/SAMD51_grandcentral_m4 | 3 +- 6 files changed, 50 insertions(+), 42 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index b83da5441b..68cf81627f 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1578,6 +1578,7 @@ //#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 ' and list long filenames with 'M20 L' //#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol + //#define M20_TIMESTAMP_SUPPORT // Include timestamps by adding the 'T' flag to M20 commands //#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu diff --git a/Marlin/src/gcode/sd/M20.cpp b/Marlin/src/gcode/sd/M20.cpp index c640309be8..2a7e0d08df 100644 --- a/Marlin/src/gcode/sd/M20.cpp +++ b/Marlin/src/gcode/sd/M20.cpp @@ -28,18 +28,23 @@ #include "../../sd/cardreader.h" /** - * M20: List SD card to serial output + * M20: List SD card to serial output in [name] [size] format. + * + * With CUSTOM_FIRMWARE_UPLOAD: + * F - List BIN files only, for use with firmware upload + * + * With LONG_FILENAME_HOST_SUPPORT: + * L - List long filenames (instead of DOS8.3 names) + * + * With M20_TIMESTAMP_SUPPORT: + * T - Include timestamps */ void GcodeSuite::M20() { if (card.flag.mounted) { SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST); - card.ls( - TERN_(CUSTOM_FIRMWARE_UPLOAD, parser.boolval('F')) - #if BOTH(CUSTOM_FIRMWARE_UPLOAD, LONG_FILENAME_HOST_SUPPORT) - , - #endif - TERN_(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L')) - ); + card.ls(TERN0(CUSTOM_FIRMWARE_UPLOAD, parser.boolval('F') << LS_ONLY_BIN) + | TERN0(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L') << LS_LONG_FILENAME) + | TERN0(M20_TIMESTAMP_SUPPORT, parser.boolval('T') << LS_TIMESTAMP)); SERIAL_ECHOLNPGM(STR_END_FILE_LIST); } else diff --git a/Marlin/src/inc/Conditionals_adv.h b/Marlin/src/inc/Conditionals_adv.h index 0d79d710bc..49b6652587 100644 --- a/Marlin/src/inc/Conditionals_adv.h +++ b/Marlin/src/inc/Conditionals_adv.h @@ -1003,7 +1003,7 @@ #endif // Flag whether hex_print.cpp is used -#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER) +#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT) #define NEED_HEX_PRINT 1 #endif diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp index 3fff796539..3057bf68af 100644 --- a/Marlin/src/sd/cardreader.cpp +++ b/Marlin/src/sd/cardreader.cpp @@ -29,6 +29,7 @@ #include "cardreader.h" #include "../MarlinCore.h" +#include "../libs/hex_print.h" #include "../lcd/marlinui.h" #if ENABLED(DWIN_CREALITY_LCD) @@ -197,7 +198,7 @@ char *createFilename(char * const buffer, const dir_t &p) { // // Return 'true' if the item is a folder, G-code file or Binary file // -bool CardReader::is_visible_entity(const dir_t &p OPTARG(CUSTOM_FIRMWARE_UPLOAD, bool onlyBin/*=false*/)) { +bool CardReader::is_visible_entity(const dir_t &p OPTARG(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin/*=false*/)) { //uint8_t pn0 = p.name[0]; #if DISABLED(CUSTOM_FIRMWARE_UPLOAD) @@ -279,12 +280,17 @@ void CardReader::selectByName(SdFile dir, const char * const match) { * this can blow up the stack, so a 'depth' parameter would be a * good addition. */ -void CardReader::printListing( - SdFile parent, const char * const prepend - OPTARG(CUSTOM_FIRMWARE_UPLOAD, bool onlyBin/*=false*/) - OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/) +void CardReader::printListing(SdFile parent, const char * const prepend, const uint8_t lsflags OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong/*=nullptr*/) ) { + const bool includeTime = TERN0(M20_TIMESTAMP_SUPPORT, TEST(lsflags, LS_TIMESTAMP)); + #if ENABLED(LONG_FILENAME_HOST_SUPPORT) + const bool includeLong = TEST(lsflags, LS_LONG_FILENAME); + #endif + #if ENABLED(CUSTOM_FIRMWARE_UPLOAD) + const bool onlyBin = TEST(lsflags, LS_ONLY_BIN); + #endif + UNUSED(lsflags); dir_t p; while (parent.readDir(&p, longFilename) > 0) { if (DIR_IS_SUBDIR(&p)) { @@ -301,19 +307,17 @@ void CardReader::printListing( SdFile child; // child.close() in destructor if (child.open(&parent, dosFilename, O_READ)) { #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - if (includeLongNames) { - size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0; + if (includeLong) { + const size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0; // Allocate enough stack space for the full long path including / separator char pathLong[lenPrependLong + strlen(longFilename) + 1]; if (prependLong) { strcpy(pathLong, prependLong); pathLong[lenPrependLong - 1] = '/'; } strcpy(pathLong + lenPrependLong, longFilename); - printListing(child, path OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin), true, pathLong); + printListing(child, path, lsflags, pathLong); + continue; } - else - printListing(child, path OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin)); - #else - printListing(child, path OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin)); #endif + printListing(child, path, lsflags); } else { SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename); @@ -325,8 +329,18 @@ void CardReader::printListing( SERIAL_ECHO(createFilename(filename, p)); SERIAL_CHAR(' '); SERIAL_ECHO(p.fileSize); + if (includeTime) { + SERIAL_CHAR(' '); + uint16_t crmodDate = p.lastWriteDate, crmodTime = p.lastWriteTime; + if (crmodDate < p.creationDate || (crmodDate == p.creationDate && crmodTime < p.creationTime)) { + crmodDate = p.creationDate; + crmodTime = p.creationTime; + } + SERIAL_ECHOPGM("0x", hex_word(crmodDate)); + print_hex_word(crmodTime); + } #if ENABLED(LONG_FILENAME_HOST_SUPPORT) - if (includeLongNames) { + if (includeLong) { SERIAL_CHAR(' '); if (prependLong) { SERIAL_ECHO(prependLong); SERIAL_CHAR('/'); } SERIAL_ECHO(longFilename[0] ? longFilename : filename); @@ -340,16 +354,10 @@ void CardReader::printListing( // // List all files on the SD card // -void CardReader::ls( - TERN_(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin/*=false*/) - #if BOTH(CUSTOM_FIRMWARE_UPLOAD, LONG_FILENAME_HOST_SUPPORT) - , - #endif - TERN_(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/) -) { +void CardReader::ls(const uint8_t lsflags) { if (flag.mounted) { root.rewind(); - printListing(root, nullptr OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin) OPTARG(LONG_FILENAME_HOST_SUPPORT, includeLongNames)); + printListing(root, nullptr, lsflags); } } diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h index d2f462c2a7..6fe75f760e 100644 --- a/Marlin/src/sd/cardreader.h +++ b/Marlin/src/sd/cardreader.h @@ -89,6 +89,8 @@ typedef struct { ; } card_flags_t; +enum ListingFlags : uint8_t { LS_LONG_FILENAME, LS_ONLY_BIN, LS_TIMESTAMP }; + #if ENABLED(AUTO_REPORT_SD_STATUS) #include "../libs/autoreport.h" #endif @@ -207,13 +209,7 @@ public: FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); } #endif - static void ls( - TERN_(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin=false) - #if BOTH(CUSTOM_FIRMWARE_UPLOAD, LONG_FILENAME_HOST_SUPPORT) - , - #endif - TERN_(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false) - ); + static void ls(const uint8_t lsflags); #if ENABLED(POWER_LOSS_RECOVERY) static bool jobRecoverFileExists(); @@ -348,10 +344,7 @@ private: static int countItems(SdFile dir); static void selectByIndex(SdFile dir, const uint8_t index); static void selectByName(SdFile dir, const char * const match); - static void printListing( - SdFile parent, const char * const prepend - OPTARG(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin=false) - OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false) + static void printListing(SdFile parent, const char * const prepend, const uint8_t lsflags OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr) ); diff --git a/buildroot/tests/SAMD51_grandcentral_m4 b/buildroot/tests/SAMD51_grandcentral_m4 index e6e27d8cb8..c8e08c19e6 100755 --- a/buildroot/tests/SAMD51_grandcentral_m4 +++ b/buildroot/tests/SAMD51_grandcentral_m4 @@ -22,7 +22,8 @@ opt_enable ENDSTOP_INTERRUPTS_FEATURE S_CURVE_ACCELERATION BLTOUCH Z_MIN_PROBE_R EEPROM_SETTINGS NOZZLE_PARK_FEATURE SDSUPPORT SD_CHECK_AND_RETRY \ REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER Z_STEPPER_AUTO_ALIGN ADAPTIVE_STEP_SMOOTHING \ STATUS_MESSAGE_SCROLLING LCD_SET_PROGRESS_MANUALLY SHOW_REMAINING_TIME USE_M73_REMAINING_TIME \ - LONG_FILENAME_HOST_SUPPORT SCROLL_LONG_FILENAMES BABYSTEPPING DOUBLECLICK_FOR_Z_BABYSTEPPING \ + LONG_FILENAME_HOST_SUPPORT CUSTOM_FIRMWARE_UPLOAD M20_TIMESTAMP_SUPPORT \ + SCROLL_LONG_FILENAMES BABYSTEPPING DOUBLECLICK_FOR_Z_BABYSTEPPING \ MOVE_Z_WHEN_IDLE BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \ LIN_ADVANCE ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE MONITOR_DRIVER_STATUS SENSORLESS_HOMING \ SQUARE_WAVE_STEPPING TMC_DEBUG EXPERIMENTAL_SCURVE