From d86015b154d21ba58d16189789a5f0ec16ccff13 Mon Sep 17 00:00:00 2001 From: Terje Io Date: Mon, 13 Dec 2021 12:42:19 +0100 Subject: [PATCH] Added generic stream switcher functions for driver use, to avoid duplicated code. Some minor fixes. --- README.md | 4 +- changelog.md | 21 +++++++ grbl.h | 2 +- hal.h | 3 + plugins.h | 2 +- plugins_init.h | 6 +- stepper.c | 8 ++- stream.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++- stream.h | 11 +++- 9 files changed, 199 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 350c747..a8a6aa6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ It has been written to complement grblHAL and has features such as proper keyboa --- -Latest build date is 20211130, see the [changelog](changelog.md) for details. +Latest build date is 20211213, see the [changelog](changelog.md) for details. __NOTE:__ A settings reset will be performed on an update for versions earlier than 20211122. Backup and restore of settings is recommended. __IMPORTANT!__ A new setting has been introduced for ganged axes motors in version 20211121. I have only bench tested this for a couple of drivers, correct function should be verified after updating by those who have more than three motors configured. @@ -83,4 +83,4 @@ List of Supported G-Codes: Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes. --- -2021-11-28 +2021-12-13 diff --git a/changelog.md b/changelog.md index cbd2061..1d0a3b4 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,26 @@ ## grblHAL changelog +Build 20211213: + +Core: + +* Added generic stream switcher functions for driver use, to avoid duplicated code. +* Added HAL entry point as workaround fix for random ESP32 crashes \(related to unreferenced float variable in ISR context\). + +Drivers: + +* Most: updated to use new core based stream switcher. +* STM32F4xx: updates for BTT SKR 1.1 & 2.0 UART mode Trinamic stepper driver support. +* LPC176x: Added tentative support for BTT SKR E3 board including soft UART mode Trinamic TMC2209 drivers. Code by Dimitris Zervas, somewhat modified by Terje Io. +* ESP32: added driver support for ganged/auto squared axes and Trinamic SPI mode stepper drivers. Untested for now since hardware is not available. +Added board map for xPro v5 controller with TMC5160 drivers. Untested. +Fix for random Guru crashes when streaming gcode at high feedrates/accelerations. + +Plugins: +* Trinamic: workaround for ESP32 enums always defaulting to 32bit(!) +* Networking, Bluetooth: updated for core stream switcher. + +--- Core: * Renamed unused function. diff --git a/grbl.h b/grbl.h index 0296976..b34deb6 100644 --- a/grbl.h +++ b/grbl.h @@ -34,7 +34,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20211203 +#define GRBL_BUILD 20211209 // The following symbols are set here if not already set by the compiler or in config.h // Do NOT change here! diff --git a/hal.h b/hal.h index 71001b1..bbeb873 100644 --- a/hal.h +++ b/hal.h @@ -183,6 +183,9 @@ typedef struct { spindle_update_pwm_ptr update_pwm; //!< Handler for updating spindle PWM output. #else spindle_update_rpm_ptr update_rpm; //!< Handler for updating spindle RPM. +#endif +#ifdef GRBL_ESP32 + void (*esp32_off)(void); //!< Workaround handler for snowflake ESP32 Guru awaken by floating point data in ISR context. #endif // Optional entry points: spindle_get_data_ptr get_data; //!< Optional handler for getting spindle data. Required for spindle sync. diff --git a/plugins.h b/plugins.h index 79afe72..4390be3 100644 --- a/plugins.h +++ b/plugins.h @@ -186,6 +186,6 @@ typedef struct { } nvs_transfer_t; extern nvs_transfer_result_t i2c_nvs_transfer (nvs_transfer_t *i2c, bool read); -extern void my_plugin_init (void) __attribute__((weak)); +extern void my_plugin_init (void); #endif diff --git a/plugins_init.h b/plugins_init.h index 3011454..983da14 100644 --- a/plugins_init.h +++ b/plugins_init.h @@ -65,7 +65,7 @@ openpnp_init(); #endif -// ESP32 has its own webui_init and crashes at runtime if the weak my_plugin_init() is called... +// ESP32 has its own webui_init #ifndef GRBL_ESP32 #if WEBUI_ENABLE @@ -73,10 +73,10 @@ webui_init(); #endif - my_plugin_init(); - #endif + my_plugin_init(); + // Third party plugin definitions. // The code for these has to be downloaded from the source and placed in the same folder as driver.c // Note: Third party plugins may have more than one implementation, there is no "owner" of plugins listed here. diff --git a/stepper.c b/stepper.c index bd3cee4..662a983 100644 --- a/stepper.c +++ b/stepper.c @@ -404,9 +404,15 @@ ISR_CODE void stepper_driver_interrupt_handler (void) } else { // Segment buffer empty. Shutdown. st_go_idle(); + // Ensure pwm is set properly upon completion of rate-controlled motion. - if (st.exec_block->dynamic_rpm && settings.mode == Mode_Laser) + if (st.exec_block->dynamic_rpm && settings.mode == Mode_Laser) { + #ifndef GRBL_ESP32 hal.spindle.set_state((spindle_state_t){0}, 0.0f); + #else + hal.spindle.esp32_off(); + #endif + } st.exec_block = NULL; system_set_exec_state_flag(EXEC_CYCLE_COMPLETE); // Flag main program for cycle complete diff --git a/stream.c b/stream.c index ef043a7..5ea98ee 100644 --- a/stream.c +++ b/stream.c @@ -1,5 +1,5 @@ /* - stream.c - stream RX handling for tool change protocol + stream.c - high level (serial) stream handling Part of grblHAL @@ -19,6 +19,7 @@ along with Grbl. If not, see . */ +#include #include #include "hal.h" @@ -33,8 +34,15 @@ typedef struct { stream_rx_buffer_t *rxbuffer; } stream_state_t; +typedef struct stream_connection { + const io_stream_t *stream; + bool is_up; + struct stream_connection *next; +} stream_connection_t; + static stream_state_t stream = {0}; static io_stream_details_t *streams = NULL; +static stream_connection_t base = {0}, *connections = &base; void stream_register_streams (io_stream_details_t *details) { @@ -168,6 +176,149 @@ ISR_CODE bool stream_enable_mpg (const io_stream_t *mpg_stream, bool mpg_mode) return true; } +static void stream_write_all (const char *s) +{ + stream_connection_t *connection = connections; + + while(connection) { + if(connection->is_up) + connection->stream->write(s); + connection = connection->next; + } +} + +static bool stream_select (const io_stream_t *stream, bool add) +{ + static const io_stream_t *active_stream = NULL; + + stream_connection_t *connection, *last = connections; + + if(stream == base.stream) { + base.is_up = add; + return true; + } + + if(add) { + + if(base.stream == NULL) { + base.stream = stream; + base.is_up = stream->state.connected == On; + } else if((connection = malloc(sizeof(stream_connection_t)))) { + connection->stream = stream; + connection->is_up = stream->state.connected == On || stream->state.is_usb == On; // TODO: add connect/disconnect event to driver code + connection->next = NULL; + while(last->next) { + last = last->next; + if(last->stream == stream) { + free(connection); + return true; + } + } + last->next = connection; + } else + return false; + + } else { // disconnect + + stream_connection_t *prev; + + while(last->next) { + prev = last; + last = last->next; + if(last->stream == stream) { + prev->next = last->next; + free(last); + if(prev->next) + return false; + else { + stream = prev->stream; + break; + } + } + } + } + + bool webui_connected = hal.stream.state.webui_connected; + + switch(stream->type) { + + case StreamType_Serial: + if(active_stream && active_stream->type != StreamType_Serial && stream->state.connected) { + hal.stream.write = stream->write; + report_message("SERIAL STREAM ACTIVE", Message_Plain); + } + break; + + case StreamType_Telnet: + if(hal.stream.state.connected) + report_message("TELNET STREAM ACTIVE", Message_Plain); + if(add && sys.driver_started) { + hal.stream.write_all = stream->write; + report_init_message(); + } + break; + + case StreamType_WebSocket: + if(hal.stream.state.connected) + report_message("WEBSOCKET STREAM ACTIVE", Message_Plain); + if(add && sys.driver_started && !hal.stream.state.webui_connected) { + hal.stream.write_all = stream->write; + report_init_message(); + } + break; + + case StreamType_Bluetooth: + if(hal.stream.state.connected) + report_message("BLUETOOTH STREAM ACTIVE", Message_Plain); + if(add && sys.driver_started) { + hal.stream.write_all = stream->write; + report_init_message(); + } + break; + + default: + break; + } + + memcpy(&hal.stream, stream, sizeof(io_stream_t)); + + if(!hal.stream.write_all) + hal.stream.write_all = base.next != NULL ? stream_write_all : hal.stream.write; + + if(stream->type == StreamType_WebSocket) + hal.stream.state.webui_connected = webui_connected; + + hal.stream.set_enqueue_rt_handler(protocol_enqueue_realtime_command); + + if(hal.stream.disable_rx) + hal.stream.disable_rx(false); + + if(grbl.on_stream_changed) + grbl.on_stream_changed(hal.stream.type); + + active_stream = stream; + + return true; +} + +const io_stream_t *stream_get_base (void) +{ + return base.stream; +} + +bool stream_connect (const io_stream_t *stream) +{ + return hal.stream_select ? hal.stream_select(stream) : stream_select(stream, true); +} + +void stream_disconnect (const io_stream_t *stream) +{ + if(hal.stream_select) + hal.stream_select(NULL); + else if(stream) + stream_select(stream, false); +} + #ifdef DEBUGOUT static stream_write_ptr dbg_write = NULL; diff --git a/stream.h b/stream.h index ba3f577..9bd8638 100644 --- a/stream.h +++ b/stream.h @@ -1,5 +1,5 @@ /* - stream.h - some ASCII control character definitions and optional structures for stream buffers + stream.h - high level (serial) stream handling Part of grblHAL @@ -211,7 +211,8 @@ typedef union { struct { uint8_t connected :1, webui_connected :1, - unused :6; + is_usb :1, + unused :5; }; } io_stream_state_t; @@ -324,6 +325,12 @@ void stream_register_streams (io_stream_details_t *details); bool stream_enumerate_streams (stream_enumerate_callback_ptr callback); +bool stream_connect (const io_stream_t *stream); + +void stream_disconnect (const io_stream_t *stream); + +const io_stream_t *stream_get_base (void); + #ifdef DEBUGOUT void debug_write (const char *s); bool debug_stream_init (void);