diff --git a/README.md b/README.md index 4fc8dd7..64c6bf9 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ It has been written to complement grblHAL and has features such as proper keyboa --- -Latest build date is 20210803, see the [changelog](changelog.md) for details. +Latest build date is 20210819, see the [changelog](changelog.md) for details. +__NOTE:__ Drivers built with more than three axes configured \(`N_AXIS` > `3`\) will force a settings reset when upgraded. Backup and restore of settings is recommended for these. --- diff --git a/changelog.md b/changelog.md index 70a833a..18f69ed 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,21 @@ ## grblHAL changelog +Build 20210819: + +Core: +* Added `$376` setting for designating ABC-axes individually as rotational. +__NOTE:__ This setting is only available when N_AXIS is > 3 and will force a settings reset on an upgrade for such configurations. Backup and restore settings when upgrading! +Scaling from inches to mm is disabled for axes designated as rotational, no other processing takes place. +* Added `$ESG` and `$ESH` system commands for outputting current setting definitions in [Grbl csv-format](https://github.com/gnea/grbl/tree/master/doc/csv) and grblHAL tab-format respectively. +Only settings valid in the active configuration will be outputted, driver and plugin specific settings will be added as well - even from well behaved third party code. +* Added setting descriptions to most core/driver/plugin settings. Third party drivers and plugins may also add descriptions to any settings implementented. +NOTE: Drivers for processors with limited flash may not have the descriptions compiled in. +* Added `$SED=` for outputting a description for setting `` (if available), e.g. issue `$SED=14` to get a description for `$14`. The description is formatted for sender use. + +Drivers & plugins: +* Cleaned up/simplified many pin mapping files, mostly by moving pin to bit transforms to a common preprocessor file. +* Some general driver and plugin improvements, e.g. more flexible spindle PWM to pin mappings for STM32F4xx and STM32F7xx drivers. + Build 20210803: Core: diff --git a/config.h b/config.h index 31bb891..b7f1525 100644 --- a/config.h +++ b/config.h @@ -400,6 +400,12 @@ __NOTE:__ these definitions are only referenced in this file. Do __NOT__ change! //#define DEFAULT_STEPPING_INVERT_MASK 0 //#define DEFAULT_DIRECTION_INVERT_MASK 0 +// Designate ABC axes as rotational. This will disable scaling (to mm) in inches mode. +// Set steps/mm for the axes to the value that represent the desired movement per unit. +// For the controller the distance is unitless and and can be in degrees, radians, rotations, ... +// NOTE: $376 can be used to configure rotational axes at run-time. +//#define ST_ROTATIONAL_MASK (A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT) // Default disabled. Uncomment and possibly remove axis bit(s) as needed to enable. + // Inverts logic of the input signals based on a mask. This essentially means you are using // normally-open (NO) switches on the specified pins, rather than the default normally-closed (NC) switches. // NOTE: The first option will invert all control pins. The second option is an example of diff --git a/defaults.h b/defaults.h index c917234..baa0972 100644 --- a/defaults.h +++ b/defaults.h @@ -557,6 +557,10 @@ #define ST_DEENERGIZE_MASK 0 #endif +#ifndef ST_ROTATIONAL_MASK +#define ST_ROTATIONAL_MASK 0 +#endif + #ifndef INVERT_ST_ENABLE_MASK #define INVERT_ST_ENABLE_MASK 0 #endif diff --git a/driver_opts.h b/driver_opts.h index 7d00305..36bb210 100644 --- a/driver_opts.h +++ b/driver_opts.h @@ -141,6 +141,12 @@ #define LIMITS_OVERRIDE_ENABLE 0 #endif +#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN +#define SAFETY_DOOR_ENABLE 1 +#else +#define SAFETY_DOOR_ENABLE 0 +#endif + #ifndef ESTOP_ENABLE #if COMPATIBILITY_LEVEL <= 1 #define ESTOP_ENABLE 1 diff --git a/gcode.c b/gcode.c index db35e66..c6a4ee3 100644 --- a/gcode.c +++ b/gcode.c @@ -1362,8 +1362,11 @@ status_code_t gc_execute_block(char *block, char *message) uint_fast8_t idx = N_AXIS; if (gc_block.modal.units_imperial) do { // Axes indices are consistent, so loop may be used. idx--; -// if (bit_istrue(axis_words.mask, bit(idx)) && bit_isfalse(settings.steppers.is_rotational.mask, bit(idx))) +#if N_AXIS > 3 + if (bit_istrue(axis_words.mask, bit(idx)) && bit_isfalse(settings.steppers.is_rotational.mask, bit(idx))) +#else if (bit_istrue(axis_words.mask, bit(idx))) +#endif gc_block.values.xyz[idx] *= MM_PER_INCH; } while(idx); @@ -2087,7 +2090,6 @@ status_code_t gc_execute_block(char *block, char *message) idx = 3; do { // Axes indices are consistent, so loop may be used to save flash space. idx--; -// if (ijk_words.mask & bit(idx) && bit_isfalse(settings.steppers.is_rotational.mask, bit(idx))) if (ijk_words.mask & bit(idx)) gc_block.values.ijk[idx] *= MM_PER_INCH; } while(idx); diff --git a/grbl.h b/grbl.h index cd08323..1d4ab83 100644 --- a/grbl.h +++ b/grbl.h @@ -34,7 +34,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_VERSION_BUILD "20210809" +#define GRBL_VERSION_BUILD "20210819" // The following symbols are set here if not already set by the compiler or in config.h // Do NOT change here! diff --git a/grbllib.c b/grbllib.c index b72d1e7..9765f06 100644 --- a/grbllib.c +++ b/grbllib.c @@ -34,6 +34,7 @@ #include "report.h" #include "state_machine.h" #include "nvs_buffer.h" +#include "stream.h" #ifdef ENABLE_BACKLASH_COMPENSATION #include "motion_control.h" #endif @@ -53,16 +54,6 @@ struct system sys = {0}; //!< System global variable structure. grbl_t grbl; grbl_hal_t hal; -// called from stream drivers while tx is blocking, return false to terminate - -static bool stream_tx_blocking (void) -{ - // TODO: Restructure st_prep_buffer() calls to be executed here during a long print. - - grbl.on_execute_realtime(state_get()); - - return !(sys.rt_exec_state & EXEC_RESET); -} #ifdef KINEMATICS_API diff --git a/motor_pins.h b/motor_pins.h index 996524f..d2b089e 100644 --- a/motor_pins.h +++ b/motor_pins.h @@ -566,7 +566,7 @@ #define Z_LIMIT_BIT (1<= 6 && !defined(C_LIMIT_BIT) -#ifdef A_LIMIT_PIN -#define C_LIMIT_BIT (1<. +*/ + +#ifdef CONTROL_PORT +#ifndef RESET_PORT +#define RESET_PORT CONTROL_PORT +#endif +#ifndef FEED_HOLD_PORT +#define FEED_HOLD_PORT CONTROL_PORT +#endif +#ifndef CYCLE_START_PORT +#define CYCLE_START_PORT CONTROL_PORT +#endif +#if SAFETY_DOOR_ENABLE && !defined(SAFETY_DOOR_PORT) +#define SAFETY_DOOR_PORT CONTROL_PORT +#endif +#endif + +#ifndef RESET_BIT +#define RESET_BIT (1<id + offset)); + hal.stream.write(": "); + if(setting->group == Group_Axis0) + hal.stream.write(axis_letter[offset]); + hal.stream.write(setting->name[0] == '?' ? &setting->name[1] : setting->name); // temporary hack for ? prefix... - hal.stream.write(uitoa(setting->id + offset)); + switch(setting_datatype_to_external(setting->datatype)) { - if(human_readable) { - hal.stream.write(": "); - if(setting->group == Group_Axis0) - hal.stream.write(axis_letter[offset]); - hal.stream.write(setting->name[0] == '?' ? &setting->name[1] : setting->name); // temporary hack for ? prefix... + case Format_AxisMask: + hal.stream.write(" as axismask"); + break; - switch(setting_datatype_to_external(setting->datatype)) { + case Format_Bool: + hal.stream.write(" as boolean"); + break; - case Format_AxisMask: - hal.stream.write(" as axismask"); - break; + case Format_Bitfield: + hal.stream.write(" as bitfield:"); + report_bitfield(setting->format, true); + break; - case Format_Bool: - hal.stream.write(" as boolean"); - break; + case Format_XBitfield: + hal.stream.write(" as bitfield where setting bit 0 enables the rest:"); + report_bitfield(setting->format, true); + break; - case Format_Bitfield: - hal.stream.write(" as bitfield:"); - report_bitfield(setting->format, true); - break; + case Format_RadioButtons: + hal.stream.write(":"); + report_bitfield(setting->format, false); + break; - case Format_XBitfield: - hal.stream.write(" as bitfield where setting bit 0 enables the rest:"); - report_bitfield(setting->format, true); - break; + case Format_IPv4: + hal.stream.write(" as IP address"); + break; - case Format_RadioButtons: - hal.stream.write(":"); - report_bitfield(setting->format, false); - break; + default: + if(setting->unit) { + hal.stream.write(" in "); + hal.stream.write(setting->unit); + } + break; + } - case Format_IPv4: - hal.stream.write(" as IP address"); - break; - - default: - if(setting->unit) { - hal.stream.write(" in "); - hal.stream.write(setting->unit); - } - break; - } - - if(setting->min_value && setting->max_value) { - hal.stream.write(", range: "); - hal.stream.write(setting->min_value); - hal.stream.write(" - "); - hal.stream.write(setting->max_value); - } else if(!setting_is_list(setting)) { - if(setting->min_value) { - hal.stream.write(", min: "); + if(setting->min_value && setting->max_value) { + hal.stream.write(", range: "); hal.stream.write(setting->min_value); - } - if(setting->max_value) { - hal.stream.write(", max: "); + hal.stream.write(" - "); hal.stream.write(setting->max_value); + } else if(!setting_is_list(setting)) { + if(setting->min_value) { + hal.stream.write(", min: "); + hal.stream.write(setting->min_value); + } + if(setting->max_value) { + hal.stream.write(", max: "); + hal.stream.write(setting->max_value); + } } - } - } else { - hal.stream.write(vbar); - hal.stream.write(uitoa(setting->group + (setting->group == Group_Axis0 ? offset : 0))); - hal.stream.write(vbar); - if(setting->group == Group_Axis0) - hal.stream.write(axis_letter[offset]); - hal.stream.write(setting->name[0] == '?' ? &setting->name[1] : setting->name); // temporary hack for ? prefix... - hal.stream.write(vbar); - if(setting->unit) - hal.stream.write(setting->unit); - hal.stream.write(vbar); - hal.stream.write(uitoa(setting_datatype_to_external(setting->datatype))); - hal.stream.write(vbar); - if(setting->format) - hal.stream.write(setting->format); - hal.stream.write(vbar); - if(setting->min_value && !setting_is_list(setting)) - hal.stream.write(setting->min_value); - hal.stream.write(vbar); - if(setting->max_value) - hal.stream.write(setting->max_value); - } + break; - if(!human_readable) - hal.stream.write("]"); + case SettingsFormat_MachineReadable: + hal.stream.write("[SETTING:"); + hal.stream.write(uitoa(setting->id + offset)); + hal.stream.write(vbar); + hal.stream.write(uitoa(setting->group + (setting->group == Group_Axis0 ? offset : 0))); + hal.stream.write(vbar); + if(setting->group == Group_Axis0) + hal.stream.write(axis_letter[offset]); + hal.stream.write(setting->name[0] == '?' ? &setting->name[1] : setting->name); // temporary hack for ? prefix... + hal.stream.write(vbar); + if(setting->unit) + hal.stream.write(setting->unit); + hal.stream.write(vbar); + hal.stream.write(uitoa(setting_datatype_to_external(setting->datatype))); + hal.stream.write(vbar); + if(setting->format) + hal.stream.write(setting->format); + hal.stream.write(vbar); + if(setting->min_value && !setting_is_list(setting)) + hal.stream.write(setting->min_value); + hal.stream.write(vbar); + if(setting->max_value) + hal.stream.write(setting->max_value); + hal.stream.write("]"); + break; + + case SettingsFormat_Grbl: + hal.stream.write("\""); + hal.stream.write(uitoa(setting->id + offset)); + hal.stream.write("\",\""); + if(setting->group == Group_Axis0) + hal.stream.write(axis_letter[offset]); + hal.stream.write(setting->name[0] == '?' ? &setting->name[1] : setting->name); // temporary hack for ? prefix... + if(setting->unit) { + hal.stream.write("\",\""); + hal.stream.write(setting->unit); + } else // TODO: output sensible unit from datatype + hal.stream.write("\",\""); +#ifndef NO_SETTINGS_DESCRIPTIONS + hal.stream.write("\",\""); + report_setting_description(format, (setting_id_t)(setting->id + offset)); + hal.stream.write("\""); +#else + hal.stream.write("\",\"\""); +#endif + break; + + case SettingsFormat_grblHAL: + hal.stream.write(uitoa(setting->id + offset)); + + hal.stream.write("\t"); + + if(setting->group == Group_Axis0) + hal.stream.write(axis_letter[offset]); + hal.stream.write(setting->name[0] == '?' ? &setting->name[1] : setting->name); // temporary hack for ? prefix... + + hal.stream.write("\t"); + + if(setting->unit) + hal.stream.write(setting->unit); + else if(setting->datatype == Format_AxisMask || setting->datatype == Format_Bitfield || setting->datatype == Format_XBitfield) + hal.stream.write("mask"); + else if(setting->datatype == Format_Bool) + hal.stream.write("boolean"); + else if(setting->datatype == Format_RadioButtons) + hal.stream.write("integer"); + + hal.stream.write("\t"); +/* + Format_Bool = 0, + Format_Bitfield, + Format_XBitfield, + Format_RadioButtons, + Format_AxisMask, + Format_Integer, // 32 bit + , + Format_String, + Format_Password, + Format_IPv4, + // For internal use only + Format_Int8, + Format_Int16, +*/ + switch(setting_datatype_to_external(setting->datatype)) { + + case Format_Integer: + hal.stream.write("integer"); + break; + + case Format_Decimal: + hal.stream.write("float"); + break; + + case Format_Bool: + hal.stream.write("bool"); + break; + + case Format_AxisMask: + case Format_Bitfield: + hal.stream.write("bitfield"); + break; + + case Format_XBitfield: + hal.stream.write("xbitfield"); + break; + + case Format_RadioButtons: + hal.stream.write("radiobuttons"); + break; + + case Format_IPv4: + hal.stream.write("ipv4"); + break; + + case Format_String: + hal.stream.write("string"); + break; + + case Format_Password: + hal.stream.write("password"); + break; + + default: + break; + } + + hal.stream.write("\t"); + + if(setting->format) + hal.stream.write(setting->format); + else if (setting->datatype == Format_AxisMask) + hal.stream.write("axes"); + + hal.stream.write("\t"); + +#ifndef NO_SETTINGS_DESCRIPTIONS + report_setting_description(format, (setting_id_t)(setting->id + offset)); +#endif + hal.stream.write("\t"); + + if(setting->min_value) + hal.stream.write(setting->min_value); + + hal.stream.write("\t"); + + if(setting->max_value) + hal.stream.write(setting->max_value); + break; + } hal.stream.write(ASCII_EOL); } typedef struct { - bool human_readable; + settings_format_t format; setting_group_t group; uint_fast16_t offset; } report_args_t; @@ -1482,12 +1609,12 @@ typedef struct { static bool print_sorted (const setting_detail_t *setting, uint_fast16_t offset, void *args) { if(!(((report_args_t *)args)->group == setting->group && ((report_args_t *)args)->offset != offset)) - report_settings_detail (((report_args_t *)args)->human_readable, setting, offset); + report_settings_detail (((report_args_t *)args)->format, setting, offset); return true; } -static status_code_t sort_settings_details (bool human_readable, setting_group_t group) +static status_code_t sort_settings_details (settings_format_t format, setting_group_t group) { bool reported = group == Group_All; @@ -1498,7 +1625,7 @@ static status_code_t sort_settings_details (bool human_readable, setting_group_t args.group = settings_normalize_group(group); args.offset = group - args.group; - args.human_readable = human_readable; + args.format = format; while(details->on_get_settings) { details = details->on_get_settings(); @@ -1537,6 +1664,11 @@ static status_code_t sort_settings_details (bool human_readable, setting_group_t qsort(all_settings, n_settings, sizeof(setting_detail_t *), cmp_settings); + if(format == SettingsFormat_Grbl) + hal.stream.write("\"$-Code\",\" Setting\",\" Units\",\" Setting Description\"" ASCII_EOL); + else if(format == SettingsFormat_grblHAL) + hal.stream.write("$-Code\tSetting\tUnits\tDatatype\tData format\tSetting Description\tMin\tMax" ASCII_EOL); + for(idx = 0; idx < n_settings; idx++) { if(settings_iterator(all_settings[idx], print_sorted, &args)) reported = true; @@ -1552,16 +1684,16 @@ static bool print_unsorted (const setting_detail_t *setting, uint_fast16_t offse { if(!(((report_args_t *)args)->group == setting->group && ((report_args_t *)args)->offset != offset) && (setting->is_available == NULL ||setting->is_available(setting))) - report_settings_detail(((report_args_t *)args)->human_readable, setting, offset); + report_settings_detail(((report_args_t *)args)->format, setting, offset); return true; } -static status_code_t print_settings_details (bool human_readable, setting_group_t group, uint_fast16_t axis_rpt) +static status_code_t print_settings_details (settings_format_t format, setting_group_t group, uint_fast16_t axis_rpt) { status_code_t status; - if((status = sort_settings_details(human_readable, group)) != Status_Unhandled) + if((status = sort_settings_details(format, group)) != Status_Unhandled) return status; bool reported = group == Group_All; @@ -1572,7 +1704,7 @@ static status_code_t print_settings_details (bool human_readable, setting_group_ args.group = settings_normalize_group(group); args.offset = group - args.group; - args.human_readable = human_readable; + args.format = format; do { for(idx = 0; idx < settings->n_settings; idx++) { @@ -1590,7 +1722,7 @@ static status_code_t print_settings_details (bool human_readable, setting_group_ return reported ? Status_OK : Status_SettingDisabled; } -status_code_t report_settings_details (bool human_readable, setting_id_t id, setting_group_t group) +status_code_t report_settings_details (settings_format_t format, setting_id_t id, setting_group_t group) { uint_fast16_t axis_rpt = 0; @@ -1600,16 +1732,52 @@ status_code_t report_settings_details (bool human_readable, setting_id_t id, set const setting_detail_t *setting = setting_get_details(id, NULL); if(setting) - report_settings_detail(human_readable, setting, id - setting->id); + report_settings_detail(format, setting, id - setting->id); else status = Status_SettingDisabled; return status; } - return print_settings_details(human_readable, group, axis_rpt); + return print_settings_details(format, group, axis_rpt); } +#ifndef NO_SETTINGS_DESCRIPTIONS + +status_code_t report_setting_description (settings_format_t format, setting_id_t id) +{ + uint_fast16_t idx; + const char *description = NULL; + setting_details_t *settings = settings_get_details(); + const setting_detail_t *setting = setting_get_details(id, NULL); + + if(setting) do { + if(settings->descriptions) { + idx = settings->n_descriptions; + do { + if(settings->descriptions[--idx].id == setting->id) + description = settings->descriptions[idx].description; + } while(idx && description == NULL); + } + settings = settings->on_get_settings ? settings->on_get_settings() : NULL; + } while(settings && description == NULL); + + if(format == SettingsFormat_MachineReadable) { + hal.stream.write("[SETTINGDESCR:"); + hal.stream.write(uitoa(id)); + hal.stream.write(vbar); + } +// hal.stream.write(description == NULL ? (is_setting_available(setting_get_details(id, NULL)) ? "" : "N/A") : description); // TODO? + hal.stream.write(description == NULL ? (setting_get_details(id, NULL) ? "" : "N/A") : description); + + if(format == SettingsFormat_MachineReadable) + hal.stream.write("]" ASCII_EOL); + + return Status_OK; +} + +#endif + status_code_t report_alarm_details (void) { uint_fast16_t idx, n_alarms = sizeof(alarm_detail) / sizeof(alarm_detail_t); diff --git a/report.h b/report.h index 6185841..4025718 100644 --- a/report.h +++ b/report.h @@ -32,6 +32,13 @@ typedef enum { Message_Warning } message_type_t; +typedef enum { + SettingsFormat_MachineReadable = 0, + SettingsFormat_HumanReadable, + SettingsFormat_Grbl, + SettingsFormat_grblHAL +} settings_format_t; + // Initialize reporting subsystem void report_init (void); void report_init_fns (void); @@ -89,7 +96,10 @@ void report_build_info (char *line, bool extended); status_code_t report_alarm_details (void); status_code_t report_error_details (void); status_code_t report_setting_group_details (bool by_id, char *prefix); -status_code_t report_settings_details (bool human_readable, setting_id_t setting, setting_group_t group); +status_code_t report_settings_details (settings_format_t format, setting_id_t setting, setting_group_t group); +#ifndef NO_SETTINGS_DESCRIPTIONS +status_code_t report_setting_description (settings_format_t format, setting_id_t id); +#endif status_code_t report_last_signals_event (sys_state_t state, char *args); status_code_t report_current_limit_state (sys_state_t state, char *args); diff --git a/settings.c b/settings.c index ad3f9cf..c328a5f 100644 --- a/settings.c +++ b/settings.c @@ -100,7 +100,9 @@ PROGMEM const settings_t defaults = { .steppers.dir_invert.mask = DEFAULT_DIRECTION_INVERT_MASK, .steppers.enable_invert.mask = INVERT_ST_ENABLE_MASK, .steppers.deenergize.mask = ST_DEENERGIZE_MASK, -// .steppers.is_rotational.mask = 0, +#if N_AXIS > 3 + .steppers.is_rotational.mask = (ST_ROTATIONAL_MASK & AXES_BITMASK) >> 3, +#endif #if DEFAULT_HOMING_ENABLE .homing.flags.enabled = DEFAULT_HOMING_ENABLE, .homing.flags.init_lock = DEFAULT_HOMING_INIT_LOCK, @@ -281,39 +283,39 @@ PROGMEM const settings_t defaults = { }; PROGMEM static const setting_group_detail_t setting_group_detail [] = { - { Group_Root, Group_Root, "Root"}, - { Group_Root, Group_General, "General"}, - { Group_Root, Group_ControlSignals, "Control signals"}, - { Group_Root, Group_Limits, "Limits"}, - { Group_Limits, Group_Limits_DualAxis, "Dual axis"}, - { Group_Root, Group_Coolant, "Coolant"}, - { Group_Root, Group_Spindle, "Spindle"}, - { Group_Spindle, Group_Spindle_Sync, "Spindle sync"}, - { Group_Root, Group_Toolchange, "Tool change"}, - { Group_Root, Group_Homing, "Homing"}, - { Group_Root, Group_Probing, "Probing"}, - { Group_Root, Group_SafetyDoor, "Safety door"}, - { Group_Root, Group_Jogging, "Jogging"}, - { Group_Root, Group_Stepper, "Stepper"}, - { Group_Root, Group_MotorDriver, "Stepper driver"}, - { Group_Root, Group_Axis, "Axis"}, - { Group_Axis, Group_XAxis, "X-axis"}, - { Group_Axis, Group_YAxis, "Y-axis"}, - { Group_Axis, Group_ZAxis, "Z-axis"}, + { Group_Root, Group_Root, "Root"}, + { Group_Root, Group_General, "General"}, + { Group_Root, Group_ControlSignals, "Control signals"}, + { Group_Root, Group_Limits, "Limits"}, + { Group_Limits, Group_Limits_DualAxis, "Dual axis"}, + { Group_Root, Group_Coolant, "Coolant"}, + { Group_Root, Group_Spindle, "Spindle"}, + { Group_Spindle, Group_Spindle_Sync, "Spindle sync"}, + { Group_Root, Group_Toolchange, "Tool change"}, + { Group_Root, Group_Homing, "Homing"}, + { Group_Root, Group_Probing, "Probing"}, + { Group_Root, Group_SafetyDoor, "Safety door"}, + { Group_Root, Group_Jogging, "Jogging"}, + { Group_Root, Group_Stepper, "Stepper"}, + { Group_Root, Group_MotorDriver, "Stepper driver"}, + { Group_Root, Group_Axis, "Axis"}, + { Group_Axis, Group_XAxis, "X-axis"}, + { Group_Axis, Group_YAxis, "Y-axis"}, + { Group_Axis, Group_ZAxis, "Z-axis"}, #ifdef A_AXIS - { Group_Axis, Group_AAxis, "A-axis"}, + { Group_Axis, Group_AAxis, "A-axis"}, #endif #ifdef B_AXIS - { Group_Axis, Group_BAxis, "B-axis"}, + { Group_Axis, Group_BAxis, "B-axis"}, #endif #ifdef C_AXIS - { Group_Axis, Group_CAxis, "C-axis"}, + { Group_Axis, Group_CAxis, "C-axis"}, #endif #ifdef U_AXIS - { Group_Axis, Group_UAxis, "U-axis"}, + { Group_Axis, Group_UAxis, "U-axis"}, #endif #ifdef V_AXIS - { Group_Axis, Group_VAxis, "V-axis"} + { Group_Axis, Group_VAxis, "V-axis"} #endif }; @@ -346,6 +348,9 @@ static status_code_t set_door_options (setting_id_t id, uint_fast16_t int_value) static status_code_t set_linear_piece (setting_id_t id, char *svalue); static char *get_linear_piece (setting_id_t id); #endif +#if N_AXIS > 3 +static status_code_t set_rotational_axes (setting_id_t id, uint_fast16_t int_value); +#endif #if COMPATIBILITY_LEVEL > 1 static status_code_t set_limits_invert_mask (setting_id_t id, uint_fast16_t int_value); #endif @@ -359,131 +364,268 @@ static char spindle_signals[] = "Spindle enable,Spindle direction,PWM"; static char coolant_signals[] = "Flood,Mist"; PROGMEM static const setting_detail_t setting_detail[] = { - { Setting_PulseMicroseconds, Group_Stepper, "Step pulse time", "microseconds", Format_Decimal, "#0.0", "2.0", NULL, Setting_IsLegacy, &settings.steppers.pulse_microseconds, NULL, NULL }, - { Setting_StepperIdleLockTime, Group_Stepper, "Step idle delay", "milliseconds", Format_Int16, "####0", NULL, "65535", Setting_IsLegacy, &settings.steppers.idle_lock_time, NULL, NULL }, - { Setting_StepInvertMask, Group_Stepper, "Step pulse invert", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.steppers.step_invert.mask, NULL, NULL }, - { Setting_DirInvertMask, Group_Stepper, "Step direction invert", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.steppers.dir_invert.mask, NULL, NULL }, - { Setting_InvertStepperEnable, Group_Stepper, "Invert step enable pin(s)", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.steppers.enable_invert.mask, NULL, NULL }, + { Setting_PulseMicroseconds, Group_Stepper, "Step pulse time", "microseconds", Format_Decimal, "#0.0", "2.0", NULL, Setting_IsLegacy, &settings.steppers.pulse_microseconds, NULL, NULL }, + { Setting_StepperIdleLockTime, Group_Stepper, "Step idle delay", "milliseconds", Format_Int16, "####0", NULL, "65535", Setting_IsLegacy, &settings.steppers.idle_lock_time, NULL, NULL }, + { Setting_StepInvertMask, Group_Stepper, "Step pulse invert", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.steppers.step_invert.mask, NULL, NULL }, + { Setting_DirInvertMask, Group_Stepper, "Step direction invert", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.steppers.dir_invert.mask, NULL, NULL }, + { Setting_InvertStepperEnable, Group_Stepper, "Invert step enable pin(s)", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.steppers.enable_invert.mask, NULL, NULL }, #if COMPATIBILITY_LEVEL <= 1 - { Setting_LimitPinsInvertMask, Group_Limits, "Invert limit pins", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.limits.invert.mask, NULL, NULL }, + { Setting_LimitPinsInvertMask, Group_Limits, "Invert limit pins", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.limits.invert.mask, NULL, NULL }, #else - { Setting_LimitPinsInvertMask, Group_Limits, "Invert limit pins", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_limits_invert_mask, get_int, NULL }, + { Setting_LimitPinsInvertMask, Group_Limits, "Invert limit pins", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_limits_invert_mask, get_int, NULL }, #endif - { Setting_InvertProbePin, Group_Probing, "Invert probe pin", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_probe_invert, get_int, NULL }, - { Setting_SpindlePWMBehaviour, Group_Spindle, "Disable spindle with zero speed", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtended, &settings.spindle.flags.mask, NULL, is_setting_available }, -// { Setting_SpindlePWMBehaviour, Group_Spindle, "Spindle enable vs. speed behaviour", NULL, Format_RadioButtons, "No action,Disable spindle with zero speed,Enable spindle with all speeds", NULL, NULL, Setting_IsExtended, &settings.spindle.flags.mask, NULL, NULL }, + { Setting_InvertProbePin, Group_Probing, "Invert probe pin", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_probe_invert, get_int, NULL }, + { Setting_SpindlePWMBehaviour, Group_Spindle, "Disable spindle with zero speed", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtended, &settings.spindle.flags.mask, NULL, is_setting_available }, +// { Setting_SpindlePWMBehaviour, Group_Spindle, "Spindle enable vs. speed behaviour", NULL, Format_RadioButtons, "No action,Disable spindle with zero speed,Enable spindle with all speeds", NULL, NULL, Setting_IsExtended, &settings.spindle.flags.mask, NULL, NULL }, #if COMPATIBILITY_LEVEL <= 1 - { Setting_StatusReportMask, Group_General, "Status report options", NULL, Format_Bitfield, "Position in machine coordinate,Buffer state,Line numbers,Feed & speed,Pin state,Work coordinate offset,Overrides,Probe coordinates,Buffer sync on WCO change,Parser state,Alarm substatus,Run substatus", NULL, NULL, Setting_IsExtendedFn, set_report_mask, get_int, NULL }, + { Setting_StatusReportMask, Group_General, "Status report options", NULL, Format_Bitfield, "Position in machine coordinate,Buffer state,Line numbers,Feed & speed,Pin state,Work coordinate offset,Overrides,Probe coordinates,Buffer sync on WCO change,Parser state,Alarm substatus,Run substatus", NULL, NULL, Setting_IsExtendedFn, set_report_mask, get_int, NULL }, #else - { Setting_StatusReportMask, Group_General, "Status report options", NULL, Format_Bitfield, "Position in machine coordinate,Buffer state", NULL, NULL, Setting_IsLegacyFn, set_report_mask, get_int, NULL }, + { Setting_StatusReportMask, Group_General, "Status report options", NULL, Format_Bitfield, "Position in machine coordinate,Buffer state", NULL, NULL, Setting_IsLegacyFn, set_report_mask, get_int, NULL }, #endif - { Setting_JunctionDeviation, Group_General, "Junction deviation", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.junction_deviation, NULL, NULL }, - { Setting_ArcTolerance, Group_General, "Arc tolerance", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.arc_tolerance, NULL, NULL }, - { Setting_ReportInches, Group_General, "Report in inches", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_report_inches, get_int, NULL }, - { Setting_ControlInvertMask, Group_ControlSignals, "Invert control pins", NULL, Format_Bitfield, control_signals, NULL, NULL, Setting_IsExpandedFn, set_control_invert, get_int, NULL }, - { Setting_CoolantInvertMask, Group_Coolant, "Invert coolant pins", NULL, Format_Bitfield, coolant_signals, NULL, NULL, Setting_IsExtended, &settings.coolant_invert.mask, NULL, NULL }, - { Setting_SpindleInvertMask, Group_Spindle, "Invert spindle signals", NULL, Format_Bitfield, spindle_signals, NULL, NULL, Setting_IsExtendedFn, set_spindle_invert, get_int, NULL }, - { Setting_ControlPullUpDisableMask, Group_ControlSignals, "Pullup disable control pins", NULL, Format_Bitfield, control_signals, NULL, NULL, Setting_IsExtendedFn, set_control_disable_pullup, get_int, NULL }, - { Setting_LimitPullUpDisableMask, Group_Limits, "Pullup disable limit pins", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtended, &settings.limits.disable_pullup.mask, NULL, NULL }, - { Setting_ProbePullUpDisable, Group_Probing, "Pullup disable probe pin", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_probe_disable_pullup, get_int, NULL }, - { Setting_SoftLimitsEnable, Group_Limits, "Soft limits enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_soft_limits_enable, get_int, NULL }, + { Setting_JunctionDeviation, Group_General, "Junction deviation", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.junction_deviation, NULL, NULL }, + { Setting_ArcTolerance, Group_General, "Arc tolerance", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.arc_tolerance, NULL, NULL }, + { Setting_ReportInches, Group_General, "Report in inches", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_report_inches, get_int, NULL }, + { Setting_ControlInvertMask, Group_ControlSignals, "Invert control pins", NULL, Format_Bitfield, control_signals, NULL, NULL, Setting_IsExpandedFn, set_control_invert, get_int, NULL }, + { Setting_CoolantInvertMask, Group_Coolant, "Invert coolant pins", NULL, Format_Bitfield, coolant_signals, NULL, NULL, Setting_IsExtended, &settings.coolant_invert.mask, NULL, NULL }, + { Setting_SpindleInvertMask, Group_Spindle, "Invert spindle signals", NULL, Format_Bitfield, spindle_signals, NULL, NULL, Setting_IsExtendedFn, set_spindle_invert, get_int, NULL }, + { Setting_ControlPullUpDisableMask, Group_ControlSignals, "Pullup disable control pins", NULL, Format_Bitfield, control_signals, NULL, NULL, Setting_IsExtendedFn, set_control_disable_pullup, get_int, NULL }, + { Setting_LimitPullUpDisableMask, Group_Limits, "Pullup disable limit pins", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtended, &settings.limits.disable_pullup.mask, NULL, NULL }, + { Setting_ProbePullUpDisable, Group_Probing, "Pullup disable probe pin", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_probe_disable_pullup, get_int, NULL }, + { Setting_SoftLimitsEnable, Group_Limits, "Soft limits enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_soft_limits_enable, get_int, NULL }, #if COMPATIBILITY_LEVEL <= 1 - { Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_XBitfield, "Enable,Strict mode", NULL, NULL, Setting_IsExpandedFn, set_hard_limits_enable, get_int, NULL }, + { Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_XBitfield, "Enable,Strict mode", NULL, NULL, Setting_IsExpandedFn, set_hard_limits_enable, get_int, NULL }, #else - { Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_hard_limits_enable, get_int, NULL }, + { Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_hard_limits_enable, get_int, NULL }, #endif #if COMPATIBILITY_LEVEL <= 1 - { Setting_HomingEnable, Group_Homing, "Homing cycle", NULL, Format_XBitfield, "Enable,Enable single axis commands,Homing on startup required,Set machine origin to 0,Two switches shares one input pin,Allow manual,Override locks,Keep homed status on reset", NULL, NULL, Setting_IsExpandedFn, set_homing_enable, get_int, NULL }, + { Setting_HomingEnable, Group_Homing, "Homing cycle", NULL, Format_XBitfield, "Enable,Enable single axis commands,Homing on startup required,Set machine origin to 0,Two switches shares one input pin,Allow manual,Override locks,Keep homed status on reset", NULL, NULL, Setting_IsExpandedFn, set_homing_enable, get_int, NULL }, #else - { Setting_HomingEnable, Group_Homing, "Homing cycle enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_homing_enable, get_int, NULL }, + { Setting_HomingEnable, Group_Homing, "Homing cycle enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_homing_enable, get_int, NULL }, #endif - { Setting_HomingDirMask, Group_Homing, "Homing direction invert", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.homing.dir_mask.value, NULL, NULL }, - { Setting_HomingFeedRate, Group_Homing, "Homing locate feed rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsLegacy, &settings.homing.feed_rate, NULL, NULL }, - { Setting_HomingSeekRate, Group_Homing, "Homing search seek rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsLegacy, &settings.homing.seek_rate, NULL, NULL }, - { Setting_HomingDebounceDelay, Group_Homing, "Homing switch debounce delay", "milliseconds", Format_Int16, "##0", NULL, NULL, Setting_IsLegacy, &settings.homing.debounce_delay, NULL, NULL }, - { Setting_HomingPulloff, Group_Homing, "Homing switch pull-off distance", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.homing.pulloff, NULL, NULL }, - { Setting_G73Retract, Group_General, "G73 Retract distance", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtended, &settings.g73_retract, NULL, NULL }, - { Setting_PulseDelayMicroseconds, Group_Stepper, "Pulse delay", "microseconds", Format_Decimal, "#0.0", NULL, "10", Setting_IsExtended, &settings.steppers.pulse_delay_microseconds, NULL, NULL }, - { Setting_RpmMax, Group_Spindle, "Maximum spindle speed", "RPM", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.spindle.rpm_max, NULL, is_setting_available }, - { Setting_RpmMin, Group_Spindle, "Minimum spindle speed", "RPM", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.spindle.rpm_min, NULL, is_setting_available }, - { Setting_Mode, Group_General, "Mode of operation", NULL, Format_RadioButtons, "Normal,Laser mode,Lathe mode", NULL, NULL, Setting_IsLegacyFn, set_mode, get_int, NULL }, - { Setting_PWMFreq, Group_Spindle, "Spindle PWM frequency", "Hz", Format_Decimal, "#####0", NULL, NULL, Setting_IsExtended, &settings.spindle.pwm_freq, NULL, is_setting_available }, - { Setting_PWMOffValue, Group_Spindle, "Spindle PWM off value", "percent", Format_Decimal, "##0.0", NULL, "100", Setting_IsExtended, &settings.spindle.pwm_off_value, NULL, is_setting_available }, - { Setting_PWMMinValue, Group_Spindle, "Spindle PWM min value", "percent", Format_Decimal, "##0.0", NULL, "100", Setting_IsExtended, &settings.spindle.pwm_min_value, NULL, is_setting_available }, - { Setting_PWMMaxValue, Group_Spindle, "Spindle PWM max value", "percent", Format_Decimal, "##0.0", NULL, "100", Setting_IsExtended, &settings.spindle.pwm_max_value, NULL, is_setting_available }, - { Setting_StepperDeenergizeMask, Group_Stepper, "Steppers deenergize", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtended, &settings.steppers.deenergize.mask, NULL, NULL }, - { Setting_SpindlePPR, Group_Spindle, "Spindle pulses per revolution (PPR)", NULL, Format_Int16, "###0", NULL, NULL, Setting_IsExtended, &settings.spindle.ppr, NULL, is_setting_available }, - { Setting_EnableLegacyRTCommands, Group_General, "Enable legacy RT commands", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_enable_legacy_rt_commands, get_int, NULL }, - { Setting_JogSoftLimited, Group_Jogging, "Limit jog commands", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_jog_soft_limited, get_int, NULL }, + { Setting_HomingDirMask, Group_Homing, "Homing direction invert", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsLegacy, &settings.homing.dir_mask.value, NULL, NULL }, + { Setting_HomingFeedRate, Group_Homing, "Homing locate feed rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsLegacy, &settings.homing.feed_rate, NULL, NULL }, + { Setting_HomingSeekRate, Group_Homing, "Homing search seek rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsLegacy, &settings.homing.seek_rate, NULL, NULL }, + { Setting_HomingDebounceDelay, Group_Homing, "Homing switch debounce delay", "milliseconds", Format_Int16, "##0", NULL, NULL, Setting_IsLegacy, &settings.homing.debounce_delay, NULL, NULL }, + { Setting_HomingPulloff, Group_Homing, "Homing switch pull-off distance", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.homing.pulloff, NULL, NULL }, + { Setting_G73Retract, Group_General, "G73 Retract distance", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtended, &settings.g73_retract, NULL, NULL }, + { Setting_PulseDelayMicroseconds, Group_Stepper, "Pulse delay", "microseconds", Format_Decimal, "#0.0", NULL, "10", Setting_IsExtended, &settings.steppers.pulse_delay_microseconds, NULL, NULL }, + { Setting_RpmMax, Group_Spindle, "Maximum spindle speed", "RPM", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.spindle.rpm_max, NULL, is_setting_available }, + { Setting_RpmMin, Group_Spindle, "Minimum spindle speed", "RPM", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacy, &settings.spindle.rpm_min, NULL, is_setting_available }, + { Setting_Mode, Group_General, "Mode of operation", NULL, Format_RadioButtons, "Normal,Laser mode,Lathe mode", NULL, NULL, Setting_IsLegacyFn, set_mode, get_int, NULL }, + { Setting_PWMFreq, Group_Spindle, "Spindle PWM frequency", "Hz", Format_Decimal, "#####0", NULL, NULL, Setting_IsExtended, &settings.spindle.pwm_freq, NULL, is_setting_available }, + { Setting_PWMOffValue, Group_Spindle, "Spindle PWM off value", "percent", Format_Decimal, "##0.0", NULL, "100", Setting_IsExtended, &settings.spindle.pwm_off_value, NULL, is_setting_available }, + { Setting_PWMMinValue, Group_Spindle, "Spindle PWM min value", "percent", Format_Decimal, "##0.0", NULL, "100", Setting_IsExtended, &settings.spindle.pwm_min_value, NULL, is_setting_available }, + { Setting_PWMMaxValue, Group_Spindle, "Spindle PWM max value", "percent", Format_Decimal, "##0.0", NULL, "100", Setting_IsExtended, &settings.spindle.pwm_max_value, NULL, is_setting_available }, + { Setting_StepperDeenergizeMask, Group_Stepper, "Steppers deenergize", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtended, &settings.steppers.deenergize.mask, NULL, NULL }, + { Setting_SpindlePPR, Group_Spindle, "Spindle pulses per revolution (PPR)", NULL, Format_Int16, "###0", NULL, NULL, Setting_IsExtended, &settings.spindle.ppr, NULL, is_setting_available }, + { Setting_EnableLegacyRTCommands, Group_General, "Enable legacy RT commands", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_enable_legacy_rt_commands, get_int, NULL }, + { Setting_JogSoftLimited, Group_Jogging, "Limit jog commands", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_jog_soft_limited, get_int, NULL }, #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN - { Setting_ParkingEnable, Group_SafetyDoor, "Parking cycle", NULL, Format_XBitfield, "Enable,Enable parking override control,Deactivate upon init", NULL, NULL, Setting_IsExtendedFn, set_parking_enable, get_int, NULL }, - { Setting_ParkingAxis, Group_SafetyDoor, "Parking axis", NULL, Format_RadioButtons, "X,Y,Z", NULL, NULL, Setting_IsExtended, &settings.parking.axis, NULL, NULL }, + { Setting_ParkingEnable, Group_SafetyDoor, "Parking cycle", NULL, Format_XBitfield, "Enable,Enable parking override control,Deactivate upon init", NULL, NULL, Setting_IsExtendedFn, set_parking_enable, get_int, NULL }, + { Setting_ParkingAxis, Group_SafetyDoor, "Parking axis", NULL, Format_RadioButtons, "X,Y,Z", NULL, NULL, Setting_IsExtended, &settings.parking.axis, NULL, NULL }, #endif - { Setting_HomingLocateCycles, Group_Homing, "Homing passes", NULL, Format_Int8, "##0", "1", "128", Setting_IsExtended, &settings.homing.locate_cycles, NULL, NULL }, - { Setting_HomingCycle_1, Group_Homing, "Axes homing, first pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, - { Setting_HomingCycle_2, Group_Homing, "Axes homing, second pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, - { Setting_HomingCycle_3, Group_Homing, "Axes homing, third pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, + { Setting_HomingLocateCycles, Group_Homing, "Homing passes", NULL, Format_Int8, "##0", "1", "128", Setting_IsExtended, &settings.homing.locate_cycles, NULL, NULL }, + { Setting_HomingCycle_1, Group_Homing, "Axes homing, first pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, + { Setting_HomingCycle_2, Group_Homing, "Axes homing, second pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, + { Setting_HomingCycle_3, Group_Homing, "Axes homing, third pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, #ifdef A_AXIS - { Setting_HomingCycle_4, Group_Homing, "Axes homing, fourth pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, + { Setting_HomingCycle_4, Group_Homing, "Axes homing, fourth pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, #endif #ifdef B_AXIS - { Setting_HomingCycle_5, Group_Homing, "Axes homing, fifth pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, + { Setting_HomingCycle_5, Group_Homing, "Axes homing, fifth pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, #endif #ifdef C_AXIS - { Setting_HomingCycle_6, Group_Homing, "Axes homing, sixth pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, + { Setting_HomingCycle_6, Group_Homing, "Axes homing, sixth pass", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL }, #endif #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN - { Setting_ParkingPulloutIncrement, Group_SafetyDoor, "Parking pull-out distance", "mm", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.pullout_increment, NULL, NULL }, - { Setting_ParkingPulloutRate, Group_SafetyDoor, "Parking pull-out rate", "mm/min", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.pullout_rate, NULL, NULL }, - { Setting_ParkingTarget, Group_SafetyDoor, "Parking target", "mm", Format_Decimal, "-###0.0", "-100000", NULL, Setting_IsExtended, &settings.parking.target, NULL, NULL }, - { Setting_ParkingFastRate, Group_SafetyDoor, "Parking fast rate", "mm/min", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.rate, NULL, NULL }, - { Setting_RestoreOverrides, Group_General, "Restore overrides", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_restore_overrides, get_int, NULL }, - { Setting_DoorOptions, Group_SafetyDoor, "Safety door options", NULL, Format_Bitfield, "Ignore when idle,Keep coolant state on open", NULL, NULL, Setting_IsExtendedFn, set_door_options, get_int, NULL }, + { Setting_ParkingPulloutIncrement, Group_SafetyDoor, "Parking pull-out distance", "mm", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.pullout_increment, NULL, NULL }, + { Setting_ParkingPulloutRate, Group_SafetyDoor, "Parking pull-out rate", "mm/min", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.pullout_rate, NULL, NULL }, + { Setting_ParkingTarget, Group_SafetyDoor, "Parking target", "mm", Format_Decimal, "-###0.0", "-100000", NULL, Setting_IsExtended, &settings.parking.target, NULL, NULL }, + { Setting_ParkingFastRate, Group_SafetyDoor, "Parking fast rate", "mm/min", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.rate, NULL, NULL }, + { Setting_RestoreOverrides, Group_General, "Restore overrides", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_restore_overrides, get_int, NULL }, + { Setting_DoorOptions, Group_SafetyDoor, "Safety door options", NULL, Format_Bitfield, "Ignore when idle,Keep coolant state on open", NULL, NULL, Setting_IsExtendedFn, set_door_options, get_int, NULL }, #endif - { Setting_SleepEnable, Group_General, "Sleep enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_sleep_enable, get_int, NULL }, - { Setting_HoldActions, Group_General, "Feed hold actions", NULL, Format_Bitfield, "Disable laser during hold,Restore spindle and coolant state on resume", NULL, NULL, Setting_IsExtendedFn, set_hold_actions, get_int, NULL }, - { Setting_ForceInitAlarm, Group_General, "Force init alarm", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_force_initialization_alarm, get_int, NULL }, - { Setting_ProbingFeedOverride, Group_Probing, "Probing feed override", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_probe_allow_feed_override, get_int, NULL }, + { Setting_SleepEnable, Group_General, "Sleep enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_sleep_enable, get_int, NULL }, + { Setting_HoldActions, Group_General, "Feed hold actions", NULL, Format_Bitfield, "Disable laser during hold,Restore spindle and coolant state on resume", NULL, NULL, Setting_IsExtendedFn, set_hold_actions, get_int, NULL }, + { Setting_ForceInitAlarm, Group_General, "Force init alarm", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_force_initialization_alarm, get_int, NULL }, + { Setting_ProbingFeedOverride, Group_Probing, "Probing feed override", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_probe_allow_feed_override, get_int, NULL }, #ifdef ENABLE_SPINDLE_LINEARIZATION - { Setting_LinearSpindlePiece1, Group_Spindle, "Spindle linearisation, first point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, - { Setting_LinearSpindlePiece2, Group_Spindle, "Spindle linearisation, second point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, - { Setting_LinearSpindlePiece3, Group_Spindle, "Spindle linearisation, third point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, - { Setting_LinearSpindlePiece4, Group_Spindle, "Spindle linearisation, fourth point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, + { Setting_LinearSpindlePiece1, Group_Spindle, "Spindle linearisation, first point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, + { Setting_LinearSpindlePiece2, Group_Spindle, "Spindle linearisation, second point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, + { Setting_LinearSpindlePiece3, Group_Spindle, "Spindle linearisation, third point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, + { Setting_LinearSpindlePiece4, Group_Spindle, "Spindle linearisation, fourth point", NULL, Format_String, "x30", NULL, "30", Setting_IsExtendedFn, set_linear_piece, get_linear_piece, NULL }, #endif - { Setting_SpindlePGain, Group_Spindle_ClosedLoop, "Spindle P-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.p_gain, NULL, NULL }, - { Setting_SpindleIGain, Group_Spindle_ClosedLoop, "Spindle I-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.i_gain, NULL, NULL }, - { Setting_SpindleDGain, Group_Spindle_ClosedLoop, "Spindle D-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.d_gain, NULL, NULL }, - { Setting_SpindleMaxError, Group_Spindle_ClosedLoop, "Spindle PID max error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.max_error, NULL, NULL }, - { Setting_SpindleIMaxError, Group_Spindle_ClosedLoop, "Spindle PID max I error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.i_max_error, NULL, NULL }, - { Setting_PositionPGain, Group_Spindle_Sync, "Spindle sync P-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.p_gain, NULL, NULL }, - { Setting_PositionIGain, Group_Spindle_Sync, "Spindle sync I-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.i_gain, NULL, NULL }, - { Setting_PositionDGain, Group_Spindle_Sync, "Spindle sync D-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.d_gain, NULL, NULL }, - { Setting_PositionIMaxError, Group_Spindle_Sync, "Spindle sync PID max I error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.i_max_error, NULL, NULL }, - { Setting_AxisStepsPerMM, Group_Axis0, "?-axis travel resolution", "step/mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, - { Setting_AxisMaxRate, Group_Axis0, "?-axis maximum rate", "mm/min", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, - { Setting_AxisAcceleration, Group_Axis0, "?-axis acceleration", "mm/sec^2", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, - { Setting_AxisMaxTravel, Group_Axis0, "?-axis maximum travel", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_SpindlePGain, Group_Spindle_ClosedLoop, "Spindle P-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.p_gain, NULL, NULL }, + { Setting_SpindleIGain, Group_Spindle_ClosedLoop, "Spindle I-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.i_gain, NULL, NULL }, + { Setting_SpindleDGain, Group_Spindle_ClosedLoop, "Spindle D-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.d_gain, NULL, NULL }, + { Setting_SpindleMaxError, Group_Spindle_ClosedLoop, "Spindle PID max error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.max_error, NULL, NULL }, + { Setting_SpindleIMaxError, Group_Spindle_ClosedLoop, "Spindle PID max I error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.spindle.pid.i_max_error, NULL, NULL }, + { Setting_PositionPGain, Group_Spindle_Sync, "Spindle sync P-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.p_gain, NULL, NULL }, + { Setting_PositionIGain, Group_Spindle_Sync, "Spindle sync I-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.i_gain, NULL, NULL }, + { Setting_PositionDGain, Group_Spindle_Sync, "Spindle sync D-gain", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.d_gain, NULL, NULL }, + { Setting_PositionIMaxError, Group_Spindle_Sync, "Spindle sync PID max I error", NULL, Format_Decimal, "###0.000", NULL, NULL, Setting_IsExtended, &settings.position.pid.i_max_error, NULL, NULL }, + { Setting_AxisStepsPerMM, Group_Axis0, "?-axis travel resolution", "step/mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisMaxRate, Group_Axis0, "?-axis maximum rate", "mm/min", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisAcceleration, Group_Axis0, "?-axis acceleration", "mm/sec^2", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, + { Setting_AxisMaxTravel, Group_Axis0, "?-axis maximum travel", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsLegacyFn, set_axis_setting, get_float, NULL }, #ifdef ENABLE_BACKLASH_COMPENSATION - { Setting_AxisBacklash, Group_Axis0, "?-axis backlash compensation", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtendedFn, set_axis_setting, get_float, NULL, NULL }, + { Setting_AxisBacklash, Group_Axis0, "?-axis backlash compensation", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtendedFn, set_axis_setting, get_float, NULL, NULL }, +#endif + { Setting_AxisAutoSquareOffset, Group_Axis0, "?-axis dual axis offset", "mm", Format_Decimal, "-0.000", "-2", "2", Setting_IsExtendedFn, set_axis_setting, get_float, is_setting_available }, + { Setting_SpindleAtSpeedTolerance, Group_Spindle, "Spindle at speed tolerance", "percent", Format_Decimal, "##0.0", NULL, NULL, Setting_IsExtended, &settings.spindle.at_speed_tolerance, NULL, is_setting_available }, + { Setting_ToolChangeMode, Group_Toolchange, "Tool change mode", NULL, Format_RadioButtons, "Normal,Manual touch off,Manual touch off @ G59.3,Automatic touch off @ G59.3,Ignore M6", NULL, NULL, Setting_IsExtendedFn, set_tool_change_mode, get_int, NULL }, + { Setting_ToolChangeProbingDistance, Group_Toolchange, "Tool change probing distance", "mm", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtendedFn, set_tool_change_probing_distance, get_float, NULL }, + { Setting_ToolChangeFeedRate, Group_Toolchange, "Tool change locate feed rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtended, &settings.tool_change.feed_rate, NULL, NULL }, + { Setting_ToolChangeSeekRate, Group_Toolchange, "Tool change search seek rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtended, &settings.tool_change.seek_rate, NULL, NULL }, + { Setting_ToolChangePulloffRate, Group_Toolchange, "Tool change probe pull-off rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtended, &settings.tool_change.pulloff_rate, NULL, NULL }, + { Setting_DualAxisLengthFailPercent, Group_Limits_DualAxis, "Dual axis length fail", "percent", Format_Decimal, "##0.0", "0", "100", Setting_IsExtended, &settings.homing.dual_axis.fail_length_percent, NULL, NULL }, + { Setting_DualAxisLengthFailMin, Group_Limits_DualAxis, "Dual axis length fail min", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtended, &settings.homing.dual_axis.fail_distance_min, NULL, NULL }, + { Setting_DualAxisLengthFailMax, Group_Limits_DualAxis, "Dual axis length fail max", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtended, &settings.homing.dual_axis.fail_distance_max, NULL, NULL }, +#if N_AXIS == 4 + { Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL } +#elif N_AXIS == 5 + { Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL }, +#elif N_AXIS > 5 + { Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_Bitfield, "A-Axis,B-Axis,C-Axis", NULL, NULL, Setting_IsExtendedFn, set_rotational_axes, get_int, NULL }, #endif - { Setting_AxisAutoSquareOffset, Group_Axis0, "?-axis dual axis offset", "mm", Format_Decimal, "-0.000", "-2", "2", Setting_IsExtendedFn, set_axis_setting, get_float, is_setting_available }, - { Setting_SpindleAtSpeedTolerance, Group_Spindle, "Spindle at speed tolerance", "percent", Format_Decimal, "##0.0", NULL, NULL, Setting_IsExtended, &settings.spindle.at_speed_tolerance, NULL, is_setting_available }, - { Setting_ToolChangeMode, Group_Toolchange, "Tool change mode", NULL, Format_RadioButtons, "Normal,Manual touch off,Manual touch off @ G59.3,Automatic touch off @ G59.3,Ignore M6", NULL, NULL, Setting_IsExtendedFn, set_tool_change_mode, get_int, NULL }, - { Setting_ToolChangeProbingDistance, Group_Toolchange, "Tool change probing distance", "mm", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtendedFn, set_tool_change_probing_distance, get_float, NULL }, - { Setting_ToolChangeFeedRate, Group_Toolchange, "Tool change locate feed rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtended, &settings.tool_change.feed_rate, NULL, NULL }, - { Setting_ToolChangeSeekRate, Group_Toolchange, "Tool change search seek rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtended, &settings.tool_change.seek_rate, NULL, NULL }, - { Setting_ToolChangePulloffRate, Group_Toolchange, "Tool change probe pull-off rate", "mm/min", Format_Decimal, "#####0.0", NULL, NULL, Setting_IsExtended, &settings.tool_change.pulloff_rate, NULL, NULL }, - { Setting_DualAxisLengthFailPercent, Group_Limits_DualAxis, "Dual axis length fail", "percent", Format_Decimal, "##0.0", "0", "100", Setting_IsExtended, &settings.homing.dual_axis.fail_length_percent, NULL, NULL }, - { Setting_DualAxisLengthFailMin, Group_Limits_DualAxis, "Dual axis length fail min", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtended, &settings.homing.dual_axis.fail_distance_min, NULL, NULL }, - { Setting_DualAxisLengthFailMax, Group_Limits_DualAxis, "Dual axis length fail max", "mm", Format_Decimal, "#####0.000", NULL, NULL, Setting_IsExtended, &settings.homing.dual_axis.fail_distance_max, NULL, NULL } -// { Settings_Axis_Rotational, Group_Stepper, "Rotational axes", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtended, &settings.steppers.is_rotational.mask, NULL, NULL } }; +#ifndef NO_SETTINGS_DESCRIPTIONS + +PROGMEM static const setting_descr_t setting_descr[] = { + { Setting_PulseMicroseconds, "Sets time length per step. Minimum 2 microseconds.\\n\\n" + "This needs to be reduced from the default value of 10 when max. step rates exceed approximately 80 kHz." + }, + { Setting_StepperIdleLockTime, "Sets a short hold delay when stopping to let dynamics settle before disabling steppers. Value 255 keeps motors enabled." }, + { Setting_StepInvertMask, "Inverts the step signals (active low)." }, + { Setting_DirInvertMask, "Inverts the direction signals (active low)." }, + { Setting_InvertStepperEnable, "Inverts the stepper driver enable signals (active low). If the stepper drivers shares the same enable signal only X is used." }, + { Setting_LimitPinsInvertMask, "Inverts the axis limit input signals." }, + { Setting_InvertProbePin, "Inverts the probe input pin signal." }, + { Setting_SpindlePWMBehaviour, "" }, + { Setting_StatusReportMask, "Specifies optional data included in status reports.\\n" + "If Run substatus is enabled it may be used for simple probe protection.\\n\\n" + "Note that Parser state will be sent separately after the status report and only on changes." + }, + { Setting_JunctionDeviation, "Sets how fast Grbl travels through consecutive motions. Lower value slows it down." }, + { Setting_ArcTolerance, "Sets the G2 and G3 arc tracing accuracy based on radial error. Beware: A very small value may effect performance." }, + { Setting_ReportInches, "Enables inch units when returning any position and rate value that is not a settings value." }, + { Setting_ControlInvertMask, "Inverts the control signals (active low).\\n" + "NOTE: Block delete, Optional stop, EStop and Probe connected are optional signals, availability is driver dependent." + }, + { Setting_CoolantInvertMask, "Inverts the coolant and mist signals (active low)." }, + { Setting_SpindleInvertMask, "Inverts the spindle on, counterclockwise and PWM signals (active low)." }, + { Setting_ControlPullUpDisableMask, "Disable the control signals pullup resistors. Potentially enables pulldown resistor if available.\\n" + "NOTE: Block delete, Optional stop and EStop are optional signals, availability is driver dependent." + }, + { Setting_LimitPullUpDisableMask, "Disable the limit signals pullup resistors. Potentially enables pulldown resistor if available."}, + { Setting_ProbePullUpDisable, "Disable the probe signal pullup resistor. Potentially enables pulldown resistor if available." }, + { Setting_SoftLimitsEnable, "Enables soft limits checks within machine travel and sets alarm when exceeded. Requires homing." }, + { Setting_HardLimitsEnable, "When enabled immediately halts motion and throws an alarm when a limit switch is triggered. In strict mode only homing is possible when a switch is engaged." }, + { Setting_HomingEnable, "Enables homing cycle. Requires limit switches on axes to be automatically homed.\\n\\n" + "When `Enable single axis commands` is checked, single axis homing can be performed by $H commands.\\n\\n" + "When `Allow manual` is checked, axes not homed automatically may be homed manually by $H or $H commands.\\n\\n" + "`Override locks` is for allowing a soft reset to disable `Homing on startup required`." + }, + { Setting_HomingDirMask, "Homing searches for a switch in the positive direction. Set axis bit to search in negative direction." }, + { Setting_HomingFeedRate, "Feed rate to slowly engage limit switch to determine its location accurately." }, + { Setting_HomingSeekRate, "Seek rate to quickly find the limit switch before the slower locating phase." }, + { Setting_HomingDebounceDelay, "Sets a short delay between phases of homing cycle to let a switch debounce." }, + { Setting_HomingPulloff, "Retract distance after triggering switch to disengage it. Homing will fail if switch isn't cleared." }, + { Setting_G73Retract, "G73 retract distance (for chip breaking drilling)." }, + { Setting_PulseDelayMicroseconds, "Step pulse delay.\\n\\n" + "Normally leave this at 0 as there is an implicit delay on direction changes when AMASS is active." + }, + { Setting_RpmMax, "Maximum spindle speed. Sets PWM to maximum duty cycle." }, + { Setting_RpmMin, "Minimum spindle speed. Sets PWM to minimum duty cycle." }, + { Setting_Mode, "Laser mode: consecutive G1/2/3 commands will not halt when spindle speed is changed.\\n" + "Lathe mode: allows use of G7, G8, G96 and G97." + }, + { Setting_PWMFreq, "Spindle PWM frequency." }, + { Setting_PWMOffValue, "Spindle PWM off value in percent (duty cycle)." }, + { Setting_PWMMinValue, "Spindle PWM min value in percent (duty cycle)." }, + { Setting_PWMMaxValue, "Spindle PWM max value in percent (duty cycle)." }, + { Setting_StepperDeenergizeMask, "Specifies which steppers not to disable when stopped." }, + { Setting_SpindlePPR, "Spindle encoder pulses per revolution." }, + { Setting_EnableLegacyRTCommands, "Enables \"normal\" processing of ?, ! and ~ characters when part of $-setting or comment. If disabled then they are added to the input string instead." }, + { Setting_JogSoftLimited, "Limit jog commands to machine limits for homed axes." }, + { Setting_ParkingEnable, "Enables parking cycle, requires parking axis homed." }, + { Setting_ParkingAxis, "Define which axis that performs the parking motion." }, + { Setting_HomingLocateCycles, "Number of homing passes. Minimum 1, maximum 128." }, + { Setting_HomingCycle_1, "Axes to home in first pass." }, + { Setting_HomingCycle_2, "Axes to home in second pass." }, + { Setting_HomingCycle_3, "Axes to home in third pass." }, +#ifdef A_AXIS + { Setting_HomingCycle_4, "Axes to home in fourth pass." }, +#endif +#ifdef B_AXIS + { Setting_HomingCycle_5, "Axes to home in fifth pass." }, +#endif +#ifdef C_AXIS + { Setting_HomingCycle_6, "Axes to home in sixth pass." }, +#endif + { Setting_JogStepSpeed, "Step jogging speed in millimeters per minute." }, + { Setting_JogSlowSpeed, "Slow jogging speed in millimeters per minute." }, + { Setting_JogFastSpeed, "Fast jogging speed in millimeters per minute." }, + { Setting_JogStepDistance, "Jog distance for single step jogging." }, + { Setting_JogSlowDistance, "Jog distance before automatic stop." }, + { Setting_JogFastDistance, "Jog distance before automatic stop." }, +#ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + { Setting_ParkingPulloutIncrement, "Spindle pull-out and plunge distance in mm.Incremental distance." }, + { Setting_ParkingPulloutRate, "Spindle pull-out/plunge slow feed rate in mm/min." }, + { Setting_ParkingTarget, "Parking axis target. In mm, as machine coordinate [-max_travel, 0]." }, + { Setting_ParkingFastRate, "Parking fast rate to target after pull-out in mm/min." }, + { Setting_RestoreOverrides, "Restore overrides to default values at program end." }, + { Setting_DoorOptions, "Enable this if it is desirable to open the safety door when in IDLE mode (eg. for jogging)." }, +#endif + { Setting_SleepEnable, "Enable sleep mode." }, + { Setting_HoldActions, "Actions taken during feed hold and on resume from feed hold." }, + { Setting_ForceInitAlarm, "Starts Grbl in alarm mode after a cold reset." }, + { Setting_ProbingFeedOverride, "Allow feed override during probing." }, + { Setting_SpindlePGain, "" }, + { Setting_SpindleIGain, "" }, + { Setting_SpindleDGain, "" }, + { Setting_SpindleMaxError, "" }, + { Setting_SpindleIMaxError, "Spindle PID max integrator error." }, + { Setting_PositionPGain, "" }, + { Setting_PositionIGain, "" }, + { Setting_PositionDGain, "" }, + { Setting_PositionIMaxError, "Spindle sync PID max integrator error." }, + { Setting_AxisStepsPerMM, "Axis travel resolution in steps per millimeter." }, + { Setting_AxisMaxRate, "Axis maximum rate. Used as G0 rapid rate." }, + { Setting_AxisAcceleration, "Axis acceleration. Used for motion planning to not exceed motor torque and lose steps." }, + { Setting_AxisMaxTravel, "Maximum axis travel distance from homing switch. Determines valid machine space for soft-limits and homing search distances." }, +#ifdef ENABLE_BACKLASH_COMPENSATION + { Setting_AxisBacklash, "Axis backlash distance to compensate for." }, +#endif + { Setting_AxisAutoSquareOffset, "Axis offset between sides to compensate for homing switches inaccuracies." }, + { Setting_SpindleAtSpeedTolerance, "Spindle at speed" }, + { Setting_ToolChangeMode, "Normal: allows jogging for manual touch off. Set new position manually.\\n\\n" + "Manual touch off: retracts tool axis to home position for tool change, use jogging or $TPW for touch off.\\n\\n" + "Manual touch off @ G59.3: retracts tool axis to home position then to G59.3 position for tool change, use jogging or $TPW for touch off.\\n\\n" + "Automatic touch off @ G59.3: retracts tool axis to home position for tool change, then to G59.3 position for automatic touch off.\\n\\n" + "All modes except \"Normal\" and \"Ignore M6\" returns the tool (controlled point) to original position after touch off." + }, + { Setting_ToolChangeProbingDistance, "Maximum probing distance for automatic or $TPW touch off." }, + { Setting_ToolChangeFeedRate, "Feed rate to slowly engage tool change sensor to determine the tool offset accurately." }, + { Setting_ToolChangeSeekRate, "Seek rate to quickly find the tool change sensor before the slower locating phase." }, + { Setting_ToolChangePulloffRate, "Pull-off rate for the retract move before the slower locating phase." }, + { Setting_DualAxisLengthFailPercent, "Dual axis length fail in percent of axis max travel." }, + { Setting_DualAxisLengthFailMin, "Dual axis length fail minimum distance." }, + { Setting_DualAxisLengthFailMax, "Dual axis length fail minimum distance." } +}; + +#endif + static setting_details_t details = { .groups = setting_group_detail, .n_groups = sizeof(setting_group_detail) / sizeof(setting_group_detail_t), .settings = setting_detail, .n_settings = sizeof(setting_detail) / sizeof(setting_detail_t), +#ifndef NO_SETTINGS_DESCRIPTIONS + .descriptions = setting_descr, + .n_descriptions = sizeof(setting_descr) / sizeof(setting_descr_t), +#endif .save = settings_write_global }; @@ -797,6 +939,15 @@ static status_code_t set_tool_change_probing_distance (setting_id_t id, float va return Status_OK; } +#if N_AXIS > 3 +static status_code_t set_rotational_axes (setting_id_t id, uint_fast16_t int_value) +{ + settings.steppers.is_rotational.mask = (int_value << 3) & AXES_BITMASK; + + return Status_OK; +} +#endif + #ifdef ENABLE_SPINDLE_LINEARIZATION static status_code_t set_linear_piece (setting_id_t id, char *svalue) @@ -1080,6 +1231,12 @@ static uint32_t get_int (setting_id_t id) value = settings.tool_change.mode; break; +#if N_AXIS > 3 + case Settings_Axis_Rotational: + value = (settings.steppers.is_rotational.mask & AXES_BITMASK) >> 3; + break; +#endif + default: break; } @@ -1169,7 +1326,7 @@ static bool is_setting_available (const setting_detail_t *setting) { bool available = false; // settings_is_group_available(setting->group); - switch(normalize_id(setting->id)) { + if(setting) switch(normalize_id(setting->id)) { case Setting_SpindlePWMBehaviour: available = hal.driver_cap.variable_spindle; diff --git a/settings.h b/settings.h index 5f7ff4d..98fd5f3 100644 --- a/settings.h +++ b/settings.h @@ -30,7 +30,11 @@ // Version of the persistent storage data. Will be used to migrate existing data from older versions of Grbl // when firmware is upgraded. Always stored in byte 0 of non-volatile storage +#if N_AXIS > 3 // TODO: remove on next version update +#define SETTINGS_VERSION 20 // NOTE: Check settings_reset() when moving to next version. +#else #define SETTINGS_VERSION 19 // NOTE: Check settings_reset() when moving to next version. +#endif // Define axis settings numbering scheme. Starts at Setting_AxisSettingsBase, every INCREMENT, over N_SETTINGS. #define AXIS_SETTINGS_INCREMENT 10 // Must be greater than the number of axis settings. @@ -449,7 +453,9 @@ typedef struct { axes_signals_t dir_invert; axes_signals_t enable_invert; axes_signals_t deenergize; -// axes_signals_t is_rotational; or add to axis_settings_t below as bitmap union? rotational axes are not scaled in imperial mode +#if N_AXIS > 3 + axes_signals_t is_rotational; // rotational axes are not scaled in imperial mode +#endif float pulse_microseconds; float pulse_delay_microseconds; uint16_t idle_lock_time; // If value = 255, steppers do not disable. @@ -660,6 +666,11 @@ typedef struct setting_detail { bool (*is_available)(const struct setting_detail *setting); } setting_detail_t; +typedef struct { + setting_id_t id; + const char *description; +} setting_descr_t; + typedef status_code_t (*setting_set_int_ptr)(setting_id_t id, uint_fast16_t value); typedef status_code_t (*setting_set_float_ptr)(setting_id_t id, float value); typedef status_code_t (*setting_set_string_ptr)(setting_id_t id, char *value); @@ -682,6 +693,10 @@ typedef struct setting_details { const setting_group_detail_t *groups; const uint16_t n_settings; const setting_detail_t *settings; +#ifndef NO_SETTINGS_DESCRIPTIONS + const uint16_t n_descriptions; + const setting_descr_t *descriptions; +#endif struct setting_details *(*on_get_settings)(void); settings_changed_ptr on_changed; driver_settings_save_ptr save; diff --git a/stream.c b/stream.c index 9127085..5996518 100644 --- a/stream.c +++ b/stream.c @@ -35,6 +35,16 @@ typedef struct { static stream_state_t stream = {0}; +// called from stream drivers while tx is blocking, returns false to terminate +bool stream_tx_blocking (void) +{ + // TODO: Restructure st_prep_buffer() calls to be executed here during a long print. + + grbl.on_execute_realtime(state_get()); + + return !(sys.rt_exec_state & EXEC_RESET); +} + // "dummy" version of serialGetC int16_t stream_get_null (void) { diff --git a/stream.h b/stream.h index 8ed0527..6332e0a 100644 --- a/stream.h +++ b/stream.h @@ -255,6 +255,8 @@ bool stream_enable_mpg (const io_stream_t *mpg_stream, bool mpg_mode); bool stream_buffer_all (char c); +bool stream_tx_blocking (void); + #ifdef DEBUGOUT void debug_stream_init (io_stream_t *stream); #endif diff --git a/system.c b/system.c index bf002a2..e37e68f 100644 --- a/system.c +++ b/system.c @@ -39,9 +39,14 @@ static status_code_t enumerate_errors (sys_state_t state, char *args); static status_code_t enumerate_groups (sys_state_t state, char *args); static status_code_t enumerate_settings (sys_state_t state, char *args); static status_code_t enumerate_all (sys_state_t state, char *args); +static status_code_t enumerate_settings_grblformatted (sys_state_t state, char *args); +static status_code_t enumerate_settings_halformatted (sys_state_t state, char *args); static status_code_t enumerate_pins (sys_state_t state, char *args); static status_code_t output_settings (sys_state_t state, char *args); static status_code_t output_all_settings (sys_state_t state, char *args); +#ifndef NO_SETTINGS_DESCRIPTIONS +static status_code_t output_setting_description (sys_state_t state, char *args); +#endif static status_code_t output_parser_state (sys_state_t state, char *args); static status_code_t toggle_block_delete (sys_state_t state, char *args); static status_code_t toggle_single_block (sys_state_t state, char *args); @@ -168,52 +173,57 @@ status_code_t read_int (char *s, int32_t *value) } PROGMEM static const sys_command_t sys_commands[] = { - {"G", true, output_parser_state}, - {"J", false, jog}, - {"#", true, output_ngc_parameters}, - {"$", false, output_settings}, - {"+", false, output_all_settings}, - {"B", true, toggle_block_delete}, - {"S", true, toggle_single_block}, - {"O", true, toggle_optional_stop}, - {"C", true, check_mode}, - {"X", false, disable_lock}, - {"H", false, home}, - {"HX", false, home_x}, - {"HY", false, home_y}, - {"HZ", false, home_z}, + { "G", true, output_parser_state }, + { "J", false, jog }, + { "#", true, output_ngc_parameters }, + { "$", false, output_settings }, + { "+", false, output_all_settings }, +#ifndef NO_SETTINGS_DESCRIPTIONS + { "SED", false, output_setting_description }, +#endif + { "B", true, toggle_block_delete }, + { "S", true, toggle_single_block }, + { "O", true, toggle_optional_stop }, + { "C", true, check_mode }, + { "X", false, disable_lock }, + { "H", false, home }, + { "HX", false, home_x }, + { "HY", false, home_y }, + { "HZ", false, home_z }, #ifdef A_AXIS - {"HA", false, home_a}, + { "HA", false, home_a }, #endif #ifdef B_AXIS - {"HB", false, home_b}, + { "HB", false, home_b }, #endif #ifdef C_AXIS - {"HC", false, home_c}, + { "HC", false, home_c }, #endif - {"HELP", false, output_help}, - {"SLP", true, enter_sleep}, - {"TLR", true, set_tool_reference}, - {"TPW", true, tool_probe_workpiece}, - {"I", false, build_info}, - {"I+", true, output_all_build_info}, - {"RST", false, settings_reset}, - {"N", true, output_startup_lines}, - {"N0", false, set_startup_line0}, - {"N1", false, set_startup_line1}, - {"EA", true, enumerate_alarms}, - {"EE", true, enumerate_errors}, - {"EG", true, enumerate_groups}, - {"ES", true, enumerate_settings}, - {"E*", true, enumerate_all}, - {"PINS", true, enumerate_pins}, - {"RST", false, settings_reset}, - {"LEV", true, report_last_signals_event}, - {"LIM", true, report_current_limit_state}, - {"SD", false, report_spindle_data}, - {"SR", false, spindle_reset_data}, + { "HELP", false, output_help }, + { "SLP", true, enter_sleep }, + { "TLR", true, set_tool_reference }, + { "TPW", true, tool_probe_workpiece }, + { "I", false, build_info }, + { "I+", true, output_all_build_info }, + { "RST", false, settings_reset }, + { "N", true, output_startup_lines }, + { "N0", false, set_startup_line0 }, + { "N1", false, set_startup_line1 }, + { "EA", true, enumerate_alarms }, + { "EE", true, enumerate_errors }, + { "EG", true, enumerate_groups }, + { "ES", true, enumerate_settings }, + { "ESG", true, enumerate_settings_grblformatted }, + { "ESH", true, enumerate_settings_halformatted }, + { "E*", true, enumerate_all }, + { "PINS", true, enumerate_pins }, + { "RST", false, settings_reset }, + { "LEV", true, report_last_signals_event }, + { "LIM", true, report_current_limit_state }, + { "SD", false, report_spindle_data }, + { "SR", false, spindle_reset_data }, #ifdef DEBUGOUT - {"Q", true, output_memmap}, + { "Q", true, output_memmap }, #endif }; @@ -345,7 +355,17 @@ static status_code_t enumerate_groups (sys_state_t state, char *args) static status_code_t enumerate_settings (sys_state_t state, char *args) { - return report_settings_details(false, Setting_SettingsAll, Group_All); + return report_settings_details(SettingsFormat_MachineReadable, Setting_SettingsAll, Group_All); +} + +static status_code_t enumerate_settings_grblformatted (sys_state_t state, char *args) +{ + return report_settings_details(SettingsFormat_Grbl, Setting_SettingsAll, Group_All); +} + +static status_code_t enumerate_settings_halformatted (sys_state_t state, char *args) +{ + return report_settings_details(SettingsFormat_grblHAL, Setting_SettingsAll, Group_All); } static status_code_t enumerate_all (sys_state_t state, char *args) @@ -353,7 +373,7 @@ static status_code_t enumerate_all (sys_state_t state, char *args) report_alarm_details(); report_error_details(); report_setting_group_details(true, NULL); - return report_settings_details(false, Setting_SettingsAll, Group_All); + return report_settings_details(SettingsFormat_MachineReadable, Setting_SettingsAll, Group_All); } static status_code_t enumerate_pins (sys_state_t state, char *args) @@ -369,7 +389,7 @@ static status_code_t output_settings (sys_state_t state, char *args) int32_t id; retval = read_int(args, &id); if(retval == Status_OK && id >= 0) - retval = report_settings_details(true, (setting_id_t)id, Group_All); + retval = report_settings_details(SettingsFormat_HumanReadable, (setting_id_t)id, Group_All); } else if (state & (STATE_CYCLE|STATE_HOLD)) retval = Status_IdleError; // Block during cycle. Takes too long to print. else @@ -382,6 +402,24 @@ static status_code_t output_settings (sys_state_t state, char *args) return retval; } +#ifndef NO_SETTINGS_DESCRIPTIONS + +static status_code_t output_setting_description (sys_state_t state, char *args) +{ + status_code_t retval = Status_BadNumberFormat; + + if(args) { + int32_t id; + retval = read_int(args, &id); + if(retval == Status_OK && id >= 0) + retval = report_setting_description(SettingsFormat_MachineReadable, (setting_id_t)id); + } + + return retval; +} + +#endif + static status_code_t output_all_settings (sys_state_t state, char *args) { status_code_t retval = Status_OK; @@ -390,7 +428,7 @@ static status_code_t output_all_settings (sys_state_t state, char *args) int32_t id; retval = read_int(args, &id); if(retval == Status_OK && id >= 0) - retval = report_settings_details(true, (setting_id_t)id, Group_All); + retval = report_settings_details(SettingsFormat_HumanReadable, (setting_id_t)id, Group_All); } else if (state & (STATE_CYCLE|STATE_HOLD)) retval = Status_IdleError; // Block during cycle. Takes too long to print. else