More cleanup, removed MICROSTEP line settings
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Sun, 3 Jan 2016 03:31:55 +0000 (19:31 -0800)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Sun, 3 Jan 2016 03:31:55 +0000 (19:31 -0800)
20 files changed:
src/canonical_machine.c
src/canonical_machine.h
src/config.c
src/encoder.c
src/gcode_parser.c
src/gcode_parser.h
src/hardware.c
src/hardware.h
src/help.c
src/json_parser.c
src/persistence.c
src/plan_exec.c
src/plan_line.c
src/plan_zoid.c
src/planner.c
src/report.c
src/spindle.c
src/stepper.c
src/stepper.h
src/tinyg.h

index 34cbb2c7c617e1d8ab03fb5b9037a56b213c942b..cc82c0f56a22d5bcb9dc87d1b36edb03b2b5a6c7 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 /*
- *     This code is a loose implementation of Kramer, Proctor and Messina's canonical
+ *    This code is a loose implementation of Kramer, Proctor and Messina's canonical
  *    machining functions as described in the NIST RS274/NGC v3
  *
  *    The canonical machine is the layer between the Gcode parser and the motion control
@@ -131,15 +131,16 @@ static int8_t _get_axis_type(const index_t index);
  * cm_set_motion_state() - adjusts active model pointer as well
  */
 uint8_t cm_get_combined_state() {
-  if (cm.cycle_state == CYCLE_OFF) { cm.combined_state = cm.machine_state;}
-  else if (cm.cycle_state == CYCLE_PROBE) { cm.combined_state = COMBINED_PROBE;}
-  else if (cm.cycle_state == CYCLE_HOMING) { cm.combined_state = COMBINED_HOMING;}
-  else if (cm.cycle_state == CYCLE_JOG) { cm.combined_state = COMBINED_JOG;}
+  if (cm.cycle_state == CYCLE_OFF) cm.combined_state = cm.machine_state;
+  else if (cm.cycle_state == CYCLE_PROBE) cm.combined_state = COMBINED_PROBE;
+  else if (cm.cycle_state == CYCLE_HOMING) cm.combined_state = COMBINED_HOMING;
+  else if (cm.cycle_state == CYCLE_JOG) cm.combined_state = COMBINED_JOG;
   else {
     if (cm.motion_state == MOTION_RUN) cm.combined_state = COMBINED_RUN;
     if (cm.motion_state == MOTION_HOLD) cm.combined_state = COMBINED_HOLD;
   }
-  if (cm.machine_state == MACHINE_SHUTDOWN) { cm.combined_state = COMBINED_SHUTDOWN;}
+
+  if (cm.machine_state == MACHINE_SHUTDOWN) cm.combined_state = COMBINED_SHUTDOWN;
 
   return cm.combined_state;
 }
@@ -150,41 +151,43 @@ uint8_t cm_get_motion_state() {return cm.motion_state;}
 uint8_t cm_get_hold_state() {return cm.hold_state;}
 uint8_t cm_get_homing_state() {return cm.homing_state;}
 
+
 void cm_set_motion_state(uint8_t motion_state) {
   cm.motion_state = motion_state;
 
   switch (motion_state) {
-  case (MOTION_STOP): { ACTIVE_MODEL = MODEL; break; }
-  case (MOTION_RUN):  { ACTIVE_MODEL = RUNTIME; break; }
-  case (MOTION_HOLD): { ACTIVE_MODEL = RUNTIME; break; }
+  case (MOTION_STOP): ACTIVE_MODEL = MODEL; break;
+  case (MOTION_RUN):  ACTIVE_MODEL = RUNTIME; break;
+  case (MOTION_HOLD): ACTIVE_MODEL = RUNTIME; break;
   }
 }
 
-/*    These getters and setters will work on any gm model with inputs:
- *        MODEL         (GCodeState_t *)&cm.gm        // absolute pointer from canonical machine gm model
- *        PLANNER        (GCodeState_t *)&bf->gm        // relative to buffer *bf is currently pointing to
- *        RUNTIME        (GCodeState_t *)&mr.gm        // absolute pointer from runtime mm struct
- *        ACTIVE_MODEL cm.am                        // active model pointer is maintained by state management
+
+/* These getters and setters will work on any gm model with inputs:
+ *   MODEL         (GCodeState_t *)&cm.gm     // absolute pointer from canonical machine gm model
+ *   PLANNER       (GCodeState_t *)&bf->gm    // relative to buffer *bf is currently pointing to
+ *   RUNTIME       (GCodeState_t *)&mr.gm     // absolute pointer from runtime mm struct
+ *   ACTIVE_MODEL  cm.am                      // active model pointer is maintained by state management
  */
-uint32_t cm_get_linenum(GCodeState_t *gcode_state) { return gcode_state->linenum;}
-uint8_t cm_get_motion_mode(GCodeState_t *gcode_state) { return gcode_state->motion_mode;}
-uint8_t cm_get_coord_system(GCodeState_t *gcode_state) { return gcode_state->coord_system;}
-uint8_t cm_get_units_mode(GCodeState_t *gcode_state) { return gcode_state->units_mode;}
-uint8_t cm_get_select_plane(GCodeState_t *gcode_state) { return gcode_state->select_plane;}
-uint8_t cm_get_path_control(GCodeState_t *gcode_state) { return gcode_state->path_control;}
-uint8_t cm_get_distance_mode(GCodeState_t *gcode_state) { return gcode_state->distance_mode;}
-uint8_t cm_get_feed_rate_mode(GCodeState_t *gcode_state) { return gcode_state->feed_rate_mode;}
-uint8_t cm_get_tool(GCodeState_t *gcode_state) { return gcode_state->tool;}
-uint8_t cm_get_spindle_mode(GCodeState_t *gcode_state) { return gcode_state->spindle_mode;}
-uint8_t cm_get_block_delete_switch() { return cm.gmx.block_delete_switch;}
-uint8_t cm_get_runtime_busy() { return mp_get_runtime_busy();}
-
-float cm_get_feed_rate(GCodeState_t *gcode_state) { return gcode_state->feed_rate;}
-
-void cm_set_motion_mode(GCodeState_t *gcode_state, uint8_t motion_mode) { gcode_state->motion_mode = motion_mode;}
-void cm_set_spindle_mode(GCodeState_t *gcode_state, uint8_t spindle_mode) { gcode_state->spindle_mode = spindle_mode;}
-void cm_set_spindle_speed_parameter(GCodeState_t *gcode_state, float speed) { gcode_state->spindle_speed = speed;}
-void cm_set_tool_number(GCodeState_t *gcode_state, uint8_t tool) { gcode_state->tool = tool;}
+uint32_t cm_get_linenum(GCodeState_t *gcode_state) {return gcode_state->linenum;}
+uint8_t cm_get_motion_mode(GCodeState_t *gcode_state) {return gcode_state->motion_mode;}
+uint8_t cm_get_coord_system(GCodeState_t *gcode_state) {return gcode_state->coord_system;}
+uint8_t cm_get_units_mode(GCodeState_t *gcode_state) {return gcode_state->units_mode;}
+uint8_t cm_get_select_plane(GCodeState_t *gcode_state) {return gcode_state->select_plane;}
+uint8_t cm_get_path_control(GCodeState_t *gcode_state) {return gcode_state->path_control;}
+uint8_t cm_get_distance_mode(GCodeState_t *gcode_state) {return gcode_state->distance_mode;}
+uint8_t cm_get_feed_rate_mode(GCodeState_t *gcode_state) {return gcode_state->feed_rate_mode;}
+uint8_t cm_get_tool(GCodeState_t *gcode_state) {return gcode_state->tool;}
+uint8_t cm_get_spindle_mode(GCodeState_t *gcode_state) {return gcode_state->spindle_mode;}
+uint8_t cm_get_block_delete_switch() {return cm.gmx.block_delete_switch;}
+uint8_t cm_get_runtime_busy() {return mp_get_runtime_busy();}
+
+float cm_get_feed_rate(GCodeState_t *gcode_state) {return gcode_state->feed_rate;}
+
+void cm_set_motion_mode(GCodeState_t *gcode_state, uint8_t motion_mode) {gcode_state->motion_mode = motion_mode;}
+void cm_set_spindle_mode(GCodeState_t *gcode_state, uint8_t spindle_mode) {gcode_state->spindle_mode = spindle_mode;}
+void cm_set_spindle_speed_parameter(GCodeState_t *gcode_state, float speed) {gcode_state->spindle_speed = speed;}
+void cm_set_tool_number(GCodeState_t *gcode_state, uint8_t tool) {gcode_state->tool = tool;}
 
 void cm_set_absolute_override(GCodeState_t *gcode_state, uint8_t absolute_override) {
   gcode_state->absolute_override = absolute_override;
@@ -347,7 +350,7 @@ void cm_update_model_position_from_runtime() {copy_vector(cm.gmx.position, mr.gm
  */
 stat_t cm_deferred_write_callback() {
   if ((cm.cycle_state == CYCLE_OFF) && (cm.deferred_write_flag == true)) {
-    if (!usart_rx_empty()) return STAT_OK;        // don't write back if serial RX is not empty
+    if (!usart_rx_empty()) return STAT_OK; // don't write back if serial RX is not empty
     cm.deferred_write_flag = false;
     nvObj_t nv;
     for (uint8_t i=1; i<=COORDS; i++)
@@ -355,7 +358,7 @@ stat_t cm_deferred_write_callback() {
         sprintf((char *)nv.token, "g%2d%c", 53+i, ("xyzabc")[j]);
         nv.index = nv_get_index((const char_t *)"", nv.token);
         nv.value = cm.offset[i][j];
-        nv_persist(&nv);                // Note: only writes values that have changed
+        nv_persist(&nv);                  // Note: only writes values that have changed
       }
   }
 
@@ -373,9 +376,9 @@ stat_t cm_deferred_write_callback() {
  *    - computation and application of axis modes as so:
  *
  *    DISABLED  - Incoming value is ignored. Target value is not changed
- *    ENABLED      - Convert axis values to canonical format and store as target
+ *    ENABLED   - Convert axis values to canonical format and store as target
  *    INHIBITED - Same processing as ENABLED, but axis will not actually be run
- *     RADIUS      - ABC axis value is provided in Gcode block in linear units
+ *    RADIUS    - ABC axis value is provided in Gcode block in linear units
  *              - Target is set to degrees based on axis' Radius value
  *              - Radius mode is only processed for ABC axes. Application to XYZ is ignored.
  *
@@ -388,7 +391,7 @@ stat_t cm_deferred_write_callback() {
 // ALDEN: This shows up in avr-gcc 4.7.0 and avr-libc 1.8.0
 static float _calc_ABC(uint8_t axis, float target[], float flag[]) {
   if ((cm.a[axis].axis_mode == AXIS_STANDARD) || (cm.a[axis].axis_mode == AXIS_INHIBITED))
-    return(target[axis]);    // no mm conversion - it's in degrees
+    return target[axis];    // no mm conversion - it's in degrees
 
   return _to_millimeters(target[axis]) * 360 / (2 * M_PI * cm.a[axis].radius);
 }
@@ -465,13 +468,12 @@ stat_t cm_test_soft_limits(float target[]) {
 /// canonical_machine_init() - Config init cfg_init() must have been run beforehand
 void canonical_machine_init() {
   // If you can assume all memory has been zeroed by a hard reset you don't need this code:
-  //    memset(&cm, 0, sizeof(cm));                    // do not reset canonicalMachineSingleton once it's been initialized
-  memset(&cm.gm, 0, sizeof(GCodeState_t));    // clear all values, pointers and status
+  memset(&cm.gm, 0, sizeof(GCodeState_t));      // clear all values, pointers and status
   memset(&cm.gn, 0, sizeof(GCodeInput_t));
   memset(&cm.gf, 0, sizeof(GCodeInput_t));
 
-  canonical_machine_init_assertions();        // establish assertions
-  ACTIVE_MODEL = MODEL;                        // setup initial Gcode model pointer
+  canonical_machine_init_assertions();          // establish assertions
+  ACTIVE_MODEL = MODEL;                         // setup initial Gcode model pointer
 
   // set gcode defaults
   cm_set_units_mode(cm.units_mode);
@@ -479,7 +481,7 @@ void canonical_machine_init() {
   cm_select_plane(cm.select_plane);
   cm_set_path_control(cm.path_control);
   cm_set_distance_mode(cm.distance_mode);
-  cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE);// always the default
+  cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE); // always the default
 
   cm.gmx.block_delete_switch = true;
 
@@ -505,7 +507,6 @@ void canonical_machine_init() {
  * canonical_machine_init_assertions()
  * canonical_machine_test_assertions() - test assertions, return error code if violation exists
  */
-
 void canonical_machine_init_assertions() {
   cm.magic_start = MAGICNUM;
   cm.magic_end = MAGICNUM;
@@ -527,11 +528,11 @@ stat_t canonical_machine_test_assertions() {
 
 /*
  * cm_soft_alarm() - alarm state; send an exception report and stop processing input
- * cm_clear()        - clear soft alarm
+ * cm_clear()      - clear soft alarm
  * cm_hard_alarm() - alarm state; send an exception report and shut down machine
  */
 stat_t cm_soft_alarm(stat_t status) {
-  rpt_exception(status);                    // send alarm message
+  rpt_exception(status);                // send alarm message
   cm.machine_state = MACHINE_ALARM;
   return status;                        // NB: More efficient than inlining rpt_exception() call.
 }
@@ -548,7 +549,7 @@ stat_t cm_clear(nvObj_t *nv) {               // clear soft alarm
 
 stat_t cm_hard_alarm(stat_t status) {
   // stop the motors and the spindle
-  stepper_init();                            // hard stop
+  stepper_init();                           // hard stop
   cm_spindle_control(SPINDLE_OFF);
   rpt_exception(status);                    // send shutdown message
   cm.machine_state = MACHINE_SHUTDOWN;
@@ -577,12 +578,12 @@ stat_t cm_select_plane(uint8_t plane) {
 
 stat_t cm_set_units_mode(uint8_t mode) {
   cm.gm.units_mode = mode;        // 0 = inches, 1 = mm.
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
 stat_t cm_set_distance_mode(uint8_t mode) {
-  cm.gm.distance_mode = mode;        // 0 = absolute mode, 1 = incremental
+  cm.gm.distance_mode = mode;     // 0 = absolute mode, 1 = incremental
   return STAT_OK;
 }
 
@@ -622,19 +623,19 @@ stat_t cm_set_coord_system(uint8_t coord_system) {
   cm.gm.coord_system = coord_system;
 
   float value[AXES] = { (float)coord_system,0,0,0,0,0 };    // pass coordinate system in value[0] element
-  mp_queue_command(_exec_offset, value, value);            // second vector (flags) is not used, so fake it
+  mp_queue_command(_exec_offset, value, value);             // second vector (flags) is not used, so fake it
   return STAT_OK;
 }
 
 
 static void _exec_offset(float *value, float *flag) {
-  uint8_t coord_system = ((uint8_t)value[0]);                // coordinate system is passed in value[0] element
+  uint8_t coord_system = ((uint8_t)value[0]);               // coordinate system is passed in value[0] element
   float offsets[AXES];
   for (uint8_t axis = AXIS_X; axis < AXES; axis++)
     offsets[axis] = cm.offset[coord_system][axis] + (cm.gmx.origin_offset[axis] * cm.gmx.origin_offset_enable);
 
   mp_set_runtime_work_offset(offsets);
-  cm_set_work_offsets(MODEL);                                // set work offsets in the Gcode model
+  cm_set_work_offsets(MODEL);                               // set work offsets in the Gcode model
 }
 
 
@@ -645,7 +646,7 @@ static void _exec_offset(float *value, float *flag) {
  *    This is useful for setting origins for homing, probing, and other operations.
  *
  *  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- *    !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!!
+ *  !!!!! DO NOT CALL THIS FUNCTION WHILE IN A MACHINING CYCLE !!!!!
  *  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  *
  *    More specifically, do not call this function if there are any moves in the planner or
@@ -685,9 +686,9 @@ stat_t cm_set_absolute_origin(float origin[], float flag[]) {
   for (uint8_t axis = AXIS_X; axis < AXES; axis++)
     if (fp_TRUE(flag[axis])) {
       value[axis] = _to_millimeters(origin[axis]);
-      cm.gmx.position[axis] = value[axis];        // set model position
+      cm.gmx.position[axis] = value[axis];         // set model position
       cm.gm.target[axis] = value[axis];            // reset model target
-      mp_set_planner_position(axis, value[axis]);    // set mm position
+      mp_set_planner_position(axis, value[axis]);  // set mm position
     }
 
   mp_queue_command(_exec_absolute_origin, value, flag);
@@ -708,9 +709,9 @@ static void _exec_absolute_origin(float *value, float *flag) {
 
 
 /*
- * cm_set_origin_offsets()         - G92
- * cm_reset_origin_offsets()     - G92.1
- * cm_suspend_origin_offsets()     - G92.2
+ * cm_set_origin_offsets()        - G92
+ * cm_reset_origin_offsets()      - G92.1
+ * cm_suspend_origin_offsets()    - G92.2
  * cm_resume_origin_offsets()     - G92.3
  *
  * G92's behave according to NIST 3.5.18 & LinuxCNC G92
@@ -726,7 +727,7 @@ stat_t cm_set_origin_offsets(float offset[], float flag[]) {
 
   // now pass the offset to the callback - setting the coordinate system also applies the offsets
   float value[AXES] = { (float)cm.gm.coord_system,0,0,0,0,0 }; // pass coordinate system in value[0] element
-  mp_queue_command(_exec_offset, value, value);                  // second vector is not used
+  mp_queue_command(_exec_offset, value, value);                // second vector is not used
 
   return STAT_OK;
 }
@@ -765,10 +766,8 @@ stat_t cm_resume_origin_offsets() {
 /*****************************
  * Free Space Motion (4.3.4) *
  *****************************/
-/*
- * cm_straight_traverse() - G0 linear rapid
- */
 
+/// G0 linear rapid
 stat_t cm_straight_traverse(float target[], float flags[]) {
   cm.gm.motion_mode = MOTION_MODE_STRAIGHT_TRAVERSE;
   cm_set_model_target(target, flags);
@@ -779,8 +778,8 @@ stat_t cm_straight_traverse(float target[], float flags[]) {
 
   // prep and plan the move
   cm_set_work_offsets(&cm.gm);                // capture the fully resolved offsets to the state
-  cm_cycle_start();                            // required for homing & other cycles
-  mp_aline(&cm.gm);                            // send the move to the planner
+  cm_cycle_start();                           // required for homing & other cycles
+  mp_aline(&cm.gm);                           // send the move to the planner
   cm_finalize_move();
   return STAT_OK;
 }
@@ -800,10 +799,10 @@ stat_t cm_set_g28_position() {
 
 stat_t cm_goto_g28_position(float target[], float flags[]) {
   cm_set_absolute_override(MODEL, true);
-  cm_straight_traverse(target, flags);             // move through intermediate point, or skip
-  while (mp_get_planner_buffers_available() == 0); // make sure you have an available buffer
-  float f[] = {1,1,1,1,1,1};
-  return cm_straight_traverse(cm.gmx.g28_position, f);// execute actual stored move
+  cm_straight_traverse(target, flags);                 // move through intermediate point, or skip
+  while (mp_get_planner_buffers_available() == 0);     // make sure you have an available buffer
+  float f[] = {1, 1, 1, 1, 1, 1};
+  return cm_straight_traverse(cm.gmx.g28_position, f); // execute actual stored move
 }
 
 
@@ -815,10 +814,10 @@ stat_t cm_set_g30_position() {
 
 stat_t cm_goto_g30_position(float target[], float flags[]) {
   cm_set_absolute_override(MODEL, true);
-  cm_straight_traverse(target, flags);             // move through intermediate point, or skip
-  while (mp_get_planner_buffers_available() == 0); // make sure you have an available buffer
-  float f[] = {1,1,1,1,1,1};
-  return cm_straight_traverse(cm.gmx.g30_position, f);// execute actual stored move
+  cm_straight_traverse(target, flags);                 // move through intermediate point, or skip
+  while (mp_get_planner_buffers_available() == 0);     // make sure you have an available buffer
+  float f[] = {1, 1, 1, 1, 1, 1};
+  return cm_straight_traverse(cm.gmx.g30_position, f); // execute actual stored move
 }
 
 
@@ -842,8 +841,8 @@ stat_t cm_set_feed_rate(float feed_rate) {
 /*
  * cm_set_feed_rate_mode() - G93, G94 (affects MODEL only)
  *
- *    INVERSE_TIME_MODE = 0,            // G93
- *    UNITS_PER_MINUTE_MODE,            // G94
+ *    INVERSE_TIME_MODE = 0,           // G93
+ *    UNITS_PER_MINUTE_MODE,           // G94
  *    UNITS_PER_REVOLUTION_MODE        // G95 (unimplemented)
  */
 stat_t cm_set_feed_rate_mode(uint8_t mode) {
@@ -852,9 +851,7 @@ stat_t cm_set_feed_rate_mode(uint8_t mode) {
 }
 
 
-/*
- * cm_set_path_control() - G61, G61.1, G64 (affects MODEL only)
- */
+/// G61, G61.1, G64 (affects MODEL only)
 stat_t cm_set_path_control(uint8_t mode) {
   cm.gm.path_control = mode;
   return STAT_OK;
@@ -868,9 +865,8 @@ stat_t cm_set_path_control(uint8_t mode) {
  * cm_arc_feed() - SEE plan_arc.c(pp)
  */
 
-/*
- * cm_dwell() - G4, P parameter (seconds)
- */
+
+/// G4, P parameter (seconds)
 stat_t cm_dwell(float seconds) {
   cm.gm.parameter = seconds;
   mp_dwell(seconds);
@@ -878,9 +874,7 @@ stat_t cm_dwell(float seconds) {
 }
 
 
-/*
- * cm_straight_feed() - G1
- */
+/// G1
 stat_t cm_straight_feed(float target[], float flags[]) {
   // trap zero feed rate condition
   if ((cm.gm.feed_rate_mode != INVERSE_TIME_MODE) && (fp_ZERO(cm.gm.feed_rate)))
@@ -895,8 +889,8 @@ stat_t cm_straight_feed(float target[], float flags[]) {
 
   // prep and plan the move
   cm_set_work_offsets(&cm.gm);                // capture the fully resolved offsets to the state
-  cm_cycle_start();                            // required for homing & other cycles
-  status = mp_aline(&cm.gm);                    // send the move to the planner
+  cm_cycle_start();                           // required for homing & other cycles
+  status = mp_aline(&cm.gm);                  // send the move to the planner
   cm_finalize_move();
   return status;
 }
@@ -912,16 +906,16 @@ stat_t cm_straight_feed(float target[], float flags[]) {
  **************************/
 /*
  * cm_select_tool()        - T parameter
- * _exec_select_tool()    - execution callback
+ * _exec_select_tool()     - execution callback
  *
  * cm_change_tool()        - M6 (This might become a complete tool change cycle)
- * _exec_change_tool()    - execution callback
+ * _exec_change_tool()     - execution callback
  *
  * Note: These functions don't actually do anything for now, and there's a bug
  *         where T and M in different blocks don;t work correctly
  */
 stat_t cm_select_tool(uint8_t tool_select) {
-  float value[AXES] = { (float)tool_select,0,0,0,0,0 };
+  float value[AXES] = {(float)tool_select, 0, 0, 0, 0, 0};
   mp_queue_command(_exec_select_tool, value, value);
   return STAT_OK;
 }
@@ -933,7 +927,7 @@ static void _exec_select_tool(float *value, float *flag) {
 
 
 stat_t cm_change_tool(uint8_t tool_change) {
-  float value[AXES] = { (float)cm.gm.tool_select,0,0,0,0,0 };
+  float value[AXES] = {(float)cm.gm.tool_select, 0, 0, 0, 0, 0};
   mp_queue_command(_exec_change_tool, value, value);
   return STAT_OK;
 }
@@ -952,7 +946,7 @@ static void _exec_change_tool(float *value, float *flag) {
  * cm_flood_coolant_control() - M8, M9
  */
 stat_t cm_mist_coolant_control(uint8_t mist_coolant) {
-  float value[AXES] = { (float)mist_coolant,0,0,0,0,0 };
+  float value[AXES] = {(float)mist_coolant, 0, 0, 0, 0, 0};
   mp_queue_command(_exec_mist_coolant_control, value, value);
   return STAT_OK;
 }
@@ -961,14 +955,13 @@ stat_t cm_mist_coolant_control(uint8_t mist_coolant) {
 static void _exec_mist_coolant_control(float *value, float *flag) {
   cm.gm.mist_coolant = (uint8_t)value[0];
 
-  if (cm.gm.mist_coolant == true)
-    gpio_set_bit_on(MIST_COOLANT_BIT);    // if
-  gpio_set_bit_off(MIST_COOLANT_BIT);        // else
+  if (cm.gm.mist_coolant == true) gpio_set_bit_on(MIST_COOLANT_BIT);
+  else gpio_set_bit_off(MIST_COOLANT_BIT);
 }
 
 
 stat_t cm_flood_coolant_control(uint8_t flood_coolant) {
-  float value[AXES] = { (float)flood_coolant,0,0,0,0,0 };
+  float value[AXES] = {(float)flood_coolant, 0, 0, 0, 0, 0};
   mp_queue_command(_exec_flood_coolant_control, value, value);
   return STAT_OK;
 }
@@ -998,7 +991,7 @@ static void _exec_flood_coolant_control(float *value, float *flag) {
  *    Override enables are kind of a mess in Gcode. This is an attempt to sort them out.
  *    See http://www.linuxcnc.org/docs/2.4/html/gcode_main.html#sec:M50:-Feed-Override
  */
-stat_t cm_override_enables(uint8_t flag) {           // M48, M49
+stat_t cm_override_enables(uint8_t flag) {             // M48, M49
   cm.gmx.feed_rate_override_enable = flag;
   cm.gmx.traverse_override_enable = flag;
   cm.gmx.spindle_override_enable = flag;
@@ -1006,7 +999,7 @@ stat_t cm_override_enables(uint8_t flag) {           // M48, M49
 }
 
 
-stat_t cm_feed_rate_override_enable(uint8_t flag) {   // M50
+stat_t cm_feed_rate_override_enable(uint8_t flag) {    // M50
   if (fp_TRUE(cm.gf.parameter) && fp_ZERO(cm.gn.parameter))
     cm.gmx.feed_rate_override_enable = false;
   else cm.gmx.feed_rate_override_enable = true;
@@ -1015,14 +1008,14 @@ stat_t cm_feed_rate_override_enable(uint8_t flag) {   // M50
 }
 
 
-stat_t cm_feed_rate_override_factor(uint8_t flag) {   // M50.1
+stat_t cm_feed_rate_override_factor(uint8_t flag) {    // M50.1
   cm.gmx.feed_rate_override_enable = flag;
   cm.gmx.feed_rate_override_factor = cm.gn.parameter;
   return STAT_OK;
 }
 
 
-stat_t cm_traverse_override_enable(uint8_t flag) {   // M50.2
+stat_t cm_traverse_override_enable(uint8_t flag) {     // M50.2
   if (fp_TRUE(cm.gf.parameter) && fp_ZERO(cm.gn.parameter))
     cm.gmx.traverse_override_enable = false;
   else cm.gmx.traverse_override_enable = true;
@@ -1031,7 +1024,7 @@ stat_t cm_traverse_override_enable(uint8_t flag) {   // M50.2
 }
 
 
-stat_t cm_traverse_override_factor(uint8_t flag) {   // M51
+stat_t cm_traverse_override_factor(uint8_t flag) {     // M51
   cm.gmx.traverse_override_enable = flag;
   cm.gmx.traverse_override_factor = cm.gn.parameter;
   return STAT_OK;
@@ -1073,12 +1066,12 @@ void cm_message(char_t *message) {
  * It is extended beyond the NIST spec to handle various situations.
  *
  *    _exec_program_finalize()
- *    cm_cycle_start()            (no Gcode)  Do a cycle start right now
- *    cm_cycle_end()                (no Gcode)    Do a cycle end right now
- *    cm_feedhold()                (no Gcode)    Initiate a feedhold right now
- *    cm_program_stop()            (M0, M60)    Queue a program stop
- *    cm_optional_program_stop()    (M1)
- *    cm_program_end()            (M2, M30)
+ *    cm_cycle_start()             (no Gcode)  Do a cycle start right now
+ *    cm_cycle_end()               (no Gcode)  Do a cycle end right now
+ *    cm_feedhold()                (no Gcode)  Initiate a feedhold right now
+ *    cm_program_stop()            (M0, M60)   Queue a program stop
+ *    cm_optional_program_stop()   (M1)
+ *    cm_program_end()             (M2, M30)
  *    cm_machine_ready()            puts machine into a READY state
  *
  * cm_program_stop and cm_optional_program_stop are synchronous Gcode
@@ -1108,15 +1101,15 @@ void cm_message(char_t *message) {
  *
  *    A queue flush request received during motion should be ignored but not reset
  *    A queue flush request received during a feedhold should be deferred until
- *        the feedhold enters a HOLD state (i.e. until deceleration is complete)
+ *      the feedhold enters a HOLD state (i.e. until deceleration is complete)
  *    A queue flush request received during a motion stop should be honored
  *
  *    A cycle start request received during motion should be ignored and reset
  *    A cycle start request received during a feedhold should be deferred until
- *        the feedhold enters a HOLD state (i.e. until deceleration is complete)
- *        If a queue flush request is also present the queue flush should be done first
+ *      the feedhold enters a HOLD state (i.e. until deceleration is complete)
+ *      If a queue flush request is also present the queue flush should be done first
  *    A cycle start request received during a motion stop should be honored and
- *        should start to run anything in the planner queue
+ *      should start to run anything in the planner queue
  */
 
 void cm_request_feedhold() {cm.feedhold_requested = true;}
@@ -1128,8 +1121,9 @@ stat_t cm_feedhold_sequencing_callback() {
   if (cm.feedhold_requested == true) {
     if ((cm.motion_state == MOTION_RUN) && (cm.hold_state == FEEDHOLD_OFF)) {
       cm_set_motion_state(MOTION_HOLD);
-      cm.hold_state = FEEDHOLD_SYNC;    // invokes hold from aline execution
+      cm.hold_state = FEEDHOLD_SYNC;     // invokes hold from aline execution
     }
+
     cm.feedhold_requested = false;
   }
 
@@ -1142,7 +1136,7 @@ stat_t cm_feedhold_sequencing_callback() {
     }
   }
 
-  bool feedhold_processing =                // added feedhold processing lockout from omco fork
+  bool feedhold_processing =              // added feedhold processing lockout from omco fork
     cm.hold_state == FEEDHOLD_SYNC ||
     cm.hold_state == FEEDHOLD_PLAN ||
     cm.hold_state == FEEDHOLD_DECEL;
@@ -1167,11 +1161,11 @@ stat_t cm_queue_flush() {
   rx_request_rx_report();
 
   // Note: The following uses low-level mp calls for absolute position.
-  //         It could also use cm_get_absolute_position(RUNTIME, axis);
+  //   It could also use cm_get_absolute_position(RUNTIME, axis);
   for (uint8_t axis = AXIS_X; axis < AXES; axis++)
     cm_set_position(axis, mp_get_runtime_absolute_position(axis)); // set mm from mr
 
-  float value[AXES] = { (float)MACHINE_PROGRAM_STOP, 0,0,0,0,0 };
+  float value[AXES] = {(float)MACHINE_PROGRAM_STOP, 0,0,0,0,0};
   _exec_program_finalize(value, value);    // finalize now, not later
 
   return STAT_OK;
@@ -1185,8 +1179,8 @@ stat_t cm_queue_flush() {
  * cm_cycle_start()
  * cm_cycle_end()
  * cm_program_stop()            - M0
- * cm_optional_program_stop()    - M1
- * cm_program_end()                - M2, M30
+ * cm_optional_program_stop()   - M1
+ * cm_program_end()             - M2, M30
  *
  * cm_program_end() implements M2 and M30
  * The END behaviors are defined by NIST 3.6.1 are:
@@ -1206,7 +1200,7 @@ stat_t cm_queue_flush() {
  *    2. Selected plane is set to default plane ($gpl) (instead of setting it to G54)
  *    3. Distance mode is set to MODE_ABSOLUTE (like G90)
  *    4. Feed rate mode is set to UNITS_PER_MINUTE (like G94)
- *     5. Not implemented
+ *    5. Not implemented
  *    6. Not implemented
  *    7. The spindle is stopped (like M5)
  *    8. Motion mode is canceled like G80 (not set to G1)
@@ -1217,34 +1211,34 @@ static void _exec_program_finalize(float *value, float *flag) {
   cm.machine_state = (uint8_t)value[0];
   cm_set_motion_state(MOTION_STOP);
   if (cm.cycle_state == CYCLE_MACHINING)
-    cm.cycle_state = CYCLE_OFF;                        // don't end cycle if homing, probing, etc.
+    cm.cycle_state = CYCLE_OFF;                      // don't end cycle if homing, probing, etc.
 
-  cm.hold_state = FEEDHOLD_OFF;                        // end feedhold (if in feed hold)
-  cm.cycle_start_requested = false;                    // cancel any pending cycle start request
-  mp_zero_segment_velocity();                            // for reporting purposes
+  cm.hold_state = FEEDHOLD_OFF;                      // end feedhold (if in feed hold)
+  cm.cycle_start_requested = false;                  // cancel any pending cycle start request
+  mp_zero_segment_velocity();                        // for reporting purposes
 
   // perform the following resets if it's a program END
   if (cm.machine_state == MACHINE_PROGRAM_END) {
-    cm_reset_origin_offsets();                        // G92.1 - we do G91.1 instead of G92.2
+    cm_reset_origin_offsets();                       // G92.1 - we do G91.1 instead of G92.2
     cm_set_coord_system(cm.coord_system);            // reset to default coordinate system
     cm_select_plane(cm.select_plane);                // reset to default arc plane
     cm_set_distance_mode(cm.distance_mode);
-    cm_spindle_control(SPINDLE_OFF);                // M5
-    cm_flood_coolant_control(false);                // M9
+    cm_spindle_control(SPINDLE_OFF);                 // M5
+    cm_flood_coolant_control(false);                 // M9
     cm_set_feed_rate_mode(UNITS_PER_MINUTE_MODE);    // G94
     cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);
   }
 
-  sr_request_status_report(SR_IMMEDIATE_REQUEST);        // request a final status report (not unfiltered)
+  sr_request_status_report(SR_IMMEDIATE_REQUEST);    // request a final status report (not unfiltered)
 }
 
 
 void cm_cycle_start() {
   cm.machine_state = MACHINE_CYCLE;
 
-  if (cm.cycle_state == CYCLE_OFF) {                    // don't (re)start homing, probe or other canned cycles
+  if (cm.cycle_state == CYCLE_OFF) {                 // don't (re)start homing, probe or other canned cycles
     cm.cycle_state = CYCLE_MACHINING;
-    qr_init_queue_report();                            // clear queue reporting buffer counts
+    qr_init_queue_report();                          // clear queue reporting buffer counts
   }
 }
 
@@ -1282,18 +1276,18 @@ void cm_program_end() {
 static const char msg_units0[] PROGMEM = " in";    // used by generic print functions
 static const char msg_units1[] PROGMEM = " mm";
 static const char msg_units2[] PROGMEM = " deg";
-static const char *const msg_units[] PROGMEM = { msg_units0, msg_units1, msg_units2 };
+static const char *const msg_units[] PROGMEM = {msg_units0, msg_units1, msg_units2};
 #define DEGREE_INDEX 2
 
 static const char msg_am00[] PROGMEM = "[disabled]";
 static const char msg_am01[] PROGMEM = "[standard]";
 static const char msg_am02[] PROGMEM = "[inhibited]";
 static const char msg_am03[] PROGMEM = "[radius]";
-static const char *const msg_am[] PROGMEM = { msg_am00, msg_am01, msg_am02, msg_am03};
+static const char *const msg_am[] PROGMEM = {msg_am00, msg_am01, msg_am02, msg_am03};
 
 static const char msg_g20[] PROGMEM = "G20 - inches mode";
 static const char msg_g21[] PROGMEM = "G21 - millimeter mode";
-static const char *const msg_unit[] PROGMEM = { msg_g20, msg_g21 };
+static const char *const msg_unit[] PROGMEM = {msg_g20, msg_g21};
 
 static const char msg_stat0[] PROGMEM = "Initializing";    // combined state (stat) uses this array
 static const char msg_stat1[] PROGMEM = "Ready";
@@ -1307,9 +1301,11 @@ static const char msg_stat8[] PROGMEM = "Cycle";
 static const char msg_stat9[] PROGMEM = "Homing";
 static const char msg_stat10[] PROGMEM = "Jog";
 static const char msg_stat11[] PROGMEM = "Shutdown";
-static const char *const msg_stat[] PROGMEM = { msg_stat0, msg_stat1, msg_stat2, msg_stat3,
-                                                msg_stat4, msg_stat5, msg_stat6, msg_stat7,
-                                                msg_stat8, msg_stat9, msg_stat10, msg_stat11 };
+static const char *const msg_stat[] PROGMEM = {
+  msg_stat0, msg_stat1, msg_stat2, msg_stat3,
+  msg_stat4, msg_stat5, msg_stat6, msg_stat7,
+  msg_stat8, msg_stat9, msg_stat10, msg_stat11
+};
 
 static const char msg_macs0[] PROGMEM = "Initializing";
 static const char msg_macs1[] PROGMEM = "Ready";
@@ -1318,20 +1314,22 @@ static const char msg_macs3[] PROGMEM = "Stop";
 static const char msg_macs4[] PROGMEM = "End";
 static const char msg_macs5[] PROGMEM = "Cycle";
 static const char msg_macs6[] PROGMEM = "Shutdown";
-static const char *const msg_macs[] PROGMEM = { msg_macs0, msg_macs1, msg_macs2, msg_macs3,
-                                                msg_macs4, msg_macs5, msg_macs6 };
+static const char *const msg_macs[] PROGMEM = {
+  msg_macs0, msg_macs1, msg_macs2, msg_macs3,
+  msg_macs4, msg_macs5, msg_macs6
+};
 
 static const char msg_cycs0[] PROGMEM = "Off";
 static const char msg_cycs1[] PROGMEM = "Machining";
 static const char msg_cycs2[] PROGMEM = "Probe";
 static const char msg_cycs3[] PROGMEM = "Homing";
 static const char msg_cycs4[] PROGMEM = "Jog";
-static const char *const msg_cycs[] PROGMEM = { msg_cycs0, msg_cycs1, msg_cycs2, msg_cycs3,  msg_cycs4 };
+static const char *const msg_cycs[] PROGMEM = {msg_cycs0, msg_cycs1, msg_cycs2, msg_cycs3,  msg_cycs4};
 
 static const char msg_mots0[] PROGMEM = "Stop";
 static const char msg_mots1[] PROGMEM = "Run";
 static const char msg_mots2[] PROGMEM = "Hold";
-static const char *const msg_mots[] PROGMEM = { msg_mots0, msg_mots1, msg_mots2 };
+static const char *const msg_mots[] PROGMEM = {msg_mots0, msg_mots1, msg_mots2};
 
 static const char msg_hold0[] PROGMEM = "Off";
 static const char msg_hold1[] PROGMEM = "Sync";
@@ -1339,13 +1337,12 @@ static const char msg_hold2[] PROGMEM = "Plan";
 static const char msg_hold3[] PROGMEM = "Decel";
 static const char msg_hold4[] PROGMEM = "Hold";
 static const char msg_hold5[] PROGMEM = "End Hold";
-static const char *const msg_hold[] PROGMEM = { msg_hold0, msg_hold1, msg_hold2, msg_hold3,
-                                                msg_hold4,  msg_hold5 };
+static const char *const msg_hold[] PROGMEM = {msg_hold0, msg_hold1, msg_hold2, msg_hold3, msg_hold4,  msg_hold5};
 
 static const char msg_home0[] PROGMEM = "Not Homed";
 static const char msg_home1[] PROGMEM = "Homed";
 static const char msg_home2[] PROGMEM = "Homing";
-static const char *const msg_home[] PROGMEM = { msg_home0, msg_home1, msg_home2 };
+static const char *const msg_home[] PROGMEM = {msg_home0, msg_home1, msg_home2};
 
 static const char msg_g53[] PROGMEM = "G53 - machine coordinate system";
 static const char msg_g54[] PROGMEM = "G54 - coordinate system 1";
@@ -1354,33 +1351,33 @@ static const char msg_g56[] PROGMEM = "G56 - coordinate system 3";
 static const char msg_g57[] PROGMEM = "G57 - coordinate system 4";
 static const char msg_g58[] PROGMEM = "G58 - coordinate system 5";
 static const char msg_g59[] PROGMEM = "G59 - coordinate system 6";
-static const char *const msg_coor[] PROGMEM = { msg_g53, msg_g54, msg_g55, msg_g56, msg_g57, msg_g58, msg_g59 };
+static const char *const msg_coor[] PROGMEM = {msg_g53, msg_g54, msg_g55, msg_g56, msg_g57, msg_g58, msg_g59};
 
 static const char msg_g00[] PROGMEM = "G0  - linear traverse (seek)";
 static const char msg_g01[] PROGMEM = "G1  - linear feed";
 static const char msg_g02[] PROGMEM = "G2  - clockwise arc feed";
 static const char msg_g03[] PROGMEM = "G3  - counter clockwise arc feed";
 static const char msg_g80[] PROGMEM = "G80 - cancel motion mode (none active)";
-static const char *const msg_momo[] PROGMEM = { msg_g00, msg_g01, msg_g02, msg_g03, msg_g80 };
+static const char *const msg_momo[] PROGMEM = {msg_g00, msg_g01, msg_g02, msg_g03, msg_g80};
 
 static const char msg_g17[] PROGMEM = "G17 - XY plane";
 static const char msg_g18[] PROGMEM = "G18 - XZ plane";
 static const char msg_g19[] PROGMEM = "G19 - YZ plane";
-static const char *const msg_plan[] PROGMEM = { msg_g17, msg_g18, msg_g19 };
+static const char *const msg_plan[] PROGMEM = {msg_g17, msg_g18, msg_g19};
 
 static const char msg_g61[] PROGMEM = "G61 - exact path mode";
 static const char msg_g6a[] PROGMEM = "G61.1 - exact stop mode";
 static const char msg_g64[] PROGMEM = "G64 - continuous mode";
-static const char *const msg_path[] PROGMEM = { msg_g61, msg_g6a, msg_g64 };
+static const char *const msg_path[] PROGMEM = {msg_g61, msg_g6a, msg_g64};
 
 static const char msg_g90[] PROGMEM = "G90 - absolute distance mode";
 static const char msg_g91[] PROGMEM = "G91 - incremental distance mode";
-static const char *const msg_dist[] PROGMEM = { msg_g90, msg_g91 };
+static const char *const msg_dist[] PROGMEM = {msg_g90, msg_g91};
 
 static const char msg_g93[] PROGMEM = "G93 - inverse time mode";
 static const char msg_g94[] PROGMEM = "G94 - units-per-minute mode (i.e. feedrate mode)";
 static const char msg_g95[] PROGMEM = "G95 - units-per-revolution mode";
-static const char *const msg_frmo[] PROGMEM = { msg_g93, msg_g94, msg_g95 };
+static const char *const msg_frmo[] PROGMEM = {msg_g93, msg_g94, msg_g95};
 
 #else
 
@@ -1402,12 +1399,7 @@ static const char *const msg_frmo[] PROGMEM = { msg_g93, msg_g94, msg_g95 };
 
 #endif // __TEXT_MODE
 
-/***** AXIS HELPERS *****************************************************************
- * cm_get_axis_char() - return ASCII char for axis given the axis number
- * _get_axis()          - return axis number or -1 if NA
- * _get_axis_type()      - return 0 -f axis is linear, 1 if rotary, -1 if NA
- */
-
+/// return ASCII char for axis given the axis number
 char_t cm_get_axis_char(const int8_t axis) {
   char_t axis_char[] = "XYZABC";
   if ((axis < 0) || (axis > AXES)) return ' ';
@@ -1415,14 +1407,15 @@ char_t cm_get_axis_char(const int8_t axis) {
 }
 
 
+/// return axis number or -1 if NA
 static int8_t _get_axis(const index_t index) {
   char_t *ptr;
   char_t tmp[TOKEN_LEN+1];
   char_t axes[] = {"xyzabc"};
 
-  strncpy_P(tmp, cfgArray[index].token, TOKEN_LEN);    // kind of a hack. Looks for an axis
+  strncpy_P(tmp, cfgArray[index].token, TOKEN_LEN);   // kind of a hack. Looks for an axis
   if ((ptr = strchr(axes, tmp[0])) == 0) {            // character in the 0 and 3 positions
-    if ((ptr = strchr(axes, tmp[3])) == 0)        // to accommodate 'xam' and 'g54x' styles
+    if ((ptr = strchr(axes, tmp[3])) == 0)            // to accommodate 'xam' and 'g54x' styles
       return -1;
   }
 
@@ -1430,6 +1423,7 @@ static int8_t _get_axis(const index_t index) {
 }
 
 
+/// return 0 -f axis is linear, 1 if rotary, -1 if NA
 static int8_t _get_axis_type(const index_t index) {
   int8_t axis = _get_axis(index);
   if (axis >= AXIS_A) return 1;
@@ -1472,24 +1466,24 @@ static int8_t _get_axis_type(const index_t index) {
 stat_t _get_msg_helper(nvObj_t *nv, const char *const msg_array[], uint8_t value) {
   nv->value = (float)value;
   nv->valuetype = TYPE_INTEGER;
-  return(nv_copy_string(nv, (const char_t *)GET_TEXT_ITEM(msg_array, value)));
+  return nv_copy_string(nv, (const char_t *)GET_TEXT_ITEM(msg_array, value));
 }
 
 
-stat_t cm_get_stat(nvObj_t *nv) {return(_get_msg_helper(nv, msg_stat, cm_get_combined_state()));}
-stat_t cm_get_macs(nvObj_t *nv) {return(_get_msg_helper(nv, msg_macs, cm_get_machine_state()));}
-stat_t cm_get_cycs(nvObj_t *nv) {return(_get_msg_helper(nv, msg_cycs, cm_get_cycle_state()));}
-stat_t cm_get_mots(nvObj_t *nv) {return(_get_msg_helper(nv, msg_mots, cm_get_motion_state()));}
-stat_t cm_get_hold(nvObj_t *nv) {return(_get_msg_helper(nv, msg_hold, cm_get_hold_state()));}
-stat_t cm_get_home(nvObj_t *nv) {return(_get_msg_helper(nv, msg_home, cm_get_homing_state()));}
+stat_t cm_get_stat(nvObj_t *nv) {return _get_msg_helper(nv, msg_stat, cm_get_combined_state());}
+stat_t cm_get_macs(nvObj_t *nv) {return _get_msg_helper(nv, msg_macs, cm_get_machine_state());}
+stat_t cm_get_cycs(nvObj_t *nv) {return _get_msg_helper(nv, msg_cycs, cm_get_cycle_state());}
+stat_t cm_get_mots(nvObj_t *nv) {return _get_msg_helper(nv, msg_mots, cm_get_motion_state());}
+stat_t cm_get_hold(nvObj_t *nv) {return _get_msg_helper(nv, msg_hold, cm_get_hold_state());}
+stat_t cm_get_home(nvObj_t *nv) {return _get_msg_helper(nv, msg_home, cm_get_homing_state());}
 
-stat_t cm_get_unit(nvObj_t *nv) {return(_get_msg_helper(nv, msg_unit, cm_get_units_mode(ACTIVE_MODEL)));}
-stat_t cm_get_coor(nvObj_t *nv) {return(_get_msg_helper(nv, msg_coor, cm_get_coord_system(ACTIVE_MODEL)));}
-stat_t cm_get_momo(nvObj_t *nv) {return(_get_msg_helper(nv, msg_momo, cm_get_motion_mode(ACTIVE_MODEL)));}
-stat_t cm_get_plan(nvObj_t *nv) {return(_get_msg_helper(nv, msg_plan, cm_get_select_plane(ACTIVE_MODEL)));}
-stat_t cm_get_path(nvObj_t *nv) {return(_get_msg_helper(nv, msg_path, cm_get_path_control(ACTIVE_MODEL)));}
-stat_t cm_get_dist(nvObj_t *nv) {return(_get_msg_helper(nv, msg_dist, cm_get_distance_mode(ACTIVE_MODEL)));}
-stat_t cm_get_frmo(nvObj_t *nv) {return(_get_msg_helper(nv, msg_frmo, cm_get_feed_rate_mode(ACTIVE_MODEL)));}
+stat_t cm_get_unit(nvObj_t *nv) {return _get_msg_helper(nv, msg_unit, cm_get_units_mode(ACTIVE_MODEL));}
+stat_t cm_get_coor(nvObj_t *nv) {return _get_msg_helper(nv, msg_coor, cm_get_coord_system(ACTIVE_MODEL));}
+stat_t cm_get_momo(nvObj_t *nv) {return _get_msg_helper(nv, msg_momo, cm_get_motion_mode(ACTIVE_MODEL));}
+stat_t cm_get_plan(nvObj_t *nv) {return _get_msg_helper(nv, msg_plan, cm_get_select_plane(ACTIVE_MODEL));}
+stat_t cm_get_path(nvObj_t *nv) {return _get_msg_helper(nv, msg_path, cm_get_path_control(ACTIVE_MODEL));}
+stat_t cm_get_dist(nvObj_t *nv) {return _get_msg_helper(nv, msg_dist, cm_get_distance_mode(ACTIVE_MODEL));}
+stat_t cm_get_frmo(nvObj_t *nv) {return _get_msg_helper(nv, msg_frmo, cm_get_feed_rate_mode(ACTIVE_MODEL));}
 
 
 stat_t cm_get_toolv(nvObj_t *nv) {
@@ -1567,7 +1561,7 @@ stat_t cm_get_ofs(nvObj_t *nv) {
  */
 stat_t cm_get_am(nvObj_t *nv) {
   get_ui8(nv);
-  return(_get_msg_helper(nv, msg_am, nv->value));
+  return _get_msg_helper(nv, msg_am, nv->value);
 }
 
 
@@ -1577,7 +1571,7 @@ stat_t cm_set_am(nvObj_t *nv) {        // axis mode
   } else if (nv->value > AXIS_MODE_MAX_ROTARY) return STAT_INPUT_EXCEEDS_MAX_VALUE;
 
   set_ui8(nv);
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 /**** Jerk functions
@@ -1612,14 +1606,14 @@ stat_t cm_set_xjm(nvObj_t *nv) {
   if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER;
   set_flu(nv);
   cm_set_axis_jerk(_get_axis(nv->index), nv->value);
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
 stat_t cm_set_xjh(nvObj_t *nv) {
   if (nv->value > JERK_MULTIPLIER) nv->value /= JERK_MULTIPLIER;
   set_flu(nv);
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 /*
@@ -1702,15 +1696,9 @@ stat_t cm_run_joga(nvObj_t *nv) {
   return STAT_OK;
 }
 
-/***********************************************************************************
- * TEXT MODE SUPPORT
- * Functions to print variables from the cfgArray table
- ***********************************************************************************/
-
 #ifdef __TEXT_MODE
 
-/* model state print functions */
-
+// model state print functions
 const char fmt_vel[]  PROGMEM = "Velocity:%17.3f%s/min\n";
 const char fmt_feed[] PROGMEM = "Feed rate:%16.3f%s/min\n";
 const char fmt_line[] PROGMEM = "Line number:%10.0f\n";
@@ -1779,32 +1767,7 @@ void cm_print_ml(nvObj_t *nv) {text_print_flt_units(nv, fmt_ml, GET_UNITS(ACTIVE
 void cm_print_ma(nvObj_t *nv) {text_print_flt_units(nv, fmt_ma, GET_UNITS(ACTIVE_MODEL));}
 void cm_print_ms(nvObj_t *nv) {text_print_flt_units(nv, fmt_ms, GET_UNITS(ACTIVE_MODEL));}
 
-/*
- * axis print functions
- *
- *    _print_axis_ui8() - helper to print an integer value with no units
- *    _print_axis_flt() - helper to print a floating point linear value in prevailing units
- *    _print_pos_helper()
- *
- *    cm_print_am()
- *    cm_print_fr()
- *    cm_print_vm()
- *    cm_print_tm()
- *    cm_print_tn()
- *    cm_print_jm()
- *    cm_print_jh()
- *    cm_print_jd()
- *    cm_print_ra()
- *    cm_print_sn()
- *    cm_print_sx()
- *    cm_print_lv()
- *    cm_print_lb()
- *    cm_print_zb()
- *
- *    cm_print_pos() - print position with unit displays for MM or Inches
- *     cm_print_mpo() - print position with fixed unit display - always in Degrees or MM
- */
-
+// axis print functions
 static const char fmt_Xam[] PROGMEM = "[%s%s] %s axis mode%18d %s\n";
 static const char fmt_Xfr[] PROGMEM = "[%s%s] %s feedrate maximum%11.0f%s/min\n";
 static const char fmt_Xvm[] PROGMEM = "[%s%s] %s velocity maximum%11.0f%s/min\n";
@@ -1824,11 +1787,13 @@ static const char fmt_cofs[] PROGMEM = "[%s%s] %s %s offset%20.3f%s\n";
 static const char fmt_cpos[] PROGMEM = "[%s%s] %s %s position%18.3f%s\n";
 
 
+/// helper to print an integer value with no units
 static void _print_axis_ui8(nvObj_t *nv, const char *format) {
   fprintf_P(stderr, format, nv->group, nv->token, nv->group, (uint8_t)nv->value);
 }
 
 
+/// helper to print a floating point linear value in prevailing units
 static void _print_axis_flt(nvObj_t *nv, const char *format) {
   char *units;
   if (_get_axis_type(nv->index) == 0)    // linear
@@ -1849,6 +1814,7 @@ static void _print_axis_coord_flt(nvObj_t *nv, const char *format) {
 }
 
 
+/// print position with unit displays for MM or Inches
 static void _print_pos(nvObj_t *nv, const char *format, uint8_t units) {
   char axes[] = {"XYZABC"};
   uint8_t axis = _get_axis(nv->index);
@@ -1882,6 +1848,7 @@ void cm_print_cofs(nvObj_t *nv) {_print_axis_coord_flt(nv, fmt_cofs);}
 void cm_print_cpos(nvObj_t *nv) {_print_axis_coord_flt(nv, fmt_cpos);}
 
 void cm_print_pos(nvObj_t *nv) {_print_pos(nv, fmt_pos, cm_get_units_mode(MODEL));}
+/// print position with fixed unit display - always in Degrees or MM
 void cm_print_mpo(nvObj_t *nv) {_print_pos(nv, fmt_mpo, MILLIMETERS);}
 void cm_print_ofs(nvObj_t *nv) {_print_pos(nv, fmt_ofs, MILLIMETERS);}
 
index 529a6cbb9c6a0700ac4eca7fa6b80b838be71c62..ff076c060ea175540a6eb26b246450f88e195f0b 100644 (file)
 
 #include "config.h"
 
-/* Defines, Macros, and  Assorted Parameters */
-
-#define MODEL     (GCodeState_t *)&cm.gm        // absolute pointer from canonical machine gm model
-#define PLANNER (GCodeState_t *)&bf->gm        // relative to buffer *bf is currently pointing to
+#define MODEL   (GCodeState_t *)&cm.gm        // absolute pointer from canonical machine gm model
+#define PLANNER (GCodeState_t *)&bf->gm       // relative to buffer *bf is currently pointing to
 #define RUNTIME (GCodeState_t *)&mr.gm        // absolute pointer from runtime mm struct
 #define ACTIVE_MODEL cm.am                    // active model pointer is maintained by state management
 
@@ -45,6 +43,7 @@
 #define JOGGING_START_VELOCITY ((float)10.0)
 #define DISABLE_SOFT_LIMIT (-1000000)
 
+
 /*****************************************************************************
  * GCODE MODEL - The following GCodeModel/GCodeInput structs are used:
  *
@@ -60,7 +59,7 @@
  *     machine and do not need to be passed further down.
  *
  * - gn is used by the gcode interpreter and is re-initialized for each
- *   gcode block.It accepts data in the new gcode block in the formats
+ *     gcode block.It accepts data in the new gcode block in the formats
  *     present in the block (pre-normalized forms). During initialization
  *     some state elements are necessarily restored from gm.
  *
  *     G92 offsets. cfg has the power-on / reset gcode default values, but gm has
  *     the operating state for the values (which may have changed).
  */
-typedef struct GCodeState {                // Gcode model state - used by model, planning and runtime
-    uint32_t linenum;                    // Gcode block line number
-    uint8_t motion_mode;                // Group1: G0, G1, G2, G3, G38.2, G80, G81,
-                                        // G82, G83 G84, G85, G86, G87, G88, G89
-    float target[AXES];                 // XYZABC where the move should go
-    float work_offset[AXES];            // offset from the work coordinate system (for reporting only)
-
-    float move_time;                    // optimal time for move given axis constraints
-    float minimum_time;                    // minimum time possible for move given axis constraints
-    float feed_rate;                     // F - normalized to millimeters/minute or in inverse time mode
-
-    float spindle_speed;                // in RPM
-    float parameter;                    // P - parameter used for dwell time in seconds, G10 coord select...
-
-    uint8_t feed_rate_mode;                // See cmFeedRateMode for settings
-    uint8_t select_plane;                // G17,G18,G19 - values to set plane to
-    uint8_t units_mode;                    // G20,G21 - 0=inches (G20), 1 = mm (G21)
-    uint8_t coord_system;                // G54-G59 - select coordinate system 1-9
-    uint8_t absolute_override;            // G53 TRUE = move using machine coordinates - this block only (G53)
-    uint8_t path_control;                // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS
-    uint8_t distance_mode;                // G91   0=use absolute coords(G90), 1=incremental movement
-    uint8_t arc_distance_mode;            // G91.1   0=use absolute coords(G90), 1=incremental movement
-    uint8_t tool;                        // M6 tool change - moves "tool_select" to "tool"
-    uint8_t tool_select;                // T value - T sets this value
-    uint8_t mist_coolant;                // TRUE = mist on (M7), FALSE = off (M9)
-    uint8_t flood_coolant;                // TRUE = flood on (M8), FALSE = off (M9)
-    uint8_t spindle_mode;                // 0=OFF (M5), 1=CW (M3), 2=CCW (M4)
-
+typedef struct GCodeState {           // Gcode model state - used by model, planning and runtime
+  uint32_t linenum;                   // Gcode block line number
+  uint8_t motion_mode;                // Group1: G0, G1, G2, G3, G38.2, G80, G81,
+  // G82, G83 G84, G85, G86, G87, G88, G89
+  float target[AXES];                 // XYZABC where the move should go
+  float work_offset[AXES];            // offset from the work coordinate system (for reporting only)
+
+  float move_time;                    // optimal time for move given axis constraints
+  float minimum_time;                 // minimum time possible for move given axis constraints
+  float feed_rate;                    // F - normalized to millimeters/minute or in inverse time mode
+
+  float spindle_speed;                // in RPM
+  float parameter;                    // P - parameter used for dwell time in seconds, G10 coord select...
+
+  uint8_t feed_rate_mode;             // See cmFeedRateMode for settings
+  uint8_t select_plane;               // G17,G18,G19 - values to set plane to
+  uint8_t units_mode;                 // G20,G21 - 0=inches (G20), 1 = mm (G21)
+  uint8_t coord_system;               // G54-G59 - select coordinate system 1-9
+  uint8_t absolute_override;          // G53 TRUE = move using machine coordinates - this block only (G53)
+  uint8_t path_control;               // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS
+  uint8_t distance_mode;              // G91   0=use absolute coords(G90), 1=incremental movement
+  uint8_t arc_distance_mode;          // G91.1   0=use absolute coords(G90), 1=incremental movement
+  uint8_t tool;                       // M6 tool change - moves "tool_select" to "tool"
+  uint8_t tool_select;                // T value - T sets this value
+  uint8_t mist_coolant;               // TRUE = mist on (M7), FALSE = off (M9)
+  uint8_t flood_coolant;              // TRUE = flood on (M8), FALSE = off (M9)
+  uint8_t spindle_mode;               // 0=OFF (M5), 1=CW (M3), 2=CCW (M4)
 } GCodeState_t;
 
-typedef struct GCodeStateExtended {        // Gcode dynamic state extensions - used by model and arcs
-    uint16_t magic_start;                // magic number to test memory integrity
-    uint8_t next_action;                // handles G modal group 1 moves & non-modals
-    uint8_t program_flow;                // used only by the gcode_parser
 
-    float position[AXES];                // XYZABC model position (Note: not used in gn or gf)
-    float origin_offset[AXES];            // XYZABC G92 offsets (Note: not used in gn or gf)
-    float g28_position[AXES];            // XYZABC stored machine position for G28
-    float g30_position[AXES];            // XYZABC stored machine position for G30
+typedef struct GCodeStateExtended {   // Gcode dynamic state extensions - used by model and arcs
+  uint16_t magic_start;               // magic number to test memory integrity
+  uint8_t next_action;                // handles G modal group 1 moves & non-modals
+  uint8_t program_flow;               // used only by the gcode_parser
 
-    float feed_rate_override_factor;    // 1.0000 x F feed rate. Go up or down from there
-    float traverse_override_factor;        // 1.0000 x traverse rate. Go down from there
-    uint8_t    feed_rate_override_enable;    // TRUE = overrides enabled (M48), F=(M49)
-    uint8_t    traverse_override_enable;    // TRUE = traverse override enabled
-    uint8_t l_word;                        // L word - used by G10s
+  float position[AXES];               // XYZABC model position (Note: not used in gn or gf)
+  float origin_offset[AXES];          // XYZABC G92 offsets (Note: not used in gn or gf)
+  float g28_position[AXES];           // XYZABC stored machine position for G28
+  float g30_position[AXES];           // XYZABC stored machine position for G30
 
-    uint8_t origin_offset_enable;        // G92 offsets enabled/disabled.  0=disabled, 1=enabled
-    uint8_t block_delete_switch;        // set true to enable block deletes (true is default)
+  float feed_rate_override_factor;    // 1.0000 x F feed rate. Go up or down from there
+  float traverse_override_factor;     // 1.0000 x traverse rate. Go down from there
+  uint8_t feed_rate_override_enable;  // TRUE = overrides enabled (M48), F=(M49)
+  uint8_t traverse_override_enable;   // TRUE = traverse override enabled
+  uint8_t l_word;                     // L word - used by G10s
 
-    float spindle_override_factor;        // 1.0000 x S spindle speed. Go up or down from there
-    uint8_t    spindle_override_enable;    // TRUE = override enabled
+  uint8_t origin_offset_enable;       // G92 offsets enabled/disabled.  0=disabled, 1=enabled
+  uint8_t block_delete_switch;        // set true to enable block deletes (true is default)
 
-// unimplemented gcode parameters
-//    float cutter_radius;                // D - cutter radius compensation (0 is off)
-//    float cutter_length;                // H - cutter length compensation (0 is off)
+  float spindle_override_factor;      // 1.0000 x S spindle speed. Go up or down from there
+  uint8_t spindle_override_enable;    // TRUE = override enabled
 
-    uint16_t magic_end;
+  // unimplemented gcode parameters
+  //    float cutter_radius;                // D - cutter radius compensation (0 is off)
+  //    float cutter_length;                // H - cutter length compensation (0 is off)
 
+  uint16_t magic_end;
 } GCodeStateX_t;
 
-typedef struct GCodeInput {                // Gcode model inputs - meaning depends on context
-    uint8_t next_action;                // handles G modal group 1 moves & non-modals
-    uint8_t motion_mode;                // Group1: G0, G1, G2, G3, G38.2, G80, G81,
-                                        // G82, G83 G84, G85, G86, G87, G88, G89
-    uint8_t program_flow;                // used only by the gcode_parser
-    uint32_t linenum;                    // N word or autoincrement in the model
-
-    float target[AXES];                 // XYZABC where the move should go
-
-    float feed_rate;                     // F - normalized to millimeters/minute
-    float feed_rate_override_factor;    // 1.0000 x F feed rate. Go up or down from there
-    float traverse_override_factor;        // 1.0000 x traverse rate. Go down from there
-    uint8_t feed_rate_mode;                // See cmFeedRateMode for settings
-    uint8_t    feed_rate_override_enable;    // TRUE = overrides enabled (M48), F=(M49)
-    uint8_t    traverse_override_enable;    // TRUE = traverse override enabled
-    uint8_t override_enables;            // enables for feed and spoindle (GN/GF only)
-    uint8_t l_word;                        // L word - used by G10s
-
-    uint8_t select_plane;                // G17,G18,G19 - values to set plane to
-    uint8_t units_mode;                    // G20,G21 - 0=inches (G20), 1 = mm (G21)
-    uint8_t coord_system;                // G54-G59 - select coordinate system 1-9
-    uint8_t absolute_override;            // G53 TRUE = move using machine coordinates - this block only (G53)
-    uint8_t origin_offset_mode;            // G92...TRUE=in origin offset mode
-    uint8_t path_control;                // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS
-    uint8_t distance_mode;                // G91   0=use absolute coords(G90), 1=incremental movement
-    uint8_t arc_distance_mode;            // G91.1   0=use absolute coords(G90), 1=incremental movement
-
-    uint8_t tool;                        // Tool after T and M6 (tool_select and tool_change)
-    uint8_t tool_select;                // T value - T sets this value
-    uint8_t tool_change;                // M6 tool change flag - moves "tool_select" to "tool"
-    uint8_t mist_coolant;                // TRUE = mist on (M7), FALSE = off (M9)
-    uint8_t flood_coolant;                // TRUE = flood on (M8), FALSE = off (M9)
-
-    uint8_t spindle_mode;                // 0=OFF (M5), 1=CW (M3), 2=CCW (M4)
-    float spindle_speed;                // in RPM
-    float spindle_override_factor;        // 1.0000 x S spindle speed. Go up or down from there
-    uint8_t    spindle_override_enable;    // TRUE = override enabled
-
-    float parameter;                    // P - parameter used for dwell time in seconds, G10 coord select...
-    float arc_radius;                    // R - radius value in arc radius mode
-    float arc_offset[3];                  // IJK - used by arc commands
-
-// unimplemented gcode parameters
-//    float cutter_radius;                // D - cutter radius compensation (0 is off)
-//    float cutter_length;                // H - cutter length compensation (0 is off)
 
+typedef struct GCodeInput {             // Gcode model inputs - meaning depends on context
+  uint8_t next_action;                // handles G modal group 1 moves & non-modals
+  uint8_t motion_mode;                // Group1: G0, G1, G2, G3, G38.2, G80, G81,
+  // G82, G83 G84, G85, G86, G87, G88, G89
+  uint8_t program_flow;               // used only by the gcode_parser
+  uint32_t linenum;                   // N word or autoincrement in the model
+
+  float target[AXES];                 // XYZABC where the move should go
+
+  float feed_rate;                    // F - normalized to millimeters/minute
+  float feed_rate_override_factor;    // 1.0000 x F feed rate. Go up or down from there
+  float traverse_override_factor;     // 1.0000 x traverse rate. Go down from there
+  uint8_t feed_rate_mode;             // See cmFeedRateMode for settings
+  uint8_t feed_rate_override_enable;  // TRUE = overrides enabled (M48), F=(M49)
+  uint8_t traverse_override_enable;   // TRUE = traverse override enabled
+  uint8_t override_enables;           // enables for feed and spoindle (GN/GF only)
+  uint8_t l_word;                     // L word - used by G10s
+
+  uint8_t select_plane;               // G17,G18,G19 - values to set plane to
+  uint8_t units_mode;                 // G20,G21 - 0=inches (G20), 1 = mm (G21)
+  uint8_t coord_system;               // G54-G59 - select coordinate system 1-9
+  uint8_t absolute_override;          // G53 TRUE = move using machine coordinates - this block only (G53)
+  uint8_t origin_offset_mode;         // G92...TRUE=in origin offset mode
+  uint8_t path_control;               // G61... EXACT_PATH, EXACT_STOP, CONTINUOUS
+  uint8_t distance_mode;              // G91   0=use absolute coords(G90), 1=incremental movement
+  uint8_t arc_distance_mode;          // G91.1   0=use absolute coords(G90), 1=incremental movement
+
+  uint8_t tool;                       // Tool after T and M6 (tool_select and tool_change)
+  uint8_t tool_select;                // T value - T sets this value
+  uint8_t tool_change;                // M6 tool change flag - moves "tool_select" to "tool"
+  uint8_t mist_coolant;               // TRUE = mist on (M7), FALSE = off (M9)
+  uint8_t flood_coolant;              // TRUE = flood on (M8), FALSE = off (M9)
+
+  uint8_t spindle_mode;               // 0=OFF (M5), 1=CW (M3), 2=CCW (M4)
+  float spindle_speed;                // in RPM
+  float spindle_override_factor;      // 1.0000 x S spindle speed. Go up or down from there
+  uint8_t spindle_override_enable;    // TRUE = override enabled
+
+  float parameter;                    // P - parameter used for dwell time in seconds, G10 coord select...
+  float arc_radius;                   // R - radius value in arc radius mode
+  float arc_offset[3];                // IJK - used by arc commands
+
+  // unimplemented gcode parameters
+  //   float cutter_radius;              // D - cutter radius compensation (0 is off)
+  //   float cutter_length;              // H - cutter length compensation (0 is off)
 } GCodeInput_t;
 
-/*****************************************************************************
- * CANONICAL MACHINE STRUCTURES
- */
 
 typedef struct cmAxis {
-    uint8_t axis_mode;                    // see tgAxisMode in gcode.h
-    float feedrate_max;                    // max velocity in mm/min or deg/min
-    float velocity_max;                    // max velocity in mm/min or deg/min
-    float travel_max;                    // max work envelope for soft limits
-    float travel_min;                    // min work envelope for soft limits
-    float jerk_max;                        // max jerk (Jm) in mm/min^3 divided by 1 million
-    float jerk_homing;                    // homing jerk (Jh) in mm/min^3 divided by 1 million
-    float recip_jerk;                    // stored reciprocal of current jerk value - has the million in it
-    float junction_dev;                    // aka cornering delta
-    float radius;                        // radius in mm for rotary axis modes
-    float search_velocity;                // homing search velocity
-    float latch_velocity;                // homing latch velocity
-    float latch_backoff;                // backoff from switches prior to homing latch movement
-    float zero_backoff;                    // backoff from switches for machine zero
+  uint8_t axis_mode;                   // see tgAxisMode in gcode.h
+  float feedrate_max;                  // max velocity in mm/min or deg/min
+  float velocity_max;                  // max velocity in mm/min or deg/min
+  float travel_max;                    // max work envelope for soft limits
+  float travel_min;                    // min work envelope for soft limits
+  float jerk_max;                      // max jerk (Jm) in mm/min^3 divided by 1 million
+  float jerk_homing;                   // homing jerk (Jh) in mm/min^3 divided by 1 million
+  float recip_jerk;                    // stored reciprocal of current jerk value - has the million in it
+  float junction_dev;                  // aka cornering delta
+  float radius;                        // radius in mm for rotary axis modes
+  float search_velocity;               // homing search velocity
+  float latch_velocity;                // homing latch velocity
+  float latch_backoff;                 // backoff from switches prior to homing latch movement
+  float zero_backoff;                  // backoff from switches for machine zero
 } cfgAxis_t;
 
-typedef struct cmSingleton {            // struct to manage cm globals and cycles
-    magic_t magic_start;                // magic number to test memory integrity
-
-    /**** Config variables (PUBLIC) ****/
-
-    // system group settings
-    float junction_acceleration;        // centripetal acceleration max for cornering
-    float chordal_tolerance;            // arc chordal accuracy setting in mm
-    uint8_t soft_limit_enable;
-
-    // hidden system settings
-    float min_segment_len;                // line drawing resolution in mm
-    float arc_segment_len;                // arc drawing resolution in mm
-    float estd_segment_usec;            // approximate segment time in microseconds
-
-    // gcode power-on default settings - defaults are not the same as the gm state
-    uint8_t coord_system;                // G10 active coordinate system default
-    uint8_t select_plane;                // G17,G18,G19 reset default
-    uint8_t units_mode;                    // G20,G21 reset default
-    uint8_t path_control;                // G61,G61.1,G64 reset default
-    uint8_t distance_mode;                // G90,G91 reset default
-
-    // coordinate systems and offsets
-    float offset[COORDS+1][AXES];        // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59
-
-    // settings for axes X,Y,Z,A B,C
-    cfgAxis_t a[AXES];
-
-    /**** Runtime variables (PRIVATE) ****/
-
-    uint8_t combined_state;                // stat: combination of states for display purposes
-    uint8_t machine_state;                // macs: machine/cycle/motion is the actual machine state
-    uint8_t cycle_state;                // cycs
-    uint8_t motion_state;                // momo
-    uint8_t hold_state;                    // hold: feedhold sub-state machine
-    uint8_t homing_state;                // home: homing cycle sub-state machine
-    uint8_t homed[AXES];                // individual axis homing flags
-
-    uint8_t probe_state;                // 1==success, 0==failed
-    float probe_results[AXES];            // probing results
-
-    uint8_t    g28_flag;                    // true = complete a G28 move
-    uint8_t    g30_flag;                    // true = complete a G30 move
-    uint8_t deferred_write_flag;        // G10 data has changed (e.g. offsets) - flag to persist them
-    uint8_t feedhold_requested;            // feedhold character has been received
-    uint8_t queue_flush_requested;        // queue flush character has been received
-    uint8_t cycle_start_requested;        // cycle start character has been received (flag to end feedhold)
-    float jogging_dest;                    // jogging direction as a relative move from current position
-    struct GCodeState *am;                // active Gcode model is maintained by state management
-
-    /**** Model states ****/
-    GCodeState_t  gm;                    // core gcode model state
-    GCodeStateX_t gmx;                    // extended gcode model state
-    GCodeInput_t  gn;                    // gcode input values - transient
-    GCodeInput_t  gf;                    // gcode input flags - transient
-
-    magic_t magic_end;
+
+typedef struct cmSingleton {          // struct to manage cm globals and cycles
+  magic_t magic_start;                // magic number to test memory integrity
+
+  // Public
+  // system group settings
+  float junction_acceleration;        // centripetal acceleration max for cornering
+  float chordal_tolerance;            // arc chordal accuracy setting in mm
+  uint8_t soft_limit_enable;
+
+  // hidden system settings
+  float min_segment_len;              // line drawing resolution in mm
+  float arc_segment_len;              // arc drawing resolution in mm
+  float estd_segment_usec;            // approximate segment time in microseconds
+
+  // gcode power-on default settings - defaults are not the same as the gm state
+  uint8_t coord_system;                // G10 active coordinate system default
+  uint8_t select_plane;                // G17,G18,G19 reset default
+  uint8_t units_mode;                  // G20,G21 reset default
+  uint8_t path_control;                // G61,G61.1,G64 reset default
+  uint8_t distance_mode;               // G90,G91 reset default
+
+  // coordinate systems and offsets
+  float offset[COORDS+1][AXES];        // persistent coordinate offsets: absolute (G53) + G54,G55,G56,G57,G58,G59
+
+  // settings for axes X,Y,Z,A B,C
+  cfgAxis_t a[AXES];
+
+  // Private
+  uint8_t combined_state;              // stat: combination of states for display purposes
+  uint8_t machine_state;               // macs: machine/cycle/motion is the actual machine state
+  uint8_t cycle_state;                 // cycs
+  uint8_t motion_state;                // momo
+  uint8_t hold_state;                  // hold: feedhold sub-state machine
+  uint8_t homing_state;                // home: homing cycle sub-state machine
+  uint8_t homed[AXES];                 // individual axis homing flags
+
+  uint8_t probe_state;                 // 1==success, 0==failed
+  float probe_results[AXES];           // probing results
+
+  uint8_t g28_flag;                    // true = complete a G28 move
+  uint8_t g30_flag;                    // true = complete a G30 move
+  uint8_t deferred_write_flag;         // G10 data has changed (e.g. offsets) - flag to persist them
+  uint8_t feedhold_requested;          // feedhold character has been received
+  uint8_t queue_flush_requested;       // queue flush character has been received
+  uint8_t cycle_start_requested;       // cycle start character has been received (flag to end feedhold)
+  float jogging_dest;                  // jogging direction as a relative move from current position
+  struct GCodeState *am;               // active Gcode model is maintained by state management
+
+  // Model states
+  GCodeState_t  gm;                    // core gcode model state
+  GCodeStateX_t gmx;                   // extended gcode model state
+  GCodeInput_t  gn;                    // gcode input values - transient
+  GCodeInput_t  gf;                    // gcode input flags - transient
+
+  magic_t magic_end;
 } cmSingleton_t;
 
-/**** Externs - See canonical_machine.c for allocation ****/
 
-extern cmSingleton_t cm;                // canonical machine controller singleton
+extern cmSingleton_t cm;               // canonical machine controller singleton
+
 
 /*****************************************************************************
  * MACHINE STATE MODEL
@@ -277,236 +271,251 @@ extern cmSingleton_t cm;                // canonical machine controller singleto
  */
 /*    Allowed states and combined states
  *
- *    MACHINE STATE        CYCLE STATE        MOTION_STATE        COMBINED_STATE (FYI)
- *    -------------        ------------    -------------        --------------------
- *    MACHINE_UNINIT        na                na                    (U)
- *    MACHINE_READY        CYCLE_OFF        MOTION_STOP            (ROS) RESET-OFF-STOP
- *    MACHINE_PROG_STOP    CYCLE_OFF        MOTION_STOP            (SOS) STOP-OFF-STOP
- *    MACHINE_PROG_END    CYCLE_OFF        MOTION_STOP            (EOS) END-OFF-STOP
+ *    MACHINE STATE        CYCLE STATE      MOTION_STATE         COMBINED_STATE (FYI)
+ *    -------------        ------------     -------------        --------------------
+ *    MACHINE_UNINIT       na               na                   (U)
+ *    MACHINE_READY        CYCLE_OFF        MOTION_STOP          (ROS) RESET-OFF-STOP
+ *    MACHINE_PROG_STOP    CYCLE_OFF        MOTION_STOP          (SOS) STOP-OFF-STOP
+ *    MACHINE_PROG_END     CYCLE_OFF        MOTION_STOP          (EOS) END-OFF-STOP
  *
- *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_STOP            (CSS) CYCLE-START-STOP
- *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_RUN            (CSR) CYCLE-START-RUN
- *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_HOLD            (CSH) CYCLE-START-HOLD
- *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_END_HOLD        (CSE) CYCLE-START-END_HOLD
+ *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_STOP          (CSS) CYCLE-START-STOP
+ *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_RUN           (CSR) CYCLE-START-RUN
+ *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_HOLD          (CSH) CYCLE-START-HOLD
+ *    MACHINE_CYCLE        CYCLE_STARTED    MOTION_END_HOLD      (CSE) CYCLE-START-END_HOLD
  *
- *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_STOP            (CHS) CYCLE-HOMING-STOP
+ *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_STOP           (CHS) CYCLE-HOMING-STOP
  *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_RUN            (CHR) CYCLE-HOMING-RUN
- *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_HOLD            (CHH) CYCLE-HOMING-HOLD
- *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_END_HOLD        (CHE) CYCLE-HOMING-END_HOLD
+ *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_HOLD           (CHH) CYCLE-HOMING-HOLD
+ *    MACHINE_CYCLE        CYCLE_HOMING    MOTION_END_HOLD       (CHE) CYCLE-HOMING-END_HOLD
  */
 // *** Note: check config printout strings align with all the state variables
 
 // ### LAYER 8 CRITICAL REGION ###
 // ### DO NOT CHANGE THESE ENUMERATIONS WITHOUT COMMUNITY INPUT ###
-enum cmCombinedState {                // check alignment with messages in config.c / msg_stat strings
-    COMBINED_INITIALIZING = 0,        // [0] machine is initializing
-    COMBINED_READY,                    // [1] machine is ready for use. Also used to force STOP state for null moves
-    COMBINED_ALARM,                    // [2] machine in soft alarm state
-    COMBINED_PROGRAM_STOP,            // [3] program stop or no more blocks
-    COMBINED_PROGRAM_END,            // [4] program end
-    COMBINED_RUN,                    // [5] motion is running
-    COMBINED_HOLD,                    // [6] motion is holding
-    COMBINED_PROBE,                    // [7] probe cycle active
-    COMBINED_CYCLE,                    // [8] machine is running (cycling)
-    COMBINED_HOMING,                // [9] homing is treated as a cycle
-    COMBINED_JOG,                    // [10] jogging is treated as a cycle
-    COMBINED_SHUTDOWN,                // [11] machine in hard alarm state (shutdown)
+enum cmCombinedState {              // check alignment with messages in config.c / msg_stat strings
+  COMBINED_INITIALIZING = 0,        // [0] machine is initializing
+  COMBINED_READY,                   // [1] machine is ready for use. Also used to force STOP state for null moves
+  COMBINED_ALARM,                   // [2] machine in soft alarm state
+  COMBINED_PROGRAM_STOP,            // [3] program stop or no more blocks
+  COMBINED_PROGRAM_END,             // [4] program end
+  COMBINED_RUN,                     // [5] motion is running
+  COMBINED_HOLD,                    // [6] motion is holding
+  COMBINED_PROBE,                   // [7] probe cycle active
+  COMBINED_CYCLE,                   // [8] machine is running (cycling)
+  COMBINED_HOMING,                  // [9] homing is treated as a cycle
+  COMBINED_JOG,                     // [10] jogging is treated as a cycle
+  COMBINED_SHUTDOWN,                // [11] machine in hard alarm state (shutdown)
 };
 //### END CRITICAL REGION ###
 
+
 enum cmMachineState {
-    MACHINE_INITIALIZING = 0,        // machine is initializing
-    MACHINE_READY,                    // machine is ready for use
-    MACHINE_ALARM,                    // machine in soft alarm state
-    MACHINE_PROGRAM_STOP,            // program stop or no more blocks
-    MACHINE_PROGRAM_END,            // program end
-    MACHINE_CYCLE,                    // machine is running (cycling)
-    MACHINE_SHUTDOWN,                // machine in hard alarm state (shutdown)
+  MACHINE_INITIALIZING = 0,         // machine is initializing
+  MACHINE_READY,                    // machine is ready for use
+  MACHINE_ALARM,                    // machine in soft alarm state
+  MACHINE_PROGRAM_STOP,             // program stop or no more blocks
+  MACHINE_PROGRAM_END,              // program end
+  MACHINE_CYCLE,                    // machine is running (cycling)
+  MACHINE_SHUTDOWN,                 // machine in hard alarm state (shutdown)
 };
 
+
 enum cmCycleState {
-    CYCLE_OFF = 0,                    // machine is idle
-    CYCLE_MACHINING,                // in normal machining cycle
-    CYCLE_PROBE,                    // in probe cycle
-    CYCLE_HOMING,                    // homing is treated as a specialized cycle
-    CYCLE_JOG                        // jogging is treated as a specialized cycle
+  CYCLE_OFF = 0,                    // machine is idle
+  CYCLE_MACHINING,                  // in normal machining cycle
+  CYCLE_PROBE,                      // in probe cycle
+  CYCLE_HOMING,                     // homing is treated as a specialized cycle
+  CYCLE_JOG                         // jogging is treated as a specialized cycle
 };
 
+
 enum cmMotionState {
-    MOTION_STOP = 0,                // motion has stopped
-    MOTION_RUN,                        // machine is in motion
-    MOTION_HOLD                        // feedhold in progress
+  MOTION_STOP = 0,                  // motion has stopped
+  MOTION_RUN,                       // machine is in motion
+  MOTION_HOLD                       // feedhold in progress
 };
 
-enum cmFeedholdState {                // feedhold_state machine
-    FEEDHOLD_OFF = 0,                // no feedhold in effect
-    FEEDHOLD_SYNC,                     // start hold - sync to latest aline segment
-    FEEDHOLD_PLAN,                     // replan blocks for feedhold
-    FEEDHOLD_DECEL,                    // decelerate to hold point
-    FEEDHOLD_HOLD,                    // holding
-    FEEDHOLD_END_HOLD                // end hold (transient state to OFF)
+
+enum cmFeedholdState {              // feedhold_state machine
+  FEEDHOLD_OFF = 0,                 // no feedhold in effect
+  FEEDHOLD_SYNC,                    // start hold - sync to latest aline segment
+  FEEDHOLD_PLAN,                    // replan blocks for feedhold
+  FEEDHOLD_DECEL,                   // decelerate to hold point
+  FEEDHOLD_HOLD,                    // holding
+  FEEDHOLD_END_HOLD                 // end hold (transient state to OFF)
 };
 
+
 enum cmHomingState {                // applies to cm.homing_state
-    HOMING_NOT_HOMED = 0,            // machine is not homed (0=false)
-    HOMING_HOMED = 1,                // machine is homed (1=true)
-    HOMING_WAITING                    // machine waiting to be homed
+  HOMING_NOT_HOMED = 0,             // machine is not homed (0=false)
+  HOMING_HOMED = 1,                 // machine is homed (1=true)
+  HOMING_WAITING                    // machine waiting to be homed
 };
 
-enum cmProbeState {                    // applies to cm.probe_state
-    PROBE_FAILED = 0,                // probe reached endpoint without triggering
-    PROBE_SUCCEEDED = 1,            // probe was triggered, cm.probe_results has position
-    PROBE_WAITING                    // probe is waiting to be started
+
+enum cmProbeState {                 // applies to cm.probe_state
+  PROBE_FAILED = 0,                 // probe reached endpoint without triggering
+  PROBE_SUCCEEDED = 1,              // probe was triggered, cm.probe_results has position
+  PROBE_WAITING                     // probe is waiting to be started
 };
 
+
 /* The difference between NextAction and MotionMode is that NextAction is
  * used by the current block, and may carry non-modal commands, whereas
  * MotionMode persists across blocks (as G modal group 1)
  */
-
-enum cmNextAction {                        // these are in order to optimized CASE statement
-    NEXT_ACTION_DEFAULT = 0,            // Must be zero (invokes motion modes)
-    NEXT_ACTION_SEARCH_HOME,            // G28.2 homing cycle
-    NEXT_ACTION_SET_ABSOLUTE_ORIGIN,    // G28.3 origin set
-    NEXT_ACTION_HOMING_NO_SET,            // G28.4 homing cycle with no coordinate setting
-    NEXT_ACTION_SET_G28_POSITION,        // G28.1 set position in abs coordinates
-    NEXT_ACTION_GOTO_G28_POSITION,        // G28 go to machine position
-    NEXT_ACTION_SET_G30_POSITION,        // G30.1
-    NEXT_ACTION_GOTO_G30_POSITION,        // G30
-    NEXT_ACTION_SET_COORD_DATA,            // G10
-    NEXT_ACTION_SET_ORIGIN_OFFSETS,        // G92
-    NEXT_ACTION_RESET_ORIGIN_OFFSETS,    // G92.1
-    NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS,    // G92.2
-    NEXT_ACTION_RESUME_ORIGIN_OFFSETS,    // G92.3
-    NEXT_ACTION_DWELL,                    // G4
-    NEXT_ACTION_STRAIGHT_PROBE            // G38.2
+enum cmNextAction {                   // these are in order to optimized CASE statement
+  NEXT_ACTION_DEFAULT = 0,            // Must be zero (invokes motion modes)
+  NEXT_ACTION_SEARCH_HOME,            // G28.2 homing cycle
+  NEXT_ACTION_SET_ABSOLUTE_ORIGIN,    // G28.3 origin set
+  NEXT_ACTION_HOMING_NO_SET,          // G28.4 homing cycle with no coordinate setting
+  NEXT_ACTION_SET_G28_POSITION,       // G28.1 set position in abs coordinates
+  NEXT_ACTION_GOTO_G28_POSITION,      // G28 go to machine position
+  NEXT_ACTION_SET_G30_POSITION,       // G30.1
+  NEXT_ACTION_GOTO_G30_POSITION,      // G30
+  NEXT_ACTION_SET_COORD_DATA,         // G10
+  NEXT_ACTION_SET_ORIGIN_OFFSETS,     // G92
+  NEXT_ACTION_RESET_ORIGIN_OFFSETS,   // G92.1
+  NEXT_ACTION_SUSPEND_ORIGIN_OFFSETS, // G92.2
+  NEXT_ACTION_RESUME_ORIGIN_OFFSETS,  // G92.3
+  NEXT_ACTION_DWELL,                  // G4
+  NEXT_ACTION_STRAIGHT_PROBE          // G38.2
 };
 
-enum cmMotionMode {                        // G Modal Group 1
-    MOTION_MODE_STRAIGHT_TRAVERSE=0,    // G0 - straight traverse
-    MOTION_MODE_STRAIGHT_FEED,            // G1 - straight feed
-    MOTION_MODE_CW_ARC,                    // G2 - clockwise arc feed
-    MOTION_MODE_CCW_ARC,                // G3 - counter-clockwise arc feed
-    MOTION_MODE_CANCEL_MOTION_MODE,        // G80
-    MOTION_MODE_STRAIGHT_PROBE,            // G38.2
-    MOTION_MODE_CANNED_CYCLE_81,        // G81 - drilling
-    MOTION_MODE_CANNED_CYCLE_82,        // G82 - drilling with dwell
-    MOTION_MODE_CANNED_CYCLE_83,        // G83 - peck drilling
-    MOTION_MODE_CANNED_CYCLE_84,        // G84 - right hand tapping
-    MOTION_MODE_CANNED_CYCLE_85,        // G85 - boring, no dwell, feed out
-    MOTION_MODE_CANNED_CYCLE_86,        // G86 - boring, spindle stop, rapid out
-    MOTION_MODE_CANNED_CYCLE_87,        // G87 - back boring
-    MOTION_MODE_CANNED_CYCLE_88,        // G88 - boring, spindle stop, manual out
-    MOTION_MODE_CANNED_CYCLE_89            // G89 - boring, dwell, feed out
+
+enum cmMotionMode {                   // G Modal Group 1
+  MOTION_MODE_STRAIGHT_TRAVERSE = 0,  // G0 - straight traverse
+  MOTION_MODE_STRAIGHT_FEED,          // G1 - straight feed
+  MOTION_MODE_CW_ARC,                 // G2 - clockwise arc feed
+  MOTION_MODE_CCW_ARC,                // G3 - counter-clockwise arc feed
+  MOTION_MODE_CANCEL_MOTION_MODE,     // G80
+  MOTION_MODE_STRAIGHT_PROBE,         // G38.2
+  MOTION_MODE_CANNED_CYCLE_81,        // G81 - drilling
+  MOTION_MODE_CANNED_CYCLE_82,        // G82 - drilling with dwell
+  MOTION_MODE_CANNED_CYCLE_83,        // G83 - peck drilling
+  MOTION_MODE_CANNED_CYCLE_84,        // G84 - right hand tapping
+  MOTION_MODE_CANNED_CYCLE_85,        // G85 - boring, no dwell, feed out
+  MOTION_MODE_CANNED_CYCLE_86,        // G86 - boring, spindle stop, rapid out
+  MOTION_MODE_CANNED_CYCLE_87,        // G87 - back boring
+  MOTION_MODE_CANNED_CYCLE_88,        // G88 - boring, spindle stop, manual out
+  MOTION_MODE_CANNED_CYCLE_89         // G89 - boring, dwell, feed out
 };
 
-enum cmModalGroup {                        // Used for detecting gcode errors. See NIST section 3.4
-    MODAL_GROUP_G0 = 0,                 // {G10,G28,G28.1,G92}     non-modal axis commands (note 1)
-    MODAL_GROUP_G1,                        // {G0,G1,G2,G3,G80}    motion
-    MODAL_GROUP_G2,                        // {G17,G18,G19}        plane selection
-    MODAL_GROUP_G3,                        // {G90,G91}            distance mode
-    MODAL_GROUP_G5,                        // {G93,G94}            feed rate mode
-    MODAL_GROUP_G6,                        // {G20,G21}            units
-    MODAL_GROUP_G7,                        // {G40,G41,G42}        cutter radius compensation
-    MODAL_GROUP_G8,                        // {G43,G49}            tool length offset
-    MODAL_GROUP_G9,                        // {G98,G99}            return mode in canned cycles
-    MODAL_GROUP_G12,                    // {G54,G55,G56,G57,G58,G59} coordinate system selection
-    MODAL_GROUP_G13,                    // {G61,G61.1,G64}        path control mode
-    MODAL_GROUP_M4,                        // {M0,M1,M2,M30,M60}    stopping
-    MODAL_GROUP_M6,                        // {M6}                    tool change
-    MODAL_GROUP_M7,                        // {M3,M4,M5}            spindle turning
-    MODAL_GROUP_M8,                        // {M7,M8,M9}            coolant (M7 & M8 may be active together)
-    MODAL_GROUP_M9                        // {M48,M49}            speed/feed override switches
+
+enum cmModalGroup {                   // Used for detecting gcode errors. See NIST section 3.4
+  MODAL_GROUP_G0 = 0,                 // {G10,G28,G28.1,G92}       non-modal axis commands (note 1)
+  MODAL_GROUP_G1,                     // {G0,G1,G2,G3,G80}         motion
+  MODAL_GROUP_G2,                     // {G17,G18,G19}             plane selection
+  MODAL_GROUP_G3,                     // {G90,G91}                 distance mode
+  MODAL_GROUP_G5,                     // {G93,G94}                 feed rate mode
+  MODAL_GROUP_G6,                     // {G20,G21}                 units
+  MODAL_GROUP_G7,                     // {G40,G41,G42}             cutter radius compensation
+  MODAL_GROUP_G8,                     // {G43,G49}                 tool length offset
+  MODAL_GROUP_G9,                     // {G98,G99}                 return mode in canned cycles
+  MODAL_GROUP_G12,                    // {G54,G55,G56,G57,G58,G59} coordinate system selection
+  MODAL_GROUP_G13,                    // {G61,G61.1,G64}           path control mode
+  MODAL_GROUP_M4,                     // {M0,M1,M2,M30,M60}        stopping
+  MODAL_GROUP_M6,                     // {M6}                      tool change
+  MODAL_GROUP_M7,                     // {M3,M4,M5}                spindle turning
+  MODAL_GROUP_M8,                     // {M7,M8,M9}                coolant (M7 & M8 may be active together)
+  MODAL_GROUP_M9                      // {M48,M49}                 speed/feed override switches
 };
-#define MODAL_GROUP_COUNT (MODAL_GROUP_M9+1)
+
+#define MODAL_GROUP_COUNT (MODAL_GROUP_M9 + 1)
+
 // Note 1: Our G0 omits G4,G30,G53,G92.1,G92.2,G92.3 as these have no axis components to error check
 
-enum cmCanonicalPlane {                // canonical plane - translates to:
-                                    //         axis_0    axis_1    axis_2
-    CANON_PLANE_XY = 0,                // G17    X          Y          Z
-    CANON_PLANE_XZ,                    // G18    X          Z          Y
-    CANON_PLANE_YZ                    // G19      Y          Z          X
+enum cmCanonicalPlane { // canonical plane - translates to:
+  //                          axis_0    axis_1    axis_2
+  CANON_PLANE_XY = 0, // G17    X          Y          Z
+  CANON_PLANE_XZ,     // G18    X          Z          Y
+  CANON_PLANE_YZ      // G19    Y          Z          X
 };
 
+
 enum cmUnitsMode {
-    INCHES = 0,                        // G20
-    MILLIMETERS,                    // G21
-    DEGREES                            // ABC axes (this value used for displays only)
+  INCHES = 0,                     // G20
+  MILLIMETERS,                    // G21
+  DEGREES                         // ABC axes (this value used for displays only)
 };
 
+
 enum cmCoordSystem {
-    ABSOLUTE_COORDS = 0,            // machine coordinate system
-    G54,                            // G54 coordinate system
-    G55,                            // G55 coordinate system
-    G56,                            // G56 coordinate system
-    G57,                            // G57 coordinate system
-    G58,                            // G58 coordinate system
-    G59                                // G59 coordinate system
+  ABSOLUTE_COORDS = 0,            // machine coordinate system
+  G54,                            // G54 coordinate system
+  G55,                            // G55 coordinate system
+  G56,                            // G56 coordinate system
+  G57,                            // G57 coordinate system
+  G58,                            // G58 coordinate system
+  G59                             // G59 coordinate system
 };
-#define COORD_SYSTEM_MAX G59        // set this manually to the last one
 
-enum cmPathControlMode {            // G Modal Group 13
-    PATH_EXACT_PATH = 0,            // G61 - hits corners but does not stop if it does not need to.
-    PATH_EXACT_STOP,                // G61.1 - stops at all corners
-    PATH_CONTINUOUS                    // G64 and typically the default mode
+#define COORD_SYSTEM_MAX G59      // set this manually to the last one
+
+enum cmPathControlMode {          // G Modal Group 13
+  PATH_EXACT_PATH = 0,            // G61 - hits corners but does not stop if it does not need to.
+  PATH_EXACT_STOP,                // G61.1 - stops at all corners
+  PATH_CONTINUOUS                 // G64 and typically the default mode
 };
 
+
 enum cmDistanceMode {
-    ABSOLUTE_MODE = 0,                // G90
-    INCREMENTAL_MODE                // G91
+  ABSOLUTE_MODE = 0,              // G90
+  INCREMENTAL_MODE                // G91
 };
 
+
 enum cmFeedRateMode {
-    INVERSE_TIME_MODE = 0,            // G93
-    UNITS_PER_MINUTE_MODE,            // G94
-    UNITS_PER_REVOLUTION_MODE        // G95 (unimplemented)
+  INVERSE_TIME_MODE = 0,          // G93
+  UNITS_PER_MINUTE_MODE,          // G94
+  UNITS_PER_REVOLUTION_MODE       // G95 (unimplemented)
 };
 
+
 enum cmOriginOffset {
-    ORIGIN_OFFSET_SET=0,            // G92 - set origin offsets
-    ORIGIN_OFFSET_CANCEL,            // G92.1 - zero out origin offsets
-    ORIGIN_OFFSET_SUSPEND,            // G92.2 - do not apply offsets, but preserve the values
-    ORIGIN_OFFSET_RESUME            // G92.3 - resume application of the suspended offsets
+  ORIGIN_OFFSET_SET = 0,          // G92 - set origin offsets
+  ORIGIN_OFFSET_CANCEL,           // G92.1 - zero out origin offsets
+  ORIGIN_OFFSET_SUSPEND,          // G92.2 - do not apply offsets, but preserve the values
+  ORIGIN_OFFSET_RESUME            // G92.3 - resume application of the suspended offsets
 };
 
+
 enum cmProgramFlow {
-    PROGRAM_STOP = 0,
-    PROGRAM_END
+  PROGRAM_STOP = 0,
+  PROGRAM_END
 };
 
-enum cmSpindleState {                // spindle state settings (See hardware.h for bit settings)
-    SPINDLE_OFF = 0,
-    SPINDLE_CW,
-    SPINDLE_CCW
+
+enum cmSpindleState {             // spindle state settings (See hardware.h for bit settings)
+  SPINDLE_OFF = 0,
+  SPINDLE_CW,
+  SPINDLE_CCW
 };
 
-enum cmCoolantState {                // mist and flood coolant states
-    COOLANT_OFF = 0,                // all coolant off
-    COOLANT_ON,                        // request coolant on or indicates both coolants are on
-    COOLANT_MIST,                    // indicates mist coolant on
-    COOLANT_FLOOD                    // indicates flood coolant on
+
+enum cmCoolantState {             // mist and flood coolant states
+  COOLANT_OFF = 0,                // all coolant off
+  COOLANT_ON,                     // request coolant on or indicates both coolants are on
+  COOLANT_MIST,                   // indicates mist coolant on
+  COOLANT_FLOOD                   // indicates flood coolant on
 };
 
-enum cmDirection {                    // used for spindle and arc dir
-    DIRECTION_CW = 0,
-    DIRECTION_CCW
+
+enum cmDirection {                // used for spindle and arc dir
+  DIRECTION_CW = 0,
+  DIRECTION_CCW
 };
 
-enum cmAxisMode {                    // axis modes (ordered: see _cm_get_feed_time())
-    AXIS_DISABLED = 0,                // kill axis
-    AXIS_STANDARD,                    // axis in coordinated motion w/standard behaviors
-    AXIS_INHIBITED,                    // axis is computed but not activated
-    AXIS_RADIUS                        // rotary axis calibrated to circumference
-};    // ordering must be preserved. See cm_set_move_times()
+enum cmAxisMode {                 // axis modes (ordered: see _cm_get_feed_time())
+  AXIS_DISABLED = 0,              // kill axis
+  AXIS_STANDARD,                  // axis in coordinated motion w/standard behaviors
+  AXIS_INHIBITED,                 // axis is computed but not activated
+  AXIS_RADIUS                     // rotary axis calibrated to circumference
+}; // ordering must be preserved. See cm_set_move_times()
+
 #define AXIS_MODE_MAX_LINEAR AXIS_INHIBITED
 #define AXIS_MODE_MAX_ROTARY AXIS_RADIUS
 
-/*****************************************************************************
- * FUNCTION PROTOTYPES
- * Serves as a table of contents for the rather large canonical machine source file.
- */
-
-/*--- Internal functions and helpers ---*/
 
 // Model state getters and setters
 uint8_t cm_get_combined_state();
@@ -530,7 +539,7 @@ uint8_t cm_get_distance_mode(GCodeState_t *gcode_state);
 uint8_t cm_get_feed_rate_mode(GCodeState_t *gcode_state);
 uint8_t cm_get_tool(GCodeState_t *gcode_state);
 uint8_t cm_get_spindle_mode(GCodeState_t *gcode_state);
-uint8_t    cm_get_block_delete_switch();
+uint8_t cm_get_block_delete_switch();
 uint8_t cm_get_runtime_busy();
 float cm_get_feed_rate(GCodeState_t *gcode_state);
 
@@ -555,7 +564,7 @@ stat_t cm_deferred_write_callback();
 void cm_set_model_target(float target[], float flag[]);
 stat_t cm_test_soft_limits(float target[]);
 
-/*--- Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc] ---*/
+// Canonical machining functions (loosely) defined by NIST [organized by NIST Gcode doc]
 
 // Initialization and termination (4.3.2)
 void canonical_machine_init();
@@ -567,58 +576,58 @@ stat_t cm_soft_alarm(stat_t status);                            // enter soft al
 stat_t cm_clear(nvObj_t *nv);
 
 // Representation (4.3.3)
-stat_t cm_select_plane(uint8_t plane);                            // G17, G18, G19
-stat_t cm_set_units_mode(uint8_t mode);                            // G20, G21
-stat_t cm_set_distance_mode(uint8_t mode);                        // G90, G91
+stat_t cm_select_plane(uint8_t plane);                          // G17, G18, G19
+stat_t cm_set_units_mode(uint8_t mode);                         // G20, G21
+stat_t cm_set_distance_mode(uint8_t mode);                      // G90, G91
 stat_t cm_set_coord_offsets(uint8_t coord_system, float offset[], float flag[]); // G10 L2
 
-void cm_set_position(uint8_t axis, float position);                // set absolute position - single axis
+void cm_set_position(uint8_t axis, float position);             // set absolute position - single axis
 stat_t cm_set_absolute_origin(float origin[], float flag[]);    // G28.3
 void cm_set_axis_origin(uint8_t axis, const float position);    // G28.3 planner callback
 
-stat_t cm_set_coord_system(uint8_t coord_system);                // G54 - G59
-stat_t cm_set_origin_offsets(float offset[], float flag[]);        // G92
-stat_t cm_reset_origin_offsets();                             // G92.1
-stat_t cm_suspend_origin_offsets();                         // G92.2
-stat_t cm_resume_origin_offsets();                             // G92.3
+stat_t cm_set_coord_system(uint8_t coord_system);               // G54 - G59
+stat_t cm_set_origin_offsets(float offset[], float flag[]);     // G92
+stat_t cm_reset_origin_offsets();                               // G92.1
+stat_t cm_suspend_origin_offsets();                             // G92.2
+stat_t cm_resume_origin_offsets();                              // G92.3
 
 // Free Space Motion (4.3.4)
-stat_t cm_straight_traverse(float target[], float flags[]);        // G0
-stat_t cm_set_g28_position();                                // G28.1
+stat_t cm_straight_traverse(float target[], float flags[]);     // G0
+stat_t cm_set_g28_position();                                   // G28.1
 stat_t cm_goto_g28_position(float target[], float flags[]);     // G28
-stat_t cm_set_g30_position();                                // G30.1
-stat_t cm_goto_g30_position(float target[], float flags[]);        // G30
+stat_t cm_set_g30_position();                                   // G30.1
+stat_t cm_goto_g30_position(float target[], float flags[]);     // G30
 
 // Machining Attributes (4.3.5)
 stat_t cm_set_feed_rate(float feed_rate);                        // F parameter
-stat_t cm_set_feed_rate_mode(uint8_t mode);                        // G93, G94, (G95 unimplemented)
+stat_t cm_set_feed_rate_mode(uint8_t mode);                      // G93, G94, (G95 unimplemented)
 stat_t cm_set_path_control(uint8_t mode);                        // G61, G61.1, G64
 
 // Machining Functions (4.3.6)
-stat_t cm_straight_feed(float target[], float flags[]);            // G1
-stat_t cm_arc_feed(    float target[], float flags[],              // G2, G3
-                    float i, float j, float k,
-                    float radius, uint8_t motion_mode);
-stat_t cm_dwell(float seconds);                                    // G4, P parameter
+stat_t cm_straight_feed(float target[], float flags[]);          // G1
+stat_t cm_arc_feed(float target[], float flags[],                // G2, G3
+                   float i, float j, float k,
+                   float radius, uint8_t motion_mode);
+stat_t cm_dwell(float seconds);                                  // G4, P parameter
 
 // Spindle Functions (4.3.7)
 // see spindle.h for spindle definitions - which would go right here
 
 // Tool Functions (4.3.8)
-stat_t cm_select_tool(uint8_t tool);                            // T parameter
-stat_t cm_change_tool(uint8_t tool);                            // M6
+stat_t cm_select_tool(uint8_t tool);                             // T parameter
+stat_t cm_change_tool(uint8_t tool);                             // M6
 
 // Miscellaneous Functions (4.3.9)
-stat_t cm_mist_coolant_control(uint8_t mist_coolant);             // M7
-stat_t cm_flood_coolant_control(uint8_t flood_coolant);            // M8, M9
+stat_t cm_mist_coolant_control(uint8_t mist_coolant);            // M7
+stat_t cm_flood_coolant_control(uint8_t flood_coolant);          // M8, M9
 
-stat_t cm_override_enables(uint8_t flag);                         // M48, M49
-stat_t cm_feed_rate_override_enable(uint8_t flag);                 // M50
-stat_t cm_feed_rate_override_factor(uint8_t flag);                // M50.1
-stat_t cm_traverse_override_enable(uint8_t flag);                 // M50.2
+stat_t cm_override_enables(uint8_t flag);                        // M48, M49
+stat_t cm_feed_rate_override_enable(uint8_t flag);               // M50
+stat_t cm_feed_rate_override_factor(uint8_t flag);               // M50.1
+stat_t cm_traverse_override_enable(uint8_t flag);                // M50.2
 stat_t cm_traverse_override_factor(uint8_t flag);                // M50.3
 stat_t cm_spindle_override_enable(uint8_t flag);                 // M51
-stat_t cm_spindle_override_factor(uint8_t flag);                // M51.1
+stat_t cm_spindle_override_factor(uint8_t flag);                 // M51.1
 
 void cm_message(char_t *message);                                // msg to console (e.g. Gcode comments)
 
@@ -627,37 +636,37 @@ void cm_request_feedhold();
 void cm_request_queue_flush();
 void cm_request_cycle_start();
 
-stat_t cm_feedhold_sequencing_callback();                    // process feedhold, cycle start and queue flush requests
+stat_t cm_feedhold_sequencing_callback();                   // process feedhold, cycle start and queue flush requests
 stat_t cm_queue_flush();                                    // flush serial and planner queues with coordinate resets
 
-void cm_cycle_start();                                        // (no Gcode)
-void cm_cycle_end();                                         // (no Gcode)
-void cm_feedhold();                                            // (no Gcode)
-void cm_program_stop();                                        // M0
-void cm_optional_program_stop();                            // M1
-void cm_program_end();                                        // M2
+void cm_cycle_start();                                           // (no Gcode)
+void cm_cycle_end();                                             // (no Gcode)
+void cm_feedhold();                                              // (no Gcode)
+void cm_program_stop();                                          // M0
+void cm_optional_program_stop();                                 // M1
+void cm_program_end();                                           // M2
 
 /*--- Cycles ---*/
 
 // Homing cycles
-stat_t cm_homing_cycle_start();                                // G28.2
-stat_t cm_homing_cycle_start_no_set();                        // G28.4
-stat_t cm_homing_callback();                                // G28.2/.4 main loop callback
+stat_t cm_homing_cycle_start();                                  // G28.2
+stat_t cm_homing_cycle_start_no_set();                           // G28.4
+stat_t cm_homing_callback();                                     // G28.2/.4 main loop callback
 
 // Probe cycles
-stat_t cm_straight_probe(float target[], float flags[]);        // G38.2
-stat_t cm_probe_callback();                                    // G38.2 main loop callback
+stat_t cm_straight_probe(float target[], float flags[]);         // G38.2
+stat_t cm_probe_callback();                                      // G38.2 main loop callback
 
 // Jogging cycle
-stat_t cm_jogging_callback();                                // jogging cycle main loop
-stat_t cm_jogging_cycle_start(uint8_t axis);                    // {"jogx":-100.3}
+stat_t cm_jogging_callback();                                    // jogging cycle main loop
+stat_t cm_jogging_cycle_start(uint8_t axis);                     // {"jogx":-100.3}
 float cm_get_jogging_dest();
 
 /*--- cfgArray interface functions ---*/
 
 char_t cm_get_axis_char(const int8_t axis);
 
-stat_t cm_get_mline(nvObj_t *nv);        // get model line number
+stat_t cm_get_mline(nvObj_t *nv);       // get model line number
 stat_t cm_get_line(nvObj_t *nv);        // get active (model or runtime) line number
 stat_t cm_get_stat(nvObj_t *nv);        // get combined machine state as value and string
 stat_t cm_get_macs(nvObj_t *nv);        // get raw machine state as value and string
@@ -672,145 +681,143 @@ stat_t cm_get_plan(nvObj_t *nv);        // get active plane...
 stat_t cm_get_path(nvObj_t *nv);        // get patch control mode...
 stat_t cm_get_dist(nvObj_t *nv);        // get distance mode...
 stat_t cm_get_frmo(nvObj_t *nv);        // get feedrate mode...
-stat_t cm_get_toolv(nvObj_t *nv);        // get tool (value)
-stat_t cm_get_pwr(nvObj_t *nv);            // get motor power enable state
+stat_t cm_get_toolv(nvObj_t *nv);       // get tool (value)
+stat_t cm_get_pwr(nvObj_t *nv);         // get motor power enable state
 
-stat_t cm_get_vel(nvObj_t *nv);            // get runtime velocity...
+stat_t cm_get_vel(nvObj_t *nv);         // get runtime velocity...
 stat_t cm_get_feed(nvObj_t *nv);
-stat_t cm_get_pos(nvObj_t *nv);            // get runtime work position...
-stat_t cm_get_mpo(nvObj_t *nv);            // get runtime machine position...
-stat_t cm_get_ofs(nvObj_t *nv);            // get runtime work offset...
+stat_t cm_get_pos(nvObj_t *nv);         // get runtime work position...
+stat_t cm_get_mpo(nvObj_t *nv);         // get runtime machine position...
+stat_t cm_get_ofs(nvObj_t *nv);         // get runtime work offset...
 
-stat_t cm_run_qf(nvObj_t *nv);            // run queue flush
+stat_t cm_run_qf(nvObj_t *nv);          // run queue flush
 stat_t cm_run_home(nvObj_t *nv);        // start homing cycle
 
-stat_t cm_dam(nvObj_t *nv);                // dump active model (debugging command)
+stat_t cm_dam(nvObj_t *nv);             // dump active model (debugging command)
 
 stat_t cm_run_jogx(nvObj_t *nv);        // start jogging cycle for x
 stat_t cm_run_jogy(nvObj_t *nv);        // start jogging cycle for y
 stat_t cm_run_jogz(nvObj_t *nv);        // start jogging cycle for z
 stat_t cm_run_joga(nvObj_t *nv);        // start jogging cycle for a
 
-stat_t cm_get_am(nvObj_t *nv);            // get axis mode
-stat_t cm_set_am(nvObj_t *nv);            // set axis mode
-stat_t cm_set_xjm(nvObj_t *nv);            // set jerk max with 1,000,000 correction
-stat_t cm_set_xjh(nvObj_t *nv);            // set jerk homing with 1,000,000 correction
-
-/*--- text_mode support functions ---*/
+stat_t cm_get_am(nvObj_t *nv);          // get axis mode
+stat_t cm_set_am(nvObj_t *nv);          // set axis mode
+stat_t cm_set_xjm(nvObj_t *nv);         // set jerk max with 1,000,000 correction
+stat_t cm_set_xjh(nvObj_t *nv);         // set jerk homing with 1,000,000 correction
 
 #ifdef __TEXT_MODE
 
-    void cm_print_vel(nvObj_t *nv);        // model state reporting
-    void cm_print_feed(nvObj_t *nv);
-    void cm_print_line(nvObj_t *nv);
-    void cm_print_stat(nvObj_t *nv);
-    void cm_print_macs(nvObj_t *nv);
-    void cm_print_cycs(nvObj_t *nv);
-    void cm_print_mots(nvObj_t *nv);
-    void cm_print_hold(nvObj_t *nv);
-    void cm_print_home(nvObj_t *nv);
-    void cm_print_unit(nvObj_t *nv);
-    void cm_print_coor(nvObj_t *nv);
-    void cm_print_momo(nvObj_t *nv);
-    void cm_print_plan(nvObj_t *nv);
-    void cm_print_path(nvObj_t *nv);
-    void cm_print_dist(nvObj_t *nv);
-    void cm_print_frmo(nvObj_t *nv);
-    void cm_print_tool(nvObj_t *nv);
-
-    void cm_print_gpl(nvObj_t *nv);        // Gcode defaults
-    void cm_print_gun(nvObj_t *nv);
-    void cm_print_gco(nvObj_t *nv);
-    void cm_print_gpa(nvObj_t *nv);
-    void cm_print_gdi(nvObj_t *nv);
-
-    void cm_print_lin(nvObj_t *nv);        // generic print for linear values
-    void cm_print_pos(nvObj_t *nv);        // print runtime work position in prevailing units
-    void cm_print_mpo(nvObj_t *nv);        // print runtime work position always in MM units
-    void cm_print_ofs(nvObj_t *nv);        // print runtime work offset always in MM units
-
-    void cm_print_ja(nvObj_t *nv);        // global CM settings
-    void cm_print_ct(nvObj_t *nv);
-    void cm_print_sl(nvObj_t *nv);
-    void cm_print_ml(nvObj_t *nv);
-    void cm_print_ma(nvObj_t *nv);
-    void cm_print_ms(nvObj_t *nv);
-    void cm_print_st(nvObj_t *nv);
-
-    void cm_print_am(nvObj_t *nv);        // axis print functions
-    void cm_print_fr(nvObj_t *nv);
-    void cm_print_vm(nvObj_t *nv);
-    void cm_print_tm(nvObj_t *nv);
-    void cm_print_tn(nvObj_t *nv);
-    void cm_print_jm(nvObj_t *nv);
-    void cm_print_jh(nvObj_t *nv);
-    void cm_print_jd(nvObj_t *nv);
-    void cm_print_ra(nvObj_t *nv);
-    void cm_print_sn(nvObj_t *nv);
-    void cm_print_sx(nvObj_t *nv);
-    void cm_print_sv(nvObj_t *nv);
-    void cm_print_lv(nvObj_t *nv);
-    void cm_print_lb(nvObj_t *nv);
-    void cm_print_zb(nvObj_t *nv);
-    void cm_print_cofs(nvObj_t *nv);
-    void cm_print_cpos(nvObj_t *nv);
+void cm_print_vel(nvObj_t *nv);         // model state reporting
+void cm_print_feed(nvObj_t *nv);
+void cm_print_line(nvObj_t *nv);
+void cm_print_stat(nvObj_t *nv);
+void cm_print_macs(nvObj_t *nv);
+void cm_print_cycs(nvObj_t *nv);
+void cm_print_mots(nvObj_t *nv);
+void cm_print_hold(nvObj_t *nv);
+void cm_print_home(nvObj_t *nv);
+void cm_print_unit(nvObj_t *nv);
+void cm_print_coor(nvObj_t *nv);
+void cm_print_momo(nvObj_t *nv);
+void cm_print_plan(nvObj_t *nv);
+void cm_print_path(nvObj_t *nv);
+void cm_print_dist(nvObj_t *nv);
+void cm_print_frmo(nvObj_t *nv);
+void cm_print_tool(nvObj_t *nv);
+
+void cm_print_gpl(nvObj_t *nv);         // Gcode defaults
+void cm_print_gun(nvObj_t *nv);
+void cm_print_gco(nvObj_t *nv);
+void cm_print_gpa(nvObj_t *nv);
+void cm_print_gdi(nvObj_t *nv);
+
+void cm_print_lin(nvObj_t *nv);         // generic print for linear values
+void cm_print_pos(nvObj_t *nv);         // print runtime work position in prevailing units
+void cm_print_mpo(nvObj_t *nv);         // print runtime work position always in MM units
+void cm_print_ofs(nvObj_t *nv);         // print runtime work offset always in MM units
+
+void cm_print_ja(nvObj_t *nv);          // global CM settings
+void cm_print_ct(nvObj_t *nv);
+void cm_print_sl(nvObj_t *nv);
+void cm_print_ml(nvObj_t *nv);
+void cm_print_ma(nvObj_t *nv);
+void cm_print_ms(nvObj_t *nv);
+void cm_print_st(nvObj_t *nv);
+
+void cm_print_am(nvObj_t *nv);          // axis print functions
+void cm_print_fr(nvObj_t *nv);
+void cm_print_vm(nvObj_t *nv);
+void cm_print_tm(nvObj_t *nv);
+void cm_print_tn(nvObj_t *nv);
+void cm_print_jm(nvObj_t *nv);
+void cm_print_jh(nvObj_t *nv);
+void cm_print_jd(nvObj_t *nv);
+void cm_print_ra(nvObj_t *nv);
+void cm_print_sn(nvObj_t *nv);
+void cm_print_sx(nvObj_t *nv);
+void cm_print_sv(nvObj_t *nv);
+void cm_print_lv(nvObj_t *nv);
+void cm_print_lb(nvObj_t *nv);
+void cm_print_zb(nvObj_t *nv);
+void cm_print_cofs(nvObj_t *nv);
+void cm_print_cpos(nvObj_t *nv);
 
 #else // __TEXT_MODE
 
-    #define cm_print_vel tx_print_stub        // model state reporting
-    #define cm_print_feed tx_print_stub
-    #define cm_print_line tx_print_stub
-    #define cm_print_stat tx_print_stub
-    #define cm_print_macs tx_print_stub
-    #define cm_print_cycs tx_print_stub
-    #define cm_print_mots tx_print_stub
-    #define cm_print_hold tx_print_stub
-    #define cm_print_home tx_print_stub
-    #define cm_print_unit tx_print_stub
-    #define cm_print_coor tx_print_stub
-    #define cm_print_momo tx_print_stub
-    #define cm_print_plan tx_print_stub
-    #define cm_print_path tx_print_stub
-    #define cm_print_dist tx_print_stub
-    #define cm_print_frmo tx_print_stub
-    #define cm_print_tool tx_print_stub
-
-    #define cm_print_gpl tx_print_stub        // Gcode defaults
-    #define cm_print_gun tx_print_stub
-    #define cm_print_gco tx_print_stub
-    #define cm_print_gpa tx_print_stub
-    #define cm_print_gdi tx_print_stub
-
-    #define cm_print_lin tx_print_stub        // generic print for linear values
-    #define cm_print_pos tx_print_stub        // print runtime work position in prevailing units
-    #define cm_print_mpo tx_print_stub        // print runtime work position always in MM uints
-    #define cm_print_ofs tx_print_stub        // print runtime work offset always in MM uints
-
-    #define cm_print_ja tx_print_stub        // global CM settings
-    #define cm_print_ct tx_print_stub
-    #define cm_print_sl tx_print_stub
-    #define cm_print_ml tx_print_stub
-    #define cm_print_ma tx_print_stub
-    #define cm_print_ms tx_print_stub
-    #define cm_print_st tx_print_stub
-
-    #define cm_print_am tx_print_stub        // axis print functions
-    #define cm_print_fr tx_print_stub
-    #define cm_print_vm tx_print_stub
-    #define cm_print_tm tx_print_stub
-    #define cm_print_tn tx_print_stub
-    #define cm_print_jm tx_print_stub
-    #define cm_print_jh tx_print_stub
-    #define cm_print_jd tx_print_stub
-    #define cm_print_ra tx_print_stub
-    #define cm_print_sn tx_print_stub
-    #define cm_print_sx tx_print_stub
-    #define cm_print_sv tx_print_stub
-    #define cm_print_lv tx_print_stub
-    #define cm_print_lb tx_print_stub
-    #define cm_print_zb tx_print_stub
-    #define cm_print_cofs tx_print_stub
-    #define cm_print_cpos tx_print_stub
+#define cm_print_vel tx_print_stub      // model state reporting
+#define cm_print_feed tx_print_stub
+#define cm_print_line tx_print_stub
+#define cm_print_stat tx_print_stub
+#define cm_print_macs tx_print_stub
+#define cm_print_cycs tx_print_stub
+#define cm_print_mots tx_print_stub
+#define cm_print_hold tx_print_stub
+#define cm_print_home tx_print_stub
+#define cm_print_unit tx_print_stub
+#define cm_print_coor tx_print_stub
+#define cm_print_momo tx_print_stub
+#define cm_print_plan tx_print_stub
+#define cm_print_path tx_print_stub
+#define cm_print_dist tx_print_stub
+#define cm_print_frmo tx_print_stub
+#define cm_print_tool tx_print_stub
+
+#define cm_print_gpl tx_print_stub      // Gcode defaults
+#define cm_print_gun tx_print_stub
+#define cm_print_gco tx_print_stub
+#define cm_print_gpa tx_print_stub
+#define cm_print_gdi tx_print_stub
+
+#define cm_print_lin tx_print_stub      // generic print for linear values
+#define cm_print_pos tx_print_stub      // print runtime work position in prevailing units
+#define cm_print_mpo tx_print_stub      // print runtime work position always in MM uints
+#define cm_print_ofs tx_print_stub      // print runtime work offset always in MM uints
+
+#define cm_print_ja tx_print_stub       // global CM settings
+#define cm_print_ct tx_print_stub
+#define cm_print_sl tx_print_stub
+#define cm_print_ml tx_print_stub
+#define cm_print_ma tx_print_stub
+#define cm_print_ms tx_print_stub
+#define cm_print_st tx_print_stub
+
+#define cm_print_am tx_print_stub       // axis print functions
+#define cm_print_fr tx_print_stub
+#define cm_print_vm tx_print_stub
+#define cm_print_tm tx_print_stub
+#define cm_print_tn tx_print_stub
+#define cm_print_jm tx_print_stub
+#define cm_print_jh tx_print_stub
+#define cm_print_jd tx_print_stub
+#define cm_print_ra tx_print_stub
+#define cm_print_sn tx_print_stub
+#define cm_print_sx tx_print_stub
+#define cm_print_sv tx_print_stub
+#define cm_print_lv tx_print_stub
+#define cm_print_lb tx_print_stub
+#define cm_print_zb tx_print_stub
+#define cm_print_cofs tx_print_stub
+#define cm_print_cpos tx_print_stub
 
 #endif // __TEXT_MODE
-#endif // End of include guard: CANONICAL_MACHINE_H_ONCE
+#endif // CANONICAL_MACHINE_H_ONCE
index b16e5329893437f80372976296c18a35a6e99bbb..cb262bf6990a8791e4bc7544825fb729b01ef58d 100644 (file)
@@ -65,7 +65,7 @@ nvList_t nvl;
  */
 stat_t nv_set(nvObj_t *nv) {
   if (nv->index >= nv_index_max())
-    return(STAT_INTERNAL_RANGE_ERROR);
+    return STAT_INTERNAL_RANGE_ERROR;
   return ((fptrCmd)GET_TABLE_WORD(set))(nv);
 }
 
@@ -83,8 +83,8 @@ void nv_print(nvObj_t *nv) {
 
 
 stat_t nv_persist(nvObj_t *nv) {   // nv_persist() cannot be called from an interrupt on the AVR due to the AVR1008 EEPROM workaround
-  if (nv_index_lt_groups(nv->index) == false) return(STAT_INTERNAL_RANGE_ERROR);
-  if (GET_TABLE_BYTE(flags) & F_PERSIST) return(write_persistent_value(nv));
+  if (nv_index_lt_groups(nv->index) == false) return STAT_INTERNAL_RANGE_ERROR;
+  if (GET_TABLE_BYTE(flags) & F_PERSIST) return write_persistent_value(nv);
 
   return STAT_OK;
 }
@@ -148,7 +148,7 @@ static void _set_defa(nvObj_t *nv) {
 
 stat_t set_defaults(nvObj_t *nv) {
   // failsafe. nv->value must be true or no action occurs
-  if (fp_FALSE(nv->value)) return(help_defa(nv));
+  if (fp_FALSE(nv->value)) return help_defa(nv);
   _set_defa(nv);
 
   // The values in nv are now garbage. Mark the nv as $defa so it displays nicely.
@@ -240,7 +240,7 @@ stat_t set_nul(nvObj_t *nv) { return STAT_PARAMETER_IS_READ_ONLY; }
 stat_t set_ui8(nvObj_t *nv) {
   *((uint8_t *)GET_TABLE_WORD(target)) = nv->value;
   nv->valuetype = TYPE_INTEGER;
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
@@ -265,7 +265,7 @@ stat_t set_0123(nvObj_t *nv) {
 stat_t set_int(nvObj_t *nv) {
   *((uint32_t *)GET_TABLE_WORD(target)) = (uint32_t)nv->value;
   nv->valuetype = TYPE_INTEGER;
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
@@ -273,7 +273,7 @@ stat_t set_data(nvObj_t *nv) {
   uint32_t *v = (uint32_t*)&nv->value;
   *((uint32_t *)GET_TABLE_WORD(target)) = *v;
   nv->valuetype = TYPE_DATA;
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
@@ -281,7 +281,7 @@ stat_t set_flt(nvObj_t *nv) {
   *((float *)GET_TABLE_WORD(target)) = nv->value;
   nv->precision = GET_TABLE_WORD(precision);
   nv->valuetype = TYPE_FLOAT;
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
@@ -399,13 +399,13 @@ index_t nv_get_index(const char_t *group, const char_t *token) {
 
   for (i = 0; i < index_max; i++) {
     if ((c = GET_TOKEN_BYTE(token[0])) != str[0]) continue;                   // 1st character mismatch
-    if ((c = GET_TOKEN_BYTE(token[1])) == 0) {if (str[1] == 0) return(i);}    // one character match
+    if ((c = GET_TOKEN_BYTE(token[1])) == 0) {if (str[1] == 0) return i;}    // one character match
     if (c != str[1]) continue;                                                // 2nd character mismatch
-    if ((c = GET_TOKEN_BYTE(token[2])) == 0) {if (str[2] == 0) return(i);}    // two character match
+    if ((c = GET_TOKEN_BYTE(token[2])) == 0) {if (str[2] == 0) return i;}    // two character match
     if (c != str[2]) continue;                                                // 3rd character mismatch
-    if ((c = GET_TOKEN_BYTE(token[3])) == 0) {if (str[3] == 0) return(i);}    // three character match
+    if ((c = GET_TOKEN_BYTE(token[3])) == 0) {if (str[3] == 0) return i;}    // three character match
     if (c != str[3]) continue;                                                // 4th character mismatch
-    if ((c = GET_TOKEN_BYTE(token[4])) == 0) {if (str[4] == 0) return(i);}    // four character match
+    if ((c = GET_TOKEN_BYTE(token[4])) == 0) {if (str[4] == 0) return i;}    // four character match
     if (c != str[4]) continue;                                                // 5th character mismatch
     return i;                                                                 // five character match
   }
@@ -537,7 +537,7 @@ nvObj_t *nv_add_object(const char_t *token) {  // add an object to the body usin
   nvObj_t *nv = nv_body;
   for (uint8_t i=0; i<NV_BODY_LEN; i++) {
     if (nv->valuetype != TYPE_EMPTY) {
-      if ((nv = nv->nx) == 0) return(0); // not supposed to find a 0; here for safety
+      if ((nv = nv->nx) == 0) return 0; // not supposed to find a 0; here for safety
       continue;
     }
 
@@ -555,7 +555,7 @@ nvObj_t *nv_add_integer(const char_t *token, const uint32_t value) { // add an i
   nvObj_t *nv = nv_body;
   for (uint8_t i=0; i<NV_BODY_LEN; i++) {
     if (nv->valuetype != TYPE_EMPTY) {
-      if ((nv = nv->nx) == 0) return(0); // not supposed to find a 0; here for safety
+      if ((nv = nv->nx) == 0) return 0; // not supposed to find a 0; here for safety
       continue;
     }
 
@@ -573,7 +573,7 @@ nvObj_t *nv_add_data(const char_t *token, const uint32_t value) { // add an inte
   nvObj_t *nv = nv_body;
   for (uint8_t i=0; i<NV_BODY_LEN; i++) {
     if (nv->valuetype != TYPE_EMPTY) {
-      if ((nv = nv->nx) == 0) return(0); // not supposed to find a 0; here for safety
+      if ((nv = nv->nx) == 0) return 0; // not supposed to find a 0; here for safety
       continue;
     }
 
@@ -591,7 +591,7 @@ nvObj_t *nv_add_float(const char_t *token, const float value) { // add a float o
   nvObj_t *nv = nv_body;
   for (uint8_t i=0; i<NV_BODY_LEN; i++) {
     if (nv->valuetype != TYPE_EMPTY) {
-      if ((nv = nv->nx) == 0) return(0);        // not supposed to find a 0; here for safety
+      if ((nv = nv->nx) == 0) return 0;        // not supposed to find a 0; here for safety
       continue;
     }
 
index df5dfb15aa6e97acb9e3356aeaa3512acd142ce1..717fc89eab44b7504073496e9bb9e24898778789 100644 (file)
@@ -87,5 +87,5 @@ void en_set_encoder_steps(uint8_t motor, float steps)
 
 float en_read_encoder(uint8_t motor)
 {
-    return((float)en.en[motor].encoder_steps);
+    return (float)en.en[motor].encoder_steps;
 }
index 6bbfb13213ad896183ff0dbbab7239c04bcd2d76..6d8ec237748cce543754e28df4559240e89a12a0 100644 (file)
@@ -65,7 +65,7 @@ stat_t gc_gcode_parser(char_t *block)
     // queue a "(MSG" response
     if (*msg) cm_message(msg);                // queue the message
 
-    return(_parse_gcode_block(block));
+    return _parse_gcode_block(block);
 }
 
 /*
@@ -181,7 +181,7 @@ static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
     char *end;
     *value = strtof(*pstr, &end);
     if(end == *pstr)
-        return(STAT_BAD_NUMBER_FORMAT); // more robust test then checking for value=0;
+        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
 }
@@ -191,7 +191,7 @@ static stat_t _get_next_gcode_word(char **pstr, char *letter, float *value)
  */
 static uint8_t _point(float value)
 {
-    return((uint8_t)(value*10 - trunc(value)*10));    // isolate the decimal point as an int
+    return (uint8_t)(value*10 - trunc(value)*10);    // isolate the decimal point as an int
 }
 
 /*
@@ -518,5 +518,5 @@ stat_t gc_get_gc(nvObj_t *nv)
 
 stat_t gc_run_gc(nvObj_t *nv)
 {
-    return(gc_gcode_parser(*nv->stringp));
+    return gc_gcode_parser(*nv->stringp);
 }
index 0796fdb923302ee6d51e155e957d76f6330f092b..44c5b3ff709f17528952ddb93b08e01f16ba3dc1 100644 (file)
 #ifndef GCODE_PARSER_H_ONCE
 #define GCODE_PARSER_H_ONCE
 
-/*
- * Global Scope Functions
- */
 stat_t gc_gcode_parser(char_t *block);
 stat_t gc_get_gc(nvObj_t *nv);
 stat_t gc_run_gc(nvObj_t *nv);
 
-#endif // End of include guard: GCODE_PARSER_H_ONCE
+#endif // GCODE_PARSER_H_ONCE
index 8827f676779e2a85e9c2f8178efd780c0f06593c..af312f08385ceb571fd3d9be1bcead6770222577 100644 (file)
@@ -163,7 +163,7 @@ stat_t hw_get_id(nvObj_t *nv) {
 /// hw_run_boot() - invoke boot form the cfgArray
 stat_t hw_run_boot(nvObj_t *nv) {
   hw_request_bootloader();
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 
index 9c40629b600fd1b9f794a26f6dd43ca6fbb2da0a..941418a207d63c50f5ac8b0519c9f309e5140c26 100644 (file)
@@ -111,11 +111,11 @@ enum hwPlatform {
  *    b0    (out) step             (SET is step,  CLR is rest)
  *    b1    (out) direction        (CLR = Clockwise)
  *    b2    (out) motor enable     (CLR = Enabled)
- *    b3    (out) microstep 0
- *    b4    (out) microstep 1
+ *    b3    (out) chip select
+ *    b4    (in)  fault
  *    b5    (out) output bit for GPIO port1
- *    b6    (in) min limit switch on GPIO 2 (note: motor controls and GPIO2 port mappings are not the same)
- *    b7    (in) max limit switch on GPIO 2 (note: motor controls and GPIO2 port mappings are not the same)
+ *    b6    (in)  min limit switch on GPIO 2 (note: motor controls and GPIO2 port mappings are not the same)
+ *    b7    (in)  max limit switch on GPIO 2 (note: motor controls and GPIO2 port mappings are not the same)
  */
 #define MOTOR_PORT_DIR_gm 0x3F    // dir settings: lower 6 out, upper 2 in
 
@@ -123,8 +123,8 @@ enum cfgPortBits {        // motor control port bit positions
   STEP_BIT_bp = 0,        // bit 0
   DIRECTION_BIT_bp,       // bit 1
   MOTOR_ENABLE_BIT_bp,    // bit 2
-  MICROSTEP_BIT_0_bp,     // bit 3
-  MICROSTEP_BIT_1_bp,     // bit 4
+  CHIP_SELECT_BIT_bp,     // bit 3
+  FAULT_BIT_bp,           // bit 4
   GPIO1_OUT_BIT_bp,       // bit 5 (4 gpio1 output bits; 1 from each axis)
   SW_MIN_BIT_bp,          // bit 6 (4 input bits for homing/limit switches)
   SW_MAX_BIT_bp           // bit 7 (4 input bits for homing/limit switches)
@@ -133,8 +133,8 @@ enum cfgPortBits {        // motor control port bit positions
 #define STEP_BIT_bm           (1 << STEP_BIT_bp)
 #define DIRECTION_BIT_bm      (1 << DIRECTION_BIT_bp)
 #define MOTOR_ENABLE_BIT_bm   (1 << MOTOR_ENABLE_BIT_bp)
-#define MICROSTEP_BIT_0_bm    (1 << MICROSTEP_BIT_0_bp)
-#define MICROSTEP_BIT_1_bm    (1 << MICROSTEP_BIT_1_bp)
+#define CHIP_SELECT_BIT_bm    (1 << CHIP_SELECT_BIT_bp)
+#define FAULT_BIT_bm          (1 << FAULT_BIT_bp)
 #define GPIO1_OUT_BIT_bm      (1 << GPIO1_OUT_BIT_bp)    // spindle and coolant output bits
 #define SW_MIN_BIT_bm         (1 << SW_MIN_BIT_bp)       // minimum switch inputs
 #define SW_MAX_BIT_bm         (1 << SW_MAX_BIT_bp)       // maximum switch inputs
index 01102affd61000130d72e130bd959d3ffcea7748..bbec30e47b28e6c6fbf82c66a8c66f5f0af571e5 100644 (file)
@@ -69,7 +69,7 @@ These commands are active from the command line:\n\
 _status_report_advisory();
 _postscript();
 rpt_print_system_ready_message();
-return(STAT_OK);
+return STAT_OK;
 }
 
 /*
@@ -102,7 +102,7 @@ For configuration details see: https://github.com/synthetos/TinyG/wiki/TinyG-Con
 "));
 _status_report_advisory();
 _postscript();
-return(STAT_OK);
+return STAT_OK;
 }
 
 /*
@@ -133,7 +133,7 @@ Tests start with a G0 X0 Y0 Z0 move\n\
 Homing is the exception. No initial position or clearance is assumed\n\
 "));
 _postscript();
-return(STAT_OK);
+return STAT_OK;
 }
 
 /*
@@ -146,7 +146,7 @@ fprintf_P(stderr, PSTR("\
 Enter $defa=1 to reset the system to the factory default values.\n\
 This will overwrite any changes you have made.\n"));
 _postscript();
-return(STAT_OK);
+return STAT_OK;
 }
 
 /*
@@ -158,7 +158,7 @@ fprintf_P(stderr, PSTR("\n\n\n### TinyG BOOT LOADER Help ###\n"));
 fprintf_P(stderr, PSTR("\
 Enter $boot=1 to enter the boot loader.\n"));
 _postscript();
-return(STAT_OK);
+return STAT_OK;
 }
 
 #endif // __HELP_SCREENS
index df53ebc911134b32e256d1d89e08e4c87c2d3d03..24270007f09f487b6c70fe954c0a682dc0059d9e 100644 (file)
@@ -254,7 +254,7 @@ static stat_t _get_nv_pair(nvObj_t *nv, char_t **pstr, int8_t *depth)
         nv->valuetype = TYPE_PARENT;
 //        *depth += 1;                            // nv_reset_nv() sets the next object's level so this is redundant
         (*pstr)++;
-        return(STAT_EAGAIN);                    // signal that there is more to parse
+        return STAT_EAGAIN;                    // signal that there is more to parse
 
     // strings
     } else if (**pstr == '\"') {                 // value is a string
@@ -566,7 +566,7 @@ stat_t json_set_jv(nvObj_t *nv)
     if (nv->value >= JV_LINENUM)    { js.echo_json_linenum = true;}
     if (nv->value >= JV_VERBOSE)    { js.echo_json_gcode_block = true;}
 
-    return(STAT_OK);
+    return STAT_OK;
 }
 
 
index 7a3f1548a85371cc71fd7f95c073fbf424ec6a2d..9f05d92ce4bbd22f61583d591153e5b8b3312779 100644 (file)
@@ -57,7 +57,7 @@ stat_t read_persistent_value(nvObj_t *nv) {
 
 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
+    return rpt_exception(STAT_FILE_NOT_OPEN);    // can't write when machine is moving
 
   nvm.tmp_value = nv->value;
   ritorno(read_persistent_value(nv));
index 39f8ca6c5a21279d6ef60ededa926978efd43fb5..edf44bc0193cad9ee3c1c8d11c9fae34c0627f1e 100644 (file)
@@ -65,7 +65,7 @@ stat_t mp_exec_move()
         if (cm.motion_state == MOTION_STOP) cm_set_motion_state(MOTION_RUN);
     }
     if (bf->bf_func == 0)
-        return(cm_hard_alarm(STAT_INTERNAL_ERROR));     // never supposed to get here
+        return cm_hard_alarm(STAT_INTERNAL_ERROR);     // never supposed to get here
 
     return bf->bf_func(bf);                             // run the move callback in the planner buffer
 }
@@ -203,7 +203,7 @@ stat_t mp_exec_aline(mpBuf_t *bf)
     if (mr.section == SECTION_BODY) { status = _exec_aline_body();} else
     if (mr.section == SECTION_TAIL) { status = _exec_aline_tail();} else
     if (mr.move_state == MOVE_SKIP_BLOCK) { status = STAT_OK;}
-    else { return(cm_hard_alarm(STAT_INTERNAL_ERROR));}    // never supposed to get here
+    else { return cm_hard_alarm(STAT_INTERNAL_ERROR);}    // never supposed to get here
 
     // Feedhold processing. Refer to canonical_machine.h for state machine
     // Catch the feedhold request and start the planning the hold
@@ -387,7 +387,7 @@ static stat_t _exec_aline_head()
     if (mr.section_state == SECTION_NEW) {                            // initialize the move singleton (mr)
         if (fp_ZERO(mr.head_length)) {
             mr.section = SECTION_BODY;
-            return(_exec_aline_body());                                // skip ahead to the body generator
+            return _exec_aline_body();                                // skip ahead to the body generator
         }
         mr.midpoint_velocity = (mr.entry_velocity + mr.cruise_velocity) / 2;
         mr.gm.move_time = mr.head_length / mr.midpoint_velocity;    // time for entire accel region
@@ -399,7 +399,7 @@ static stat_t _exec_aline_head()
         mr.elapsed_accel_time = mr.segment_accel_time / 2;            // elapsed time starting point (offset)
         mr.segment_count = (uint32_t)mr.segments;
         if (mr.segment_time < MIN_SEGMENT_TIME)
-            return(STAT_MINIMUM_TIME_MOVE);                         // exit without advancing position
+            return STAT_MINIMUM_TIME_MOVE;                         // exit without advancing position
         mr.section = SECTION_HEAD;
         mr.section_state = SECTION_1st_HALF;
     }
@@ -410,7 +410,7 @@ static stat_t _exec_aline_head()
             mr.section_state = SECTION_2nd_HALF;
             mr.elapsed_accel_time = mr.segment_accel_time / 2;        // start time from midpoint of segment
         }
-        return(STAT_EAGAIN);
+        return STAT_EAGAIN;
     }
     if (mr.section_state == SECTION_2nd_HALF) {                        // SECOND HAF (convex part of accel curve)
         mr.segment_velocity = mr.midpoint_velocity +
@@ -418,12 +418,12 @@ static stat_t _exec_aline_head()
             (square(mr.elapsed_accel_time) * mr.jerk_div2);
         if (_exec_aline_segment() == STAT_OK) {                        // OK means this section is done
             if ((fp_ZERO(mr.body_length)) && (fp_ZERO(mr.tail_length)))
-                return(STAT_OK);                                    // ends the move
+                return STAT_OK;                                    // ends the move
             mr.section = SECTION_BODY;
             mr.section_state = SECTION_NEW;
         }
     }
-    return(STAT_EAGAIN);
+    return STAT_EAGAIN;
 }
 #else // __ JERK_EXEC
 
@@ -432,7 +432,7 @@ static stat_t _exec_aline_head()
     if (mr.section_state == SECTION_NEW) {                            // initialize the move singleton (mr)
         if (fp_ZERO(mr.head_length)) {
             mr.section = SECTION_BODY;
-            return(_exec_aline_body());                                // skip ahead to the body generator
+            return _exec_aline_body();                                // skip ahead to the body generator
         }
         mr.gm.move_time = 2*mr.head_length / (mr.entry_velocity + mr.cruise_velocity);// time for entire accel region
         mr.segments = ceil(uSec(mr.gm.move_time) / NOM_SEGMENT_USEC);// # of segments for the section
@@ -440,7 +440,7 @@ static stat_t _exec_aline_head()
         _init_forward_diffs(mr.entry_velocity, mr.cruise_velocity);
         mr.segment_count = (uint32_t)mr.segments;
         if (mr.segment_time < MIN_SEGMENT_TIME)
-            return(STAT_MINIMUM_TIME_MOVE);                         // exit without advancing position
+            return STAT_MINIMUM_TIME_MOVE;                         // exit without advancing position
         mr.section = SECTION_HEAD;
         mr.section_state = SECTION_1st_HALF;                        // Note: Set to SECTION_1st_HALF for one segment
     }
@@ -453,7 +453,7 @@ static stat_t _exec_aline_head()
         } else {
             mr.section_state = SECTION_2nd_HALF;
         }
-        return(STAT_EAGAIN);
+        return STAT_EAGAIN;
     }
     if (mr.section_state == SECTION_2nd_HALF) {                        // SECOND HALF (convex part of accel curve)
 #ifndef __KAHAN
@@ -467,7 +467,7 @@ static stat_t _exec_aline_head()
 
         if (_exec_aline_segment() == STAT_OK) {                     // set up for body
             if ((fp_ZERO(mr.body_length)) && (fp_ZERO(mr.tail_length)))
-                return(STAT_OK);                                    // ends the move
+                return STAT_OK;                                    // ends the move
             mr.section = SECTION_BODY;
             mr.section_state = SECTION_NEW;
         } else {
@@ -503,7 +503,7 @@ static stat_t _exec_aline_head()
 #endif
         }
     }
-    return(STAT_EAGAIN);
+    return STAT_EAGAIN;
 }
 #endif // __ JERK_EXEC
 
@@ -518,7 +518,7 @@ static stat_t _exec_aline_body()
     if (mr.section_state == SECTION_NEW) {
         if (fp_ZERO(mr.body_length)) {
             mr.section = SECTION_TAIL;
-            return(_exec_aline_tail());                        // skip ahead to tail periods
+            return _exec_aline_tail();                        // skip ahead to tail periods
         }
         mr.gm.move_time = mr.body_length / mr.cruise_velocity;
         mr.segments = ceil(uSec(mr.gm.move_time) / NOM_SEGMENT_USEC);
@@ -526,19 +526,19 @@ static stat_t _exec_aline_body()
         mr.segment_velocity = mr.cruise_velocity;
         mr.segment_count = (uint32_t)mr.segments;
         if (mr.segment_time < MIN_SEGMENT_TIME)
-            return(STAT_MINIMUM_TIME_MOVE);                 // exit without advancing position
+            return STAT_MINIMUM_TIME_MOVE;                 // exit without advancing position
         mr.section = SECTION_BODY;
         mr.section_state = SECTION_2nd_HALF;                // uses PERIOD_2 so last segment detection works
     }
     if (mr.section_state == SECTION_2nd_HALF) {                // straight part (period 3)
         if (_exec_aline_segment() == STAT_OK) {                // OK means this section is done
             if (fp_ZERO(mr.tail_length))
-                return(STAT_OK);                            // ends the move
+                return STAT_OK;                            // ends the move
             mr.section = SECTION_TAIL;
             mr.section_state = SECTION_NEW;
         }
     }
-    return(STAT_EAGAIN);
+    return STAT_EAGAIN;
 }
 
 /*********************************************************************************************
@@ -551,7 +551,7 @@ static stat_t _exec_aline_tail()
 {
     if (mr.section_state == SECTION_NEW) {                            // INITIALIZATION
         if (fp_ZERO(mr.tail_length))
-            return(STAT_OK);                                        // end the move
+            return STAT_OK;                                        // end the move
         mr.midpoint_velocity = (mr.cruise_velocity + mr.exit_velocity) / 2;
         mr.gm.move_time = mr.tail_length / mr.midpoint_velocity;
         mr.segments = ceil(uSec(mr.gm.move_time) / (2 * NOM_SEGMENT_USEC));// # of segments in *each half*
@@ -562,7 +562,7 @@ static stat_t _exec_aline_tail()
         mr.elapsed_accel_time = mr.segment_accel_time / 2;            //compute time from midpoint of segment
         mr.segment_count = (uint32_t)mr.segments;
         if (mr.segment_time < MIN_SEGMENT_TIME)
-            return(STAT_MINIMUM_TIME_MOVE);                         // exit without advancing position
+            return STAT_MINIMUM_TIME_MOVE;                         // exit without advancing position
         mr.section = SECTION_TAIL;
         mr.section_state = SECTION_1st_HALF;
     }
@@ -573,7 +573,7 @@ static stat_t _exec_aline_tail()
             mr.section_state = SECTION_2nd_HALF;
             mr.elapsed_accel_time = mr.segment_accel_time / 2;        // start time from midpoint of segment
         }
-        return(STAT_EAGAIN);
+        return STAT_EAGAIN;
     }
     if (mr.section_state == SECTION_2nd_HALF) {                        // SECOND HALF - concave part (period 5)
         mr.segment_velocity = mr.midpoint_velocity -
@@ -581,7 +581,7 @@ static stat_t _exec_aline_tail()
             (square(mr.elapsed_accel_time) * mr.jerk_div2);
         return _exec_aline_segment();                             // ends the move or continues EAGAIN
     }
-    return(STAT_EAGAIN);                                            // should never get here
+    return STAT_EAGAIN;                                            // should never get here
 }
 
 #else // __JERK_EXEC -- run forward differencing math
@@ -590,14 +590,14 @@ static stat_t _exec_aline_tail()
 {
     if (mr.section_state == SECTION_NEW) {                            // INITIALIZATION
         if (fp_ZERO(mr.tail_length))
-            return(STAT_OK);                                        // end the move
+            return STAT_OK;                                        // end the move
         mr.gm.move_time = 2*mr.tail_length / (mr.cruise_velocity + mr.exit_velocity); // len/avg. velocity
         mr.segments = ceil(uSec(mr.gm.move_time) / NOM_SEGMENT_USEC);// # of segments for the section
         mr.segment_time = mr.gm.move_time / mr.segments;            // time to advance for each segment
         _init_forward_diffs(mr.cruise_velocity, mr.exit_velocity);
         mr.segment_count = (uint32_t)mr.segments;
         if (mr.segment_time < MIN_SEGMENT_TIME)
-            return(STAT_MINIMUM_TIME_MOVE);                         // exit without advancing position
+            return STAT_MINIMUM_TIME_MOVE;                         // exit without advancing position
         mr.section = SECTION_TAIL;
         mr.section_state = SECTION_1st_HALF;
     }
@@ -611,7 +611,7 @@ static stat_t _exec_aline_tail()
         } else {
             mr.section_state = SECTION_2nd_HALF;
         }
-        return(STAT_EAGAIN);
+        return STAT_EAGAIN;
     }
     if (mr.section_state == SECTION_2nd_HALF) {                        // SECOND HALF - concave part (period 5)
 #ifndef __KAHAN
@@ -658,7 +658,7 @@ static stat_t _exec_aline_tail()
 #endif
         }
     }
-    return(STAT_EAGAIN);                                    // should never get here
+    return STAT_EAGAIN;                                    // should never get here
 }
 #endif // __JERK_EXEC
 
index f024317475fb99d97ace28c7f2c03338ee37b4fe..c880ef360cacacd0158bbc4d3f93da19ba4bcded 100644 (file)
@@ -143,7 +143,7 @@ stat_t mp_aline(GCodeState_t *gm_in)
 
     // get a cleared buffer and setup move variables
     if ((bf = mp_get_write_buffer()) == 0)
-        return(cm_hard_alarm(STAT_BUFFER_FULL_FATAL));                  // never supposed to fail
+        return cm_hard_alarm(STAT_BUFFER_FULL_FATAL);                  // never supposed to fail
     bf->bf_func = mp_exec_aline;                                        // register the callback to the exec function
     bf->length = length;
     memcpy(&bf->gm, gm_in, sizeof(GCodeState_t));                        // copy model state into planner buffer
index f477438a5c81a9531cab4ab0083c13e0aec9c881..7b289f5b427f3f17c2da8ea48ca5d62e7b884aed 100644 (file)
@@ -336,7 +336,7 @@ void mp_calculate_trapezoid(mpBuf_t *bf)
  *     e)    Vf = L^(2/3) * Jm^(1/3) + Vi
  *
  *  FYI: Here's an expression that returns the jerk for a given deltaV and L:
- *     return(cube(deltaV / (pow(L, 0.66666666))));
+ *     return cube(deltaV / (pow(L, 0.66666666)));
  */
 
 float mp_get_target_length(const float Vi, const float Vf, const mpBuf_t *bf)
index df5f394164f188e0261aea228b32fe0a129e7c77..07c02bb0fa077245b6b18b5ce227b353aae53a0b 100644 (file)
@@ -237,7 +237,7 @@ stat_t mp_dwell(float seconds)
     mpBuf_t *bf;
 
     if ((bf = mp_get_write_buffer()) == 0)            // get write buffer or fail
-        return(cm_hard_alarm(STAT_BUFFER_FULL_FATAL));    // not ever supposed to fail
+        return cm_hard_alarm(STAT_BUFFER_FULL_FATAL);    // not ever supposed to fail
 
     bf->bf_func = _exec_dwell;                            // register callback to dwell start
     bf->gm.move_time = seconds;                            // in seconds, not minutes
@@ -400,7 +400,7 @@ uint8_t mp_free_run_buffer()                    // EMPTY current run buf & adv t
 
 mpBuf_t * mp_get_first_buffer()
 {
-    return(mp_get_run_buffer());    // returns buffer or 0 if nothing's running
+    return mp_get_run_buffer();    // returns buffer or 0 if nothing's running
 }
 
 mpBuf_t * mp_get_last_buffer()
@@ -408,7 +408,7 @@ mpBuf_t * mp_get_last_buffer()
     mpBuf_t *bf = mp_get_run_buffer();
     mpBuf_t *bp = bf;
 
-    if (bf == 0) return(0);
+    if (bf == 0) return 0;
 
     do {
         if ((bp->nx->move_state == MOVE_OFF) || (bp->nx == bf)) {
index b5289e5be82b1bae3a6f00dac2bd6d5937622503..bd2e8429ff4d5a2af8bbef32b328fc12a89e949c 100644 (file)
@@ -61,7 +61,7 @@ stat_t rpt_exception(uint8_t status)
                TINYG_FIRMWARE_BUILD, status, get_status_message(status));
     }
   }
-  return status;            // makes it possible to inline, e.g: return(rpt_exception(status));
+  return status;            // makes it possible to inline, e.g: return rpt_exception(status);
 }
 
 /*
@@ -69,7 +69,7 @@ stat_t rpt_exception(uint8_t status)
  */
 stat_t rpt_er(nvObj_t *nv)
 {
-  return(rpt_exception(STAT_GENERIC_EXCEPTION_REPORT)); // bogus exception report for testing
+  return rpt_exception(STAT_GENERIC_EXCEPTION_REPORT); // bogus exception report for testing
 }
 
 /**** Application Messages *********************************************************
@@ -226,7 +226,7 @@ stat_t sr_set_status_report(nvObj_t *nv)
   if (elements == 0)
     return STAT_INVALID_OR_MALFORMED_COMMAND;
   memcpy(sr.status_report_list, status_report_list, sizeof(status_report_list));
-  return(_populate_unfiltered_status_report());            // return current values
+  return _populate_unfiltered_status_report();            // return current values
 }
 
 /*
@@ -386,7 +386,7 @@ stat_t sr_set_si(nvObj_t *nv)
 {
   if (nv->value < STATUS_REPORT_MIN_MS) { nv->value = STATUS_REPORT_MIN_MS;}
   sr.status_report_interval = (uint32_t)nv->value;
-  return(STAT_OK);
+  return STAT_OK;
 }
 
 /*********************
index 0237e7c674d7b63d11c3e650459a246944284507..f687802496374d63a3d9c3fb02a93e47b9ac28c4 100644 (file)
@@ -88,7 +88,7 @@ stat_t cm_spindle_control(uint8_t spindle_mode)
 {
     float value[AXES] = { (float)spindle_mode, 0,0,0,0,0 };
     mp_queue_command(_exec_spindle_control, value, value);
-    return(STAT_OK);
+    return STAT_OK;
 }
 
 //static void _exec_spindle_control(uint8_t spindle_mode, float f, float *vector, float *flag)
index 47b81231d81b98a32363865ffe04360c25ff5a0e..2270095c2ed9e40f41012883ed9caabc65825817 100644 (file)
 #include "text_parser.h"
 #include "util.h"
 
-/**** Allocate structures ****/
 
 stConfig_t st_cfg;
 stPrepSingleton_t st_pre;
 static stRunSingleton_t st_run;
 
-/**** Setup local functions ****/
-
 static void _load_move();
 static void _request_load_move();
 
+
 // handy macro
 #define _f_to_period(f) (uint16_t)((float)F_CPU / (float)f)
 
+
 /*
  * stepper_init() - initialize stepper motor subsystem
  *
  *    Notes:
  *      - This init requires sys_init() to be run beforehand
- *       - microsteps are setup during config_init()
+ *      - microsteps are setup during config_init()
  *      - motor polarity is setup during config_init()
  *      - high level interrupts must be enabled in main() once all inits are complete
  */
@@ -75,69 +74,69 @@ static void _request_load_move();
  *    pmc_enable_periph_clk(TC_ID_DDA);
  *    TC_Start(TC_BLOCK_DDA, TC_CHANNEL_DDA);
  */
+void stepper_init() {
+  memset(&st_run, 0, sizeof(st_run));            // clear all values, pointers and status
+  stepper_init_assertions();
 
-void stepper_init()
-{
-    memset(&st_run, 0, sizeof(st_run));            // clear all values, pointers and status
-    stepper_init_assertions();
+  // Configure virtual ports
+  PORTCFG.VPCTRLA = PORTCFG_VP0MAP_PORT_MOTOR_1_gc | PORTCFG_VP1MAP_PORT_MOTOR_2_gc;
+  PORTCFG.VPCTRLB = PORTCFG_VP2MAP_PORT_MOTOR_3_gc | PORTCFG_VP3MAP_PORT_MOTOR_4_gc;
 
-    // Configure virtual ports
-    PORTCFG.VPCTRLA = PORTCFG_VP0MAP_PORT_MOTOR_1_gc | PORTCFG_VP1MAP_PORT_MOTOR_2_gc;
-    PORTCFG.VPCTRLB = PORTCFG_VP2MAP_PORT_MOTOR_3_gc | PORTCFG_VP3MAP_PORT_MOTOR_4_gc;
+  // setup ports and data structures
+  for (uint8_t i = 0; i < MOTORS; i++) {
+    hw.st_port[i]->DIR = MOTOR_PORT_DIR_gm;    // sets outputs for motors & GPIO1, and GPIO2 inputs
+    hw.st_port[i]->OUT = MOTOR_ENABLE_BIT_bm;  // zero port bits AND disable motor
+  }
 
-    // setup ports and data structures
-    for (uint8_t i=0; i<MOTORS; i++) {
-        hw.st_port[i]->DIR = MOTOR_PORT_DIR_gm;  // sets outputs for motors & GPIO1, and GPIO2 inputs
-        hw.st_port[i]->OUT = MOTOR_ENABLE_BIT_bm;// zero port bits AND disable motor
-    }
-    // setup DDA timer
-    TIMER_DDA.CTRLA = STEP_TIMER_DISABLE;        // turn timer off
-    TIMER_DDA.CTRLB = STEP_TIMER_WGMODE;        // waveform mode
-    TIMER_DDA.INTCTRLA = TIMER_DDA_INTLVL;        // interrupt mode
+  // setup DDA timer
+  TIMER_DDA.CTRLA = STEP_TIMER_DISABLE;        // turn timer off
+  TIMER_DDA.CTRLB = STEP_TIMER_WGMODE;         // waveform mode
+  TIMER_DDA.INTCTRLA = TIMER_DDA_INTLVL;       // interrupt mode
 
-    // setup DWELL timer
-    TIMER_DWELL.CTRLA = STEP_TIMER_DISABLE;        // turn timer off
-    TIMER_DWELL.CTRLB = STEP_TIMER_WGMODE;        // waveform mode
-    TIMER_DWELL.INTCTRLA = TIMER_DWELL_INTLVL;    // interrupt mode
+  // setup DWELL timer
+  TIMER_DWELL.CTRLA = STEP_TIMER_DISABLE;      // turn timer off
+  TIMER_DWELL.CTRLB = STEP_TIMER_WGMODE;       // waveform mode
+  TIMER_DWELL.INTCTRLA = TIMER_DWELL_INTLVL;   // interrupt mode
 
-    // setup software interrupt load timer
-    TIMER_LOAD.CTRLA = LOAD_TIMER_DISABLE;        // turn timer off
-    TIMER_LOAD.CTRLB = LOAD_TIMER_WGMODE;        // waveform mode
-    TIMER_LOAD.INTCTRLA = TIMER_LOAD_INTLVL;    // interrupt mode
-    TIMER_LOAD.PER = LOAD_TIMER_PERIOD;            // set period
+  // setup software interrupt load timer
+  TIMER_LOAD.CTRLA = LOAD_TIMER_DISABLE;       // turn timer off
+  TIMER_LOAD.CTRLB = LOAD_TIMER_WGMODE;        // waveform mode
+  TIMER_LOAD.INTCTRLA = TIMER_LOAD_INTLVL;     // interrupt mode
+  TIMER_LOAD.PER = LOAD_TIMER_PERIOD;          // set period
 
-    // setup software interrupt exec timer
-    TIMER_EXEC.CTRLA = EXEC_TIMER_DISABLE;        // turn timer off
-    TIMER_EXEC.CTRLB = EXEC_TIMER_WGMODE;        // waveform mode
-    TIMER_EXEC.INTCTRLA = TIMER_EXEC_INTLVL;    // interrupt mode
-    TIMER_EXEC.PER = EXEC_TIMER_PERIOD;            // set period
+  // setup software interrupt exec timer
+  TIMER_EXEC.CTRLA = EXEC_TIMER_DISABLE;       // turn timer off
+  TIMER_EXEC.CTRLB = EXEC_TIMER_WGMODE;        // waveform mode
+  TIMER_EXEC.INTCTRLA = TIMER_EXEC_INTLVL;     // interrupt mode
+  TIMER_EXEC.PER = EXEC_TIMER_PERIOD;          // set period
 
-    st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;
-    st_reset();                                    // reset steppers to known state
+  st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;
+  st_reset();                                    // reset steppers to known state
 }
 
+
 /*
  * stepper_init_assertions() - test assertions, return error code if violation exists
  * stepper_test_assertions() - test assertions, return error code if violation exists
  */
-
-void stepper_init_assertions()
-{
-    st_run.magic_end = MAGICNUM;
-    st_run.magic_start = MAGICNUM;
-    st_pre.magic_end = MAGICNUM;
-    st_pre.magic_start = MAGICNUM;
+void stepper_init_assertions() {
+  st_run.magic_end = MAGICNUM;
+  st_run.magic_start = MAGICNUM;
+  st_pre.magic_end = MAGICNUM;
+  st_pre.magic_start = MAGICNUM;
 }
 
-stat_t stepper_test_assertions()
-{
-    if (st_run.magic_end    != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
-    if (st_run.magic_start    != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
-    if (st_pre.magic_end    != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
-    if (st_pre.magic_start    != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
-    return STAT_OK;
+
+stat_t stepper_test_assertions() {
+  if (st_run.magic_end   != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
+  if (st_run.magic_start != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
+  if (st_pre.magic_end   != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
+  if (st_pre.magic_start != MAGICNUM) return STAT_STEPPER_ASSERTION_FAILURE;
+
+  return STAT_OK;
 }
 
+
 /*
  * st_runtime_isbusy() - return TRUE if runtime is busy:
  *
@@ -145,37 +144,28 @@ stat_t stepper_test_assertions()
  *    - motors are running
  *    - dwell is running
  */
-
-uint8_t st_runtime_isbusy()
-{
-    if (st_run.dda_ticks_downcount == 0) {
-        return false;
-    }
-    return true;
+uint8_t st_runtime_isbusy() {
+  return st_run.dda_ticks_downcount != 0;
 }
 
-/*
- * st_reset() - reset stepper internals
- */
 
-void st_reset()
-{
-    for (uint8_t motor=0; motor<MOTORS; motor++) {
-        st_pre.mot[motor].prev_direction = STEP_INITIAL_DIRECTION;
-        st_run.mot[motor].substep_accumulator = 0;    // will become max negative during per-motor setup;
-        st_pre.mot[motor].corrected_steps = 0;        // diagnostic only - no action effect
-    }
-    mp_set_steps_to_runtime_position();
+/// Reset stepper internals
+void st_reset() {
+  for (uint8_t motor = 0; motor < MOTORS; motor++) {
+    st_pre.mot[motor].prev_direction = STEP_INITIAL_DIRECTION;
+    st_run.mot[motor].substep_accumulator = 0;    // will become max negative during per-motor setup;
+    st_pre.mot[motor].corrected_steps = 0;        // diagnostic only - no action effect
+  }
+
+  mp_set_steps_to_runtime_position();
 }
 
-/*
- * st_clc() - clear counters
- */
 
-stat_t st_clc(nvObj_t *nv)    // clear diagnostic counters, reset stepper prep
-{
-    st_reset();
-    return(STAT_OK);
+/// Clear counters
+stat_t st_clc(nvObj_t *nv) {
+  // clear diagnostic counters, reset stepper prep
+  st_reset();
+  return STAT_OK;
 }
 
 /*
@@ -189,198 +179,192 @@ stat_t st_clc(nvObj_t *nv)    // clear diagnostic counters, reset stepper prep
  * st_deenergize_motors()     - remove power from all motors
  * st_motor_power_callback() - callback to manage motor power sequencing
  */
+static uint8_t _motor_is_enabled(uint8_t motor) {
+  uint8_t port;
+  switch(motor) {
+  case (MOTOR_1): port = PORT_MOTOR_1_VPORT.OUT; break;
+  case (MOTOR_2): port = PORT_MOTOR_2_VPORT.OUT; break;
+  case (MOTOR_3): port = PORT_MOTOR_3_VPORT.OUT; break;
+  case (MOTOR_4): port = PORT_MOTOR_4_VPORT.OUT; break;
+  default: port = 0xff;    // defaults to disabled for bad motor input value
+  }
 
-static uint8_t _motor_is_enabled(uint8_t motor)
-{
-    uint8_t port;
-    switch(motor) {
-        case (MOTOR_1): { port = PORT_MOTOR_1_VPORT.OUT; break; }
-        case (MOTOR_2): { port = PORT_MOTOR_2_VPORT.OUT; break; }
-        case (MOTOR_3): { port = PORT_MOTOR_3_VPORT.OUT; break; }
-        case (MOTOR_4): { port = PORT_MOTOR_4_VPORT.OUT; break; }
-        default: port = 0xff;    // defaults to disabled for bad motor input value
-    }
-    return (port & MOTOR_ENABLE_BIT_bm ? 0 : 1);    // returns 1 if motor is enabled (motor is actually active low)
+  return port & MOTOR_ENABLE_BIT_bm ? 0 : 1;    // returns 1 if motor is enabled (motor is actually active low)
 }
 
-static void _deenergize_motor(const uint8_t motor)
-{
-    switch (motor) {
-        case (MOTOR_1): { PORT_MOTOR_1_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break; }
-        case (MOTOR_2): { PORT_MOTOR_2_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break; }
-        case (MOTOR_3): { PORT_MOTOR_3_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break; }
-        case (MOTOR_4): { PORT_MOTOR_4_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break; }
-    }
-    st_run.mot[motor].power_state = MOTOR_OFF;
+
+static void _deenergize_motor(const uint8_t motor) {
+  switch (motor) {
+  case (MOTOR_1): PORT_MOTOR_1_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break;
+  case (MOTOR_2): PORT_MOTOR_2_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break;
+  case (MOTOR_3): PORT_MOTOR_3_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break;
+  case (MOTOR_4): PORT_MOTOR_4_VPORT.OUT |= MOTOR_ENABLE_BIT_bm; break;
+  }
+
+  st_run.mot[motor].power_state = MOTOR_OFF;
 }
 
-static void _energize_motor(const uint8_t motor)
-{
-    if (st_cfg.mot[motor].power_mode == MOTOR_DISABLED) {
-        _deenergize_motor(motor);
-        return;
-    }
 
-    switch(motor) {
-        case (MOTOR_1): { PORT_MOTOR_1_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break; }
-        case (MOTOR_2): { PORT_MOTOR_2_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break; }
-        case (MOTOR_3): { PORT_MOTOR_3_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break; }
-        case (MOTOR_4): { PORT_MOTOR_4_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break; }
-    }
+static void _energize_motor(const uint8_t motor) {
+  if (st_cfg.mot[motor].power_mode == MOTOR_DISABLED) {
+    _deenergize_motor(motor);
+    return;
+  }
 
-    st_run.mot[motor].power_state = MOTOR_POWER_TIMEOUT_START;
+  switch(motor) {
+  case (MOTOR_1): PORT_MOTOR_1_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break;
+  case (MOTOR_2): PORT_MOTOR_2_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break;
+  case (MOTOR_3): PORT_MOTOR_3_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break;
+  case (MOTOR_4): PORT_MOTOR_4_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm; break;
+  }
+
+  st_run.mot[motor].power_state = MOTOR_POWER_TIMEOUT_START;
 }
 
-void st_energize_motors()
-{
-    for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) {
-        _energize_motor(motor);
-        st_run.mot[motor].power_state = MOTOR_POWER_TIMEOUT_START;
-    }
+
+void st_energize_motors() {
+  for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) {
+    _energize_motor(motor);
+    st_run.mot[motor].power_state = MOTOR_POWER_TIMEOUT_START;
+  }
 }
 
-void st_deenergize_motors()
-{
-    for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++) {
-        _deenergize_motor(motor);
-    }
+
+void st_deenergize_motors() {
+  for (uint8_t motor = MOTOR_1; motor < MOTORS; motor++)
+    _deenergize_motor(motor);
 }
 
+
 /*
  * st_motor_power_callback() - callback to manage motor power sequencing
  *
  *    Handles motor power-down timing, low-power idle, and adaptive motor power
  */
-stat_t st_motor_power_callback()     // called by controller
-{
-    // manage power for each motor individually
-    for (uint8_t m = MOTOR_1; m < MOTORS; m++) {
-
-        // de-energize motor if it's set to MOTOR_DISABLED
-        if (st_cfg.mot[m].power_mode == MOTOR_DISABLED) {
-            _deenergize_motor(m);
-            continue;
-        }
-
-        // energize motor if it's set to MOTOR_ALWAYS_POWERED
-        if (st_cfg.mot[m].power_mode == MOTOR_ALWAYS_POWERED) {
-            if (! _motor_is_enabled(m)) _energize_motor(m);
-            continue;
-        }
-
-        // start a countdown if MOTOR_POWERED_IN_CYCLE or MOTOR_POWERED_ONLY_WHEN_MOVING
-        if (st_run.mot[m].power_state == MOTOR_POWER_TIMEOUT_START) {
-            st_run.mot[m].power_state = MOTOR_POWER_TIMEOUT_COUNTDOWN;
-            st_run.mot[m].power_systick = SysTickTimer_getValue() +
-                                            (st_cfg.motor_power_timeout * 1000);
-        }
-
-        // do not process countdown if in a feedhold
-        if (cm_get_combined_state() == COMBINED_HOLD) {
-            continue;
-        }
-
-        // do not process countdown if in a feedhold
-        if (cm_get_combined_state() == COMBINED_HOLD) {
-            continue;
-        }
-
-        // run the countdown if you are in a countdown
-        if (st_run.mot[m].power_state == MOTOR_POWER_TIMEOUT_COUNTDOWN) {
-            if (SysTickTimer_getValue() > st_run.mot[m].power_systick ) {
-                st_run.mot[m].power_state = MOTOR_IDLE;
-                _deenergize_motor(m);
-                sr_request_status_report(SR_TIMED_REQUEST);        // request a status report when motors shut down
-            }
-        }
+stat_t st_motor_power_callback() {    // called by controller
+  // manage power for each motor individually
+  for (uint8_t m = MOTOR_1; m < MOTORS; m++) {
+
+    // de-energize motor if it's set to MOTOR_DISABLED
+    if (st_cfg.mot[m].power_mode == MOTOR_DISABLED) {
+      _deenergize_motor(m);
+      continue;
     }
-    return STAT_OK;
-}
-
 
-/******************************
- * Interrupt Service Routines *
- ******************************/
-
-/***** Stepper Interrupt Service Routine ************************************************
- * ISR - DDA timer interrupt routine - service ticks from DDA timer
- */
+    // energize motor if it's set to MOTOR_ALWAYS_POWERED
+    if (st_cfg.mot[m].power_mode == MOTOR_ALWAYS_POWERED) {
+      if (! _motor_is_enabled(m)) _energize_motor(m);
+      continue;
+    }
 
-/*
- *    Uses direct struct addresses and literal values for hardware devices - it's faster than
- *    using indexed timer and port accesses. I checked. Even when -0s or -03 is used.
- */
-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
-        st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps;
-        INCREMENT_ENCODER(MOTOR_1);
+    // start a countdown if MOTOR_POWERED_IN_CYCLE or MOTOR_POWERED_ONLY_WHEN_MOVING
+    if (st_run.mot[m].power_state == MOTOR_POWER_TIMEOUT_START) {
+      st_run.mot[m].power_state = MOTOR_POWER_TIMEOUT_COUNTDOWN;
+      st_run.mot[m].power_systick = SysTickTimer_getValue() +
+        (st_cfg.motor_power_timeout * 1000);
     }
-    if ((st_run.mot[MOTOR_2].substep_accumulator += st_run.mot[MOTOR_2].substep_increment) > 0) {
-        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);
+
+    // do not process countdown if in a feedhold
+    if (cm_get_combined_state() == COMBINED_HOLD) {
+      continue;
     }
-    if ((st_run.mot[MOTOR_3].substep_accumulator += st_run.mot[MOTOR_3].substep_increment) > 0) {
-        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);
+
+    // do not process countdown if in a feedhold
+    if (cm_get_combined_state() == COMBINED_HOLD) {
+      continue;
     }
-    if ((st_run.mot[MOTOR_4].substep_accumulator += st_run.mot[MOTOR_4].substep_increment) > 0) {
-        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);
+
+    // run the countdown if you are in a countdown
+    if (st_run.mot[m].power_state == MOTOR_POWER_TIMEOUT_COUNTDOWN) {
+      if (SysTickTimer_getValue() > st_run.mot[m].power_systick ) {
+        st_run.mot[m].power_state = MOTOR_IDLE;
+        _deenergize_motor(m);
+        sr_request_status_report(SR_TIMED_REQUEST);        // request a status report when motors shut down
+      }
     }
+  }
 
-    // pulse stretching for using external drivers.- turn step bits off
-    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
+  return STAT_OK;
+}
 
-    if (--st_run.dda_ticks_downcount != 0) return;
 
-    TIMER_DDA.CTRLA = STEP_TIMER_DISABLE;                // disable DDA timer
-    _load_move();                                        // load the next move
-}
+/***
+    Stepper Interrupt Service Routine
+    DDA timer interrupt routine - service ticks from DDA timer
 
+    Uses direct struct addresses and literal values for hardware devices - it's faster than
+    using indexed timer and port accesses. I checked. Even when -0s or -03 is used.
+*/
+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
+    st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps;
+    INCREMENT_ENCODER(MOTOR_1);
+  }
 
-/***** Dwell Interrupt Service Routine **************************************************
- * ISR - DDA timer interrupt routine - service ticks from DDA timer
- */
+  if ((st_run.mot[MOTOR_2].substep_accumulator += st_run.mot[MOTOR_2].substep_increment) > 0) {
+    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;
+    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;
+    st_run.mot[MOTOR_4].substep_accumulator -= st_run.dda_ticks_X_substeps;
+    INCREMENT_ENCODER(MOTOR_4);
+  }
+
+  // pulse stretching for using external drivers.- turn step bits off
+  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
+  _load_move();                                        // load the next move
+}
+
+
+/// DDA timer interrupt routine - service ticks from DDA timer
 ISR(TIMER_DWELL_ISR_vect) {                                // DWELL timer interrupt
-    if (--st_run.dda_ticks_downcount == 0) {
-        TIMER_DWELL.CTRLA = STEP_TIMER_DISABLE;            // disable DWELL timer
-        _load_move();
-    }
+  if (--st_run.dda_ticks_downcount == 0) {
+    TIMER_DWELL.CTRLA = STEP_TIMER_DISABLE;            // disable DWELL timer
+    _load_move();
+  }
 }
 
+
 /****************************************************************************************
  * Exec sequencing code        - computes and prepares next load segment
  * st_request_exec_move()    - SW interrupt to request to execute a move
  * exec_timer interrupt        - interrupt handler for calling exec function
  */
-
-void st_request_exec_move()
-{
-    if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) {// bother interrupting
-        TIMER_EXEC.PER = EXEC_TIMER_PERIOD;
-        TIMER_EXEC.CTRLA = EXEC_TIMER_ENABLE;                // trigger a LO interrupt
-    }
+void st_request_exec_move() {
+  if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) {// bother interrupting
+    TIMER_EXEC.PER = EXEC_TIMER_PERIOD;
+    TIMER_EXEC.CTRLA = EXEC_TIMER_ENABLE;                // trigger a LO interrupt
+  }
 }
 
+
 ISR(TIMER_EXEC_ISR_vect) {                                // exec move SW interrupt
-    TIMER_EXEC.CTRLA = EXEC_TIMER_DISABLE;                // disable SW interrupt timer
-
-    // exec_move
-    if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) {
-        if (mp_exec_move() != STAT_NOOP) {
-            st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // flip it back
-            _request_load_move();
-        }
+  TIMER_EXEC.CTRLA = EXEC_TIMER_DISABLE;                // disable SW interrupt timer
+
+  // exec_move
+  if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_EXEC) {
+    if (mp_exec_move() != STAT_NOOP) {
+      st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER; // flip it back
+      _request_load_move();
     }
+  }
 }
 
 /****************************************************************************************
@@ -392,21 +376,19 @@ ISR(TIMER_EXEC_ISR_vect) {                                // exec move SW interr
  *    the DDA or dwell ISR. A software interrupt has been provided to allow a non-ISR to
  *    request a load (see st_request_load_move())
  */
+static void _request_load_move() {
+  if (st_runtime_isbusy()) return; // don't request a load if the runtime is busy
 
-static void _request_load_move()
-{
-    if (st_runtime_isbusy()) {
-        return;                                                    // don't request a load if the runtime is busy
-    }
-    if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_LOADER) {    // bother interrupting
-        TIMER_LOAD.PER = LOAD_TIMER_PERIOD;
-        TIMER_LOAD.CTRLA = LOAD_TIMER_ENABLE;                    // trigger a HI interrupt
-    }
+  if (st_pre.buffer_state == PREP_BUFFER_OWNED_BY_LOADER) {  // bother interrupting
+    TIMER_LOAD.PER = LOAD_TIMER_PERIOD;
+    TIMER_LOAD.CTRLA = LOAD_TIMER_ENABLE;                    // trigger a HI interrupt
+  }
 }
 
-ISR(TIMER_LOAD_ISR_vect) {                                        // load steppers SW interrupt
-    TIMER_LOAD.CTRLA = LOAD_TIMER_DISABLE;                        // disable SW interrupt timer
-    _load_move();
+
+ISR(TIMER_LOAD_ISR_vect) {                                      // load steppers SW interrupt
+  TIMER_LOAD.CTRLA = LOAD_TIMER_DISABLE;                        // disable SW interrupt timer
+  _load_move();
 }
 
 
@@ -422,218 +404,230 @@ ISR(TIMER_LOAD_ISR_vect) {                                        // load steppe
  *     - If axis has 0 steps the direction setting can be omitted
  *     - If axis has 0 steps the motor must not be enabled to support power mode = 1
  */
-static void _load_move()
-{
-    // Be aware that dda_ticks_downcount must equal zero for the loader to run.
-    // So the initial load must also have this set to zero as part of initialization
-    if (st_runtime_isbusy()) {
-        return;                                                    // exit if the runtime is busy
-    }
-    if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) {    // if there are no moves to load...
-        return;
+static void _load_move() {
+  // Be aware that dda_ticks_downcount must equal zero for the loader to run.
+  // So the initial load must also have this set to zero as part of initialization
+  if (st_runtime_isbusy()) return; // exit if the runtime is busy
+  if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_LOADER) return; // if there are no moves to load...
+
+  // handle aline loads first (most common case)
+  if (st_pre.move_type == MOVE_TYPE_ALINE) {
+    //**** setup the new segment ****
+    st_run.dda_ticks_downcount = st_pre.dda_ticks;
+    st_run.dda_ticks_X_substeps = st_pre.dda_ticks_X_substeps;
+
+    //**** MOTOR_1 LOAD ****
+
+    // These sections are somewhat optimized for execution speed. The whole load operation
+    // is supposed to take < 10 uSec (Xmega). Be careful if you mess with this.
+
+    // the following if() statement sets the runtime substep increment value or zeroes it
+    if ((st_run.mot[MOTOR_1].substep_increment = st_pre.mot[MOTOR_1].substep_increment) != 0) {
+      // NB: If motor has 0 steps the following is all skipped. This ensures that state comparisons
+      //       always operate on the last segment actually run by this motor, regardless of how many
+      //       segments it may have been inactive in between.
+
+      // Apply accumulator correction if the time base has changed since previous segment
+      if (st_pre.mot[MOTOR_1].accumulator_correction_flag == true) {
+        st_pre.mot[MOTOR_1].accumulator_correction_flag = false;
+        st_run.mot[MOTOR_1].substep_accumulator *= st_pre.mot[MOTOR_1].accumulator_correction;
+      }
+
+      // Detect direction change and if so:
+      //    - Set the direction bit in hardware.
+      //    - Compensate for direction change by flipping substep accumulator value about its midpoint.
+      if (st_pre.mot[MOTOR_1].direction != st_pre.mot[MOTOR_1].prev_direction) {
+        st_pre.mot[MOTOR_1].prev_direction = st_pre.mot[MOTOR_1].direction;
+        st_run.mot[MOTOR_1].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_1].substep_accumulator);
+
+        if (st_pre.mot[MOTOR_1].direction == DIRECTION_CW)
+          PORT_MOTOR_1_VPORT.OUT &= ~DIRECTION_BIT_bm;
+        else PORT_MOTOR_1_VPORT.OUT |= DIRECTION_BIT_bm;
+      }
+
+      SET_ENCODER_STEP_SIGN(MOTOR_1, st_pre.mot[MOTOR_1].step_sign);
+
+      // Enable the stepper and start motor power management
+      if (st_cfg.mot[MOTOR_1].power_mode != MOTOR_DISABLED) {
+        PORT_MOTOR_1_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;             // energize motor
+        st_run.mot[MOTOR_1].power_state = MOTOR_POWER_TIMEOUT_START;// set power management state
+      }
+
+    } else if (st_cfg.mot[MOTOR_1].power_mode == MOTOR_POWERED_IN_CYCLE) {
+      // Motor has 0 steps; might need to energize motor for power mode processing
+      PORT_MOTOR_1_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;             // energize motor
+      st_run.mot[MOTOR_1].power_state = MOTOR_POWER_TIMEOUT_START;
     }
-    // handle aline loads first (most common case)
-    if (st_pre.move_type == MOVE_TYPE_ALINE) {
-
-        //**** setup the new segment ****
-
-        st_run.dda_ticks_downcount = st_pre.dda_ticks;
-        st_run.dda_ticks_X_substeps = st_pre.dda_ticks_X_substeps;
-
-        //**** MOTOR_1 LOAD ****
-
-        // These sections are somewhat optimized for execution speed. The whole load operation
-        // is supposed to take < 10 uSec (Xmega). Be careful if you mess with this.
-
-        // the following if() statement sets the runtime substep increment value or zeroes it
-        if ((st_run.mot[MOTOR_1].substep_increment = st_pre.mot[MOTOR_1].substep_increment) != 0) {
-
-            // NB: If motor has 0 steps the following is all skipped. This ensures that state comparisons
-            //       always operate on the last segment actually run by this motor, regardless of how many
-            //       segments it may have been inactive in between.
-
-            // Apply accumulator correction if the time base has changed since previous segment
-            if (st_pre.mot[MOTOR_1].accumulator_correction_flag == true) {
-                st_pre.mot[MOTOR_1].accumulator_correction_flag = false;
-                st_run.mot[MOTOR_1].substep_accumulator *= st_pre.mot[MOTOR_1].accumulator_correction;
-            }
-
-            // Detect direction change and if so:
-            //    - Set the direction bit in hardware.
-            //    - Compensate for direction change by flipping substep accumulator value about its midpoint.
-
-            if (st_pre.mot[MOTOR_1].direction != st_pre.mot[MOTOR_1].prev_direction) {
-                st_pre.mot[MOTOR_1].prev_direction = st_pre.mot[MOTOR_1].direction;
-                st_run.mot[MOTOR_1].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_1].substep_accumulator);
-                if (st_pre.mot[MOTOR_1].direction == DIRECTION_CW)
-                PORT_MOTOR_1_VPORT.OUT &= ~DIRECTION_BIT_bm; else
-                PORT_MOTOR_1_VPORT.OUT |= DIRECTION_BIT_bm;
-            }
-            SET_ENCODER_STEP_SIGN(MOTOR_1, st_pre.mot[MOTOR_1].step_sign);
-
-            // Enable the stepper and start motor power management
-            if (st_cfg.mot[MOTOR_1].power_mode != MOTOR_DISABLED) {
-                PORT_MOTOR_1_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;             // energize motor
-                st_run.mot[MOTOR_1].power_state = MOTOR_POWER_TIMEOUT_START;// set power management state
-            }
-
-        } else {  // Motor has 0 steps; might need to energize motor for power mode processing
-            if (st_cfg.mot[MOTOR_1].power_mode == MOTOR_POWERED_IN_CYCLE) {
-                PORT_MOTOR_1_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;             // energize motor
-                st_run.mot[MOTOR_1].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        }
-        // accumulate counted steps to the step position and zero out counted steps for the segment currently being loaded
-        ACCUMULATE_ENCODER(MOTOR_1);
+
+    // accumulate counted steps to the step position and zero out counted steps for the segment currently being loaded
+    ACCUMULATE_ENCODER(MOTOR_1);
 
 #if (MOTORS >= 2)    //**** MOTOR_2 LOAD ****
-        if ((st_run.mot[MOTOR_2].substep_increment = st_pre.mot[MOTOR_2].substep_increment) != 0) {
-            if (st_pre.mot[MOTOR_2].accumulator_correction_flag == true) {
-                st_pre.mot[MOTOR_2].accumulator_correction_flag = false;
-                st_run.mot[MOTOR_2].substep_accumulator *= st_pre.mot[MOTOR_2].accumulator_correction;
-            }
-            if (st_pre.mot[MOTOR_2].direction != st_pre.mot[MOTOR_2].prev_direction) {
-                st_pre.mot[MOTOR_2].prev_direction = st_pre.mot[MOTOR_2].direction;
-                st_run.mot[MOTOR_2].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_2].substep_accumulator);
-                if (st_pre.mot[MOTOR_2].direction == DIRECTION_CW)
-                PORT_MOTOR_2_VPORT.OUT &= ~DIRECTION_BIT_bm; else
-                PORT_MOTOR_2_VPORT.OUT |= DIRECTION_BIT_bm;
-            }
-            SET_ENCODER_STEP_SIGN(MOTOR_2, st_pre.mot[MOTOR_2].step_sign);
-            if (st_cfg.mot[MOTOR_2].power_mode != MOTOR_DISABLED) {
-                PORT_MOTOR_2_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_2].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        } else {
-            if (st_cfg.mot[MOTOR_2].power_mode == MOTOR_POWERED_IN_CYCLE) {
-                PORT_MOTOR_2_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_2].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        }
-        ACCUMULATE_ENCODER(MOTOR_2);
+    if ((st_run.mot[MOTOR_2].substep_increment = st_pre.mot[MOTOR_2].substep_increment) != 0) {
+      if (st_pre.mot[MOTOR_2].accumulator_correction_flag == true) {
+        st_pre.mot[MOTOR_2].accumulator_correction_flag = false;
+        st_run.mot[MOTOR_2].substep_accumulator *= st_pre.mot[MOTOR_2].accumulator_correction;
+      }
+
+      if (st_pre.mot[MOTOR_2].direction != st_pre.mot[MOTOR_2].prev_direction) {
+        st_pre.mot[MOTOR_2].prev_direction = st_pre.mot[MOTOR_2].direction;
+        st_run.mot[MOTOR_2].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_2].substep_accumulator);
+        if (st_pre.mot[MOTOR_2].direction == DIRECTION_CW)
+          PORT_MOTOR_2_VPORT.OUT &= ~DIRECTION_BIT_bm;
+        else PORT_MOTOR_2_VPORT.OUT |= DIRECTION_BIT_bm;
+      }
+
+      SET_ENCODER_STEP_SIGN(MOTOR_2, st_pre.mot[MOTOR_2].step_sign);
+
+      if (st_cfg.mot[MOTOR_2].power_mode != MOTOR_DISABLED) {
+        PORT_MOTOR_2_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+        st_run.mot[MOTOR_2].power_state = MOTOR_POWER_TIMEOUT_START;
+      }
+    } else if (st_cfg.mot[MOTOR_2].power_mode == MOTOR_POWERED_IN_CYCLE) {
+      PORT_MOTOR_2_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_2].power_state = MOTOR_POWER_TIMEOUT_START;
+    }
+
+    ACCUMULATE_ENCODER(MOTOR_2);
 #endif
+
 #if (MOTORS >= 3)    //**** MOTOR_3 LOAD ****
-        if ((st_run.mot[MOTOR_3].substep_increment = st_pre.mot[MOTOR_3].substep_increment) != 0) {
-            if (st_pre.mot[MOTOR_3].accumulator_correction_flag == true) {
-                st_pre.mot[MOTOR_3].accumulator_correction_flag = false;
-                st_run.mot[MOTOR_3].substep_accumulator *= st_pre.mot[MOTOR_3].accumulator_correction;
-            }
-            if (st_pre.mot[MOTOR_3].direction != st_pre.mot[MOTOR_3].prev_direction) {
-                st_pre.mot[MOTOR_3].prev_direction = st_pre.mot[MOTOR_3].direction;
-                st_run.mot[MOTOR_3].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_3].substep_accumulator);
-                if (st_pre.mot[MOTOR_3].direction == DIRECTION_CW)
-                PORT_MOTOR_3_VPORT.OUT &= ~DIRECTION_BIT_bm; else
-                PORT_MOTOR_3_VPORT.OUT |= DIRECTION_BIT_bm;
-            }
-            SET_ENCODER_STEP_SIGN(MOTOR_3, st_pre.mot[MOTOR_3].step_sign);
-            if (st_cfg.mot[MOTOR_3].power_mode != MOTOR_DISABLED) {
-                PORT_MOTOR_3_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_3].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        } else {
-            if (st_cfg.mot[MOTOR_3].power_mode == MOTOR_POWERED_IN_CYCLE) {
-                PORT_MOTOR_3_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_3].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        }
-        ACCUMULATE_ENCODER(MOTOR_3);
+    if ((st_run.mot[MOTOR_3].substep_increment = st_pre.mot[MOTOR_3].substep_increment) != 0) {
+      if (st_pre.mot[MOTOR_3].accumulator_correction_flag == true) {
+        st_pre.mot[MOTOR_3].accumulator_correction_flag = false;
+        st_run.mot[MOTOR_3].substep_accumulator *= st_pre.mot[MOTOR_3].accumulator_correction;
+      }
+
+      if (st_pre.mot[MOTOR_3].direction != st_pre.mot[MOTOR_3].prev_direction) {
+        st_pre.mot[MOTOR_3].prev_direction = st_pre.mot[MOTOR_3].direction;
+        st_run.mot[MOTOR_3].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_3].substep_accumulator);
+        if (st_pre.mot[MOTOR_3].direction == DIRECTION_CW)
+          PORT_MOTOR_3_VPORT.OUT &= ~DIRECTION_BIT_bm;
+        else PORT_MOTOR_3_VPORT.OUT |= DIRECTION_BIT_bm;
+      }
+
+      SET_ENCODER_STEP_SIGN(MOTOR_3, st_pre.mot[MOTOR_3].step_sign);
+
+      if (st_cfg.mot[MOTOR_3].power_mode != MOTOR_DISABLED) {
+        PORT_MOTOR_3_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+        st_run.mot[MOTOR_3].power_state = MOTOR_POWER_TIMEOUT_START;
+      }
+
+    } else if (st_cfg.mot[MOTOR_3].power_mode == MOTOR_POWERED_IN_CYCLE) {
+      PORT_MOTOR_3_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_3].power_state = MOTOR_POWER_TIMEOUT_START;
+    }
+
+    ACCUMULATE_ENCODER(MOTOR_3);
 #endif
+
 #if (MOTORS >= 4)  //**** MOTOR_4 LOAD ****
-        if ((st_run.mot[MOTOR_4].substep_increment = st_pre.mot[MOTOR_4].substep_increment) != 0) {
-            if (st_pre.mot[MOTOR_4].accumulator_correction_flag == true) {
-                st_pre.mot[MOTOR_4].accumulator_correction_flag = false;
-                st_run.mot[MOTOR_4].substep_accumulator *= st_pre.mot[MOTOR_4].accumulator_correction;
-            }
-            if (st_pre.mot[MOTOR_4].direction != st_pre.mot[MOTOR_4].prev_direction) {
-                st_pre.mot[MOTOR_4].prev_direction = st_pre.mot[MOTOR_4].direction;
-                st_run.mot[MOTOR_4].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_4].substep_accumulator);
-                if (st_pre.mot[MOTOR_4].direction == DIRECTION_CW)
-                PORT_MOTOR_4_VPORT.OUT &= ~DIRECTION_BIT_bm; else
-                PORT_MOTOR_4_VPORT.OUT |= DIRECTION_BIT_bm;
-            }
-            SET_ENCODER_STEP_SIGN(MOTOR_4, st_pre.mot[MOTOR_4].step_sign);
-            if (st_cfg.mot[MOTOR_4].power_mode != MOTOR_DISABLED) {
-                PORT_MOTOR_4_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_4].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        } else {
-            if (st_cfg.mot[MOTOR_4].power_mode == MOTOR_POWERED_IN_CYCLE) {
-                PORT_MOTOR_4_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_4].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        }
-        ACCUMULATE_ENCODER(MOTOR_4);
+    if ((st_run.mot[MOTOR_4].substep_increment = st_pre.mot[MOTOR_4].substep_increment) != 0) {
+      if (st_pre.mot[MOTOR_4].accumulator_correction_flag == true) {
+        st_pre.mot[MOTOR_4].accumulator_correction_flag = false;
+        st_run.mot[MOTOR_4].substep_accumulator *= st_pre.mot[MOTOR_4].accumulator_correction;
+      }
+
+      if (st_pre.mot[MOTOR_4].direction != st_pre.mot[MOTOR_4].prev_direction) {
+        st_pre.mot[MOTOR_4].prev_direction = st_pre.mot[MOTOR_4].direction;
+        st_run.mot[MOTOR_4].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_4].substep_accumulator);
+
+        if (st_pre.mot[MOTOR_4].direction == DIRECTION_CW)
+          PORT_MOTOR_4_VPORT.OUT &= ~DIRECTION_BIT_bm;
+        else PORT_MOTOR_4_VPORT.OUT |= DIRECTION_BIT_bm;
+      }
+
+      SET_ENCODER_STEP_SIGN(MOTOR_4, st_pre.mot[MOTOR_4].step_sign);
+
+      if (st_cfg.mot[MOTOR_4].power_mode != MOTOR_DISABLED) {
+        PORT_MOTOR_4_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+        st_run.mot[MOTOR_4].power_state = MOTOR_POWER_TIMEOUT_START;
+      }
+
+    } else if (st_cfg.mot[MOTOR_4].power_mode == MOTOR_POWERED_IN_CYCLE) {
+      PORT_MOTOR_4_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_4].power_state = MOTOR_POWER_TIMEOUT_START;
+    }
+
+    ACCUMULATE_ENCODER(MOTOR_4);
 #endif
+
 #if (MOTORS >= 5)    //**** MOTOR_5 LOAD ****
-        if ((st_run.mot[MOTOR_5].substep_increment = st_pre.mot[MOTOR_5].substep_increment) != 0) {
-            if (st_pre.mot[MOTOR_5].accumulator_correction_flag == true) {
-                st_pre.mot[MOTOR_5].accumulator_correction_flag = false;
-                st_run.mot[MOTOR_5].substep_accumulator *= st_pre.mot[MOTOR_5].accumulator_correction;
-            }
-            if (st_pre.mot[MOTOR_5].direction != st_pre.mot[MOTOR_5].prev_direction) {
-                st_pre.mot[MOTOR_5].prev_direction = st_pre.mot[MOTOR_5].direction;
-                st_run.mot[MOTOR_5].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_5].substep_accumulator);
-                if (st_pre.mot[MOTOR_5].direction == DIRECTION_CW)
-                PORT_MOTOR_5_VPORT.OUT &= ~DIRECTION_BIT_bm; else
-                PORT_MOTOR_5_VPORT.OUT |= DIRECTION_BIT_bm;
-            }
-            PORT_MOTOR_5_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-            st_run.mot[MOTOR_5].power_state = MOTOR_POWER_TIMEOUT_START;
-            SET_ENCODER_STEP_SIGN(MOTOR_5, st_pre.mot[MOTOR_5].step_sign);
-        } else {
-            if (st_cfg.mot[MOTOR_5].power_mode == MOTOR_POWERED_IN_CYCLE) {
-                PORT_MOTOR_5_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_5].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        }
-        ACCUMULATE_ENCODER(MOTOR_5);
+    if ((st_run.mot[MOTOR_5].substep_increment = st_pre.mot[MOTOR_5].substep_increment) != 0) {
+      if (st_pre.mot[MOTOR_5].accumulator_correction_flag == true) {
+        st_pre.mot[MOTOR_5].accumulator_correction_flag = false;
+        st_run.mot[MOTOR_5].substep_accumulator *= st_pre.mot[MOTOR_5].accumulator_correction;
+      }
+
+      if (st_pre.mot[MOTOR_5].direction != st_pre.mot[MOTOR_5].prev_direction) {
+        st_pre.mot[MOTOR_5].prev_direction = st_pre.mot[MOTOR_5].direction;
+        st_run.mot[MOTOR_5].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_5].substep_accumulator);
+
+        if (st_pre.mot[MOTOR_5].direction == DIRECTION_CW)
+          PORT_MOTOR_5_VPORT.OUT &= ~DIRECTION_BIT_bm;
+        else PORT_MOTOR_5_VPORT.OUT |= DIRECTION_BIT_bm;
+      }
+
+      PORT_MOTOR_5_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_5].power_state = MOTOR_POWER_TIMEOUT_START;
+      SET_ENCODER_STEP_SIGN(MOTOR_5, st_pre.mot[MOTOR_5].step_sign);
+
+    } else if (st_cfg.mot[MOTOR_5].power_mode == MOTOR_POWERED_IN_CYCLE) {
+      PORT_MOTOR_5_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_5].power_state = MOTOR_POWER_TIMEOUT_START;
+    }
+
+    ACCUMULATE_ENCODER(MOTOR_5);
 #endif
+
 #if (MOTORS >= 6)    //**** MOTOR_6 LOAD ****
-        if ((st_run.mot[MOTOR_6].substep_increment = st_pre.mot[MOTOR_6].substep_increment) != 0) {
-            if (st_pre.mot[MOTOR_6].accumulator_correction_flag == true) {
-                st_pre.mot[MOTOR_6].accumulator_correction_flag = false;
-                st_run.mot[MOTOR_6].substep_accumulator *= st_pre.mot[MOTOR_6].accumulator_correction;
-            }
-            if (st_pre.mot[MOTOR_6].direction != st_pre.mot[MOTOR_6].prev_direction) {
-                st_pre.mot[MOTOR_6].prev_direction = st_pre.mot[MOTOR_6].direction;
-                st_run.mot[MOTOR_6].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_6].substep_accumulator);
-                if (st_pre.mot[MOTOR_6].direction == DIRECTION_CW)
-                PORT_MOTOR_6_VPORT.OUT &= ~DIRECTION_BIT_bm; else
-                PORT_MOTOR_6_VPORT.OUT |= DIRECTION_BIT_bm;
-            }
-            PORT_MOTOR_6_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-            st_run.mot[MOTOR_6].power_state = MOTOR_POWER_TIMEOUT_START;
-            SET_ENCODER_STEP_SIGN(MOTOR_6, st_pre.mot[MOTOR_6].step_sign);
-        } else {
-            if (st_cfg.mot[MOTOR_6].power_mode == MOTOR_POWERED_IN_CYCLE) {
-                PORT_MOTOR_6_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
-                st_run.mot[MOTOR_6].power_state = MOTOR_POWER_TIMEOUT_START;
-            }
-        }
-        ACCUMULATE_ENCODER(MOTOR_6);
+    if ((st_run.mot[MOTOR_6].substep_increment = st_pre.mot[MOTOR_6].substep_increment) != 0) {
+      if (st_pre.mot[MOTOR_6].accumulator_correction_flag == true) {
+        st_pre.mot[MOTOR_6].accumulator_correction_flag = false;
+        st_run.mot[MOTOR_6].substep_accumulator *= st_pre.mot[MOTOR_6].accumulator_correction;
+      }
+
+      if (st_pre.mot[MOTOR_6].direction != st_pre.mot[MOTOR_6].prev_direction) {
+        st_pre.mot[MOTOR_6].prev_direction = st_pre.mot[MOTOR_6].direction;
+        st_run.mot[MOTOR_6].substep_accumulator = -(st_run.dda_ticks_X_substeps + st_run.mot[MOTOR_6].substep_accumulator);
+        if (st_pre.mot[MOTOR_6].direction == DIRECTION_CW)
+          PORT_MOTOR_6_VPORT.OUT &= ~DIRECTION_BIT_bm;
+        else PORT_MOTOR_6_VPORT.OUT |= DIRECTION_BIT_bm;
+      }
+
+      PORT_MOTOR_6_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_6].power_state = MOTOR_POWER_TIMEOUT_START;
+      SET_ENCODER_STEP_SIGN(MOTOR_6, st_pre.mot[MOTOR_6].step_sign);
+
+    } else if (st_cfg.mot[MOTOR_6].power_mode == MOTOR_POWERED_IN_CYCLE) {
+      PORT_MOTOR_6_VPORT.OUT &= ~MOTOR_ENABLE_BIT_bm;
+      st_run.mot[MOTOR_6].power_state = MOTOR_POWER_TIMEOUT_START;
+    }
+
+    ACCUMULATE_ENCODER(MOTOR_6);
 #endif
-        //**** do this last ****
 
-        TIMER_DDA.PER = st_pre.dda_period;
-        TIMER_DDA.CTRLA = STEP_TIMER_ENABLE;            // enable the DDA timer
+    //**** do this last ****
+    TIMER_DDA.PER = st_pre.dda_period;
+    TIMER_DDA.CTRLA = STEP_TIMER_ENABLE;            // enable the DDA timer
 
+  } else if (st_pre.move_type == MOVE_TYPE_DWELL) {
     // handle dwells
-    } else if (st_pre.move_type == MOVE_TYPE_DWELL) {
-        st_run.dda_ticks_downcount = st_pre.dda_ticks;
-        TIMER_DWELL.PER = st_pre.dda_period;            // load dwell timer period
-        TIMER_DWELL.CTRLA = STEP_TIMER_ENABLE;            // enable the dwell timer
+    st_run.dda_ticks_downcount = st_pre.dda_ticks;
+    TIMER_DWELL.PER = st_pre.dda_period;            // load dwell timer period
+    TIMER_DWELL.CTRLA = STEP_TIMER_ENABLE;          // enable the dwell timer
 
+  } else if (st_pre.move_type == MOVE_TYPE_COMMAND)
     // handle synchronous commands
-    } else if (st_pre.move_type == MOVE_TYPE_COMMAND) {
-        mp_runtime_command(st_pre.bf);
-    }
+    mp_runtime_command(st_pre.bf);
 
-    // all other cases drop to here (e.g. Null moves after Mcodes skip to here)
-    st_pre.move_type = MOVE_TYPE_0;
-    st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;    // we are done with the prep buffer - flip the flag back
-    st_request_exec_move();                                // exec and prep next move
+  // all other cases drop to here (e.g. Null moves after Mcodes skip to here)
+  st_pre.move_type = MOVE_TYPE_0;
+  st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;    // we are done with the prep buffer - flip the flag back
+  st_request_exec_move();                             // exec and prep next move
 }
 
+
 /***********************************************************************************
  * st_prep_line() - Prepare the next move for the loader
  *
@@ -654,215 +648,163 @@ static void _load_move()
  *        100% accurate this will affect the move velocity, but not the distance traveled.
  *
  * NOTE:  Many of the expressions are sensitive to casting and execution order to avoid long-term
- *          accuracy errors due to floating point round off. One earlier failed attempt was:
- *            dda_ticks_X_substeps = (int32_t)((microseconds/1000000) * f_dda * dda_substeps);
+ *        accuracy errors due to floating point round off. One earlier failed attempt was:
+ *        dda_ticks_X_substeps = (int32_t)((microseconds / 1000000) * f_dda * dda_substeps);
  */
-
-stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time)
-{
-    // trap conditions that would prevent queueing the line
-    if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_EXEC) {
-        return cm_hard_alarm(STAT_INTERNAL_ERROR);
-    } else if (isinf(segment_time)) { return cm_hard_alarm(STAT_PREP_LINE_MOVE_TIME_IS_INFINITE);    // never supposed to happen
-    } else if (isnan(segment_time)) { return cm_hard_alarm(STAT_PREP_LINE_MOVE_TIME_IS_NAN);        // never supposed to happen
-    } else if (segment_time < EPSILON) { return STAT_MINIMUM_TIME_MOVE;
+stat_t st_prep_line(float travel_steps[], float following_error[], float segment_time) {
+  // trap conditions that would prevent queueing the line
+  if (st_pre.buffer_state != PREP_BUFFER_OWNED_BY_EXEC) return cm_hard_alarm(STAT_INTERNAL_ERROR);
+  else if (isinf(segment_time)) return cm_hard_alarm(STAT_PREP_LINE_MOVE_TIME_IS_INFINITE);    // never supposed to happen
+  else if (isnan(segment_time)) return cm_hard_alarm(STAT_PREP_LINE_MOVE_TIME_IS_NAN);         // never supposed to happen
+  else if (segment_time < EPSILON) return STAT_MINIMUM_TIME_MOVE;
+
+  // setup segment parameters
+  // - dda_ticks is the integer number of DDA clock ticks needed to play out the segment
+  // - ticks_X_substeps is the maximum depth of the DDA accumulator (as a negative number)
+  st_pre.dda_period = _f_to_period(FREQUENCY_DDA);
+  st_pre.dda_ticks = (int32_t)(segment_time * 60 * FREQUENCY_DDA);// NB: converts minutes to seconds
+  st_pre.dda_ticks_X_substeps = st_pre.dda_ticks * DDA_SUBSTEPS;
+
+  // setup motor parameters
+  float correction_steps;
+  for (uint8_t motor = 0; motor < MOTORS; motor++) {
+    // Skip this motor if there are no new steps. Leave all other values intact.
+    if (fp_ZERO(travel_steps[motor])) {
+      st_pre.mot[motor].substep_increment = 0;
+      continue;
     }
-    // setup segment parameters
-    // - dda_ticks is the integer number of DDA clock ticks needed to play out the segment
-    // - ticks_X_substeps is the maximum depth of the DDA accumulator (as a negative number)
 
-    st_pre.dda_period = _f_to_period(FREQUENCY_DDA);
-    st_pre.dda_ticks = (int32_t)(segment_time * 60 * FREQUENCY_DDA);// NB: converts minutes to seconds
-    st_pre.dda_ticks_X_substeps = st_pre.dda_ticks * DDA_SUBSTEPS;
+    // Setup the direction, compensating for polarity.
+    // Set the step_sign which is used by the stepper ISR to accumulate step position
+    if (travel_steps[motor] >= 0) {                    // positive direction
+      st_pre.mot[motor].direction = DIRECTION_CW ^ st_cfg.mot[motor].polarity;
+      st_pre.mot[motor].step_sign = 1;
 
-    // setup motor parameters
-
-    float correction_steps;
-    for (uint8_t motor=0; motor<MOTORS; motor++) {    // I want to remind myself that this is motors, not axes
+    } else {
+      st_pre.mot[motor].direction = DIRECTION_CCW ^ st_cfg.mot[motor].polarity;
+      st_pre.mot[motor].step_sign = -1;
+    }
 
-        // Skip this motor if there are no new steps. Leave all other values intact.
-        if (fp_ZERO(travel_steps[motor])) { st_pre.mot[motor].substep_increment = 0; continue;}
+    // Detect segment time changes and setup the accumulator correction factor and flag.
+    // Putting this here computes the correct factor even if the motor was dormant for some
+    // number of previous moves. Correction is computed based on the last segment time actually used.
+    if (fabs(segment_time - st_pre.mot[motor].prev_segment_time) > 0.0000001) {  // highly tuned FP != compare
+      if (fp_NOT_ZERO(st_pre.mot[motor].prev_segment_time)) {                    // special case to skip first move
+        st_pre.mot[motor].accumulator_correction_flag = true;
+        st_pre.mot[motor].accumulator_correction = segment_time / st_pre.mot[motor].prev_segment_time;
+      }
 
-        // Setup the direction, compensating for polarity.
-        // Set the step_sign which is used by the stepper ISR to accumulate step position
+      st_pre.mot[motor].prev_segment_time = segment_time;
+    }
 
-        if (travel_steps[motor] >= 0) {                    // positive direction
-            st_pre.mot[motor].direction = DIRECTION_CW ^ st_cfg.mot[motor].polarity;
-            st_pre.mot[motor].step_sign = 1;
-        } else {
-            st_pre.mot[motor].direction = DIRECTION_CCW ^ st_cfg.mot[motor].polarity;
-            st_pre.mot[motor].step_sign = -1;
-        }
+#ifdef __STEP_CORRECTION
+    // 'Nudge' correction strategy. Inject a single, scaled correction value then hold off
+    if ((--st_pre.mot[motor].correction_holdoff < 0) &&
+        (fabs(following_error[motor]) > STEP_CORRECTION_THRESHOLD)) {
 
-        // Detect segment time changes and setup the accumulator correction factor and flag.
-        // Putting this here computes the correct factor even if the motor was dormant for some
-        // number of previous moves. Correction is computed based on the last segment time actually used.
+      st_pre.mot[motor].correction_holdoff = STEP_CORRECTION_HOLDOFF;
+      correction_steps = following_error[motor] * STEP_CORRECTION_FACTOR;
 
-        if (fabs(segment_time - st_pre.mot[motor].prev_segment_time) > 0.0000001) { // highly tuned FP != compare
-            if (fp_NOT_ZERO(st_pre.mot[motor].prev_segment_time)) {                    // special case to skip first move
-                st_pre.mot[motor].accumulator_correction_flag = true;
-                st_pre.mot[motor].accumulator_correction = segment_time / st_pre.mot[motor].prev_segment_time;
-            }
-            st_pre.mot[motor].prev_segment_time = segment_time;
-        }
+      if (correction_steps > 0)
+        correction_steps = min3(correction_steps, fabs(travel_steps[motor]), STEP_CORRECTION_MAX);
+      else correction_steps = max3(correction_steps, -fabs(travel_steps[motor]), -STEP_CORRECTION_MAX);
 
-#ifdef __STEP_CORRECTION
-        // 'Nudge' correction strategy. Inject a single, scaled correction value then hold off
-
-        if ((--st_pre.mot[motor].correction_holdoff < 0) &&
-            (fabs(following_error[motor]) > STEP_CORRECTION_THRESHOLD)) {
-
-            st_pre.mot[motor].correction_holdoff = STEP_CORRECTION_HOLDOFF;
-            correction_steps = following_error[motor] * STEP_CORRECTION_FACTOR;
-
-            if (correction_steps > 0) {
-                correction_steps = min3(correction_steps, fabs(travel_steps[motor]), STEP_CORRECTION_MAX);
-            } else {
-                correction_steps = max3(correction_steps, -fabs(travel_steps[motor]), -STEP_CORRECTION_MAX);
-            }
-            st_pre.mot[motor].corrected_steps += correction_steps;
-            travel_steps[motor] -= correction_steps;
-        }
+      st_pre.mot[motor].corrected_steps += correction_steps;
+      travel_steps[motor] -= correction_steps;
+    }
 #endif
-        // Compute substeb increment. The accumulator must be *exactly* the incoming
-        // fractional steps times the substep multiplier or positional drift will occur.
-        // Rounding is performed to eliminate a negative bias in the uint32 conversion
-        // that results in long-term negative drift. (fabs/round order doesn't matter)
 
-        st_pre.mot[motor].substep_increment = round(fabs(travel_steps[motor] * DDA_SUBSTEPS));
-    }
-    st_pre.move_type = MOVE_TYPE_ALINE;
-    st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER;    // signal that prep buffer is ready
-    return STAT_OK;
-}
+    // Compute substeb increment. The accumulator must be *exactly* the incoming
+    // fractional steps times the substep multiplier or positional drift will occur.
+    // Rounding is performed to eliminate a negative bias in the uint32 conversion
+    // that results in long-term negative drift. (fabs/round order doesn't matter)
+    st_pre.mot[motor].substep_increment = round(fabs(travel_steps[motor] * DDA_SUBSTEPS));
+  }
 
-/*
- * st_prep_null() - Keeps the loader happy. Otherwise performs no action
- */
+  st_pre.move_type = MOVE_TYPE_ALINE;
+  st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER;    // signal that prep buffer is ready
 
-void st_prep_null()
-{
-    st_pre.move_type = MOVE_TYPE_0;
-    st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;    // signal that prep buffer is empty
+  return STAT_OK;
 }
 
-/*
- * st_prep_command() - Stage command to execution
- */
 
-void st_prep_command(void *bf)
-{
-    st_pre.move_type = MOVE_TYPE_COMMAND;
-    st_pre.bf = (mpBuf_t *)bf;
-    st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER;    // signal that prep buffer is ready
+/// Keeps the loader happy. Otherwise performs no action
+void st_prep_null() {
+  st_pre.move_type = MOVE_TYPE_0;
+  st_pre.buffer_state = PREP_BUFFER_OWNED_BY_EXEC;    // signal that prep buffer is empty
 }
 
-/*
- * st_prep_dwell()      - Add a dwell to the move buffer
- */
 
-void st_prep_dwell(float microseconds)
-{
-    st_pre.move_type = MOVE_TYPE_DWELL;
-    st_pre.dda_period = _f_to_period(FREQUENCY_DWELL);
-    st_pre.dda_ticks = (uint32_t)((microseconds/1000000) * FREQUENCY_DWELL);
-    st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER;    // signal that prep buffer is ready
+/// Stage command to execution
+void st_prep_command(void *bf) {
+  st_pre.move_type = MOVE_TYPE_COMMAND;
+  st_pre.bf = (mpBuf_t *)bf;
+  st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER;    // signal that prep buffer is ready
 }
 
-/*
- * _set_hw_microsteps() - set microsteps in hardware
- *
- *    For now the microsteps is the same as the microsteps (1,2,4,8)
- *    This may change if microstep morphing is implemented.
- */
 
-static void _set_hw_microsteps(const uint8_t motor, const uint8_t microsteps)
-{
-    if (microsteps == 8) {
-        hw.st_port[motor]->OUTSET = MICROSTEP_BIT_0_bm;
-        hw.st_port[motor]->OUTSET = MICROSTEP_BIT_1_bm;
-    } else if (microsteps == 4) {
-        hw.st_port[motor]->OUTCLR = MICROSTEP_BIT_0_bm;
-        hw.st_port[motor]->OUTSET = MICROSTEP_BIT_1_bm;
-    } else if (microsteps == 2) {
-        hw.st_port[motor]->OUTSET = MICROSTEP_BIT_0_bm;
-        hw.st_port[motor]->OUTCLR = MICROSTEP_BIT_1_bm;
-    } else if (microsteps == 1) {
-        hw.st_port[motor]->OUTCLR = MICROSTEP_BIT_0_bm;
-        hw.st_port[motor]->OUTCLR = MICROSTEP_BIT_1_bm;
-    }
+/// Add a dwell to the move buffer
+void st_prep_dwell(float microseconds) {
+  st_pre.move_type = MOVE_TYPE_DWELL;
+  st_pre.dda_period = _f_to_period(FREQUENCY_DWELL);
+  st_pre.dda_ticks = (uint32_t)(microseconds / 1000000 * FREQUENCY_DWELL);
+  st_pre.buffer_state = PREP_BUFFER_OWNED_BY_LOADER;    // signal that prep buffer is ready
 }
 
 
-/***********************************************************************************
- * CONFIGURATION AND INTERFACE FUNCTIONS
- * Functions to get and set variables from the cfgArray table
- ***********************************************************************************/
+/// Helper to return motor number as an index
+static int8_t _get_motor(const nvObj_t *nv) {
+  return nv->group[0] ? nv->group[0] : nv->token[0] - 0x31;
+}
 
-/* HELPERS
- * _get_motor() - helper to return motor number as an index
- */
 
-static int8_t _get_motor(const nvObj_t *nv)
-{
-    return (nv->group[0] ? nv->group[0] : nv->token[0] - 0x31);
+/// This function will need to be rethought if microstep morphing is implemented
+static void _set_motor_steps_per_unit(nvObj_t *nv) {
+  uint8_t m = _get_motor(nv);
+  st_cfg.mot[m].steps_per_unit = (360 * st_cfg.mot[m].microsteps) / (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle);
+  st_reset();
 }
 
-/*
- * _set_motor_steps_per_unit() - what it says
- * This function will need to be rethought if microstep morphing is implemented
- */
 
-static void _set_motor_steps_per_unit(nvObj_t *nv)
-{
-    uint8_t m = _get_motor(nv);
-    st_cfg.mot[m].steps_per_unit = (360 * st_cfg.mot[m].microsteps) / (st_cfg.mot[m].travel_rev * st_cfg.mot[m].step_angle);
-    st_reset();
+/// Set motor step angle
+stat_t st_set_sa(nvObj_t *nv) {
+  set_flt(nv);
+  _set_motor_steps_per_unit(nv);
+
+  return STAT_OK;
 }
 
-/* PER-MOTOR FUNCTIONS
- * st_set_sa() - set motor step angle
- * st_set_tr() - set travel per motor revolution
- * st_set_mi() - set motor microsteps
- * st_set_pm() - set motor power mode
- * st_set_pl() - set motor power level
- */
 
-stat_t st_set_sa(nvObj_t *nv)            // motor step angle
-{
-    set_flt(nv);
-    _set_motor_steps_per_unit(nv);
-    return(STAT_OK);
-}
+/// Set motor travel per revolution
+stat_t st_set_tr(nvObj_t *nv) {
+  set_flu(nv);
+  _set_motor_steps_per_unit(nv);
 
-stat_t st_set_tr(nvObj_t *nv)            // motor travel per revolution
-{
-    set_flu(nv);
-    _set_motor_steps_per_unit(nv);
-    return(STAT_OK);
+  return STAT_OK;
 }
 
-stat_t st_set_mi(nvObj_t *nv)            // motor microsteps
-{
-    uint32_t mi = (uint32_t)nv->value;
-    if ((mi != 1) && (mi != 2) && (mi != 4) && (mi != 8)) {
-        nv_add_conditional_message((const char_t *)"*** WARNING *** Setting non-standard microstep value");
-    }
-    set_int(nv);                        // set it anyway, even if it's unsupported. It could also be > 255
-    _set_motor_steps_per_unit(nv);
-    _set_hw_microsteps(_get_motor(nv), (uint8_t)nv->value);
-    return STAT_OK;
+
+// Set motor microsteps
+stat_t st_set_mi(nvObj_t *nv) {
+  set_int(nv);
+  _set_motor_steps_per_unit(nv);
+
+  return STAT_OK;
 }
 
-stat_t st_set_pm(nvObj_t *nv)            // motor power mode
-{
-    if ((uint8_t)nv->value >= MOTOR_POWER_MODE_MAX_VALUE)
-        return STAT_INPUT_VALUE_RANGE_ERROR;
-    set_ui8(nv);
-    return STAT_OK;
-    // NOTE: The motor power callback makes these settings take effect immediately
+
+// Set motor power mode
+stat_t st_set_pm(nvObj_t *nv) {
+  // NOTE: The motor power callback makes these settings take effect immediately
+  if ((uint8_t)nv->value >= MOTOR_POWER_MODE_MAX_VALUE)
+    return STAT_INPUT_VALUE_RANGE_ERROR;
+
+  set_ui8(nv);
+
+  return STAT_OK;
 }
 
+
 /*
  * st_set_pl() - set motor power level
  *
@@ -870,77 +812,71 @@ stat_t st_set_pm(nvObj_t *nv)            // motor power mode
  *    This function sets both the scaled and dynamic power levels, and applies the
  *    scaled value to the vref.
  */
-stat_t st_set_pl(nvObj_t *nv)    // motor power level
-{
-    return(STAT_OK);
+stat_t st_set_pl(nvObj_t *nv) {
+  return STAT_OK;
 }
 
-/*
- * st_get_pwr()    - get motor enable power state
- */
-stat_t st_get_pwr(nvObj_t *nv)
-{
-    nv->value = _motor_is_enabled(_get_motor(nv));
-    nv->valuetype = TYPE_INTEGER;
-    return STAT_OK;
+
+/// get motor enable power state
+stat_t st_get_pwr(nvObj_t *nv) {
+  nv->value = _motor_is_enabled(_get_motor(nv));
+  nv->valuetype = TYPE_INTEGER;
+
+  return STAT_OK;
 }
 
+
 /* GLOBAL FUNCTIONS (SYSTEM LEVEL)
- *
- * st_set_mt() - set motor timeout in seconds
- * st_set_md() - disable motor power
- * st_set_me() - enable motor power
- *
  * Calling me or md with 0 will enable or disable all motors
  * Setting a value of 0 will enable or disable all motors
  * Setting a value from 1 to MOTORS will enable or disable that motor only
  */
 
-stat_t st_set_mt(nvObj_t *nv)
-{
-    st_cfg.motor_power_timeout = min(MOTOR_TIMEOUT_SECONDS_MAX, max(nv->value, MOTOR_TIMEOUT_SECONDS_MIN));
-    return STAT_OK;
+/// Set motor timeout in seconds
+stat_t st_set_mt(nvObj_t *nv) {
+  st_cfg.motor_power_timeout = min(MOTOR_TIMEOUT_SECONDS_MAX, max(nv->value, MOTOR_TIMEOUT_SECONDS_MIN));
+  return STAT_OK;
 }
 
-stat_t st_set_md(nvObj_t *nv)    // Make sure this function is not part of initialization --> f00
-{
-    if (((uint8_t)nv->value == 0) || (nv->valuetype == TYPE_0)) {
-        st_deenergize_motors();
-    } else {
-        uint8_t motor = (uint8_t)nv->value;
-        if (motor > MOTORS) {
-            return STAT_INPUT_VALUE_RANGE_ERROR;
-        }
-        _deenergize_motor(motor-1);     // adjust so that motor 1 is actually 0 (etc)
-    }
-    return STAT_OK;
+
+/// Disable motor power
+stat_t st_set_md(nvObj_t *nv) {
+  // Make sure this function is not part of initialization --> f00
+  if (((uint8_t)nv->value == 0) || (nv->valuetype == TYPE_0))
+    st_deenergize_motors();
+
+  else {
+    uint8_t motor = (uint8_t)nv->value;
+    if (motor > MOTORS) return STAT_INPUT_VALUE_RANGE_ERROR;
+    _deenergize_motor(motor - 1);     // adjust so that motor 1 is actually 0 (etc)
+  }
+
+  return STAT_OK;
 }
 
-stat_t st_set_me(nvObj_t *nv)    // Make sure this function is not part of initialization --> f00
-{
-    if (((uint8_t)nv->value == 0) || (nv->valuetype == TYPE_0)) {
-        st_energize_motors();
-    } else {
-        uint8_t motor = (uint8_t)nv->value;
-        if (motor > MOTORS) {
-            return STAT_INPUT_VALUE_RANGE_ERROR;
-        }
-        _energize_motor(motor-1);     // adjust so that motor 1 is actually 0 (etc)
-    }
-    return STAT_OK;
+
+/// enable motor power
+stat_t st_set_me(nvObj_t *nv) {
+  // Make sure this function is not part of initialization --> f00
+  if (((uint8_t)nv->value == 0) || (nv->valuetype == TYPE_0))
+    st_energize_motors();
+
+  else {
+    uint8_t motor = (uint8_t)nv->value;
+    if (motor > MOTORS) return STAT_INPUT_VALUE_RANGE_ERROR;
+    _energize_motor(motor - 1);     // adjust so that motor 1 is actually 0 (etc)
+  }
+
+  return STAT_OK;
 }
 
-/***********************************************************************************
- * TEXT MODE SUPPORT
- * Functions to print variables from the cfgArray table
- ***********************************************************************************/
 
 #ifdef __TEXT_MODE
 
 static const char msg_units0[] PROGMEM = " in";    // used by generic print functions
 static const char msg_units1[] PROGMEM = " mm";
 static const char msg_units2[] PROGMEM = " deg";
-static const char *const msg_units[] PROGMEM = { msg_units0, msg_units1, msg_units2 };
+static const char *const msg_units[] PROGMEM = {msg_units0, msg_units1, msg_units2};
 #define DEGREE_INDEX 2
 
 static const char fmt_me[] PROGMEM = "motors energized\n";
@@ -949,43 +885,43 @@ static const char fmt_mt[] PROGMEM = "[mt]  motor idle timeout%14.2f Sec\n";
 static const char fmt_0ma[] PROGMEM = "[%s%s] m%s map to axis%15d [0=X,1=Y,2=Z...]\n";
 static const char fmt_0sa[] PROGMEM = "[%s%s] m%s step angle%20.3f%s\n";
 static const char fmt_0tr[] PROGMEM = "[%s%s] m%s travel per revolution%10.4f%s\n";
-static const char fmt_0mi[] PROGMEM = "[%s%s] m%s microsteps%16d [1,2,4,8]\n";
+static const char fmt_0mi[] PROGMEM = "[%s%s] m%s microsteps%16d [1,2,4,8,16,32,64,128,256]\n";
 static const char fmt_0po[] PROGMEM = "[%s%s] m%s polarity%18d [0=normal,1=reverse]\n";
 static const char fmt_0pm[] PROGMEM = "[%s%s] m%s power management%10d [0=disabled,1=always on,2=in cycle,3=when moving]\n";
 static const char fmt_0pl[] PROGMEM = "[%s%s] m%s motor power level%13.3f [0.000=minimum, 1.000=maximum]\n";
 static const char fmt_pwr[] PROGMEM = "Motor %c power enabled state:%2.0f\n";
 
-void st_print_mt(nvObj_t *nv) { text_print_flt(nv, fmt_mt);}
-void st_print_me(nvObj_t *nv) { text_print_nul(nv, fmt_me);}
-void st_print_md(nvObj_t *nv) { text_print_nul(nv, fmt_md);}
+void st_print_mt(nvObj_t *nv) {text_print_flt(nv, fmt_mt);}
+void st_print_me(nvObj_t *nv) {text_print_nul(nv, fmt_me);}
+void st_print_md(nvObj_t *nv) {text_print_nul(nv, fmt_md);}
 
-static void _print_motor_ui8(nvObj_t *nv, const char *format)
-{
-    fprintf_P(stderr, format, nv->group, nv->token, nv->group, (uint8_t)nv->value);
+
+static void _print_motor_ui8(nvObj_t *nv, const char *format) {
+  fprintf_P(stderr, format, nv->group, nv->token, nv->group, (uint8_t)nv->value);
 }
 
-static void _print_motor_flt_units(nvObj_t *nv, const char *format, uint8_t units)
-{
-    fprintf_P(stderr, format, nv->group, nv->token, nv->group, nv->value, GET_TEXT_ITEM(msg_units, units));
+
+static void _print_motor_flt_units(nvObj_t *nv, const char *format, uint8_t units) {
+  fprintf_P(stderr, format, nv->group, nv->token, nv->group, nv->value, GET_TEXT_ITEM(msg_units, units));
 }
 
-static void _print_motor_flt(nvObj_t *nv, const char *format)
-{
-    fprintf_P(stderr, format, nv->group, nv->token, nv->group, nv->value);
+
+static void _print_motor_flt(nvObj_t *nv, const char *format) {
+  fprintf_P(stderr, format, nv->group, nv->token, nv->group, nv->value);
 }
 
-static void _print_motor_pwr(nvObj_t *nv, const char *format)
-{
-    fprintf_P(stderr, format, nv->token[0], nv->value);
+static void _print_motor_pwr(nvObj_t *nv, const char *format) {
+  fprintf_P(stderr, format, nv->token[0], nv->value);
 }
 
-void st_print_ma(nvObj_t *nv) { _print_motor_ui8(nv, fmt_0ma);}
-void st_print_sa(nvObj_t *nv) { _print_motor_flt_units(nv, fmt_0sa, DEGREE_INDEX);}
-void st_print_tr(nvObj_t *nv) { _print_motor_flt_units(nv, fmt_0tr, cm_get_units_mode(MODEL));}
-void st_print_mi(nvObj_t *nv) { _print_motor_ui8(nv, fmt_0mi);}
-void st_print_po(nvObj_t *nv) { _print_motor_ui8(nv, fmt_0po);}
-void st_print_pm(nvObj_t *nv) { _print_motor_ui8(nv, fmt_0pm);}
-void st_print_pl(nvObj_t *nv) { _print_motor_flt(nv, fmt_0pl);}
-void st_print_pwr(nvObj_t *nv){ _print_motor_pwr(nv, fmt_pwr);}
+
+void st_print_ma(nvObj_t *nv) {_print_motor_ui8(nv, fmt_0ma);}
+void st_print_sa(nvObj_t *nv) {_print_motor_flt_units(nv, fmt_0sa, DEGREE_INDEX);}
+void st_print_tr(nvObj_t *nv) {_print_motor_flt_units(nv, fmt_0tr, cm_get_units_mode(MODEL));}
+void st_print_mi(nvObj_t *nv) {_print_motor_ui8(nv, fmt_0mi);}
+void st_print_po(nvObj_t *nv) {_print_motor_ui8(nv, fmt_0po);}
+void st_print_pm(nvObj_t *nv) {_print_motor_ui8(nv, fmt_0pm);}
+void st_print_pl(nvObj_t *nv) {_print_motor_flt(nv, fmt_0pl);}
+void st_print_pwr(nvObj_t *nv){_print_motor_pwr(nv, fmt_pwr);}
 
 #endif // __TEXT_MODE
index fe913e681883e23e31798a3dbed63880dadc16c2..f388c44f0c828489e7408beccf9d29aa8c50da43 100644 (file)
  *        Also, all moves are loaded from the DDA interrupt level (HI), avoiding the need
  *        for mutual exclusion locking or volatiles (which slow things down).
  */
+
 /*
- **** Move generation overview and timing illustration ****
- *
- *    This ASCII art illustrates a 4 segment move to show stepper sequencing timing.
- *
- *    LOAD/STEP (~5000uSec)          [L1][segment1][L2][segment2][L3][segment3][L4][segment4][Lb1]
- *    PREP (100 uSec)            [P1]       [P2]          [P3]          [P4]          [Pb1]
- *    EXEC (400 uSec)         [EXEC1]    [EXEC2]       [EXEC3]       [EXEC4]       [EXECb1]
- *    PLAN (<4ms)  [planmoveA][plan move B][plan move C][plan move D][plan move E] etc.
- *
- *    The move begins with the planner PLANning move A [planmoveA]. When this is done the
- *    computations for the first segment of move A's S curve are performed by the planner
- *    runtime, EXEC1. The runtime computes the number of segments and the segment-by-segment
- *    accelerations and decelerations for the move. Each call to EXEC generates the values
- *    for the next segment to be run. Once the move is running EXEC is executed as a
- *    callback from the step loader.
- *
- *    When the runtime calculations are done EXEC calls the segment PREParation function [P1].
- *    PREP turns the EXEC results into values needed for the loader and does some encoder work.
- *    The combined exec and prep take about 400 uSec.
- *
- *    PREP takes care of heavy numerics and other cycle-intesive operations so the step loader
- *    L1 can run as fast as possible. The time budget for LOAD is about 10 uSec. In the diagram,
- *    when P1 is done segment 1 is loaded into the stepper runtime [L1]
- *
- *    Once the segment is loaded it will pulse out steps for the duration of the segment.
- *    Segment timing can vary, but segments take around 5 Msec to pulse out, which is 250 DDA
- *    ticks at a 50 KHz step clock.
- *
- *    Now the move is pulsing out segment 1 (at HI interrupt level). Once the L1 loader is
- *    finished it invokes the exec function for the next segment (at LO interrupt level).
- *    [EXEC2] and [P2] compute and prepare the segment 2 for the loader so it can be loaded
- *    as soon as segment 1 is complete [L2]. When move A is done EXEC pulls the next move
- *    (moveB) from the planner queue, The process repeats until there are no more segments or moves.
- *
- *    While all this is happening subsequent moves (B, C, and D) are being planned in background.
- *    As long as a move takes less than the segment times (5ms x N) the timing budget is satisfied,
- *
- *    A few things worth noting:
- *      -    This scheme uses 2 interrupt levels and background, for 3 levels of execution:
- *        - STEP pulsing and LOADs occur at HI interrupt level
- *        - EXEC and PREP occur at LO interrupt level (leaving MED int level for serial IO)
- *        - move PLANning occurs in background and is managed by the controller
- *
- *      -    Because of the way the timing is laid out there is no contention for resources between
- *        the STEP, LOAD, EXEC, and PREP phases. PLANing is similarly isolated. Very few volatiles
- *        or mutexes are needed, which makes the code simpler and faster. With the exception of
- *        the actual values used in step generation (which runs continuously) you can count on
- *        LOAD, EXEC, PREP and PLAN not stepping on each other's variables.
- */
+**** Move generation overview and timing illustration ****
+*
+*    This ASCII art illustrates a 4 segment move to show stepper sequencing timing.
+*
+*    LOAD/STEP (~5000uSec)          [L1][segment1][L2][segment2][L3][segment3][L4][segment4][Lb1]
+*    PREP (100 uSec)            [P1]       [P2]          [P3]          [P4]          [Pb1]
+*    EXEC (400 uSec)         [EXEC1]    [EXEC2]       [EXEC3]       [EXEC4]       [EXECb1]
+*    PLAN (<4ms)  [planmoveA][plan move B][plan move C][plan move D][plan move E] etc.
+*
+*    The move begins with the planner PLANning move A [planmoveA]. When this is done the
+*    computations for the first segment of move A's S curve are performed by the planner
+*    runtime, EXEC1. The runtime computes the number of segments and the segment-by-segment
+*    accelerations and decelerations for the move. Each call to EXEC generates the values
+*    for the next segment to be run. Once the move is running EXEC is executed as a
+*    callback from the step loader.
+*
+*    When the runtime calculations are done EXEC calls the segment PREParation function [P1].
+*    PREP turns the EXEC results into values needed for the loader and does some encoder work.
+*    The combined exec and prep take about 400 uSec.
+*
+*    PREP takes care of heavy numerics and other cycle-intesive operations so the step loader
+*    L1 can run as fast as possible. The time budget for LOAD is about 10 uSec. In the diagram,
+*    when P1 is done segment 1 is loaded into the stepper runtime [L1]
+*
+*    Once the segment is loaded it will pulse out steps for the duration of the segment.
+*    Segment timing can vary, but segments take around 5 Msec to pulse out, which is 250 DDA
+*    ticks at a 50 KHz step clock.
+*
+*    Now the move is pulsing out segment 1 (at HI interrupt level). Once the L1 loader is
+*    finished it invokes the exec function for the next segment (at LO interrupt level).
+*    [EXEC2] and [P2] compute and prepare the segment 2 for the loader so it can be loaded
+*    as soon as segment 1 is complete [L2]. When move A is done EXEC pulls the next move
+*    (moveB) from the planner queue, The process repeats until there are no more segments or moves.
+*
+*    While all this is happening subsequent moves (B, C, and D) are being planned in background.
+*    As long as a move takes less than the segment times (5ms x N) the timing budget is satisfied,
+*
+*    A few things worth noting:
+*        - This scheme uses 2 interrupt levels and background, for 3 levels of execution:
+*        - STEP pulsing and LOADs occur at HI interrupt level
+*        - EXEC and PREP occur at LO interrupt level (leaving MED int level for serial IO)
+*        - move PLANning occurs in background and is managed by the controller
+*
+*        - Because of the way the timing is laid out there is no contention for resources between
+*          the STEP, LOAD, EXEC, and PREP phases. PLANing is similarly isolated. Very few volatiles
+*          or mutexes are needed, which makes the code simpler and faster. With the exception of
+*          the actual values used in step generation (which runs continuously) you can count on
+*          LOAD, EXEC, PREP and PLAN not stepping on each other's variables.
+*/
+
 /**** Line planning and execution (in more detail) ****
  *
  *    Move planning, execution and pulse generation takes place at 3 levels:
  *    timer interrupts that generate the stepper pulses. This level also transfers new
  *    stepper parameters once each pulse train ("segment") is complete ("load" and "run" stages).
  */
-/*     What happens when the pulse generator is done with the current pulse train (segment)
+
+/*    What happens when the pulse generator is done with the current pulse train (segment)
  *    is a multi-stage "pull" queue that looks like this:
  *
  *    As long as the steppers are running the sequence of events is:
  *    invoked from the main loop by the software interrupt, and the stepper load is
  *    invoked from the exec by another software interrupt.
  */
+
 /*    Control flow can be a bit confusing. This is a typical sequence for planning
  *    executing, and running an acceleration planned line:
  *
  *    Note: For this to work you have to be really careful about what structures
  *    are modified at what level, and use volatiles where necessary.
  */
+
 /* Partial steps and phase angle compensation
  *
  *    The DDA accepts partial steps as input. Fractional steps are managed by the
  *    be thought of as a phase angle value for the DDA accumulation. Each 360
  *    degrees of phase angle results in a step being generated.
  */
+
 #ifndef STEPPER_H_ONCE
 #define STEPPER_H_ONCE
 
-/*********************************
- * Stepper configs and constants *
- *********************************/
-//See hardware.h for platform specific stepper definitions
+// See hardware.h for platform specific stepper definitions
 
 enum prepBufferState {
-    PREP_BUFFER_OWNED_BY_LOADER = 0,    // staging buffer is ready for load
-    PREP_BUFFER_OWNED_BY_EXEC            // staging buffer is being loaded
+  PREP_BUFFER_OWNED_BY_LOADER = 0,     // staging buffer is ready for load
+  PREP_BUFFER_OWNED_BY_EXEC            // staging buffer is being loaded
 };
 
+
 // Currently there is no distinction between IDLE and OFF (DEENERGIZED)
 // In the future IDLE will be powered at a low, torque-maintaining current
-
-enum motorPowerState {                    // used w/start and stop flags to sequence motor power
-    MOTOR_OFF = 0,                        // motor is stopped and deenergized
-    MOTOR_IDLE,                            // motor is stopped and may be partially energized for torque maintenance
-    MOTOR_RUNNING,                        // motor is running (and fully energized)
-    MOTOR_POWER_TIMEOUT_START,            // transitional state to start power-down timeout
-    MOTOR_POWER_TIMEOUT_COUNTDOWN        // count down the time to de-energizing motors
+enum motorPowerState {                 // used w/start and stop flags to sequence motor power
+  MOTOR_OFF = 0,                       // motor is stopped and deenergized
+  MOTOR_IDLE,                          // motor is stopped and may be partially energized for torque maintenance
+  MOTOR_RUNNING,                       // motor is running (and fully energized)
+  MOTOR_POWER_TIMEOUT_START,           // transitional state to start power-down timeout
+  MOTOR_POWER_TIMEOUT_COUNTDOWN        // count down the time to de-energizing motors
 };
 
+
 enum cmMotorPowerMode {
-    MOTOR_DISABLED = 0,                    // motor enable is deactivated
-    MOTOR_ALWAYS_POWERED,                // motor is always powered while machine is ON
-    MOTOR_POWERED_IN_CYCLE,                // motor fully powered during cycles, de-powered out of cycle
-    MOTOR_POWERED_ONLY_WHEN_MOVING,        // motor only powered while moving - idles shortly after it's stopped - even in cycle
-//    MOTOR_POWER_REDUCED_WHEN_IDLE,        // enable Vref current reduction for idle (FUTURE)
-//    MOTOR_ADAPTIVE_POWER                // adjust motor current with velocity (FUTURE)
-    MOTOR_POWER_MODE_MAX_VALUE            // for input range checking
+  MOTOR_DISABLED = 0,                  // motor enable is deactivated
+  MOTOR_ALWAYS_POWERED,                // motor is always powered while machine is ON
+  MOTOR_POWERED_IN_CYCLE,              // motor fully powered during cycles, de-powered out of cycle
+  MOTOR_POWERED_ONLY_WHEN_MOVING,      // motor only powered while moving - idles shortly after it's stopped - even in cycle
+  MOTOR_POWER_MODE_MAX_VALUE           // for input range checking
 };
 
+
 // Min/Max timeouts allowed for motor disable. Allow for inertial stop; must be non-zero
-#define MOTOR_TIMEOUT_SECONDS_MIN     (float)0.1        // seconds !!! SHOULD NEVER BE ZERO !!!
+#define MOTOR_TIMEOUT_SECONDS_MIN    (float)0.1        // seconds !!! SHOULD NEVER BE ZERO !!!
 #define MOTOR_TIMEOUT_SECONDS_MAX    (float)4294967    // (4294967295/1000) -- for conversion to uint32_t
-#define MOTOR_TIMEOUT_SECONDS         (float)0.1        // seconds in DISABLE_AXIS_WHEN_IDLE mode
-#define MOTOR_TIMEOUT_WHEN_MOVING    (float)0.25        // timeout for a motor in _ONLY_WHEN_MOVING mode
+#define MOTOR_TIMEOUT_SECONDS        (float)0.1        // seconds in DISABLE_AXIS_WHEN_IDLE mode
+#define MOTOR_TIMEOUT_WHEN_MOVING    (float)0.25       // timeout for a motor in _ONLY_WHEN_MOVING mode
 
 /* DDA substepping
  *    DDA Substepping is a fixed.point scheme to increase the resolution of the DDA pulse generation
@@ -296,6 +299,7 @@ enum cmMotorPowerMode {
  */
 #define DDA_SUBSTEPS ((MAX_LONG * 0.90) / (FREQUENCY_DDA * (NOM_SEGMENT_TIME * 60)))
 
+
 /* Step correction settings
  *    Step correction settings determine how the encoder error is fed back to correct position errors.
  *    Since the following_error is running 2 segments behind the current segment you have to be careful
@@ -305,10 +309,11 @@ enum cmMotorPowerMode {
  *    and error will grow instead of shrink (or oscillate).
  */
 #define STEP_CORRECTION_THRESHOLD    (float)2.00        // magnitude of forwarding error to apply correction (in steps)
-#define STEP_CORRECTION_FACTOR        (float)0.25        // factor to apply to step correction for a single segment
-#define STEP_CORRECTION_MAX            (float)0.60        // max step correction allowed in a single segment
-#define STEP_CORRECTION_HOLDOFF                    5        // minimum number of segments to wait between error correction
-#define STEP_INITIAL_DIRECTION        DIRECTION_CW
+#define STEP_CORRECTION_FACTOR       (float)0.25        // factor to apply to step correction for a single segment
+#define STEP_CORRECTION_MAX          (float)0.60        // max step correction allowed in a single segment
+#define STEP_CORRECTION_HOLDOFF      5                  // minimum number of segments to wait between error correction
+#define STEP_INITIAL_DIRECTION       DIRECTION_CW
+
 
 /*
  * Stepper control structures
@@ -316,11 +321,11 @@ enum cmMotorPowerMode {
  *    There are 5 main structures involved in stepper operations;
  *
  *    data structure:                        found in:        runs primarily at:
- *      mpBuffer planning buffers (bf)      planner.c          main loop
- *      mrRuntimeSingleton (mr)              planner.c          MED ISR
- *      stConfig (st_cfg)                      stepper.c          write=bkgd, read=ISRs
- *      stPrepSingleton (st_pre)              stepper.c          MED ISR
- *      stRunSingleton (st_run)              stepper.c          HI ISR
+ *      mpBuffer planning buffers (bf)         planner.c        main loop
+ *      mrRuntimeSingleton (mr)                planner.c        MED ISR
+ *      stConfig (st_cfg)                      stepper.c        write=bkgd, read=ISRs
+ *      stPrepSingleton (st_pre)               stepper.c        MED ISR
+ *      stRunSingleton (st_run)                stepper.c        HI ISR
  *
  *    Care has been taken to isolate actions on these structures to the execution level
  *    in which they run and to use the minimum number of volatiles in these structures.
@@ -328,84 +333,86 @@ enum cmMotorPowerMode {
  */
 
 // Motor config structure
-
-typedef struct cfgMotor {                // per-motor configs
-    // public
-    uint8_t    motor_map;                    // map motor to axis
-    uint32_t microsteps;                // microsteps to apply for each axis (ex: 8)
-    uint8_t polarity;                    // 0=normal polarity, 1=reverse motor direction
-    uint8_t power_mode;                    // See cmMotorPowerMode for enum
-    float power_level;                    // set 0.000 to 1.000 for PMW vref setting
-    float step_angle;                    // degrees per whole step (ex: 1.8)
-    float travel_rev;                    // mm or deg of travel per motor revolution
-    float steps_per_unit;                // microsteps per mm (or degree) of travel
-    float units_per_step;                // mm or degrees of travel per microstep
-
-    // private
-    float power_level_scaled;            // scaled to internal range - must be between 0 and 1
+typedef struct cfgMotor {               // per-motor configs
+  // public
+  uint8_t motor_map;                    // map motor to axis
+  uint32_t microsteps;                  // microsteps to apply for each axis (ex: 8)
+  uint8_t polarity;                     // 0=normal polarity, 1=reverse motor direction
+  uint8_t power_mode;                   // See cmMotorPowerMode for enum
+  float power_level;                    // set 0.000 to 1.000 for PMW vref setting
+  float step_angle;                     // degrees per whole step (ex: 1.8)
+  float travel_rev;                     // mm or deg of travel per motor revolution
+  float steps_per_unit;                 // microsteps per mm (or degree) of travel
+  float units_per_step;                 // mm or degrees of travel per microstep
+
+  // private
+  float power_level_scaled;             // scaled to internal range - must be between 0 and 1
 } cfgMotor_t;
 
-typedef struct stConfig {                // stepper configs
-    float motor_power_timeout;            // seconds before setting motors to idle current (currently this is OFF)
-    cfgMotor_t mot[MOTORS];                // settings for motors 1-N
+
+typedef struct stConfig {               // stepper configs
+  float motor_power_timeout;            // seconds before setting motors to idle current (currently this is OFF)
+  cfgMotor_t mot[MOTORS];               // settings for motors 1-N
 } stConfig_t;
 
-// Motor runtime structure. Used exclusively by step generation ISR (HI)
 
-typedef struct stRunMotor {                // one per controlled motor
-    uint32_t substep_increment;            // total steps in axis times substeps factor
-    int32_t substep_accumulator;        // DDA phase angle accumulator
-    uint8_t power_state;                // state machine for managing motor power
-    uint32_t power_systick;                // sys_tick for next motor power state transition
+// Motor runtime structure. Used exclusively by step generation ISR (HI)
+typedef struct stRunMotor {           // one per controlled motor
+  uint32_t substep_increment;         // total steps in axis times substeps factor
+  int32_t substep_accumulator;        // DDA phase angle accumulator
+  uint8_t power_state;                // state machine for managing motor power
+  uint32_t power_systick;             // sys_tick for next motor power state transition
 } stRunMotor_t;
 
-typedef struct stRunSingleton {            // Stepper static values and axis parameters
-    uint16_t magic_start;                // magic number to test memory integrity
-    uint32_t dda_ticks_downcount;        // tick down-counter (unscaled)
-    uint32_t dda_ticks_X_substeps;        // ticks multiplied by scaling factor
-    stRunMotor_t mot[MOTORS];            // runtime motor structures
-    uint16_t magic_end;
+
+typedef struct stRunSingleton {       // Stepper static values and axis parameters
+  uint16_t magic_start;               // magic number to test memory integrity
+  uint32_t dda_ticks_downcount;       // tick down-counter (unscaled)
+  uint32_t dda_ticks_X_substeps;      // ticks multiplied by scaling factor
+  stRunMotor_t mot[MOTORS];           // runtime motor structures
+  uint16_t magic_end;
 } stRunSingleton_t;
 
+
 // Motor prep structure. Used by exec/prep ISR (MED) and read-only during load
 // Must be careful about volatiles in this one
-
 typedef struct stPrepMotor {
-    uint32_t substep_increment;             // total steps in axis times substep factor
+  uint32_t substep_increment;         // total steps in axis times substep factor
 
-    // direction and direction change
-    int8_t direction;                    // travel direction corrected for polarity
-    uint8_t prev_direction;                // travel direction from previous segment run for this motor
-    int8_t step_sign;                    // set to +1 or -1 for encoders
+  // direction and direction change
+  int8_t direction;                   // travel direction corrected for polarity
+  uint8_t prev_direction;             // travel direction from previous segment run for this motor
+  int8_t step_sign;                   // set to +1 or -1 for encoders
 
-    // following error correction
-    int32_t correction_holdoff;            // count down segments between corrections
-    float corrected_steps;                // accumulated correction steps for the cycle (for diagnostic display only)
+  // following error correction
+  int32_t correction_holdoff;         // count down segments between corrections
+  float corrected_steps;              // accumulated correction steps for the cycle (for diagnostic display only)
 
-    // accumulator phase correction
-    float prev_segment_time;            // segment time from previous segment run for this motor
-    float accumulator_correction;        // factor for adjusting accumulator between segments
-    uint8_t accumulator_correction_flag;// signals accumulator needs correction
+  // accumulator phase correction
+  float prev_segment_time;            // segment time from previous segment run for this motor
+  float accumulator_correction;       // factor for adjusting accumulator between segments
+  uint8_t accumulator_correction_flag;// signals accumulator needs correction
 
 } stPrepMotor_t;
 
+
 typedef struct stPrepSingleton {
-    uint16_t magic_start;                // magic number to test memory integrity
-    volatile uint8_t buffer_state;        // prep buffer state - owned by exec or loader
-    struct mpBuffer *bf;                // static pointer to relevant buffer
-    uint8_t move_type;                    // move type
-
-    uint16_t dda_period;                // DDA or dwell clock period setting
-    uint32_t dda_ticks;                    // DDA or dwell ticks for the move
-    uint32_t dda_ticks_X_substeps;        // DDA ticks scaled by substep factor
-    stPrepMotor_t mot[MOTORS];            // prep time motor structs
-    uint16_t magic_end;
+  uint16_t magic_start;               // magic number to test memory integrity
+  volatile uint8_t buffer_state;      // prep buffer state - owned by exec or loader
+  struct mpBuffer *bf;                // static pointer to relevant buffer
+  uint8_t move_type;                  // move type
+
+  uint16_t dda_period;                // DDA or dwell clock period setting
+  uint32_t dda_ticks;                 // DDA or dwell ticks for the move
+  uint32_t dda_ticks_X_substeps;      // DDA ticks scaled by substep factor
+  stPrepMotor_t mot[MOTORS];          // prep time motor structs
+  uint16_t magic_end;
 } stPrepSingleton_t;
 
-extern stConfig_t st_cfg;                // config struct is exposed. The rest are private
-extern stPrepSingleton_t st_pre;        // only used by config_app diagnostics
 
-/**** FUNCTION PROTOTYPES ****/
+extern stConfig_t st_cfg;             // config struct is exposed. The rest are private
+extern stPrepSingleton_t st_pre;      // only used by config_app diagnostics
+
 
 void stepper_init();
 void stepper_init_assertions();
@@ -441,32 +448,32 @@ stat_t st_set_me(nvObj_t *nv);
 
 #ifdef __TEXT_MODE
 
-    void st_print_ma(nvObj_t *nv);
-    void st_print_sa(nvObj_t *nv);
-    void st_print_tr(nvObj_t *nv);
-    void st_print_mi(nvObj_t *nv);
-    void st_print_po(nvObj_t *nv);
-    void st_print_pm(nvObj_t *nv);
-    void st_print_pl(nvObj_t *nv);
-    void st_print_pwr(nvObj_t *nv);
-    void st_print_mt(nvObj_t *nv);
-    void st_print_me(nvObj_t *nv);
-    void st_print_md(nvObj_t *nv);
+void st_print_ma(nvObj_t *nv);
+void st_print_sa(nvObj_t *nv);
+void st_print_tr(nvObj_t *nv);
+void st_print_mi(nvObj_t *nv);
+void st_print_po(nvObj_t *nv);
+void st_print_pm(nvObj_t *nv);
+void st_print_pl(nvObj_t *nv);
+void st_print_pwr(nvObj_t *nv);
+void st_print_mt(nvObj_t *nv);
+void st_print_me(nvObj_t *nv);
+void st_print_md(nvObj_t *nv);
 
 #else
 
-    #define st_print_ma tx_print_stub
-    #define st_print_sa tx_print_stub
-    #define st_print_tr tx_print_stub
-    #define st_print_mi tx_print_stub
-    #define st_print_po tx_print_stub
-    #define st_print_pm tx_print_stub
-    #define st_print_pl tx_print_stub
-    #define st_print_pwr tx_print_stub
-    #define st_print_mt tx_print_stub
-    #define st_print_me tx_print_stub
-    #define st_print_md tx_print_stub
+#define st_print_ma tx_print_stub
+#define st_print_sa tx_print_stub
+#define st_print_tr tx_print_stub
+#define st_print_mi tx_print_stub
+#define st_print_po tx_print_stub
+#define st_print_pm tx_print_stub
+#define st_print_pl tx_print_stub
+#define st_print_pwr tx_print_stub
+#define st_print_mt tx_print_stub
+#define st_print_me tx_print_stub
+#define st_print_md tx_print_stub
 
 #endif // __TEXT_MODE
 
-#endif    // End of include guard: STEPPER_H_ONCE
+#endif // STEPPER_H_ONCE
index 13b92447ca15e85b289b0f471e35dcf62c21b1d7..99e69e1b328bff50005825374564581642d894cf 100644 (file)
@@ -165,7 +165,7 @@ char *get_status_message(stat_t status);
 
 // ritorno is a handy way to provide exception returns
 // It returns only if an error occurred. (ritorno is Italian for return)
-#define ritorno(a) if((status_code=a) != STAT_OK) { return(status_code); }
+#define ritorno(a) if((status_code=a) != STAT_OK) { return status_code; }
 
 // OS, communications and low-level status
 #define STAT_OK 0                        // function completed OK