diff --git a/gcode.c b/gcode.c index a4a8e70..8557956 100644 --- a/gcode.c +++ b/gcode.c @@ -92,7 +92,7 @@ uint8_t gc_execute_line(char *line) memset(&gc_block, 0, sizeof(gc_block)); // Initialize the parser block struct. memcpy(&gc_block.modal,&gc_state.modal,sizeof(gc_modal_t)); // Copy current modes - uint8_t axis_explicit = AXIS_COMMAND_NONE; + uint8_t axis_command = AXIS_COMMAND_NONE; uint8_t axis_0, axis_1, axis_linear; float coordinate_data[N_AXIS]; // Multi-use variable to store coordinate data for execution float parameter_data[N_AXIS]; // Multi-use variable to store parameter data for execution @@ -149,8 +149,8 @@ uint8_t gc_execute_line(char *line) case 10: case 28: case 30: case 92: // Check for G10/28/30/92 being called with G0/1/2/3/38 on same block. if (mantissa == 0) { // Ignore G28.1, G30.1, and G92.1 - if (axis_explicit) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] - axis_explicit = AXIS_COMMAND_NON_MODAL; + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] + axis_command = AXIS_COMMAND_NON_MODAL; } // No break. Continues to next line. case 4: case 53: @@ -187,8 +187,8 @@ uint8_t gc_execute_line(char *line) break; case 0: case 1: case 2: case 3: case 38: // Check for G0/1/2/3/38 being called with G10/28/30/92 on same block. - if (axis_explicit) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] - axis_explicit = AXIS_COMMAND_MOTION_MODE; + if (axis_command) { FAIL(STATUS_GCODE_AXIS_COMMAND_CONFLICT); } // [Axis word/command conflict] + axis_command = AXIS_COMMAND_MOTION_MODE; // No break. Continues to next line. case 80: word_bit = MODAL_GROUP_G1; @@ -363,21 +363,10 @@ uint8_t gc_execute_line(char *line) // [0. Non-specific/common error-checks and miscellaneous setup]: - // Determine how axis words are used and error-check it. Apply implicit conditions and exceptions. - if (axis_explicit) { // Either a non-modal or motion mode axis-explicit command has been passed. - // Axis-words are required (with exceptions) with axis-explicit commands. - // NOTE: G28/30 reserve any axis words as an intermediate motion, but are not required. G2/3 full - // circle arcs don't require axis words, but this aren't supported. - if (!axis_words) { - if ((gc_block.non_modal_command == NON_MODAL_GO_HOME_0) || (gc_block.non_modal_command == NON_MODAL_GO_HOME_1)) { - axis_explicit = AXIS_COMMAND_NONE; // No axis words passed for G28/30. - } else { - FAIL(STATUS_GCODE_NO_AXIS_WORDS); // [No axis words] - } - } - } else { - // If no axis-explicit commands in the block, axis words implicitly activate the current motion mode. - if (axis_words) { axis_explicit = AXIS_COMMAND_MOTION_MODE; } // Assign implicit motion-mode + // Determine implicit axis command conditions. Axis words have been passed, but no explicit axis + // command has been sent. If so, set axis command to current motion mode. + if (axis_words) { + if (!axis_command) { axis_command = AXIS_COMMAND_MOTION_MODE; } // Assign implicit motion-mode } // Check for valid line number N value. @@ -391,7 +380,7 @@ uint8_t gc_execute_line(char *line) // NOTE: Single-meaning value words are removed all at once at the end of error-checking, because // they are always used when present. This was done to save a few bytes of flash. For clarity, the // single-meaning value words may be removed as they are used. Also, axis words are treated in the - // same way. If there is an axis explicit/implicit command, XYZ words are always used and are + // same way. If there is an explicit/implicit axis command, XYZ words are always used and are // are removed at the end of error-checking. // [1. Comments ]: MSG's NOT SUPPORTED. Comment handling performed by protocol. @@ -400,7 +389,7 @@ uint8_t gc_execute_line(char *line) // is not defined after switching to G94 from G93. if (gc_block.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { // = G93 // NOTE: G38 can also operate in inverse time, but is undefined as an error. Missing F word check added here. - if (axis_explicit == AXIS_COMMAND_MOTION_MODE) { + if (axis_command == AXIS_COMMAND_MOTION_MODE) { if ((gc_block.modal.motion != MOTION_MODE_NONE) || (gc_block.modal.motion != MOTION_MODE_SEEK)) { if (bit_isfalse(value_words,bit(WORD_F))) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [F word missing] } @@ -497,15 +486,16 @@ uint8_t gc_execute_line(char *line) // [18. Set retract mode ]: NOT SUPPORTED. // [19. Remaining non-modal actions ]: Check go to predefined position, set G10, or set axis offsets. - // NOTE: We need to separate the non-modal commands that are axis-explicit (G10/G28/G30/G92), as these + // NOTE: We need to separate the non-modal commands that are axis word-using (G10/G28/G30/G92), as these // commands all treat axis words differently. G10 as absolute offsets or computes current position as // the axis value, G92 similarly to G10 L20, and G28/30 as an intermediate target position that observes // all the current coordinate system and G92 offsets. switch (gc_block.non_modal_command) { case NON_MODAL_SET_COORDINATE_DATA: // [G10 Errors]: L missing and is not 2 or 20. P word missing. (Negative P value done.) - // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing (done.) - // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing (done.) + // [G10 L2 Errors]: R word NOT SUPPORTED. P value not 0 to nCoordSys(max 9). Axis words missing. + // [G10 L20 Errors]: P must be 0 to nCoordSys(max 9). Axis words missing. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS) }; // [No axis words] if (bit_isfalse(value_words,((1< N_COORDINATE_SYSTEM) { FAIL(STATUS_GCODE_UNSUPPORTED_COORD_SYS); } // [Greater than N sys] @@ -533,7 +523,8 @@ uint8_t gc_execute_line(char *line) } break; case NON_MODAL_SET_COORDINATE_OFFSET: - // [G92 Errors]: No axis words (done.) + // [G92 Errors]: No axis words. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] // Update axes defined only in block. Offsets current system to defined value. Does not update when // active coordinate system is selected, but is still active unless G92.1 disables it. @@ -548,7 +539,7 @@ uint8_t gc_execute_line(char *line) default: - // At this point, the rest of the axis-explicit commands treat the axis values as the traditional + // At this point, the rest of the explicit axis commands treat the axis values as the traditional // target position with the coordinate system offsets, G92 offsets, absolute override, and distance // modes applied. This includes the motion mode commands. We can now pre-compute the target position. // NOTE: Tool offsets may be appended to these conversions when/if this feature is added. @@ -603,26 +594,31 @@ uint8_t gc_execute_line(char *line) // [20. Motion modes ]: if (gc_block.modal.motion == MOTION_MODE_NONE) { // [G80 Errors]: Axis word exist and are not used by a non-modal command. - if ((axis_words) && (axis_explicit != AXIS_COMMAND_NON_MODAL)) { + if ((axis_words) && (axis_command != AXIS_COMMAND_NON_MODAL)) { FAIL(STATUS_GCODE_AXIS_WORDS_EXIST); // [No axis words allowed] } // Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or // was explicitly commanded in the g-code block. - } else if ( axis_explicit == AXIS_COMMAND_MOTION_MODE ) { + } else if ( axis_command == AXIS_COMMAND_MOTION_MODE ) { - // [G0 Errors]: (All done!) No axis words. Axis letter not configured or without real value. + if (gc_block.modal.motion == MOTION_MODE_SEEK) { + // [G0 Errors]: Axis letter not configured or without real value (done.) + // Axis words are optional. If missing, set axis command flag to ignore execution. + if (!axis_words) { axis_command = AXIS_COMMAND_NONE; } // All remaining motion modes (all but G0 and G80), require a valid feed rate value. In units per mm mode, // the value must be positive. In inverse time mode, a positive value must be passed with each block. - if (gc_block.modal.motion != MOTION_MODE_SEEK) { - + } else { // Check if feed rate is defined for the motion modes that require it. if (gc_block.values.f == 0.0) { FAIL(STATUS_GCODE_UNDEFINED_FEED_RATE); } // [Feed rate undefined] switch (gc_block.modal.motion) { case MOTION_MODE_LINEAR: - // [G1 Errors]: (All done!) No axis words and feed rate undefined. Axis letter not configured or without real value. + // [G1 Errors]: Feed rate undefined. Axis letter not configured or without real value. + // Axis words are optional. If missing, set axis command flag to ignore execution. + if (!axis_words) { axis_command = AXIS_COMMAND_NONE; } + break; case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: // [G2/3 Errors All-Modes]: Feed rate undefined. @@ -632,6 +628,7 @@ uint8_t gc_execute_line(char *line) // [G2/3 Full-Circle-Mode Errors]: NOT SUPPORTED. Axis words exist. No offsets programmed. P must be an integer. // NOTE: Both radius and offsets are required for arc tracing and are pre-computed with the error-checking. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] if (!(axis_words & (bit(axis_0)|bit(axis_1)))) { FAIL(STATUS_GCODE_NO_AXIS_WORDS_IN_PLANE); } // [No axis words in plane] // Calculate the change in position along each selected axis @@ -760,6 +757,7 @@ uint8_t gc_execute_line(char *line) case MOTION_MODE_PROBE: // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate // is undefined. Probe is triggered. + if (!axis_words) { FAIL(STATUS_GCODE_NO_AXIS_WORDS); } // [No axis words] if (gc_check_same_position(gc_state.position, gc_block.values.xyz)) { FAIL(STATUS_GCODE_INVALID_TARGET); } // [Invalid target] if (probe_get_state()) { FAIL(STATUS_GCODE_PROBE_TRIGGERED); } // [Probe triggered] break; @@ -772,7 +770,7 @@ uint8_t gc_execute_line(char *line) // [0. Non-specific error-checks]: Complete unused value words check, i.e. IJK used when in arc // radius mode, or axis words that aren't used in the block. bit_false(value_words,(bit(WORD_N)|bit(WORD_F)|bit(WORD_S)|bit(WORD_T))); // Remove single-meaning value words. - if (axis_explicit) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words. + if (axis_command) { bit_false(value_words,(bit(WORD_X)|bit(WORD_Y)|bit(WORD_Z))); } // Remove axis words. if (value_words) { FAIL(STATUS_GCODE_UNUSED_WORDS); } // [Unused words] @@ -859,7 +857,7 @@ uint8_t gc_execute_line(char *line) case NON_MODAL_GO_HOME_0: case NON_MODAL_GO_HOME_1: // Move to intermediate position before going home. Obeys current coordinate system and offsets // and absolute and incremental modes. - if (axis_explicit) { + if (axis_command) { #ifdef USE_LINE_NUMBERS mc_line(gc_block.values.xyz, -1.0, false, gc_block.values.n); #else @@ -893,7 +891,7 @@ uint8_t gc_execute_line(char *line) // Enter motion modes only if there are axis words or a motion mode command word in the block. gc_state.modal.motion = gc_block.modal.motion; if (gc_state.modal.motion != MOTION_MODE_NONE) { - if (axis_explicit == AXIS_COMMAND_MOTION_MODE) { + if (axis_command == AXIS_COMMAND_MOTION_MODE) { switch (gc_state.modal.motion) { case MOTION_MODE_SEEK: #ifdef USE_LINE_NUMBERS