Skip to content

Commit

Permalink
M2x commands, EXTENDED_M20 support
Browse files Browse the repository at this point in the history
Implement M20 compatible with Marlin
Align M23 & M24 compatibility with Marlin
Add gcode M27 auto report support
  • Loading branch information
thess committed Aug 15, 2024
1 parent 132592a commit 9a19293
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 26 deletions.
7 changes: 7 additions & 0 deletions lib/Marlin/Marlin/src/gcode/gcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,13 @@

enum AxisRelative : uint8_t { REL_X, REL_Y, REL_Z, REL_E, E_MODE_ABS, E_MODE_REL };

#if ENABLED(SDSUPPORT) || ENABLED(SDCARD_GCODES)
namespace M27_handler {
extern uint32_t sd_auto_report_delay;
void print_sd_status();
} // namespace M27_handler
#endif

class GcodeSuite {
public:

Expand Down
13 changes: 13 additions & 0 deletions src/common/marlin_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,15 @@ void handle_nfc() {

#endif

void print_sd_report() {
static uint32_t last_sd_report = 0;
uint32_t current_time = ticks_s();
if (M27_handler::sd_auto_report_delay && (current_time - last_sd_report) >= M27_handler::sd_auto_report_delay) {
M27_handler::print_sd_status();
last_sd_report = current_time;
}
}

#if ENABLED(PRUSA_MMU2)
/// Helper function that enqueues gcodes to safely unload filament from nozzle back to mmu
///
Expand Down Expand Up @@ -641,6 +650,10 @@ static void cycle() {

print_fan_spd();

#if ENABLED(SDSUPPORT) || ENABLED(SDCARD_GCODES)
print_sd_report();
#endif

#ifdef MINDA_BROKEN_CABLE_DETECTION
print_Z_probe_cnt();
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/common/media.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void media_print_start() {
media_print_size_estimate = media_print_file->get_gcode_stream_size_estimate();

// Do not remove, needed for 3rd party tools such as octoprint to get status about the gcode file being opened
SERIAL_ECHOLNPAIR(MSG_SD_FILE_OPENED, marlin_vars()->media_SFN_path.get_ptr(), " Size:", media_print_size_estimate);
SERIAL_ECHOLNPAIR(MSG_SD_FILE_OPENED, marlin_vars()->media_SFN_path.get_ptr(), MSG_SD_SIZE, media_print_size_estimate);

gcode_filter.reset();
osSignalSet(prefetch_thread_id, PREFETCH_SIGNAL_START);
Expand Down
3 changes: 3 additions & 0 deletions src/marlin_stubs/host/M115.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ void GcodeSuite::M115() {
#endif
);

// EXTENDED_M20
cap_line(PSTR("EXTENDED_M20"), true);

// THERMAL_PROTECTION
cap_line(PSTR("THERMAL_PROTECTION")
#if ((ENABLED(THERMAL_PROTECTION_HOTENDS) || HAS_DWARF()) && (ENABLED(THERMAL_PROTECTION_BED) || !HAS_HEATED_BED || HAS_MODULARBED()) && (ENABLED(THERMAL_PROTECTION_CHAMBER) || !HAS_HEATED_CHAMBER))
Expand Down
152 changes: 127 additions & 25 deletions src/marlin_stubs/sdcard/M20-M30_M32-M34.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,80 @@
#include "media.hpp"
#include "marlin_vars.hpp"

struct ListControl {
bool print_lfn : 1;
bool print_time : 1;
uint8_t recursion_count;
};

// Depends on stack size/RAM, etc
// Set to 0 to disallow recursion, Marlin MAX is 6
#define MAX_RECURSION_DEPTH 3
// Device root name for FatFS
#define ROOT_PREFIX "/usb"

static void list_files(const char *const dir_path, struct ListControl lc) {
DIR *dir;
dir = opendir(dir_path);
if (dir != NULL) {
struct dirent *entry;
// Get timezone offset to report local filetime
time_t tz_offset_seconds = time_tools::calculate_total_timezone_offset_minutes() * 60;
while ((entry = readdir(dir)) != NULL && entry->d_name[0]) {
// Construct path to sub-dir.
int len = strlen(dir_path) + strlen(entry->d_name) + 2;
char *path = reinterpret_cast<char *>(alloca(len));
strcpy(path, dir_path);
strcat(path, "/");
strcat(path, entry->d_name);

if (entry->d_type != DT_DIR) {
struct stat fstats;

// Hide ROOT_PREFIX
SERIAL_ECHO(&path[sizeof(ROOT_PREFIX) - 1]);
int rc = stat(path, &fstats);
if (rc == 0) {
SERIAL_ECHOPAIR(PSTR(" "), fstats.st_size);
if (lc.print_time) {
struct tm lt;
time_t t = fstats.st_mtim.tv_sec + tz_offset_seconds;
localtime_r(&t, &lt);
// M20 Date in high-word
t = ((lt.tm_year + 1900 - 1980) << 9 | (lt.tm_mon + 1) << 5 | lt.tm_mday) << 16;
// M20 Time in low-word
t |= lt.tm_hour << 11 | lt.tm_min << 5 | int((lt.tm_sec - (lt.tm_sec % 2)) / 2);
SERIAL_ECHOPGM(" 0x");
SERIAL_PRINT((unsigned int)t, HEX);
}
if (lc.print_lfn) {
SERIAL_ECHOPAIR(PSTR(" \""), entry->lfn, PSTR("\""));
}
}
SERIAL_EOL();
} else {
// Check recursion depth
if (lc.recursion_count == 0) {
continue;
}

if (lc.print_lfn) {
SERIAL_ECHOPAIR(PSTR("DIR_ENTER: "), &path[sizeof(ROOT_PREFIX) - 1], PSTR("/ \""), entry->lfn, PSTR("\""));
SERIAL_EOL();
}
// Recurse into sub-dir
lc.recursion_count--;
list_files(path, lc);
lc.recursion_count++;
if (lc.print_lfn) {
SERIAL_ECHOLNPGM("DIR_EXIT");
}
}
}
closedir(dir);
}
}

/** \addtogroup G-Codes
* @{
*/
Expand All @@ -13,16 +87,16 @@
* 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);
ListControl lc;
if (parser.seen('L')) {
lc.print_lfn = 1;
}
if (parser.seen('T')) {
lc.print_time = 1;
}
lc.recursion_count = MAX_RECURSION_DEPTH;
SERIAL_ECHOLNPGM(MSG_BEGIN_FILE_LIST);
list_files(ROOT_PREFIX, lc);
SERIAL_ECHOLNPGM(MSG_END_FILE_LIST);
}

Expand All @@ -44,22 +118,42 @@ void GcodeSuite::M22() {
* M23 - Select SD file
*/
void GcodeSuite::M23() {
// Simplify3D includes the size, so zero out all spaces (#7227)
for (char *fn = parser.string_arg; *fn; ++fn) {
if (*fn == ' ') {
*fn = '\0';
}
char namebuf[marlin_vars()->media_SFN_path.max_length()];
// Simplify3D includes the size, terminate name at first space
char *idx = strchr(parser.string_arg, ' ');
if (idx) {
*idx = '\0';
}
marlin_vars()->media_SFN_path.set(parser.string_arg);
// Need to prepend root device name
strcpy(namebuf, PSTR(ROOT_PREFIX));
strncpy(&namebuf[sizeof(ROOT_PREFIX) - 1], parser.string_arg, sizeof(namebuf) - sizeof(ROOT_PREFIX));

// Do not remove. Used by third party tools to detect that a file has been selected
SERIAL_ECHOLNPGM(MSG_SD_FILE_SELECTED);
SERIAL_ECHO_START();
SERIAL_ECHOPAIR(PSTR("Now doing file: "), parser.string_arg);
SERIAL_EOL();

struct stat fstats;
int rc = stat(namebuf, &fstats);
if (rc == 0) {
marlin_vars()->media_SFN_path.set(namebuf);
// Do not remove, needed for 3rd party tools such as octoprint to get notification about the gcode file being opened
SERIAL_ECHOLNPAIR(MSG_SD_FILE_OPENED, parser.string_arg, MSG_SD_SIZE, fstats.st_size);
SERIAL_ECHOLNPGM(MSG_SD_FILE_SELECTED);
} else {
SERIAL_ECHOLNPAIR(MSG_SD_OPEN_FILE_FAIL, parser.string_arg);
}
}

/**
* M24 - Start/resume SD print
*/
void GcodeSuite::M24() {
marlin_server::print_resume();
if (media_print_get_state() == media_print_state_PAUSED) {
marlin_server::print_resume();
} else {
marlin_server::print_start(marlin_vars()->media_SFN_path.get_ptr(), marlin_server::PreviewSkipIfAble::all);
}
}

/**
Expand Down Expand Up @@ -89,19 +183,27 @@ void GcodeSuite::M26() {
*
* - `C` - Report current file's short file name instead
*/
uint32_t M27_handler::sd_auto_report_delay = 0;

void M27_handler::print_sd_status() {
if (media_print_get_state() != media_print_state_NONE) {
SERIAL_ECHOPGM(MSG_SD_PRINTING_BYTE);
SERIAL_ECHO(media_print_get_position());
SERIAL_CHAR('/');
SERIAL_ECHOLN(media_print_get_size());
} else {
SERIAL_ECHOLNPGM(MSG_SD_NOT_PRINTING);
}
}

void GcodeSuite::M27() {
if (parser.seen('C')) {
SERIAL_ECHOPGM("Current file: ");
SERIAL_ECHOLN(marlin_vars()->media_SFN_path.get_ptr());
} else if (parser.seen('S')) {
M27_handler::sd_auto_report_delay = parser.byteval('S');
} else {
if (media_print_get_state() != media_print_state_NONE) {
SERIAL_ECHOPGM(MSG_SD_PRINTING_BYTE);
SERIAL_ECHO(media_print_get_position());
SERIAL_CHAR('/');
SERIAL_ECHOLN(media_print_get_size());
} else {
SERIAL_ECHOLNPGM(MSG_SD_NOT_PRINTING);
}
M27_handler::print_sd_status();
}
}

Expand Down

0 comments on commit 9a19293

Please sign in to comment.