Completed core support for additional probes (toolsetter, probe 2).

Switched to universal use of aux I/O for many signals, includes reset/ESTop, feed hold and cycle start.
This commit is contained in:
Terje Io
2025-05-29 13:02:10 +02:00
parent 070f80cc5c
commit fc7ec7e219
11 changed files with 300 additions and 312 deletions
+28
View File
@@ -1,5 +1,33 @@
## grblHAL changelog
<a name="20250526">Build 20250526
Core:
* Completed core support for additional probes \(toolsetter, probe 2\).
* Switched to universal use of aux I/O for many signals, includes reset/ESTop, feed hold and cycle start.
> [!NOTE]
> The board map syntax for assigning reset/ESTop, feed hold and cycle start inputs has changed and any custom map files has to be updated.
Please refer to an existing _\*\_map.h_ file for how to do this.
Drivers:
* STM32F1xx: removed support for 128K flash devices.
* SAMD21, PSoC5, TM4C1294 and MSP432E401Y: no longer updated for new core builds, latest supported core is build 20250518.
* All but SAMD21, PSoC5, TM4C1294 and MSP432E401Y: added driver support for additional probes, updated to use universal aux I/O.
Additional probe input pins can either be explicitly mapped in the board map file or claimed from the pool of unassigned auxiliary inputs.
> [!NOTE]
> I do not have access to all the different boards supported nor the time to verify all so please carefully verify correct operation of at least probe and reset/EStop inputs after upgrading.
Plugins:
* Misc, BLTouch: fixed typo.
---
<a name="20250519">20250519
Plugins:
+20 -29
View File
@@ -87,10 +87,6 @@
#define N_AUTO_SQUARED (X_AUTO_SQUARE + Y_AUTO_SQUARE + Z_AUTO_SQUARE)
#define N_ABC_MOTORS (N_ABC_AXIS + N_GANGED)
#ifndef PROBE_ENABLE
#define PROBE_ENABLE 1
#endif
#ifndef NEOPIXELS_ENABLE
#define NEOPIXELS_ENABLE 0
#endif
@@ -251,26 +247,29 @@
#warning "Enabling ESTOP may not work with all senders!"
#endif
#define AUX_CONTROL_SPINDLE 0b0001
#define AUX_CONTROL_COOLANT 0b0010
#define AUX_CONTROL_DEVICES 0b0100
#define AUX_CONTROL_INPUTS 0b1000
// Control signals, keep in sync with control_signals_t
#define CONTROL_RESET 0b0000001
#define CONTROL_FEEDHOLD 0b0000010
#define CONTROL_CYCLESTART 0b0000100
#define CONTROL_SAFETYDOOR 0b0001000
#define CONTROL_BLOCKDELETE 0b0010000
#define CONTROL_STOPDISABLE 0b0100000
#define CONTROL_ESTOP 0b1000000
#ifndef CONTROL_ENABLE
// Control signals, keep in sync with control_signals_t bit order
#define CONTROL_RESET (1<<0)
#define CONTROL_FEED_HOLD (1<<1)
#define CONTROL_CYCLE_START (1<<2)
#define CONTROL_ESTOP (1<<6)
#if ESTOP_ENABLE
#define CONTROL_ENABLE (CONTROL_FEEDHOLD|CONTROL_CYCLESTART|CONTROL_ESTOP)
#define CONTROL_HALT CONTROL_ESTOP
#else
#define CONTROL_ENABLE (CONTROL_RESET|CONTROL_FEEDHOLD|CONTROL_CYCLESTART)
#define CONTROL_HALT CONTROL_RESET
#endif
// Probe signals
#ifndef PROBE_ENABLE
#define PROBE_ENABLE 1
#endif
#ifndef PROBE2_ENABLE
#define PROBE2_ENABLE 0
#endif
#ifndef TOOLSETTER_ENABLE
#define TOOLSETTER_ENABLE 0
#endif
// Coolant signals, keep in sync with coolant_state_t
@@ -477,14 +476,6 @@
#define LIMITS_OVERRIDE_ENABLE 0
#endif
#ifndef PROBE2_ENABLE
#define PROBE2_ENABLE 0
#endif
#ifndef TOOLSETTER_ENABLE
#define TOOLSETTER_ENABLE 0
#endif
#if SAFETY_DOOR_ENABLE && defined(NO_SAFETY_DOOR_SUPPORT)
#error "Driver does not support safety door functionality!"
#endif
+6
View File
@@ -55,6 +55,12 @@
#error "I2C strobe not supported!"
#endif
#define DRIVER_PROBES ((PROBE_ENABLE ? 1 : 0) + PROBE2_ENABLE + TOOLSETTER_ENABLE)
#ifndef CONTROL_ENABLE
#define CONTROL_ENABLE 0
#endif
#if EEPROM_ENABLE == 0
#define FLASH_ENABLE 1
#else
+1 -1
View File
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20250518
#define GRBL_BUILD 20250526
#define GRBL_URL "https://github.com/grblHAL"
-1
View File
@@ -248,7 +248,6 @@ int grbl_enter (void)
hal.control.interrupt_callback = control_interrupt_handler;
hal.stepper.interrupt_callback = stepper_driver_interrupt_handler;
hal.stream_blocking_callback = stream_tx_blocking;
hal.signals_cap.reset = hal.signals_cap.feed_hold = hal.signals_cap.cycle_start = On;
hal.signals_pullup_disable_cap.value = (uint16_t)-1;
sys.cold_start = true;
+3 -2
View File
@@ -69,12 +69,13 @@ typedef union {
odometers :1,
pwm_spindle :1,
probe_latch :1, //!< Deprecated.
toolsetter :1, //!< Toolsetter (2nd probe) input is supported.
probe :1, //!< Primary (default) probe input is supported.
probe2 :1, //!< 2nd or 3rd probe input is supported.
toolsetter :1, //!< Toolsetter (2nd probe) input is supported.
rtc :1,
rtc_set :1,
bltouch_probe :1,
unassigned :6;
unassigned :5;
};
} driver_cap_t;
+39 -23
View File
@@ -1255,6 +1255,38 @@ static const setting_descr_t ioport_settings_descr[] = {
#endif
static bool config_probe_pins (pin_function_t function, gpio_in_config_t *config)
{
bool ok = true;
switch(function) {
case Input_Probe:
config->debounce = Off;
config->inverted = settings.probe.invert_probe_pin;
config->pull_mode = settings.probe.disable_probe_pullup ? PullMode_None : PullMode_Up;
break;
case Input_Probe2:
config->debounce = Off;
config->inverted = settings.probe.invert_probe2_input;
config->pull_mode = settings.probe.disable_probe_pullup ? PullMode_None : PullMode_Up;
break;
case Input_Toolsetter:
config->debounce = Off;
config->inverted = settings.probe.invert_toolsetter_input;
config->pull_mode = settings.probe.disable_toolsetter_pullup ? PullMode_None : PullMode_Up;
break;
default:
ok = false;
break;
}
return ok;
}
void ioport_setting_changed (setting_id_t id)
{
if(on_setting_changed)
@@ -1271,29 +1303,11 @@ void ioport_setting_changed (setting_id_t id)
do {
if((xbar = hal.port.get_pin_info(Port_Digital, Port_Input, map_reverse(&ports_cfg[Port_DigitalIn], --port)))) {
if(xbar->config && xbar->function == Input_Probe) {
in_config.debounce = Off;
in_config.inverted = settings.probe.invert_probe_pin;
in_config.pull_mode = settings.probe.disable_probe_pullup ? PullMode_None : PullMode_Up;
if(xbar->config && config_probe_pins(xbar->function, &in_config)) {
if(in_config.inverted)
settings.ioport.invert_in.mask |= (1 << port);
else
settings.ioport.invert_in.mask &= ~(1 << port);
xbar->config(xbar, &in_config, false);
} else if(xbar->config && xbar->function == Input_Toolsetter) {
in_config.debounce = Off;
in_config.inverted = settings.probe.invert_toolsetter_input;
in_config.pull_mode = settings.probe.disable_toolsetter_pullup ? PullMode_None : PullMode_Up;
if(in_config.inverted)
settings.ioport.invert_in.mask |= (1 << port);
else
settings.ioport.invert_in.mask &= ~(1 << port);
xbar->config(xbar, &in_config, false);
}
}
@@ -1368,12 +1382,14 @@ static void ioports_configure (settings_t *settings)
#endif
} else { // For probe and control signals higher level config takes priority
in_config.inverted = Off;
if(xbar->function == Input_Probe)
in_config.pull_mode = settings->probe.disable_probe_pullup ? PullMode_None : PullMode_Up;
else if(xbar->function < Input_Probe) {
if(!config_probe_pins(xbar->function, &in_config) && xbar->function < Input_Probe) {
control_signals_t ctrl;
if((ctrl = xbar_fn_to_signals_mask(xbar->function)).mask)
if((ctrl = xbar_fn_to_signals_mask(xbar->function)).mask) {
#ifdef RP2040 // RP2xxx MCUs use hardware signal inversion
in_config.inverted = !!(settings->control_invert.mask & ctrl.mask);
#endif
in_config.pull_mode = (settings->control_disable_pullup.mask & ctrl.mask) ? PullMode_None : PullMode_Up;
}
}
}
xbar->config(xbar, &in_config, false);
+31 -2
View File
@@ -620,11 +620,40 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
// grblHAL extensions
case NGCParam_probe_state:
value = hal.probe.get_state ? (float)hal.probe.get_state().triggered : -1.0f;
value = -1.0f;
if(hal.probe.get_state /*&& hal.driver_cap.probe*/) {
probe_state_t probe_state = hal.probe.get_state();
if((probe_id_t)probe_state.probe_id == Probe_Default)
value = (float)probe_state.triggered;
else if(hal.probe.select) {
if(hal.probe.select(Probe_Default))
value = (float)hal.probe.get_state().triggered;
hal.probe.select((probe_id_t)probe_state.probe_id);
}
}
break;
case NGCParam_toolsetter_state:
value = hal.probe.get_state && hal.driver_cap.toolsetter ? (float)hal.probe.get_state().tls_triggered : -1.0f;
value = -1.0f;
if(hal.probe.get_state && hal.driver_cap.toolsetter) {
probe_state_t probe_state = hal.probe.get_state();
if((probe_id_t)probe_state.probe_id == Probe_Toolsetter)
value = (float)probe_state.triggered;
else if(hal.probe.select) {
if(hal.probe.select(Probe_Toolsetter))
value = (float)hal.probe.get_state().triggered;
hal.probe.select((probe_id_t)probe_state.probe_id);
} else
value = (float)probe_state.tls_triggered;
}
break;
default:
+146 -246
View File
File diff suppressed because it is too large Load Diff
+13 -1
View File
@@ -48,9 +48,21 @@ typedef union {
};
} probe_state_t;
typedef union {
uint8_t value;
struct {
uint8_t connected :1, //!< Set to true when probe is connected. Always set to true if the driver does not have a probe connected input.
latchable :1, //!< Set to true when probe input supports change rising/falling.
watchable :1, //!< Set to true when probe input supports change interrupt.
unassigned :5;
};
} probe_flags_t;
typedef struct {
probe_id_t probe_id;
probe_flags_t flags;
uint8_t port;
bool latchable;
void *input;
} probe_t;
#endif
+13 -7
View File
@@ -60,23 +60,29 @@ directly from the incoming data stream.
*/
ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
{
static control_signals_t onoff_signals = {
static const control_signals_t onoff_signals = {
.block_delete = On,
.single_block = On,
.stop_disable = On,
.deasserted = On
};
static const control_signals_t critical_signals = {
.reset = On,
.e_stop = On,
.motor_fault = On
};
if(signals.deasserted)
signals.value &= onoff_signals.mask;
signals.bits &= onoff_signals.bits;
if(signals.value) {
if(signals.bits) {
sys.last_event.control.value = signals.value;
sys.last_event.control.bits = signals.bits;
if((signals.reset || signals.e_stop || signals.motor_fault) && state_get() != STATE_ESTOP)
mc_reset();
else {
if(signals.bits & critical_signals.bits) {
if(state_get() != STATE_ESTOP)
mc_reset();
} else {
#ifndef NO_SAFETY_DOOR_SUPPORT
if(signals.safety_door_ajar && hal.signals_cap.safety_door_ajar && !gc_state.tool_change) {
if(settings.safety_door.flags.ignore_when_idle) {