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.
This commit is contained in:
Terje Io
2023-07-04 15:40:47 +02:00
parent 83d708a872
commit c2450947ae
14 changed files with 162 additions and 46 deletions
+1 -1
View File
@@ -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.
+15
View File
@@ -1,5 +1,20 @@
## grblHAL changelog
<a name="20230704"/>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).
---
<a name="20230626"/>Build 20230626
Core:
+29 -26
View File
@@ -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 ]:
+2
View File
@@ -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
+1 -1
View File
@@ -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"
+14 -11
View File
@@ -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;
+2 -1
View File
@@ -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)
+2 -1
View File
@@ -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 {
+11
View File
@@ -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;
+5
View File
@@ -34,6 +34,9 @@
#include <stdint.h>
#include <stdbool.h>
#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
+59 -4
View File
@@ -193,16 +193,71 @@
#define COOLANT_MIST_BIT (1<<COOLANT_MIST_PIN)
#endif
#if defined(I2C_STROBE_PIN) && !defined(I2C_STROBE_BIT)
#if defined(RTS_PIN) && !defined(RTS_BIT)
#define RTS_BIT (1<<RTS_PIN)
#endif
// IRQ enabled input singnals
#if SAFETY_DOOR_ENABLE
#ifndef SAFETY_DOOR_BIT
#define SAFETY_DOOR_BIT (1<<SAFETY_DOOR_PIN)
#endif
#else
#define SAFETY_DOOR_BIT 0
#endif
#ifndef MPG_MODE_PIN
#define MPG_MODE_BIT 0
#elif !defined(MPG_MODE_BIT)
#define MPG_MODE_BIT (1<<MPG_MODE_PIN)
#endif
#ifndef I2C_STROBE_PIN
#define I2C_STROBE_BIT 0
#elif !defined(I2C_STROBE_BIT)
#define I2C_STROBE_BIT (1<<I2C_STROBE_PIN)
#endif
#if defined(SPI_IRQ_PIN) && !defined(SPI_IRQ_BIT)
#ifndef SPI_IRQ_PIN
#define SPI_IRQ_BIT 0
#elif !defined(SPI_IRQ_BIT)
#define SPI_IRQ_BIT (1<<SPI_IRQ_PIN)
#endif
#if defined(RTS_PIN) && !defined(RTS_BIT)
#define RTS_BIT (1<<RTS_PIN)
#if SPINDLE_SYNC_ENABLE
#ifndef SPINDLE_INDEX_BIT
#define SPINDLE_INDEX_BIT (1<<SPINDLE_INDEX_PIN)
#endif
#ifndef SPINDLE_PULSE_BIT
#define SPINDLE_PULSE_BIT (1<<SPINDLE_PULSE_PIN)
#endif
#else
#define SPINDLE_INDEX_BIT 0
#define SPINDLE_PULSE_BIT 0
#endif
#if QEI_ENABLE
#ifndef QEI_A_BIT
#define QEI_A_BIT (1<<QEI_A_PIN)
#endif
#ifndef QEI_B_BIT
#define QEI_B_BIT (1<<QEI_B_PIN)
#endif
#ifndef QEI_SELECT_PIN
#define QEI_SELECT_BIT 0
#elif !defined(QEI_SELECT_BIT)
#define QEI_SELECT_BIT (1<<QEI_SELECT_PIN)
#endif
#else
#define QEI_A_BIT 0
#define QEI_B_BIT 0
#define QEI_SELECT_BIT 0
#endif
#ifndef DEVICES_IRQ_MASK
#define DEVICES_IRQ_MASK (MPG_MODE_BIT|I2C_STROBE_BIT|SPI_IRQ_BIT|SPINDLE_INDEX_BIT|QEI_A_BIT|QEI_B_BIT|QEI_SELECT_BIT)
#define DEVICES_IRQ_MASK_SUM (MPG_MODE_BIT+I2C_STROBE_BIT+SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+QEI_SELECT_BIT)
#endif
// Auxillary input signals
+3
View File
@@ -137,6 +137,9 @@ bool protocol_main_loop (void)
// Check for motor fault active. Blocks everything until cleared.
system_raise_alarm(Alarm_MotorFault);
grbl.report.feedback_message(Message_MotorFault);
} else if(settings.probe.enable_protection && hal.control.get_state().probe_triggered) {
system_raise_alarm(Alarm_ProbeProtect);
grbl.report.feedback_message(Message_ProbeProtected);
} else if (limits_homing_required()) {
// Check for power-up and set system alarm if homing is enabled to force homing cycle
// by setting Grbl's alarm state. Alarm locks out all g-code commands, including the
+15 -1
View File
@@ -260,12 +260,26 @@ void state_set (sys_state_t new_state)
st_prep_buffer(); // Initialize step segment buffer before beginning cycle.
if (block->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();
+3
View File
@@ -77,6 +77,8 @@ Helper functions for saving away and restoring a stream input buffer. _Not refer
#include <stdint.h>
#include <stdbool.h>
#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);