mirror of
https://github.com/grblHAL/core.git
synced 2026-08-18 00:47:25 +08:00
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:
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 ]:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user