From 1997bd46598a969b3b777909f2e407f1964abe58 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 | 77 ++++++++++++++++++--- 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/marlin_stubs/host/M115.cpp b/src/marlin_stubs/host/M115.cpp index fcb4309146..5930baa982 100644 --- a/src/marlin_stubs/host/M115.cpp +++ b/src/marlin_stubs/host/M115.cpp @@ -218,6 +218,9 @@ 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 5741c06022..e99e3c3037 100644 --- a/src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp +++ b/src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp @@ -4,9 +4,69 @@ #include #include "../../lib/Marlin/Marlin/src/gcode/gcode.h" +#include "libs/hex_print_routines.h" #include "marlin_server.hpp" #include "media.hpp" #include "marlin_vars.hpp" +#include "str_utils.hpp" + +struct TimeFlags { + bool print_lfn : 1; + bool print_timestamps : 1; +}; + +static void time_to_m20(const struct stat stat_buf, uint16_t *m20_date, uint16_t *m20_time) { + time_t t = stat_buf.st_mtim.tv_sec; + struct tm lt; + localtime_r(&t, <); + *m20_date = (lt.tm_year + 1900 - 1980) << 9 | (lt.tm_mon + 1) << 5 | lt.tm_mday; + *m20_time = lt.tm_hour << 11 | lt.tm_min << 5; + *m20_time |= int((lt.tm_sec - (lt.tm_sec % 2)) / 2); +} + +static void print_file_info(const char *const prefix, const char *const path, const char *const long_path, const struct TimeFlags tf) { + // we skip the /usb/ prefix on print as it is only used internally + SERIAL_ECHO(&path[strlen_constexpr(prefix) + 1]); + SERIAL_CHAR(' '); + struct stat stat_buf; + int rc = stat(path, &stat_buf); + if (rc == 0) { + SERIAL_ECHO(stat_buf.st_size); + if (tf.print_timestamps) { + uint16_t m20_date; + uint16_t m20_time; + time_to_m20(stat_buf, &m20_date, &m20_time); + SERIAL_ECHOPGM(" 0x"); + print_hex_word(m20_date); + print_hex_word(m20_time); + } + if (tf.print_lfn) { + SERIAL_CHAR(' '); + SERIAL_CHAR('"'); + SERIAL_ECHO(&long_path[strlen_constexpr(prefix) + 1]); + SERIAL_CHAR('"'); + } + } + SERIAL_EOL(); +} + +static void print_listing(const char *const prefix, const char *const prefix_long, const struct TimeFlags tf) { + DIR *dir; + dir = opendir(prefix); + if (dir != NULL) { + struct dirent *entry; + while ((entry = readdir(dir)) != NULL && entry->d_name[0]) { + char path[strlen_constexpr(prefix) + 1 + strlen_constexpr(entry->d_name) + 1]; + snprintf(path, sizeof(path), "%s/%s", prefix, entry->d_name); + char long_path[strlen_constexpr(prefix_long) + 1 + strlen_constexpr(entry->lfn) + 1]; + snprintf(long_path, sizeof(long_path), "%s/%s", prefix_long, entry->lfn); + if (entry->d_type != DT_DIR) { + print_file_info(prefix, path, long_path, tf); + } + } + closedir(dir); + } +} /** \addtogroup G-Codes * @{ @@ -16,16 +76,15 @@ * M20 - List SD card on serial port */ void GcodeSuite::M20() { - SERIAL_ECHOLNPGM(MSG_BEGIN_FILE_LIST); - DIR *dir; - dir = opendir("/usb/"); - if (dir != NULL) { - struct dirent *entry; - while ((entry = readdir(dir)) != NULL && entry->d_name[0]) { - SERIAL_ECHOLN(entry->d_name); - } - closedir(dir); + TimeFlags tf; + if (parser.seen('L')) { + tf.print_lfn = 1; + } + if (parser.seen('T')) { + tf.print_timestamps = 1; } + SERIAL_ECHOLNPGM(MSG_BEGIN_FILE_LIST); + print_listing("/usb", "/usb", tf); SERIAL_ECHOLNPGM(MSG_END_FILE_LIST); }