More cleanup
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Wed, 6 Jan 2016 07:22:44 +0000 (23:22 -0800)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Wed, 6 Jan 2016 07:22:44 +0000 (23:22 -0800)
src/config_app.c
src/gcode_parser.c
src/hardware.c
src/hardware.h
src/persistence.c
src/settings/settings_default.h
src/status.c
src/stepper.c
src/text_parser.c
src/util.c

index 3c4e8ee54fd03ae80b42a3c9fdc20e3c23bba0b1..c33e06096e2c79f20c97700885136d34c6caa143 100644 (file)
@@ -100,6 +100,7 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"mst", "mst2", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
   {"mst", "mst3", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
   {"mst", "mst4", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
+
   {"mfl", "mfl1", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
   {"mfl", "mfl2", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
   {"mfl", "mfl3", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
@@ -672,7 +673,7 @@ uint8_t nv_index_lt_groups(index_t index) {return (index <= NV_INDEX_START_GROUP
 
 
 /*
- * Det floating point number with G20/G21 units conversion
+ * Set floating point number with G20/G21 units conversion
  *
  * The number 'setted' will have been delivered in external units (inches or mm).
  * It is written to the target memory location in internal canonical units (mm).
index 6d8ec237748cce543754e28df4559240e89a12a0..7185d7f92b719c0f0d40374c59b4c9a4c9389ae6 100644 (file)
@@ -16,7 +16,7 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "tinyg.h"            // #1
+#include "tinyg.h"             // #1
 #include "config.h"            // #2
 #include "controller.h"
 #include "gcode_parser.h"
@@ -24,8 +24,8 @@
 #include "spindle.h"
 #include "util.h"
 
-struct gcodeParserSingleton {           // struct to manage globals
-    uint8_t modals[MODAL_GROUP_COUNT];// collects modal groups in a block
+struct gcodeParserSingleton {          // struct to manage globals
+  uint8_t modals[MODAL_GROUP_COUNT]; // collects modal groups in a block
 }; struct gcodeParserSingleton gp;
 
 // local helper functions and macros
@@ -40,36 +40,33 @@ static stat_t _execute_gcode_block();        // Execute the gcode block
 #define SET_NON_MODAL(parm,val) ({cm.gn.parm=val; cm.gf.parm=1; break;})
 #define EXEC_FUNC(f,v) if((uint8_t)cm.gf.v != false) { status = f(cm.gn.v);}
 
-/*
- * gc_gcode_parser() - parse a block (line) of gcode
- *
- *    Top level of gcode parser. Normalizes block and looks for special cases
- */
-stat_t gc_gcode_parser(char_t *block)
-{
-    char_t *str = block;                    // gcode command or 0 string
-    char_t none = 0;
-    char_t *com = &none;                    // gcode comment or 0 string
-    char_t *msg = &none;                    // gcode message or 0 string
-    uint8_t block_delete_flag;
+/// Parse a block (line) of gcode
+/// Top level of gcode parser. Normalizes block and looks for special cases
+stat_t gc_gcode_parser(char_t *block) {
+  char_t *str = block;                    // gcode command or 0 string
+  char_t none = 0;
+  char_t *com = &none;                    // gcode comment or 0 string
+  char_t *msg = &none;                    // gcode message or 0 string
+  uint8_t block_delete_flag;
 
-    // don't process Gcode blocks if in alarmed state
-    if (cm.machine_state == MACHINE_ALARM) return STAT_MACHINE_ALARMED;
+  // don't process Gcode blocks if in alarmed state
+  if (cm.machine_state == MACHINE_ALARM) return STAT_MACHINE_ALARMED;
 
-    _normalize_gcode_block(str, &com, &msg, &block_delete_flag);
+  _normalize_gcode_block(str, &com, &msg, &block_delete_flag);
 
-    // Block delete omits the line if a / char is present in the first space
-    // For now this is unconditional and will always delete
-    if (block_delete_flag) return STAT_NOOP;
+  // Block delete omits the line if a / char is present in the first space
+  // For now this is unconditional and will always delete
+  if (block_delete_flag) return STAT_NOOP;
 
-    // queue a "(MSG" response
-    if (*msg) cm_message(msg);                // queue the message
+  // queue a "(MSG" response
+  if (*msg) cm_message(msg);                // queue the message
 
-    return _parse_gcode_block(block);
+  return _parse_gcode_block(block);
 }
 
+
 /*
- * _normalize_gcode_block() - normalize a block (line) of gcode in place
+ * Normalize a block (line) of gcode in place
  *
  *    Normalization functions:
  *   - convert all letters to upper case
@@ -105,122 +102,111 @@ stat_t gc_gcode_parser(char_t *block)
  *     - block_delete_flag is set true if block delete encountered, false otherwise
  */
 
-static void _normalize_gcode_block(char_t *str, char_t **com, char_t **msg, uint8_t *block_delete_flag)
-{
-    char_t *rd = str;                // read pointer
-    char_t *wr = str;                // write pointer
-
-    // Preset comments and messages to 0 string
-    // Not required if com and msg already point to 0 on entry
-//    for (rd = str; *rd != 0; rd++) { if (*rd == 0) { *com = rd; *msg = rd; rd = str;} }
-
-    // mark block deletes
-    if (*rd == '/') { *block_delete_flag = true; }
-    else { *block_delete_flag = false; }
-
-    // normalize the command block & find the comment (if any)
-    for (; *wr != 0; rd++) {
-        if (*rd == 0) { *wr = 0; }
-        else if ((*rd == '(') || (*rd == ';')) { *wr = 0; *com = rd+1; }
-        else if ((isalnum((char)*rd)) || (strchr("-.", *rd))) { // all valid characters
-            *(wr++) = (char_t)toupper((char)*(rd));
-        }
-    }
+static void _normalize_gcode_block(char_t *str, char_t **com, char_t **msg, uint8_t *block_delete_flag) {
+  char_t *rd = str;                // read pointer
+  char_t *wr = str;                // write pointer
 
-    // Perform Octal stripping - remove invalid leading zeros in number strings
-    rd = str;
-    while (*rd != 0) {
-        if (*rd == '.') break;                            // don't strip past a decimal point
-        if ((!isdigit(*rd)) && (*(rd+1) == '0') && (isdigit(*(rd+2)))) {
-            wr = rd+1;
-            while (*wr != 0) { *wr = *(wr+1); wr++;}    // copy forward w/overwrite
-            continue;
-        }
-        rd++;
-    }
+  // mark block deletes
+  if (*rd == '/') { *block_delete_flag = true; }
+  else { *block_delete_flag = false; }
 
-    // process comments and messages
-    if (**com != 0) {
-        rd = *com;
-        while (isspace(*rd)) { rd++; }        // skip any leading spaces before "msg"
-        if ((tolower(*rd) == 'm') && (tolower(*(rd+1)) == 's') && (tolower(*(rd+2)) == 'g')) {
-            *msg = rd+3;
-        }
-        for (; *rd != 0; rd++) {
-            if (*rd == ')') *rd = 0;        // 0 terminate on trailing parenthesis, if any
-        }
+  // normalize the command block & find the comment (if any)
+  for (; *wr != 0; rd++) {
+    if (*rd == 0) { *wr = 0; }
+    else if ((*rd == '(') || (*rd == ';')) { *wr = 0; *com = rd+1; }
+    else if ((isalnum((char)*rd)) || (strchr("-.", *rd))) { // all valid characters
+      *(wr++) = (char_t)toupper((char)*(rd));
     }
+  }
+
+  // Perform Octal stripping - remove invalid leading zeros in number strings
+  rd = str;
+  while (*rd != 0) {
+    if (*rd == '.') break;                            // don't strip past a decimal point
+    if ((!isdigit(*rd)) && (*(rd + 1) == '0') && (isdigit(*(rd + 2)))) {
+      wr = rd + 1;
+      while (*wr != 0) {*wr = *(wr + 1); wr++;}    // copy forward w/overwrite
+      continue;
+    }
+    rd++;
+  }
+
+  // process comments and messages
+  if (**com != 0) {
+    rd = *com;
+    while (isspace(*rd)) { rd++; }        // skip any leading spaces before "msg"
+    if ((tolower(*rd) == 'm') && (tolower(*(rd+1)) == 's') && (tolower(*(rd+2)) == 'g'))
+      *msg = rd + 3;
+
+    for (; *rd != 0; rd++)
+      if (*rd == ')') *rd = 0;        // 0 terminate on trailing parenthesis, if any
+  }
 }
 
+
 /*
- * _get_next_gcode_word() - get gcode word consisting of a letter and a value
+ * Get gcode word consisting of a letter and a value
  *
  *    This function requires the Gcode string to be normalized.
  *    Normalization must remove any leading zeros or they will be converted to Octal
  *    G0X... is not interpreted as hexadecimal. This is trapped.
  */
-static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
-{
-    if (**pstr == 0)
-        return STAT_COMPLETE;    // no more words to process
-
-    // get letter part
-    if(isupper(**pstr) == false)
-        return STAT_INVALID_OR_MALFORMED_COMMAND;
-    *letter = **pstr;
+static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value) {
+  if (**pstr == 0) return STAT_COMPLETE;    // no more words to process
+
+  // get letter part
+  if(isupper(**pstr) == false)
+    return STAT_INVALID_OR_MALFORMED_COMMAND;
+  *letter = **pstr;
+  (*pstr)++;
+
+  // X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255
+  if ((**pstr == '0') && (*(*pstr+1) == 'X')) {
+    *value = 0;
     (*pstr)++;
+    return STAT_OK;        // pointer points to X
+  }
 
-    // X-axis-becomes-a-hexadecimal-number get-value case, e.g. G0X100 --> G255
-    if ((**pstr == '0') && (*(*pstr+1) == 'X')) {
-        *value = 0;
-        (*pstr)++;
-        return STAT_OK;        // pointer points to X
-    }
+  // get-value general case
+  char *end;
+  *value = strtof(*pstr, &end);
+  if (end == *pstr) return STAT_BAD_NUMBER_FORMAT; // more robust test then checking for value=0;
+  *pstr = end;
 
-    // get-value general case
-    char *end;
-    *value = strtof(*pstr, &end);
-    if(end == *pstr)
-        return STAT_BAD_NUMBER_FORMAT; // more robust test then checking for value=0;
-    *pstr = end;
-    return STAT_OK;            // pointer points to next character after the word
+  return STAT_OK;            // pointer points to next character after the word
 }
 
-/*
- * _point() - isolate the decimal point value as an integer
- */
-static uint8_t _point(float value)
-{
-    return (uint8_t)(value*10 - trunc(value)*10);    // isolate the decimal point as an int
+
+/// Isolate the decimal point value as an integer
+static uint8_t _point(float value) {
+  return (uint8_t)(value * 10 - trunc(value) * 10);    // isolate the decimal point as an int
 }
 
-/*
- * _validate_gcode_block() - check for some gross Gcode block semantic violations
- */
 
-static stat_t _validate_gcode_block()
-{
-    //    Check for modal group violations. From NIST, section 3.4 "It is an error to put
-    //    a G-code from group 1 and a G-code from group 0 on the same line if both of them
-    //    use axis words. If an axis word-using G-code from group 1 is implicitly in effect
-    //    on a line (by having been activated on an earlier line), and a group 0 G-code that
-    //    uses axis words appears on the line, the activity of the group 1 G-code is suspended
-    //    for that line. The axis word-using G-codes from group 0 are G10, G28, G30, and G92"
-
-//    if ((gp.modals[MODAL_GROUP_G0] == true) && (gp.modals[MODAL_GROUP_G1] == true)) {
-//        return STAT_MODAL_GROUP_VIOLATION;
-//    }
-
-    // look for commands that require an axis word to be present
-//    if ((gp.modals[MODAL_GROUP_G0] == true) || (gp.modals[MODAL_GROUP_G1] == true)) {
-//        if (_axis_changed() == false)
-//        return STAT_GCODE_AXIS_IS_MISSING;
-//    }
-    return STAT_OK;
+/// Check for some gross Gcode block semantic violations
+static stat_t _validate_gcode_block() {
+  //    Check for modal group violations. From NIST, section 3.4 "It is an error to put
+  //    a G-code from group 1 and a G-code from group 0 on the same line if both of them
+  //    use axis words. If an axis word-using G-code from group 1 is implicitly in effect
+  //    on a line (by having been activated on an earlier line), and a group 0 G-code that
+  //    uses axis words appears on the line, the activity of the group 1 G-code is suspended
+  //    for that line. The axis word-using G-codes from group 0 are G10, G28, G30, and G92"
+
+  //    if ((gp.modals[MODAL_GROUP_G0] == true) && (gp.modals[MODAL_GROUP_G1] == true)) {
+  //        return STAT_MODAL_GROUP_VIOLATION;
+  //    }
+
+  // look for commands that require an axis word to be present
+  //    if ((gp.modals[MODAL_GROUP_G0] == true) || (gp.modals[MODAL_GROUP_G1] == true)) {
+  //        if (_axis_changed() == false)
+  //        return STAT_GCODE_AXIS_IS_MISSING;
+  //    }
+  return STAT_OK;
 }
 
+
 /*
- * _parse_gcode_block() - parses one line of 0 terminated G-Code.
+ * Parses one line of 0 terminated G-Code.
  *
  *    All the parser does is load the state values in gn (next model state) and set flags
  *    in gf (model state flags). The execute routine applies them. The buffer is assumed to
@@ -229,169 +215,171 @@ static stat_t _validate_gcode_block()
  *    A number of implicit things happen when the gn struct is zeroed:
  *      - inverse feed rate mode is canceled - set back to units_per_minute mode
  */
-static stat_t _parse_gcode_block(char_t *buf)
-{
-    char *pstr = (char *)buf;        // persistent pointer into gcode block for parsing words
-      char letter;                    // parsed letter, eg.g. G or X or Y
-    float value = 0;                // value parsed from letter (e.g. 2 for G2)
-    stat_t status = STAT_OK;
-
-    // set initial state for new move
-    memset(&gp, 0, sizeof(gp));                        // clear all parser values
-    memset(&cm.gf, 0, sizeof(GCodeInput_t));        // clear all next-state flags
-    memset(&cm.gn, 0, sizeof(GCodeInput_t));        // clear all next-state values
-    cm.gn.motion_mode = cm_get_motion_mode(MODEL);    // get motion mode from previous block
-
-    // extract commands and parameters
-    while((status = _get_next_gcode_word(&pstr, &letter, &value)) == STAT_OK) {
-        switch(letter) {
-            case 'G':
-            switch((uint8_t)value) {
-                case 0:  SET_MODAL (MODAL_GROUP_G1, motion_mode, MOTION_MODE_STRAIGHT_TRAVERSE);
-                case 1:  SET_MODAL (MODAL_GROUP_G1, motion_mode, MOTION_MODE_STRAIGHT_FEED);
-                case 2:  SET_MODAL (MODAL_GROUP_G1, motion_mode, MOTION_MODE_CW_ARC);
-                case 3:  SET_MODAL (MODAL_GROUP_G1, motion_mode, MOTION_MODE_CCW_ARC);
-                case 4:  SET_NON_MODAL (next_action, NEXT_ACTION_DWELL);
-                case 10: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_COORD_DATA);
-                case 17: SET_MODAL (MODAL_GROUP_G2, select_plane, CANON_PLANE_XY);
-                case 18: SET_MODAL (MODAL_GROUP_G2, select_plane, CANON_PLANE_XZ);
-                case 19: SET_MODAL (MODAL_GROUP_G2, select_plane, CANON_PLANE_YZ);
-                case 20: SET_MODAL (MODAL_GROUP_G6, units_mode, INCHES);
-                case 21: SET_MODAL (MODAL_GROUP_G6, units_mode, MILLIMETERS);
-                case 28: {
-                    switch (_point(value)) {
-                        case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G28_POSITION);
-                        case 1: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_G28_POSITION);
-                        case 2: SET_NON_MODAL (next_action, NEXT_ACTION_SEARCH_HOME);
-                        case 3: SET_NON_MODAL (next_action, NEXT_ACTION_SET_ABSOLUTE_ORIGIN);
-                        case 4: SET_NON_MODAL (next_action, NEXT_ACTION_HOMING_NO_SET);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 30: {
-                    switch (_point(value)) {
-                        case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G30_POSITION);
-                        case 1: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_G30_POSITION);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 38: {
-                    switch (_point(value)) {
-                        case 2: SET_NON_MODAL (next_action, NEXT_ACTION_STRAIGHT_PROBE);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 40: break;    // ignore cancel cutter radius compensation
-                case 49: break;    // ignore cancel tool length offset comp.
-                case 53: SET_NON_MODAL (absolute_override, true);
-                case 54: SET_MODAL (MODAL_GROUP_G12, coord_system, G54);
-                case 55: SET_MODAL (MODAL_GROUP_G12, coord_system, G55);
-                case 56: SET_MODAL (MODAL_GROUP_G12, coord_system, G56);
-                case 57: SET_MODAL (MODAL_GROUP_G12, coord_system, G57);
-                case 58: SET_MODAL (MODAL_GROUP_G12, coord_system, G58);
-                case 59: SET_MODAL (MODAL_GROUP_G12, coord_system, G59);
-                case 61: {
-                    switch (_point(value)) {
-                        case 0: SET_MODAL (MODAL_GROUP_G13, path_control, PATH_EXACT_PATH);
-                        case 1: SET_MODAL (MODAL_GROUP_G13, path_control, PATH_EXACT_STOP);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 64: SET_MODAL (MODAL_GROUP_G13,path_control, PATH_CONTINUOUS);
-                case 80: SET_MODAL (MODAL_GROUP_G1, motion_mode,  MOTION_MODE_CANCEL_MOTION_MODE);
-//                case 90: SET_MODAL (MODAL_GROUP_G3, distance_mode, ABSOLUTE_MODE);
-//                case 91: SET_MODAL (MODAL_GROUP_G3, distance_mode, INCREMENTAL_MODE);
-                case 90: {
-                    switch (_point(value)) {
-                        case 0: SET_MODAL (MODAL_GROUP_G3, distance_mode, ABSOLUTE_MODE);
-                        case 1: SET_MODAL (MODAL_GROUP_G3, arc_distance_mode, ABSOLUTE_MODE);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 91: {
-                    switch (_point(value)) {
-                        case 0: SET_MODAL (MODAL_GROUP_G3, distance_mode, INCREMENTAL_MODE);
-                        case 1: SET_MODAL (MODAL_GROUP_G3, arc_distance_mode, INCREMENTAL_MODE);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 92: {
-                    switch (_point(value)) {
-                        case 0: SET_MODAL (MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_ORIGIN_OFFSETS);
-                        case 1: SET_NON_MODAL (next_action, NEXT_ACTION_RESET_ORIGIN_OFFSETS);
-                        case 2: SET_NON_MODAL (next_action, NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS);
-                        case 3: SET_NON_MODAL (next_action, NEXT_ACTION_RESUME_ORIGIN_OFFSETS);
-                        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-                    }
-                    break;
-                }
-                case 93: SET_MODAL (MODAL_GROUP_G5, feed_rate_mode, INVERSE_TIME_MODE);
-                case 94: SET_MODAL (MODAL_GROUP_G5, feed_rate_mode, UNITS_PER_MINUTE_MODE);
-//                case 95: SET_MODAL (MODAL_GROUP_G5, feed_rate_mode, UNITS_PER_REVOLUTION_MODE);
-                default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
-            }
-            break;
-
-            case 'M':
-            switch((uint8_t)value) {
-                case 0: case 1: case 60:
-                        SET_MODAL (MODAL_GROUP_M4, program_flow, PROGRAM_STOP);
-                case 2: case 30:
-                        SET_MODAL (MODAL_GROUP_M4, program_flow, PROGRAM_END);
-                case 3: SET_MODAL (MODAL_GROUP_M7, spindle_mode, SPINDLE_CW);
-                case 4: SET_MODAL (MODAL_GROUP_M7, spindle_mode, SPINDLE_CCW);
-                case 5: SET_MODAL (MODAL_GROUP_M7, spindle_mode, SPINDLE_OFF);
-                case 6: SET_NON_MODAL (tool_change, true);
-                case 7: SET_MODAL (MODAL_GROUP_M8, mist_coolant, true);
-                case 8: SET_MODAL (MODAL_GROUP_M8, flood_coolant, true);
-                case 9: SET_MODAL (MODAL_GROUP_M8, flood_coolant, false);
-                case 48: SET_MODAL (MODAL_GROUP_M9, override_enables, true);
-                case 49: SET_MODAL (MODAL_GROUP_M9, override_enables, false);
-                case 50: SET_MODAL (MODAL_GROUP_M9, feed_rate_override_enable, true); // conditionally true
-                case 51: SET_MODAL (MODAL_GROUP_M9, spindle_override_enable, true);      // conditionally true
-                default: status = STAT_MCODE_COMMAND_UNSUPPORTED;
-            }
-            break;
-
-            case 'T': SET_NON_MODAL (tool_select, (uint8_t)trunc(value));
-            case 'F': SET_NON_MODAL (feed_rate, value);
-            case 'P': SET_NON_MODAL (parameter, value);                // used for dwell time, G10 coord select, rotations
-            case 'S': SET_NON_MODAL (spindle_speed, value);
-            case 'X': SET_NON_MODAL (target[AXIS_X], value);
-            case 'Y': SET_NON_MODAL (target[AXIS_Y], value);
-            case 'Z': SET_NON_MODAL (target[AXIS_Z], value);
-            case 'A': SET_NON_MODAL (target[AXIS_A], value);
-            case 'B': SET_NON_MODAL (target[AXIS_B], value);
-            case 'C': SET_NON_MODAL (target[AXIS_C], value);
-        //    case 'U': SET_NON_MODAL (target[AXIS_U], value);        // reserved
-        //    case 'V': SET_NON_MODAL (target[AXIS_V], value);        // reserved
-        //    case 'W': SET_NON_MODAL (target[AXIS_W], value);        // reserved
-            case 'I': SET_NON_MODAL (arc_offset[0], value);
-            case 'J': SET_NON_MODAL (arc_offset[1], value);
-            case 'K': SET_NON_MODAL (arc_offset[2], value);
-            case 'R': SET_NON_MODAL (arc_radius, value);
-            case 'N': SET_NON_MODAL (linenum,(uint32_t)value);        // line number
-            case 'L': break;                                        // not used for anything
-            default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+static stat_t _parse_gcode_block(char_t *buf) {
+  char *pstr = (char *)buf;       // persistent pointer into gcode block for parsing words
+  char letter;                    // parsed letter, eg.g. G or X or Y
+  float value = 0;                // value parsed from letter (e.g. 2 for G2)
+  stat_t status = STAT_OK;
+
+  // set initial state for new move
+  memset(&gp, 0, sizeof(gp));                     // clear all parser values
+  memset(&cm.gf, 0, sizeof(GCodeInput_t));        // clear all next-state flags
+  memset(&cm.gn, 0, sizeof(GCodeInput_t));        // clear all next-state values
+  cm.gn.motion_mode = cm_get_motion_mode(MODEL);  // get motion mode from previous block
+
+  // extract commands and parameters
+  while((status = _get_next_gcode_word(&pstr, &letter, &value)) == STAT_OK) {
+    switch(letter) {
+    case 'G':
+      switch((uint8_t)value) {
+      case 0:  SET_MODAL(MODAL_GROUP_G1, motion_mode, MOTION_MODE_STRAIGHT_TRAVERSE);
+      case 1:  SET_MODAL(MODAL_GROUP_G1, motion_mode, MOTION_MODE_STRAIGHT_FEED);
+      case 2:  SET_MODAL(MODAL_GROUP_G1, motion_mode, MOTION_MODE_CW_ARC);
+      case 3:  SET_MODAL(MODAL_GROUP_G1, motion_mode, MOTION_MODE_CCW_ARC);
+      case 4:  SET_NON_MODAL(next_action, NEXT_ACTION_DWELL);
+      case 10: SET_MODAL(MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_COORD_DATA);
+      case 17: SET_MODAL(MODAL_GROUP_G2, select_plane, CANON_PLANE_XY);
+      case 18: SET_MODAL(MODAL_GROUP_G2, select_plane, CANON_PLANE_XZ);
+      case 19: SET_MODAL(MODAL_GROUP_G2, select_plane, CANON_PLANE_YZ);
+      case 20: SET_MODAL(MODAL_GROUP_G6, units_mode, INCHES);
+      case 21: SET_MODAL(MODAL_GROUP_G6, units_mode, MILLIMETERS);
+      case 28:
+        switch (_point(value)) {
+        case 0: SET_MODAL(MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G28_POSITION);
+        case 1: SET_MODAL(MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_G28_POSITION);
+        case 2: SET_NON_MODAL(next_action, NEXT_ACTION_SEARCH_HOME);
+        case 3: SET_NON_MODAL(next_action, NEXT_ACTION_SET_ABSOLUTE_ORIGIN);
+        case 4: SET_NON_MODAL(next_action, NEXT_ACTION_HOMING_NO_SET);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
         }
-        if(status != STAT_OK) break;
+        break;
+
+      case 30:
+        switch (_point(value)) {
+        case 0: SET_MODAL(MODAL_GROUP_G0, next_action, NEXT_ACTION_GOTO_G30_POSITION);
+        case 1: SET_MODAL(MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_G30_POSITION);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+        }
+        break;
+
+      case 38:
+        switch (_point(value)) {
+        case 2: SET_NON_MODAL(next_action, NEXT_ACTION_STRAIGHT_PROBE);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+        }
+        break;
+
+      case 40: break; // ignore cancel cutter radius compensation
+      case 49: break; // ignore cancel tool length offset comp.
+      case 53: SET_NON_MODAL(absolute_override, true);
+      case 54: SET_MODAL(MODAL_GROUP_G12, coord_system, G54);
+      case 55: SET_MODAL(MODAL_GROUP_G12, coord_system, G55);
+      case 56: SET_MODAL(MODAL_GROUP_G12, coord_system, G56);
+      case 57: SET_MODAL(MODAL_GROUP_G12, coord_system, G57);
+      case 58: SET_MODAL(MODAL_GROUP_G12, coord_system, G58);
+      case 59: SET_MODAL(MODAL_GROUP_G12, coord_system, G59);
+      case 61:
+        switch (_point(value)) {
+        case 0: SET_MODAL(MODAL_GROUP_G13, path_control, PATH_EXACT_PATH);
+        case 1: SET_MODAL(MODAL_GROUP_G13, path_control, PATH_EXACT_STOP);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+        }
+        break;
+
+      case 64: SET_MODAL(MODAL_GROUP_G13,path_control, PATH_CONTINUOUS);
+      case 80: SET_MODAL(MODAL_GROUP_G1, motion_mode,  MOTION_MODE_CANCEL_MOTION_MODE);
+        // case 90: SET_MODAL(MODAL_GROUP_G3, distance_mode, ABSOLUTE_MODE);
+        // case 91: SET_MODAL(MODAL_GROUP_G3, distance_mode, INCREMENTAL_MODE);
+      case 90:
+        switch (_point(value)) {
+        case 0: SET_MODAL(MODAL_GROUP_G3, distance_mode, ABSOLUTE_MODE);
+        case 1: SET_MODAL(MODAL_GROUP_G3, arc_distance_mode, ABSOLUTE_MODE);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+        }
+        break;
+
+      case 91:
+        switch (_point(value)) {
+        case 0: SET_MODAL(MODAL_GROUP_G3, distance_mode, INCREMENTAL_MODE);
+        case 1: SET_MODAL(MODAL_GROUP_G3, arc_distance_mode, INCREMENTAL_MODE);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+        }
+        break;
+
+      case 92:
+        switch (_point(value)) {
+        case 0: SET_MODAL(MODAL_GROUP_G0, next_action, NEXT_ACTION_SET_ORIGIN_OFFSETS);
+        case 1: SET_NON_MODAL(next_action, NEXT_ACTION_RESET_ORIGIN_OFFSETS);
+        case 2: SET_NON_MODAL(next_action, NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS);
+        case 3: SET_NON_MODAL(next_action, NEXT_ACTION_RESUME_ORIGIN_OFFSETS);
+        default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+        }
+        break;
+
+      case 93: SET_MODAL(MODAL_GROUP_G5, feed_rate_mode, INVERSE_TIME_MODE);
+      case 94: SET_MODAL(MODAL_GROUP_G5, feed_rate_mode, UNITS_PER_MINUTE_MODE);
+        // case 95: SET_MODAL(MODAL_GROUP_G5, feed_rate_mode, UNITS_PER_REVOLUTION_MODE);
+      default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
+      }
+      break;
+
+    case 'M':
+      switch ((uint8_t)value) {
+      case 0: case 1: case 60:
+        SET_MODAL(MODAL_GROUP_M4, program_flow, PROGRAM_STOP);
+      case 2: case 30:
+        SET_MODAL(MODAL_GROUP_M4, program_flow, PROGRAM_END);
+      case 3: SET_MODAL(MODAL_GROUP_M7, spindle_mode, SPINDLE_CW);
+      case 4: SET_MODAL(MODAL_GROUP_M7, spindle_mode, SPINDLE_CCW);
+      case 5: SET_MODAL(MODAL_GROUP_M7, spindle_mode, SPINDLE_OFF);
+      case 6: SET_NON_MODAL(tool_change, true);
+      case 7: SET_MODAL(MODAL_GROUP_M8, mist_coolant, true);
+      case 8: SET_MODAL(MODAL_GROUP_M8, flood_coolant, true);
+      case 9: SET_MODAL(MODAL_GROUP_M8, flood_coolant, false);
+      case 48: SET_MODAL(MODAL_GROUP_M9, override_enables, true);
+      case 49: SET_MODAL(MODAL_GROUP_M9, override_enables, false);
+      case 50: SET_MODAL(MODAL_GROUP_M9, feed_rate_override_enable, true); // conditionally true
+      case 51: SET_MODAL(MODAL_GROUP_M9, spindle_override_enable, true);      // conditionally true
+      default: status = STAT_MCODE_COMMAND_UNSUPPORTED;
+      }
+      break;
+
+    case 'T': SET_NON_MODAL(tool_select, (uint8_t)trunc(value));
+    case 'F': SET_NON_MODAL(feed_rate, value);
+    case 'P': SET_NON_MODAL(parameter, value);                // used for dwell time, G10 coord select, rotations
+    case 'S': SET_NON_MODAL(spindle_speed, value);
+    case 'X': SET_NON_MODAL(target[AXIS_X], value);
+    case 'Y': SET_NON_MODAL(target[AXIS_Y], value);
+    case 'Z': SET_NON_MODAL(target[AXIS_Z], value);
+    case 'A': SET_NON_MODAL(target[AXIS_A], value);
+    case 'B': SET_NON_MODAL(target[AXIS_B], value);
+    case 'C': SET_NON_MODAL(target[AXIS_C], value);
+      //    case 'U': SET_NON_MODAL(target[AXIS_U], value);        // reserved
+      //    case 'V': SET_NON_MODAL(target[AXIS_V], value);        // reserved
+      //    case 'W': SET_NON_MODAL(target[AXIS_W], value);        // reserved
+    case 'I': SET_NON_MODAL(arc_offset[0], value);
+    case 'J': SET_NON_MODAL(arc_offset[1], value);
+    case 'K': SET_NON_MODAL(arc_offset[2], value);
+    case 'R': SET_NON_MODAL(arc_radius, value);
+    case 'N': SET_NON_MODAL(linenum,(uint32_t)value);       // line number
+    case 'L': break;                                        // not used for anything
+    default: status = STAT_GCODE_COMMAND_UNSUPPORTED;
     }
-    if ((status != STAT_OK) && (status != STAT_COMPLETE)) return status;
-    ritorno(_validate_gcode_block());
-    return _execute_gcode_block();        // if successful execute the block
+    if (status != STAT_OK) break;
+  }
+
+  if ((status != STAT_OK) && (status != STAT_COMPLETE)) return status;
+  ritorno(_validate_gcode_block());
+
+  return _execute_gcode_block();        // if successful execute the block
 }
 
+
 /*
- * _execute_gcode_block() - execute parsed block
+ * Execute parsed block
  *
  *  Conditionally (based on whether a flag is set in gf) call the canonical
- *    machining functions in order of execution as per RS274NGC_3 table 8
+ *  machining functions in order of execution as per RS274NGC_3 table 8
  *  (below, with modifications):
  *
  *        0. record the line number
@@ -425,98 +413,89 @@ static stat_t _parse_gcode_block(char_t *buf)
  *    Values in gn are in original units and should not be unit converted prior
  *    to calling the canonical functions (which do the unit conversions)
  */
-
-static stat_t _execute_gcode_block()
-{
-    stat_t status = STAT_OK;
-
-    cm_set_model_linenum(cm.gn.linenum);
-    EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode);
-    EXEC_FUNC(cm_set_feed_rate, feed_rate);
-    EXEC_FUNC(cm_feed_rate_override_factor, feed_rate_override_factor);
-    EXEC_FUNC(cm_traverse_override_factor, traverse_override_factor);
-    EXEC_FUNC(cm_set_spindle_speed, spindle_speed);
-    EXEC_FUNC(cm_spindle_override_factor, spindle_override_factor);
-    EXEC_FUNC(cm_select_tool, tool_select);                    // tool_select is where it's written
-    EXEC_FUNC(cm_change_tool, tool_change);
-    EXEC_FUNC(cm_spindle_control, spindle_mode);             // spindle on or off
-    EXEC_FUNC(cm_mist_coolant_control, mist_coolant);
-    EXEC_FUNC(cm_flood_coolant_control, flood_coolant);        // also disables mist coolant if OFF
-    EXEC_FUNC(cm_feed_rate_override_enable, feed_rate_override_enable);
-    EXEC_FUNC(cm_traverse_override_enable, traverse_override_enable);
-    EXEC_FUNC(cm_spindle_override_enable, spindle_override_enable);
-    EXEC_FUNC(cm_override_enables, override_enables);
-
-    if (cm.gn.next_action == NEXT_ACTION_DWELL) {             // G4 - dwell
-        ritorno(cm_dwell(cm.gn.parameter));                    // return if error, otherwise complete the block
+static stat_t _execute_gcode_block() {
+  stat_t status = STAT_OK;
+
+  cm_set_model_linenum(cm.gn.linenum);
+  EXEC_FUNC(cm_set_feed_rate_mode, feed_rate_mode);
+  EXEC_FUNC(cm_set_feed_rate, feed_rate);
+  EXEC_FUNC(cm_feed_rate_override_factor, feed_rate_override_factor);
+  EXEC_FUNC(cm_traverse_override_factor, traverse_override_factor);
+  EXEC_FUNC(cm_set_spindle_speed, spindle_speed);
+  EXEC_FUNC(cm_spindle_override_factor, spindle_override_factor);
+  EXEC_FUNC(cm_select_tool, tool_select);                    // tool_select is where it's written
+  EXEC_FUNC(cm_change_tool, tool_change);
+  EXEC_FUNC(cm_spindle_control, spindle_mode);               // spindle on or off
+  EXEC_FUNC(cm_mist_coolant_control, mist_coolant);
+  EXEC_FUNC(cm_flood_coolant_control, flood_coolant);        // also disables mist coolant if OFF
+  EXEC_FUNC(cm_feed_rate_override_enable, feed_rate_override_enable);
+  EXEC_FUNC(cm_traverse_override_enable, traverse_override_enable);
+  EXEC_FUNC(cm_spindle_override_enable, spindle_override_enable);
+  EXEC_FUNC(cm_override_enables, override_enables);
+
+  if (cm.gn.next_action == NEXT_ACTION_DWELL)              // G4 - dwell
+    ritorno(cm_dwell(cm.gn.parameter));                    // return if error, otherwise complete the block
+
+  EXEC_FUNC(cm_select_plane, select_plane);
+  EXEC_FUNC(cm_set_units_mode, units_mode);
+  //--> cutter radius compensation goes here
+  //--> cutter length compensation goes here
+  EXEC_FUNC(cm_set_coord_system, coord_system);
+  EXEC_FUNC(cm_set_path_control, path_control);
+  EXEC_FUNC(cm_set_distance_mode, distance_mode);
+  //--> set retract mode goes here
+
+  switch (cm.gn.next_action) {
+  case NEXT_ACTION_SET_G28_POSITION:  status = cm_set_g28_position(); break;                                // G28.1
+  case NEXT_ACTION_GOTO_G28_POSITION: status = cm_goto_g28_position(cm.gn.target, cm.gf.target); break;     // G28
+  case NEXT_ACTION_SET_G30_POSITION:  status = cm_set_g30_position(); break;                                // G30.1
+  case NEXT_ACTION_GOTO_G30_POSITION: status = cm_goto_g30_position(cm.gn.target, cm.gf.target); break;     // G30
+
+  case NEXT_ACTION_SEARCH_HOME: status = cm_homing_cycle_start(); break;                                    // G28.2
+  case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: status = cm_set_absolute_origin(cm.gn.target, cm.gf.target); break; // G28.3
+  case NEXT_ACTION_HOMING_NO_SET: status = cm_homing_cycle_start_no_set(); break;                           // G28.4
+
+  case NEXT_ACTION_STRAIGHT_PROBE: status = cm_straight_probe(cm.gn.target, cm.gf.target); break;           // G38.2
+
+  case NEXT_ACTION_SET_COORD_DATA: status = cm_set_coord_offsets(cm.gn.parameter, cm.gn.target, cm.gf.target); break;
+  case NEXT_ACTION_SET_ORIGIN_OFFSETS: status = cm_set_origin_offsets(cm.gn.target, cm.gf.target); break;
+  case NEXT_ACTION_RESET_ORIGIN_OFFSETS: status = cm_reset_origin_offsets(); break;
+  case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: status = cm_suspend_origin_offsets(); break;
+  case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: status = cm_resume_origin_offsets(); break;
+
+  case NEXT_ACTION_DEFAULT:
+    cm_set_absolute_override(MODEL, cm.gn.absolute_override);    // apply override setting to gm struct
+    switch (cm.gn.motion_mode) {
+    case MOTION_MODE_CANCEL_MOTION_MODE: cm.gm.motion_mode = cm.gn.motion_mode; break;
+    case MOTION_MODE_STRAIGHT_TRAVERSE: status = cm_straight_traverse(cm.gn.target, cm.gf.target); break;
+    case MOTION_MODE_STRAIGHT_FEED: status = cm_straight_feed(cm.gn.target, cm.gf.target); break;
+    case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC:
+      // gf.radius sets radius mode if radius was collected in gn
+      status = cm_arc_feed(cm.gn.target, cm.gf.target, cm.gn.arc_offset[0], cm.gn.arc_offset[1],
+                           cm.gn.arc_offset[2], cm.gn.arc_radius, cm.gn.motion_mode);
+      break;
     }
-    EXEC_FUNC(cm_select_plane, select_plane);
-    EXEC_FUNC(cm_set_units_mode, units_mode);
-    //--> cutter radius compensation goes here
-    //--> cutter length compensation goes here
-    EXEC_FUNC(cm_set_coord_system, coord_system);
-    EXEC_FUNC(cm_set_path_control, path_control);
-    EXEC_FUNC(cm_set_distance_mode, distance_mode);
-    //--> set retract mode goes here
-
-    switch (cm.gn.next_action) {
-        case NEXT_ACTION_SET_G28_POSITION:  { status = cm_set_g28_position(); break;}                                // G28.1
-        case NEXT_ACTION_GOTO_G28_POSITION: { status = cm_goto_g28_position(cm.gn.target, cm.gf.target); break;}    // G28
-        case NEXT_ACTION_SET_G30_POSITION:  { status = cm_set_g30_position(); break;}                                // G30.1
-        case NEXT_ACTION_GOTO_G30_POSITION: { status = cm_goto_g30_position(cm.gn.target, cm.gf.target); break;}    // G30
-
-        case NEXT_ACTION_SEARCH_HOME: { status = cm_homing_cycle_start(); break;}                                    // G28.2
-        case NEXT_ACTION_SET_ABSOLUTE_ORIGIN: { status = cm_set_absolute_origin(cm.gn.target, cm.gf.target); break;}// G28.3
-        case NEXT_ACTION_HOMING_NO_SET: { status = cm_homing_cycle_start_no_set(); break;}                            // G28.4
-
-        case NEXT_ACTION_STRAIGHT_PROBE: { status = cm_straight_probe(cm.gn.target, cm.gf.target); break;}            // G38.2
-
-        case NEXT_ACTION_SET_COORD_DATA: { status = cm_set_coord_offsets(cm.gn.parameter, cm.gn.target, cm.gf.target); break;}
-        case NEXT_ACTION_SET_ORIGIN_OFFSETS: { status = cm_set_origin_offsets(cm.gn.target, cm.gf.target); break;}
-        case NEXT_ACTION_RESET_ORIGIN_OFFSETS: { status = cm_reset_origin_offsets(); break;}
-        case NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS: { status = cm_suspend_origin_offsets(); break;}
-        case NEXT_ACTION_RESUME_ORIGIN_OFFSETS: { status = cm_resume_origin_offsets(); break;}
-
-        case NEXT_ACTION_DEFAULT: {
-            cm_set_absolute_override(MODEL, cm.gn.absolute_override);    // apply override setting to gm struct
-            switch (cm.gn.motion_mode) {
-                case MOTION_MODE_CANCEL_MOTION_MODE: { cm.gm.motion_mode = cm.gn.motion_mode; break;}
-                case MOTION_MODE_STRAIGHT_TRAVERSE: { status = cm_straight_traverse(cm.gn.target, cm.gf.target); break;}
-                case MOTION_MODE_STRAIGHT_FEED: { status = cm_straight_feed(cm.gn.target, cm.gf.target); break;}
-                case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC:
-                    // gf.radius sets radius mode if radius was collected in gn
-                    { status = cm_arc_feed(cm.gn.target, cm.gf.target, cm.gn.arc_offset[0], cm.gn.arc_offset[1],
-                                           cm.gn.arc_offset[2], cm.gn.arc_radius, cm.gn.motion_mode); break;}
-            }
-        }
-    }
-    cm_set_absolute_override(MODEL, false);     // un-set absolute override once the move is planned
-
-    // do the program stops and ends : M0, M1, M2, M30, M60
-    if (cm.gf.program_flow == true) {
-        if (cm.gn.program_flow == PROGRAM_STOP) {
-            cm_program_stop();
-        } else {
-            cm_program_end();
-        }
-    }
-    return status;
+  }
+  cm_set_absolute_override(MODEL, false);     // un-set absolute override once the move is planned
+
+  // do the program stops and ends : M0, M1, M2, M30, M60
+  if (cm.gf.program_flow == true) {
+    if (cm.gn.program_flow == PROGRAM_STOP) cm_program_stop();
+    else cm_program_end();
+  }
+
+  return status;
 }
 
 
-/***********************************************************************************
- * CONFIGURATION AND INTERFACE FUNCTIONS
- * Functions to get and set variables from the cfgArray table
- ***********************************************************************************/
+stat_t gc_get_gc(nvObj_t *nv) {
+  ritorno(nv_copy_string(nv, cs.saved_buf));
+  nv->valuetype = TYPE_STRING;
 
-stat_t gc_get_gc(nvObj_t *nv)
-{
-    ritorno(nv_copy_string(nv, cs.saved_buf));
-    nv->valuetype = TYPE_STRING;
-    return STAT_OK;
+  return STAT_OK;
 }
 
-stat_t gc_run_gc(nvObj_t *nv)
-{
-    return gc_gcode_parser(*nv->stringp);
+
+stat_t gc_run_gc(nvObj_t *nv) {
+  return gc_gcode_parser(*nv->stringp);
 }
index af312f08385ceb571fd3d9be1bcead6770222577..730961cdb278f479ac0ba84290cae2449b561fd8 100644 (file)
@@ -25,7 +25,7 @@
  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-#include <avr/wdt.h>            // used for software reset
+#include <avr/wdt.h>      // used for software reset
 
 #include "tinyg.h"        // #1
 #include "config.h"       // #2
@@ -65,7 +65,7 @@ void hardware_init() {
 
 
 /*
- * _get_id() - get a human readable signature
+ * Get a human readable signature
  *
  *    Produce a unique deviceID based on the factory calibration data.
  *        Format is: 123456-ABC
@@ -93,7 +93,7 @@ static void _get_id(char_t *id) {
   char printable[33] = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
   uint8_t i;
 
-  NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;     // Load NVM Command register to read the calibration row
+  NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc; // Load NVM Command register to read the calibration row
 
   for (i = 0; i < 6; i++)
     id[i] = pgm_read_byte(LOTNUM0 + i);
@@ -104,38 +104,29 @@ static void _get_id(char_t *id) {
   id[i++] = printable[(pgm_read_byte(COORDY0) & 0x1F)];
   id[i] = 0;
 
-  NVM_CMD = NVM_CMD_NO_OPERATION_gc;          // Clean up NVM Command register
+  NVM_CMD = NVM_CMD_NO_OPERATION_gc; // Clean up NVM Command register
 }
 
 
-/*
- * Hardware Reset Handlers
- *
- * hw_request_hard_reset()
- * hw_hard_reset()            - hard reset using watchdog timer
- * hw_hard_reset_handler()    - controller's rest handler
- */
 void hw_request_hard_reset() {cs.hard_reset_requested = true;}
 
 
+/// Hard reset using watchdog timer
 void hw_hard_reset() {            // software hard reset using the watchdog timer
   wdt_enable(WDTO_15MS);
-  while (true);                    // loops for about 15ms then resets
+  while (true);                   // loops for about 15ms then resets
 }
 
 
+/// Controller's rest handler
 stat_t hw_hard_reset_handler() {
   if (cs.hard_reset_requested == false) return STAT_NOOP;
   hw_hard_reset();                // hard reset - identical to hitting RESET button
   return STAT_EAGAIN;
 }
 
-/*
- * Bootloader Handlers
- *
- * hw_request_bootloader()
- * hw_request_bootloader_handler() - executes a software reset using CCPWrite
- */
+
+/// Executes a software reset using CCPWrite
 void hw_request_bootloader() {cs.bootloader_requested = true;}
 
 
@@ -144,13 +135,13 @@ stat_t hw_bootloader_handler() {
     return STAT_NOOP;
 
   cli();
-  CCPWrite(&RST.CTRL, RST_SWRST_bm);  // fire a software reset
+  CCPWrite(&RST.CTRL, RST_SWRST_bm); // fire a software reset
 
   return STAT_EAGAIN;                // never gets here but keeps the compiler happy
 }
 
 
-/// hw_get_id() - get device ID (signature)
+/// Get device ID (signature)
 stat_t hw_get_id(nvObj_t *nv) {
   char_t tmp[SYS_ID_LEN];
   _get_id(tmp);
@@ -160,21 +151,21 @@ stat_t hw_get_id(nvObj_t *nv) {
 }
 
 
-/// hw_run_boot() - invoke boot form the cfgArray
+/// Invoke boot form the cfgArray
 stat_t hw_run_boot(nvObj_t *nv) {
   hw_request_bootloader();
   return STAT_OK;
 }
 
 
-/// hw_set_hv() - set hardware version number
+/// Set hardware version number
 stat_t hw_set_hv(nvObj_t *nv) {
   if (nv->value > TINYG_HARDWARE_VERSION_MAX)
     return STAT_INPUT_EXCEEDS_MAX_VALUE;
 
   set_flt(nv);                    // record the hardware version
-  _port_bindings(nv->value);        // reset port bindings
-  switch_init();                    // re-initialize the GPIO ports
+  _port_bindings(nv->value);      // reset port bindings
+  switch_init();                  // re-initialize the GPIO ports
   return STAT_OK;
 }
 
index 24a6ae32e4f66bd71c138dff4729dc91414d1fa5..c80a2ee01829fbc466d5dc9aad36c61798d1450b 100644 (file)
@@ -163,7 +163,6 @@ enum cfgPortBits {        // motor control port bit positions
 #define FREQUENCY_DWELL        (float)10000    // Dwell count frequency in hz.
 #define LOAD_TIMER_PERIOD      100             // cycles you have to shut off SW interrupt
 #define EXEC_TIMER_PERIOD      100             // cycles you have to shut off SW interrupt
-#define EXEC_TIMER_PERIOD_LONG 100             // cycles you have to shut off SW interrupt
 
 #define STEP_TIMER_TYPE        TC0_struct       // stepper subsybstem uses all the TC0's
 #define STEP_TIMER_DISABLE     0                // turn timer off (clock = 0 Hz)
@@ -208,7 +207,6 @@ enum cfgPortBits {        // motor control port bit positions
   are not assigned to the designated function - ur unpredicatable results will
   occur.
 */
-
 typedef struct {
   PORT_t *st_port[MOTORS];       // bindings for stepper motor ports (stepper.c)
   PORT_t *sw_port[MOTORS];       // bindings for switch ports (GPIO2)
index 9f05d92ce4bbd22f61583d591153e5b8b3312779..9aebe4730e975fce5f357988bea99d85918cbf2e 100644 (file)
@@ -41,12 +41,9 @@ void persistence_init() {
 }
 
 
-/************************************************************************************
- * read_persistent_value()    - return value (as float) by index
- * write_persistent_value() - write to NVM by index, but only if the value has changed
- *
- *    It's the responsibility of the caller to make sure the index does not exceed range
- */
+// It's the responsibility of the caller to make sure the index does not exceed range
+
+/// return value (as float) by index
 stat_t read_persistent_value(nvObj_t *nv) {
   nvm.address = nvm.profile_base + (nv->index * NVM_VALUE_LEN);
   EEPROM_ReadBytes(nvm.address, nvm.byte_array, NVM_VALUE_LEN);
@@ -55,6 +52,7 @@ stat_t read_persistent_value(nvObj_t *nv) {
 }
 
 
+/// write to NVM by index, but only if the value has changed
 stat_t write_persistent_value(nvObj_t *nv) {
   if (cm.cycle_state != CYCLE_OFF)
     return rpt_exception(STAT_FILE_NOT_OPEN);    // can't write when machine is moving
index 32cbd0c2bc3011dccbec7be14eb4c3a65f7f623c..6c9b44d032dedfa20f818f7f65d56a8f26bd7e4c 100644 (file)
 #define JUNCTION_DEVIATION       0.05         // default value, in mm
 #define JUNCTION_ACCELERATION    100000       // centripetal acceleration around corners
 
+
 // Motor settings
+#define MOTOR_MICROSTEPS         8
+
 #define M1_MOTOR_MAP             AXIS_X              // 1ma
 #define M1_STEP_ANGLE            1.8                 // 1sa
 #define M1_TRAVEL_PER_REV        1.25                // 1tr
-#define M1_MICROSTEPS            8                   // 1mi        1,2,4,8
+#define M1_MICROSTEPS            MOTOR_MICROSTEPS    // 1mi
 #define M1_POLARITY              0                   // 1po        0=normal, 1=reversed
 #define M1_POWER_MODE            MOTOR_POWER_MODE    // 1pm        standard
 #define M1_POWER_LEVEL           MOTOR_POWER_LEVEL   // 1mp
@@ -57,7 +60,7 @@
 #define M2_MOTOR_MAP             AXIS_Y
 #define M2_STEP_ANGLE            1.8
 #define M2_TRAVEL_PER_REV        1.25
-#define M2_MICROSTEPS            256
+#define M2_MICROSTEPS            MOTOR_MICROSTEPS
 #define M2_POLARITY              0
 #define M2_POWER_MODE            MOTOR_POWER_MODE
 #define M2_POWER_LEVEL           MOTOR_POWER_LEVEL
@@ -65,7 +68,7 @@
 #define M3_MOTOR_MAP             AXIS_Z
 #define M3_STEP_ANGLE            1.8
 #define M3_TRAVEL_PER_REV        1.25
-#define M3_MICROSTEPS            256
+#define M3_MICROSTEPS            MOTOR_MICROSTEPS
 #define M3_POLARITY              0
 #define M3_POWER_MODE            MOTOR_POWER_MODE
 #define M3_POWER_LEVEL           MOTOR_POWER_LEVEL
@@ -73,7 +76,7 @@
 #define M4_MOTOR_MAP             AXIS_A
 #define M4_STEP_ANGLE            1.8
 #define M4_TRAVEL_PER_REV        360            // degrees moved per motor rev
-#define M4_MICROSTEPS            256
+#define M4_MICROSTEPS            MOTOR_MICROSTEPS
 #define M4_POLARITY              0
 #define M4_POWER_MODE            MOTOR_POWER_MODE
 #define M4_POWER_LEVEL           MOTOR_POWER_LEVEL
@@ -81,7 +84,7 @@
 #define M5_MOTOR_MAP             AXIS_B
 #define M5_STEP_ANGLE            1.8
 #define M5_TRAVEL_PER_REV        360            // degrees moved per motor rev
-#define M5_MICROSTEPS            8
+#define M5_MICROSTEPS            MOTOR_MICROSTEPS
 #define M5_POLARITY              0
 #define M5_POWER_MODE            MOTOR_POWER_MODE
 #define M5_POWER_LEVEL           MOTOR_POWER_LEVEL
@@ -89,7 +92,7 @@
 #define M6_MOTOR_MAP             AXIS_C
 #define M6_STEP_ANGLE            1.8
 #define M6_TRAVEL_PER_REV        360            // degrees moved per motor rev
-#define M6_MICROSTEPS            256
+#define M6_MICROSTEPS            MOTOR_MICROSTEPS
 #define M6_POLARITY              0
 #define M6_POWER_MODE            MOTOR_POWER_MODE
 #define M6_POWER_LEVEL           MOTOR_POWER_LEVEL
index 30dedb6ffa5f83bad16726faa7b75b8027861895..985032edf1f1a4df0deb08886c1081acd1e33bbd 100644 (file)
 #include <avr/interrupt.h>
 
 /**** Status Messages ***************************************************************
- * get_status_message() - return the status message
- *
  * See tinyg.h for status codes. These strings must align with the status codes in tinyg.h
  * The number of elements in the indexing array must match the # of strings
- *
- * Reference for putting display strings and string arrays in AVR program memory:
- * http://www.cs.mun.ca/~paul/cs4723/material/atmel/avr-libc-user-manual-1.6.5/pgmspace.html
  */
 
 stat_t status_code;                     // allocate a variable for the ritorno macro
 char global_string_buf[MESSAGE_LEN];    // allocate a string for global message use
 
-/*** Status message strings ***/
 
 static const char stat_00[] PROGMEM = "OK";
 static const char stat_01[] PROGMEM = "Error";
@@ -341,6 +335,7 @@ static const char *const stat_msg[] PROGMEM = {
 };
 
 
+/// Return the status message
 char *get_status_message(stat_t status) {
   return (char *)GET_TEXT_ITEM(stat_msg, status);
 }
index 44075e98adb7cbee2b0c2e750ead804d6915c700..5c65f80a97879ca07c18be28ed0a5a56c821c139 100644 (file)
@@ -278,35 +278,29 @@ stat_t st_motor_power_callback() { // called by controller
 */
 ISR(TIMER_DDA_ISR_vect) {
   if ((st_run.mot[MOTOR_1].substep_accumulator += st_run.mot[MOTOR_1].substep_increment) > 0) {
-    PORT_MOTOR_1_VPORT.OUT ^= STEP_BIT_bm;        // turn step bit on
+    PORT_MOTOR_1_VPORT.OUT ^= STEP_BIT_bm; // toggle step line
     st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps;
     INCREMENT_ENCODER(MOTOR_1);
   }
 
   if ((st_run.mot[MOTOR_2].substep_accumulator += st_run.mot[MOTOR_2].substep_increment) > 0) {
-    PORT_MOTOR_2_VPORT.OUT |= STEP_BIT_bm;
+    PORT_MOTOR_2_VPORT.OUT ^= STEP_BIT_bm;
     st_run.mot[MOTOR_2].substep_accumulator -= st_run.dda_ticks_X_substeps;
     INCREMENT_ENCODER(MOTOR_2);
   }
 
   if ((st_run.mot[MOTOR_3].substep_accumulator += st_run.mot[MOTOR_3].substep_increment) > 0) {
-    PORT_MOTOR_3_VPORT.OUT |= STEP_BIT_bm;
+    PORT_MOTOR_3_VPORT.OUT ^= STEP_BIT_bm;
     st_run.mot[MOTOR_3].substep_accumulator -= st_run.dda_ticks_X_substeps;
     INCREMENT_ENCODER(MOTOR_3);
   }
 
   if ((st_run.mot[MOTOR_4].substep_accumulator += st_run.mot[MOTOR_4].substep_increment) > 0) {
-    PORT_MOTOR_4_VPORT.OUT |= STEP_BIT_bm;
+    PORT_MOTOR_4_VPORT.OUT ^= STEP_BIT_bm;
     st_run.mot[MOTOR_4].substep_accumulator -= st_run.dda_ticks_X_substeps;
     INCREMENT_ENCODER(MOTOR_4);
   }
 
-  // Turn step bits off - pulse stretching for using external drivers.
-  //PORT_MOTOR_1_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 5 uSec pulse width
-  PORT_MOTOR_2_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 4 uSec
-  PORT_MOTOR_3_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 3 uSec
-  PORT_MOTOR_4_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 2 uSec
-
   if (--st_run.dda_ticks_downcount != 0) return;
 
   TIMER_DDA.CTRLA = STEP_TIMER_DISABLE;                // disable DDA timer
index d9cf2adfdb2be1cc758c1008fa1bab94298451af..ea43c1d56335bcd3425df38c85acce439318f862 100644 (file)
@@ -88,6 +88,7 @@ stat_t text_parser(char_t *str) {
     status = nv_set(nv);                        // set (or run) single value
     if (status == STAT_OK) nv_persist(nv);      // conditionally persist depending on flags in array
   }
+
   nv_print_list(status, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT); // print the results
   return status;
 }
@@ -109,9 +110,10 @@ static stat_t _text_parser_kernal(char_t *str, nvObj_t *nv) {
 
   // parse fields into the nv struct
   nv->valuetype = TYPE_0;
-  if ((rd = strpbrk(str, separators)) == 0) {     // no value part
+  if ((rd = strpbrk(str, separators)) == 0)       // no value part
     strncpy(nv->token, str, TOKEN_LEN);
-  } else {
+
+  else {
     *rd = 0;                                      // terminate at end of name
     strncpy(nv->token, str, TOKEN_LEN);
     str = ++rd;
@@ -120,7 +122,7 @@ static stat_t _text_parser_kernal(char_t *str, nvObj_t *nv) {
   }
 
   // validate and post-process the token
-  if ((nv->index = nv_get_index((const char_t *)"", nv->token)) == NO_MATCH) // get index or fail it
+  if ((nv->index = nv_get_index("", nv->token)) == NO_MATCH) // get index or fail it
     return STAT_UNRECOGNIZED_NAME;
 
   strcpy_P(nv->group, cfgArray[nv->index].group);    // capture the group string if there is one
index 4836f848da33b29e4e25053e544b19ca4097f535..62270e9f6ebb9655cf30ca898e6cad3acff1136c 100644 (file)
 
 #include "xmega/xmega_rtc.h"
 
-/**** Vector utilities ****
- * copy_vector()            - copy vector of arbitrary length
- * vector_equal()            - test if vectors are equal
- * get_axis_vector_length()    - return the length of an axis vector
- * set_vector()                - load values into vector form
- * set_vector_by_axis()        - load a single value into a zero vector
- */
-
 float vector[AXES];    // statically allocated global for vector utilities
 
 
+/// Test if vectors are equal
 uint8_t vector_equal(const float a[], const float b[]) {
   if ((fp_EQ(a[AXIS_X], b[AXIS_X])) &&
       (fp_EQ(a[AXIS_Y], b[AXIS_Y])) &&
@@ -60,6 +53,7 @@ uint8_t vector_equal(const float a[], const float b[]) {
 }
 
 
+/// Return the length of an axis vector
 float get_axis_vector_length(const float a[], const float b[]) {
   return sqrt(square(a[AXIS_X] - b[AXIS_X] +
                      square(a[AXIS_Y] - b[AXIS_Y]) +
@@ -70,6 +64,7 @@ float get_axis_vector_length(const float a[], const float b[]) {
 }
 
 
+/// Load values into vector form
 float *set_vector(float x, float y, float z, float a, float b, float c) {
   vector[AXIS_X] = x;
   vector[AXIS_Y] = y;
@@ -81,6 +76,7 @@ float *set_vector(float x, float y, float z, float a, float b, float c) {
 }
 
 
+/// load a single value into a zero vector
 float *set_vector_by_axis(float value, uint8_t axis) {
   clear_vector(vector);
   switch (axis) {
@@ -106,7 +102,7 @@ float *set_vector_by_axis(float value, uint8_t axis) {
  * Implementation tip: Order the min and max values from most to least likely in the calling args
  *
  * (*) Macro min4 is about 20uSec, inline function version is closer to 10 uSec (Xmega 32 MHz)
- *     #define min3(a,b,c) (min(min(a,b),c))
+ *    #define min3(a,b,c) (min(min(a,b),c))
  *    #define min4(a,b,c,d) (min(min(a,b),min(c,d)))
  *    #define max3(a,b,c) (max(max(a,b),c))
  *    #define max4(a,b,c,d) (max(max(a,b),max(c,d)))
@@ -145,19 +141,13 @@ float max4(float x1, float x2, float x3, float x4) {
 }
 
 
-/**** String utilities ****
- * strcpy_U()        - strcpy workalike to get around initial 0 for blank string - possibly wrong
- * isnumber()        - isdigit that also accepts plus, minus, and decimal point
- * escape_string() - add escapes to a string - currently for quotes only
- */
+/// isdigit that also accepts plus, minus, and decimal point
 uint8_t isnumber(char_t c) {
-  if (c == '.') return true;
-  if (c == '-') return true;
-  if (c == '+') return true;
-  return isdigit(c);
+  return c == '.' || c == '-' || c == '+' || isdigit(c);
 }
 
 
+/// Add escapes to a string - currently for quotes only
 char_t *escape_string(char_t *dst, char_t *src) {
   char_t c;
   char_t *start_dst = dst;
@@ -172,7 +162,7 @@ char_t *escape_string(char_t *dst, char_t *src) {
 
 
 /*
- * pstr2str() - return an AVR style progmem string as a RAM string.
+ * Return an AVR style progmem string as a RAM string.
  *
  *    This function copies a string from FLASH to a pre-allocated RAM buffer -
  *  see main.c for allocation and max length.
@@ -184,7 +174,7 @@ char_t *pstr2str(const char *pgm_string) {
 
 
 /*
- * fntoa() - return ASCII string given a float and a decimal precision value
+ * Return ASCII string given a float and a decimal precision value
  *
  *    Returns length of string, less the terminating 0 character
  */
@@ -193,24 +183,19 @@ char_t fntoa(char_t *str, float n, uint8_t precision) {
   if (isnan(n)) {
     strcpy(str, "nan");
     return 3;
+  }
 
-  } else if (isinf(n)) {
+  if (isinf(n)) {
     strcpy(str, "inf");
     return 3;
+  }
 
-  } else if (precision == 0 ) {return (char_t)sprintf((char *)str, "%0.0f", (double)n);
-  } else if (precision == 1 ) {return (char_t)sprintf((char *)str, "%0.1f", (double)n);
-  } else if (precision == 2 ) {return (char_t)sprintf((char *)str, "%0.2f", (double)n);
-  } else if (precision == 3 ) {return (char_t)sprintf((char *)str, "%0.3f", (double)n);
-  } else if (precision == 4 ) {return (char_t)sprintf((char *)str, "%0.4f", (double)n);
-  } else if (precision == 5 ) {return (char_t)sprintf((char *)str, "%0.5f", (double)n);
-  } else if (precision == 6 ) {return (char_t)sprintf((char *)str, "%0.6f", (double)n);
-  } else if (precision == 7 ) {return (char_t)sprintf((char *)str, "%0.7f", (double)n);
-  } else return (char_t)sprintf((char *)str, "%f", (double)n);
+  return (char_t)sprintf((char *)str, "%0.*f", (int)precision, (double)n);
 }
 
+
 /*
- * compute_checksum() - calculate the checksum for a string
+ * Calculate the checksum for a string
  *
  *    Stops calculation on null termination or length value if non-zero.
  *
@@ -232,7 +217,7 @@ uint16_t compute_checksum(char_t const *string, const uint16_t length) {
 }
 
 
-/// SysTickTimer_getValue() - this is a hack to get around some compatibility problems
+/// This is a hack to get around some compatibility problems
 uint32_t SysTickTimer_getValue() {
   return rtc.sys_ticks;
 }