|
@ -149,13 +149,31 @@ void GCodeParser::parse(char *p) { |
|
|
#define SIGNED_CODENUM 1 |
|
|
#define SIGNED_CODENUM 1 |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Screen for good command letters. |
|
|
|
|
|
* With Realtime Reporting, commands S000, P000, and R000 are allowed. |
|
|
|
|
|
*/ |
|
|
|
|
|
#if ENABLED(REALTIME_REPORTING_COMMANDS) |
|
|
|
|
|
switch (letter) { |
|
|
|
|
|
case 'P': case 'R' ... 'S': { |
|
|
|
|
|
uint8_t digits = 0; |
|
|
|
|
|
char *a = p; |
|
|
|
|
|
while (*a++ == '0') digits++; // Count up '0' characters
|
|
|
|
|
|
if (digits == 3) { // Three '0' digits is a good command
|
|
|
|
|
|
codenum = 0; |
|
|
|
|
|
command_letter = letter; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* Screen for good command letters. G, M, and T are always accepted. |
|
|
* Screen for good command letters. G, M, and T are always accepted. |
|
|
* With Motion Modes enabled any axis letter can come first. |
|
|
* With Motion Modes enabled any axis letter can come first. |
|
|
* With Realtime Reporting, commands S000, P000, and R000 are allowed. |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
switch (letter) { |
|
|
switch (letter) { |
|
|
case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':) |
|
|
case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':) { |
|
|
// Skip spaces to get the numeric part
|
|
|
// Skip spaces to get the numeric part
|
|
|
while (*p == ' ') p++; |
|
|
while (*p == ' ') p++; |
|
|
|
|
|
|
|
@ -177,20 +195,18 @@ void GCodeParser::parse(char *p) { |
|
|
// A '?' signifies an unknown command
|
|
|
// A '?' signifies an unknown command
|
|
|
command_letter = letter; |
|
|
command_letter = letter; |
|
|
|
|
|
|
|
|
{ |
|
|
#if ENABLED(SIGNED_CODENUM) |
|
|
#if ENABLED(SIGNED_CODENUM) |
|
|
int sign = 1; // Allow for a negative code like D-1 or T-1
|
|
|
int sign = 1; // Allow for a negative code like D-1 or T-1
|
|
|
if (*p == '-') { sign = -1; ++p; } |
|
|
if (*p == '-') { sign = -1; ++p; } |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// Get the code number - integer digits only
|
|
|
// Get the code number - integer digits only
|
|
|
codenum = 0; |
|
|
codenum = 0; |
|
|
|
|
|
|
|
|
do { codenum = codenum * 10 + *p++ - '0'; } while (NUMERIC(*p)); |
|
|
do { codenum = codenum * 10 + *p++ - '0'; } while (NUMERIC(*p)); |
|
|
|
|
|
|
|
|
// Apply the sign, if any
|
|
|
// Apply the sign, if any
|
|
|
TERN_(SIGNED_CODENUM, codenum *= sign); |
|
|
TERN_(SIGNED_CODENUM, codenum *= sign); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Allow for decimal point in command
|
|
|
// Allow for decimal point in command
|
|
|
#if USE_GCODE_SUBCODES |
|
|
#if USE_GCODE_SUBCODES |
|
@ -213,38 +229,33 @@ void GCodeParser::parse(char *p) { |
|
|
} |
|
|
} |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
break; |
|
|
} break; |
|
|
|
|
|
|
|
|
#if ENABLED(GCODE_MOTION_MODES) |
|
|
#if ENABLED(GCODE_MOTION_MODES) |
|
|
case 'I' ... 'J': |
|
|
|
|
|
if (motion_mode_codenum != 5 && \ |
|
|
#if EITHER(BEZIER_CURVE_SUPPORT, ARC_SUPPORT) |
|
|
TERN1(ARC_SUPPORT, motion_mode_codenum != 2 && motion_mode_codenum != 3)) return; |
|
|
case 'I' ... 'J': case 'P': |
|
|
case 'Q': |
|
|
if (TERN1(BEZIER_CURVE_SUPPORT, motion_mode_codenum != 5) |
|
|
if (motion_mode_codenum != 5) return; |
|
|
&& TERN1(ARC_P_CIRCLES, !WITHIN(motion_mode_codenum, 2, 3)) |
|
|
|
|
|
) return; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(BEZIER_CURVE_SUPPORT) |
|
|
|
|
|
case 'Q': if (motion_mode_codenum != 5) return; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(ARC_SUPPORT) |
|
|
|
|
|
case 'R': if (!WITHIN(motion_mode_codenum, 2, 3)) return; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
case 'X' ... 'Z': case 'E' ... 'F': |
|
|
case 'X' ... 'Z': case 'E' ... 'F': |
|
|
if (motion_mode_codenum < 0) return; |
|
|
if (motion_mode_codenum < 0) return; |
|
|
command_letter = 'G'; |
|
|
command_letter = 'G'; |
|
|
codenum = motion_mode_codenum; |
|
|
codenum = motion_mode_codenum; |
|
|
TERN_(USE_GCODE_SUBCODES, subcode = motion_mode_subcode); |
|
|
TERN_(USE_GCODE_SUBCODES, subcode = motion_mode_subcode); |
|
|
p--; // Back up one character to use the current parameter
|
|
|
p--; // Back up one character to use the current parameter
|
|
|
break; |
|
|
break; |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(REALTIME_REPORTING_COMMANDS) |
|
|
|
|
|
case 'P': case 'R': { |
|
|
|
|
|
if (letter == 'R') { |
|
|
|
|
|
#if ENABLED(GCODE_MOTION_MODES) |
|
|
|
|
|
if (ENABLED(ARC_SUPPORT) && !WITHIN(motion_mode_codenum, 2, 3)) return; |
|
|
|
|
|
#endif |
|
|
|
|
|
} |
|
|
|
|
|
else if (TERN0(GCODE_MOTION_MODES, motion_mode_codenum != 5)) return; |
|
|
|
|
|
} // fall-thru
|
|
|
|
|
|
case 'S': { |
|
|
|
|
|
codenum = 0; // The only valid codenum is 0
|
|
|
|
|
|
uint8_t digits = 0; |
|
|
|
|
|
while (*p++ == '0') digits++; // Count up '0' characters
|
|
|
|
|
|
command_letter = (digits == 3) ? letter : '?'; // Three '0' digits is a good command
|
|
|
|
|
|
} return; // No parameters needed, so return now
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
default: return; |
|
|
default: return; |
|
@ -252,18 +263,12 @@ void GCodeParser::parse(char *p) { |
|
|
|
|
|
|
|
|
// The command parameters (if any) start here, for sure!
|
|
|
// The command parameters (if any) start here, for sure!
|
|
|
|
|
|
|
|
|
#if DISABLED(FASTER_GCODE_PARSER) |
|
|
IF_DISABLED(FASTER_GCODE_PARSER, command_args = p); // Scan for parameters in seen()
|
|
|
command_args = p; // Scan for parameters in seen()
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// Only use string_arg for these M codes
|
|
|
// Only use string_arg for these M codes
|
|
|
if (letter == 'M') switch (codenum) { |
|
|
if (letter == 'M') switch (codenum) { |
|
|
#if ENABLED(GCODE_MACROS) |
|
|
TERN_(GCODE_MACROS, case 810 ... 819:) |
|
|
case 810 ... 819: |
|
|
TERN_(EXPECTED_PRINTER_CHECK, case 16:) |
|
|
#endif |
|
|
|
|
|
#if ENABLED(EXPECTED_PRINTER_CHECK) |
|
|
|
|
|
case 16: |
|
|
|
|
|
#endif |
|
|
|
|
|
case 23: case 28: case 30: case 117 ... 118: case 928: |
|
|
case 23: case 28: case 30: case 117 ... 118: case 928: |
|
|
string_arg = unescape_string(p); |
|
|
string_arg = unescape_string(p); |
|
|
return; |
|
|
return; |
|
|