diff --git a/README.md b/README.md index b6b1425..a361a15 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/changelog.md b/changelog.md index 561dacb..f11b356 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,32 @@ ## grblHAL changelog +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. + +--- + Build 20260618 Core: diff --git a/config.h b/config.h index 060147b..428348f 100644 --- a/config.h +++ b/config.h @@ -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 diff --git a/grbl.h b/grbl.h index 79aedb6..abe6113 100644 --- a/grbl.h +++ b/grbl.h @@ -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" diff --git a/grbllib.c b/grbllib.c index c1ad5e1..07c63c0 100644 --- a/grbllib.c +++ b/grbllib.c @@ -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; diff --git a/ngc_expr.c b/ngc_expr.c index eafcfde..0aa7b2d 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -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)++; } diff --git a/settings.c b/settings.c index dc8fafb..7deecc7 100644 --- a/settings.c +++ b/settings.c @@ -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, diff --git a/state_machine.c b/state_machine.c index 724d9c4..f697503 100644 --- a/state_machine.c +++ b/state_machine.c @@ -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) { diff --git a/stream.c b/stream.c index 63a8952..a5e6f90 100644 --- a/stream.c +++ b/stream.c @@ -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; diff --git a/stream.h b/stream.h index b68f6b0..92b6456 100644 --- a/stream.h +++ b/stream.h @@ -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); diff --git a/stream_passthru.c b/stream_passthru.c index ff1caed..5c16649 100644 --- a/stream_passthru.c +++ b/stream_passthru.c @@ -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); diff --git a/system.c b/system.c index 6fea714..9f6048b 100644 --- a/system.c +++ b/system.c @@ -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);