Added (PRINT, <msg>) support and parameter formatting for DEBUG and PRINT commands.

Added named parameters for getting absolute (G53) position: _abs_x, abs_y, ...
Available when expression support is enabled.

Changed stepper enable HAL signature to allow current reduction when idle.
Added reference id to spindle registration in order to allow configuring default spindle, and possibly additional spindles, at compile time.
This commit is contained in:
Terje Io
2024-09-29 12:38:49 +07:00
parent 5d6a99c583
commit 323dd84b79
19 changed files with 281 additions and 91 deletions

View File

@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
---
Latest build date is 20240907, see the [changelog](changelog.md) for details.
Latest build date is 20240928, see the [changelog](changelog.md) for details.
__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.

View File

@@ -1,18 +1,42 @@
## grblHAL changelog
<a name="20240928">Build 20240928
* Added `(PRINT, <msg>)` support and parameter formatting for `DEBUG` and `PRINT` commands. Available when expression support is enabled.
* Added named parameters for getting absolute \(G53\) position: `_abs_x`, `abs_y`, ... Available when expression support is enabled.
* Changed stepper enable HAL signature to allow current reduction when idle. Requires compatible stepper drivers and low level code support.
* Added reference id to spindle registration in order to allow configuring default spindle, and possibly additional spindles, at compile time.
* Fix for hardfault when some $-settings are changed and there are no auxilary inputs defined in the board map. Ref. [issue #588](https://github.com/grblHAL/core/issues/588).
Drivers:
* All: updated for core changes mentioned above.
* ESP32, STM32F4xx, STM32F7xx: added basic support for the core HAL timer API. Changed step inject code to interrupt driven instead of polled.
Plugins:
* Spindle: updated to support new spindle reference id in the core, simplified code.
* SD Card \(macros\): fixed bug in handling of repeat loops.
---
<a name="20240921">Build 20240921
Core:
* Added generic HAL timer API and function for getting which `G65` parameter words were supplied.
Networking:
Plugins:
* Made parsing of HTTP header keywords case insensitive. Ref. [issue #11](https://github.com/grblHAL/Plugin_networking/issues/11).
* Networking: made parsing of HTTP header keywords case insensitive. Ref. [issue #11](https://github.com/grblHAL/Plugin_networking/issues/11).
SD card (macros):
* Added inbuilt `G65` macro `P3` for getting and setting NGC numerical parameters, typical use case will be for indexed access. Ref. [discussion #309 comment](https://github.com/grblHAL/core/discussions/309#discussioncomment-10710468).
* SD card \(macros\): added inbuilt `G65` macro `P3` for getting and setting NGC numerical parameters, typical use case will be for indexed access. Ref. [discussion #309 comment](https://github.com/grblHAL/core/discussions/309#discussioncomment-10710468).
---

View File

@@ -1115,6 +1115,14 @@ Default value is 0, meaning spindle sync is disabled
#endif
///@}
/*! @name $395 - Setting_SpindleType
*/
///@{
#if !defined DEFAULT_SPINDLE || defined __DOXYGEN__
#define DEFAULT_SPINDLE SPINDLE_PWM0 // Spindle number from spindle_control.h
#endif
///@}
// Closed loop spindle settings (Group_Spindle_ClosedLoop)
// $9 - Setting_SpindlePWMOptions

View File

@@ -225,40 +225,38 @@
#endif
#endif
// TODO: remove?
#ifndef VFD_SPINDLE
#if VFD_ENABLE
#define VFD_SPINDLE 1
#else
#define VFD_SPINDLE 0
#endif
#endif
#ifndef SPINDLE0_ENABLE
#if VFD_ENABLE
#define SPINDLE0_ENABLE VFD_ENABLE
#if N_SPINDLE > 1 && !defined(SPINDLE1_ENABLE)
#define SPINDLE1_ENABLE SPINDLE_PWM0
#endif
#else
#define SPINDLE0_ENABLE SPINDLE_PWM0
#endif
#define SPINDLE0_ENABLE SPINDLE_PWM0
#endif
#ifndef SPINDLE1_ENABLE
#define SPINDLE1_ENABLE 0
#elif SPINDLE1_ENABLE == -1 || SPINDLE1_ENABLE == SPINDLE_ALL || SPINDLE1_ENABLE == SPINDLE_ALL_VFD
#warning "SPINDLE1_ENABLE cannot be set to -1, SPINDLE_ALL or SPINDLE_ALL_VFD"
#undef SPINDLE1_ENABLE
#define SPINDLE1_ENABLE 0
#endif
#ifndef SPINDLE2_ENABLE
#define SPINDLE2_ENABLE 0
#elif SPINDLE2_ENABLE == -1 || SPINDLE2_ENABLE == SPINDLE_ALL || SPINDLE2_ENABLE == SPINDLE_ALL_VFD
#warning "SPINDLE2_ENABLE cannot be set to -1, SPINDLE_ALL or SPINDLE_ALL_VFD"
#undef SPINDLE2_ENABLE
#define SPINDLE2_ENABLE 0
#endif
#ifndef SPINDLE3_ENABLE
#define SPINDLE3_ENABLE 0
#elif SPINDLE3_ENABLE == -1 || SPINDLE3_ENABLE == SPINDLE_ALL || SPINDLE3_ENABLE == SPINDLE_ALL_VFD
#warning "SPINDLE3_ENABLE cannot be set to -1, SPINDLE_ALL or SPINDLE_ALL_VFD"
#undef SPINDLE1_ENABLE
#define SPINDLE1_ENABLE 0
#endif
#if SPINDLE0_ENABLE == SPINDLE_ALL
#define SPINDLE_ENABLE SPINDLE_ALL
#if SPINDLE0_ENABLE == -1 || SPINDLE0_ENABLE == SPINDLE_ALL
#define SPINDLE_ENABLE (SPINDLE_ALL|(1<<SPINDLE1_ENABLE)|(1<<SPINDLE2_ENABLE)|(1<<SPINDLE3_ENABLE))
#elif SPINDLE0_ENABLE == SPINDLE_ALL_VFD
#define SPINDLE_ENABLE (SPINDLE_ALL_VFD|SPINDLE_ALL|(1<<SPINDLE1_ENABLE)|(1<<SPINDLE2_ENABLE)|(1<<SPINDLE3_ENABLE))
#else
#define SPINDLE_ENABLE ((1<<SPINDLE0_ENABLE)|(1<<SPINDLE1_ENABLE)|(1<<SPINDLE2_ENABLE)|(1<<SPINDLE3_ENABLE))
#endif
@@ -314,7 +312,7 @@
//
#ifndef VFD_ENABLE
#if SPINDLE_ENABLE & ((1<<SPINDLE_HUANYANG1)|(1<<SPINDLE_HUANYANG2)|(1<<SPINDLE_GS20)|(1<<SPINDLE_YL620A)|(1<<SPINDLE_MODVFD)|(1<<SPINDLE_H100)|(1<<SPINDLE_NOWFOREVER))
#if SPINDLE_ENABLE & SPINDLE_ALL_VFD
#define VFD_ENABLE 1
#else
#define VFD_ENABLE 0

View File

@@ -113,6 +113,7 @@ typedef enum {
Status_FlowControlStackOverflow = 82,
Status_FlowControlOutOfMemory = 83,
Status_Handled, // For internal use only
Status_Unhandled, // For internal use only
Status_StatusMax = Status_Unhandled
} __attribute__ ((__packed__)) status_code_t;

165
gcode.c
View File

@@ -74,6 +74,7 @@ typedef union {
G15 :1, //!< [G7,G8] Lathe Diameter Mode
M4 :1, //!< [M0,M1,M2,M30] Stopping
M5 :1, //!< [M62,M63,M64,M65,M66,M67,M68] Aux I/O
M6 :1, //!< [M6] Tool change
M7 :1, //!< [M3,M4,M5] Spindle turning
M8 :1, //!< [M7,M8,M9] Coolant control
@@ -509,12 +510,66 @@ static status_code_t read_parameter (char *line, uint_fast8_t *char_counter, flo
return status;
}
static void substitute_parameters(char *comment, char **message) {
static int8_t get_format (char c, int8_t pos, uint8_t *decimals)
{
static uint8_t d;
// lcaps c?
switch(pos) {
case 1:
switch(c) {
case 'd':
*decimals = 0;
pos = -2;
break;
case 'f':
*decimals = ngc_float_decimals();
pos = -2;
break;
case '.':
pos = 2;
break;
default:
pos = 0;
break;
}
break;
case 2:
if(c >= '0' && c <= '9') {
d = c - '0';
pos = 3;
} else
pos = 0;
break;
default:
if(c == 'f') {
*decimals = d;
pos = -4;
} else
pos = 0;
break;
}
return pos;
}
static void substitute_parameters (char *comment, char **message)
{
size_t len = 0;
float value;
char *s3;
char *s, c;
uint_fast8_t char_counter = 0;
char c = *(comment + char_counter);
int8_t parse_format = 0;
uint8_t decimals = ngc_float_decimals(); // LinuxCNC is 1 (or l?)
// Trim leading spaces
while(*comment == ' ')
@@ -522,10 +577,17 @@ static void substitute_parameters(char *comment, char **message) {
// Calculate length of substituted string
while((c = comment[char_counter++])) {
if(c == '#') {
if(parse_format) {
if((parse_format = get_format(c, parse_format, &decimals)) < 0) {
len -= parse_format;
parse_format = 0;
}
} else if(c == '%')
parse_format = 1;
else if(c == '#') {
char_counter--;
if(read_parameter(comment, &char_counter, &value) == Status_OK)
len += strlen(trim_float(ftoa(value, ngc_float_decimals())));
len += strlen(decimals ? ftoa(value, decimals) : trim_float(ftoa(value, decimals)));
else
len += 3; // "N/A"
} else
@@ -533,22 +595,36 @@ static void substitute_parameters(char *comment, char **message) {
}
// Perform substitution
if((s3 = *message = malloc(len + 1))) {
if((s = *message = malloc(len + 1))) {
*s3 = '\0';
char fmt[5] = {0};
*s = '\0';
char_counter = 0;
while((c = comment[char_counter++])) {
if(c == '#') {
if(parse_format) {
fmt[parse_format] = c;
if((parse_format = get_format(c, parse_format, &decimals)) < 0)
parse_format = 0;
else if(parse_format == 0) {
strcat(s, fmt);
s = strchr(s, '\0');
continue;
}
} else if(c == '%') {
parse_format = 1;
fmt[0] = c;
} else if(c == '#') {
char_counter--;
if(read_parameter(comment, &char_counter, &value) == Status_OK)
strcat(s3, trim_float(ftoa(value, ngc_float_decimals())));
strcat(s, decimals ? ftoa(value, decimals) : trim_float(ftoa(value, decimals)));
else
strcat(s3, "N/A");
s3 = strchr(s3, '\0');
strcat(s, "N/A");
s = strchr(s, '\0');
} else {
*s3++ = c;
*s3 = '\0';
*s++ = c;
*s = '\0';
}
}
}
@@ -639,31 +715,35 @@ char *gc_normalize_block (char *block, char **message)
size_t len = s1 - comment - 4;
if(message && *message == NULL && !strncmp(comment, "(MSG,", 5) && (*message = malloc(len))) {
comment += 5;
if(message && *message == NULL) {
#if NGC_EXPRESSIONS_ENABLE
substitute_parameters(comment, message);
#else
while(*comment == ' ') {
comment++;
len--;
}
memcpy(*message, comment, len);
#endif
}
#if NGC_EXPRESSIONS_ENABLE
// Debug message string substitution
if(message && *message == NULL && !strncmp(comment, "(DEBUG,", 7)) {
if(settings.flags.ngc_debug_out) {
if(!strncmp(comment, "(DEBUG,", 7)) { // Debug message string substitution
if(settings.flags.ngc_debug_out) {
comment += 7;
substitute_parameters(comment, message);
}
*comment = '\0'; // Do not generate grbl.on_gcode_comment event!
} else if(!strncmp(comment, "(PRINT,", 7)) { // Print message string substitution
comment += 7;
substitute_parameters(comment, message);
*comment = '\0'; // Do not generate grbl.on_gcode_comment event!
} else if(!strncmp(comment, "(MSG,", 5)) {
comment += 5;
substitute_parameters(comment, message);
}
}
#else
if(!strncmp(comment, "(MSG,", 5) && (*message = malloc(len))) {
*comment = '\0'; // Do not generate grbl.on_gcode_comment event!
comment += 5;
while(*comment == ' ') {
comment++;
len--;
}
memcpy(*message, comment, len);
}
}
#endif // NGC_EXPRESSIONS_ENABLE
#endif
}
if(*comment && *message == NULL && grbl.on_gcode_comment)
@@ -679,7 +759,7 @@ char *gc_normalize_block (char *block, char **message)
}
#if NGC_EXPRESSIONS_ENABLE
if(comment && s1 - comment < (strncmp(comment, "(DEBU,", 5) ? 5 : 7))
if(comment && s1 - comment < (strncmp(comment, "(DEBU", 5) && strncmp(comment, "(PRIN", 5) ? 5 : 7))
*s1 = CAPS(c);
#else
if(comment && s1 - comment < 5)
@@ -1323,14 +1403,14 @@ status_code_t gc_execute_block (char *block)
case 65:
if(hal.port.digital_out == NULL || hal.port.num_digital_out == 0)
FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command]
word_bit.modal_group.M10 = On;
word_bit.modal_group.M5 = On;
port_command = (io_mcode_t)int_value;
break;
case 66:
if(hal.port.wait_on_input == NULL || (hal.port.num_digital_in == 0 && hal.port.num_analog_in == 0))
FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command]
word_bit.modal_group.M10 = On;
word_bit.modal_group.M5 = On;
port_command = (io_mcode_t)int_value;
break;
@@ -1338,7 +1418,7 @@ status_code_t gc_execute_block (char *block)
case 68:
if(hal.port.analog_out == NULL || hal.port.num_analog_out == 0)
FAIL(Status_GcodeUnsupportedCommand); // [Unsupported M command]
word_bit.modal_group.M10 = On;
word_bit.modal_group.M5 = On;
port_command = (io_mcode_t)int_value;
break;
@@ -2363,7 +2443,7 @@ status_code_t gc_execute_block (char *block)
// target position with the coordinate system offsets, G92 offsets, absolute override, and distance
// modes applied. This includes the motion mode commands. We can now pre-compute the target position.
// NOTE: Tool offsets may be appended to these conversions when/if this feature is added.
if (axis_words.mask && axis_command != AxisCommand_ToolLengthOffset) { // TLO block any axis command.
if((axis_words.mask || gc_block.modal.motion == MotionMode_CwArc || gc_block.modal.motion == MotionMode_CcwArc) && axis_command != AxisCommand_ToolLengthOffset) { // TLO block any axis command.
idx = N_AXIS;
do { // Axes indices are consistent, so loop may be used to save flash space.
if(bit_isfalse(axis_words.mask, bit(--idx)))
@@ -2724,13 +2804,13 @@ status_code_t gc_execute_block (char *block)
// point and the radius to the target point differs more than 0.002mm (EMC def. 0.5mm OR 0.005mm and 0.1% radius).
// [G2/3 Full-Circle-Mode Errors]: Axis words exist. No offsets programmed. P must be an integer.
// NOTE: Both radius and offsets are required for arc tracing and are pre-computed with the error-checking.
if (gc_block.words.r) { // Arc Radius Mode
if (!axis_words.mask)
FAIL(Status_GcodeNoAxisWords); // [No axis words]
if (!(axis_words.mask & (bit(plane.axis_0)|bit(plane.axis_1))))
FAIL(Status_GcodeNoAxisWordsInPlane); // [No axis words in plane]
}
if (gc_block.words.p) { // Number of turns
if(!isintf(gc_block.values.p))
FAIL(Status_GcodeCommandValueNotInteger); // [P word is not an integer]
@@ -3532,9 +3612,14 @@ status_code_t gc_execute_block (char *block)
ngc_named_param_set("_value", 0.0f);
ngc_named_param_set("_value_returned", 0.0f);
#endif
status_code_t status = grbl.on_macro_execute((macro_id_t)gc_block.values.p);
return status == Status_Unhandled ? Status_GcodeValueOutOfRange : status;
#if NGC_PARAMETERS_ENABLE
if(status != Status_Handled)
ngc_call_pop();
#endif
return status == Status_Unhandled ? Status_GcodeValueOutOfRange : (status == Status_Handled ? Status_OK : status);
}
break;

2
grbl.h
View File

@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20240921
#define GRBL_BUILD 20240928
#define GRBL_URL "https://github.com/grblHAL"

View File

@@ -283,7 +283,7 @@ int grbl_enter (void)
protocol_enqueue_foreground_task(report_driver_error, NULL);
}
hal.stepper.enable(settings.steppers.deenergize);
hal.stepper.enable(settings.steppers.energize, true);
spindle_all_off();
hal.coolant.set_state((coolant_state_t){0});

3
hal.h
View File

@@ -246,10 +246,11 @@ typedef void (*stepper_go_idle_ptr)(bool clear_signals);
/*! \brief Pointer to function for enabling/disabling stepper motors.
\param enable a \a axes_signals_t union containing separate flags for each motor to enable/disable.
\param hold a \a true to keep motor powered with reduced current, \a false otherwise.
__NOTE:__ this function may be called from an interrupt context.
*/
typedef void (*stepper_enable_ptr)(axes_signals_t enable);
typedef void (*stepper_enable_ptr)(axes_signals_t enable, bool hold);
/*! \brief Pointer to function for enabling/disabling step signals for individual motors.

View File

@@ -749,7 +749,7 @@ void ioport_setting_changed (setting_id_t id)
if(on_setting_changed)
on_setting_changed(id);
else switch(id) {
else if(digital.in.ports && digital.in.ports->n_ports) switch(id) {
case Setting_InvertProbePin:
case Setting_ProbePullUpDisable:

View File

@@ -404,8 +404,8 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
case NGCFlowCtrl_EndRepeat:
if(hal.stream.file) {
if(last_op == NGCFlowCtrl_Repeat) {
if(!skipping && o_label == stack[stack_idx].o_label) {
if(stack[stack_idx].repeats && --stack[stack_idx].repeats)
if(o_label == stack[stack_idx].o_label) {
if(!skipping && stack[stack_idx].repeats && --stack[stack_idx].repeats)
vfs_seek(stack[stack_idx].file, stack[stack_idx].file_pos);
else
stack_pull();

View File

@@ -87,6 +87,20 @@ static ngc_param_context_t call_levels[NGC_MAX_CALL_LEVEL];
static ngc_rw_param_t *rw_params = NULL;
static ngc_named_rw_param_t *rw_global_params = NULL;
static float _absolute_pos (uint_fast8_t axis)
{
float value;
if(axis < N_AXIS) {
value = sys.position[axis] / settings.axis[axis].steps_per_mm;
if(settings.flags.report_inches)
value *= 25.4f;
} else
value = 0.0f;
return value;
}
static float _relative_pos (uint_fast8_t axis)
{
float value;
@@ -373,6 +387,15 @@ PROGMEM static const ngc_named_ro_param_t ngc_named_ro_param[] = {
{ .name = "_u", .id = NGCParam_u },
{ .name = "_v", .id = NGCParam_v },
{ .name = "_w", .id = NGCParam_w },
{ .name = "_abs_x", .id = NGCParam_abs_x },
{ .name = "_abs_y", .id = NGCParam_abs_y },
{ .name = "_abs_z", .id = NGCParam_abs_z },
{ .name = "_abs_a", .id = NGCParam_abs_a },
{ .name = "_abs_b", .id = NGCParam_abs_b },
{ .name = "_abs_c", .id = NGCParam_abs_c },
{ .name = "_abs_u", .id = NGCParam_abs_u },
{ .name = "_abs_v", .id = NGCParam_abs_v },
{ .name = "_abs_w", .id = NGCParam_abs_w },
{ .name = "_current_tool", .id = NGCParam_current_tool },
{ .name = "_current_pocket", .id = NGCParam_current_pocket },
{ .name = "_selected_tool", .id = NGCParam_selected_tool },
@@ -544,6 +567,26 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
value = _relative_pos(id - NGCParam_x);
break;
case NGCParam_abs_x:
//no break
case NGCParam_abs_y:
//no break
case NGCParam_abs_z:
//no break
case NGCParam_abs_a:
//no break
case NGCParam_abs_b:
//no break
case NGCParam_abs_c:
//no break
case NGCParam_abs_u:
//no break
case NGCParam_abs_v:
//no break
case NGCParam_abs_w:
value = _absolute_pos(id - NGCParam_abs_x);
break;
case NGCParam_current_tool:
value = (float)gc_state.tool->tool_id;
break;

View File

@@ -79,6 +79,15 @@ typedef enum {
NGCParam_u,
NGCParam_v,
NGCParam_w,
NGCParam_abs_x,
NGCParam_abs_y,
NGCParam_abs_z,
NGCParam_abs_a,
NGCParam_abs_b,
NGCParam_abs_c,
NGCParam_abs_u,
NGCParam_abs_v,
NGCParam_abs_w,
NGCParam_current_tool,
NGCParam_current_pocket,
NGCParam_selected_tool,

View File

@@ -229,6 +229,9 @@ static status_code_t report_status_message (status_code_t status_code)
{
switch(status_code) {
case Status_Handled:
status_code = Status_OK;
// no break
case Status_OK: // STATUS_OK
hal.stream.write("ok" ASCII_EOL);
break;
@@ -499,7 +502,7 @@ void report_grbl_settings (bool all, void *data)
if(all && (details = details->next)) do {
for(idx = 0; idx < details->n_settings; idx++) {
setting = &details->settings[idx];
if(setting->is_available == NULL ||setting->is_available(setting)) {
if(setting->is_available == NULL || setting->is_available(setting)) {
*psetting++ = (setting_detail_t *)setting;
n_settings++;
}

View File

@@ -101,7 +101,7 @@ PROGMEM const settings_t defaults = {
#else
.steppers.enable_invert.mask = AXES_BITMASK,
#endif
.steppers.deenergize.mask = DEFAULT_STEPPER_DEENERGIZE_MASK,
.steppers.energize.mask = DEFAULT_STEPPER_DEENERGIZE_MASK,
#if N_AXIS > 3
.steppers.is_rotary.mask = (DEFAULT_AXIS_ROTATIONAL_MASK & AXES_BITMASK) & 0b11111000,
.steppers.rotary_wrap.mask = (DEFAULT_AXIS_ROTARY_WRAP_MASK & AXES_BITMASK) & 0b11111000,
@@ -396,7 +396,7 @@ static status_code_t set_tool_change_mode (setting_id_t id, uint_fast16_t int_va
static status_code_t set_tool_change_probing_distance (setting_id_t id, float value);
static status_code_t set_tool_restore_pos (setting_id_t id, uint_fast16_t int_value);
static status_code_t set_ganged_dir_invert (setting_id_t id, uint_fast16_t int_value);
static status_code_t set_stepper_deenergize_mask (setting_id_t id, uint_fast16_t int_value);
static status_code_t set_stepper_energize_mask (setting_id_t id, uint_fast16_t int_value);
static status_code_t set_report_interval (setting_id_t setting, uint_fast16_t int_value);
static status_code_t set_estop_unlock (setting_id_t id, uint_fast16_t int_value);
#if COMPATIBILITY_LEVEL <= 1
@@ -538,7 +538,7 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ 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_IsExtendedFn, set_stepper_deenergize_mask, get_int, NULL },
{ Setting_SteppersEnergize, Group_Stepper, "Steppers to keep enabled", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_stepper_energize_mask, get_int, 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, { .reboot_required = On } },
{ 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 },
@@ -710,7 +710,7 @@ PROGMEM static const setting_descr_t setting_descr[] = {
{ 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_SteppersEnergize, "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." },
@@ -956,11 +956,11 @@ static status_code_t set_ganged_dir_invert (setting_id_t id, uint_fast16_t int_v
return Status_OK;
}
static status_code_t set_stepper_deenergize_mask (setting_id_t id, uint_fast16_t int_value)
static status_code_t set_stepper_energize_mask (setting_id_t id, uint_fast16_t int_value)
{
settings.steppers.deenergize.mask = int_value;
settings.steppers.energize.mask = int_value;
hal.stepper.enable(settings.steppers.deenergize);
hal.stepper.enable(settings.steppers.energize, true);
return Status_OK;
}
@@ -1468,7 +1468,8 @@ inline static setting_id_t normalize_id (setting_id_t id)
(id > Setting_MacroPort0 && id <= Setting_MacroPort9) ||
(id > Setting_ButtonAction0 && id <= Setting_ButtonAction9) ||
(id > Setting_Action0 && id <= Setting_Action9) ||
(id > Setting_ActionPort0 && id <= Setting_ActionPort9))
(id > Setting_ActionPort0 && id <= Setting_ActionPort9) ||
(id > Setting_SpindleToolStart0 && id <= Setting_SpindleToolStart7))
id = (setting_id_t)(id - (id % 10));
return id;
@@ -1702,8 +1703,8 @@ static uint32_t get_int (setting_id_t id)
#endif
break;
case Setting_StepperDeenergizeMask:
value = settings.steppers.deenergize.mask;
case Setting_SteppersEnergize:
value = settings.steppers.energize.mask;
break;
case Setting_EnableLegacyRTCommands:
@@ -2271,6 +2272,15 @@ void settings_write_global (void)
hal.nvs.memcpy_to_nvs(NVS_ADDR_GLOBAL, (uint8_t *)&settings, sizeof(settings_t), true);
}
#if N_SPINDLE > 1
static void get_default_spindle (spindle_info_t *spindle, void *data)
{
if(spindle->ref_id == (uint8_t)((uint32_t)data))
settings.spindle.flags.type = spindle->id;
}
#endif
// Restore global settings to defaults and write to persistent storage
void settings_restore (settings_restore_t restore)
@@ -2283,7 +2293,7 @@ void settings_restore (settings_restore_t restore)
hal.nvs.put_byte(0, SETTINGS_VERSION); // Forces write to physical storage
if (restore.defaults) {
if(restore.defaults) {
memcpy(&settings, &defaults, sizeof(settings_t));
@@ -2294,6 +2304,9 @@ void settings_restore (settings_restore_t restore)
#if ENABLE_BACKLASH_COMPENSATION
if(sys.driver_started)
mc_backlash_init((axes_signals_t){AXES_BITMASK});
#endif
#if N_SPINDLE > 1
spindle_enumerate_spindles(get_default_spindle, (void *)DEFAULT_SPINDLE);
#endif
settings_write_global();
}

View File

@@ -81,7 +81,7 @@ typedef enum {
Setting_PWMOffValue = 34,
Setting_PWMMinValue = 35,
Setting_PWMMaxValue = 36,
Setting_StepperDeenergizeMask = 37,
Setting_SteppersEnergize = 37,
Setting_SpindlePPR = 38,
Setting_EnableLegacyRTCommands = 39,
Setting_JogSoftLimited = 40,
@@ -700,7 +700,7 @@ typedef struct {
axes_signals_t dir_invert;
axes_signals_t ganged_dir_invert; // applied after inversion for the master motor
axes_signals_t enable_invert;
axes_signals_t deenergize;
axes_signals_t energize;
#if N_AXIS > 3
axes_signals_t is_rotary; // rotary axes distances are not scaled in imperial mode
axes_signals_t rotary_wrap; // rotary axes that allows G28 wrap for faster move to home position

View File

@@ -370,6 +370,7 @@ bool spindle_enumerate_spindles (spindle_enumerate_callback_ptr callback, void *
for(idx = 0; idx < n_spindle; idx++) {
spindle.id = idx;
spindle.ref_id = spindles[idx].cfg->ref_id;
spindle.name = spindles[idx].name;
spindle.num = spindle_get_num(idx);
spindle.enabled = spindle.num != -1;

View File

@@ -26,7 +26,6 @@
#include "pid.h"
#define SPINDLE_ALL -1
#define SPINDLE_NONE 0
#define SPINDLE_HUANYANG1 1
#define SPINDLE_HUANYANG2 2
@@ -50,6 +49,9 @@
#define SPINDLE_NOWFOREVER 20
#define SPINDLE_MY_SPINDLE 30
#define SPINDLE_ALL_VFD ((1<<SPINDLE_HUANYANG1)|(1<<SPINDLE_HUANYANG2)|(1<<SPINDLE_GS20)|(1<<SPINDLE_YL620A)|(1<<SPINDLE_MODVFD)|(1<<SPINDLE_H100)|(1<<SPINDLE_NOWFOREVER))
#define SPINDLE_ALL (SPINDLE_ALL_VFD|(1<<SPINDLE_PWM0))
typedef int8_t spindle_id_t;
typedef int8_t spindle_num_t;
@@ -266,7 +268,8 @@ typedef union
/*! \brief Handlers and data for spindle support. */
struct spindle_ptrs {
spindle_id_t id; //!< Spindle id, assingned on spindle registration.
spindle_id_t id; //!< Spindle id, assigned on spindle registration.
uint8_t ref_id; //!< Spindle id, assigned on spindle registration.
struct spindle_param *param; //!< Pointer to current spindle parameters, assigned when spindle is enabled.
spindle_type_t type; //!< Spindle type.
spindle_cap_t cap; //!< Spindle capabilities.
@@ -320,6 +323,7 @@ typedef struct {
/*! \brief Structure holding data passed to the callback function called by spindle_enumerate_spindles(). */
typedef struct {
spindle_id_t id;
uint8_t ref_id;
spindle_num_t num;
const char *name;
bool enabled;

View File

@@ -183,7 +183,7 @@ extern void gc_output_message (char *message);
void st_deenergize (void *data)
{
if(sys.steppers_deenergize) {
hal.stepper.enable(settings.steppers.deenergize);
hal.stepper.enable(settings.steppers.energize, true);
sys.steppers_deenergize = false;
}
}
@@ -211,7 +211,7 @@ ISR_CODE void ISR_FUNC(st_go_idle)(void)
// Set stepper driver idle state, disabled or enabled, depending on settings and circumstances.
if(((settings.steppers.idle_lock_time != 255) || sys.rt_exec_alarm || state == STATE_SLEEP) && state != STATE_HOMING) {
if(settings.steppers.idle_lock_time == 0 || state == STATE_SLEEP)
hal.stepper.enable((axes_signals_t){0});
hal.stepper.enable((axes_signals_t){0}, true);
else {
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
// stop and not drift from residual inertial forces at the end of the last movement.
@@ -219,7 +219,7 @@ ISR_CODE void ISR_FUNC(st_go_idle)(void)
sys.steppers_deenergize = task_add_delayed(st_deenergize, NULL, settings.steppers.idle_lock_time);
}
} else
hal.stepper.enable(settings.steppers.idle_lock_time == 255 ? (axes_signals_t){AXES_BITMASK} : settings.steppers.deenergize);
hal.stepper.enable(settings.steppers.idle_lock_time == 255 ? (axes_signals_t){AXES_BITMASK} : settings.steppers.energize, true);
}