浏览代码

✨ 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
 
1578
 
1579
   //#define LONG_FILENAME_HOST_SUPPORT    // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
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
   //#define LONG_FILENAME_WRITE_SUPPORT   // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
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
   //#define SCROLL_LONG_FILENAMES         // Scroll long filenames in the SD card menu
1583
   //#define SCROLL_LONG_FILENAMES         // Scroll long filenames in the SD card menu
1583
 
1584
 

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

28
 #include "../../sd/cardreader.h"
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
 void GcodeSuite::M20() {
42
 void GcodeSuite::M20() {
34
   if (card.flag.mounted) {
43
   if (card.flag.mounted) {
35
     SERIAL_ECHOLNPGM(STR_BEGIN_FILE_LIST);
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
     SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
48
     SERIAL_ECHOLNPGM(STR_END_FILE_LIST);
44
   }
49
   }
45
   else
50
   else

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

1003
 #endif
1003
 #endif
1004
 
1004
 
1005
 // Flag whether hex_print.cpp is used
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
   #define NEED_HEX_PRINT 1
1007
   #define NEED_HEX_PRINT 1
1008
 #endif
1008
 #endif
1009
 
1009
 

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

29
 #include "cardreader.h"
29
 #include "cardreader.h"
30
 
30
 
31
 #include "../MarlinCore.h"
31
 #include "../MarlinCore.h"
32
+#include "../libs/hex_print.h"
32
 #include "../lcd/marlinui.h"
33
 #include "../lcd/marlinui.h"
33
 
34
 
34
 #if ENABLED(DWIN_CREALITY_LCD)
35
 #if ENABLED(DWIN_CREALITY_LCD)
197
 //
198
 //
198
 // Return 'true' if the item is a folder, G-code file or Binary file
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
   //uint8_t pn0 = p.name[0];
202
   //uint8_t pn0 = p.name[0];
202
 
203
 
203
   #if DISABLED(CUSTOM_FIRMWARE_UPLOAD)
204
   #if DISABLED(CUSTOM_FIRMWARE_UPLOAD)
279
  * this can blow up the stack, so a 'depth' parameter would be a
280
  * this can blow up the stack, so a 'depth' parameter would be a
280
  * good addition.
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
   OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong/*=nullptr*/)
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
   dir_t p;
294
   dir_t p;
289
   while (parent.readDir(&p, longFilename) > 0) {
295
   while (parent.readDir(&p, longFilename) > 0) {
290
     if (DIR_IS_SUBDIR(&p)) {
296
     if (DIR_IS_SUBDIR(&p)) {
301
       SdFile child; // child.close() in destructor
307
       SdFile child; // child.close() in destructor
302
       if (child.open(&parent, dosFilename, O_READ)) {
308
       if (child.open(&parent, dosFilename, O_READ)) {
303
         #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
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
             // Allocate enough stack space for the full long path including / separator
312
             // Allocate enough stack space for the full long path including / separator
307
             char pathLong[lenPrependLong + strlen(longFilename) + 1];
313
             char pathLong[lenPrependLong + strlen(longFilename) + 1];
308
             if (prependLong) { strcpy(pathLong, prependLong); pathLong[lenPrependLong - 1] = '/'; }
314
             if (prependLong) { strcpy(pathLong, prependLong); pathLong[lenPrependLong - 1] = '/'; }
309
             strcpy(pathLong + lenPrependLong, longFilename);
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
         #endif
319
         #endif
320
+        printListing(child, path, lsflags);
317
       }
321
       }
318
       else {
322
       else {
319
         SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
323
         SERIAL_ECHO_MSG(STR_SD_CANT_OPEN_SUBDIR, dosFilename);
325
       SERIAL_ECHO(createFilename(filename, p));
329
       SERIAL_ECHO(createFilename(filename, p));
326
       SERIAL_CHAR(' ');
330
       SERIAL_CHAR(' ');
327
       SERIAL_ECHO(p.fileSize);
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
       #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
342
       #if ENABLED(LONG_FILENAME_HOST_SUPPORT)
329
-        if (includeLongNames) {
343
+        if (includeLong) {
330
           SERIAL_CHAR(' ');
344
           SERIAL_CHAR(' ');
331
           if (prependLong) { SERIAL_ECHO(prependLong); SERIAL_CHAR('/'); }
345
           if (prependLong) { SERIAL_ECHO(prependLong); SERIAL_CHAR('/'); }
332
           SERIAL_ECHO(longFilename[0] ? longFilename : filename);
346
           SERIAL_ECHO(longFilename[0] ? longFilename : filename);
340
 //
354
 //
341
 // List all files on the SD card
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
   if (flag.mounted) {
358
   if (flag.mounted) {
351
     root.rewind();
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
     ;
89
     ;
90
 } card_flags_t;
90
 } card_flags_t;
91
 
91
 
92
+enum ListingFlags : uint8_t { LS_LONG_FILENAME, LS_ONLY_BIN, LS_TIMESTAMP };
93
+
92
 #if ENABLED(AUTO_REPORT_SD_STATUS)
94
 #if ENABLED(AUTO_REPORT_SD_STATUS)
93
   #include "../libs/autoreport.h"
95
   #include "../libs/autoreport.h"
94
 #endif
96
 #endif
207
     FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
209
     FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
208
   #endif
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
   #if ENABLED(POWER_LOSS_RECOVERY)
214
   #if ENABLED(POWER_LOSS_RECOVERY)
219
     static bool jobRecoverFileExists();
215
     static bool jobRecoverFileExists();
348
   static int countItems(SdFile dir);
344
   static int countItems(SdFile dir);
349
   static void selectByIndex(SdFile dir, const uint8_t index);
345
   static void selectByIndex(SdFile dir, const uint8_t index);
350
   static void selectByName(SdFile dir, const char * const match);
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
     OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr)
348
     OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr)
356
   );
349
   );
357
 
350
 

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

22
            EEPROM_SETTINGS NOZZLE_PARK_FEATURE SDSUPPORT SD_CHECK_AND_RETRY \
22
            EEPROM_SETTINGS NOZZLE_PARK_FEATURE SDSUPPORT SD_CHECK_AND_RETRY \
23
            REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER Z_STEPPER_AUTO_ALIGN ADAPTIVE_STEP_SMOOTHING \
23
            REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER Z_STEPPER_AUTO_ALIGN ADAPTIVE_STEP_SMOOTHING \
24
            STATUS_MESSAGE_SCROLLING LCD_SET_PROGRESS_MANUALLY SHOW_REMAINING_TIME USE_M73_REMAINING_TIME \
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
            MOVE_Z_WHEN_IDLE BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \
27
            MOVE_Z_WHEN_IDLE BABYSTEP_ZPROBE_OFFSET BABYSTEP_ZPROBE_GFX_OVERLAY \
27
            LIN_ADVANCE ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE MONITOR_DRIVER_STATUS SENSORLESS_HOMING \
28
            LIN_ADVANCE ADVANCED_PAUSE_FEATURE PARK_HEAD_ON_PAUSE MONITOR_DRIVER_STATUS SENSORLESS_HOMING \
28
            SQUARE_WAVE_STEPPING TMC_DEBUG EXPERIMENTAL_SCURVE
29
            SQUARE_WAVE_STEPPING TMC_DEBUG EXPERIMENTAL_SCURVE

正在加载...
取消
保存