Major g-code parser overhaul. 100%* compliant. Other related updates.

- Completely overhauled the g-code parser. It’s now 100%* compliant. (*
may have some bugs). Being compliant, here are some of the major
differences.

- SMALLER and JUST AS FAST! A number of optimizations were found that
sped things up and allowed for the more thorough error-checking to be
installed without a speed hit. Trimmed a lot of ‘fat’ in the parser and
still was able to make it significantly smaller than it was.

- No default feed rate setting! Removed completely! This doesn’t exist
in the g-code standard. So, it now errors out whenever it’s undefined
for motions that require it (G1/2/3/38.2).

- Any g-code parser error expunges the ENTIRE block. This means all
information is lost and not passed on to the running state. Before some
of the states would remain, which could have led to some problems.

- If the g-code block passes all of the error-checks, the g-code state
is updated and all motions are executed according to the order of
execution.

- Changes in spindle speed, when already running, will update the
output pin accordingly. This fixes a bug, where it wouldn’t update the
speed.

- Update g-code parser error reporting. Errors now return detailed
information of what exact went wrong. The most common errors return a
short text description. For less common errors, the parser reports
‘Invalid gcode ID:20’, where 20 is a error ID. A list of error code IDs
and their descriptions will be documented for user reference elsewhere
to save flash space.

- Other notable changes:

- Added a print integer routine for uint8 variables. This saved
significant flash space by switching from a heavier universal print
integer routine.

- Saved some flash space with our own short hypotenuse calculation

- Some arc computation flash and memory optimizations.
This commit is contained in:
Sonny Jeon
2014-05-25 16:05:28 -06:00
parent 06432c9de9
commit 532c359a11
22 changed files with 1162 additions and 741 deletions

124
report.c
View File

@ -51,22 +51,16 @@ void report_status_message(uint8_t status_code)
} else {
printPgmString(PSTR("error: "));
switch(status_code) {
case STATUS_BAD_NUMBER_FORMAT:
printPgmString(PSTR("Bad number format")); break;
case STATUS_EXPECTED_COMMAND_LETTER:
printPgmString(PSTR("Expected command letter")); break;
case STATUS_UNSUPPORTED_STATEMENT:
printPgmString(PSTR("Unsupported statement")); break;
case STATUS_ARC_RADIUS_ERROR:
printPgmString(PSTR("Invalid radius")); break;
case STATUS_MODAL_GROUP_VIOLATION:
printPgmString(PSTR("Modal group violation")); break;
case STATUS_BAD_NUMBER_FORMAT:
printPgmString(PSTR("Bad number format")); break;
case STATUS_INVALID_STATEMENT:
printPgmString(PSTR("Invalid statement")); break;
case STATUS_NEGATIVE_VALUE:
printPgmString(PSTR("Value < 0")); break;
case STATUS_SETTING_DISABLED:
printPgmString(PSTR("Setting disabled")); break;
case STATUS_SETTING_VALUE_NEG:
printPgmString(PSTR("Value < 0.0")); break;
case STATUS_SETTING_STEP_PULSE_MIN:
printPgmString(PSTR("Value < 3 usec")); break;
case STATUS_SETTING_READ_FAIL:
@ -79,6 +73,18 @@ void report_status_message(uint8_t status_code)
printPgmString(PSTR("Homing not enabled")); break;
case STATUS_OVERFLOW:
printPgmString(PSTR("Line overflow")); break;
// Common g-code parser errors.
case STATUS_GCODE_MODAL_GROUP_VIOLATION:
printPgmString(PSTR("Modal group violation")); break;
case STATUS_GCODE_UNSUPPORTED_COMMAND:
printPgmString(PSTR("Unsupported command")); break;
case STATUS_GCODE_UNDEFINED_FEED_RATE:
printPgmString(PSTR("Undefined feed rate")); break;
default:
// Remaining g-code parser errors with error codes
printPgmString(PSTR("Invalid gcode ID:"));
print_uint8_base10(status_code); // Print error code for user reference
}
printPgmString(PSTR("\r\n"));
}
@ -163,29 +169,28 @@ void report_grbl_settings() {
printPgmString(PSTR(" (z accel, mm/sec^2)\r\n$9=")); printFloat(-settings.max_travel[X_AXIS]); // Grbl internally store this as negative.
printPgmString(PSTR(" (x max travel, mm)\r\n$10=")); printFloat(-settings.max_travel[Y_AXIS]); // Grbl internally store this as negative.
printPgmString(PSTR(" (y max travel, mm)\r\n$11=")); printFloat(-settings.max_travel[Z_AXIS]); // Grbl internally store this as negative.
printPgmString(PSTR(" (z max travel, mm)\r\n$12=")); printInteger(settings.pulse_microseconds);
printPgmString(PSTR(" (step pulse, usec)\r\n$13=")); printFloat(settings.default_feed_rate);
printPgmString(PSTR(" (default feed, mm/min)\r\n$14=")); printInteger(settings.step_invert_mask);
printPgmString(PSTR(" (z max travel, mm)\r\n$12=")); print_uint8_base10(settings.pulse_microseconds);
printPgmString(PSTR(" (step pulse, usec)\r\n$13=")); print_uint8_base10(settings.step_invert_mask);
printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask);
printPgmString(PSTR(")\r\n$15=")); printInteger(settings.dir_invert_mask);
printPgmString(PSTR(")\r\n$14=")); print_uint8_base10(settings.dir_invert_mask);
printPgmString(PSTR(" (dir port invert mask:")); print_uint8_base2(settings.dir_invert_mask);
printPgmString(PSTR(")\r\n$16=")); printInteger(settings.stepper_idle_lock_time);
printPgmString(PSTR(" (step idle delay, msec)\r\n$17=")); printFloat(settings.junction_deviation);
printPgmString(PSTR(" (junction deviation, mm)\r\n$18=")); printFloat(settings.arc_tolerance);
printPgmString(PSTR(" (arc tolerance, mm)\r\n$19=")); printInteger(settings.decimal_places);
printPgmString(PSTR(" (n-decimals, int)\r\n$20=")); printInteger(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
printPgmString(PSTR(" (report inches, bool)\r\n$21=")); printInteger(bit_istrue(settings.flags,BITFLAG_AUTO_START));
printPgmString(PSTR(" (auto start, bool)\r\n$22=")); printInteger(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
printPgmString(PSTR(" (invert step enable, bool)\r\n$23=")); printInteger(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS));
printPgmString(PSTR(" (invert limit pins, bool)\r\n$24=")); printInteger(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE));
printPgmString(PSTR(" (soft limits, bool)\r\n$25=")); printInteger(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
printPgmString(PSTR(" (hard limits, bool)\r\n$26=")); printInteger(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
printPgmString(PSTR(" (homing cycle, bool)\r\n$27=")); printInteger(settings.homing_dir_mask);
printPgmString(PSTR(")\r\n$15=")); print_uint8_base10(settings.stepper_idle_lock_time);
printPgmString(PSTR(" (step idle delay, msec)\r\n$16=")); printFloat(settings.junction_deviation);
printPgmString(PSTR(" (junction deviation, mm)\r\n$17=")); printFloat(settings.arc_tolerance);
printPgmString(PSTR(" (arc tolerance, mm)\r\n$18=")); print_uint8_base10(settings.decimal_places);
printPgmString(PSTR(" (n-decimals, int)\r\n$19=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_AUTO_START));
printPgmString(PSTR(" (auto start, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
printPgmString(PSTR(" (invert step enable, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS));
printPgmString(PSTR(" (invert limit pins, bool)\r\n$23=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE));
printPgmString(PSTR(" (soft limits, bool)\r\n$24=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
printPgmString(PSTR(" (hard limits, bool)\r\n$25=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
printPgmString(PSTR(" (homing cycle, bool)\r\n$26=")); print_uint8_base10(settings.homing_dir_mask);
printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask);
printPgmString(PSTR(")\r\n$28=")); printFloat(settings.homing_feed_rate);
printPgmString(PSTR(" (homing feed, mm/min)\r\n$29=")); printFloat(settings.homing_seek_rate);
printPgmString(PSTR(" (homing seek, mm/min)\r\n$30=")); printInteger(settings.homing_debounce_delay);
printPgmString(PSTR(" (homing debounce, msec)\r\n$31=")); printFloat(settings.homing_pulloff);
printPgmString(PSTR(")\r\n$27=")); printFloat(settings.homing_feed_rate);
printPgmString(PSTR(" (homing feed, mm/min)\r\n$28=")); printFloat(settings.homing_seek_rate);
printPgmString(PSTR(" (homing seek, mm/min)\r\n$29=")); print_uint8_base10(settings.homing_debounce_delay);
printPgmString(PSTR(" (homing debounce, msec)\r\n$30=")); printFloat(settings.homing_pulloff);
printPgmString(PSTR(" (homing pull-off, mm)\r\n"));
}
@ -222,16 +227,11 @@ void report_ngc_parameters()
}
printPgmString(PSTR("[G"));
switch (coord_select) {
case 0: printPgmString(PSTR("54:")); break;
case 1: printPgmString(PSTR("55:")); break;
case 2: printPgmString(PSTR("56:")); break;
case 3: printPgmString(PSTR("57:")); break;
case 4: printPgmString(PSTR("58:")); break;
case 5: printPgmString(PSTR("59:")); break;
case 6: printPgmString(PSTR("28:")); break;
case 7: printPgmString(PSTR("30:")); break;
// case 8: printPgmString(PSTR("92:")); break; // G92.2, G92.3 not supported. Hence not stored.
}
case 6: printPgmString(PSTR("28")); break;
case 7: printPgmString(PSTR("30")); break;
default: print_uint8_base10(coord_select+54); break; // G54-G59
}
printPgmString(PSTR(":"));
for (i=0; i<N_AXIS; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { printFloat(coord_data[i]*INCH_PER_MM); }
else { printFloat(coord_data[i]); }
@ -241,8 +241,8 @@ void report_ngc_parameters()
}
printPgmString(PSTR("[G92:")); // Print G92,G92.1 which are not persistent in memory
for (i=0; i<N_AXIS; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { printFloat(gc.coord_offset[i]*INCH_PER_MM); }
else { printFloat(gc.coord_offset[i]); }
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { printFloat(gc_state.coord_offset[i]*INCH_PER_MM); }
else { printFloat(gc_state.coord_offset[i]); }
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }
else { printPgmString(PSTR("]\r\n")); }
}
@ -253,44 +253,45 @@ void report_ngc_parameters()
// Print current gcode parser mode state
void report_gcode_modes()
{
switch (gc.motion_mode) {
switch (gc_state.modal.motion) {
case MOTION_MODE_SEEK : printPgmString(PSTR("[G0")); break;
case MOTION_MODE_LINEAR : printPgmString(PSTR("[G1")); break;
case MOTION_MODE_CW_ARC : printPgmString(PSTR("[G2")); break;
case MOTION_MODE_CCW_ARC : printPgmString(PSTR("[G3")); break;
case MOTION_MODE_CANCEL : printPgmString(PSTR("[G80")); break;
case MOTION_MODE_NONE : printPgmString(PSTR("[G80")); break;
}
printPgmString(PSTR(" G"));
printInteger(gc.coord_select+54);
print_uint8_base10(gc_state.modal.coord_select+54);
if (gc.plane_axis_0 == X_AXIS) {
if (gc.plane_axis_1 == Y_AXIS) { printPgmString(PSTR(" G17")); }
else { printPgmString(PSTR(" G18")); }
} else { printPgmString(PSTR(" G19")); }
switch (gc_state.modal.plane_select) {
case PLANE_SELECT_XY : printPgmString(PSTR(" G17")); break;
case PLANE_SELECT_ZX : printPgmString(PSTR(" G18")); break;
case PLANE_SELECT_YZ : printPgmString(PSTR(" G19")); break;
}
if (gc.inches_mode) { printPgmString(PSTR(" G20")); }
else { printPgmString(PSTR(" G21")); }
if (gc_state.modal.units == UNITS_MODE_MM) { printPgmString(PSTR(" G21")); }
else { printPgmString(PSTR(" G20")); }
if (gc.absolute_mode) { printPgmString(PSTR(" G90")); }
if (gc_state.modal.distance == DISTANCE_MODE_ABSOLUTE) { printPgmString(PSTR(" G90")); }
else { printPgmString(PSTR(" G91")); }
if (gc.inverse_feed_rate_mode) { printPgmString(PSTR(" G93")); }
if (gc_state.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { printPgmString(PSTR(" G93")); }
else { printPgmString(PSTR(" G94")); }
switch (gc.program_flow) {
switch (gc_state.modal.program_flow) {
case PROGRAM_FLOW_RUNNING : printPgmString(PSTR(" M0")); break;
case PROGRAM_FLOW_PAUSED : printPgmString(PSTR(" M1")); break;
case PROGRAM_FLOW_COMPLETED : printPgmString(PSTR(" M2")); break;
}
switch (gc.spindle_direction) {
switch (gc_state.modal.spindle) {
case SPINDLE_ENABLE_CW : printPgmString(PSTR(" M3")); break;
case SPINDLE_ENABLE_CCW : printPgmString(PSTR(" M4")); break;
case SPINDLE_DISABLE : printPgmString(PSTR(" M5")); break;
}
switch (gc.coolant_mode) {
switch (gc_state.modal.coolant) {
case COOLANT_DISABLE : printPgmString(PSTR(" M9")); break;
case COOLANT_FLOOD_ENABLE : printPgmString(PSTR(" M8")); break;
#ifdef ENABLE_M7
@ -299,11 +300,10 @@ void report_gcode_modes()
}
printPgmString(PSTR(" T"));
printInteger(gc.tool);
print_uint8_base10(gc_state.tool);
printPgmString(PSTR(" F"));
if (gc.inches_mode) { printFloat(gc.feed_rate*INCH_PER_MM); }
else { printFloat(gc.feed_rate); }
printFloat(gc_state.feed_rate);
printPgmString(PSTR("]\r\n"));
}
@ -311,7 +311,7 @@ void report_gcode_modes()
// Prints specified startup line
void report_startup_line(uint8_t n, char *line)
{
printPgmString(PSTR("$N")); printInteger(n);
printPgmString(PSTR("$N")); print_uint8_base10(n);
printPgmString(PSTR("=")); printString(line);
printPgmString(PSTR("\r\n"));
}
@ -366,9 +366,9 @@ void report_realtime_status()
printPgmString(PSTR("WPos:"));
for (i=0; i< N_AXIS; i++) {
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
print_position[i] -= (gc.coord_system[i]+gc.coord_offset[i])*INCH_PER_MM;
print_position[i] -= (gc_state.coord_system[i]+gc_state.coord_offset[i])*INCH_PER_MM;
} else {
print_position[i] -= gc.coord_system[i]+gc.coord_offset[i];
print_position[i] -= gc_state.coord_system[i]+gc_state.coord_offset[i];
}
printFloat(print_position[i]);
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); }