From e09c144674fffa39a0077a6af0bd6093eaa138b0 Mon Sep 17 00:00:00 2001 From: thesfreader Date: Fri, 5 Oct 2018 09:35:55 +0200 Subject: [PATCH] Add CNC-like G-code options --- Marlin/Configuration_adv.h | 9 ++++ Marlin/src/gcode/parser.cpp | 104 +++++++++++++++++++++++++++--------- Marlin/src/gcode/parser.h | 9 ++++ Marlin/src/gcode/queue.cpp | 49 ++++++++++++++--- 4 files changed, 139 insertions(+), 32 deletions(-) diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 88a3df2d53..636a054e03 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1776,4 +1776,13 @@ // Enable Marlin dev mode which adds some special commands //#define MARLIN_DEV_MODE + +/** + * CNC Parsing options + * + * These options increase marlin's acceptance of non reprap dialects more in line with what laser cutter or drawing machine cams produce + */ +//#define PARENTHESE_COMMENTS // Enable Marlin to interpret parenthese delimited comments as such and ignore them +//#define STICKY_MOVE_MODE // Enable marlin to keep the current move mode (G0 G1 G2 G3 G5 G38.X) and use it even if receiving only parameters (X Y Z E F etc.) + #endif // CONFIGURATION_ADV_H diff --git a/Marlin/src/gcode/parser.cpp b/Marlin/src/gcode/parser.cpp index 392532646c..0c51318600 100644 --- a/Marlin/src/gcode/parser.cpp +++ b/Marlin/src/gcode/parser.cpp @@ -53,6 +53,13 @@ int GCodeParser::codenum; #if USE_GCODE_SUBCODES uint8_t GCodeParser::subcode; #endif +#if ENABLED(STICKY_MOVE_MODE) + int GCodeParser::current_motion_mode_codenum; + #if USE_GCODE_SUBCODES + uint8_t GCodeParser::current_motion_mode_subcode; + #endif +#endif + #if ENABLED(FASTER_GCODE_PARSER) // Optimized Parameters @@ -118,36 +125,81 @@ void GCodeParser::parse(char *p) { } // Bail if the letter is not G, M, or T - switch (letter) { case 'G': case 'M': case 'T': break; default: return; } - - // Skip spaces to get the numeric part - while (*p == ' ') p++; - - // Bail if there's no command code number - if (!NUMERIC(*p)) return; - - // Save the command letter at this point - // A '?' signifies an unknown command - command_letter = letter; + switch(letter) { + case 'G': + case 'M': + case 'T': + + // Skip spaces to get the numeric part + while (*p == ' ') p++; + + // Bail if there's no command code number + if (!NUMERIC(*p)) return; + + // Save the command letter at this point + // A '?' signifies an unknown command + command_letter = letter; + + // Get the code number - integer digits only + codenum = 0; + do { + codenum *= 10, codenum += *p++ - '0'; + } while (NUMERIC(*p)); + + // Allow for decimal point in command + #if USE_GCODE_SUBCODES + if (*p == '.') { + p++; + while (NUMERIC(*p)) + subcode *= 10, subcode += *p++ - '0'; + } + #endif - // Get the code number - integer digits only - codenum = 0; - do { - codenum *= 10, codenum += *p++ - '0'; - } while (NUMERIC(*p)); + // Skip all spaces to get to the first argument, or nul + while (*p == ' ') p++; - // Allow for decimal point in command - #if USE_GCODE_SUBCODES - if (*p == '.') { - p++; - while (NUMERIC(*p)) - subcode *= 10, subcode += *p++ - '0'; - } - #endif + #if ENABLED(STICKY_MOVE_MODE) + if( letter == 'G' && (codenum < 4 || codenum == 5 || codenum == 38 || (codenum>=80 &&codenum < 90 ))) { + current_motion_mode_codenum = codenum; + #if USE_GCODE_SUBCODES + current_motion_mode_subcode = subcode; + #endif + } + #endif + break; + + #if ENABLED(STICKY_MOVE_MODE) + + case 'P': + case 'Q': + if (current_motion_mode_codenum != 5) + return; + case 'I': + case 'J': + case 'R': + if (current_motion_mode_codenum < 2) + return; + case 'X': + case 'Y': + case 'Z': + case 'E': + case 'F': + + command_letter = 'G'; + codenum = current_motion_mode_codenum; + #if USE_GCODE_SUBCODES + subcode = current_motion_mode_subcode; + #endif + + // Roll back one character before to use the current arg + p--; + break; + #endif // STICKY_MOVE_MODE - // Skip all spaces to get to the first argument, or nul - while (*p == ' ') p++; + default: return; + } + // The command parameters (if any) start here, for sure! #if DISABLED(FASTER_GCODE_PARSER) diff --git a/Marlin/src/gcode/parser.h b/Marlin/src/gcode/parser.h index eb67bf14a7..5939ea8a77 100644 --- a/Marlin/src/gcode/parser.h +++ b/Marlin/src/gcode/parser.h @@ -78,12 +78,21 @@ public: static char *command_ptr, // The command, so it can be echoed *string_arg; // string of command line + + static char command_letter; // G, M, or T static int codenum; // 123 #if USE_GCODE_SUBCODES static uint8_t subcode; // .1 #endif + #if ENABLED(STICKY_MOVE_MODE) + static int current_motion_mode_codenum; + #if USE_GCODE_SUBCODES + static uint8_t current_motion_mode_subcode; + #endif + #endif + #if ENABLED(DEBUG_GCODE_PARSER) static void debug(); #endif diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp index 8e30248853..6cbd0cc331 100644 --- a/Marlin/src/gcode/queue.cpp +++ b/Marlin/src/gcode/queue.cpp @@ -283,6 +283,9 @@ static int read_serial(const int index) { inline void get_serial_commands() { static char serial_line_buffer[NUM_SERIAL][MAX_CMD_SIZE]; static bool serial_comment_mode[NUM_SERIAL] = { false }; + #if ENABLED(PARENTHESE_COMMENTS) + static bool serial_comment_paranthese_mode[NUM_SERIAL] = { false }; + #endif // If the command buffer is empty for too long, // send "wait" to indicate Marlin is still waiting. @@ -311,6 +314,9 @@ inline void get_serial_commands() { if (serial_char == '\n' || serial_char == '\r') { serial_comment_mode[i] = false; // end of line == end of comment + #if ENABLED(PARENTHESE_COMMENTS) + serial_comment_paranthese_mode[i] = false; // end of line == end of comment + #endif // Skip empty lines and comments if (!serial_count[i]) { thermalManager.manage_heater(); continue; } @@ -404,12 +410,24 @@ inline void get_serial_commands() { } else if (serial_char == '\\') { // Handle escapes // if we have one more character, copy it over - if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i]) + if ((c = read_serial(i)) >= 0 && !serial_comment_mode[i] + #if ENABLED(PARENTHESE_COMMENTS) + && ! serial_comment_paranthese_mode[i] + #endif + ) serial_line_buffer[i][serial_count[i]++] = (char)c; } else { // it's not a newline, carriage return or escape char - if (serial_char == ';') serial_comment_mode[i] = true; - if (!serial_comment_mode[i]) serial_line_buffer[i][serial_count[i]++] = serial_char; + if (serial_char == ';') serial_comment_mode[i] = true; + #if ENABLED(PARENTHESE_COMMENTS) + else if (serial_char == '(') serial_comment_paranthese_mode[i] = true; + else if (serial_char == ')') serial_comment_paranthese_mode[i] = false; + #endif + else if (!serial_comment_mode[i] + #if ENABLED(PARENTHESE_COMMENTS) + && ! serial_comment_paranthese_mode[i] + #endif + ) serial_line_buffer[i][serial_count[i]++] = serial_char; } } // for NUM_SERIAL } // queue has space, serial has data @@ -426,6 +444,9 @@ inline void get_serial_commands() { static bool stop_buffering = false, sd_comment_mode = false; + #if ENABLED(PARENTHESE_COMMENTS) + static bool sd_comment_parenthese_mode = false; + #endif if (!IS_SD_PRINTING) return; /** @@ -445,7 +466,11 @@ inline void get_serial_commands() { card_eof = card.eof(); if (card_eof || n == -1 || sd_char == '\n' || sd_char == '\r' - || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode) + || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode + #if ENABLED(PARENTHESE_COMMENTS) + && ! sd_comment_parenthese_mode + #endif + ) ) { if (card_eof) { @@ -481,6 +506,9 @@ inline void get_serial_commands() { if (sd_char == '#') stop_buffering = true; sd_comment_mode = false; // for new command + #if ENABLED(PARENTHESE_COMMENTS) + sd_comment_parenthese_mode = false; + #endif // Skip empty lines and comments if (!sd_count) { thermalManager.manage_heater(); continue; } @@ -497,8 +525,17 @@ inline void get_serial_commands() { */ } else { - if (sd_char == ';') sd_comment_mode = true; - if (!sd_comment_mode) command_queue[cmd_queue_index_w][sd_count++] = sd_char; + if (sd_char == ';') sd_comment_mode = true; + #if ENABLED(PARENTHESE_COMMENTS) + else if (sd_char == '(') sd_comment_parenthese_mode = true; + else if (sd_char == ')') sd_comment_parenthese_mode = false; + #endif + else if (!sd_comment_mode + #if ENABLED(PARENTHESE_COMMENTS) + && ! sd_comment_parenthese_mode + #endif + ) + command_queue[cmd_queue_index_w][sd_count++] = sd_char; } } }