From c2450947ae9334bcdcd136c9acbcf1144f32bfac Mon Sep 17 00:00:00 2001 From: Terje Io Date: Tue, 4 Jul 2023 15:40:47 +0200 Subject: [PATCH] Skip calling tool change code if current and selected tool number is the same. Added 5s timeout/abort handling when waiting for index pulses prior to startiong spindle synchronized motion. Added definitions for M401 (deploy probe) and M402 (stow probe) for plugin use. Added support for probe protected message and alarm. Requires driver support for interrupt handled probe input. --- README.md | 2 +- changelog.md | 15 ++++++++++++ gcode.c | 55 ++++++++++++++++++++++-------------------- gcode.h | 2 ++ grbl.h | 2 +- hal.h | 25 ++++++++++--------- messages.c | 3 ++- messages.h | 3 ++- modbus.c | 11 +++++++++ modbus.h | 5 ++++ pin_bits_masks.h | 63 +++++++++++++++++++++++++++++++++++++++++++++--- protocol.c | 3 +++ state_machine.c | 16 +++++++++++- stream.h | 3 +++ 14 files changed, 162 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 1a7800d..4add82c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa --- -Latest build date is 20230626, see the [changelog](changelog.md) for details. +Latest build date is 20230704, see the [changelog](changelog.md) for details. __NOTE:__ A settings reset will be performed on an update of builds earlier than 20230125. Backup and restore of settings is recommended. __IMPORTANT!__ A new setting has been introduced for ganged axes motors in build 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. diff --git a/changelog.md b/changelog.md index 22f08fb..b1a25e7 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,20 @@ ## grblHAL changelog +Build 20230704 + +Core: + +* Skip calling tool change code if current and selected tool number are equal. +* Added 5s timeout/abort handling when waiting for index pulses prior to startiong spindle synchronized motion. +* Added definitions for M401 (deploy probe) and M402 (stow probe) for plugin use. +* Added core support for probe protected message and alarm. Requires driver support for interrupt handled probe input. + +Drivers: + +*STM32F1xx, STM32F4xx and STM32F7xx: simplified and made GPIO interrupt handling more generic/flexible. Fixes [issue #116](https://github.com/grblHAL/STM32F4xx/issues/116). + +--- + Build 20230626 Core: diff --git a/gcode.c b/gcode.c index dd6702d..ddbf297 100644 --- a/gcode.c +++ b/gcode.c @@ -3019,42 +3019,45 @@ status_code_t gc_execute_block (char *block) plan_data.message = NULL; } - if(grbl.on_tool_selected) { + if(pending_tool->tool != gc_state.tool->tool) { - spindle_state_t state = gc_state.modal.spindle.state; + if(grbl.on_tool_selected) { - grbl.on_tool_selected(pending_tool); + spindle_state_t state = gc_state.modal.spindle.state; - if(state.value != gc_state.modal.spindle.state.value) - gc_block.modal.spindle.state = gc_state.modal.spindle.state; - } + grbl.on_tool_selected(pending_tool); - if(hal.tool.change) { // ATC - if((int_value = (uint_fast16_t)hal.tool.change(&gc_state)) != Status_OK) { -#if NGC_EXPRESSIONS_ENABLE - if(int_value != Status_Unhandled) -#endif - FAIL((status_code_t)int_value); + if(state.value != gc_state.modal.spindle.state.value) + gc_block.modal.spindle.state = gc_state.modal.spindle.state; } - system_add_rt_report(Report_Tool); - } else { // Manual - int_value = (uint_fast16_t)Status_OK; - gc_state.tool_change = true; - system_set_exec_state_flag(EXEC_TOOL_CHANGE); // Set up program pause for manual tool change - protocol_execute_realtime(); // Execute... - } + + if(hal.tool.change) { // ATC + if((int_value = (uint_fast16_t)hal.tool.change(&gc_state)) != Status_OK) { #if NGC_EXPRESSIONS_ENABLE - if((status_code_t)int_value != Status_Unhandled) - tool_set(pending_tool); + if(int_value != Status_Unhandled) +#endif + FAIL((status_code_t)int_value); + } + system_add_rt_report(Report_Tool); + } else { // Manual + int_value = (uint_fast16_t)Status_OK; + gc_state.tool_change = true; + 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) + tool_set(pending_tool); #if N_TOOLS - else if(command_words.G8 && gc_block.modal.tool_offset_mode && ToolLengthOffset_Enable) { - gc_state.g43_pending = gc_block.values.h; - command_words.G8 = Off; - } + else if(command_words.G8 && gc_block.modal.tool_offset_mode && ToolLengthOffset_Enable) { + gc_state.g43_pending = gc_block.values.h; + command_words.G8 = Off; + } #endif #else - tool_set(pending_tool); + tool_set(pending_tool); #endif + } } // [7. Spindle control ]: diff --git a/gcode.h b/gcode.h index 53355d7..c7d5c37 100644 --- a/gcode.h +++ b/gcode.h @@ -237,6 +237,8 @@ typedef enum { LaserPPI_PulseLength = 128, //!< 128 - M128 OpenPNP_SetAcceleration = 204, //!< 204 - M204 OpenPNP_FinishMoves = 400, //!< 400 - M400 + Probe_Deploy = 401, //!< 401 - M401, Marlin format + Probe_Stow = 402, //!< 402 - M402, Marlin format OpenPNP_SettingsReset = 502, //!< 502 - M502 Trinamic_ModeToggle = 569, //!< 569 - M569, Marlin format Trinamic_StepperCurrent = 906, //!< 906 - M906, Marlin format diff --git a/grbl.h b/grbl.h index e6ed77d..f82036f 100644 --- a/grbl.h +++ b/grbl.h @@ -42,7 +42,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20230626 +#define GRBL_BUILD 20230704 #define GRBL_URL "https://github.com/grblHAL" diff --git a/hal.h b/hal.h index 4d6978f..c9c76e5 100644 --- a/hal.h +++ b/hal.h @@ -65,7 +65,8 @@ typedef union { no_gcode_message_handling :1, odometers :1, pwm_spindle :1, - unassigned :12; + probe_latch :1, + unassigned :11; }; } driver_cap_t; @@ -232,7 +233,7 @@ typedef void (*stepper_wake_up_ptr)(void); \param clear_signals when true stepper motor outputs can be reset to the default state. This parameter can often be ignored. -__NOTE:__ this function will be called from an interrupt context +__NOTE:__ this function will be called from an interrupt context. */ typedef void (*stepper_go_idle_ptr)(bool clear_signals); @@ -240,7 +241,7 @@ typedef void (*stepper_go_idle_ptr)(bool clear_signals); \param enable a \a axes_signals_t union containing separate flags for each motor to enable/disable. -__NOTE:__ this function may be called from an interrupt context +__NOTE:__ this function may be called from an interrupt context. */ typedef void (*stepper_enable_ptr)(axes_signals_t enable); @@ -274,7 +275,7 @@ If the driver is to support spindle synced motion many more needs to be referenc \param stepper pointer to a \ref stepper struct containing information about the stepper signals to be output. -__NOTE:__ this function will be called from an interrupt context +__NOTE:__ this function will be called from an interrupt context. */ typedef void (*stepper_pulse_start_ptr)(stepper_t *stepper); @@ -285,7 +286,7 @@ This is for an experimental implementation of plasma Torch Height Control (THC) \param step_outbits a \a #axes_signals_t union containing the axes to output a step signal for. \param dir_outbits a \a #axes_signals_t union containing the axes to output a direction signal for. -__NOTE:__ this function will be called from an interrupt context +__NOTE:__ this function will be called from an interrupt context. */ typedef void (*stepper_output_step_ptr)(axes_signals_t step_outbits, axes_signals_t dir_outbits); @@ -304,14 +305,14 @@ typedef void (*stepper_interrupt_callback_ptr)(void); //! Stepper motor handlers typedef struct { stepper_wake_up_ptr wake_up; //!< Handler for enabling stepper motor power and main stepper interrupt. - stepper_go_idle_ptr go_idle; //!< Handler for disabling main stepper interrupt and optionally reset stepper signals. - stepper_enable_ptr enable; //!< Handler for enabling/disabling stepper motor power for individual motors. + stepper_go_idle_ptr go_idle; //!< Handler for disabling main stepper interrupt and optionally reset stepper signals. Called from interrupt context. + stepper_enable_ptr enable; //!< Handler for enabling/disabling stepper motor power for individual motors. Called from interrupt context. stepper_disable_motors_ptr disable_motors; //!< Optional handler for enabling/disabling stepper motor step signals for individual motors. - stepper_cycles_per_tick_ptr cycles_per_tick; //!< Handler for setting the step pulse rate for the next motion segment. - stepper_pulse_start_ptr pulse_start; //!< Handler for starting outputting direction signals and a step pulse. + stepper_cycles_per_tick_ptr cycles_per_tick; //!< Handler for setting the step pulse rate for the next motion segment. Called from interrupt context. + stepper_pulse_start_ptr pulse_start; //!< Handler for starting outputting direction signals and a step pulse. Called from interrupt context. stepper_interrupt_callback_ptr interrupt_callback; //!< Callback for informing about the next step pulse to output. _Set by the core at startup._ stepper_get_ganged_ptr get_ganged; //!< Optional handler getting which axes are configured for ganging or auto squaring. - stepper_output_step_ptr output_step; //!< Optional handler for outputting a single step pulse. _Experimental._ + stepper_output_step_ptr output_step; //!< Optional handler for outputting a single step pulse. _Experimental._ Called from interrupt context. motor_iterator_ptr motor_iterator; //!< Optional handler iteration over motor vs. axis mappings. Required for the motors plugin (Trinamic drivers). } stepper_ptrs_t; @@ -336,6 +337,8 @@ typedef struct { /*! \brief Pointer to function for getting probe status. \returns probe state in a \a #probe_state_t enum. + +__NOTE:__ this function will be called from an interrupt context. */ typedef probe_state_t (*probe_get_state_ptr)(void); @@ -355,7 +358,7 @@ typedef void (*probe_connected_toggle_ptr)(void); //! Handlers for probe input(s). typedef struct { probe_configure_ptr configure; //!< Optional handler for setting probe operation mode. - probe_get_state_ptr get_state; //!< Optional handler for getting probe status. + probe_get_state_ptr get_state; //!< Optional handler for getting probe status. Called from interrupt context. probe_connected_toggle_ptr connected_toggle; //!< Optional handler for toggling probe connected status. } probe_ptrs_t; diff --git a/messages.c b/messages.c index 4cab0b0..75641ea 100644 --- a/messages.c +++ b/messages.c @@ -44,7 +44,8 @@ PROGMEM static const message_t messages[] = { { .id = Message_CycleStart2Continue, .text = "Press cycle start to continue." }, { .id = Message_TPCycleStart2Continue, .text = "Remove any touch plate and press cycle start to continue." }, { .id = Message_ProbeFailedRetry, .text = "Probe failed, try again." }, - { .id = Message_ExecuteTPW, .text = "Perform a probe with $TPW first!", .type = Message_Warning} + { .id = Message_ExecuteTPW, .text = "Perform a probe with $TPW first!", .type = Message_Warning}, + { .id = Message_ProbeProtected, .text = "Probe protection activated."} }; const message_t *message_get (message_code_t id) diff --git a/messages.h b/messages.h index da23cb4..2b3614d 100644 --- a/messages.h +++ b/messages.h @@ -45,7 +45,8 @@ typedef enum { Message_TPCycleStart2Continue = 18, //!< 18 Message_ProbeFailedRetry = 19, //!< 19 Message_ExecuteTPW = 20, //!< 20 - Message_NextMessage //!< 21 - next unassigned message number. + Message_ProbeProtected = 21, //!< 21 + Message_NextMessage //!< 22 - next unassigned message number. } message_code_t; typedef enum { diff --git a/modbus.c b/modbus.c index 186ccfd..8fc0131 100644 --- a/modbus.c +++ b/modbus.c @@ -72,6 +72,17 @@ bool modbus_send (modbus_message_t *msg, const modbus_callbacks_t *callbacks, bo return ok || (rtu_api != N_MODBUS_API && modbus[rtu_api].send(msg, callbacks, block)); } +uint16_t modbus_read_u16 (uint8_t *p) +{ + return (*p << 8) | *(p + 1); +} + +void modbus_write_u16 (uint8_t *p, uint16_t value) +{ + *p = (uint8_t)(value >> 8); + *(p + 1) = (uint8_t)(value & 0x00FF); +} + bool modbus_register_api (const modbus_api_t *api) { bool ok; diff --git a/modbus.h b/modbus.h index d51880b..c48a538 100644 --- a/modbus.h +++ b/modbus.h @@ -34,6 +34,9 @@ #include #include +#define MODBUS_SET_MSB16(v) ((v) >> 8) +#define MODBUS_SET_LSB16(v) ((v) & 0xFF) + typedef enum { Modbus_InterfaceRTU = 0, Modbus_InterfaceASCII, @@ -96,6 +99,8 @@ bool modbus_enabled (void); void modbus_flush_queue (void); void modbus_set_silence (const modbus_silence_timeout_t *timeout); bool modbus_send (modbus_message_t *msg, const modbus_callbacks_t *callbacks, bool block); +uint16_t modbus_read_u16 (uint8_t *p); +void modbus_write_u16 (uint8_t *p, uint16_t value); bool modbus_register_api (const modbus_api_t *api); #endif diff --git a/pin_bits_masks.h b/pin_bits_masks.h index e96d7bc..83eedeb 100644 --- a/pin_bits_masks.h +++ b/pin_bits_masks.h @@ -193,16 +193,71 @@ #define COOLANT_MIST_BIT (1<spindle.state.synchronized) { + uint32_t ms = hal.get_elapsed_ticks(); + if (block->spindle.hal->reset_data) block->spindle.hal->reset_data(); uint32_t index = block->spindle.hal->get_data(SpindleData_Counters)->index_count + 2; - while(index != block->spindle.hal->get_data(SpindleData_Counters)->index_count); // check for abort in this loop? + while(index != block->spindle.hal->get_data(SpindleData_Counters)->index_count) { + + if(hal.get_elapsed_ticks() - ms > 5000) { + system_raise_alarm(Alarm_Spindle); + return; + } + + if(sys.rt_exec_state & (EXEC_RESET|EXEC_STOP)) { + system_set_exec_state_flag(EXEC_RESET); + return; + } + // TODO: allow real time reporting? + } } st_wake_up(); diff --git a/stream.h b/stream.h index 8b872ad..91fb0b4 100644 --- a/stream.h +++ b/stream.h @@ -77,6 +77,8 @@ Helper functions for saving away and restoring a stream input buffer. _Not refer #include #include +#include "vfs.h" + typedef enum { StreamType_Serial = 0, StreamType_MPG, @@ -245,6 +247,7 @@ typedef struct { get_stream_buffer_count_ptr get_tx_buffer_count; //!< Optional handler for getting number of characters in the output buffer(s). Count shall include any unsent characters in any transmit FIFO and/or transmit register. Required for Modbus support. flush_stream_buffer_ptr reset_write_buffer; //!< Optional handler for flushing the output buffer. Any transmit FIFO shall be flushed as well. Required for Modbus support. set_baud_rate_ptr set_baud_rate; //!< Optional handler for setting the stream baud rate. Required for Modbus support, recommended for Bluetooth support. +// vfs_file_t *file; //!< File handle, non-null if streaming from a file. } io_stream_t; typedef const io_stream_t *(*stream_claim_ptr)(uint32_t baud_rate);