gcode_parse.c: process incoming digits earlier.

Idea and patch from ItsDrone, see
http://forums.reprap.org/read.php?146,174364,174550#msg-174550

Thanks, ItsDrone.
This commit is contained in:
Markus Hitter 2013-01-03 15:07:29 +01:00
parent 03d49a1a87
commit 63d3f012a8
1 changed files with 95 additions and 92 deletions

View File

@ -211,101 +211,104 @@ void gcode_parse_char(uint8_t c) {
} }
// process character // process character
switch (c) { // Can't do ranges in switch..case, so process actual digits here.
// each currently known command is either G or M, so preserve previous G/M unless a new one has appeared // Do it early, as there are many more digits than characters expected.
// FIXME: same for T command if (c >= '0' && c <= '9') {
case 'G': if (read_digit.exponent < DECFLOAT_EXP_MAX + 1 &&
next_target.seen_G = 1; ((next_target.option_inches == 0 &&
next_target.seen_M = 0; read_digit.mantissa < DECFLOAT_MANT_MM_MAX) ||
next_target.M = 0; (next_target.option_inches &&
break; read_digit.mantissa < DECFLOAT_MANT_IN_MAX))) {
case 'M': // this is simply mantissa = (mantissa * 10) + atoi(c) in different clothes
next_target.seen_M = 1; read_digit.mantissa = (read_digit.mantissa << 3) +
next_target.seen_G = 0; (read_digit.mantissa << 1) + (c - '0');
next_target.G = 0; if (read_digit.exponent)
break; read_digit.exponent++;
case 'X': }
next_target.seen_X = 1; }
break; else {
case 'Y': switch (c) {
next_target.seen_Y = 1; // Each currently known command is either G or M, so preserve
break; // previous G/M unless a new one has appeared.
case 'Z': // FIXME: same for T command
next_target.seen_Z = 1; case 'G':
break; next_target.seen_G = 1;
case 'E': next_target.seen_M = 0;
next_target.seen_E = 1; next_target.M = 0;
break; break;
case 'F': case 'M':
next_target.seen_F = 1; next_target.seen_M = 1;
break; next_target.seen_G = 0;
case 'S': next_target.G = 0;
next_target.seen_S = 1; break;
break; case 'X':
case 'P': next_target.seen_X = 1;
next_target.seen_P = 1; break;
break; case 'Y':
case 'T': next_target.seen_Y = 1;
next_target.seen_T = 1; break;
break; case 'Z':
case 'N': next_target.seen_Z = 1;
next_target.seen_N = 1; break;
break; case 'E':
case '*': next_target.seen_E = 1;
next_target.seen_checksum = 1; break;
break; case 'F':
next_target.seen_F = 1;
break;
case 'S':
next_target.seen_S = 1;
break;
case 'P':
next_target.seen_P = 1;
break;
case 'T':
next_target.seen_T = 1;
break;
case 'N':
next_target.seen_N = 1;
break;
case '*':
next_target.seen_checksum = 1;
break;
// comments // comments
case ';': case ';':
next_target.seen_semi_comment = 1; next_target.seen_semi_comment = 1;
break; break;
case '(': case '(':
next_target.seen_parens_comment = 1; next_target.seen_parens_comment = 1;
break; break;
// now for some numeracy // now for some numeracy
case '-': case '-':
read_digit.sign = 1; read_digit.sign = 1;
// force sign to be at start of number, so 1-2 = -2 instead of -12 // force sign to be at start of number, so 1-2 = -2 instead of -12
read_digit.exponent = 0; read_digit.exponent = 0;
read_digit.mantissa = 0; read_digit.mantissa = 0;
break; break;
case '.': case '.':
if (read_digit.exponent == 0) if (read_digit.exponent == 0)
read_digit.exponent = 1; read_digit.exponent = 1;
break; break;
#ifdef DEBUG #ifdef DEBUG
case ' ': case ' ':
case '\t': case '\t':
case 10: case 10:
case 13: case 13:
// ignore // ignore
break; break;
#endif #endif
default: default:
// can't do ranges in switch..case, so process actual digits here. #ifdef DEBUG
if (c >= '0' && c <= '9') { // invalid
if (read_digit.exponent < DECFLOAT_EXP_MAX + 1 && serial_writechar('?');
((next_target.option_inches == 0 && serial_writechar(c);
read_digit.mantissa < DECFLOAT_MANT_MM_MAX) || serial_writechar('?');
(next_target.option_inches && #endif
read_digit.mantissa < DECFLOAT_MANT_IN_MAX))) break;
{ }
// this is simply mantissa = (mantissa * 10) + atoi(c) in different clothes
read_digit.mantissa = (read_digit.mantissa << 3) + (read_digit.mantissa << 1) + (c - '0');
if (read_digit.exponent)
read_digit.exponent++;
}
}
#ifdef DEBUG
else {
// invalid
serial_writechar('?');
serial_writechar(c);
serial_writechar('?');
}
#endif
} }
} else if ( next_target.seen_parens_comment == 1 && c == ')') } else if ( next_target.seen_parens_comment == 1 && c == ')')
next_target.seen_parens_comment = 0; // recognize stuff after a (comment) next_target.seen_parens_comment = 0; // recognize stuff after a (comment)