From a419933e77c69ccf1c730fba303dcb1250c1c705 Mon Sep 17 00:00:00 2001 From: Bjoern Kerler Date: Sun, 18 Feb 2024 19:08:50 +0100 Subject: [PATCH] Update gcode M20 to fit common marlin behaviour --- src/marlin_stubs/host/M115.cpp | 3 + src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp | 65 +++++++++++++++++++-- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/marlin_stubs/host/M115.cpp b/src/marlin_stubs/host/M115.cpp index dfade61623..7f3df434f0 100644 --- a/src/marlin_stubs/host/M115.cpp +++ b/src/marlin_stubs/host/M115.cpp @@ -214,5 +214,8 @@ void GcodeSuite::M115() { #endif ); + // PARSE FILES ON USB (M20) + cap_line(PSTR("EXTENDED_M20"), true); + #endif // EXTENDED_CAPABILITIES_REPORT } diff --git a/src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp b/src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp index 56b018f3f4..a0ecf87198 100644 --- a/src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp +++ b/src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp @@ -1,22 +1,77 @@ #include #include "../../lib/Marlin/Marlin/src/gcode/gcode.h" +#include "libs/hex_print_routines.h" #include "marlin_server.hpp" #include "media.h" #include "marlin_vars.hpp" -// M20 - List SD card -void GcodeSuite::M20() { - SERIAL_ECHOLNPGM(MSG_BEGIN_FILE_LIST); +static void print_file_size(const char *const filename) { + struct stat stat_buf; + int rc = stat(filename, &stat_buf); + if (rc == 0) { + SERIAL_ECHO(stat_buf.st_size); + } +} + +static void print_file_info(const char *const dirname, const char *const long_dirname, bool timestamps, bool long_filenames) { + SERIAL_ECHO(&dirname[5]); + SERIAL_CHAR(' '); + print_file_size(dirname); + if (timestamps) { + struct stat stat_buf; + int rc = stat(dirname, &stat_buf); + if (rc == 0) { + time_t t = stat_buf.st_mtim.tv_sec; + struct tm lt; + localtime_r(&t, <); + uint16_t m20_date = (lt.tm_year + 1900 - 1980) << 9 | (lt.tm_mon + 1) << 5 | lt.tm_mday; + uint16_t m20_time = lt.tm_hour << 11 | lt.tm_min << 5; + m20_time |= int((lt.tm_sec - (lt.tm_sec % 2)) / 2); + SERIAL_ECHOPGM(" 0x"); + print_hex_word(m20_date); + print_hex_word(m20_time); + } + } + if (long_filenames) { + SERIAL_CHAR(' '); + SERIAL_CHAR('"'); + SERIAL_ECHO(&long_dirname[5]); + SERIAL_CHAR('"'); + } + SERIAL_EOL(); +} + +static void print_listing(const char *const prepend, const char *const prepend_long, bool timestamps, bool long_filenames) { DIR *dir; - dir = opendir("/usb/"); + dir = opendir(prepend); if (dir != NULL) { struct dirent *entry; while ((entry = readdir(dir)) != NULL && entry->d_name[0]) { - SERIAL_ECHOLN(entry->d_name); + char dirname[5 + 512]; + char long_dirname[5 + 512]; + snprintf(dirname, sizeof(dirname), "%s/%s", prepend, entry->d_name); + snprintf(long_dirname, sizeof(long_dirname), "%s/%s", prepend_long, entry->lfn); + if (entry->d_type != DT_DIR) { + print_file_info(dirname, long_dirname, timestamps, long_filenames); + } } closedir(dir); } +} + +// M20 - List SD card +void GcodeSuite::M20() { + bool longfilenames = false; + bool timestamps = false; + if (parser.seen('L')) { + longfilenames = true; + } + if (parser.seen('T')) { + timestamps = true; + } + SERIAL_ECHOLNPGM(MSG_BEGIN_FILE_LIST); + print_listing("/usb", "/usb", timestamps, longfilenames); SERIAL_ECHOLNPGM(MSG_END_FILE_LIST); }