Skip to content

Commit

Permalink
Update gcode M20 to fit common marlin behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
bkerler committed Feb 20, 2024
1 parent b3ee47a commit e38da17
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/marlin_stubs/host/M115.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,8 @@ void GcodeSuite::M115() {
#endif
);

// PARSE FILES ON USB (M20)
cap_line(PSTR("EXTENDED_M20"), true);

#endif // EXTENDED_CAPABILITIES_REPORT
}
68 changes: 63 additions & 5 deletions src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,80 @@
#include <dirent.h>

#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);
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, &lt);
*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 path, const char *const long_path, const struct TimeFlags tf) {
// &path[5] and &long_path[5], because we skip the /usb/ prefix on print as it is only used internally
SERIAL_ECHO(&path[5]);
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[5]);
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("/usb/");
dir = opendir(prefix);
if (dir != NULL) {
struct dirent *entry;
while ((entry = readdir(dir)) != NULL && entry->d_name[0]) {
SERIAL_ECHOLN(entry->d_name);
char path[5 + sizeof(entry->d_name) * 2];
snprintf(path, sizeof(path), "%s/%s", prefix, entry->d_name);
char long_path[5 + sizeof(entry->lfn) * 2];
snprintf(long_path, sizeof(long_path), "%s/%s", prefix_long, entry->lfn);
if (entry->d_type != DT_DIR) {
print_file_info(path, long_path, tf);
}
}
closedir(dir);
}
}

// M20 - List SD card
void GcodeSuite::M20() {
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);
}

Expand Down

0 comments on commit e38da17

Please sign in to comment.