diff --git a/changelog.md b/changelog.md index b3a5487..3a1e45a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,26 @@ ## grblHAL changelog +20250104 + +Core: + +* Changed error code reported when file not found for `G65` macro or named `O`-sub calls from `39` to `84`. +Removed `IDLE` state requirement for executing `G65` macros, an error will no longer be returned and the macro will be run. + +* Added event handler for outputting welcome message on "native" USB connect for drivers that provides the linestate changed event. Ref. STMF32F4xx issue [#206](https://github.com/grblHAL/STM32F4xx/issues/206). + +Drivers: + +* LPC176x: added support for USB linestate changed event. + +* iMXRT1062: now outputs the welcome message on the first USB connection after a cold start. + +Plugins: + +* Bluetooth: updated for core change. + +--- + 20250103 Core: @@ -10,7 +31,7 @@ They can be either set to 0 or to a value in the range 0.5 - 20s. The settings a > If the spindle supports "at speed" functionality and this is enabled by setting `$340` \(Spindle at speed tolerance\) > 0 then the spin up delay is used as a timeout value before alarm 14 is raised. If `$394` is set to 0 the timeout will default to one minute. > [!NOTE] -> Setting `$392` and `$393`, if available, are now only used for spindle spin up delay and coolant start delay respectively when the safety door is closed. +> Settings `$392` and `$393`, if available, are now only used for spindle spin up delay and coolant start delay respectively when the safety door is closed. Plugins: diff --git a/core_handlers.h b/core_handlers.h index db2ab08..a324884 100644 --- a/core_handlers.h +++ b/core_handlers.h @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2020-2024 Terje Io + Copyright (c) 2020-2025 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 @@ -58,7 +58,7 @@ typedef struct { // Report entry points set by core at startup and reset. -typedef void (*init_message_ptr)(void); +typedef void (*init_message_ptr)(stream_write_ptr write); typedef void (*help_message_ptr)(void); typedef status_code_t (*status_message_ptr)(status_code_t status_code); typedef message_code_t (*feedback_message_ptr)(message_code_t message_code); diff --git a/errors.c b/errors.c index 56a3335..46bb8b8 100644 --- a/errors.c +++ b/errors.c @@ -104,6 +104,7 @@ PROGMEM static const status_detail_t status_detail[] = { { Status_FlowControlStackOverflow, "Stack overflow while executing flow statement." }, { Status_FlowControlOutOfMemory, "Out of memory while executing flow statement." }, #endif + { Status_FileOpenFailed, "Could not open file." }, { Status_UserException, "User defined error occured." } #endif // NO_SETTINGS_DESCRIPTIONS }; diff --git a/errors.h b/errors.h index 78aba0c..79adfda 100644 --- a/errors.h +++ b/errors.h @@ -112,6 +112,7 @@ typedef enum { Status_FlowControlSyntaxError = 81, Status_FlowControlStackOverflow = 82, Status_FlowControlOutOfMemory = 83, + Status_FileOpenFailed = 84, Status_StatusMax = Status_FlowControlOutOfMemory, Status_UserException = 253, Status_Handled, // For internal use only diff --git a/grbl.h b/grbl.h index c7b741b..8b8c365 100644 --- a/grbl.h +++ b/grbl.h @@ -42,7 +42,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20250103 +#define GRBL_BUILD 20250104 #define GRBL_URL "https://github.com/grblHAL" diff --git a/grbllib.c b/grbllib.c index e97843a..038a81b 100644 --- a/grbllib.c +++ b/grbllib.c @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2017-2024 Terje Io + Copyright (c) 2017-2025 Terje Io Copyright (c) 2011-2015 Sungeun K. Jeon Copyright (c) 2009-2011 Simen Svale Skogsrud @@ -92,6 +92,7 @@ grbl_hal_t hal; static driver_startup_t driver = { .ok = 0xFF }; static core_task_t task_pool[CORE_TASK_POOL_SIZE] = {0}; static core_task_t *next_task = NULL, *immediate_task = NULL, *systick_task = NULL, *last_freed = NULL; +static on_linestate_changed_ptr on_linestate_changed; #ifdef KINEMATICS_API kinematics_t kinematics; @@ -166,6 +167,20 @@ ISR_CODE static home_signals_t ISR_FUNC(get_homing_status2)(void) return home; } +static void output_welcome_message (void *data) +{ + grbl.report.init_message(hal.stream.write); +} + +static void onLinestateChanged (serial_linestate_t state) +{ + if(state.dtr) + task_add_delayed(output_welcome_message, NULL, 200); + + if(on_linestate_changed) + on_linestate_changed(state); +} + // main entry point int grbl_enter (void) @@ -333,6 +348,11 @@ int grbl_enter (void) setting_remove_elements(Setting_FSOptions, fs_options.mask); } + if(hal.stream.state.linestate_event && !hal.stream.state.passthru) { + on_linestate_changed = hal.stream.on_linestate_changed; + hal.stream.on_linestate_changed = onLinestateChanged; + } + // Initialization loop upon power-up or a system abort. For the latter, all processes // will return to this loop to be cleanly re-initialized. while(looping) { @@ -380,7 +400,7 @@ int grbl_enter (void) tc_init(); // Print welcome message. Indicates an initialization has occurred at power-up or with a reset. - grbl.report.init_message(); + grbl.report.init_message(hal.stream.write_all); if(!settings.flags.no_unlock_after_estop && state_get() == STATE_ESTOP) state_set(STATE_ALARM); diff --git a/ngc_flowctrl.c b/ngc_flowctrl.c index a7e8985..67b11b0 100644 --- a/ngc_flowctrl.c +++ b/ngc_flowctrl.c @@ -661,7 +661,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo if(!skipping) { - ngc_sub_t *sub; + ngc_sub_t *sub = NULL; if(o_label > NGC_MAX_PARAM_ID) { @@ -684,7 +684,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo if((sub = add_sub(o_label, file)) == NULL) status = Status_FlowControlOutOfMemory; } else - status = Status_FlowControlOutOfMemory; // file not found... + status = Status_FileOpenFailed; } } else if((sub = subs)) do { if(sub->o_label == o_label && sub->file == hal.stream.file) diff --git a/report.c b/report.c index 98b565b..db15086 100644 --- a/report.c +++ b/report.c @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2017-2024 Terje Io + Copyright (c) 2017-2025 Terje Io Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC grblHAL is free software: you can redistribute it and/or modify @@ -323,14 +323,14 @@ static message_code_t report_feedback_message (message_code_t id) } // Welcome message -static void report_init_message (void) +static void report_init_message (stream_write_ptr write) { override_counter = wco_counter = 0; #if COMPATIBILITY_LEVEL == 0 - hal.stream.write_all(ASCII_EOL "GrblHAL " GRBL_VERSION " ['$' or '$HELP' for help]" ASCII_EOL); + write(ASCII_EOL "GrblHAL " GRBL_VERSION " ['$' or '$HELP' for help]" ASCII_EOL); #else - hal.stream.write_all(ASCII_EOL "Grbl " GRBL_VERSION " ['$' for help]" ASCII_EOL); + write(ASCII_EOL "Grbl " GRBL_VERSION " ['$' for help]" ASCII_EOL); #endif } diff --git a/stream.c b/stream.c index 0152e43..c0e4b9d 100644 --- a/stream.c +++ b/stream.c @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2021-2024 Terje Io + Copyright (c) 2021-2025 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 @@ -255,12 +255,21 @@ 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) @@ -336,6 +345,9 @@ static bool stream_select (const io_stream_t *stream, bool add) memcpy(&hal.stream, stream, sizeof(io_stream_t)); + 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; @@ -345,10 +357,8 @@ static bool stream_select (const io_stream_t *stream, bool add) if(stream->type == StreamType_WebSocket && !stream->state.webui_connected) hal.stream.state.webui_connected = webui_connected; - if(send_init_message) { - hal.stream.write_all = stream->write; - grbl.report.init_message(); - } + if(send_init_message) + grbl.report.init_message(stream->write); hal.stream.write_all = stream_write_all; hal.stream.set_enqueue_rt_handler(protocol_enqueue_realtime_command); diff --git a/stream.h b/stream.h index 9e81619..a87c033 100644 --- a/stream.h +++ b/stream.h @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2019-2024 Terje Io + Copyright (c) 2019-2025 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 @@ -235,7 +235,8 @@ typedef union { uint8_t webui_connected :1, is_usb :1, linestate_event :1, //!< Set when driver supports on_linestate_changed event. - unused :5; + passthru :1, //!< Set when stream is in passthru mode. + unused :4; }; } io_stream_state_t; diff --git a/stream_passthru.c b/stream_passthru.c index f8bbe55..780c75c 100644 --- a/stream_passthru.c +++ b/stream_passthru.c @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2024 Terje Io + Copyright (c) 2024-2025 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 @@ -190,7 +190,7 @@ void stream_passthru_init (uint8_t instance, uint32_t baud_rate, bool start) io_stream_t const *stream = stream_open_instance(instance, baud_rate, NULL, "Passthru"); - if(stream != NULL) { + if((hal.stream.state.passthru = stream != NULL)) { protocol_enqueue_foreground_task(passthru_start1, NULL); // enter passthrouh mode after finished booting grblHAL