浏览代码

✨ M20_TIMESTAMP_SUPPORT (#24679)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
Arkadiusz Miśkiewicz 2 年前
父节点
当前提交
82d1851743
没有帐户链接到提交者的电子邮件

+ 1
- 0
Marlin/Configuration_adv.h 查看文件

@@ -1578,6 +1578,7 @@
1578 1578
 
1579 1579
   //#define LONG_FILENAME_HOST_SUPPORT    // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
1580 1580
   //#define LONG_FILENAME_WRITE_SUPPORT   // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
1581
+  //#define M20_TIMESTAMP_SUPPORT         // Include timestamps by adding the 'T' flag to M20 commands
1581 1582
 
1582 1583
   //#define SCROLL_LONG_FILENAMES         // Scroll long filenames in the SD card menu
1583 1584
 

+ 13
- 8
Marlin/src/gcode/sd/M20.cpp 查看文件

@@ -28,18 +28,23 @@
28 28
 #include "../../sd/cardreader.h"
29 29
 
30 30
 /**
31
- * M20: List SD card to serial output
31
+ * M20: List SD card to serial output in [name] [size] format.
32
+ *
33
+ * With CUSTOM_FIRMWARE_UPLOAD:
34
+ *   F<bool> - List BIN files only, for use with firmware upload
35
+ *
36
+ * With LONG_FILENAME_HOST_SUPPORT:
37
+ *   L<bool> - List long filenames (instead of DOS8.3 names)
38
+ *
39
+ * With M20_TIMESTAMP_SUPPORT:
40
+ *   T<bool> - Include timestamps
32 41
  */
33 42
 void GcodeSuite::M20() {
34 43
   if (card.flag.mounted) {
35 44
     SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
36
-    card.ls(
37
-      TERN_(CUSTOM_FIRMWARE_UPLOAD, parser.boolval('F'))
38
-      #if BOTH(CUSTOM_FIRMWARE_UPLOAD, LONG_FILENAME_HOST_SUPPORT)
39
-        ,
40
-      #endif
41
-      TERN_(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L'))
42
-    );
45
+    card.ls(TERN0(CUSTOM_FIRMWARE_UPLOAD,     parser.boolval('F') << LS_ONLY_BIN)
46
+          | TERN0(LONG_FILENAME_HOST_SUPPORT, parser.boolval('L') << LS_LONG_FILENAME)
47
+          | TERN0(M20_TIMESTAMP_SUPPORT,      parser.boolval('T') << LS_TIMESTAMP));
43 48
     SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
44 49
   }
45 50
   else

+ 1
- 1
Marlin/src/inc/Conditionals_adv.h 查看文件

@@ -1003,7 +1003,7 @@
1003 1003
 #endif
1004 1004
 
1005 1005
 // Flag whether hex_print.cpp is used
1006
-#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER)
1006
+#if ANY(AUTO_BED_LEVELING_UBL, M100_FREE_MEMORY_WATCHER, DEBUG_GCODE_PARSER, TMC_DEBUG, MARLIN_DEV_MODE, DEBUG_CARDREADER, M20_TIMESTAMP_SUPPORT)
1007 1007
   #define NEED_HEX_PRINT 1
1008 1008
 #endif
1009 1009
 

+ 29
- 21
Marlin/src/sd/cardreader.cpp 查看文件

@@ -29,6 +29,7 @@
29 29
 #include "cardreader.h"
30 30
 
31 31
 #include "../MarlinCore.h"
32
+#include "../libs/hex_print.h"
32 33
 #include "../lcd/marlinui.h"
33 34
 
34 35
 #if ENABLED(DWIN_CREALITY_LCD)
@@ -197,7 +198,7 @@ char *createFilename(char * const buffer, const dir_t &p) {
197 198
 //
198 199
 // Return 'true' if the item is a folder, G-code file or Binary file
199 200
 //
200
-bool CardReader::is_visible_entity(const dir_t &p OPTARG(CUSTOM_FIRMWARE_UPLOAD, bool onlyBin/*=false*/)) {
201
+bool CardReader::is_visible_entity(const dir_t &p OPTARG(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin/*=false*/)) {
201 202
   //uint8_t pn0 = p.name[0];
202 203
 
203 204
   #if DISABLED(CUSTOM_FIRMWARE_UPLOAD)
@@ -279,12 +280,17 @@ void CardReader::selectByName(SdFile dir, const char * const match) {
279 280
  * this can blow up the stack, so a 'depth' parameter would be a
280 281
  * good addition.
281 282
  */
282
-void CardReader::printListing(
283
-  SdFile parent, const char * const prepend
284
-  OPTARG(CUSTOM_FIRMWARE_UPLOAD, bool onlyBin/*=false*/)
285
-  OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/)
283
+void CardReader::printListing(SdFile parent,  const char * const prepend, const uint8_t lsflags
286 284
   OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong/*=nullptr*/)
287 285
 ) {
286
+  const bool includeTime = TERN0(M20_TIMESTAMP_SUPPORT, TEST(lsflags, LS_TIMESTAMP));
287
+  #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
288
+    const bool includeLong = TEST(lsflags, LS_LONG_FILENAME);
289
+  #endif
290
+  #if ENABLED(CUSTOM_FIRMWARE_UPLOAD)
291
+    const bool onlyBin = TEST(lsflags, LS_ONLY_BIN);
292
+  #endif
293
+  UNUSED(lsflags);
288 294
   dir_t p;
289 295
   while (parent.readDir(&p, longFilename) > 0) {
290 296
     if (DIR_IS_SUBDIR(&p)) {
@@ -301,19 +307,17 @@ void CardReader::printListing(
301 307
       SdFile child; // child.close() in destructor
302 308
       if (child.open(&parent, dosFilename, O_READ)) {
303 309
         #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
304
-          if (includeLongNames) {
305
-            size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0;
310
+          if (includeLong) {
311
+            const size_t lenPrependLong = prependLong ? strlen(prependLong) + 1 : 0;
306 312
             // Allocate enough stack space for the full long path including / separator
307 313
             char pathLong[lenPrependLong + strlen(longFilename) + 1];
308 314
             if (prependLong) { strcpy(pathLong, prependLong); pathLong[lenPrependLong - 1] = '/'; }
309 315
             strcpy(pathLong + lenPrependLong, longFilename);
310
-            printListing(child, path OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin), true, pathLong);
316
+            printListing(child, path, lsflags, pathLong);
317
+            continue;
311 318
           }
312
-          else
313
-            printListing(child, path OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin));
314
-        #else
315
-          printListing(child, path OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin));
316 319
         #endif
320
+        printListing(child, path, lsflags);
317 321
       }
318 322
       else {
319 323
         SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
@@ -325,8 +329,18 @@ void CardReader::printListing(
325 329
       SERIAL_ECHO(createFilename(filename, p));
326 330
       SERIAL_CHAR(' ');
327 331
       SERIAL_ECHO(p.fileSize);
332
+      if (includeTime) {
333
+    		SERIAL_CHAR(' ');
334
+    		uint16_t crmodDate = p.lastWriteDate, crmodTime = p.lastWriteTime;
335
+    		if (crmodDate < p.creationDate || (crmodDate == p.creationDate && crmodTime < p.creationTime)) {
336
+    			crmodDate = p.creationDate;
337
+    			crmodTime = p.creationTime;
338
+    		}
339
+    		SERIAL_ECHOPGM("0x", hex_word(crmodDate));
340
+    		print_hex_word(crmodTime);
341
+    	}
328 342
       #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
329
-        if (includeLongNames) {
343
+        if (includeLong) {
330 344
           SERIAL_CHAR(' ');
331 345
           if (prependLong) { SERIAL_ECHO(prependLong); SERIAL_CHAR('/'); }
332 346
           SERIAL_ECHO(longFilename[0] ? longFilename : filename);
@@ -340,16 +354,10 @@ void CardReader::printListing(
340 354
 //
341 355
 // List all files on the SD card
342 356
 //
343
-void CardReader::ls(
344
-  TERN_(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin/*=false*/)
345
-  #if BOTH(CUSTOM_FIRMWARE_UPLOAD, LONG_FILENAME_HOST_SUPPORT)
346
-    ,
347
-  #endif
348
-  TERN_(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames/*=false*/)
349
-) {
357
+void CardReader::ls(const uint8_t lsflags) {
350 358
   if (flag.mounted) {
351 359
     root.rewind();
352
-    printListing(root, nullptr OPTARG(CUSTOM_FIRMWARE_UPLOAD, onlyBin) OPTARG(LONG_FILENAME_HOST_SUPPORT, includeLongNames));
360
+    printListing(root, nullptr, lsflags);
353 361
   }
354 362
 }
355 363
 

+ 4
- 11
Marlin/src/sd/cardreader.h 查看文件

@@ -89,6 +89,8 @@ typedef struct {
89 89
     ;
90 90
 } card_flags_t;
91 91
 
92
+enum ListingFlags : uint8_t { LS_LONG_FILENAME, LS_ONLY_BIN, LS_TIMESTAMP };
93
+
92 94
 #if ENABLED(AUTO_REPORT_SD_STATUS)
93 95
   #include "../libs/autoreport.h"
94 96
 #endif
@@ -207,13 +209,7 @@ public:
207 209
     FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
208 210
   #endif
209 211
 
210
-  static void ls(
211
-    TERN_(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin=false)
212
-    #if BOTH(CUSTOM_FIRMWARE_UPLOAD, LONG_FILENAME_HOST_SUPPORT)
213
-      ,
214
-    #endif
215
-    TERN_(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false)
216
-  );
212
+  static void ls(const uint8_t lsflags);
217 213
 
218 214
   #if ENABLED(POWER_LOSS_RECOVERY)
219 215
     static bool jobRecoverFileExists();
@@ -348,10 +344,7 @@ private:
348 344
   static int countItems(SdFile dir);
349 345
   static void selectByIndex(SdFile dir, const uint8_t index);
350 346
   static void selectByName(SdFile dir, const char * const match);
351
-  static void printListing(
352
-    SdFile parent, const char * const prepend
353
-    OPTARG(CUSTOM_FIRMWARE_UPLOAD, const bool onlyBin=false)
354
-    OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false)
347
+  static void printListing(SdFile parent, const char * const prepend, const uint8_t lsflags
355 348
     OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr)
356 349
   );
357 350
 

+ 2
- 1
buildroot/tests/SAMD51_grandcentral_m4 查看文件

@@ -22,7 +22,8 @@ opt_enable ENDSTOP_INTERRUPTS_FEATURE S_CURVE_ACCELERATION BLTOUCH Z_MIN_PROBE_R
22 22
            EEPROM_SETTINGS NOZZLE_PARK_FEATURE SDSUPPORT SD_CHECK_AND_RETRY \
23 23
            REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER Z_STEPPER_AUTO_ALIGN ADAPTIVE_STEP_SMOOTHING \
24 24
            STATUS_MESSAGE_SCROLLING LCD_SET_PROGRESS_MANUALLY SHOW_REMAINING_TIME USE_M73_REMAINING_TIME \
25
-           LONG_FILENAME_HOST_SUPPORT SCROLL_LONG_FILENAMES BABYSTEPPING DOUBLECLICK_FOR_Z_BABYSTEPPING \
25
+           LONG_FILENAME_HOST_SUPPORT CUSTOM_FIRMWARE_UPLOAD M20_TIMESTAMP_SUPPORT \
26
+           SCROLL_LONG_FILENAMES BABYSTEPPING DOUBLECLICK_FOR_Z_BABYSTEPPING \
26 27
            MOVE_Z_WHEN_IDLE BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \
27 28
            LIN_ADVANCE ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE MONITOR_DRIVER_STATUS SENSORLESS_HOMING \
28 29
            SQUARE_WAVE_STEPPING TMC_DEBUG EXPERIMENTAL_SCURVE

正在加载...
取消
保存