diff --git a/README.md b/README.md
index 4eb6a1a..17dae85 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
## grblHAL ##
-Latest build date is 20250910, see the [changelog](changelog.md) for details.
+Latest build date is 20250922, see the [changelog](changelog.md) for details.
> [!NOTE]
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.
diff --git a/changelog.md b/changelog.md
index 8e39c7f..e789733 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,10 +1,29 @@
## grblHAL changelog
+Build 20250922
+
+* added `G65P6` for disabling spindle on/off delay for the next spindle command (`M3`, `M4` and `M5`)
+
+* for programmers: added `grbl.on_control_signals_changed` event, fired on some signals: optional stop, single step, block delete and cycle start.
+
+* fix for incorrect handling of arcs when negative scaling is enabled with `G51`.
+
+Drivers:
+
+* STM32F4xx: added tentative support for THCAD2 voltage to frequency converter - for use by plasma plugin.
+
+Plugins:
+
+* Networking: httpd - fix/workaround for network stack failure when attempting to send data from flash via DMA. Only seen with the _STM32F407VET6_DEV_ board.
+
+* Misc, eventout: added _Motion_ event \(trigged by RUN, JOG and HOMING states\) and toggle events for optional stop, single step and block delete signals.
+Ref. discussion [#813](https://github.com/grblHAL/core/discussions/813).
+
Build 20250910
Core:
-* Added setting options for clearing rapids and feed overrids on soft reset to `$676`, defaults to on. Ref. issue [#803](https://github.com/grblHAL/core/issues/803).
+* Added setting options for clearing rapids and feed override on soft reset to `$676`, defaults to on. Ref. issue [#803](https://github.com/grblHAL/core/issues/803).
* Added realtime report of distance-to-go. Ref. PR [#802](https://github.com/grblHAL/core/pull/802).
diff --git a/core_handlers.h b/core_handlers.h
index 8ddbf56..1adf43a 100644
--- a/core_handlers.h
+++ b/core_handlers.h
@@ -95,6 +95,7 @@ typedef void (*on_program_completed_ptr)(program_flow_t program_flow, bool check
typedef void (*on_execute_realtime_ptr)(sys_state_t state);
typedef void (*on_unknown_accessory_override_ptr)(uint8_t cmd);
typedef void (*on_cycle_start_ptr)(void);
+typedef void (*on_control_signals_changed_ptr)(control_signals_t signals);
typedef bool (*on_unknown_realtime_cmd_ptr)(char c);
typedef void (*on_report_handlers_init_ptr)(void);
typedef void (*on_report_options_ptr)(bool newopt);
@@ -233,9 +234,9 @@ typedef struct {
on_unknown_accessory_override_ptr on_unknown_accessory_override;
on_report_options_ptr on_report_options;
on_report_ngc_parameters_ptr on_report_ngc_parameters;
- on_report_command_help_ptr on_report_command_help; //!< Deprecated, use system_register_commands() to register new commands.
+ on_report_command_help_ptr on_report_command_help; //!< Deprecated, use system_register_commands() to register new commands.
on_rt_reports_added_ptr on_rt_reports_added;
- on_settings_changed_ptr on_settings_changed; //!< Called on initial settings load and on setting changes.
+ on_settings_changed_ptr on_settings_changed; //!< Called on initial settings load and on setting changes.
on_global_settings_restore_ptr on_global_settings_restore;
on_setting_get_description_ptr on_setting_get_description;
on_get_alarms_ptr on_get_alarms;
@@ -243,10 +244,11 @@ typedef struct {
on_get_settings_ptr on_get_settings;
on_realtime_report_ptr on_realtime_report;
on_unknown_feedback_message_ptr on_unknown_feedback_message;
- on_cycle_start_ptr on_cycle_start; //!< Called from interrupt context. NOTE: this is for the cycle start signal.
- on_unknown_realtime_cmd_ptr on_unknown_realtime_cmd; //!< Called from interrupt context.
- on_unknown_sys_command_ptr on_unknown_sys_command; //!< return Status_Unhandled if not handled.
- on_get_commands_ptr on_get_commands; //!< Deprecated, use system_register_commands() to register new commands.
+ on_cycle_start_ptr on_cycle_start; //!< Called from interrupt context. NOTE: this is for the cycle start signal.
+ on_control_signals_changed_ptr on_control_signals_changed; //!< Called from interrupt context. NOTE: this is only for cycle start and some of the optional signals.
+ on_unknown_realtime_cmd_ptr on_unknown_realtime_cmd; //!< Called from interrupt context.
+ on_unknown_sys_command_ptr on_unknown_sys_command; //!< Return Status_Unhandled if not handled.
+ on_get_commands_ptr on_get_commands; //!< Deprecated, use system_register_commands() to register new commands.
on_user_command_ptr on_user_command;
on_stream_changed_ptr on_stream_changed;
on_homing_rate_set_ptr on_homing_rate_set;
@@ -256,20 +258,20 @@ typedef struct {
on_probe_completed_ptr on_probe_completed;
on_set_axis_setting_unit_ptr on_set_axis_setting_unit;
on_process_gcode_comment_ptr on_process_gcode_comment;
- on_gcode_message_ptr on_gcode_message; //!< Called on output of message parsed from gcode. NOTE: string pointed to is freed after this call.
- on_gcode_message_ptr on_gcode_comment; //!< Called when a plain gcode comment has been parsed.
- on_tool_selected_ptr on_tool_selected; //!< Called prior to executing M6 or after executing M61.
- on_tool_changed_ptr on_tool_changed; //!< Called after executing M6 or M61.
- on_toolchange_ack_ptr on_toolchange_ack; //!< Called from interrupt context.
- on_jog_cancel_ptr on_jog_cancel; //!< Called from interrupt context.
+ on_gcode_message_ptr on_gcode_message; //!< Called on output of message parsed from gcode. NOTE: string pointed to is freed after this call.
+ on_gcode_message_ptr on_gcode_comment; //!< Called when a plain gcode comment has been parsed.
+ on_tool_selected_ptr on_tool_selected; //!< Called prior to executing M6 or after executing M61.
+ on_tool_changed_ptr on_tool_changed; //!< Called after executing M6 or M61.
+ on_toolchange_ack_ptr on_toolchange_ack; //!< Called from interrupt context.
+ on_jog_cancel_ptr on_jog_cancel; //!< Called from interrupt context.
on_laser_ppi_enable_ptr on_laser_ppi_enable;
- on_spindle_select_ptr on_spindle_select; //!< Called before spindle is selected, hook in HAL overrides here
- on_spindle_selected_ptr on_spindle_selected; //!< Called when spindle is selected, do not change HAL pointers here!
- on_reset_ptr on_reset; //!< Called from interrupt context.
- on_file_demarcate_ptr on_file_demarcate; //!< Called when percent sign is parsed in the gcode stream.
- on_file_open_ptr on_file_open; //!< Called when a file is opened for streaming.
- on_file_end_ptr on_file_end; //!< Called when a file opened for streaming reaches the end.
- user_mcode_ptrs_t user_mcode; //!< Optional handlers for user defined M-codes.
+ on_spindle_select_ptr on_spindle_select; //!< Called before spindle is selected, hook in HAL overrides here
+ on_spindle_selected_ptr on_spindle_selected; //!< Called when spindle is selected, do not change HAL pointers here!
+ on_reset_ptr on_reset; //!< Called from interrupt context.
+ on_file_demarcate_ptr on_file_demarcate; //!< Called when percent sign is parsed in the gcode stream.
+ on_file_open_ptr on_file_open; //!< Called when a file is opened for streaming.
+ on_file_end_ptr on_file_end; //!< Called when a file opened for streaming reaches the end.
+ user_mcode_ptrs_t user_mcode; //!< Optional handlers for user defined M-codes.
// core entry points - set up by core before driver_init() is called.
home_machine_ptr home_machine;
travel_limits_ptr check_travel_limits;
diff --git a/gcode.c b/gcode.c
index b761626..b77ffe8 100644
--- a/gcode.c
+++ b/gcode.c
@@ -2840,13 +2840,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]
@@ -2862,6 +2862,9 @@ status_code_t gc_execute_block (char *block)
x = gc_block.values.xyz[plane.axis_0] - gc_state.position[plane.axis_0]; // Delta x between current position and target
y = gc_block.values.xyz[plane.axis_1] - gc_state.position[plane.axis_1]; // Delta y between current position and target
+ if(gc_state.modal.scaling_active && scale_factor.ijk[plane.axis_0] * scale_factor.ijk[plane.axis_1] < 0.0f)
+ gc_parser_flags.arc_is_clockwise = !gc_parser_flags.arc_is_clockwise;
+
if (gc_block.words.r) { // Arc Radius Mode
gc_block.words.r = Off;
@@ -3446,6 +3449,8 @@ status_code_t gc_execute_block (char *block)
spindle_event = !spindle_ok;
}
+ sys.override.control.spindle_wait_disable = Off;
+
if(spindle_event && grbl.on_spindle_programmed)
grbl.on_spindle_programmed(sspindle->hal, sspindle->state, plan_data.spindle.rpm, sspindle->rpm_mode);
}
diff --git a/gcode.h b/gcode.h
index 5fc66fc..83a30da 100644
--- a/gcode.h
+++ b/gcode.h
@@ -341,12 +341,13 @@ typedef union {
typedef union {
uint8_t value;
struct {
- uint8_t feed_rate_disable :1,
- feed_hold_disable :1,
- spindle_rpm_disable :1,
- parking_disable :1,
- reserved :3,
- sync :1;
+ uint8_t feed_rate_disable :1,
+ feed_hold_disable :1,
+ spindle_rpm_disable :1,
+ parking_disable :1,
+ spindle_wait_disable :1,
+ reserved :2,
+ sync :1;
};
} gc_override_flags_t;
diff --git a/grbl.h b/grbl.h
index d9a777f..1fa1a95 100644
--- a/grbl.h
+++ b/grbl.h
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
-#define GRBL_BUILD 20250910
+#define GRBL_BUILD 20250922
#define GRBL_URL "https://github.com/grblHAL"
diff --git a/ngc_params.c b/ngc_params.c
index 9da2807..27a9945 100644
--- a/ngc_params.c
+++ b/ngc_params.c
@@ -95,32 +95,30 @@ static ngc_string_id_t ref_id = (uint32_t)-1;
static ngc_string_param_t *ngc_string_params = NULL;
static on_macro_execute_ptr on_macro_execute;
+#if N_AXIS > 3
+
+static float _convert_pos (float value, uint_fast8_t axis)
+{
+ return settings.flags.report_inches && bit_isfalse(settings.steppers.is_rotary.mask, bit(idx)) ? value * 25.4f : value;
+}
+
+#else
+
+static inline float _convert_pos (float value, uint_fast8_t axis)
+{
+ return settings.flags.report_inches ? value * 25.4f : value;
+}
+
+#endif
+
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;
+ return _convert_pos(axis < N_AXIS ? sys.position[axis] / settings.axis[axis].steps_per_mm : 0.0f, axis);
}
static float _relative_pos (uint_fast8_t axis)
{
- float value;
-
- if(axis < N_AXIS) {
- value = sys.position[axis] / settings.axis[axis].steps_per_mm - gc_get_offset(axis, false);
- if(settings.flags.report_inches)
- value *= 25.4f;
- } else
- value = 0.0f;
-
- return value;
+ return _convert_pos(axis < N_AXIS ? sys.position[axis] / settings.axis[axis].steps_per_mm - gc_get_offset(axis, false) : 0.0f, axis);
}
// numbered parameters
@@ -131,14 +129,11 @@ static float probe_coord (ngc_param_id_t id)
uint_fast8_t axis = (id % 10) - 1;
coord_system_t data;
- if(axis < N_AXIS && (sys.probe_coordsys_id == gc_state.modal.coord_system.id || settings_read_coord_data(sys.probe_coordsys_id, &data.xyz))) {
+ if(axis < N_AXIS && (sys.probe_coordsys_id == gc_state.modal.coord_system.id || settings_read_coord_data(sys.probe_coordsys_id, &data.xyz)))
value = sys.probe_position[axis] / settings.axis[axis].steps_per_mm -
(sys.probe_coordsys_id == gc_state.modal.coord_system.id ? gc_state.modal.coord_system.xyz[axis] : data.xyz[axis]);
- if(settings.flags.report_inches)
- value *= 25.4f;
- }
- return value;
+ return _convert_pos(value, axis);
}
static float scaling_factors (ngc_param_id_t id)
@@ -242,13 +237,7 @@ static float g92_offset (ngc_param_id_t id)
static float work_position (ngc_param_id_t id)
{
- float value = 0.0f;
- uint_fast8_t axis = id % 10;
-
- if(axis < N_AXIS)
- value = _relative_pos(axis);
-
- return value;
+ return _relative_pos(id % 10);
}
static float debug_output (ngc_param_id_t id)
@@ -1139,6 +1128,11 @@ static status_code_t onMacroExecute (macro_id_t macro_id)
case G65Macro_SelectProbe:
status = macro_select_probe();
break;
+
+ case G65Macro_SpindleDelayDisable:
+ sys.override.control.spindle_wait_disable = On;
+ status = Status_OK;
+ break;
}
return status == Status_Unhandled && on_macro_execute ? on_macro_execute(macro_id) : status;
diff --git a/ngc_params.h b/ngc_params.h
index 12c40b5..d6152ce 100644
--- a/ngc_params.h
+++ b/ngc_params.h
@@ -109,11 +109,12 @@ typedef enum {
} ncg_name_param_id_t;
typedef enum {
- G65Macro_GetSetting = 1,
- G65Macro_GetToolOffset = 2,
- G65Macro_ParameterRW = 3,
- G65Macro_GetMachineState = 4,
- G65Macro_SelectProbe = 5
+ G65Macro_GetSetting = 1,
+ G65Macro_GetToolOffset = 2,
+ G65Macro_ParameterRW = 3,
+ G65Macro_GetMachineState = 4,
+ G65Macro_SelectProbe = 5,
+ G65Macro_SpindleDelayDisable = 6
} g65_inbuilt_t;
void ngc_params_init (void);
diff --git a/protocol.c b/protocol.c
index 9339458..8b0353d 100644
--- a/protocol.c
+++ b/protocol.c
@@ -826,6 +826,7 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
static bool esc = false;
bool drop = false;
+ control_signals_t signals = {};
// 1. Process characters in the ranges 0x - 1x and 8x-Ax
// Characters with functions assigned are always acted upon even when the input stream
@@ -886,12 +887,7 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
break;
case CMD_CYCLE_START:
- system_set_exec_state_flag(EXEC_CYCLE_START);
- // Cancel any pending tool change
- gc_state.tool_change = false;
- drop = true;
- if(grbl.on_cycle_start)
- grbl.on_cycle_start();
+ signals.cycle_start = On;
break;
case CMD_FEED_HOLD:
@@ -929,12 +925,12 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
break;
case CMD_OPTIONAL_STOP_TOGGLE:
- if(!hal.signals_cap.stop_disable) // Not available as realtime command if HAL supports physical switch
+ if((signals.stop_disable = !hal.signals_cap.stop_disable)) // Not available as realtime command if HAL supports physical switch
sys.flags.optional_stop_disable = !sys.flags.optional_stop_disable;
break;
case CMD_SINGLE_BLOCK_TOGGLE:
- if(!hal.signals_cap.single_block) // Not available as realtime command if HAL supports physical switch
+ if((signals.single_block = !hal.signals_cap.single_block)) // Not available as realtime command if HAL supports physical switch
sys.flags.single_block = !sys.flags.single_block;
break;
@@ -1007,14 +1003,7 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
break;
case CMD_CYCLE_START_LEGACY:
- if(!keep_rt_commands || settings.flags.legacy_rt_commands) {
- system_set_exec_state_flag(EXEC_CYCLE_START);
- // Cancel any pending tool change
- gc_state.tool_change = false;
- drop = true;
- if(grbl.on_cycle_start)
- grbl.on_cycle_start();
- }
+ signals.cycle_start = !keep_rt_commands || settings.flags.legacy_rt_commands;
break;
case CMD_FEED_HOLD_LEGACY:
@@ -1031,6 +1020,21 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
esc = c == ASCII_ESC;
+ if(signals.bits) {
+
+ if(grbl.on_control_signals_changed)
+ grbl.on_control_signals_changed(signals);
+
+ if(signals.cycle_start) {
+ system_set_exec_state_flag(EXEC_CYCLE_START);
+ // Cancel any pending tool change
+ gc_state.tool_change = false;
+ drop = true;
+ if(grbl.on_cycle_start)
+ grbl.on_cycle_start();
+ }
+ }
+
return drop;
}
diff --git a/settings.c b/settings.c
index 28ab47a..e77dd9c 100644
--- a/settings.c
+++ b/settings.c
@@ -2073,17 +2073,17 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ Setting_ParkingEnable, Group_SafetyDoor, "Parking cycle", NULL, Format_XBitfield, "Enable,Deactivate upon init,Enable parking override control", 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_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_HomingCycle_1, Group_Homing, "Axes homing, first phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
+ { Setting_HomingCycle_2, Group_Homing, "Axes homing, second phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
+ { Setting_HomingCycle_3, Group_Homing, "Axes homing, third phase", 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 phase", 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 phase", 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 phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
#endif
{ 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 },
@@ -2250,17 +2250,17 @@ PROGMEM static const setting_descr_t setting_descr[] = {
{ 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." },
+ { Setting_HomingCycle_1, "Axes to home in first phase." },
+ { Setting_HomingCycle_2, "Axes to home in second phase." },
+ { Setting_HomingCycle_3, "Axes to home in third phase." },
#ifdef A_AXIS
- { Setting_HomingCycle_4, "Axes to home in fourth pass." },
+ { Setting_HomingCycle_4, "Axes to home in fourth phase." },
#endif
#ifdef B_AXIS
- { Setting_HomingCycle_5, "Axes to home in fifth pass." },
+ { Setting_HomingCycle_5, "Axes to home in fifth phase." },
#endif
#ifdef C_AXIS
- { Setting_HomingCycle_6, "Axes to home in sixth pass." },
+ { Setting_HomingCycle_6, "Axes to home in sixth phase." },
#endif
{ Setting_JogStepSpeed, "Step jogging speed in millimeters per minute." },
{ Setting_JogSlowSpeed, "Slow jogging speed in millimeters per minute." },
diff --git a/spindle_control.c b/spindle_control.c
index ebd98cf..dc7f6b0 100644
--- a/spindle_control.c
+++ b/spindle_control.c
@@ -631,25 +631,30 @@ static bool spindle_set_state_wait (spindle_ptrs_t *spindle, spindle_state_t sta
if((ok = spindle_set_state(spindle, state, rpm))) {
- bool at_speed = !spindle->cap.at_speed || spindle->cap.torch || spindle->at_speed_tolerance <= 0.0f;
+ if(sys.override.control.spindle_wait_disable) {
+ sys.override.control.spindle_wait_disable = Off;
+ } else {
- if(at_speed)
- ok = delay_ms == 0 || spindle->cap.torch || delay_sec((float)delay_ms / 1000.0f, delay_mode);
- else {
- uint16_t delay = 0;
- if(delay_ms == 0)
- delay_ms = 60000; // one minute...
- while(!(at_speed = spindle->get_state(spindle).at_speed)) {
- if(!delay_sec(0.2f, delay_mode))
- break;
- delay += 200;
- if(delay > delay_ms) {
- gc_spindle_off();
- system_raise_alarm(Alarm_Spindle);
- break;
+ bool at_speed = !spindle->cap.at_speed || spindle->cap.torch || spindle->at_speed_tolerance <= 0.0f;
+
+ if(at_speed)
+ ok = delay_ms == 0 || spindle->cap.torch || delay_sec((float)delay_ms / 1000.0f, delay_mode);
+ else {
+ uint16_t delay = 0;
+ if(delay_ms == 0)
+ delay_ms = 60000; // one minute...
+ while(!(at_speed = spindle->get_state(spindle).at_speed)) {
+ if(!delay_sec(0.2f, delay_mode))
+ break;
+ delay += 200;
+ if(delay > delay_ms) {
+ gc_spindle_off();
+ system_raise_alarm(Alarm_Spindle);
+ break;
+ }
}
+ ok &= at_speed;
}
- ok &= at_speed;
}
}
diff --git a/state_machine.c b/state_machine.c
index 62ffcdf..cc9d637 100644
--- a/state_machine.c
+++ b/state_machine.c
@@ -520,7 +520,7 @@ static void state_await_hold (uint_fast16_t rt_exec)
// Ensure any prior spindle stop override is disabled at start of safety door routine.
sys.override.spindle_stop.value = 0;
- // Parking requires parking axis homed, the current location not exceeding the???
+ // Parking requires parking axis homed, the current location not exceeding the
// parking target location, and laser mode disabled.
if (settings.parking.flags.enabled && !sys.override.control.parking_disable && settings.mode != Mode_Laser) {
diff --git a/system.c b/system.c
index da18188..811a9fa 100644
--- a/system.c
+++ b/system.c
@@ -77,6 +77,8 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
if(signals.bits) {
+ control_signals_t event_signals = {};
+
sys.last_event.control.bits = signals.bits;
if(signals.bits & critical_signals.bits) {
@@ -97,7 +99,9 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
}
#endif
- if(signals.probe_overtravel) {
+ if(signals.probe_overtravel || signals.tls_overtravel) {
+ event_signals.probe_overtravel = On;
+ event_signals.tls_overtravel = signals.tls_overtravel;
limit_signals_t overtravel = { .min.z = On};
hal.limits.interrupt_callback(overtravel);
// TODO: add message?
@@ -108,19 +112,15 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
} else
hal.probe.configure(false, false);
} else if(signals.probe_disconnected) {
+ event_signals.probe_disconnected = On;
if(sys.probing_state == Probing_Active && state_get() == STATE_CYCLE) {
system_set_exec_state_flag(EXEC_FEED_HOLD);
sys.alarm_pending = Alarm_ProbeProtect;
}
} else if(signals.feed_hold)
system_set_exec_state_flag(EXEC_FEED_HOLD);
- else if(signals.cycle_start) {
- system_set_exec_state_flag(EXEC_CYCLE_START);
- sys.report.cycle_start = settings.status_report.pin_state;
- gc_state.tool_change = false;
- if(grbl.on_cycle_start)
- grbl.on_cycle_start();
- }
+ else if(signals.cycle_start)
+ event_signals.cycle_start = On;
if(signals.block_delete)
sys.flags.block_delete_enabled = !signals.deasserted;
@@ -130,11 +130,26 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
if(signals.stop_disable)
sys.flags.optional_stop_disable = !signals.deasserted;
+
+ event_signals.bits |= (signals.bits & (control_signals_t){ .block_delete = On, .single_block = On, .stop_disable = On }.bits);
+
+ if(event_signals.bits) {
+
+ if(grbl.on_control_signals_changed)
+ grbl.on_control_signals_changed(signals);
+
+ if(event_signals.cycle_start) {
+ system_set_exec_state_flag(EXEC_CYCLE_START);
+ sys.report.cycle_start = settings.status_report.pin_state;
+ gc_state.tool_change = false;
+ if(grbl.on_cycle_start)
+ grbl.on_cycle_start();
+ }
+ }
}
}
}
-
/*! \brief Executes user startup scripts, if stored.
*/
void system_execute_startup (void *data)
@@ -331,6 +346,8 @@ static status_code_t toggle_single_block (sys_state_t state, char *args)
if(!hal.signals_cap.single_block) {
sys.flags.single_block = !sys.flags.single_block;
grbl.report.feedback_message(sys.flags.single_block ? Message_Enabled : Message_Disabled);
+ if(grbl.on_control_signals_changed)
+ grbl.on_control_signals_changed((control_signals_t){ .single_block = On });
}
return hal.signals_cap.single_block ? Status_InvalidStatement : Status_OK;
@@ -341,6 +358,8 @@ static status_code_t toggle_block_delete (sys_state_t state, char *args)
if(!hal.signals_cap.block_delete) {
sys.flags.block_delete_enabled = !sys.flags.block_delete_enabled;
grbl.report.feedback_message(sys.flags.block_delete_enabled ? Message_Enabled : Message_Disabled);
+ if(grbl.on_control_signals_changed)
+ grbl.on_control_signals_changed((control_signals_t){ .block_delete = On });
}
return hal.signals_cap.block_delete ? Status_InvalidStatement : Status_OK;
@@ -350,7 +369,9 @@ static status_code_t toggle_optional_stop (sys_state_t state, char *args)
{
if(!hal.signals_cap.stop_disable) {
sys.flags.optional_stop_disable = !sys.flags.optional_stop_disable;
- grbl.report.feedback_message(sys.flags.block_delete_enabled ? Message_Enabled : Message_Disabled);
+ grbl.report.feedback_message(sys.flags.optional_stop_disable ? Message_Enabled : Message_Disabled);
+ if(grbl.on_control_signals_changed)
+ grbl.on_control_signals_changed((control_signals_t){ .stop_disable = On });
}
return hal.signals_cap.stop_disable ? Status_InvalidStatement : Status_OK;