diff --git a/README.md b/README.md
index 7b97501..f760421 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 20230907, see the [changelog](changelog.md) for details.
+Latest build date is 20230919, 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 aa4fae0..83522bf 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,24 @@
## grblHAL changelog
+Build 20230919
+
+Core:
+
+* Added setting option to _$21 - Hard limit enable_ to enable exception for rotary axes.
+
+Plugins:
+
+* Spindle: fix for {issue #22](https://github.com/grblHAL/Plugins_spindle/issues/22), H100 VFD driver not working.
+
+Drivers:
+
+* Simulator: updates for core changes and for using native libraries for Windows build. Linux and Windows executables can now be built using the [Web Builder](http://svn.io-engineering.com:8080/?driver=Simulator).
+
+* STM32F1xx, STM32F4xx, LPC176x, RP2040: now keeps motor enable signals high until startup is completed to avoid current surges with Trinamic drivers.
+Ref [RP2040 issue #74](https://github.com/grblHAL/RP2040/issues/74)
+
+---
+
Build 20230917
Core:
diff --git a/config.h b/config.h
index ae8846e..d013d2c 100644
--- a/config.h
+++ b/config.h
@@ -919,6 +919,9 @@ not throw an alarm message.
#if !defined DEFAULT_CHECK_LIMITS_AT_INIT || defined __DOXYGEN__
#define DEFAULT_CHECK_LIMITS_AT_INIT Off
#endif
+#if !defined DEFAULT_HARD_LIMITS_DISABLE_FOR_ROTARY || defined __DOXYGEN__
+#define DEFAULT_HARD_LIMITS_DISABLE_FOR_ROTARY Off
+#endif
/*! @name Group_Limits_DualAxis
\brief Dual axis limits settings (Group_Limits_DualAxis)
diff --git a/grbl.h b/grbl.h
index 0c282f0..f0c9d44 100644
--- a/grbl.h
+++ b/grbl.h
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
-#define GRBL_BUILD 20230917
+#define GRBL_BUILD 20230919
#define GRBL_URL "https://github.com/grblHAL"
diff --git a/machine_limits.c b/machine_limits.c
index 0b16f63..8f75a71 100644
--- a/machine_limits.c
+++ b/machine_limits.c
@@ -87,6 +87,11 @@ ISR_CODE void ISR_FUNC(limit_interrupt_handler)(limit_signals_t state) // DEFAUL
// locked out until a homing cycle or a kill lock command. Allows the user to disable the hard
// limit setting if their limits are constantly triggering after a reset and move their axes.
+#if N_AXIS > 3
+ if((limit_signals_merge(state).value & sys.hard_limits.mask) == 0)
+ return;
+#endif
+
memcpy(&sys.last_event.limits, &state, sizeof(limit_signals_t));
if (!(state_get() & (STATE_ALARM|STATE_ESTOP)) && !sys.rt_exec_alarm) {
diff --git a/motion_control.c b/motion_control.c
index 3449b9d..4febedc 100644
--- a/motion_control.c
+++ b/motion_control.c
@@ -954,7 +954,9 @@ status_code_t mc_homing_cycle (axes_signals_t cycle)
system_add_rt_report(Report_Homed);
- homed_status = settings.limits.flags.hard_enabled && settings.limits.flags.check_at_init && limit_signals_merge(hal.limits.get_state()).value
+ homed_status = settings.limits.flags.hard_enabled &&
+ settings.limits.flags.check_at_init &&
+ (limit_signals_merge(hal.limits.get_state()).value & sys.hard_limits.mask)
? Status_LimitsEngaged
: Status_OK;
diff --git a/protocol.c b/protocol.c
index bc10593..65daac8 100644
--- a/protocol.c
+++ b/protocol.c
@@ -149,7 +149,9 @@ bool protocol_main_loop (void)
// blocks from crashing into things uncontrollably. Very bad.
system_raise_alarm(Alarm_HomingRequired);
grbl.report.feedback_message(Message_HomingCycleRequired);
- } else if (settings.limits.flags.hard_enabled && settings.limits.flags.check_at_init && limit_signals_merge(hal.limits.get_state()).value) {
+ } else if (settings.limits.flags.hard_enabled &&
+ settings.limits.flags.check_at_init &&
+ (limit_signals_merge(hal.limits.get_state()).value & sys.hard_limits.mask)) {
if(sys.alarm == Alarm_LimitsEngaged && hal.control.get_state().limits_override)
state_set(STATE_IDLE); // Clear alarm state to enable limit switch pulloff.
else {
diff --git a/settings.c b/settings.c
index c0cbf63..55b2f8c 100644
--- a/settings.c
+++ b/settings.c
@@ -143,6 +143,7 @@ PROGMEM const settings_t defaults = {
.limits.flags.soft_enabled = DEFAULT_SOFT_LIMIT_ENABLE,
.limits.flags.jog_soft_limited = DEFAULT_JOG_LIMIT_ENABLE,
.limits.flags.check_at_init = DEFAULT_CHECK_LIMITS_AT_INIT,
+ .limits.flags.hard_disabled_rotary = DEFAULT_HARD_LIMITS_DISABLE_FOR_ROTARY,
.limits.flags.two_switches = DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES,
.limits.invert.mask = DEFAULT_LIMIT_SIGNALS_INVERT_MASK,
.limits.disable_pullup.mask = DEFAULT_LIMIT_SIGNALS_PULLUP_DISABLE_MASK,
@@ -467,7 +468,11 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ Setting_ProbePullUpDisable, Group_Probing, "Pullup disable probe pin", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsExtendedFn, set_probe_disable_pullup, get_int, is_setting_available },
{ Setting_SoftLimitsEnable, Group_Limits, "Soft limits enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_soft_limits_enable, get_int, NULL },
#if COMPATIBILITY_LEVEL <= 1
+ #if N_AXIS > 3
+ { Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_XBitfield, "Enable,Strict mode,Disable for rotary axes", NULL, NULL, Setting_IsExpandedFn, set_hard_limits_enable, get_int, NULL },
+ #else
{ Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_XBitfield, "Enable,Strict mode", NULL, NULL, Setting_IsExpandedFn, set_hard_limits_enable, get_int, NULL },
+ #endif
#else
{ Setting_HardLimitsEnable, Group_Limits, "Hard limits enable", NULL, Format_Bool, NULL, NULL, NULL, Setting_IsLegacyFn, set_hard_limits_enable, get_int, NULL },
#endif
@@ -1062,12 +1067,28 @@ static status_code_t set_offset_lock (setting_id_t id, uint_fast16_t int_value)
return Status_OK;
}
+static inline void tmp_set_hard_limits (void)
+{
+ sys.hard_limits.mask = settings.limits.flags.hard_enabled ? AXES_BITMASK : 0;
+ #if N_AXIS > 3
+ if(settings.limits.flags.hard_disabled_rotary)
+ sys.hard_limits.mask &= ~settings.steppers.is_rotational.mask;
+ #endif
+}
+
static status_code_t set_hard_limits_enable (setting_id_t id, uint_fast16_t int_value)
{
- settings.limits.flags.hard_enabled = bit_istrue(int_value, bit(0));
+ if((settings.limits.flags.hard_enabled = bit_istrue(int_value, bit(0)))) {
#if COMPATIBILITY_LEVEL <= 1
- settings.limits.flags.check_at_init = bit_istrue(int_value, bit(1));
+ settings.limits.flags.check_at_init = bit_istrue(int_value, bit(1));
+ #if N_AXIS > 3
+ settings.limits.flags.hard_disabled_rotary = bit_istrue(int_value, bit(2));
+ #endif
#endif
+ } else
+ settings.limits.flags.check_at_init = settings.limits.flags.hard_disabled_rotary = Off;
+
+ tmp_set_hard_limits();
hal.limits.enable(settings.limits.flags.hard_enabled, (axes_signals_t){0}); // Change immediately. NOTE: Nice to have but could be problematic later.
return Status_OK;
@@ -1553,7 +1574,9 @@ static uint32_t get_int (setting_id_t id)
break;
case Setting_HardLimitsEnable:
- value = ((settings.limits.flags.hard_enabled & bit(0)) ? bit(0) | (settings.limits.flags.check_at_init ? bit(1) : 0) : 0);
+ value = ((settings.limits.flags.hard_enabled & bit(0)) ? bit(0) |
+ (settings.limits.flags.check_at_init ? bit(1) : 0) |
+ (settings.limits.flags.hard_disabled_rotary ? bit(2) : 0) : 0);
break;
case Setting_JogSoftLimited:
@@ -2784,6 +2807,7 @@ void settings_init (void)
xbar_set_homing_source();
tmp_set_soft_limits();
+ tmp_set_hard_limits();
if(spindle_get_count() == 0)
spindle_add_null();
diff --git a/settings.h b/settings.h
index 5f20a37..b30591d 100644
--- a/settings.h
+++ b/settings.h
@@ -640,12 +640,13 @@ typedef struct {
typedef union {
uint8_t value;
struct {
- uint8_t hard_enabled :1,
- soft_enabled :1,
- check_at_init :1,
- jog_soft_limited :1,
- two_switches :1,
- unassigned :3;
+ uint8_t hard_enabled :1,
+ soft_enabled :1,
+ check_at_init :1,
+ jog_soft_limited :1,
+ two_switches :1,
+ hard_disabled_rotary :1,
+ unassigned :2;
};
} limit_settings_flags_t;
diff --git a/system.h b/system.h
index 92453b6..0ffced1 100644
--- a/system.h
+++ b/system.h
@@ -307,6 +307,7 @@ typedef struct system {
bool mpg_mode; //!< To be moved to system_flags_t
signal_event_t last_event; //!< Last signal events (control and limits signal).
int32_t position[N_AXIS]; //!< Real-time machine (aka home) position vector in steps.
+ axes_signals_t hard_limits; //!< temporary?, will be removed when available in settings.
axes_signals_t soft_limits; //!< temporary, will be removed when available in settings.
//@}
} system_t;