diff --git a/changelog.md b/changelog.md index 1cfbb28..63a8473 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,33 @@ ## grblHAL changelog +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. + +--- + 20250519 Plugins: diff --git a/driver_opts.h b/driver_opts.h index 3a376da..be409b1 100644 --- a/driver_opts.h +++ b/driver_opts.h @@ -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 diff --git a/driver_opts2.h b/driver_opts2.h index e4b6228..2c22efc 100644 --- a/driver_opts2.h +++ b/driver_opts2.h @@ -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 diff --git a/grbl.h b/grbl.h index dba03d6..54486b5 100644 --- a/grbl.h +++ b/grbl.h @@ -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" diff --git a/grbllib.c b/grbllib.c index fc92974..37a512d 100644 --- a/grbllib.c +++ b/grbllib.c @@ -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; diff --git a/hal.h b/hal.h index ed8c4c1..d3336d8 100644 --- a/hal.h +++ b/hal.h @@ -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; diff --git a/ioports.c b/ioports.c index 9186b25..9863bde 100644 --- a/ioports.c +++ b/ioports.c @@ -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); diff --git a/ngc_params.c b/ngc_params.c index 21babf9..bf48fe8 100644 --- a/ngc_params.c +++ b/ngc_params.c @@ -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: diff --git a/pin_bits_masks.h b/pin_bits_masks.h index 223a8e4..815dbb7 100644 --- a/pin_bits_masks.h +++ b/pin_bits_masks.h @@ -5,7 +5,7 @@ Part of grblHAL - Copyright (c) 2021-2024 Terje Io + Copyright (c) 2021-2025 Terje Io grblHAL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,8 @@ along with grblHAL. If not, see . */ +#include "platform.h" + // Sanity checks #if PROBE_ENABLE && !defined(PROBE_PIN) @@ -97,38 +99,6 @@ #endif // CONTROL_PORT -#ifndef RESET_BIT -#ifdef RESET_PIN -#define RESET_BIT (1<pin) { + if(ctrl_pin != &aux_ctrl[idx]) { + if((aux_ctrl[idx].cap.bits & main_signals.bits) || (aux_ctrl[idx].cap.bits && !ctrl_pin->cap.bits)) + ctrl_pin->irq_mode = IRQ_Mode_None; + } else if(ctrl_pin->cap.bits && !(aux_ctrl[idx].cap.bits & main_signals.bits)) + aux_ctrl[idx].irq_mode = IRQ_Mode_None; + } + } while(idx); + } + +#endif // STM32_PLATFORM + return ctrl_pin; } @@ -322,7 +262,7 @@ static inline aux_ctrl_t *aux_ctrl_get_pin (uint8_t aux_port) uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t); - do { + if(idx) do { if(aux_ctrl[--idx].aux_port == aux_port) ctrl_pin = &aux_ctrl[idx]; } while(idx && ctrl_pin == NULL); @@ -335,23 +275,12 @@ static inline void aux_ctrl_irq_enable (settings_t *settings, ioport_interrupt_c uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t); if(idx) do { - if(aux_ctrl[--idx].aux_port != 0xFF) { -#if PROBE_ENABLE && defined(PROBE_PIN) && defined(AUX_DEVICES) - if(aux_ctrl[idx].function == Input_Probe) { - xbar_t *xbar; - if((xbar = hal.port.get_pin_info(Port_Digital, Port_Input, aux_ctrl[idx].aux_port))) { - gpio_in_config_t cfg; - cfg.inverted = settings->probe.invert_probe_pin; - cfg.debounce = xbar->mode.debounce; - cfg.pull_mode = settings->probe.disable_probe_pullup ? PullMode_None : PullMode_Up; - xbar->config(xbar, &cfg, false); - } - } else -#endif - if(aux_ctrl[idx].irq_mode != IRQ_Mode_None) { - if(aux_ctrl[idx].irq_mode & (IRQ_Mode_Falling|IRQ_Mode_Rising)) - aux_ctrl[idx].irq_mode = (settings->control_invert.mask & aux_ctrl[idx].cap.mask) ? IRQ_Mode_Falling : IRQ_Mode_Rising; - hal.port.register_interrupt_handler(aux_ctrl[idx].aux_port, aux_ctrl[idx].irq_mode, aux_irq_handler); + if(aux_ctrl[--idx].aux_port != 0xFF && aux_ctrl[idx].irq_mode != IRQ_Mode_None) { + if(!(aux_ctrl[idx].function == Input_Probe || aux_ctrl[idx].function == Input_Probe2 || aux_ctrl[idx].function == Input_Toolsetter)) { + pin_irq_mode_t irq_mode; + if((irq_mode = aux_ctrl[idx].irq_mode) & IRQ_Mode_RisingFalling) + irq_mode = (settings->control_invert.mask & aux_ctrl[idx].cap.mask) ? IRQ_Mode_Falling : IRQ_Mode_Rising; + hal.port.register_interrupt_handler(aux_ctrl[idx].aux_port, irq_mode, aux_irq_handler); } } } while(idx); @@ -367,6 +296,13 @@ static bool aux_ctrl_claim_port (xbar_t *properties, uint8_t port, void *data) return ((aux_ctrl_t *)data)->aux_port != 0xFF; } +static bool aux_ctrl_find_port (xbar_t *properties, uint8_t port, void *data) +{ + ((aux_ctrl_t *)data)->aux_port = port; + + return true; +} + static inline void aux_ctrl_claim_ports (aux_claim_explicit_ptr aux_claim_explicit, ioports_enumerate_callback_ptr aux_claim) { uint_fast8_t idx; @@ -375,18 +311,27 @@ static inline void aux_ctrl_claim_ports (aux_claim_explicit_ptr aux_claim_explic aux_claim = aux_ctrl_claim_port; for(idx = 0; idx < sizeof(aux_ctrl) / sizeof(aux_ctrl_t); idx++) { + + pin_cap_t cap = { .irq_mode = aux_ctrl[idx].irq_mode, .claimable = On }; + + if(aux_ctrl[idx].pin == 0xFE) // Toolsetter and Probe2 + ioports_enumerate(Port_Digital, Port_Input, cap, aux_ctrl_find_port, (void *)&aux_ctrl[idx]); +#ifdef STM32_PLATFORM + if(aux_ctrl[idx].irq_mode == IRQ_Mode_None && !(aux_ctrl[idx].function == Input_Probe || aux_ctrl[idx].function == Input_LimitsOverride)) + continue; +#endif if(aux_ctrl[idx].pin == 0xFF) { - if(ioports_enumerate(Port_Digital, Port_Input, (pin_cap_t){ .irq_mode = aux_ctrl[idx].irq_mode, .claimable = On }, aux_claim, (void *)&aux_ctrl[idx])) + if(ioports_enumerate(Port_Digital, Port_Input, cap, aux_claim, (void *)&aux_ctrl[idx])) hal.signals_cap.mask |= aux_ctrl[idx].cap.mask; } else if(aux_ctrl[idx].aux_port != 0xFF) aux_claim_explicit(&aux_ctrl[idx]); } } -#if AUX_CONTROLS_SCAN - static inline control_signals_t aux_ctrl_scan_status (control_signals_t signals) { +#if PROBE_DISCONNECT_ENABLE || STOP_DISABLE_ENABLE || BLOCK_DELETE_ENABLE || SINGLE_BLOCK_ENABLE || LIMITS_OVERRIDE_ENABLE + uint_fast8_t idx = sizeof(aux_ctrl) / sizeof(aux_ctrl_t); if(idx) do { @@ -394,34 +339,21 @@ static inline control_signals_t aux_ctrl_scan_status (control_signals_t signals) break; if(aux_ctrl[idx].aux_port != 0xFF) { signals.mask &= ~aux_ctrl[idx].cap.mask; -#ifdef GRBL_ESP32 // Snowflake guru workaround + #ifdef GRBL_ESP32 // Snowflake guru workaround if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].aux_port, WaitMode_Immediate, FZERO) == 1) signals.mask |= aux_ctrl[idx].cap.mask; -#else + #else if(hal.port.wait_on_input(Port_Digital, aux_ctrl[idx].aux_port, WaitMode_Immediate, 0.0f) == 1) signals.mask |= aux_ctrl[idx].cap.mask; -#endif + #endif } } while(idx); +#endif + return signals; } -#endif - -#else -#define AUX_CONTROLS_ENABLED 0 -#define AUX_CONTROLS_SCAN 0 -#endif - -#if defined(AUX_CONTROLS_OUT) && !defined(AUX_CONTROLS) -#define AUX_CONTROLS AUX_CONTROL_SPINDLE -#elif !defined(AUX_CONTROLS) -#define AUX_CONTROLS 0 -#endif - -#if AUX_CONTROLS - // The following pins are bound explicitly to aux output pins static aux_ctrl_out_t aux_ctrl_out[] = { #if defined(ESP_PLATFORM) || defined(RP2040) // for now @@ -431,17 +363,28 @@ static aux_ctrl_out_t aux_ctrl_out[] = { #if defined(X_ENABLE_PIN) && X_ENABLE_PORT == EXPANDER_PORT { .function = Output_StepperEnableX, .aux_port = 0xFF, .pin = X_ENABLE_PIN, .port = (void *)X_ENABLE_PORT }, #endif +#if defined(X2_ENABLE_PIN) && X2_ENABLE_PORT == EXPANDER_PORT + { .function = Output_StepperEnableX2, .aux_port = 0xFF, .pin = X2_ENABLE_PIN, .port = (void *)X2_ENABLE_PORT }, +#endif #if defined(Y_ENABLE_PIN) && Y_ENABLE_PORT == EXPANDER_PORT { .function = Output_StepperEnableY, .aux_port = 0xFF, .pin = Y_ENABLE_PIN, .port = (void *)Y_ENABLE_PORT }, #endif +#if defined(Y2_ENABLE_PIN) && Y2_ENABLE_PORT == EXPANDER_PORT + { .function = Output_StepperEnableY2, .aux_port = 0xFF, .pin = Y2_ENABLE_PIN, .port = (void *)Y2_ENABLE_PORT }, +#endif #if defined(XY_ENABLE_PIN) && XY_ENABLE_PORT == EXPANDER_PORT { .function = Output_StepperEnableXY, .aux_port = 0xFF, .pin = XY_ENABLE_PIN, .port = (void *)XY_ENABLE_PORT }, #endif #if defined(Z_ENABLE_PIN) && Z_ENABLE_PORT == EXPANDER_PORT { .function = Output_StepperEnableZ, .aux_port = 0xFF, .pin = Z_ENABLE_PIN, .port = (void *)Z_ENABLE_PORT }, #endif +#if defined(Z2_ENABLE_PIN) && Z2_ENABLE_PORT == EXPANDER_PORT + { .function = Output_StepperEnableZ2, .aux_port = 0xFF, .pin = Z2_ENABLE_PIN, .port = (void *)Z2_ENABLE_PORT }, +#endif +#if defined(A_ENABLE_PIN) && A_ENABLE_PORT == EXPANDER_PORT + { .function = Output_StepperEnableA, .aux_port = 0xFF, .pin = A_ENABLE_PIN, .port = (void *)A_ENABLE_PORT }, +#endif #endif -#if AUX_CONTROLS & AUX_CONTROL_SPINDLE #ifdef SPINDLE_ENABLE_PIN #ifndef SPINDLE_ENABLE_PORT #define SPINDLE_ENABLE_PORT 0 @@ -479,9 +422,7 @@ static aux_ctrl_out_t aux_ctrl_out[] = { #endif { .function = Output_Spindle1Dir, .aux_port = 0xFF, .pin = SPINDLE1_DIRECTION_PIN, .port = (void *)SPINDLE1_DIRECTION_PORT }, #endif -#endif // SPINDLES -#if AUX_CONTROLS & AUX_CONTROL_COOLANT #ifdef COOLANT_FLOOD_PIN #ifndef COOLANT_FLOOD_PORT #define COOLANT_FLOOD_PORT 0 @@ -494,7 +435,6 @@ static aux_ctrl_out_t aux_ctrl_out[] = { #endif { .function = Output_CoolantMist, .aux_port = 0xFF, .pin = COOLANT_MIST_PIN, .port = (void *)COOLANT_MIST_PORT }, #endif -#endif // COOLANT #ifdef COPROC_RESET_PIN #ifndef COPROC_RESET_PORT @@ -570,20 +510,6 @@ static inline void aux_ctrl_claim_out_ports (aux_claim_explicit_out_ptr aux_clai } } -#endif // AUX_CONTROLS - -// - -#ifndef CONTROL_MASK -#if SAFETY_DOOR_ENABLE -#define CONTROL_MASK (RESET_BIT|FEED_HOLD_BIT|CYCLE_START_BIT|ESTOP_BIT|PROBE_DISCONNECT_BIT|STOP_DISABLE_BIT|BLOCK_DELETE_BIT|SINGLE_BLOCK_BIT|MOTOR_FAULT_BIT|MOTOR_WARNING_BIT|LIMITS_OVERRIDE_BIT|SAFETY_DOOR_BIT) -#define CONTROL_MASK_SUM (RESET_BIT+FEED_HOLD_BIT+CYCLE_START_BIT+ESTOP_BIT+PROBE_DISCONNECT_BIT+STOP_DISABLE_BIT+BLOCK_DELETE_BIT+SINGLE_BLOCK_BIT+MOTOR_FAULT_BIT+MOTOR_WARNING_BIT+LIMITS_OVERRIDE_BIT+SAFETY_DOOR_BIT) -#else -#define CONTROL_MASK (RESET_BIT|FEED_HOLD_BIT|CYCLE_START_BIT|ESTOP_BIT|PROBE_DISCONNECT_BIT|STOP_DISABLE_BIT|BLOCK_DELETE_BIT|SINGLE_BLOCK_BIT|MOTOR_FAULT_BIT|MOTOR_WARNING_BIT|LIMITS_OVERRIDE_BIT) -#define CONTROL_MASK_SUM (RESET_BIT+FEED_HOLD_BIT+CYCLE_START_BIT+ESTOP_BIT+PROBE_DISCONNECT_BIT+STOP_DISABLE_BIT+BLOCK_DELETE_BIT+SINGLE_BLOCK_BIT+MOTOR_FAULT_BIT+MOTOR_WARNING_BIT+LIMITS_OVERRIDE_BIT) -#endif -#endif - // Output Signals #if defined(SPINDLE_ENABLE_PIN) && !defined(SPINDLE_ENABLE_BIT) @@ -613,27 +539,6 @@ static inline void aux_ctrl_claim_out_ports (aux_claim_explicit_out_ptr aux_clai // IRQ enabled input singnals -#ifndef AUX_DEVICES - -// IRQ capability for the probe input is optional -#if defined(PROBE_PIN) && !defined(PROBE_BIT) -#define PROBE_BIT (1<