Made named O-call LinuxCNC compliant by changing name to lowercase.

Fix for parking motion using `$32` laser mode setting when it should use the current spindle mode.
For developers: changed signature of `hal.stream.on_linestate_changed()` to include stream properties.
This commit is contained in:
Terje Io
2026-06-19 20:56:58 +02:00
parent 41abd8c84d
commit fe7632bb7d
12 changed files with 102 additions and 58 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
## grblHAL ##
Latest build date is 20260618, see the [changelog](changelog.md) for details.
Latest build date is 20260619, 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.
+27
View File
@@ -1,5 +1,32 @@
## grblHAL changelog
<a name="20260619">Build 20260619
Core:
* Made named O-call LinuxCNC compliant by changing name to lowercase.
* Fix for parking motion using `$32` laser mode setting when it should use the current spindle mode.
* For developers: changed signature of `hal.stream.on_linestate_changed()` to include stream properties.
Currently the event only fires for native USB connections and it will now fire even if the current stream is not USB based.
Drivers:
* LPC176x, RP2040, STM32F1xx, STM32F3xx, STM32F4xx and STM32F7xx: updated for `hal.stream.on_linestate_changed()` signature change.
> [!NOTE]
> Other drivers that support native USB currently does not fire this event.
* STM32F7xx: fixed typo that got committed. Ref. issue [#29](https://github.com/grblHAL/STM32F7xx/issues/29).
Plugins:
* SD card, macros: moved default values for `$675` - _Macro ATC Options_ to core.
* SD card, stream: "hardened" code a bit.
---
<a name="20260618">Build 20260618
Core:
+17 -4
View File
@@ -1496,6 +1496,20 @@ and less range over the total 255 PWM levels to signal different spindle speeds.
#endif
///@}
/*! @name $675 - Setting_MacroATC_Options
*/
///@{
#if !defined DEFAULT_MACRO_ATC_OPTION_EXECUTEM6T0 || defined __DOXYGEN__
#define DEFAULT_MACRO_ATC_OPTION_EXECUTEM6T0 Off
#endif
#if !defined DEFAULT_MACRO_ATC_ERROR_NO_MACRO || defined __DOXYGEN__
#define DEFAULT_MACRO_ATC_ERROR_NO_MACRO Off
#endif
#if !defined DEFAULT_MACRO_ATC_RANDOM_TOOLCHANGER || defined __DOXYGEN__
#define DEFAULT_MACRO_ATC_RANDOM_TOOLCHANGER Off
#endif
///@}
// Homing settings (Group_Homing)
/*! @name $22 - Setting_HomingEnable
@@ -2202,12 +2216,12 @@ Filing systems options.
#define DEFAULT_FS_SD_AUTOMOUNT Off // Default disabled. Set to \ref On or 1 to enable.
#endif
/*! /def DEFAULT_FS_LITLLEFS_HIDDEN
/*! /def DEFAULT_FS_LITTLEFS_HIDDEN
\brief Hides LittleFS mount from directory listings.
\internal Bit 1 in settings.fs_options.mask.
*/
#if !defined DEFAULT_FS_LITLLEFS_HIDDEN || defined __DOXYGEN__
#define DEFAULT_FS_LITLLEFS_HIDDEN Off // Default disabled. Set to \ref On or 1 to enable.
#if !defined DEFAULT_FS_LITTLEFS_HIDDEN || defined __DOXYGEN__
#define DEFAULT_FS_LITTLEFS_HIDDEN Off // Default disabled. Set to \ref On or 1 to enable.
#endif
/*! /def DEFAULT_FS_HIERACHICAL_LISTING
@@ -2220,7 +2234,6 @@ Adds directory entries in $F and $F+ output to allow hierarchical navigation of
#endif
///@}
// Axis settings (Group_XAxis - Group_VAxis)
/*! @name $10x - Setting_AxisStepsPerMM
+1 -1
View File
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20260618
#define GRBL_BUILD 20260619
#define GRBL_URL "https://github.com/grblHAL"
+2 -24
View File
@@ -75,7 +75,6 @@ DCRAM grbl_t grbl;
DCRAM grbl_hal_t hal;
static driver_startup_t driver = { .ok = 0xFF };
static on_linestate_changed_ptr on_linestate_changed;
static settings_changed_ptr hal_settings_changed;
static stepper_enable_ptr stepper_enable;
DCRAM static struct {
@@ -191,22 +190,6 @@ ISR_CODE static home_signals_t ISR_FUNC(get_homing_status2)(void)
return home;
}
FLASHMEM static void output_welcome_message (void *data)
{
grbl.report.init_message(hal.stream.write);
}
FLASHMEM static void onLinestateChanged (serial_linestate_t state)
{
if(state.dtr) {
task_delete(output_welcome_message, NULL);
task_add_delayed(output_welcome_message, NULL, 200);
}
if(on_linestate_changed)
on_linestate_changed(state);
}
FLASHMEM static void stepperEnable (axes_signals_t enable, bool hold)
{
if(stepper_enable)
@@ -232,9 +215,9 @@ FLASHMEM static void print_pos_msg (void *data)
#pragma GCC diagnostic pop
#endif
FLASHMEM static void onPosFailure (serial_linestate_t state)
FLASHMEM static void onPosFailure (io_stream_properties_t *stream, serial_linestate_t state)
{
if(state.dtr) // delay a bit to let the USB stack come up
if(state.dtr && stream->flags.is_usb == hal.stream.state.is_usb) // delay a bit to let the USB stack come up
task_add_delayed(print_pos_msg, NULL, 50);
}
@@ -461,11 +444,6 @@ FLASHMEM int grbl_enter (void)
setting_remove_elements(Setting_FSOptions, fs_options.mask, true);
}
if(hal.stream.state.linestate_event && !hal.stream.state.passthru) {
on_linestate_changed = hal.stream.on_linestate_changed;
hal.stream.on_linestate_changed = onLinestateChanged;
}
if(grbl.on_probe_toolsetter == NULL && hal.driver_cap.toolsetter && hal.probe.select)
grbl.on_probe_toolsetter = onProbeToolsetter;
+4 -4
View File
@@ -591,7 +591,7 @@ starting at the index given by the pos offset.
*/
FLASHMEM status_code_t ngc_read_name (char *line, uint_fast8_t *pos, char *buffer)
{
char *s;
char c, *s;
uint_fast8_t len = 0;
status_code_t status = Status_BadNumberFormat;
@@ -599,13 +599,13 @@ FLASHMEM status_code_t ngc_read_name (char *line, uint_fast8_t *pos, char *buffe
s++;
while(*s && *s != '>' && len <= NGC_MAX_PARAM_LENGTH) {
*buffer++ = *s++;
while((c = *s++) && c != '>' && len <= NGC_MAX_PARAM_LENGTH) {
*buffer++ = LCAPS(c);
(*pos)++;
len++;
}
if((status = *s == '>' ? Status_OK : Status_FlowControlSyntaxError) == Status_OK) {
if((status = c == '>' ? Status_OK : Status_FlowControlSyntaxError) == Status_OK) {
*buffer = '\0';
(*pos)++;
}
+5 -1
View File
@@ -370,6 +370,10 @@ PROGMEM static const settings_t defaults = {
.tool_change.seek_rate = DEFAULT_TOOLCHANGE_SEEK_RATE,
.tool_change.pulloff_rate = DEFAULT_TOOLCHANGE_PULLOFF_RATE,
.macro_atc_flags.execute_m6t0 = DEFAULT_MACRO_ATC_OPTION_EXECUTEM6T0,
.macro_atc_flags.error_on_no_macro = DEFAULT_MACRO_ATC_ERROR_NO_MACRO,
.macro_atc_flags.random_toolchanger = DEFAULT_MACRO_ATC_RANDOM_TOOLCHANGER,
.parking.flags.enabled = DEFAULT_PARKING_ENABLE,
.parking.flags.deactivate_upon_init = DEFAULT_DEACTIVATE_PARKING_UPON_INIT,
.parking.flags.enable_override_control= DEFAULT_ENABLE_PARKING_OVERRIDE_CONTROL,
@@ -385,7 +389,7 @@ PROGMEM static const settings_t defaults = {
.safety_door.coolant_on_delay = DEFAULT_SAFETY_DOOR_COOLANT_DELAY,
.fs_options.sd_mount_on_boot = DEFAULT_FS_SD_AUTOMOUNT,
.fs_options.lfs_hidden = DEFAULT_FS_LITLLEFS_HIDDEN,
.fs_options.lfs_hidden = DEFAULT_FS_LITTLEFS_HIDDEN,
.fs_options.hierarchical_listing = DEFAULT_FS_HIERACHICAL_LISTING,
.modbus_baud = DEFAULT_MODBUS_STREAM_BAUD,
+1 -1
View File
@@ -535,7 +535,7 @@ FLASHMEM static void state_await_hold (uint_fast16_t rt_exec)
// 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) {
if (settings.parking.flags.enabled && !sys.override.control.parking_disable && gc_spindle_get(0)->hal->cap.laser) {
// Get current position and store as restore location.
if (!park.flags.active) {
+27 -11
View File
@@ -24,6 +24,7 @@
#include "hal.h"
#include "protocol.h"
#include "task.h"
#include "state_machine.h"
#if defined(DEBUG) || defined(DEBUGOUT)
@@ -300,26 +301,41 @@ FLASHMEM static stream_connection_t *add_connection (const io_stream_t *stream)
return connection;
}
FLASHMEM static void output_welcome_message (void *data)
{
grbl.report.init_message(hal.stream.write);
}
FLASHMEM void stream_usb_linestate_changed (uint8_t instance, serial_linestate_t state)
{
if(state.dtr && hal.stream.state.is_usb && !hal.stream.state.passthru) {
task_delete(output_welcome_message, NULL);
task_add_delayed(output_welcome_message, NULL, 200);
}
if(hal.stream.on_linestate_changed) {
io_stream_properties_t prop = {
.type = StreamType_Serial,
.instance = instance,
.flags.is_usb = On
};
hal.stream.on_linestate_changed(&prop, state);
}
}
FLASHMEM static bool stream_select (const io_stream_t *stream, bool add)
{
static const io_stream_t *active_stream = NULL;
bool send_init_message = false, mpg_enable = false;
static struct {
const io_stream_t *stream;
on_linestate_changed_ptr on_linestate_changed;
} usb = {};
if(stream == base.stream) {
base.is_up = add ? (stream->is_connected ? stream->is_connected : stream_connected) : is_not_connected;
return true;
}
if(active_stream != NULL && hal.stream.state.is_usb) {
usb.stream = active_stream;
usb.on_linestate_changed = hal.stream.on_linestate_changed;
}
if(!add) { // disconnect
if(stream == base.stream || stream == &mpg.stream)
@@ -391,8 +407,8 @@ FLASHMEM static bool stream_select (const io_stream_t *stream, bool add)
memcpy(&hal.stream, stream, offsetof(io_stream_t, report));
if(stream == usb.stream)
hal.stream.on_linestate_changed = usb.on_linestate_changed;
// if(stream == usb.stream)
// hal.stream.on_linestate_changed = usb.on_linestate_changed;
if(stream == base.stream && base.is_up == is_not_connected)
base.is_up = stream_connected;
+13 -7
View File
@@ -85,8 +85,8 @@ typedef enum {
StreamType_Bluetooth,
StreamType_Telnet,
StreamType_WebSocket,
StreamType_SDCard, // deprecated, use StreamType_File instead
StreamType_File = StreamType_SDCard,
StreamType_File,
StreamType_SDCard = StreamType_File, // deprecated, use StreamType_File instead
StreamType_Redirected,
StreamType_Null
} stream_type_t;
@@ -203,6 +203,9 @@ typedef struct {
uint8_t wco_counter; //!< Tracks when to add work coordinate offset data to status reports.
} status_report_tracking_t;
struct io_stream_properties;
typedef struct io_stream_properties io_stream_properties_t;
/*! \brief Pointer to function for getting stream connected status.
\returns \a true connected, \a false otherwise.
*/
@@ -326,7 +329,7 @@ typedef bool (*disable_rx_stream_ptr)(bool disable);
\param \a serial_linestate_t enum.
*/
typedef void (*on_linestate_changed_ptr)(serial_linestate_t state);
typedef void (*on_linestate_changed_ptr)(io_stream_properties_t *stream, serial_linestate_t state);
typedef union {
uint8_t value;
@@ -338,7 +341,7 @@ typedef union {
modbus_ready :1,
rts_handshake :1,
init_ok :1,
unused :1;
is_usb :1;
};
} io_stream_flags_t;
@@ -380,9 +383,10 @@ typedef struct {
set_baud_rate_ptr set_baud_rate; //!< Optional handler for setting the stream baud rate. Required for Modbus/RS-485 support, recommended for Bluetooth support.
set_format_ptr set_format; //!< Optional handler for setting the stream format.
stream_set_direction_ptr set_direction; //!< Optional handler for setting the transfer direction for half-duplex communication.
on_linestate_changed_ptr on_linestate_changed; //!< Optional handler to be called when line state changes. Set by client.
vfs_file_t *file; //!< File handle, non-null if streaming from a file.
// The following fields are kept over a stream change
status_report_tracking_t report; //!< Tracks when to add data to status reports.
on_linestate_changed_ptr on_linestate_changed; //!< Optional handler to be called when line state changes. Set by client.
} io_stream_t;
typedef struct {
@@ -396,14 +400,14 @@ typedef const io_stream_t *(*stream_claim_ptr)(uint32_t baud_rate);
typedef bool (*stream_release_ptr)(uint8_t instance);
typedef const io_stream_status_t *(*stream_get_status_ptr)(uint8_t instance);
typedef struct {
struct io_stream_properties {
stream_type_t type; //!< Type of stream.
uint8_t instance; //!< Instance of stream type, starts from 0.
io_stream_flags_t flags;
stream_claim_ptr claim;
stream_release_ptr release;
stream_get_status_ptr get_status; //!< Optional handler for getting stream status, for UART streams only
} io_stream_properties_t;
};
typedef bool (*stream_enumerate_callback_ptr)(io_stream_properties_t const *properties, void *data);
@@ -512,6 +516,8 @@ const io_stream_status_t *stream_get_uart_status (uint8_t instance);
const io_stream_t *stream_null_init (uint32_t baud_rate);
void stream_usb_linestate_changed (uint8_t instance, serial_linestate_t state);
io_stream_t const *stream_open_instance (uint8_t instance, uint32_t baud_rate, stream_write_char_ptr rx_handler, const char *description);
bool stream_close (io_stream_t const *stream);
bool stream_set_description (const io_stream_t *stream, const char *description);
+3 -3
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2024-2025 Terje Io
Copyright (c) 2024-2026 Terje Io
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -70,7 +70,7 @@ static void forward_uart_rx (void *data)
task_add_delayed(forward_uart_rx, NULL, 8);
}
static void onLinestateChanged (serial_linestate_t state)
static void onLinestateChanged (io_stream_properties_t *stream, serial_linestate_t state)
{
/*
Auto program
@@ -80,7 +80,7 @@ static void onLinestateChanged (serial_linestate_t state)
1 0 0 1
0 1 1 0
*/
if(conn_ok) {
if(conn_ok && stream->flags.is_usb) {
if(state.dtr == state.rts) {
ioport_digital_out(boot0_port, 0);
+1 -1
View File
@@ -122,7 +122,7 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
// NOTE: at least for lasers there should be an external interlock blocking laser power.
if(state_get() != STATE_IDLE && state_get() != STATE_JOG)
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
if(settings.mode == Mode_Laser) // Turn off spindle immediately (laser) when in laser mode
if(gc_spindle_get(0)->hal->cap.laser) // Turn off spindle immediately (laser) when in laser mode
spindle_all_off(true);
} else
system_set_exec_state_flag(EXEC_SAFETY_DOOR);