Skip to content

Commit

Permalink
Now allows some $-commands while critical events are active or in sle…
Browse files Browse the repository at this point in the history
…ep mode.

Added work envelope data to global sys struct, used by soft limits and jog limit handling.
  • Loading branch information
terjeio committed Apr 29, 2023
1 parent 36035cf commit c652eee
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 120 deletions.
16 changes: 16 additions & 0 deletions changelog.md
@@ -1,5 +1,21 @@
## grblHAL changelog

<a name="20230429"/>Build 20230429

Core:

* Now allows some $-commands while critical events are active or in sleep mode. E.g. settings commands can be used to configure the controller.

* Added work envelope data to [global sys struct](http://svn.io-engineering.com/grblHAL/html/structsystem.html), used by soft limits and jog limit handling. This can be modified by plugin code to restrict motion.

Drivers:

* STM32F1xx: added driver support for ganged and auto-squared axes.

* STM32F4xx: fixed typos.

---

<a name="20230427"/>Build 20230427

Core:
Expand Down
1 change: 1 addition & 0 deletions errors.c
Expand Up @@ -93,6 +93,7 @@ PROGMEM static const status_detail_t status_detail[] = {
#endif
{ Status_AuthenticationRequired, "Authentication required." },
{ Status_AccessDenied, "Access denied." },
{ Status_NotAllowedCriticalEvent, "Not allowed while critical event is active." }
};

static error_details_t details = {
Expand Down
1 change: 1 addition & 0 deletions errors.h
Expand Up @@ -105,6 +105,7 @@ typedef enum {

Status_AuthenticationRequired = 77,
Status_AccessDenied = 78,
Status_NotAllowedCriticalEvent = 79,

Status_Unhandled, // For internal use only
Status_StatusMax = Status_Unhandled
Expand Down
2 changes: 1 addition & 1 deletion grbl.h
Expand Up @@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20230427
#define GRBL_BUILD 20230429

#define GRBL_URL "https://github.com/grblHAL"

Expand Down
30 changes: 30 additions & 0 deletions machine_limits.c
Expand Up @@ -109,7 +109,36 @@ ISR_CODE void ISR_FUNC(limit_interrupt_handler)(limit_signals_t state) // DEFAUL
}
}

// Establish work envelope for homed axes, used by soft limits and jog limits handling.
// When hard limits are enabled pulloff distance is subtracted to avoid triggering limit switches.
void limits_set_work_envelope (void)
{
uint_fast8_t idx = N_AXIS;

do {
if(sys.homed.mask & bit(--idx)) {

float pulloff = settings.limits.flags.hard_enabled && bit_istrue(sys.homing.mask, bit(idx)) ? settings.homing.pulloff : 0.0f;

if(settings.homing.flags.force_set_origin) {
if(bit_isfalse(settings.homing.dir_mask.value, bit(idx))) {
sys.work_envelope.min[idx] = settings.axis[idx].max_travel + pulloff;
sys.work_envelope.max[idx] = 0.0f;
} else {
sys.work_envelope.min[idx] = 0.0f;
sys.work_envelope.max[idx] = - (settings.axis[idx].max_travel + pulloff);
}
} else {
sys.work_envelope.min[idx] = settings.axis[idx].max_travel + pulloff;
sys.work_envelope.max[idx] = - pulloff;
}
} else
sys.work_envelope.min[idx] = sys.work_envelope.max[idx] = 0.0f;
} while(idx);
}

#ifndef KINEMATICS_API

// Set machine positions for homed limit switches. Don't update non-homed axes.
// NOTE: settings.max_travel[] is stored as a negative value.
void limits_set_machine_positions (axes_signals_t cycle, bool add_pulloff)
Expand All @@ -133,6 +162,7 @@ void limits_set_machine_positions (axes_signals_t cycle, bool add_pulloff)
}
} while(idx);
}

#endif

// Pulls off axes from asserted homing switches before homing starts.
Expand Down
3 changes: 2 additions & 1 deletion machine_limits.h
Expand Up @@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2022 Terje Io
Copyright (c) 2017-2023 Terje Io
Copyright (c) 2012-2015 Sungeun K. Jeon
Copyright (c) 2009-2011 Simen Svale Skogsrud
Expand Down Expand Up @@ -45,6 +45,7 @@ bool limits_homing_required (void);
// Set axes to be homed from settings.
void limits_set_homing_axes (void);
void limits_set_machine_positions (axes_signals_t cycle, bool add_pulloff);
void limits_set_work_envelope (void);

void limit_interrupt_handler (limit_signals_t state);

Expand Down
9 changes: 7 additions & 2 deletions motion_control.c
Expand Up @@ -929,8 +929,13 @@ status_code_t mc_homing_cycle (axes_signals_t cycle)
? Status_LimitsEngaged
: Status_OK;

if(homed_status == Status_OK && grbl.on_homing_completed)
grbl.on_homing_completed();
if(homed_status == Status_OK) {

limits_set_work_envelope();

if(grbl.on_homing_completed)
grbl.on_homing_completed();
}

return homed_status;
}
Expand Down
82 changes: 64 additions & 18 deletions protocol.c
Expand Up @@ -61,7 +61,7 @@ static char xcommand[LINE_BUFFER_SIZE];
static bool keep_rt_commands = false;
static realtime_queue_t realtime_queue = {0};

static void protocol_exec_rt_suspend ();
static void protocol_exec_rt_suspend (sys_state_t state);
static void protocol_execute_rt_commands (void);

// add gcode to execute not originating from normal input stream
Expand Down Expand Up @@ -239,14 +239,14 @@ bool protocol_main_loop (void)
// Direct and execute one line of formatted input, and report status of execution.
if (line_flags.overflow) // Report line overflow error.
gc_state.last_error = Status_Overflow;
else if(line[0] == '\0') // Empty line. For syncing purposes.
else if(*line == '\0') // Empty line. For syncing purposes.
gc_state.last_error = Status_OK;
else if (line[0] == '$') {// Grbl '$' system command
else if(*line == '$') {// Grbl '$' system command
if((gc_state.last_error = system_execute_line(line)) == Status_LimitsEngaged) {
system_raise_alarm(Alarm_LimitsEngaged);
grbl.report.feedback_message(Message_CheckLimits);
}
} else if (line[0] == '[' && grbl.on_user_command)
} else if(*line == '[' && grbl.on_user_command)
gc_state.last_error = grbl.on_user_command(line);
else if (state_get() & (STATE_ALARM|STATE_ESTOP|STATE_JOG)) // Everything else is gcode. Block if in alarm, eStop or jog mode.
gc_state.last_error = Status_SystemGClock;
Expand Down Expand Up @@ -276,7 +276,7 @@ bool protocol_main_loop (void)
keep_rt_commands = false;
char_counter = line_flags.value = 0;

} else if (c <= (char_counter > 0 ? ' ' - 1 : ' '))
} else if (c != ASCII_BS && c <= (char_counter > 0 ? ' ' - 1 : ' '))
continue; // Strip control characters and leading whitespace.
else {
switch(c) {
Expand Down Expand Up @@ -304,6 +304,7 @@ bool protocol_main_loop (void)
}
break;

case ASCII_BS:
case ASCII_DEL:
if(char_counter) {
line[--char_counter] = '\0';
Expand Down Expand Up @@ -388,18 +389,42 @@ bool protocol_execute_realtime (void)
{
if(protocol_exec_rt_system()) {

if (sys.suspend)
protocol_exec_rt_suspend();
sys_state_t state = state_get();

#if NVSDATA_BUFFER_ENABLE
if((state_get() == STATE_IDLE || (state_get() & (STATE_ALARM|STATE_ESTOP))) && settings_dirty.is_dirty && !gc_state.file_run)
if(sys.suspend)
protocol_exec_rt_suspend(state);

#if NVSDATA_BUFFER_ENABLE
if((state == STATE_IDLE || (state & (STATE_ALARM|STATE_ESTOP))) && settings_dirty.is_dirty && !gc_state.file_run)
nvs_buffer_sync_physical();
#endif
#endif
}

return !ABORTED;
}

static void protocol_poll_cmd (void)
{
int16_t c;

if((c = hal.stream.read()) != SERIAL_NO_DATA) {

if ((c == '\n') || (c == '\r')) { // End of line reached
line[char_counter] = '\0';
gc_state.last_error = *line == '\0' ? Status_OK : (*line == '$' ? system_execute_line(line) : Status_SystemGClock);
char_counter = 0;
*line = '\0';
grbl.report.status_message(gc_state.last_error);
} else if(c == ASCII_DEL || c == ASCII_BS) {
if(char_counter)
line[--char_counter] = '\0';
} else if(char_counter == 0 ? c != ' ' : char_counter < (LINE_BUFFER_SIZE - 1))
line[char_counter++] = c;

keep_rt_commands = char_counter > 0 && *line == '$';
}
}

// Executes run-time commands, when required. This function primarily operates as Grbl's state
// machine and controls the various real-time features Grbl has to offer.
// NOTE: Do not alter this unless you know exactly what you are doing!
Expand All @@ -426,11 +451,13 @@ bool protocol_exec_rt_system (void)
hal.driver_reset();

// Halt everything upon a critical event flag. Currently hard and soft limits flag this.
if ((alarm_code_t)rt_exec == Alarm_HardLimit ||
(alarm_code_t)rt_exec == Alarm_SoftLimit ||
(alarm_code_t)rt_exec == Alarm_EStop ||
(alarm_code_t)rt_exec == Alarm_MotorFault) {
if((sys.blocking_event = (alarm_code_t)rt_exec == Alarm_HardLimit ||
(alarm_code_t)rt_exec == Alarm_SoftLimit ||
(alarm_code_t)rt_exec == Alarm_EStop ||
(alarm_code_t)rt_exec == Alarm_MotorFault)) {

system_set_exec_alarm(rt_exec);

switch((alarm_code_t)rt_exec) {

case Alarm_EStop:
Expand All @@ -445,20 +472,30 @@ bool protocol_exec_rt_system (void)
grbl.report.feedback_message(Message_CriticalEvent);
break;
}

system_clear_exec_state_flag(EXEC_RESET); // Disable any existing reset

*line = '\0';
char_counter = 0;
hal.stream.reset_read_buffer();

while (bit_isfalse(sys.rt_exec_state, EXEC_RESET)) {

// Block everything, except reset and status reports, until user issues reset or power
// cycles. Hard limits typically occur while unattended or not paying attention. Gives
// the user and a GUI time to do what is needed before resetting, like killing the
// incoming stream. The same could be said about soft limits. While the position is not
// lost, continued streaming could cause a serious crash if by chance it gets executed.

if(bit_istrue(sys.rt_exec_state, EXEC_STATUS_REPORT)) {
system_clear_exec_state_flag(EXEC_STATUS_REPORT);
report_realtime_status();
}

protocol_poll_cmd();
grbl.on_execute_realtime(STATE_ESTOP);
}

system_clear_exec_alarm(); // Clear alarm
}
}
Expand Down Expand Up @@ -723,13 +760,22 @@ bool protocol_exec_rt_system (void)
// whatever function that invoked the suspend, such that Grbl resumes normal operation.
// This function is written in a way to promote custom parking motions. Simply use this as a
// template.
static void protocol_exec_rt_suspend (void)
static void protocol_exec_rt_suspend (sys_state_t state)
{
while (sys.suspend) {
if((sys.blocking_event = state == STATE_SLEEP)) {
*line = '\0';
char_counter = 0;
hal.stream.reset_read_buffer();
}

if (sys.abort)
while(sys.suspend) {

if(sys.abort)
return;

if(sys.blocking_event)
protocol_poll_cmd();

// Handle spindle overrides during suspend
state_suspend_manager();

Expand Down Expand Up @@ -910,7 +956,7 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
break;

default:
if(c < ' ' || (c > ASCII_DEL && c <= 0xBF))
if((c < ' ' && c != ASCII_BS) || (c > ASCII_DEL && c <= 0xBF))
drop = grbl.on_unknown_realtime_cmd == NULL || grbl.on_unknown_realtime_cmd(c);
break;
}
Expand Down

0 comments on commit c652eee

Please sign in to comment.