Motor status reporting
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 4 Jan 2016 21:08:22 +0000 (13:08 -0800)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Mon, 4 Jan 2016 21:08:22 +0000 (13:08 -0800)
12 files changed:
Makefile
src/config.h
src/config_app.c
src/config_app.h
src/controller.c
src/report.c
src/report.h
src/settings.h
src/settings/settings_default.h
src/stepper.c
src/tmc2660.c
src/tmc2660.h

index 1db20ee921302754495ca9a1d273b668d11a70f8..60c8120c452f595e3bee24f1adb52d95290df499 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,9 @@ size: $(TARGET)
        avr-size -C --mcu=$(MCU) $(TARGET)
 
 # Program
+reset:
+       avrdude $(AVRDUDE_OPTS)
+
 erase:
        avrdude $(AVRDUDE_OPTS) -e
 
@@ -89,7 +92,7 @@ clean: tidy
        rm -rf $(PROJECT).elf $(PROJECT).hex $(PROJECT).eep $(PROJECT).lss \
          $(PROJECT).map build fuse?.hex
 
-.PHONY: tidy clean size all erase program fuses read_fuses
+.PHONY: tidy clean size all reset erase program fuses read_fuses
 
 # Dependencies
 -include $(shell mkdir -p build/dep) $(wildcard build/dep/*)
index 078f5a0814a41adea4927eb37606c39e812564b9..a51936ce26fc0a623093e37d2269502c9228ae94 100644 (file)
@@ -28,9 +28,7 @@
 #ifndef CONFIG_H_ONCE
 #define CONFIG_H_ONCE
 
-/***** PLEASE NOTE *****
-#include "config_app.h"    // is present at the end of this file
-*/
+// Please note config_app.h in included at the end of this file
 
 /**** Config System Overview and Usage ***
  *
@@ -44,6 +42,7 @@
  *    This way the internals don't care about how the variable is represented or communicated
  *    externally as all internal operations occur on the nvObjs, not the wire form (text or JSON).
  */
+
 /*    --- Config variables, tables and strings ---
  *
  *    Each configuration value is identified by a short mnemonic string (token). The token
@@ -72,9 +71,9 @@
  *        with: xyzabcuvw0123456789 (but there can be exceptions)
  *
  *  "Groups" are collections of values that mimic REST resources. Groups include:
- *     - axis groups prefixed by "xyzabc"        ("uvw" are reserved)
+ *     - axis groups prefixed by "xyzabc"       ("uvw" are reserved)
  *     - motor groups prefixed by "1234"        ("56789" are reserved)
- *     - PWM groups prefixed by p1, p2         (p3 - p9 are reserved)
+ *     - PWM groups prefixed by p1, p2          (p3 - p9 are reserved)
  *     - coordinate system groups prefixed by g54, g55, g56, g57, g59, g92
  *     - a system group is identified by "sys" and contains a collection of otherwise unrelated values
  *
@@ -84,6 +83,7 @@
  *     - group of all offset groups
  *     - group of all groups
  */
+
 /*  --- Making changes and adding new values
  *
  *    Adding a new value to config (or changing an existing one) involves touching the following places:
 
 /**** nvObj lists ****
  *
- *     Commands and groups of commands are processed internally a doubly linked list of nvObj_t
+ *    Commands and groups of commands are processed internally a doubly linked list of nvObj_t
  *    structures. This isolates the command and config internals from the details of communications,
  *    parsing and display in text mode and JSON mode.
  *
  *    When you use the list you can terminate your own last element, or just leave the EMPTY elements
  *    to be skipped over during output serialization.
  *
- *     We don't use recursion so parent/child nesting relationships are captured in a 'depth' variable,
+ *    We don't use recursion so parent/child nesting relationships are captured in a 'depth' variable,
  *    This must remain consistent if the curlies are to work out. You should not have to track depth
  *    explicitly if you use nv_reset_nv_list() or the accessor functions like nv_add_integer() or
  *    nv_add_message(). If you see problems with curlies check the depth values in the lists.
  *
  *    Use the nv_print_list() dispatcher for all JSON and text output. Do not simply run through printf.
  */
+
 /*    Token and Group Fields
  *
  *    The nvObject struct (nvObj_t) has strict rules on the use of the token and group fields.
  *      - JSON-mode display for single - element value e.g. xvm. Concatenate as above
  *      - JSON-mode display of a parent/child group. Parent is named grp, children nems are tokens
  */
+
 /*    --- nv object string handling ---
  *
  *    It's very expensive to allocate sufficient string space to each nvObj, so nv uses a cheater's
  *    the output buffer (typ 256 bytes), So some number less than that is sufficient for shared strings.
  *    This is all mediated through nv_copy_string(), nv_copy_string_P(), and nv_reset_nv_list().
  */
+
 /*  --- Setting nvObj indexes ---
  *
  *    It's the responsibility of the object creator to set the index. Downstream functions
  *    (linear table scan), so there are some exceptions where the index does not need to be set.
  *    These cases are put in the code, commented out, and explained.
  */
+
 /*    --- Other Notes:---
  *
  *    NV_BODY_LEN needs to allow for one parent JSON object and enough children to complete the
 
 #include <stdint.h>
 
-// Sizing and footprints                // chose one based on # of elements in cfgArray
-//typedef uint8_t index_t;               // use this if there are < 256 indexed objects
-typedef uint16_t index_t;               // use this if there are > 255 indexed objects
+// Sizing and footprints                 // chose one based on # of elements in cfgArray
+typedef uint16_t index_t;                // use this if there are > 255 indexed objects
 
-                                        // defines allocated from stack (not-pre-allocated)
-#define NV_FORMAT_LEN 128               // print formatting string max length
-#define NV_MESSAGE_LEN 128              // sufficient space to contain end-user messages
+                                         // defines allocated from stack (not-pre-allocated)
+#define NV_FORMAT_LEN 128                // print formatting string max length
+#define NV_MESSAGE_LEN 128               // sufficient space to contain end-user messages
 
-                                        // pre-allocated defines (take RAM permanently)
-#define NV_SHARED_STRING_LEN 512        // shared string for string values
-#define NV_BODY_LEN 30                  // body elements - allow for 1 parent + N children
-                                        // (each body element takes about 30 bytes of RAM)
+                                         // pre-allocated defines (take RAM permanently)
+#define NV_SHARED_STRING_LEN 512         // shared string for string values
+#define NV_BODY_LEN 30                   // body elements - allow for 1 parent + N children
+                                         // (each body element takes about 30 bytes of RAM)
 
-// Stuff you probably don't want to change
 
+// Stuff you probably don't want to change
 #define GROUP_LEN 3                      // max length of group prefix
 #define TOKEN_LEN 5                      // mnemonic token string: group prefix + short token
 #define NV_FOOTER_LEN 18                 // sufficient space to contain a JSON footer array
-#define NV_LIST_LEN (NV_BODY_LEN+2)      // +2 allows for a header and a footer
-#define NV_MAX_OBJECTS (NV_BODY_LEN-1)   // maximum number of objects in a body string
+#define NV_LIST_LEN (NV_BODY_LEN + 2)    // +2 allows for a header and a footer
+#define NV_MAX_OBJECTS (NV_BODY_LEN - 1) // maximum number of objects in a body string
 #define NO_MATCH (index_t)0xFFFF
 #define NV_STATUS_REPORT_LEN NV_MAX_OBJECTS // max number of status report elements - see cfgArray
                                             // **** must also line up in cfgArray, se00 - seXX ****
 
 enum tgCommunicationsMode {
-    TEXT_MODE = 0,                       // text command line mode
-    JSON_MODE,                           // strict JSON construction
-    JSON_MODE_RELAXED                    // relaxed JSON construction (future)
+  TEXT_MODE = 0,                      // text command line mode
+  JSON_MODE,                          // strict JSON construction
+  JSON_MODE_RELAXED                   // relaxed JSON construction (future)
 };
 
+
 enum flowControl {
-    FLOW_CONTROL_OFF = 0,               // flow control disabled
-    FLOW_CONTROL_XON,                   // flow control uses XON/XOFF
-    FLOW_CONTROL_RTS                    // flow control uses RTS/CTS
+  FLOW_CONTROL_OFF = 0,               // flow control disabled
+  FLOW_CONTROL_XON,                   // flow control uses XON/XOFF
+  FLOW_CONTROL_RTS                    // flow control uses RTS/CTS
 };
 
-enum valueType {                        // value typing for config and JSON
-    TYPE_EMPTY = -1,                    // value struct is empty (which is not the same as "0")
-    TYPE_0 = 0,                         // value is 'null' (meaning the JSON null value)
-    TYPE_BOOL,                          // value is "true" (1) or "false"(0)
-    TYPE_INTEGER,                       // value is a uint32_t
-    TYPE_DATA,                          // value is blind cast to uint32_t
-    TYPE_FLOAT,                         // value is a floating point number
-    TYPE_STRING,                        // value is in string field
-    TYPE_ARRAY,                         // value is array element count, values are CSV ASCII in string field
-    TYPE_PARENT                         // object is a parent to a sub-object
+
+enum valueType {                      // value typing for config and JSON
+  TYPE_EMPTY = -1,                    // value struct is empty (which is not the same as "0")
+  TYPE_0 = 0,                         // value is 'null' (meaning the JSON null value)
+  TYPE_BOOL,                          // value is "true" (1) or "false"(0)
+  TYPE_INTEGER,                       // value is a uint32_t
+  TYPE_DATA,                          // value is blind cast to uint32_t
+  TYPE_FLOAT,                         // value is a floating point number
+  TYPE_STRING,                        // value is in string field
+  TYPE_ARRAY,                         // value is array element count, values are CSV ASCII in string field
+  TYPE_PARENT                         // object is a parent to a sub-object
 };
 
-/**** operations flags and shorthand ****/
 
-#define F_INITIALIZE    0x01            // initialize this item (run set during initialization)
-#define F_PERSIST       0x02            // persist this item when set is run
-#define F_NOSTRIP       0x04            // do not strip the group prefix from the token
-#define F_CONVERT       0x08            // set if unit conversion is required
+// Operations flags and shorthand
+#define F_INITIALIZE    0x01          // initialize this item (run set during initialization)
+#define F_PERSIST       0x02          // persist this item when set is run
+#define F_NOSTRIP       0x04          // do not strip the group prefix from the token
+#define F_CONVERT       0x08          // set if unit conversion is required
 
 #define _f0             0x00
 #define _fi             (F_INITIALIZE)
@@ -231,103 +236,108 @@ enum valueType {                        // value typing for config and JSON
 #define _fipn           (F_INITIALIZE | F_PERSIST | F_NOSTRIP)
 #define _fipnc          (F_INITIALIZE | F_PERSIST | F_NOSTRIP | F_CONVERT)
 
-/**** Structures ****/
-
-typedef struct nvString {                // shared string object
-    uint16_t magic_start;
-  #if (NV_SHARED_STRING_LEN < 256)
-    uint8_t wp;                            // use this string array index value if string len < 256 bytes
-  #else
-    uint16_t wp;                        // use this string array index value is string len > 255 bytes
-  #endif
-    char_t string[NV_SHARED_STRING_LEN];
-    uint16_t magic_end;                    // guard to detect string buffer underruns
+
+typedef struct nvString {              // shared string object
+  uint16_t magic_start;
+#if (NV_SHARED_STRING_LEN < 256)
+  uint8_t wp;                          // use this string array index value if string len < 256 bytes
+#else
+  uint16_t wp;                         // use this string array index value is string len > 255 bytes
+#endif
+  char_t string[NV_SHARED_STRING_LEN];
+  uint16_t magic_end;                  // guard to detect string buffer underruns
 } nvStr_t;
 
-typedef struct nvObject {                // depending on use, not all elements may be populated
-    struct nvObject *pv;                // pointer to previous object or 0 if first object
-    struct nvObject *nx;                // pointer to next object or 0 if last object
-    index_t index;                        // index of tokenized name, or -1 if no token (optional)
-    int8_t depth;                        // depth of object in the tree. 0 is root (-1 is invalid)
-    int8_t valuetype;                    // see valueType enum
-    int8_t precision;                    // decimal precision for reporting (JSON)
-    float value;                        // numeric value
-    char_t group[GROUP_LEN+1];            // group prefix or 0 if not in a group
-    char_t token[TOKEN_LEN+1];            // full mnemonic token for lookup
-    char_t (*stringp)[];                // pointer to array of characters from shared character array
-} nvObj_t;                                 // OK, so it's not REALLY an object
-
-typedef uint8_t (*fptrCmd)(nvObj_t *nv);// required for cfg table access
-typedef void (*fptrPrint)(nvObj_t *nv);    // required for PROGMEM access
+
+typedef struct nvObject {              // depending on use, not all elements may be populated
+  struct nvObject *pv;                 // pointer to previous object or 0 if first object
+  struct nvObject *nx;                 // pointer to next object or 0 if last object
+  index_t index;                       // index of tokenized name, or -1 if no token (optional)
+  int8_t depth;                        // depth of object in the tree. 0 is root (-1 is invalid)
+  int8_t valuetype;                    // see valueType enum
+  int8_t precision;                    // decimal precision for reporting (JSON)
+  float value;                         // numeric value
+  char_t group[GROUP_LEN + 1];         // group prefix or 0 if not in a group
+  char_t token[TOKEN_LEN + 1];         // full mnemonic token for lookup
+  char_t (*stringp)[];                 // pointer to array of characters from shared character array
+} nvObj_t;
+
+
+typedef uint8_t (*fptrCmd)(nvObj_t *nv); // required for cfg table access
+typedef void (*fptrPrint)(nvObj_t *nv);  // required for PROGMEM access
+
 
 typedef struct nvList {
-    uint16_t magic_start;
-    nvObj_t list[NV_LIST_LEN];            // list of nv objects, including space for a JSON header element
-    uint16_t magic_end;
+  uint16_t magic_start;
+  nvObj_t list[NV_LIST_LEN];           // list of nv objects, including space for a JSON header element
+  uint16_t magic_end;
 } nvList_t;
 
+
 typedef struct cfgItem {
-    char_t group[GROUP_LEN+1];            // group prefix (with 0 termination)
-    char_t token[TOKEN_LEN+1];            // token - stripped of group prefix (w/0 termination)
-    uint8_t flags;                        // operations flags - see defines below
-    int8_t precision;                    // decimal precision for display (JSON)
-    fptrPrint print;                    // print binding: aka void (*print)(nvObj_t *nv);
-    fptrCmd get;                        // GET binding aka uint8_t (*get)(nvObj_t *nv)
-    fptrCmd set;                        // SET binding aka uint8_t (*set)(nvObj_t *nv)
-    float *target;                        // target for writing config value
-    float def_value;                    // default value for config item
+  char_t group[GROUP_LEN + 1];         // group prefix (with 0 termination)
+  char_t token[TOKEN_LEN + 1];         // token - stripped of group prefix (w/0 termination)
+  uint8_t flags;                       // operations flags - see defines below
+  int8_t precision;                    // decimal precision for display (JSON)
+  fptrPrint print;                     // print binding: aka void (*print)(nvObj_t *nv);
+  fptrCmd get;                         // GET binding aka uint8_t (*get)(nvObj_t *nv)
+  fptrCmd set;                         // SET binding aka uint8_t (*set)(nvObj_t *nv)
+  float *target;                       // target for writing config value
+  float def_value;                     // default value for config item
 } cfgItem_t;
 
-/**** static allocation and definitions ****/
 
 extern nvStr_t nvStr;
 extern nvList_t nvl;
 extern const cfgItem_t cfgArray[];
 
-//#define nv_header nv.list
+
 #define nv_header (&nvl.list[0])
 #define nv_body   (&nvl.list[1])
 
-/**** Prototypes for generic config functions - see individual modules for application-specific functions  ****/
 
 void config_init();
-stat_t set_defaults(nvObj_t *nv);            // reset config to default values
+stat_t set_defaults(nvObj_t *nv);        // reset config to default values
 void config_init_assertions();
 stat_t config_test_assertions();
 
+
 // main entry points for core access functions
-stat_t nv_get(nvObj_t *nv);                    // main entry point for get value
-stat_t nv_set(nvObj_t *nv);                    // main entry point for set value
-void nv_print(nvObj_t *nv);                    // main entry point for print value
-stat_t nv_persist(nvObj_t *nv);                // main entry point for persistence
+stat_t nv_get(nvObj_t *nv);              // main entry point for get value
+stat_t nv_set(nvObj_t *nv);              // main entry point for set value
+void nv_print(nvObj_t *nv);              // main entry point for print value
+stat_t nv_persist(nvObj_t *nv);          // main entry point for persistence
 
-// helpers
+
+// Helpers
 uint8_t nv_get_type(nvObj_t *nv);
 index_t nv_get_index(const char_t *group, const char_t *token);
-index_t    nv_index_max();                    // (see config_app.c)
-uint8_t nv_index_is_single(index_t index);    // (see config_app.c)
+index_t nv_index_max();                      // (see config_app.c)
+uint8_t nv_index_is_single(index_t index);   // (see config_app.c)
 uint8_t nv_index_is_group(index_t index);    // (see config_app.c)
-uint8_t nv_index_lt_groups(index_t index);    // (see config_app.c)
+uint8_t nv_index_lt_groups(index_t index);   // (see config_app.c)
 uint8_t nv_group_is_prefixed(char_t *group);
 
-// generic internal functions and accessors
-stat_t set_nul(nvObj_t *nv);                // set nothing (no operation)
-stat_t set_ui8(nvObj_t *nv);                // set uint8_t value
-stat_t set_01(nvObj_t *nv);                    // set a 0 or 1 value with validation
-stat_t set_012(nvObj_t *nv);                // set a 0, 1 or 2 value with validation
+
+// Generic internal functions and accessors
+stat_t set_nul(nvObj_t *nv);                 // set nothing (no operation)
+stat_t set_ui8(nvObj_t *nv);                 // set uint8_t value
+stat_t set_01(nvObj_t *nv);                  // set a 0 or 1 value with validation
+stat_t set_012(nvObj_t *nv);                 // set a 0, 1 or 2 value with validation
 stat_t set_0123(nvObj_t *nv);                // set a 0, 1, 2 or 3 value with validation
-stat_t set_int(nvObj_t *nv);                // set uint32_t integer value
+stat_t set_int(nvObj_t *nv);                 // set uint32_t integer value
 stat_t set_data(nvObj_t *nv);                // set uint32_t integer value blind cast
-stat_t set_flt(nvObj_t *nv);                // set floating point value
+stat_t set_flt(nvObj_t *nv);                 // set floating point value
 
-stat_t get_nul(nvObj_t *nv);                // get null value type
-stat_t get_ui8(nvObj_t *nv);                // get uint8_t value
-stat_t get_int(nvObj_t *nv);                // get uint32_t integer value
+stat_t get_nul(nvObj_t *nv);                 // get null value type
+stat_t get_ui8(nvObj_t *nv);                 // get uint8_t value
+stat_t get_int(nvObj_t *nv);                 // get uint32_t integer value
 stat_t get_data(nvObj_t *nv);                // get uint32_t integer value blind cast
-stat_t get_flt(nvObj_t *nv);                // get floating point value
+stat_t get_flt(nvObj_t *nv);                 // get floating point value
+
+stat_t set_grp(nvObj_t *nv);                 // set data for a group
+stat_t get_grp(nvObj_t *nv);                 // get data for a group
 
-stat_t set_grp(nvObj_t *nv);                // set data for a group
-stat_t get_grp(nvObj_t *nv);                // get data for a group
 
 // nvObj and list functions
 void nv_get_nvObj(nvObj_t *nv);
@@ -341,16 +351,17 @@ nvObj_t *nv_add_string(const char_t *token, const char_t *string);
 nvObj_t *nv_add_conditional_message(const char_t *string);
 void nv_print_list(stat_t status, uint8_t text_flags, uint8_t json_flags);
 
-// application specific helpers and functions (config_app.c)
+
+// Application specific helpers and functions (config_app.c)
 stat_t set_flu(nvObj_t *nv);                // set floating point number with G20/G21 units conversion
-void preprocess_float(nvObj_t *nv);            // pre-process float values for units and illegal values
+void preprocess_float(nvObj_t *nv);         // pre-process float values for units and illegal values
+
 
-// diagnostics
+// Diagnostics
 void nv_dump_nv(nvObj_t *nv);
 
-/*********************************************************************************************
- **** PLEASE NOTICE THAT CONFIG_APP.H IS HERE ************************************************
- *********************************************************************************************/
+
+// Please notice that config_app.h is here
 #include "config_app.h"
 
-#endif // End of include guard: CONFIG_H_ONCE
+#endif // CONFIG_H_ONCE
index 87a110f067ffdeaf8561a7817ff309c1bfaeee05..3c4e8ee54fd03ae80b42a3c9fdc20e3c23bba0b1 100644 (file)
 #include "util.h"
 #include "help.h"
 #include "usart.h"
+#include "tmc2660.h"
 
-cfgParameters_t cfg;                 // application specific configuration parameters
+cfgParameters_t cfg; // Application specific configuration parameters
 
 // See config.cpp/.h for generic variables and functions that are not specific to
 // TinyG or the motion control application domain
 
 // helpers (most helpers are defined immediately above their usage so they don't need prototypes here)
-
 static stat_t _do_motors(nvObj_t *nv);        // print parameters for all motor groups
-static stat_t _do_axes(nvObj_t *nv);        // print parameters for all axis groups
-static stat_t _do_offsets(nvObj_t *nv);        // print offset parameters for G54-G59,G92, G28, G30
-static stat_t _do_all(nvObj_t *nv);            // print all parameters
+static stat_t _do_axes(nvObj_t *nv);          // print parameters for all axis groups
+static stat_t _do_offsets(nvObj_t *nv);       // print offset parameters for G54-G59,G92, G28, G30
+static stat_t _do_all(nvObj_t *nv);           // print all parameters
 
 // communications settings and functions
-
 static stat_t set_ec(nvObj_t *nv);            // expand CRLF on TX output
 static stat_t set_ee(nvObj_t *nv);            // enable character echo
 static stat_t set_ex(nvObj_t *nv);            // enable XON/XOFF and RTS/CTS flow control
@@ -90,31 +89,40 @@ static stat_t get_rx(nvObj_t *nv);            // get bytes in RX buffer
  *    uint16_t in the config.h file.
  */
 const cfgItem_t cfgArray[] PROGMEM = {
-  // group token flags p, print_func,     get_func,  set_func, target for get/set,       default value
+  // group, token, flags, p, print_func, get_func, set_func, target for get/set, default value
   {"sys", "fb", _fipn,2, hw_print_fb, get_flt,   set_nul,  (float *)&cs.fw_build,   TINYG_FIRMWARE_BUILD}, // MUST BE FIRST!
   {"sys", "fv", _fipn,3, hw_print_fv, get_flt,   set_nul,  (float *)&cs.fw_version, TINYG_FIRMWARE_VERSION},
   {"sys", "hp", _fipn,0, hw_print_hp, get_flt,   set_flt,  (float *)&cs.hw_platform,TINYG_HARDWARE_PLATFORM},
   {"sys", "hv", _fipn,0, hw_print_hv, get_flt,   hw_set_hv,(float *)&cs.hw_version, TINYG_HARDWARE_VERSION},
-  {"sys", "id", _fn,  0, hw_print_id, hw_get_id, set_nul,  (float *)&cs.null, 0},  // device ID (ASCII signature)
-
-  // dynamic model attributes for reporting purposes (up front for speed)
-  {"",   "n",   _fi, 0, cm_print_line, cm_get_mline,set_int,(float *)&cm.gm.linenum,0},       // Model line number
-  {"",   "line",_fi, 0, cm_print_line, cm_get_line, set_int,(float *)&cm.gm.linenum,0},       // Active line number - model or runtime line number
-  {"",   "vel", _f0, 2, cm_print_vel,  cm_get_vel,  set_nul,(float *)&cs.null, 0},            // current velocity
-  {"",   "feed",_f0, 2, cm_print_feed, cm_get_feed, set_nul,(float *)&cs.null, 0},            // feed rate
-  {"",   "stat",_f0, 0, cm_print_stat, cm_get_stat, set_nul,(float *)&cs.null, 0},            // combined machine state
-  {"",   "macs",_f0, 0, cm_print_macs, cm_get_macs, set_nul,(float *)&cs.null, 0},            // raw machine state
-  {"",   "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_nul,(float *)&cs.null, 0},            // cycle state
-  {"",   "mots",_f0, 0, cm_print_mots, cm_get_mots, set_nul,(float *)&cs.null, 0},            // motion state
-  {"",   "hold",_f0, 0, cm_print_hold, cm_get_hold, set_nul,(float *)&cs.null, 0},            // feedhold state
-  {"",   "unit",_f0, 0, cm_print_unit, cm_get_unit, set_nul,(float *)&cs.null, 0},            // units mode
-  {"",   "coor",_f0, 0, cm_print_coor, cm_get_coor, set_nul,(float *)&cs.null, 0},            // coordinate system
-  {"",   "momo",_f0, 0, cm_print_momo, cm_get_momo, set_nul,(float *)&cs.null, 0},            // motion mode
-  {"",   "plan",_f0, 0, cm_print_plan, cm_get_plan, set_nul,(float *)&cs.null, 0},            // plane select
-  {"",   "path",_f0, 0, cm_print_path, cm_get_path, set_nul,(float *)&cs.null, 0},            // path control mode
-  {"",   "dist",_f0, 0, cm_print_dist, cm_get_dist, set_nul,(float *)&cs.null, 0},            // distance mode
-  {"",   "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_nul,(float *)&cs.null, 0},            // feed rate mode
-  {"",   "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_nul,(float *)&cs.null, 0},            // active tool
+  {"sys", "id", _fn,  0, hw_print_id, hw_get_id, set_nul,  (float *)&cs.null, 0},           // device ID (ASCII signature)
+
+  {"mst", "mst1", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
+  {"mst", "mst2", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
+  {"mst", "mst3", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
+  {"mst", "mst4", _f0, 0, tmc2660_print_motor_step, tmc2660_get_motor_step, set_nul, (float *)&cs.null, 0},
+  {"mfl", "mfl1", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
+  {"mfl", "mfl2", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
+  {"mfl", "mfl3", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
+  {"mfl", "mfl4", _f0, 0, tmc2660_print_motor_flags, tmc2660_get_motor_flags, set_nul, (float *)&cs.null, 0},
+
+  // Dynamic model attributes for reporting purposes (up front for speed)
+  {"",   "n",   _fi, 0, cm_print_line, cm_get_mline,set_int,(float *)&cm.gm.linenum,0},     // Model line number
+  {"",   "line",_fi, 0, cm_print_line, cm_get_line, set_int,(float *)&cm.gm.linenum,0},     // Active model or runtime line number
+  {"",   "vel", _f0, 2, cm_print_vel,  cm_get_vel,  set_nul,(float *)&cs.null, 0},          // current velocity
+  {"",   "feed",_f0, 2, cm_print_feed, cm_get_feed, set_nul,(float *)&cs.null, 0},          // feed rate
+  {"",   "stat",_f0, 0, cm_print_stat, cm_get_stat, set_nul,(float *)&cs.null, 0},          // combined machine state
+  {"",   "macs",_f0, 0, cm_print_macs, cm_get_macs, set_nul,(float *)&cs.null, 0},          // raw machine state
+  {"",   "cycs",_f0, 0, cm_print_cycs, cm_get_cycs, set_nul,(float *)&cs.null, 0},          // cycle state
+  {"",   "mots",_f0, 0, cm_print_mots, cm_get_mots, set_nul,(float *)&cs.null, 0},          // motion state
+  {"",   "hold",_f0, 0, cm_print_hold, cm_get_hold, set_nul,(float *)&cs.null, 0},          // feedhold state
+  {"",   "unit",_f0, 0, cm_print_unit, cm_get_unit, set_nul,(float *)&cs.null, 0},          // units mode
+  {"",   "coor",_f0, 0, cm_print_coor, cm_get_coor, set_nul,(float *)&cs.null, 0},          // coordinate system
+  {"",   "momo",_f0, 0, cm_print_momo, cm_get_momo, set_nul,(float *)&cs.null, 0},          // motion mode
+  {"",   "plan",_f0, 0, cm_print_plan, cm_get_plan, set_nul,(float *)&cs.null, 0},          // plane select
+  {"",   "path",_f0, 0, cm_print_path, cm_get_path, set_nul,(float *)&cs.null, 0},          // path control mode
+  {"",   "dist",_f0, 0, cm_print_dist, cm_get_dist, set_nul,(float *)&cs.null, 0},          // distance mode
+  {"",   "frmo",_f0, 0, cm_print_frmo, cm_get_frmo, set_nul,(float *)&cs.null, 0},          // feed rate mode
+  {"",   "tool",_f0, 0, cm_print_tool, cm_get_toolv,set_nul,(float *)&cs.null, 0},          // active tool
 
   {"mpo","mpox",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0},            // X machine position
   {"mpo","mpoy",_f0, 3, cm_print_mpo, cm_get_mpo, set_nul,(float *)&cs.null, 0},            // Y machine position
@@ -137,13 +145,13 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"ofs","ofsb",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0},            // B work offset
   {"ofs","ofsc",_f0, 3, cm_print_ofs, cm_get_ofs, set_nul,(float *)&cs.null, 0},            // C work offset
 
-  {"hom","home",_f0, 0, cm_print_home, cm_get_home, cm_run_home,(float *)&cs.null, 0},        // homing state, invoke homing cycle
-  {"hom","homx",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_X], false},    // X homed - Homing status group
-  {"hom","homy",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_Y], false},    // Y homed
-  {"hom","homz",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_Z], false},    // Z homed
-  {"hom","homa",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_A], false},    // A homed
-  {"hom","homb",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_B], false},    // B homed
-  {"hom","homc",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_C], false},    // C homed
+  {"hom","home",_f0, 0, cm_print_home, cm_get_home, cm_run_home,(float *)&cs.null, 0},      // homing state, invoke homing cycle
+  {"hom","homx",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_X], false},  // X homed - Homing status group
+  {"hom","homy",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_Y], false},  // Y homed
+  {"hom","homz",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_Z], false},  // Z homed
+  {"hom","homa",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_A], false},  // A homed
+  {"hom","homb",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_B], false},  // B homed
+  {"hom","homc",_f0, 0, cm_print_pos, get_ui8, set_nul,(float *)&cm.homed[AXIS_C], false},  // C homed
 
   {"prb","prbe",_f0, 0, tx_print_nul, get_ui8, set_nul,(float *)&cm.probe_state, 0},        // probing state
   {"prb","prbx",_f0, 3, tx_print_nul, get_flt, set_nul,(float *)&cm.probe_results[AXIS_X], 0},
@@ -158,7 +166,7 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"jog","jogz",_f0, 0, tx_print_nul, get_nul, cm_run_jogz, (float *)&cm.jogging_dest, 0},
   {"jog","joga",_f0, 0, tx_print_nul, get_nul, cm_run_joga, (float *)&cm.jogging_dest, 0},
 
-  {"pwr","pwr1",_f0, 0, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0},    // motor power enable readouts
+  {"pwr","pwr1",_f0, 0, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0}, // motor power enable readouts
   {"pwr","pwr2",_f0, 0, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0},
   {"pwr","pwr3",_f0, 0, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0},
   {"pwr","pwr4",_f0, 0, st_print_pwr, st_get_pwr, set_nul, (float *)&cs.null, 0},
@@ -170,23 +178,23 @@ const cfgItem_t cfgArray[] PROGMEM = {
 #endif
 
   // Reports, tests, help, and messages
-  {"", "sr",  _f0, 0, sr_print_sr,  sr_get,  sr_set,   (float *)&cs.null, 0},    // status report object
-  {"", "qr",  _f0, 0, qr_print_qr,  qr_get,  set_nul,  (float *)&cs.null, 0},    // queue report - planner buffers available
-  {"", "qi",  _f0, 0, qr_print_qi,  qi_get,  set_nul,  (float *)&cs.null, 0},    // queue report - buffers added to queue
-  {"", "qo",  _f0, 0, qr_print_qo,  qo_get,  set_nul,  (float *)&cs.null, 0},    // queue report - buffers removed from queue
-  {"", "er",  _f0, 0, tx_print_nul, rpt_er,  set_nul,  (float *)&cs.null, 0},    // invoke bogus exception report for testing
-  {"", "qf",  _f0, 0, tx_print_nul, get_nul, cm_run_qf,(float *)&cs.null, 0},    // queue flush
-  {"", "rx",  _f0, 0, tx_print_int, get_rx,  set_nul,  (float *)&cs.null, 0},    // space in RX buffer
-  {"", "msg", _f0, 0, tx_print_str, get_nul, set_nul,  (float *)&cs.null, 0},    // string for generic messages
-  {"", "clear",_f0,0, tx_print_nul, cm_clear,cm_clear, (float *)&cs.null, 0},    // GET a clear to clear soft alarm
+  {"", "sr",  _f0, 0, sr_print_sr,  sr_get,  sr_set,   (float *)&cs.null, 0},     // status report object
+  {"", "qr",  _f0, 0, qr_print_qr,  qr_get,  set_nul,  (float *)&cs.null, 0},     // queue report - planner buffers available
+  {"", "qi",  _f0, 0, qr_print_qi,  qi_get,  set_nul,  (float *)&cs.null, 0},     // queue report - buffers added to queue
+  {"", "qo",  _f0, 0, qr_print_qo,  qo_get,  set_nul,  (float *)&cs.null, 0},     // queue report - buffers removed from queue
+  {"", "er",  _f0, 0, tx_print_nul, rpt_er,  set_nul,  (float *)&cs.null, 0},     // invoke bogus exception report for testing
+  {"", "qf",  _f0, 0, tx_print_nul, get_nul, cm_run_qf,(float *)&cs.null, 0},     // queue flush
+  {"", "rx",  _f0, 0, tx_print_int, get_rx,  set_nul,  (float *)&cs.null, 0},     // space in RX buffer
+  {"", "msg", _f0, 0, tx_print_str, get_nul, set_nul,  (float *)&cs.null, 0},     // string for generic messages
+  {"", "clear",_f0,0, tx_print_nul, cm_clear,cm_clear, (float *)&cs.null, 0},     // GET a clear to clear soft alarm
 
   {"", "test",_f0, 0, tx_print_nul, help_test, run_test, (float *)&cs.null,0},    // run tests, print test help screen
-  {"", "defa",_f0, 0, tx_print_nul, help_defa, set_defaults,(float *)&cs.null,0},    // set/print defaults / help screen
+  {"", "defa",_f0, 0, tx_print_nul, help_defa, set_defaults,(float *)&cs.null,0}, // set/print defaults / help screen
   {"", "boot",_f0, 0, tx_print_nul, help_boot_loader,hw_run_boot, (float *)&cs.null,0},
 
 #ifdef __HELP_SCREENS
-  {"", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0},  // prints config help screen
-  {"", "h",   _f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0},  // alias for "help"
+  {"", "help",_f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0},   // prints config help screen
+  {"", "h",   _f0, 0, tx_print_nul, help_config, set_nul, (float *)&cs.null,0},   // alias for "help"
 #endif
 
   // Motor parameters
@@ -371,7 +379,7 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"g59","g59b",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G59][AXIS_B], G59_B_OFFSET},
   {"g59","g59c",_fipc, 3, cm_print_cofs, get_flt, set_flu,(float *)&cm.offset[G59][AXIS_C], G59_C_OFFSET},
 
-  {"g92","g92x",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_X], 0},// G92 handled differently
+  {"g92","g92x",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_X], 0}, // G92 handled differently
   {"g92","g92y",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_Y], 0},
   {"g92","g92z",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_Z], 0},
   {"g92","g92a",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_A], 0},
@@ -379,14 +387,14 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"g92","g92c",_fi, 3, cm_print_cofs, get_flt, set_nul,(float *)&cm.gmx.origin_offset[AXIS_C], 0},
 
   // Coordinate positions (G28, G30)
-  {"g28","g28x",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_X], 0},// g28 handled differently
+  {"g28","g28x",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_X], 0},  // g28 handled differently
   {"g28","g28y",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_Y], 0},
   {"g28","g28z",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_Z], 0},
   {"g28","g28a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_A], 0},
   {"g28","g28b",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_B], 0},
   {"g28","g28c",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g28_position[AXIS_C], 0},
 
-  {"g30","g30x",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_X], 0},// g30 handled differently
+  {"g30","g30x",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_X], 0},  // g30 handled differently
   {"g30","g30y",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_Y], 0},
   {"g30","g30z",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_Z], 0},
   {"g30","g30a",_fi, 3, cm_print_cpos, get_flt, set_nul,(float *)&cm.gmx.g30_position[AXIS_A], 0},
@@ -456,14 +464,14 @@ const cfgItem_t cfgArray[] PROGMEM = {
 
   // Diagnostic parameters
 #ifdef __DIAGNOSTIC_PARAMETERS
-  {"_te","_tex",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_X], 0},            // X target endpoint
+  {"_te","_tex",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_X], 0},             // X target endpoint
   {"_te","_tey",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_Y], 0},
   {"_te","_tez",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_Z], 0},
   {"_te","_tea",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_A], 0},
   {"_te","_teb",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_B], 0},
   {"_te","_tec",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.target[AXIS_C], 0},
 
-  {"_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_X], 0},            // X target runtime
+  {"_tr","_trx",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_X], 0},          // X target runtime
   {"_tr","_try",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_Y], 0},
   {"_tr","_trz",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_Z], 0},
   {"_tr","_tra",_f0, 2, tx_print_flt, get_flt, set_nul,(float *)&mr.gm.target[AXIS_A], 0},
@@ -598,10 +606,10 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"","jog",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // axis jogging state group
   {"","jid",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // job ID group
 
-  {"","uda", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // user data group
-  {"","udb", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // user data group
-  {"","udc", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // user data group
-  {"","udd", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // user data group
+  {"","uda", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},   // user data group
+  {"","udb", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},   // user data group
+  {"","udc", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},   // user data group
+  {"","udd", _f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},   // user data group
 
 #ifdef __DIAGNOSTIC_PARAMETERS
   {"","_te",_f0, 0, tx_print_nul, get_grp, set_grp,(float *)&cs.null,0},    // target axis endpoint group
@@ -622,9 +630,9 @@ const cfgItem_t cfgArray[] PROGMEM = {
   {"", "$", _f0, 0, tx_print_nul, _do_all,    set_nul,(float *)&cs.null,0}
 };
 
-/***** Make sure these defines line up with any changes in the above table *****/
 
-#define NV_COUNT_UBER_GROUPS     4         // count of uber-groups, above
+// Make sure these defines line up with any changes in the above table
+#define NV_COUNT_UBER_GROUPS     4        // count of uber-groups, above
 #define STANDARD_GROUPS         33        // count of standard groups, excluding diagnostic parameter groups
 
 #if (MOTORS >= 5)
@@ -655,20 +663,22 @@ const cfgItem_t cfgArray[] PROGMEM = {
 
 index_t nv_index_max() {return  NV_INDEX_MAX;}
 uint8_t nv_index_is_single(index_t index) {return (index <= NV_INDEX_END_SINGLES ? true : false);}
-uint8_t nv_index_is_group(index_t index) {return ((index >= NV_INDEX_START_GROUPS && (index < NV_INDEX_START_UBER_GROUPS)) ? true : false);}
+
+uint8_t nv_index_is_group(index_t index) {
+  return ((index >= NV_INDEX_START_GROUPS && (index < NV_INDEX_START_UBER_GROUPS)) ? true : false);
+}
+
 uint8_t nv_index_lt_groups(index_t index) {return (index <= NV_INDEX_START_GROUPS ? true : false);}
 
-/***** APPLICATION SPECIFIC CONFIGS AND EXTENSIONS TO GENERIC FUNCTIONS *****/
 
 /*
- * set_flu() - set floating point number with G20/G21 units conversion
+ * Det floating point number with G20/G21 units conversion
  *
  * The number 'setted' will have been delivered in external units (inches or mm).
  * It is written to the target memory location in internal canonical units (mm).
  * The original nv->value is also changed so persistence works correctly.
  * Displays should convert back from internal canonical form to external form.
  */
-
 stat_t set_flu(nvObj_t *nv) {
   if (cm_get_units_mode(MODEL) == INCHES)       // if in inches...
     nv->value *= MM_PER_INCH;                   // convert to canonical millimeter units
@@ -680,10 +690,8 @@ stat_t set_flu(nvObj_t *nv) {
   return STAT_OK;
 }
 
-/*
- * preprocess_float() - pre-process floating point number for units display
- */
 
+/// Pre-process floating point number for units display
 void preprocess_float(nvObj_t *nv) {
   if (isnan((double)nv->value) || isinf((double)nv->value)) return; // illegal float values
 
@@ -695,16 +703,16 @@ void preprocess_float(nvObj_t *nv) {
 
 /**** TinyG UberGroup Operations ****************************************************
  * Uber groups are groups of groups organized for convenience:
- *    - motors        - group of all motor groups
- *    - axes            - group of all axis groups
+ *    - motors         - group of all motor groups
+ *    - axes           - group of all axis groups
  *    - offsets        - group of all offsets and stored positions
  *    - all            - group of all groups
  *
  * _do_group_list()    - get and print all groups in the list (iteration)
  * _do_motors()        - get and print motor uber group 1-N
- * _do_axes()        - get and print axis uber group XYZABC
- * _do_offsets()    - get and print offset uber group G54-G59, G28, G30, G92
- * _do_all()        - get and print all groups uber group
+ * _do_axes()          - get and print axis uber group XYZABC
+ * _do_offsets()       - get and print offset uber group G54-G59, G28, G30, G92
+ * _do_all()           - get and print all groups uber group
  */
 static stat_t _do_group_list(nvObj_t *nv, char list[][TOKEN_LEN + 1]) { // helper to print multiple groups in a list
   for (uint8_t i = 0; i < NV_MAX_OBJECTS; i++) {
@@ -754,13 +762,13 @@ static stat_t _do_offsets(nvObj_t *nv) {   // print offset parameters for G54-G5
 }
 
 
-static stat_t _do_all(nvObj_t *nv) {  // print all parameters
-  strcpy(nv->token,"sys");            // print system group
+static stat_t _do_all(nvObj_t *nv) { // print all parameters
+  strcpy(nv->token,"sys");           // print system group
   get_grp(nv);
   nv_print_list(STAT_OK, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT);
 
   _do_motors(nv);                    // print all motor groups
-  _do_axes(nv);                        // print all axis groups
+  _do_axes(nv);                      // print all axis groups
 
   strcpy(nv->token,"p1");            // print PWM group
   get_grp(nv);
@@ -783,14 +791,14 @@ static stat_t _set_comm_helper(nvObj_t *nv, int cmd) {
 }
 
 
-static stat_t set_ec(nvObj_t *nv) {                // expand CR to CRLF on TX
+static stat_t set_ec(nvObj_t *nv) {               // expand CR to CRLF on TX
   if (nv->value > true) return STAT_INPUT_VALUE_RANGE_ERROR;
   cfg.enable_cr = (uint8_t)nv->value;
   return _set_comm_helper(nv, USART_CRLF);
 }
 
 
-static stat_t set_ee(nvObj_t *nv) {                // enable character echo
+static stat_t set_ee(nvObj_t *nv) {               // enable character echo
   if (nv->value > true) return STAT_INPUT_VALUE_RANGE_ERROR;
   cfg.enable_echo = (uint8_t)nv->value;
   return _set_comm_helper(nv, USART_ECHO);
@@ -856,11 +864,6 @@ stat_t set_baud_callback() {
 }
 
 
-/***********************************************************************************
- * TEXT MODE SUPPORT
- * Functions to print variables from the cfgArray table
- ***********************************************************************************/
-
 #ifdef __TEXT_MODE
 static const char fmt_ec[] PROGMEM = "[ec]  expand LF to CRLF on TX%6d [0=off,1=on]\n";
 static const char fmt_ee[] PROGMEM = "[ee]  enable echo%18d [0=off,1=on]\n";
@@ -873,5 +876,4 @@ void cfg_print_ee(nvObj_t *nv)   {text_print_ui8(nv, fmt_ee);}
 void cfg_print_ex(nvObj_t *nv)   {text_print_ui8(nv, fmt_ex);}
 void cfg_print_baud(nvObj_t *nv) {text_print_ui8(nv, fmt_baud);}
 void cfg_print_rx(nvObj_t *nv)   {text_print_ui8(nv, fmt_rx);}
-
 #endif // __TEXT_MODE
index 275f0b40bfcec69ce37bcc6fcfee141d2cbad5bb..39ba52ad6a5a13049044b2fed0fc3230d0890936 100644 (file)
 #ifndef CONFIG_APP_H_ONCE
 #define CONFIG_APP_H_ONCE
 
-/***********************************************************************************
- **** APPLICATION_SPECIFIC DEFINITIONS AND SETTINGS ********************************
- ***********************************************************************************/
-
-enum nvType {                        // classification of commands
-    NV_TYPE_0 = 0,
-    NV_TYPE_CONFIG,                    // configuration commands
-    NV_TYPE_GCODE,                    // gcode
-    NV_TYPE_REPORT,                    // SR, QR and any other report
-    NV_TYPE_MESSAGE,                // nv object carries a message
-    NV_TYPE_LINENUM                    // nv object carries a gcode line number
+enum nvType {                       // classification of commands
+  NV_TYPE_0 = 0,
+  NV_TYPE_CONFIG,                   // configuration commands
+  NV_TYPE_GCODE,                    // gcode
+  NV_TYPE_REPORT,                   // SR, QR and any other report
+  NV_TYPE_MESSAGE,                  // nv object carries a message
+  NV_TYPE_LINENUM                   // nv object carries a gcode line number
 };
 
-/***********************************************************************************
- **** APPLICATION_SPECIFIC CONFIG STRUCTURE(S) *************************************
- ***********************************************************************************/
 
-typedef struct cfgParameters {        // mostly communications variables at this point
-    uint16_t magic_start;             // magic number to test memory integrity
+typedef struct cfgParameters {      // mostly communications variables
+  uint16_t magic_start;             // magic number to test memory integrity
 
-    // communications settings
-    uint8_t comm_mode;                // TG_TEXT_MODE or TG_JSON_MODE
-    uint8_t enable_cr;                // enable CR in CRFL expansion on TX
-    uint8_t enable_echo;              // enable text-mode echo
-    uint8_t enable_flow_control;      // enable XON/XOFF or RTS/CTS flow control
+  // Communications settings
+  uint8_t comm_mode;                // TG_TEXT_MODE or TG_JSON_MODE
+  uint8_t enable_cr;                // enable CR in CRFL expansion on TX
+  uint8_t enable_echo;              // enable text-mode echo
+  uint8_t enable_flow_control;      // enable XON/XOFF or RTS/CTS flow control
 
-    uint8_t baud_rate;                // see usart.h for BAUD values
-    uint8_t baud_flag;                // technically this belongs in the controller singleton
+  uint8_t baud_rate;                // see usart.h for BAUD values
+  uint8_t baud_flag;                // should be in controller singleton
 
-    // user-defined data groups
-    uint32_t user_data_a[4];
-    uint32_t user_data_b[4];
-    uint32_t user_data_c[4];
-    uint32_t user_data_d[4];
+  // User defined data groups
+  uint32_t user_data_a[4];
+  uint32_t user_data_b[4];
+  uint32_t user_data_c[4];
+  uint32_t user_data_d[4];
 
-    uint16_t magic_end;
+  uint16_t magic_end;
 } cfgParameters_t;
 extern cfgParameters_t cfg;
 
-/***********************************************************************************
- * CONFIGURATION AND INTERFACE FUNCTIONS
- * Functions to get and set variables from the cfgArray table
- ***********************************************************************************/
 
 stat_t set_baud_callback();
 
-// job config
+
+// Job config
 void job_print_job(nvObj_t *nv);
 stat_t job_get(nvObj_t *nv);
 stat_t job_set(nvObj_t *nv);
 uint8_t job_report_callback();
 
-/***********************************************************************************
- * TEXT MODE SUPPORT
- * Functions to print variables from the cfgArray table
- ***********************************************************************************/
 
 #ifdef __TEXT_MODE
-
-    void cfg_print_ec(nvObj_t *nv);
-    void cfg_print_ee(nvObj_t *nv);
-    void cfg_print_ex(nvObj_t *nv);
-    void cfg_print_baud(nvObj_t *nv);
-    void cfg_print_net(nvObj_t *nv);
-    void cfg_print_rx(nvObj_t *nv);
-
+void cfg_print_ec(nvObj_t *nv);
+void cfg_print_ee(nvObj_t *nv);
+void cfg_print_ex(nvObj_t *nv);
+void cfg_print_baud(nvObj_t *nv);
+void cfg_print_net(nvObj_t *nv);
+void cfg_print_rx(nvObj_t *nv);
 #else
-
-    #define cfg_print_ec tx_print_stub
-    #define cfg_print_ee tx_print_stub
-    #define cfg_print_ex tx_print_stub
-    #define cfg_print_baud tx_print_stub
-    #define cfg_print_net tx_print_stub
-    #define cfg_print_rx tx_print_stub
-
+#define cfg_print_ec tx_print_stub
+#define cfg_print_ee tx_print_stub
+#define cfg_print_ex tx_print_stub
+#define cfg_print_baud tx_print_stub
+#define cfg_print_net tx_print_stub
+#define cfg_print_rx tx_print_stub
 #endif // __TEXT_MODE
 
-#endif //End of include guard: CONFIG_APP_H_ONCE
+#endif // CONFIG_APP_H_ONCE
index 33cec6f2ae2126b397c6f6648fc41b7317e3f6c0..44a2a05148274cb6ce723b324dae83ea0d1f2a1b 100644 (file)
 #include "util.h"
 #include "usart.h"
 
+
 controller_t cs;        // controller state structure
 
+
 static stat_t _shutdown_idler();
 static stat_t _normal_idler();
 static stat_t _limit_switch_handler();
@@ -56,6 +58,7 @@ static stat_t _sync_to_planner();
 static stat_t _sync_to_tx_buffer();
 static stat_t _command_dispatch();
 
+
 // prep for export to other modules:
 stat_t hardware_hard_reset_handler();
 stat_t hardware_bootloader_handler();
@@ -67,13 +70,13 @@ void controller_init() {
 
   cs.fw_build = TINYG_FIRMWARE_BUILD;
   cs.fw_version = TINYG_FIRMWARE_VERSION;
-  cs.hw_platform = TINYG_HARDWARE_PLATFORM;         // NB: HW version is set from EEPROM
+  cs.hw_platform = TINYG_HARDWARE_PLATFORM;        // NB: HW version is set from EEPROM
 
-  cs.state = CONTROLLER_STARTUP;                    // ready to run startup lines
+  cs.state = CONTROLLER_STARTUP;                   // ready to run startup lines
 }
 
 
-/// controller_test_assertions() - check memory integrity of controller
+/// Check memory integrity of controller
 void controller_init_assertions() {
   cs.magic_start = MAGICNUM;
   cs.magic_end = MAGICNUM;
@@ -89,7 +92,7 @@ stat_t controller_test_assertions() {
 
 
 /*
- * controller_run() - MAIN LOOP - top-level controller
+ * Main loop - top-level controller
  *
  * The order of the dispatched tasks is very important.
  * Tasks are ordered by increasing dependency (blocking hierarchy).
@@ -113,24 +116,24 @@ void controller_run() {
   // See hardware.h for a list of ISRs and their priorities.
 
   // Kernel level ISR handlers, flags are set in ISRs, order is important
-  DISPATCH(hw_hard_reset_handler());            // 1. handle hard reset requests
-  DISPATCH(hw_bootloader_handler());            // 2. handle requests to enter bootloader
-  DISPATCH(_shutdown_idler());                  // 3. idle in shutdown state
-  DISPATCH(_limit_switch_handler());            // 4. limit switch has been thrown
-  DISPATCH(cm_feedhold_sequencing_callback());  // 5a. feedhold state machine runner
-  DISPATCH(mp_plan_hold_callback());            // 5b. plan a feedhold from line runtime
-  DISPATCH(_system_assertions());               // 6. system integrity assertions
+  DISPATCH(hw_hard_reset_handler());           // 1. handle hard reset requests
+  DISPATCH(hw_bootloader_handler());           // 2. handle requests to enter bootloader
+  DISPATCH(_shutdown_idler());                 // 3. idle in shutdown state
+  DISPATCH(_limit_switch_handler());           // 4. limit switch has been thrown
+  DISPATCH(cm_feedhold_sequencing_callback()); // 5a. feedhold state machine runner
+  DISPATCH(mp_plan_hold_callback());           // 5b. plan a feedhold from line runtime
+  DISPATCH(_system_assertions());              // 6. system integrity assertions
 
   // Planner hierarchy for gcode and cycles
-  DISPATCH(st_motor_power_callback());        // stepper motor power sequencing
-  DISPATCH(sr_status_report_callback());      // conditionally send status report
-  DISPATCH(qr_queue_report_callback());       // conditionally send queue report
-  DISPATCH(rx_report_callback());             // conditionally send rx report
-  DISPATCH(cm_arc_callback());                // arc generation runs behind lines
-  DISPATCH(cm_homing_callback());             // G28.2 continuation
-  DISPATCH(cm_jogging_callback());            // jog function
-  DISPATCH(cm_probe_callback());              // G38.2 continuation
-  DISPATCH(cm_deferred_write_callback());     // persist G10 changes when not in machining cycle
+  DISPATCH(st_motor_power_callback());         // stepper motor power sequencing
+  DISPATCH(sr_status_report_callback());       // conditionally send status report
+  DISPATCH(qr_queue_report_callback());        // conditionally send queue report
+  DISPATCH(rx_report_callback());              // conditionally send rx report
+  DISPATCH(cm_arc_callback());                 // arc generation runs behind lines
+  DISPATCH(cm_homing_callback());              // G28.2 continuation
+  DISPATCH(cm_jogging_callback());             // jog function
+  DISPATCH(cm_probe_callback());               // G38.2 continuation
+  DISPATCH(cm_deferred_write_callback());      // persist G10 changes when not in machining cycle
 
   // Command readers and parsers
   DISPATCH(_sync_to_planner());                // ensure there is at least one free buffer in planning queue
@@ -142,7 +145,7 @@ void controller_run() {
 
 
 /*****************************************************************************
- * _command_dispatch() - dispatch line received from active input device
+ * Dispatch line received from active input device
  *
  *    Reads next command line and dispatches to relevant parser or action
  *    Accepts commands if the move queue has room - EAGAINS if it doesn't
@@ -167,50 +170,44 @@ static stat_t _command_dispatch() {
   strncpy(cs.saved_buf, cs.bufp, SAVED_BUFFER_LEN - 1);  // save input buffer for reporting
 
   // dispatch the new text line
-  switch (toupper(*cs.bufp)) {                        // first char
-  case '!': cm_request_feedhold(); break;             // include for diagnostics
+  switch (toupper(*cs.bufp)) {                    // first char
+  case '!': cm_request_feedhold(); break;         // include for diagnostics
   case '%': cm_request_queue_flush(); break;
   case '~': cm_request_cycle_start(); break;
 
-  case 0:                                        // blank line (just a CR)
+  case 0:                                         // blank line (just a CR)
     if (cfg.comm_mode != JSON_MODE)
       text_response(STAT_OK, cs.saved_buf);
     break;
 
-  case '$': case '?': case 'H':                  // text mode input
+  case '$': case '?': case 'H':                   // text mode input
     cfg.comm_mode = TEXT_MODE;
     text_response(text_parser(cs.bufp), cs.saved_buf);
     break;
 
-  case '{':                                      // JSON input
+  case '{':                                       // JSON input
     cfg.comm_mode = JSON_MODE;
     json_parser(cs.bufp);
     break;
 
-  default:                                          // anything else must be Gcode
+  default:                                        // anything else must be Gcode
     if (cfg.comm_mode == JSON_MODE) {             // run it as JSON...
-      strncpy(cs.out_buf, cs.bufp, INPUT_BUFFER_LEN -8);                    // use out_buf as temp
-      sprintf((char *)cs.bufp,"{\"gc\":\"%s\"}\n", (char *)cs.out_buf);     // '-8' is used for JSON chars
+      strncpy(cs.out_buf, cs.bufp, INPUT_BUFFER_LEN -8);                 // use out_buf as temp
+      sprintf((char *)cs.bufp,"{\"gc\":\"%s\"}\n", (char *)cs.out_buf);  // '-8' is used for JSON chars
       json_parser(cs.bufp);
 
-    } else text_response(gc_gcode_parser(cs.bufp), cs.saved_buf);           //...or run it as text
+    } else text_response(gc_gcode_parser(cs.bufp), cs.saved_buf);        //...or run it as text
   }
 
   return STAT_OK;
 }
 
 
-/**** Local Utilities ********************************************************/
-/*
- * _shutdown_idler() - blink rapidly and prevent further activity from occurring
- * _normal_idler() - blink Indicator LED slowly to show everything is OK
- *
- *    Shutdown idler flashes indicator LED rapidly to show everything is not OK.
- *    Shutdown idler returns EAGAIN causing the control loop to never advance beyond
- *    this point. It's important that the reset handler is still called so a SW reset
- *    (ctrl-x) or bootloader request can be processed.
- */
-
+/// Blink rapidly and prevent further activity from occurring
+/// Shutdown idler flashes indicator LED rapidly to show everything is not OK.
+/// Shutdown idler returns EAGAIN causing the control loop to never advance beyond
+/// this point. It's important that the reset handler is still called so a SW reset
+/// (ctrl-x) or bootloader request can be processed.
 static stat_t _shutdown_idler() {
   if (cm_get_machine_state() != MACHINE_SHUTDOWN) return STAT_OK;
 
@@ -227,11 +224,8 @@ static stat_t _normal_idler() {
   return STAT_OK;
 }
 
-/*
- * _sync_to_tx_buffer() - return eagain if TX queue is backed up
- * _sync_to_planner() - return eagain if planner is not ready for a new command
- * _sync_to_time() - return eagain if planner is not ready for a new command
- */
+
+/// Return eagain if TX queue is backed up
 static stat_t _sync_to_tx_buffer() {
   if (usart_tx_full()) return STAT_EAGAIN;
 
@@ -239,6 +233,7 @@ static stat_t _sync_to_tx_buffer() {
 }
 
 
+/// Return eagain if planner is not ready for a new command
 static stat_t _sync_to_planner() {
   if (mp_get_planner_buffers_available() < PLANNER_BUFFER_HEADROOM) // allow up to N planner buffers for this line
     return STAT_EAGAIN;
index bd2e8429ff4d5a2af8bbef32b328fc12a89e949c..ecd50f724d3399086245fcf0163c0295dc686683 100644 (file)
 #include "util.h"
 #include "usart.h"
 
-/**** Allocation ****/
 
 srSingleton_t sr;
 qrSingleton_t qr;
 rxSingleton_t rx;
 
-/**** Exception Reports ************************************************************
- * rpt_exception() - generate an exception message - always in JSON format
+
+/*
+ * Generate an exception message - always in JSON format
  *
  * Returns incoming status value
  *
  * WARNING: Do not call this function from MED or HI interrupts (LO is OK)
- *            or there is a potential for deadlock in the TX buffer.
+ *   or there is a potential for deadlock in the TX buffer.
  */
-stat_t rpt_exception(uint8_t status)
-{
-  if (status != STAT_OK) {    // makes it possible to call exception reports w/o checking status value
-    if (js.json_syntax == JSON_SYNTAX_RELAXED) {
+stat_t rpt_exception(uint8_t status) {
+  if (status != STAT_OK) { // makes it possible to call exception reports w/o checking status value
+    if (js.json_syntax == JSON_SYNTAX_RELAXED)
       printf_P(PSTR("{er:{fb:%0.2f,st:%d,msg:\"%s\"}}\n"),
                TINYG_FIRMWARE_BUILD, status, get_status_message(status));
-    } else {
-      printf_P(PSTR("{\"er\":{\"fb\":%0.2f,\"st\":%d,\"msg\":\"%s\"}}\n"),
+    else printf_P(PSTR("{\"er\":{\"fb\":%0.2f,\"st\":%d,\"msg\":\"%s\"}}\n"),
                TINYG_FIRMWARE_BUILD, status, get_status_message(status));
-    }
   }
-  return status;            // makes it possible to inline, e.g: return rpt_exception(status);
+
+  return status;
 }
 
-/*
- * rpt_er()    - send a bogus exception report for testing purposes (it's not real)
- */
-stat_t rpt_er(nvObj_t *nv)
-{
+
+/// Send a bogus exception report for testing purposes (it's not real)
+stat_t rpt_er(nvObj_t *nv) {
   return rpt_exception(STAT_GENERIC_EXCEPTION_REPORT); // bogus exception report for testing
 }
 
-/**** Application Messages *********************************************************
- * rpt_print_initializing_message()       - initializing configs from hard-coded profile
- * rpt_print_loading_configs_message() - loading configs from EEPROM
- * rpt_print_system_ready_message()    - system ready message
- *
- *    These messages are always in JSON format to allow UIs to sync
- */
 
-//void _startup_helper(stat_t status, const char_t *msg)
-void _startup_helper(stat_t status, const char *msg)
-{
+
+// These messages are always in JSON format to allow UIs to sync
+void _startup_helper(stat_t status, const char *msg) {
 #ifndef __SUPPRESS_STARTUP_MESSAGES
-  js.json_footer_depth = JSON_FOOTER_DEPTH;    //++++ temporary until changeover is complete
+  js.json_footer_depth = JSON_FOOTER_DEPTH;
   nv_reset_nv_list();
-  nv_add_object((const char_t *)"fv");        // firmware version
-  nv_add_object((const char_t *)"fb");        // firmware build
-  nv_add_object((const char_t *)"hp");        // hardware platform
-  nv_add_object((const char_t *)"hv");        // hardware version
-  nv_add_object((const char_t *)"id");        // hardware ID
-  nv_add_string((const char_t *)"msg", pstr2str(msg));    // startup message
+
+  nv_add_object((const char_t *)"fv");                 // firmware version
+  nv_add_object((const char_t *)"fb");                 // firmware build
+  nv_add_object((const char_t *)"hp");                 // hardware platform
+  nv_add_object((const char_t *)"hv");                 // hardware version
+  nv_add_object((const char_t *)"id");                 // hardware ID
+  nv_add_string((const char_t *)"msg", pstr2str(msg)); // startup message
+
   json_print_response(status);
 #endif
 }
 
-void rpt_print_initializing_message()
-{
+
+/// Initializing configs from hard-coded profile
+void rpt_print_initializing_message() {
   _startup_helper(STAT_INITIALIZING, PSTR(INIT_MESSAGE));
 }
 
-void rpt_print_loading_configs_message()
-{
+
+/// Loading configs from EEPROM
+void rpt_print_loading_configs_message() {
   _startup_helper(STAT_INITIALIZING, PSTR("Loading configs from EEPROM"));
 }
 
-void rpt_print_system_ready_message()
-{
+
+/// System ready message
+void rpt_print_system_ready_message() {
   _startup_helper(STAT_OK, PSTR("SYSTEM READY"));
   if (cfg.comm_mode == TEXT_MODE)
     text_response(STAT_OK, (char_t *)"");   // prompt
 }
 
+
 /*****************************************************************************
  * Status Reports
  *
@@ -127,7 +122,7 @@ void rpt_print_system_ready_message()
  *
  *    Status report formats: The following formats exist for status reports:
  *
- *      -    JSON format: Returns a JSON object as above, but with the values filled in.
+ *      - JSON format: Returns a JSON object as above, but with the values filled in.
  *        In JSON form all values are returned as numeric values or enumerations.
  *        E.g. "posx" is returned as 124.523 and "unit" is returned as 0 for
  *        inches (G20) and 1 for mm (G21).
@@ -158,80 +153,82 @@ void rpt_print_system_ready_message()
 static stat_t _populate_unfiltered_status_report();
 static uint8_t _populate_filtered_status_report();
 
-uint8_t _is_stat(nvObj_t *nv)
-{
-  char_t tok[TOKEN_LEN+1];
+
+uint8_t _is_stat(nvObj_t *nv) {
+  char_t tok[TOKEN_LEN + 1];
 
   GET_TOKEN_STRING(nv->value, tok);
-  if (strcmp(tok, "stat") == 0) { return true;}
-  return false;
+
+  return strcmp(tok, "stat") == 0;
 }
 
-/*
- * sr_init_status_report()
- *
- *    Call this function to completely re-initialize the status report
- *    Sets SR list to hard-coded defaults and re-initializes SR values in NVM
- */
-void sr_init_status_report()
-{
-  nvObj_t *nv = nv_reset_nv_list();    // used for status report persistence locations
+
+/// Call this function to completely re-initialize the status report
+/// Sets SR list to hard-coded defaults and re-initializes SR values in NVM
+void sr_init_status_report() {
+  nvObj_t *nv = nv_reset_nv_list(); // used for status report persistence locations
   sr.status_report_requested = false;
-  char_t sr_defaults[NV_STATUS_REPORT_LEN][TOKEN_LEN+1] = { STATUS_REPORT_DEFAULTS };    // see settings.h
+  char_t sr_defaults[NV_STATUS_REPORT_LEN][TOKEN_LEN+1] = {STATUS_REPORT_DEFAULTS}; // see settings.h
   nv->index = nv_get_index((const char_t *)"", (const char_t *)"se00");    // set first SR persistence index
   sr.stat_index = 0;
 
-  for (uint8_t i=0; i < NV_STATUS_REPORT_LEN ; i++) {
-    if (sr_defaults[i][0] == 0) break;                // quit on first blank array entry
-    sr.status_report_value[i] = -1234567;                // pre-load values with an unlikely number
-    nv->value = nv_get_index((const char_t *)"", sr_defaults[i]);// load the index for the SR element
+  for (uint8_t i = 0; i < NV_STATUS_REPORT_LEN; i++) {
+    if (sr_defaults[i][0] == 0) break;               // quit on first blank array entry
+
+    sr.status_report_value[i] = -1234567;            // pre-load values with an unlikely number
+    nv->value = nv_get_index((const char_t *)"", sr_defaults[i]); // load the index for the SR element
+
     if (nv->value == NO_MATCH) {
-      rpt_exception(STAT_BAD_STATUS_REPORT_SETTING);    // trap mis-configured profile settings
+      rpt_exception(STAT_BAD_STATUS_REPORT_SETTING); // trap mis-configured profile settings
       return;
     }
-    if (_is_stat(nv) == true)
-      sr.stat_index = nv->value;                        // identify index for 'stat' if status is in the report
+
+    if (_is_stat(nv)) sr.stat_index = nv->value;     // identify index for 'stat' if status is in the report
+
     nv_set(nv);
-    nv_persist(nv);                                        // conditionally persist - automatic by nv_persist()
-    nv->index++;                                        // increment SR NVM index
+    nv_persist(nv);                                  // conditionally persist - automatic by nv_persist()
+    nv->index++;                                     // increment SR NVM index
   }
 }
 
+
 /*
- * sr_set_status_report() - interpret an SR setup string and return current report
+ * Interpret an SR setup string and return current report
  *
  *    Note: By the time this function is called any unrecognized tokens have been detected and
  *    rejected by the JSON or text parser. In other words, it should never get to here if
  *    there is an unrecognized token in the SR string.
  */
-stat_t sr_set_status_report(nvObj_t *nv)
-{
+stat_t sr_set_status_report(nvObj_t *nv) {
   uint8_t elements = 0;
   index_t status_report_list[NV_STATUS_REPORT_LEN];
   memset(status_report_list, 0, sizeof(status_report_list));
-  index_t sr_start = nv_get_index((const char_t *)"",(const char_t *)"se00");// set first SR persistence index
+  index_t sr_start = nv_get_index((const char_t *)"", (const char_t *)"se00"); // set first SR persistence index
 
-  for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
+  for (uint8_t i = 0; i < NV_STATUS_REPORT_LEN; i++) {
     if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) break;
+
     if ((nv->valuetype == TYPE_BOOL) && (fp_TRUE(nv->value))) {
       status_report_list[i] = nv->index;
       nv->value = nv->index;                            // persist the index as the value
-      nv->index = sr_start + i;                        // index of the SR persistence location
+      nv->index = sr_start + i;                         // index of the SR persistence location
       nv_persist(nv);
       elements++;
-    } else {
-      return STAT_UNRECOGNIZED_NAME;
-    }
+
+    } else return STAT_UNRECOGNIZED_NAME;
   }
+
   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
 }
 
+
 /*
- * sr_request_status_report()    - request a status report to run after minimum interval
- * sr_status_report_callback()    - main loop callback to send a report if one is ready
+ * Request a status report to run after minimum interval
  *
  *    Status reports can be request from a number of sources including:
  *      - direct request from command line in the form of ? or {"sr:""}
@@ -241,88 +238,79 @@ stat_t sr_set_status_report(nvObj_t *nv)
  *    Status reports are generally returned with minimal delay (from the controller callback),
  *    but will not be provided more frequently than the status report interval
  */
-stat_t sr_request_status_report(uint8_t request_type)
-{
-  if (request_type == SR_IMMEDIATE_REQUEST) {
+stat_t sr_request_status_report(uint8_t request_type) {
+  if (request_type == SR_IMMEDIATE_REQUEST)
     sr.status_report_systick = SysTickTimer_getValue();
-  }
-  if ((request_type == SR_TIMED_REQUEST) && (sr.status_report_requested == false)) {
+
+  if ((request_type == SR_TIMED_REQUEST) && (sr.status_report_requested == false))
     sr.status_report_systick = SysTickTimer_getValue() + sr.status_report_interval;
-  }
+
   sr.status_report_requested = true;
+
   return STAT_OK;
 }
 
-stat_t sr_status_report_callback()         // called by controller dispatcher
-{
+
+/// Main loop callback to send a report if one is ready
+stat_t sr_status_report_callback() {         // called by controller dispatcher
 #ifdef __SUPPRESS_STATUS_REPORTS
   return STAT_NOOP;
 #endif
 
-  if (sr.status_report_verbosity == SR_OFF)
-    return STAT_NOOP;
-
-  if (sr.status_report_requested == false)
-    return STAT_NOOP;
-
-  if (SysTickTimer_getValue() < sr.status_report_systick)
-    return STAT_NOOP;
+  if (sr.status_report_verbosity == SR_OFF) return STAT_NOOP;
+  if (sr.status_report_requested == false) return STAT_NOOP;
+  if (SysTickTimer_getValue() < sr.status_report_systick) return STAT_NOOP;
 
   sr.status_report_requested = false;        // disable reports until requested again
 
-  if (sr.status_report_verbosity == SR_VERBOSE) {
+  if (sr.status_report_verbosity == SR_VERBOSE)
     _populate_unfiltered_status_report();
-  } else {
-    if (_populate_filtered_status_report() == false) {    // no new data
-      return STAT_OK;
-    }
-  }
+  else if (_populate_filtered_status_report() == false) return STAT_OK;  // no new data
+
   nv_print_list(STAT_OK, TEXT_INLINE_PAIRS, JSON_OBJECT_FORMAT);
+
   return STAT_OK;
 }
 
-/*
- * sr_run_text_status_report() - generate a text mode status report in multiline format
- */
-stat_t sr_run_text_status_report()
-{
+
+/// Generate a text mode status report in multiline format
+stat_t sr_run_text_status_report() {
   _populate_unfiltered_status_report();
   nv_print_list(STAT_OK, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT);
   return STAT_OK;
 }
 
-/*
- * _populate_unfiltered_status_report() - populate nvObj body with status values
- *
- *    Designed to be run as a response; i.e. have a "r" header and a footer.
- */
-static stat_t _populate_unfiltered_status_report()
-{
+
+/// Populate nvObj body with status values
+/// Designed to be run as a response; i.e. have a "r" header and a footer.
+static stat_t _populate_unfiltered_status_report() {
   const char_t sr_str[] = "sr";
-  char_t tmp[TOKEN_LEN+1];
+  char_t tmp[TOKEN_LEN + 1];
   nvObj_t *nv = nv_reset_nv_list();        // sets *nv to the start of the body
 
   nv->valuetype = TYPE_PARENT;             // setup the parent object (no length checking required)
   strcpy(nv->token, sr_str);
   nv->index = nv_get_index((const char_t *)"", sr_str);// set the index - may be needed by calling function
-  nv = nv->nx;                            // no need to check for 0 as list has just been reset
+  nv = nv->nx;                             // no need to check for 0 as list has just been reset
 
-  for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
-    if ((nv->index = sr.status_report_list[i]) == 0) { break;}
+  for (uint8_t i = 0; i < NV_STATUS_REPORT_LEN; i++) {
+    if ((nv->index = sr.status_report_list[i]) == 0) break;
     nv_get_nvObj(nv);
 
-    strcpy(tmp, nv->group);            // flatten out groups - WARNING - you cannot use strncpy here...
+    strcpy(tmp, nv->group);                // flatten out groups - WARNING - you cannot use strncpy here...
     strcat(tmp, nv->token);
-    strcpy(nv->token, tmp);            //...or here.
+    strcpy(nv->token, tmp);                //...or here.
 
-    if ((nv = nv->nx) == 0)
-      return cm_hard_alarm(STAT_BUFFER_FULL_FATAL);    // should never be 0 unless SR length exceeds available buffer array
+    if (!(nv = nv->nx))
+      return cm_hard_alarm(STAT_BUFFER_FULL_FATAL); // should never be 0 unless SR length exceeds available buffer array
   }
+
   return STAT_OK;
 }
 
+
 /*
- * _populate_filtered_status_report() - populate nvObj body with status values
+ * Populate nvObj body with status values
  *
  *    Designed to be displayed as a JSON object; i;e; no footer or header
  *    Returns 'true' if the report has new data, 'false' if there is nothing to report.
@@ -334,72 +322,65 @@ static stat_t _populate_unfiltered_status_report()
  *    NOTE: Room for improvement - look up the SR index initially and cache it, use the
  *          cached value for all remaining reports.
  */
-static uint8_t _populate_filtered_status_report()
-{
+static uint8_t _populate_filtered_status_report() {
   const char_t sr_str[] = "sr";
   uint8_t has_data = false;
-  char_t tmp[TOKEN_LEN+1];
+  char_t tmp[TOKEN_LEN + 1];
   nvObj_t *nv = nv_reset_nv_list();        // sets nv to the start of the body
 
   nv->valuetype = TYPE_PARENT;             // setup the parent object (no need to length check the copy)
   strcpy(nv->token, sr_str);
-  //    nv->index = nv_get_index((const char_t *)"", sr_str);// OMITTED - set the index - may be needed by calling function
-  nv = nv->nx;                            // no need to check for 0 as list has just been reset
+  nv = nv->nx;                             // no need to check for 0 as list has just been reset
 
-  for (uint8_t i=0; i<NV_STATUS_REPORT_LEN; i++) {
-    if ((nv->index = sr.status_report_list[i]) == 0) { break;}
+  for (uint8_t i = 0; i < NV_STATUS_REPORT_LEN; i++) {
+    if ((nv->index = sr.status_report_list[i]) == 0) break;
 
     nv_get_nvObj(nv);
     // do not report values that have not changed...
     // ...except for stat=3 (STOP), which is an exception
     if (fp_EQ(nv->value, sr.status_report_value[i])) {
-      //            if (nv->index != sr.stat_index) {
-      //                if (fp_EQ(nv->value, COMBINED_PROGRAM_STOP)) {
       nv->valuetype = TYPE_EMPTY;
       continue;
-      //                }
-      //            }
-      // report anything that has changed
+
     } else {
+      // report anything that has changed
       strcpy(tmp, nv->group);        // flatten out groups - WARNING - you cannot use strncpy here...
       strcat(tmp, nv->token);
       strcpy(nv->token, tmp);        //...or here.
       sr.status_report_value[i] = nv->value;
-      if ((nv = nv->nx) == 0) return false; // should never be 0 unless SR length exceeds available buffer array
+      if (!(nv = nv->nx)) return false; // should never be 0 unless SR length exceeds available buffer array
       has_data = true;
     }
   }
+
   return has_data;
 }
 
-/*
- * Wrappers and Setters - for calling from nvArray table
- *
- * sr_get()        - run status report
- * sr_set()        - set status report elements
- * sr_set_si()    - set status report interval
- */
-stat_t sr_get(nvObj_t *nv) { return _populate_unfiltered_status_report();}
-stat_t sr_set(nvObj_t *nv) { return sr_set_status_report(nv);}
 
-stat_t sr_set_si(nvObj_t *nv)
-{
+/// Run status report
+stat_t sr_get(nvObj_t *nv) {return _populate_unfiltered_status_report();}
+
+
+/// Set status report elements
+stat_t sr_set(nvObj_t *nv) {return sr_set_status_report(nv);}
+
+
+/// Set status report interval
+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;
 }
 
-/*********************
- * TEXT MODE SUPPORT *
- *********************/
+
 #ifdef __TEXT_MODE
 
 static const char fmt_si[] PROGMEM = "[si]  status interval%14.0f ms\n";
 static const char fmt_sv[] PROGMEM = "[sv]  status report verbosity%6d [0=off,1=filtered,2=verbose]\n";
 
-void sr_print_sr(nvObj_t *nv) { _populate_unfiltered_status_report();}
-void sr_print_si(nvObj_t *nv) { text_print_flt(nv, fmt_si);}
-void sr_print_sv(nvObj_t *nv) { text_print_ui8(nv, fmt_sv);}
+void sr_print_sr(nvObj_t *nv) {_populate_unfiltered_status_report();}
+void sr_print_si(nvObj_t *nv) {text_print_flt(nv, fmt_si);}
+void sr_print_sv(nvObj_t *nv) {text_print_ui8(nv, fmt_sv);}
 
 #endif // __TEXT_MODE
 
@@ -422,37 +403,34 @@ void sr_print_sv(nvObj_t *nv) { text_print_ui8(nv, fmt_sv);}
  *     2.    Add qr, qi and qo (or some combination) to the status report. This will
  *        return queue report data when status reports are generated.
  */
-/*
- * qr_init_queue_report() - initialize or clear queue report values
- */
-void qr_init_queue_report()
-{
+
+
+/// Initialize or clear queue report values
+void qr_init_queue_report() {
   qr.queue_report_requested = false;
   qr.buffers_added = 0;
   qr.buffers_removed = 0;
   qr.init_tick = SysTickTimer_getValue();
 }
 
+
 /*
- * qr_request_queue_report() - request a queue report
+ * Request a queue report
  *
- *    Requests a queue report and also records the buffers added and removed
- *    since the last init (usually re-initted when a report is generated).
+ * Requests a queue report and also records the buffers added and removed
+ * since the last init (usually re-initted when a report is generated).
  */
-void qr_request_queue_report(int8_t buffers)
-{
+void qr_request_queue_report(int8_t buffers) {
   // get buffer depth and added/removed count
   qr.buffers_available = mp_get_planner_buffers_available();
-  if (buffers > 0) {
-    qr.buffers_added += buffers;
-  } else {
-    qr.buffers_removed -= buffers;
-  }
+  if (buffers > 0) qr.buffers_added += buffers;
+  else qr.buffers_removed -= buffers;
 
   // time-throttle requests while generating arcs
   qr.motion_mode = cm_get_motion_mode(ACTIVE_MODEL);
   if ((qr.motion_mode == MOTION_MODE_CW_ARC) || (qr.motion_mode == MOTION_MODE_CCW_ARC)) {
     uint32_t tick = SysTickTimer_getValue();
+
     if (tick - qr.init_tick < MIN_ARC_QR_INTERVAL) {
       qr.queue_report_requested = false;
       return;
@@ -460,70 +438,54 @@ void qr_request_queue_report(int8_t buffers)
   }
 
   // either return or request a report
-  if (qr.queue_report_verbosity != QR_OFF) {
+  if (qr.queue_report_verbosity != QR_OFF)
     qr.queue_report_requested = true;
-  }
 }
 
-/*
- * qr_queue_report_callback() - generate a queue report if one has been requested
- */
-stat_t qr_queue_report_callback()         // called by controller dispatcher
-{
+
+/// generate a queue report if one has been requested
+stat_t qr_queue_report_callback() {        // called by controller dispatcher
 #ifdef __SUPPRESS_QUEUE_REPORTS
   return STAT_NOOP;
 #endif
 
-  if (qr.queue_report_verbosity == QR_OFF)
-    return STAT_NOOP;
-
-  if (qr.queue_report_requested == false)
-    return STAT_NOOP;
+  if (qr.queue_report_verbosity == QR_OFF) return STAT_NOOP;
+  if (qr.queue_report_requested == false) return STAT_NOOP;
 
   qr.queue_report_requested = false;
 
   if (cfg.comm_mode == TEXT_MODE) {
-    if (qr.queue_report_verbosity == QR_SINGLE) {
+    if (qr.queue_report_verbosity == QR_SINGLE)
       fprintf(stderr, "qr:%d\n", qr.buffers_available);
-    } else  {
-      fprintf(stderr, "qr:%d, qi:%d, qo:%d\n", qr.buffers_available,qr.buffers_added,qr.buffers_removed);
-    }
+    else fprintf(stderr, "qr:%d, qi:%d, qo:%d\n", qr.buffers_available,qr.buffers_added,qr.buffers_removed);
 
   } else if (js.json_syntax == JSON_SYNTAX_RELAXED) {
-    if (qr.queue_report_verbosity == QR_SINGLE) {
+    if (qr.queue_report_verbosity == QR_SINGLE)
       fprintf(stderr, "{qr:%d}\n", qr.buffers_available);
-    } else {
-      fprintf(stderr, "{qr:%d,qi:%d,qo:%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
-    }
+    else fprintf(stderr, "{qr:%d,qi:%d,qo:%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
 
   } else {
-    if (qr.queue_report_verbosity == QR_SINGLE) {
+    if (qr.queue_report_verbosity == QR_SINGLE)
       fprintf(stderr, "{\"qr\":%d}\n", qr.buffers_available);
-    } else {
-      fprintf(stderr, "{\"qr\":%d,\"qi\":%d,\"qo\":%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
-    }
+    else fprintf(stderr, "{\"qr\":%d,\"qi\":%d,\"qo\":%d}\n", qr.buffers_available, qr.buffers_added,qr.buffers_removed);
   }
+
   qr_init_queue_report();
 
   return STAT_OK;
 }
 
 
-/*
- * rx_request_rx_report() - request an update on serial buffer space available
- */
+/// Request an update on serial buffer space available
 void rx_request_rx_report() {
   rx.rx_report_requested = true;
   rx.space_available = usart_rx_space();
 }
 
 
-/*
- * rx_report_callback() - send rx report if one has been requested
- */
+/// Send rx report if one has been requested
 stat_t rx_report_callback() {
-  if (!rx.rx_report_requested)
-    return STAT_NOOP;
+  if (!rx.rx_report_requested) return STAT_NOOP;
 
   rx.rx_report_requested = false;
 
@@ -532,13 +494,7 @@ stat_t rx_report_callback() {
 }
 
 
-/*
- * Wrappers and Setters - for calling from cfgArray table
- *
- * qr_get() - run a queue report (as data)
- * qi_get() - run a queue report - buffers in
- * qo_get() - run a queue report - buffers out
- */
+/// Run a queue report (as data)
 stat_t qr_get(nvObj_t *nv) {
   nv->value = (float)mp_get_planner_buffers_available(); // ensure that manually requested QR count is always up to date
   nv->valuetype = TYPE_INTEGER;
@@ -546,32 +502,25 @@ stat_t qr_get(nvObj_t *nv) {
 }
 
 
+/// Run a queue report - buffers in
 stat_t qi_get(nvObj_t *nv) {
   nv->value = (float)qr.buffers_added;
   nv->valuetype = TYPE_INTEGER;
-  qr.buffers_added = 0;                // reset it
+  qr.buffers_added = 0;                    // reset it
   return STAT_OK;
 }
 
 
+/// Run a queue report - buffers out
 stat_t qo_get(nvObj_t *nv) {
   nv->value = (float)qr.buffers_removed;
   nv->valuetype = TYPE_INTEGER;
-  qr.buffers_removed = 0;                // reset it
+  qr.buffers_removed = 0;                  // reset it
   return STAT_OK;
 }
 
 
-/*****************************************************************************
- * JOB ID REPORTS
- *
- *    job_populate_job_report()
- *    job_set_job_report()
- *    job_report_callback()
- *    job_get()
- *    job_set()
- *    job_print_job()
- */
+// Job ID reports
 stat_t job_populate_job_report() {
   const char_t job_str[] = "job";
   char_t tmp[TOKEN_LEN+1];
@@ -580,12 +529,11 @@ stat_t job_populate_job_report() {
   nv->valuetype = TYPE_PARENT;             // setup the parent object
   strcpy(nv->token, job_str);
 
-  //nv->index = nv_get_index((const char_t *)"", job_str);// set the index - may be needed by calling function
-  nv = nv->nx;                            // no need to check for 0 as list has just been reset
+  nv = nv->nx;                             // no need to check for 0 as list has just been reset
 
-  index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1");// set first job persistence index
-  for (uint8_t i=0; i<4; i++) {
+  index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1"); // set first job persistence index
 
+  for (uint8_t i = 0; i < 4; i++) {
     nv->index = job_start + i;
     nv_get_nvObj(nv);
 
@@ -593,50 +541,51 @@ stat_t job_populate_job_report() {
     strcat(tmp, nv->token);
     strcpy(nv->token, tmp);
 
-    if ((nv = nv->nx) == 0)
-      return STAT_OK;               // should never be 0 unless SR length exceeds available buffer array
+    if ((nv = nv->nx) == 0) return STAT_OK; // should never be 0 unless SR length exceeds available buffer array
   }
+
   return STAT_OK;
 }
 
-stat_t job_set_job_report(nvObj_t *nv)
-{
-  index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1");// set first job persistence index
+
+stat_t job_set_job_report(nvObj_t *nv) {
+  index_t job_start = nv_get_index((const char_t *)"",(const char_t *)"job1"); // set first job persistence index
 
   for (uint8_t i=0; i<4; i++) {
-    if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) { break;}
+    if (((nv = nv->nx) == 0) || (nv->valuetype == TYPE_EMPTY)) break;
+
     if (nv->valuetype == TYPE_INTEGER) {
       cs.job_id[i] = nv->value;
       nv->index = job_start + i;        // index of the SR persistence location
       nv_persist(nv);
-    } else {
-      return STAT_UNSUPPORTED_TYPE;
-    }
+
+    } else return STAT_UNSUPPORTED_TYPE;
   }
-  job_populate_job_report();                // return current values
+
+  job_populate_job_report();            // return current values
+
   return STAT_OK;
 }
 
-uint8_t job_report_callback()
-{
-  if (cfg.comm_mode == TEXT_MODE) {
-    // no-op, job_ids are client app state
-  } else if (js.json_syntax == JSON_SYNTAX_RELAXED) {
-    fprintf(stderr, "{job:[%lu,%lu,%lu,%lu]}\n", cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3] );
-  } else {
-    fprintf(stderr, "{\"job\":[%lu,%lu,%lu,%lu]}\n", cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3] );
-    //job_clear_report();
-  }
+
+uint8_t job_report_callback() {
+  if (cfg.comm_mode == TEXT_MODE) ; // no-op, job_ids are client app state
+
+  else if (js.json_syntax == JSON_SYNTAX_RELAXED)
+    fprintf(stderr, "{job:[%lu,%lu,%lu,%lu]}\n",
+            cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3]);
+
+  else fprintf(stderr, "{\"job\":[%lu,%lu,%lu,%lu]}\n",
+               cs.job_id[0], cs.job_id[1], cs.job_id[2], cs.job_id[3]);
+
   return STAT_OK;
 }
 
-stat_t job_get(nvObj_t *nv) { return job_populate_job_report();}
-stat_t job_set(nvObj_t *nv) { return job_set_job_report(nv);}
-void job_print_job(nvObj_t *nv) { job_populate_job_report();}
+stat_t job_get(nvObj_t *nv) {return job_populate_job_report();}
+stat_t job_set(nvObj_t *nv) {return job_set_job_report(nv);}
+void job_print_job(nvObj_t *nv) {job_populate_job_report();}
+
 
-/*********************
- * TEXT MODE SUPPORT *
- *********************/
 #ifdef __TEXT_MODE
 
 static const char fmt_qr[] PROGMEM = "qr:%d\n";
@@ -644,9 +593,9 @@ static const char fmt_qi[] PROGMEM = "qi:%d\n";
 static const char fmt_qo[] PROGMEM = "qo:%d\n";
 static const char fmt_qv[] PROGMEM = "[qv]  queue report verbosity%7d [0=off,1=single,2=triple]\n";
 
-void qr_print_qr(nvObj_t *nv) { text_print_int(nv, fmt_qr);}
-void qr_print_qi(nvObj_t *nv) { text_print_int(nv, fmt_qi);}
-void qr_print_qo(nvObj_t *nv) { text_print_int(nv, fmt_qo);}
-void qr_print_qv(nvObj_t *nv) { text_print_ui8(nv, fmt_qv);}
+void qr_print_qr(nvObj_t *nv) {text_print_int(nv, fmt_qr);}
+void qr_print_qi(nvObj_t *nv) {text_print_int(nv, fmt_qi);}
+void qr_print_qo(nvObj_t *nv) {text_print_int(nv, fmt_qo);}
+void qr_print_qv(nvObj_t *nv) {text_print_ui8(nv, fmt_qv);}
 
 #endif // __TEXT_MODE
index da41d0d445a42f8377cfa44df44c303d4331c551..1163a7675caa252c49f65316f14c95cc1a1e2033 100644 (file)
 #ifndef REPORT_H_ONCE
 #define REPORT_H_ONCE
 
-/**** Configs, Definitions and Structures ****/
-//
 // Notes:
-//        - The NV_STATUS_REPORT_LEN define is in config.h
-//        - The status report defaults can be found in settings.h
+//   - The NV_STATUS_REPORT_LEN define is in config.h
+//   - The status report defaults can be found in settings.h
 
 #define MIN_ARC_QR_INTERVAL 200                    // minimum interval between QRs during arc generation (in system ticks)
 
-enum srVerbosity {                                // status report enable and verbosity
-  SR_OFF = 0,                                    // no reports
-  SR_FILTERED,                                // reports only values that have changed from the last report
-  SR_VERBOSE                                    // reports all values specified
+
+enum srVerbosity {                                 // status report enable and verbosity
+  SR_OFF = 0,                                      // no reports
+  SR_FILTERED,                                     // reports only values that have changed from the last report
+  SR_VERBOSE                                       // reports all values specified
 };
 
+
 enum cmStatusReportRequest {
-  SR_TIMED_REQUEST = 0,                        // request a status report at next timer interval
-  SR_IMMEDIATE_REQUEST                        // request a status report ASAP
+  SR_TIMED_REQUEST = 0,                            // request a status report at next timer interval
+  SR_IMMEDIATE_REQUEST                             // request a status report ASAP
 };
 
-enum qrVerbosity {                                // planner queue enable and verbosity
-  QR_OFF = 0,                                    // no response is provided
-  QR_SINGLE,                                    // queue depth reported
-  QR_TRIPLE                                    // queue depth reported for buffers, buffers added, buffered removed
+
+enum qrVerbosity {                                 // planner queue enable and verbosity
+  QR_OFF = 0,                                      // no response is provided
+  QR_SINGLE,                                       // queue depth reported
+  QR_TRIPLE                                        // queue depth reported for buffers, buffers added, buffered removed
 };
 
-typedef struct srSingleton {
 
-  /*** config values (PUBLIC) ***/
+typedef struct srSingleton {
+  // Public
   uint8_t status_report_verbosity;
-  uint32_t status_report_interval;                    // in milliseconds
-
-  /*** runtime values (PRIVATE) ***/
-  uint8_t status_report_requested;                    // flag that SR has been requested
-  uint32_t status_report_systick;                        // SysTick value for next status report
-  index_t stat_index;                                    // table index value for stat - determined during initialization
-  index_t status_report_list[NV_STATUS_REPORT_LEN];    // status report elements to report
-  float status_report_value[NV_STATUS_REPORT_LEN];    // previous values for filtered reporting
-
+  uint32_t status_report_interval;                  // in milliseconds
+
+  // Private
+  uint8_t status_report_requested;                  // flag that SR has been requested
+  uint32_t status_report_systick;                   // SysTick value for next status report
+  index_t stat_index;                               // table index value for stat - determined during initialization
+  index_t status_report_list[NV_STATUS_REPORT_LEN]; // status report elements to report
+  float status_report_value[NV_STATUS_REPORT_LEN];  // previous values for filtered reporting
 } srSingleton_t;
 
-typedef struct qrSingleton {        // data for queue reports
 
-  /*** config values (PUBLIC) ***/
-  uint8_t queue_report_verbosity;    // queue reports enabled and verbosity level
-
-  /*** runtime values (PRIVATE) ***/
-  uint8_t queue_report_requested;    // set to true to request a report
-  uint8_t buffers_available;        // stored buffer depth passed to by callback
-  uint8_t prev_available;            // buffers available at last count
-  uint16_t buffers_added;            // buffers added since last count
-  uint16_t buffers_removed;        // buffers removed since last report
-  uint8_t motion_mode;            // used to detect arc movement
-  uint32_t init_tick;                // time when values were last initialized or cleared
+typedef struct qrSingleton {                        // data for queue reports
+  // Public
+  uint8_t queue_report_verbosity;                   // queue reports enabled and verbosity level
 
+  // Private
+  uint8_t queue_report_requested;                   // set to true to request a report
+  uint8_t buffers_available;                        // stored buffer depth passed to by callback
+  uint8_t prev_available;                           // buffers available at last count
+  uint16_t buffers_added;                           // buffers added since last count
+  uint16_t buffers_removed;                         // buffers removed since last report
+  uint8_t motion_mode;                              // used to detect arc movement
+  uint32_t init_tick;                               // time when values were last initialized or cleared
 } qrSingleton_t;
 
+
 typedef struct rxSingleton {
   uint8_t rx_report_requested;
-  uint16_t space_available;       // space available in rx buffer at time of request
+  uint16_t space_available;                         // space available in rx buffer at time of request
 } rxSingleton_t;
 
-/**** Externs - See report.c for allocation ****/
 
 extern srSingleton_t sr;
 extern qrSingleton_t qr;
 extern rxSingleton_t rx;
 
-/**** Function Prototypes ****/
 
 void rpt_print_message(char *msg);
 stat_t rpt_exception(uint8_t status);
@@ -148,4 +146,4 @@ void qr_print_qo(nvObj_t *nv);
 
 #endif // __TEXT_MODE
 
-#endif // End of include guard: REPORT_H_ONCE
+#endif // REPORT_H_ONCE
index 717f6d67ca43cf0c79a22dd26fe95def1e4d5a23..4866a288d0576acce5a5b889640a1cbe06c9ff6e 100644 (file)
@@ -64,7 +64,7 @@
 #define STATUS_REPORT_VERBOSITY      SR_FILTERED               // one of: SR_OFF, SR_FILTERED, SR_VERBOSE=
 #define STATUS_REPORT_MIN_MS         100                       // milliseconds - enforces a viable minimum
 #define STATUS_REPORT_INTERVAL_MS    500                       // milliseconds - set $SV=0 to disable
-#define STATUS_REPORT_DEFAULTS "posx","posy","posz","posa","feed","vel","unit","coor","dist","frmo","stat"
+#define STATUS_REPORT_DEFAULTS "posx","posy","posz","posa","feed","vel","unit","coor","dist","frmo","stat","mst1","mfl1"
 
 #define QUEUE_REPORT_VERBOSITY       QR_OFF                    // one of: QR_OFF, QR_SINGLE, QR_TRIPLE
 
index 1f6ef74cf1be9fbc2e7d314f0e1be34b19145da0..32cbd0c2bc3011dccbec7be14eb4c3a65f7f623c 100644 (file)
@@ -49,7 +49,7 @@
 #define M1_MOTOR_MAP             AXIS_X              // 1ma
 #define M1_STEP_ANGLE            1.8                 // 1sa
 #define M1_TRAVEL_PER_REV        1.25                // 1tr
-#define M1_MICROSTEPS            256                 // 1mi        1,2,4,8
+#define M1_MICROSTEPS            8                   // 1mi        1,2,4,8
 #define M1_POLARITY              0                   // 1po        0=normal, 1=reversed
 #define M1_POWER_MODE            MOTOR_POWER_MODE    // 1pm        standard
 #define M1_POWER_LEVEL           MOTOR_POWER_LEVEL   // 1mp
index 4d8ddbb156462a2ae2aabff62fa09f86280627b2..44075e98adb7cbee2b0c2e750ead804d6915c700 100644 (file)
@@ -278,7 +278,7 @@ stat_t st_motor_power_callback() { // called by controller
 */
 ISR(TIMER_DDA_ISR_vect) {
   if ((st_run.mot[MOTOR_1].substep_accumulator += st_run.mot[MOTOR_1].substep_increment) > 0) {
-    PORT_MOTOR_1_VPORT.OUT |= STEP_BIT_bm;        // turn step bit on
+    PORT_MOTOR_1_VPORT.OUT ^= STEP_BIT_bm;        // turn step bit on
     st_run.mot[MOTOR_1].substep_accumulator -= st_run.dda_ticks_X_substeps;
     INCREMENT_ENCODER(MOTOR_1);
   }
@@ -301,8 +301,8 @@ ISR(TIMER_DDA_ISR_vect) {
     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
+  // Turn step bits off - pulse stretching for using external drivers.
+  //PORT_MOTOR_1_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 5 uSec pulse width
   PORT_MOTOR_2_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 4 uSec
   PORT_MOTOR_3_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 3 uSec
   PORT_MOTOR_4_VPORT.OUT &= ~STEP_BIT_bm;              // ~ 2 uSec
index 21b8c7565b41e82a041fb044d7d95d05398e5dce..278bc5f07af880d7d789e3fdc724232e62058a0e 100644 (file)
@@ -29,6 +29,8 @@
 
 \******************************************************************************/
 
+#include "tinyg.h"
+#include "config.h"
 #include "tmc2660.h"
 
 #include <avr/io.h>
@@ -53,7 +55,7 @@ typedef struct {
   uint8_t reset;
   uint8_t reg;
 
-  uint16_t mstep;
+  int16_t mstep;
   uint8_t status;
   uint32_t regs[5];
 } tmc2660_driver_t;
@@ -164,7 +166,8 @@ void spi_next() {
 
     case TMC2660_STATE_MONITOR:
       // Read response
-      drv->mstep = (spi_in >> 14) & 0x3ff;
+      drv->mstep = (int16_t)((spi_in >> 14) & 0x1ff);
+      if (spi_in & (1UL << 19)) drv->mstep = -drv->mstep;
       drv->status = spi_in >> 4;
 
       if (drv->reset) {
@@ -213,19 +216,24 @@ void tmc2660_init() {
     drivers[i].state = TMC2660_STATE_CONFIG;
     drivers[i].reg = 0;
 
-    drivers[i].regs[TMC2660_DRVCTRL] = TMC2660_DRVCTRL_MRES_256;
-    //drivers[i].regs[TMC2660_CHOPCONF] = TMC2660_CHOPCONF_TBL_36 | TMC2660_CHOPCONF_HEND(0) | TMC2660_CHOPCONF_HSTART(4) |
+    drivers[i].regs[TMC2660_DRVCTRL] = TMC2660_DRVCTRL_MRES_8;
+    //drivers[i].regs[TMC2660_CHOPCONF] = TMC2660_CHOPCONF_TBL_36 |
+    // TMC2660_CHOPCONF_HEND(0) | TMC2660_CHOPCONF_HSTART(4) |
     //  TMC2660_CHOPCONF_TOFF(4);
-    drivers[i].regs[TMC2660_CHOPCONF] = TMC2660_CHOPCONF_TBL_36 | TMC2660_CHOPCONF_CHM | TMC2660_CHOPCONF_HEND(7) |
+    drivers[i].regs[TMC2660_CHOPCONF] = TMC2660_CHOPCONF_TBL_36 |
+      TMC2660_CHOPCONF_CHM | TMC2660_CHOPCONF_HEND(7) |
       TMC2660_CHOPCONF_HSTART(6) | TMC2660_CHOPCONF_TOFF(7);
-    drivers[i].regs[TMC2660_SMARTEN] = TMC2660_SMARTEN_SEIMIN | TMC2660_SMARTEN_MAX(2) | TMC2660_SMARTEN_MIN(2);
-    drivers[i].regs[TMC2660_SGCSCONF] = TMC2660_SGCSCONF_SFILT | TMC2660_SGCSCONF_CS_NONE;
+    //drivers[i].regs[TMC2660_SMARTEN] = TMC2660_SMARTEN_SEIMIN |
+    //  TMC2660_SMARTEN_MAX(2) | TMC2660_SMARTEN_MIN(2);
+    drivers[i].regs[TMC2660_SGCSCONF] = TMC2660_SGCSCONF_SFILT |
+      TMC2660_SGCSCONF_THRESH(63) | TMC2660_SGCSCONF_CS_NONE;
     drivers[i].regs[TMC2660_DRVCONF] = TMC2660_DRVCONF_RDSEL_MSTEP;
   }
 
   // Setup pins
+  // Why is it necessary to set the SS pin for master mode to work?
   TMC2660_SPI_PORT.OUTSET = 1 << TMC2660_SPI_SS_PIN;   // High
-  TMC2660_SPI_PORT.DIRSET = 1 << TMC2660_SPI_SS_PIN;   // Output (Why is it necessary to set the SS pin?)
+  TMC2660_SPI_PORT.DIRSET = 1 << TMC2660_SPI_SS_PIN;   // Output
   TMC2660_SPI_PORT.OUTSET = 1 << TMC2660_SPI_SCK_PIN;  // High
   TMC2660_SPI_PORT.DIRSET = 1 << TMC2660_SPI_SCK_PIN;  // Output
   TMC2660_SPI_PORT.DIRCLR = 1 << TMC2660_SPI_MISO_PIN; // Input
@@ -285,3 +293,61 @@ int tmc2660_all_ready() {
 
   return 1;
 }
+
+
+static void tmc2660_get_status_flags(uint8_t status, char buf[35]) {
+  buf[0] = 0;
+
+  if (TMC2660_DRVSTATUS_STST & status) strcat(buf, "stst,");
+  if (TMC2660_DRVSTATUS_OLB  & status) strcat(buf, "olb,");
+  if (TMC2660_DRVSTATUS_OLA  & status) strcat(buf, "ola,");
+  if (TMC2660_DRVSTATUS_S2GB & status) strcat(buf, "s2gb,");
+  if (TMC2660_DRVSTATUS_S2GA & status) strcat(buf, "s2ga,");
+  if (TMC2660_DRVSTATUS_OTPW & status) strcat(buf, "otpw,");
+  if (TMC2660_DRVSTATUS_OT   & status) strcat(buf, "ot,");
+  if (TMC2660_DRVSTATUS_SG   & status) strcat(buf, "sg,");
+
+  if (buf[0] != 0) buf[strlen(buf) - 1] = 0; // Remove last comma
+}
+
+
+static const char mst_fmt[] PROGMEM = "Motor %i step:       %i\n";
+static const char mfl_fmt[] PROGMEM = "Motor %i flags:      %s\n";
+
+
+void tmc2660_print_motor_step(nvObj_t *nv) {
+  int driver = nv->token[3] - '1';
+  fprintf_P(stderr, mst_fmt, driver + 1, drivers[driver].mstep);
+}
+
+
+void tmc2660_print_motor_flags(nvObj_t *nv) {
+  int driver = nv->token[3] - '1';
+
+  char buf[35];
+  tmc2660_get_status_flags(drivers[driver].status, buf);
+
+  fprintf_P(stderr, mfl_fmt, driver + 1, buf);
+}
+
+
+stat_t tmc2660_get_motor_step(nvObj_t *nv) {
+  int driver = nv->token[3] - '1';
+
+  nv->value = drivers[driver].mstep;
+  nv->valuetype = TYPE_INTEGER;
+
+  return STAT_OK;
+}
+
+
+stat_t tmc2660_get_motor_flags(nvObj_t *nv) {
+  int driver = nv->token[3] - '1';
+  char buf[35];
+
+  tmc2660_get_status_flags(drivers[driver].status, buf);
+  nv_copy_string(nv, buf);
+  nv->valuetype = TYPE_STRING;
+
+  return STAT_OK;
+}
index 07212a2dc0ea85010ca4de36483a1a67eddec074..ec99b80a2bd8fb6f4c07c9d515f553859ae9936a 100644 (file)
@@ -51,7 +51,7 @@
 #define TMC2660_SPI_SSB_PORT PORTB
 #define TMC2660_SPI_SSB_PIN 3
 
-#define TMC2660_NUM_DRIVERS 4
+#define TMC2660_NUM_DRIVERS 3
 
 #define TMC2660_TIMER TCC1
 
@@ -62,6 +62,11 @@ void tmc2660_reset(int driver);
 int tmc2660_ready(int driver);
 int tmc2660_all_ready();
 
+void tmc2660_print_motor_step(nvObj_t *nv);
+void tmc2660_print_motor_flags(nvObj_t *nv);
+stat_t tmc2660_get_motor_step(nvObj_t *nv);
+stat_t tmc2660_get_motor_flags(nvObj_t *nv);
+
 #define TMC2660_DRVCTRL             0
 #define TMC2660_DRVCTRL_ADDR        (0UL << 18)
 #define TMC2660_DRVCTRL_PHA         (1UL << 17)