diff --git a/README.md b/README.md
index 430d05e..53ebe51 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
## grblHAL ##
-Latest build date is 20260225, see the [changelog](changelog.md) for details.
+Latest build date is 20260227, 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 9fd66fd..3e3ab0a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,10 +1,18 @@
## grblHAL changelog
+Build 20260227
+
+Core:
+
+* Improved handling of `G43` some more - can now be used in the same block as `M6` when the internal workflow for tool change is enabled or `M6` is ignored.
+
+---
+
Build 20260225
Core:
-* Fix incorrect behaviour when a tool change using the built-in workflow is aborted, the selected tool was set as the current tool.
+* Fixed incorrect behaviour when a tool change using the built-in workflow is aborted, the selected tool was set as the current tool.
* Clarification: `G66` macros calls are not run on their first invocation and will only be run on subsequent blocks containing axis words for `G0` or `G1` motion.
Subsequent blocks may contain either the `G0` or `G1` command word, if not their modal state will be used. The macro will be called after the motion has been sent to the planner.
diff --git a/gcode.c b/gcode.c
index 374ed99..39f4119 100644
--- a/gcode.c
+++ b/gcode.c
@@ -699,6 +699,7 @@ static status_code_t gc_at_exit (status_code_t status)
if(!(status == Status_OK || status == Status_Handled)) {
pending_tool = NULL;
+ gc_state.g43_pending = (tool_id_t)-1;
// Clear any pending output commands
gc_clear_output_commands(output_commands);
@@ -891,12 +892,63 @@ static inline void tool_set (tool_data_t *tool)
pending_tool = NULL;
}
-// For core use only
+FLASHMEM static void tool_offset_apply (tool_offset_mode_t mode, tool_id_t tool, float *values, axes_signals_t axis_words)
+{
+ uint8_t idx = N_AXIS;
+ bool tlo_changed = false;
+ tool_data_t *tool_data = NULL;
+
+ gc_state.g43_pending = (tool_id_t)-1;
+ gc_state.modal.tool_offset_mode = mode;
+
+ if(gc_state.modal.tool_offset_mode == ToolLengthOffset_Enable || gc_state.modal.tool_offset_mode == ToolLengthOffset_ApplyAdditional)
+ tool_data = grbl.tool_table.get_tool(tool)->data;
+
+ do {
+ idx--;
+ switch(gc_state.modal.tool_offset_mode) {
+
+ case ToolLengthOffset_Cancel: // G49
+ tlo_changed |= gc_state.modal.tool_length_offset[idx] != 0.0f;
+ gc_state.modal.tool_length_offset[idx] = 0.0f;
+ break;
+
+ case ToolLengthOffset_Enable: // G43
+ if(gc_state.modal.tool_length_offset[idx] != tool_data->offset.values[idx]) {
+ tlo_changed = true;
+ gc_state.modal.tool_length_offset[idx] = tool_data->offset.values[idx];
+ }
+ break;
+
+ case ToolLengthOffset_ApplyAdditional: // G43.2
+ tlo_changed |= tool_data->offset.values[idx] != 0.0f;
+ gc_state.modal.tool_length_offset[idx] += tool_data->offset.values[idx];
+ break;
+
+ case ToolLengthOffset_EnableDynamic: // G43.1
+ if(bit_istrue(axis_words.mask, bit(idx)) && gc_state.modal.tool_length_offset[idx] != values[idx]) {
+ tlo_changed = true;
+ gc_state.modal.tool_length_offset[idx] = values[idx];
+ }
+ break;
+ }
+ } while(idx);
+
+ if(tlo_changed) {
+ report_add_realtime(Report_ToolOffset);
+ system_flag_wco_change();
+ }
+}
+
+// For core use only, called internally and from state machine
FLASHMEM void gc_tool_changed (void)
{
if(pending_tool)
tool_set(pending_tool);
+ if(gc_state.g43_pending > 0)
+ tool_offset_apply(ToolLengthOffset_Enable, gc_state.g43_pending, NULL, (axes_signals_t){0});
+
grbl.on_tool_changed(gc_state.tool);
report_add_realtime(Report_Tool);
@@ -2369,15 +2421,14 @@ status_code_t gc_execute_block (char *block)
#if NGC_EXPRESSIONS_ENABLE
if(hal.stream.file) {
gc_state.tool_pending = (tool_id_t)-1; // force set tool
- if(grbl.tool_table.n_tools) {
+ if(grbl.tool_table.n_tools && !command_words.G8) {
if((gc_block.words.h = gc_state.g43_pending > 0)) { // ?? --> >= 0
command_words.G8 = On;
- gc_block.words.h = On;
gc_block.values.h = (float)gc_state.g43_pending;
gc_block.modal.tool_offset_mode = ToolLengthOffset_Enable;
}
- gc_state.g43_pending = (tool_id_t)-1;
}
+ gc_state.g43_pending = (tool_id_t)-1;
}
#endif
} else if(!gc_block.words.t)
@@ -2712,7 +2763,7 @@ status_code_t gc_execute_block (char *block)
RETURN(Status_GcodeIllegalToolTableEntry);
gc_block.words.h = Off;
} else if(!command_words.M6)
- gc_block.values.h = (float)gc_state.tool->tool_id;
+ gc_block.values.h = gc_block.words.t ? gc_block.values.t : (float)gc_state.tool->tool_id;
} else
RETURN(Status_GcodeUnsupportedCommand);
break;
@@ -3876,15 +3927,13 @@ status_code_t gc_execute_block (char *block)
system_set_exec_state_flag(EXEC_TOOL_CHANGE); // Set up program pause for manual tool change
protocol_execute_realtime(); // Execute...
}
-#if NGC_EXPRESSIONS_ENABLE
- if((status_code_t)int_value == Status_Unhandled) &&
- grbl.tool_table.n_tools && command_words.G8 && gc_block.modal.tool_offset_mode == ToolLengthOffset_Enable) {
- gc_state.g43_pending = gc_block.words.h ? (tool_id_t)gc_block.values.h : pending_tool->tool_id;
- command_words.G8 = gc_block.words.h = Off;
- }
-#endif
- if(!macro_toolchange && state_get() != STATE_TOOL_CHANGE)
+
+ if(!(macro_toolchange || state_get() == STATE_TOOL_CHANGE))
gc_tool_changed();
+ else if(grbl.tool_table.n_tools && command_words.G8 && gc_block.modal.tool_offset_mode == ToolLengthOffset_Enable) {
+ command_words.G8 = Off;
+ gc_state.g43_pending = gc_block.values.h > 0.0f ? (tool_id_t)gc_block.values.h : pending_tool->tool_id;
+ }
}
}
@@ -4092,57 +4141,8 @@ status_code_t gc_execute_block (char *block)
// NOTE: If G43 were supported, its operation wouldn't be any different from G43.1 in terms
// of execution. The error-checking step would simply load the offset value into the correct
// axis of the block XYZ value array.
- if(command_words.G8) { // Indicates a change.
-
- bool tlo_changed = false;
- tool_data_t *tool_data = NULL;
-
- idx = N_AXIS;
- gc_state.modal.tool_offset_mode = gc_block.modal.tool_offset_mode;
-
- if(gc_state.modal.tool_offset_mode == ToolLengthOffset_Enable || gc_state.modal.tool_offset_mode == ToolLengthOffset_ApplyAdditional)
- tool_data = grbl.tool_table.get_tool((tool_id_t)gc_block.values.h)->data;
-
- do {
-
- idx--;
-
- switch(gc_state.modal.tool_offset_mode) {
-
- case ToolLengthOffset_Cancel: // G49
- tlo_changed |= gc_state.modal.tool_length_offset[idx] != 0.0f;
- gc_state.modal.tool_length_offset[idx] = 0.0f;
- break;
-
- case ToolLengthOffset_Enable: // G43
- if(gc_state.modal.tool_length_offset[idx] != tool_data->offset.values[idx]) {
- tlo_changed = true;
- gc_state.modal.tool_length_offset[idx] = tool_data->offset.values[idx];
- }
- break;
-
- case ToolLengthOffset_ApplyAdditional: // G43.2
- tlo_changed |= tool_data->offset.values[idx] != 0.0f;
- gc_state.modal.tool_length_offset[idx] += tool_data->offset.values[idx];
- break;
-
- case ToolLengthOffset_EnableDynamic: // G43.1
- if(bit_istrue(axis_words.mask, bit(idx)) && gc_state.modal.tool_length_offset[idx] != gc_block.values.xyz[idx]) {
- tlo_changed = true;
- gc_state.modal.tool_length_offset[idx] = gc_block.values.xyz[idx];
- }
- break;
-
- default:
- break;
- }
- } while(idx);
-
- if(tlo_changed) {
- report_add_realtime(Report_ToolOffset);
- system_flag_wco_change();
- }
- }
+ if(command_words.G8)
+ tool_offset_apply(gc_block.modal.tool_offset_mode, (tool_id_t)gc_block.values.h, gc_block.values.xyz, axis_words);
// [15. Coordinate system selection ]:
if(command_words.G12) {
diff --git a/gcode.h b/gcode.h
index 962c16d..816c4f9 100644
--- a/gcode.h
+++ b/gcode.h
@@ -636,9 +636,7 @@ typedef struct {
#endif
uint32_t line_number; //!< Last line number sent
tool_id_t tool_pending; //!< Tool to be selected on next M6
-#if NGC_EXPRESSIONS_ENABLE
- tool_id_t g43_pending; //!< Tool offset to be selected on next M6, for macro ATC
-#endif
+ tool_id_t g43_pending; //!< Tool offset from tool in tool table to be applied on M6 completed, set when G43 is in block with M6
bool file_run; //!< Tracks % command
bool file_stream; //!< Tracks streaming from file
bool is_laser_ppi_mode;
diff --git a/grbl.h b/grbl.h
index 7ac299e..6148906 100644
--- a/grbl.h
+++ b/grbl.h
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
-#define GRBL_BUILD 20260225
+#define GRBL_BUILD 20260227
#define GRBL_URL "https://github.com/grblHAL"