}
-/* G93, G94 (affects MODEL only)
- *
- * INVERSE_TIME_MODE = 0, // G93
- * UNITS_PER_MINUTE_MODE, // G94
- * UNITS_PER_REVOLUTION_MODE // G95 (unimplemented)
- */
+/// G93, G94 (affects MODEL only) See cmFeedRateMode
stat_t cm_set_feed_rate_mode(uint8_t mode) {
cm.gm.feed_rate_mode = mode;
return STAT_OK;
// Machining Functions (4.3.6) See arc.c
-
/// G4, P parameter (seconds)
stat_t cm_dwell(float seconds) {
cm.gm.parameter = seconds;
AXIS_DISABLED, // kill axis
AXIS_STANDARD, // axis in coordinated motion w/standard behaviors
AXIS_INHIBITED, // axis is computed but not activated
- AXIS_RADIUS // rotary axis calibrated to circumference
+ AXIS_RADIUS, // rotary axis calibrated to circumference
+ AXIS_MODE_MAX
}; // ordering must be preserved.
#define AXIS_MODE_MAX_LINEAR AXIS_INHIBITED
#include "config.h"
#include <avr/pgmspace.h>
+#include <avr/wdt.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <ctype.h>
else if (maxArgs < argc - 1) printf_P(PSTR("Too many arguments\n"));
else {
command_cb_t cb = pgm_read_word(&commands[i].cb);
- status = cb(argc, argv);
+ return cb(argc, argv);
}
- } else printf_P(PSTR("Unknown command '%s'\n"), argv[0]);
+ } else if (argc == 1) {
+ char *p = strchr(argv[0], '=');
+ if (p) {
+ *p++ = 0;
+ if (vars_set(argv[0], p)) return STAT_OK;
+ }
+
+ } else if (argc == 2 && vars_set(argv[0], argv[1]))
+ return STAT_OK;
+
+ printf_P(PSTR("Unknown command or unsetable variable '%s'\n"), argv[0]);
return status;
}
int command_parser(char *cmd) {
// Parse line
- char *p = cmd + 1;
+ char *p = cmd + 1; // Skip `$`
int argc = 0;
char *argv[MAX_ARGS] = {};
// Command functions
void static print_command_help(int i) {
- static const char fmt[] PROGMEM = " %-8S %S\n";
+ static const char fmt[] PROGMEM = " $%-8S %S\n";
const char *name = pgm_read_word(&commands[i].name);
const char *help = pgm_read_word(&commands[i].help);
const char *name = pgm_read_word(&commands[i].name);
if (!name) break;
print_command_help(i);
+ wdt_reset();
}
puts_P(PSTR("\nVariables:"));
#define AXES 6 // number of axes
#define MOTORS 4 // number of motors on the board
#define COORDS 6 // number of supported coordinate systems (1-6)
+#define SWITCHES 8 // number of supported limit switches
#define PWMS 2 // number of supported PWM channels
// Motor settings
#define MOTOR_CURRENT 0.8 // 1.0 is full power
#define MOTOR_MICROSTEPS 16
-#define MOTOR_POWER_MODE MOTOR_ALWAYS_POWERED // See stepper.c
+#define MOTOR_POWER_MODE MOTOR_POWERED_IN_CYCLE // See stepper.c
#define MOTOR_IDLE_TIMEOUT 2.00 // secs, motor off after this time
#define M1_MOTOR_MAP AXIS_X
/// motor control port bit positions
enum cfgPortBits {
- STEP_BIT_bp = 0, // bit 0
+ STEP_BIT_bp, // bit 0
DIRECTION_BIT_bp, // bit 1 (low = clockwise)
MOTOR_ENABLE_BIT_bp, // bit 2 (low = enabled)
CHIP_SELECT_BIT_bp, // bit 3
#include "config.h"
enum moveType { // bf->move_type values
- MOVE_TYPE_0 = 0, // null move - does a no-op
+ MOVE_TYPE_0, // null move - does a no-op
MOVE_TYPE_ALINE, // acceleration planned line
MOVE_TYPE_DWELL, // delay with no movement
MOVE_TYPE_COMMAND, // general command
};
enum moveState {
- MOVE_OFF = 0, // move inactive (MUST BE ZERO)
+ MOVE_OFF, // move inactive (MUST BE ZERO)
MOVE_NEW, // general value if you need an initialization
MOVE_RUN, // general run state (for non-acceleration moves)
MOVE_SKIP_BLOCK // mark a skipped block
};
enum moveSection {
- SECTION_HEAD = 0, // acceleration
+ SECTION_HEAD, // acceleration
SECTION_BODY, // cruise
SECTION_TAIL // deceleration
};
#define SECTIONS 3
enum sectionState {
- SECTION_OFF = 0, // section inactive
+ SECTION_OFF, // section inactive
SECTION_NEW, // uninitialized section
SECTION_1st_HALF, // first half of S curve
SECTION_2nd_HALF // second half of S curve or running a BODY (cruise)
// All the enums that equal zero must be zero. Don't change this
enum mpBufferState { // bf->buffer_state values
- MP_BUFFER_EMPTY = 0, // struct is available for use (MUST BE 0)
+ MP_BUFFER_EMPTY, // struct is available for use (MUST BE 0)
MP_BUFFER_LOADING, // being written ("checked out")
MP_BUFFER_QUEUED, // in queue
MP_BUFFER_PENDING, // marked as the next buffer to run
}
-float get_pos(int index) {
+float get_position(int index) {
return cm_get_absolute_position(0, index);
}
-float get_vel() {
+float get_velocity() {
return mp_get_runtime_velocity();
}
// update spindle speed if we're running
pwm_set_duty(PWM_1, cm_get_spindle_pwm(cm.gm.spindle_mode));
}
+
+
+float get_max_spin(int index) {
+ return 0;
+}
+
+
+void set_max_spin(int axis, float value) {
+}
+
+
+uint8_t get_spindle_type(int index) {
+ return 0;
+}
+
+
+void set_spindle_type(int axis, uint8_t value) {
+}
+
+
+float get_spin_min_pulse(int index) {
+ return 0;
+}
+
+
+void set_spin_min_pulse(int axis, float value) {
+}
+
+
+float get_spin_max_pulse(int index) {
+ return 0;
+}
+
+
+void set_spin_max_pulse(int axis, float value) {
+}
+
+
+uint8_t get_spin_polarity(int index) {
+ return 0;
+}
+
+
+void set_spin_polarity(int axis, uint8_t value) {
+}
+
+
+float get_spin_up(int index) {
+ return 0;
+}
+
+
+void set_spin_up(int axis, float value) {
+}
+
+
+float get_spin_down(int index) {
+ return 0;
+}
+
+
+void set_spin_down(int axis, float value) {
+}
for (int motor = 0; motor < MOTORS; motor++)
_update_steps_per_unit(motor);
- st_reset(); // reset steppers to known state
-}
-
-
-/// Return true if motors or dwell are running
-uint8_t st_runtime_isbusy() {return st_run.busy;}
-
-
-/// Reset stepper internals
-void st_reset() {
+ // reset steppers to known state
for (uint8_t motor = 0; motor < MOTORS; motor++) {
st_pre.mot[motor].prev_direction = STEP_INITIAL_DIRECTION;
st_pre.mot[motor].timer_clock = 0;
}
+/// Return true if motors or dwell are running
+uint8_t st_runtime_isbusy() {return st_run.busy;}
+
+
/// returns 1 if motor is enabled (motor is actually active low)
static uint8_t _motor_is_enabled(uint8_t motor) {
uint8_t port = motor < MOTORS ? hw.st_port[motor]->OUT : 0xff;
}
-/// Apply power to all motors
-void st_energize_motors() {
- for (uint8_t motor = 0; motor < MOTORS; motor++) {
- _energize_motor(motor);
- st_run.mot[motor].power_state = MOTOR_POWER_TIMEOUT_START;
- }
-}
-
-
-/// Remove power from all motors
-void st_deenergize_motors() {
- for (uint8_t motor = 0; motor < MOTORS; motor++)
- _deenergize_motor(motor);
-}
-
-
-
/// Callback to manage motor power sequencing
/// Handles motor power-down timing, low-power idle, and adaptive motor power
stat_t st_motor_power_callback() { // called by controller
}
-float get_ang(int index) {return st_cfg.mot[index].step_angle;}
-float get_trvl(int index) {return st_cfg.mot[index].travel_rev;}
-uint16_t get_mstep(int index) {return st_cfg.mot[index].microsteps;}
-bool get_pol(int index) {return st_cfg.mot[index].polarity;}
-uint16_t get_mvel(int index) {return 0;}
-uint16_t get_mjerk(int index) {return 0;}
-
-
static void _update_steps_per_unit(int motor) {
st_cfg.mot[motor].steps_per_unit =
(360 * st_cfg.mot[motor].microsteps) /
}
-void set_ang(int index, float value) {
+float get_step_angle(int index) {
+ return st_cfg.mot[index].step_angle;
+}
+
+
+void set_step_angle(int index, float value) {
st_cfg.mot[index].step_angle = value;
_update_steps_per_unit(index);
}
-void set_trvl(int index, float value) {
+float get_travel(int index) {
+ return st_cfg.mot[index].travel_rev;
+}
+
+
+void set_travel(int index, float value) {
st_cfg.mot[index].travel_rev = value;
_update_steps_per_unit(index);
}
-void set_mstep(int index, uint16_t value) {
+uint16_t get_microstep(int index) {
+ return st_cfg.mot[index].microsteps;
+}
+
+
+void set_microstep(int index, uint16_t value) {
switch (value) {
case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128: case 256:
break;
}
-void set_pol(int index, bool value) {
+uint8_t get_polarity(int index) {
+ if (index < 0 || MOTORS <= index) return 0;
+ return st_cfg.mot[index].polarity;
+}
+
+
+void set_polarity(int index, uint8_t value) {
st_cfg.mot[index].polarity = value;
}
-void set_mvel(int index, uint16_t value) {
+uint8_t get_motor_map(int index) {
+ return st_cfg.mot[index].motor_map;
+}
+
+
+void set_motor_map(int index, uint16_t value) {
+ if (value < AXES) st_cfg.mot[index].motor_map = value;
+}
+
+
+uint8_t get_power_mode(int index) {
+ return st_cfg.mot[index].power_mode;
}
-void set_mjerk(int index, uint16_t value) {
+void set_power_mode(int index, uint16_t value) {
+ if (value < MOTOR_POWER_MODE_MAX_VALUE)
+ st_cfg.mot[index].power_mode = value;
}
#include <stdbool.h>
enum prepBufferState {
- PREP_BUFFER_OWNED_BY_LOADER = 0, // staging buffer is ready for load
- PREP_BUFFER_OWNED_BY_EXEC // staging buffer is being loaded
+ PREP_BUFFER_OWNED_BY_LOADER, // staging buffer is ready for load
+ PREP_BUFFER_OWNED_BY_EXEC // staging buffer is being loaded
};
// In the future IDLE will be powered at a low, torque-maintaining current
// Used w/start and stop flags to sequence motor power
enum motorPowerState {
- MOTOR_OFF = 0, // motor stopped and deenergized
+ MOTOR_OFF, // motor stopped and deenergized
MOTOR_IDLE, // motor stopped and may be partially energized
MOTOR_RUNNING, // motor is running (and fully energized)
MOTOR_POWER_TIMEOUT_START, // transition state to start power-down timeout
enum cmMotorPowerMode {
- MOTOR_DISABLED = 0, // motor enable is deactivated
+ MOTOR_DISABLED, // motor enable is deactivated
MOTOR_ALWAYS_POWERED, // motor is always powered while machine is ON
MOTOR_POWERED_IN_CYCLE, // motor fully powered during cycles,
// de-powered out of cycle
/// Min/Max timeouts allowed for motor disable. Allow for inertial stop.
/// Must be non-zero
#define MOTOR_TIMEOUT_SECONDS_MIN (float)0.1
-/// For conversion to uint32_t (4294967295/1000)
+/// For conversion to uint32_t (4294967295 / 1000)
#define MOTOR_TIMEOUT_SECONDS_MAX (float)4294967
/// seconds in DISABLE_AXIS_WHEN_IDLE mode
#define MOTOR_TIMEOUT_SECONDS (float)0.1
// Per motor config structure
typedef struct cfgMotor {
uint8_t motor_map; // map motor to axis
- uint32_t microsteps; // microsteps to apply for each axis (ex: 8)
+ uint16_t microsteps; // microsteps to apply for each axis (ex: 8)
uint8_t polarity; // 0=normal polarity, 1=reverse motor direction
uint8_t power_mode; // See cmMotorPowerMode for enum
float step_angle; // degrees per whole step (ex: 1.8)
void stepper_init();
uint8_t st_runtime_isbusy();
-void st_reset();
-void st_energize_motors();
-void st_deenergize_motors();
stat_t st_motor_power_callback();
void st_request_exec_move();
/// Called from RTC for each RTC tick
void switch_rtc_callback() {
- for (uint8_t i = 0; i < NUM_SWITCHES; i++) {
+ for (uint8_t i = 0; i < SWITCHES; i++) {
if (sw.mode[i] == SW_MODE_DISABLED || sw.debounce[i] == SW_IDLE)
continue;
uint8_t get_switch_thrown() {return sw.sw_num_thrown;}
-// global switch type
-void set_switch_type(uint8_t switch_type) {sw.switch_type = switch_type;}
-uint8_t get_switch_type() {return sw.switch_type;}
-
-
/// reset all switches and reset limit flag
void reset_switches() {
- for (uint8_t i = 0; i < NUM_SWITCHES; i++) {
+ for (uint8_t i = 0; i < SWITCHES; i++) {
sw.debounce[i] = SW_IDLE;
read_switch(i);
}
/// read a switch directly with no interrupts or deglitching
uint8_t read_switch(uint8_t sw_num) {
- if (sw_num < 0 || sw_num >= NUM_SWITCHES) return SW_DISABLED;
+ if (sw_num < 0 || sw_num >= SWITCHES) return SW_DISABLED;
uint8_t read = 0;
switch (sw_num) {
return sw.state[sw_num];
}
+
+
+uint8_t get_switch_type(int index) {
+ return 0;
+}
+
+
+void set_switch_type(int axis, uint8_t value) {
+}
#pragma once
+#include "config.h"
+
#include <stdint.h>
// timer for debouncing switches
SW_MIN_Z,
SW_MAX_Z,
SW_MIN_A,
- SW_MAX_A,
- NUM_SWITCHES // must be last one. Used for array sizing and for loops
+ SW_MAX_A
};
#define SW_OFFSET SW_MAX_X // offset between MIN and MAX switches
-#define NUM_SWITCH_PAIRS (NUM_SWITCHES / 2)
+#define NUM_SWITCH_PAIRS (SWITCHES / 2)
/// Interrupt levels and vectors - The vectors are hard-wired to xmega ports
/// If you change axis port assignments you need to change these, too.
uint8_t limit_flag; // 1=limit switch thrown - do a lockout
uint8_t sw_num_thrown; // number of switch that was just thrown
/// 0=OPEN, 1=CLOSED (depends on switch type)
- uint8_t state[NUM_SWITCHES];
+ uint8_t state[SWITCHES];
/// 0=disabled, 1=homing, 2=homing+limit, 3=limit
- volatile uint8_t mode[NUM_SWITCHES];
+ volatile uint8_t mode[SWITCHES];
/// debouncer state machine - see swDebounce
- volatile uint8_t debounce[NUM_SWITCHES];
- volatile int8_t count[NUM_SWITCHES]; // deglitching and lockout counter
+ volatile uint8_t debounce[SWITCHES];
+ volatile int8_t count[SWITCHES]; // deglitching and lockout counter
};
struct swStruct sw;
uint8_t get_switch_thrown();
void reset_switches();
void sw_show_switch();
-
-void set_switch_type(uint8_t switch_type);
-uint8_t get_switch_type();
-
-
#include <stdio.h>
-void set_dcur(int driver, float value);
+void set_power_level(int driver, float value);
typedef enum {
TMC2660_SGCSCONF_THRESH(63);
drivers[i].regs[TMC2660_DRVCONF] = TMC2660_DRVCONF_RDSEL_SG;
- set_dcur(i, MOTOR_CURRENT);
+ set_power_level(i, MOTOR_CURRENT);
drivers[driver].reset = 0; // No need to reset
}
}
-uint8_t get_dflags(int driver) {return drivers[driver].flags;}
+uint8_t get_status_flags(int index) {
+ return drivers[driver].flags;
+}
-float get_dcur(int driver) {
- uint8_t x = drivers[driver].regs[TMC2660_SGCSCONF] & 31;
+float get_power_level(int index) {
+ uint8_t x = drivers[index].regs[TMC2660_SGCSCONF] & 31;
return (x + 1) / 32.0;
}
-void set_dcur(int driver, float value) {
+void set_power_level(int index, float value) {
if (value < 0 || 1 < value) return;
uint8_t x = value ? value * 32.0 - 1 : 0;
if (x < 0) x = 0;
- tmc2660_driver_t *d = &drivers[driver];
+ tmc2660_driver_t *d = &drivers[index];
d->regs[TMC2660_SGCSCONF] = (d->regs[TMC2660_SGCSCONF] & ~31) | x;
- tmc2660_reset(driver);
+ tmc2660_reset(index);
}
-uint16_t get_sguard(int driver) {
- return drivers[driver].sguard;
+uint16_t get_sg_value(int index) {
+ return drivers[index].sguard;
}
-int8_t get_sgt(int driver) {
- uint8_t x = (drivers[driver].regs[TMC2660_SGCSCONF] & 0x7f) >> 8;
+int8_t get_stallguard(int index) {
+ uint8_t x = (drivers[index].regs[TMC2660_SGCSCONF] & 0x7f) >> 8;
return (x & (1 << 6)) ? (x & 0xc0) : x;
}
-void set_sgt(int driver, int8_t value) {
+void set_stallguard(int index, int8_t value) {
if (value < -64 || 63 < value) return;
- tmc2660_driver_t *d = &drivers[driver];
+ tmc2660_driver_t *d = &drivers[index];
d->regs[TMC2660_SGCSCONF] = (d->regs[TMC2660_SGCSCONF] & ~31) |
TMC2660_SGCSCONF_THRESH(value);
- tmc2660_reset(driver);
+ tmc2660_reset(index);
}
#include <math.h>
#include <avr/pgmspace.h>
+#include <avr/wdt.h>
// Type names
static const char bool_name [] PROGMEM = "<bool>";
MAP(TYPE_NAME, SEMI, string, float, int8_t, uint8_t, uint16_t);
-static void var_print_bool(bool x) {
- printf_P(x ? PSTR("true") : PSTR("false"));
-}
-
-
static void var_print_float(float x) {
char buf[20];
}
-static bool var_parse_bool(const char *value) {
- return strcmp_P(value, PSTR("false"));
-}
-
-
static float var_parse_float(const char *value) {
return strtod(value, 0);
}
return strtol(value, 0, 0);
}
+static uint8_t var_parse_uint8_t(const char *value) {
+ return strtol(value, 0, 0);
+}
+
static uint16_t var_parse_uint16_t(const char *value) {
return strtol(value, 0, 0);
// Var forward declarations
-#define VAR(NAME, TYPE, INDEX, SET, ...) \
+#define VAR(NAME, CODE, TYPE, INDEX, SET, ...) \
TYPE get_##NAME(IF(INDEX)(int index)); \
IF(SET) \
(void set_##NAME(IF(INDEX)(int index,) TYPE value);)
#undef VAR
// Var names, count & help
-#define VAR(NAME, TYPE, INDEX, SET, DEFAULT, HELP) \
- static const char NAME##_name[] PROGMEM = #NAME; \
- static const int NAME##_count = INDEX ? INDEX : 1; \
+#define VAR(NAME, CODE, TYPE, INDEX, SET, DEFAULT, HELP) \
+ static const char NAME##_name[] PROGMEM = #NAME; \
+ static const int NAME##_count = INDEX ? INDEX : 1; \
static const char NAME##_help[] PROGMEM = HELP;
#include "vars.def"
#undef VAR
// Last value
-#define VAR(NAME, TYPE, INDEX, ...) \
+#define VAR(NAME, CODE, TYPE, INDEX, ...) \
static TYPE NAME##_last IF(INDEX)([INDEX]);
#include "vars.def"
void vars_init() {
-#define VAR(NAME, TYPE, INDEX, SET, DEFAULT, ...) \
+#define VAR(NAME, CODE, TYPE, INDEX, SET, DEFAULT, ...) \
IF(SET) \
(IF(INDEX)(for (int i = 0; i < INDEX; i++)) { \
set_##NAME(IF(INDEX)(i,) DEFAULT); \
void vars_report(bool full) {
bool reported = false;
- static const char value_fmt[] PROGMEM = "\"%S\":";
- static const char index_value_fmt[] PROGMEM = "\"%S%c\":";
+ static const char value_fmt[] PROGMEM = "\"%s\":";
+ static const char index_value_fmt[] PROGMEM = "\"%c%s\":";
-#define VAR(NAME, TYPE, INDEX, ...) \
+#define VAR(NAME, CODE, TYPE, INDEX, ...) \
IF(INDEX)(for (int i = 0; i < NAME##_count; i++)) { \
TYPE value = get_##NAME(IF(INDEX)(i)); \
\
\
printf_P \
(IF_ELSE(INDEX)(index_value_fmt, value_fmt), \
- NAME##_name IF(INDEX)(, INDEX##_LABEL[i])); \
+ IF(INDEX)(INDEX##_LABEL[i],) CODE); \
\
var_print_##TYPE(value); \
} \
+ wdt_reset(); \
}
#include "vars.def"
}
-void vars_set(const char *name, const char *value) {
+bool vars_set(const char *name, const char *value) {
uint8_t i;
unsigned len = strlen(name);
- if (!len) return;
-#define VAR(NAME, TYPE, INDEX, SET, ...) \
+ if (!len) return false;
+
+#define VAR(NAME, CODE, TYPE, INDEX, SET, ...) \
IF(SET) \
- (if (!strncmp_P(name, NAME##_name, IF_ELSE(INDEX)(len - 1, len))) { \
+ (if (!strcmp(IF_ELSE(INDEX)(name + 1, name), CODE)) { \
IF(INDEX) \
- (i = strchr(INDEX##_LABEL, name[len - 1]) - INDEX##_LABEL; \
- if (INDEX <= i) return); \
+ (i = strchr(INDEX##_LABEL, name[0]) - INDEX##_LABEL; \
+ if (INDEX <= i) return false); \
\
set_##NAME(IF(INDEX)(i ,) var_parse_##TYPE(value)); \
\
- return; \
- })
+ return true; \
+ }) \
#include "vars.def"
#undef VAR
+
+ return false;
}
void vars_print_help() {
- static const char fmt[] PROGMEM = " %-8S %-10S %S\n";
+ static const char fmt[] PROGMEM = " $%-5s %-14S %-12S %S\n";
-#define VAR(NAME, TYPE, ...) \
- printf_P(fmt, NAME##_name, TYPE##_name, NAME##_help);
+#define VAR(NAME, CODE, TYPE, ...) \
+ printf_P(fmt, CODE, NAME##_name, TYPE##_name, NAME##_help); \
+ wdt_reset();
#include "vars.def"
#undef VAR
}
\******************************************************************************/
-#define MOTORS_LABEL "xyzabcuvw"
-
-// VAR(name, type, index, settable, default, help)
-VAR(pos, float, MOTORS, 0, 0, "Current axis position")
-VAR(vel, float, 0, 0, 0, "Current velocity")
-VAR(ang, float, MOTORS, 1, 0, "Rotation angle in deg per full step")
-VAR(trvl, float, MOTORS, 1, 0, "Travel in mm per revolution")
-VAR(mstep, uint16_t, MOTORS, 1, 0, "Microsteps per full step")
-VAR(pol, bool, MOTORS, 1, 0, "Normal or reversed")
-VAR(mvel, uint16_t, MOTORS, 1, 0, "Maxium velocity in mm/min")
-VAR(mjerk, uint16_t, MOTORS, 1, 0, "Maxium jerk in m/min^3")
-
-// Motor driver
-VAR(dflags, uint8_t, MOTORS, 0, 0, "Current motor status flags")
-VAR(dcur, float, MOTORS, 1, 0, "Driver current as a percentage")
-VAR(sguard, uint16_t, MOTORS, 0, 0, "Driver StallGuard reading")
-VAR(sgt, int8_t, MOTORS, 1, 0, "Driver StallGuard threshold -64 to 63")
+#define AXES_LABEL "xyzabcuvw"
+#define MOTORS_LABEL "1234"
+#define SWITCHES_LABEL "12345678"
+
+// VAR(name, code, type, index, settable, default, help)
+
+// Motor
+VAR(motor_map, "ma", uint8_t, MOTORS, 1, 0, "Motor to axis mapping")
+VAR(step_angle, "sa", float, MOTORS, 1, 0, "In degrees per full step")
+VAR(travel, "tr", float, MOTORS, 1, 0, "Travel in mm per revolution")
+VAR(microstep, "mi", uint16_t, MOTORS, 1, 0, "Microsteps per full step")
+VAR(polarity, "po", uint8_t, MOTORS, 1, 0, "Normal or reversed")
+
+VAR(power_mode, "pm", uint8_t, MOTORS, 1, 0, "Motor power mode")
+VAR(power_level, "pl", float, MOTORS, 1, 0, "Motor current")
+VAR(stallguard, "sg", int8_t, MOTORS, 1, 0, "StallGuard threshold")
+VAR(sg_value, "sgv", uint16_t, MOTORS, 0, 0, "StallGuard reading")
+VAR(status_flags, "sf", uint8_t, MOTORS, 0, 0, "Motor status flags")
+
+// Axis
+VAR(position, "p", float, AXES, 0, 0, "Current axis position")
+VAR(axis_mode, "am", uint8_t, AXES, 1, 0, "Axis mode")
+VAR(max_velocity, "vm", float, AXES, 1, 0, "Maxium velocity in mm/min")
+VAR(max_feedrate, "fr", float, AXES, 1, 0, "Maxium feedrate in mm/min")
+VAR(max_jerk, "jm", float, AXES, 1, 0, "Maxium jerk in mm/min^3")
+VAR(junction_dev, "jd", float, AXES, 1, 0, "Junction deviation")
+
+VAR(travel_min, "tn", float, AXES, 1, 0, "Minimum soft limit")
+VAR(travel_max, "tm", float, AXES, 1, 0, "Maximum soft limit")
+VAR(min_switch, "sn", uint8_t, AXES, 1, 0, "Minimum switch's ID")
+VAR(max_switch, "sx", uint8_t, AXES, 1, 0, "Maximum switch's ID")
+
+VAR(jerk_homing, "jh", float, AXES, 1, 0, "Maxium homing jerk")
+VAR(search_vel, "sv", float, AXES, 1, 0, "Homing search velocity")
+VAR(latch_vel, "lv", float, AXES, 1, 0, "Homing latch velocity")
+VAR(latch_backoff, "lb", float, AXES, 1, 0, "Homing latch backof")
+VAR(zero_backoff, "zb", float, AXES, 1, 0, "Homing zero backof")
+
+// Spindle
+VAR(max_spin, "ss", float, 0, 1, 0, "Maximum spindle speed")
+VAR(spindle_type, "st", uint8_t, 0, 1, 0, "RS485 or PWM")
+VAR(spin_min_pulse, "np", float, 0, 1, 0, "Minimum pulse width")
+VAR(spin_max_pulse, "mp", float, 0, 1, 0, "Maximum pulse width")
+VAR(spin_polarity, "sp", uint8_t, 0, 1, 0, "Normal or reversed")
+VAR(spin_up, "su", float, 0, 1, 0, "Spin up velocity")
+VAR(spin_down, "sd", float, 0, 1, 0, "Spin down velocity")
+
+// Switches
+VAR(switch_type, "sw", uint8_t, SWITCHES, 1, 0, "Normally open or closed")
+
+// System
+VAR(velocity, "v", float, 0, 0, 0, "Current velocity")
void vars_init();
void vars_report(bool full);
-void vars_set(const char *name, const char *value);
+bool vars_set(const char *name, const char *value);
int vars_parser(char *vars);
void vars_print_help();