mirror of
https://github.com/grblHAL/core.git
synced 2026-02-06 00:52:35 +08:00
Improved parameter handling some more, now allows indirected O-calls and line numbers with O-word.
Fix for issue #609, homing may cause a controller crash.
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 20241014, see the [changelog](changelog.md) for details.
|
||||
Latest build date is 20241016, see the [changelog](changelog.md) for details.
|
||||
|
||||
__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
|
||||
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.
|
||||
|
||||
14
changelog.md
14
changelog.md
@@ -1,5 +1,19 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20241016">Build 20241016
|
||||
|
||||
Core:
|
||||
|
||||
* Improved parameter handling some more, now allows indirected O-calls and line numbers with O-word.
|
||||
|
||||
* Fix for [issue #609](https://github.com/grblHAL/core/issues/609), homing may cause a controller crash.
|
||||
|
||||
Plugins:
|
||||
|
||||
* Spindle: Fixed compiler warning. Ref. [issue #33](https://github.com/grblHAL/Plugins_spindle/issues/33)
|
||||
|
||||
---
|
||||
|
||||
<a name="20241014">Build 20241014
|
||||
|
||||
Core:
|
||||
|
||||
77
gcode.c
77
gcode.c
@@ -992,45 +992,60 @@ status_code_t gc_execute_block (char *block)
|
||||
|
||||
if(block[char_counter] == '<') {
|
||||
|
||||
char *s = &block[++char_counter];
|
||||
|
||||
while(*s && *s != '>')
|
||||
s++;
|
||||
|
||||
if(*s && *(s + 1) == '=') {
|
||||
char *name = &block[char_counter];
|
||||
*s++ = '\0';
|
||||
s++;
|
||||
char_counter += s - name;
|
||||
if((status = ngc_read_real_value(block, &char_counter, &value)) != Status_OK)
|
||||
FAIL(status); // [Expected parameter value]
|
||||
if(!ngc_named_param_set(name, value))
|
||||
FAIL(Status_BadNumberFormat); // [Expected equal sign]
|
||||
}
|
||||
char name[NGC_MAX_PARAM_LENGTH + 1];
|
||||
|
||||
if((status = ngc_read_name(block, &char_counter, name)) == Status_OK) {
|
||||
if(block[char_counter++] != '=')
|
||||
status = Status_BadNumberFormat; // [Expected equal sign]
|
||||
else if((status = ngc_read_real_value(block, &char_counter, &value)) == Status_OK) {
|
||||
if(!ngc_named_param_set(name, value))
|
||||
status = Status_BadNumberFormat; // [Out of memory or attempt to write RO parameter]
|
||||
} // else: [Expected value]
|
||||
} // else: [Expected parameter name]
|
||||
} else {
|
||||
|
||||
float param;
|
||||
|
||||
if((status = ngc_read_real_value(block, &char_counter, ¶m)) != Status_OK) {
|
||||
FAIL(status); // [Expected parameter number]
|
||||
} else if(!ngc_param_is_rw((ngc_param_id_t)param))
|
||||
FAIL(Status_GcodeValueOutOfRange); // [Parameter does not exist or is read only]
|
||||
|
||||
if(block[char_counter++] != '=')
|
||||
FAIL(Status_BadNumberFormat); // [Expected equal sign]
|
||||
|
||||
if((status = ngc_read_real_value(block, &char_counter, &value)) != Status_OK)
|
||||
FAIL(status); // [Expected parameter value]
|
||||
|
||||
if(ngc_param_count < NGC_N_ASSIGN_PARAMETERS_PER_BLOCK && ngc_param_is_rw((ngc_param_id_t)param)) {
|
||||
ngc_params[ngc_param_count].id = (ngc_param_id_t)param;
|
||||
ngc_params[ngc_param_count++].value = value;
|
||||
} else
|
||||
FAIL(Status_BadNumberFormat); // [Expected parameter value]
|
||||
if((status = ngc_read_real_value(block, &char_counter, ¶m)) == Status_OK) {
|
||||
if(!ngc_param_is_rw((ngc_param_id_t)param))
|
||||
status = Status_GcodeValueOutOfRange; // [Parameter does not exist or is read only]
|
||||
else if(block[char_counter++] != '=')
|
||||
status = Status_BadNumberFormat; // [Expected equal sign]
|
||||
else if((status = ngc_read_real_value(block, &char_counter, &value)) == Status_OK) {
|
||||
if(ngc_param_count < NGC_N_ASSIGN_PARAMETERS_PER_BLOCK) {
|
||||
ngc_params[ngc_param_count].id = (ngc_param_id_t)param;
|
||||
ngc_params[ngc_param_count++].value = value;
|
||||
} else
|
||||
FAIL(Status_BadNumberFormat); // [Too many parameters in block]
|
||||
} // else: [Expected parameter value]
|
||||
} // else: [Expected parameter number]
|
||||
}
|
||||
|
||||
if(status != Status_OK)
|
||||
FAIL(status);
|
||||
|
||||
continue;
|
||||
} else if(letter == 'O') {
|
||||
|
||||
gc_block.words.n = Off; // Hack to allow line number with O word
|
||||
|
||||
if(block[char_counter] == '[') {
|
||||
int32_t value;
|
||||
if((status = ngc_read_integer_value(block, &char_counter, &value)) == Status_OK) {
|
||||
gc_block.words.o = On;
|
||||
gc_block.values.o = (uint32_t)value;
|
||||
char_counter++;
|
||||
} else
|
||||
FAIL(status);
|
||||
} else if(block[char_counter] == '<') {
|
||||
/* char o_label[NGC_MAX_PARAM_LENGTH + 1];
|
||||
if((status = ngc_read_name(block, &char_counter, o_label)) != Status_OK)
|
||||
FAIL(status);
|
||||
gc_block.words.o = On;
|
||||
gc_block.values.o = 0xFFFFFFFE;
|
||||
continue;*/
|
||||
FAIL(Status_GcodeUnsupportedCommand); // [For now...]
|
||||
}
|
||||
}
|
||||
|
||||
if((gc_block.words.mask & o_label.mask) && (gc_block.words.mask & ~o_label.mask) == 0) {
|
||||
|
||||
2
grbl.h
2
grbl.h
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20241014
|
||||
#define GRBL_BUILD 20241016
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ static bool limits_pull_off (axes_signals_t axis, float distance)
|
||||
|
||||
plan_data.feed_rate = settings.homing.seek_rate * sqrtf(n_axis); // Adjust so individual axes all move at pull-off rate.
|
||||
plan_data.condition.coolant = gc_state.modal.coolant;
|
||||
memcpy(&plan_data.spindle, &gc_state.spindle, sizeof(spindle_t));
|
||||
|
||||
#ifdef KINEMATICS_API
|
||||
coord_data_t k_target;
|
||||
@@ -275,13 +274,12 @@ static bool homing_cycle (axes_signals_t cycle, axes_signals_t auto_square)
|
||||
plan_line_data_t plan_data;
|
||||
rt_exec_t rt_exec, rt_exec_states = EXEC_SAFETY_DOOR|EXEC_RESET|EXEC_CYCLE_COMPLETE;
|
||||
|
||||
// Initialize plan data struct for homing motion.
|
||||
|
||||
plan_data_init(&plan_data);
|
||||
plan_data.condition.system_motion = On;
|
||||
plan_data.condition.no_feed_override = On;
|
||||
plan_data.line_number = DEFAULT_HOMING_CYCLE_LINE_NUMBER;
|
||||
|
||||
// Initialize plan data struct for homing motion.
|
||||
memcpy(&plan_data.spindle, &gc_state.spindle, sizeof(spindle_t));
|
||||
plan_data.condition.coolant = gc_state.modal.coolant;
|
||||
|
||||
uint_fast8_t idx = N_AXIS;
|
||||
|
||||
112
ngc_expr.c
112
ngc_expr.c
@@ -571,6 +571,39 @@ static status_code_t read_operation_unary (char *line, uint_fast8_t *pos, ngc_un
|
||||
return status;
|
||||
}
|
||||
|
||||
/*! \brief Reads the name of a parameter out of the line
|
||||
starting at the index given by the pos offset.
|
||||
|
||||
\param line pointer to RS274/NGC code (block).
|
||||
\param pos offset into line where expression starts.
|
||||
\param buffer pointer to a character buffer for the name.
|
||||
\returns #Status_OK enum value if processed without error, appropriate \ref status_code_t enum value if not.
|
||||
*/
|
||||
status_code_t ngc_read_name (char *line, uint_fast8_t *pos, char *buffer)
|
||||
{
|
||||
char *s;
|
||||
uint_fast8_t len = 0;
|
||||
status_code_t status = Status_BadNumberFormat;
|
||||
|
||||
if(*(s = line + (*pos)++) == '<') {
|
||||
|
||||
s++;
|
||||
|
||||
while(*s && *s != '>' && len <= NGC_MAX_PARAM_LENGTH) {
|
||||
*buffer++ = *s++;
|
||||
(*pos)++;
|
||||
len++;
|
||||
}
|
||||
|
||||
if((status = *s == '>' ? Status_OK : Status_FlowControlSyntaxError) == Status_OK) {
|
||||
*buffer = '\0';
|
||||
(*pos)++;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*! \brief Reads the value out of a parameter of the line, starting at the
|
||||
index given by the pos offset.
|
||||
|
||||
@@ -593,6 +626,7 @@ sequentially, the value of #2 would be 10 after the line was executed.
|
||||
*/
|
||||
status_code_t ngc_read_parameter (char *line, uint_fast8_t *pos, float *value, bool check)
|
||||
{
|
||||
int32_t param;
|
||||
status_code_t status = Status_BadNumberFormat;
|
||||
|
||||
if(*(line + *pos) == '#') {
|
||||
@@ -601,34 +635,18 @@ status_code_t ngc_read_parameter (char *line, uint_fast8_t *pos, float *value, b
|
||||
|
||||
if(*(line + *pos) == '<') {
|
||||
|
||||
(*pos)++;
|
||||
char *param = line + *pos, *arg = line + *pos;
|
||||
char name[NGC_MAX_PARAM_LENGTH + 1];
|
||||
|
||||
while(*arg && *arg != '>')
|
||||
arg++;
|
||||
|
||||
*pos += arg - param + 1;
|
||||
|
||||
if(*arg == '>') {
|
||||
*arg = '\0';
|
||||
if(ngc_named_param_get(param, value))
|
||||
status = Status_OK;
|
||||
*arg = '>';
|
||||
if((status = ngc_read_name(line, pos, name)) == Status_OK) {
|
||||
if(!ngc_named_param_get(name, value))
|
||||
status = Status_BadNumberFormat;
|
||||
}
|
||||
} else if((status = ngc_read_integer_value(line, pos, ¶m)) == Status_OK) {
|
||||
|
||||
} else if((status = ngc_read_real_value(line, pos, value)) == Status_OK) {
|
||||
|
||||
uint32_t param = (uint32_t)floorf(*value);
|
||||
|
||||
if((*value - (float)param) > 0.9999f) {
|
||||
param = (uint32_t)ceilf(*value);
|
||||
} else if((*value - (float)param) > 0.0001f)
|
||||
status = Status_BadNumberFormat; // not integer
|
||||
|
||||
if(check && !ngc_param_exists((ngc_param_id_t)param))
|
||||
if(param < 0 || (check && !ngc_param_exists((ngc_param_id_t)param)))
|
||||
status = Status_GcodeValueOutOfRange;
|
||||
else if(!ngc_param_get((ngc_param_id_t)param, value))
|
||||
status = Status_GcodeValueOutOfRange;
|
||||
else if(ngc_param_get((ngc_param_id_t)param, value))
|
||||
status = Status_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -761,6 +779,52 @@ status_code_t ngc_read_real_value (char *line, uint_fast8_t *pos, float *value)
|
||||
return status;
|
||||
}
|
||||
|
||||
/*! \brief Reads explicit unsigned (positive) integer out of the line,
|
||||
starting at the index given by the pos offset. It expects to find one
|
||||
or more digits. Any character other than a digit terminates reading
|
||||
the integer. Note that if the first character is a sign (+ or -),
|
||||
an error will be reported (since a sign is not a digit).
|
||||
|
||||
\param line pointer to RS274/NGC code (block).
|
||||
\param pos offset into line where expression starts.
|
||||
\param value pointer to integer where result is to be stored.
|
||||
\returns #Status_OK enum value if processed without error, appropriate \ref status_code_t enum value if not.
|
||||
*/
|
||||
status_code_t ngc_read_integer_unsigned (char *line, uint_fast8_t *pos, uint32_t *value)
|
||||
{
|
||||
return line[*pos] == '+' ? Status_GcodeCommandValueNotInteger : read_uint(line, pos, value);
|
||||
}
|
||||
|
||||
/*! \brief Reads an integer (positive, negative or zero) out of the line,
|
||||
starting at the index given by the pos offset. The value being
|
||||
read may be written with a decimal point or it may be an expression
|
||||
involving non-integers, as long as the result comes out within 0.0001
|
||||
of an integer.
|
||||
|
||||
This proceeds by calling read_real_value and checking that it is
|
||||
close to an integer, then returning the integer it is close to.
|
||||
|
||||
\param line pointer to RS274/NGC code (block).
|
||||
\param pos offset into line where expression starts.
|
||||
\param value pointer to integer where result is to be stored.
|
||||
\returns #Status_OK enum value if processed without error, appropriate \ref status_code_t enum value if not.
|
||||
*/
|
||||
status_code_t ngc_read_integer_value (char *line, uint_fast8_t *pos, int32_t *value)
|
||||
{
|
||||
float fvalue;
|
||||
status_code_t status;
|
||||
|
||||
if((status = ngc_read_real_value(line, pos, &fvalue)) == Status_OK) {
|
||||
*value = (int32_t)floorf(fvalue);
|
||||
if((fvalue - (float)*value) > 0.9999f) {
|
||||
*value = (uint32_t)ceilf(fvalue);
|
||||
} else if((fvalue - (float)*value) > 0.0001f)
|
||||
status = Status_GcodeCommandValueNotInteger; // not integer
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*! \brief Evaluate expression and set result if successful.
|
||||
|
||||
\param line pointer to RS274/NGC code (block).
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
#ifndef _NGC_EXPR_H_
|
||||
#define _NGC_EXPR_H_
|
||||
|
||||
status_code_t ngc_eval_expression (char *line, uint_fast8_t *pos, float *value);
|
||||
status_code_t ngc_read_name (char *line, uint_fast8_t *pos, char *buffer);
|
||||
status_code_t ngc_read_real_value (char *line, uint_fast8_t *pos, float *value);
|
||||
status_code_t ngc_read_integer_value(char *line, uint_fast8_t *pos, int32_t *value);
|
||||
status_code_t ngc_read_integer_unsigned (char *line, uint_fast8_t *pos, uint32_t *value);
|
||||
status_code_t ngc_read_parameter (char *line, uint_fast8_t *pos, float *value, bool check);
|
||||
status_code_t ngc_eval_expression (char *line, uint_fast8_t *pos, float *value);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,9 +41,6 @@
|
||||
#ifndef NGC_MAX_CALL_LEVEL
|
||||
#define NGC_MAX_CALL_LEVEL 10
|
||||
#endif
|
||||
#ifndef NGC_MAX_PARAM_LENGTH
|
||||
#define NGC_MAX_PARAM_LENGTH 20
|
||||
#endif
|
||||
|
||||
typedef float (*ngc_param_get_ptr)(ngc_param_id_t id);
|
||||
typedef float (*ngc_named_param_get_ptr)(void);
|
||||
@@ -622,7 +619,7 @@ static char *ngc_name_tolower (char *s)
|
||||
uint_fast8_t len = 0;
|
||||
char c, *s1 = s, *s2 = name;
|
||||
|
||||
while((c = *s1++) && len < NGC_MAX_PARAM_LENGTH) {
|
||||
while((c = *s1++) && len <= NGC_MAX_PARAM_LENGTH) {
|
||||
if(c > ' ') {
|
||||
*s2++ = LCAPS(c);
|
||||
len++;
|
||||
@@ -679,7 +676,7 @@ bool ngc_named_param_exists (char *name)
|
||||
} while(idx && !ok);
|
||||
|
||||
// If not predefined attempt to find it.
|
||||
if(!ok && rw_global_params && strlen(name) < NGC_MAX_PARAM_LENGTH) {
|
||||
if(!ok && rw_global_params && strlen(name) <= NGC_MAX_PARAM_LENGTH) {
|
||||
|
||||
void *context = *name == '_' ? NULL : call_context;
|
||||
ngc_named_rw_param_t *rw_param = rw_global_params;
|
||||
@@ -712,7 +709,7 @@ bool ngc_named_param_set (char *name, float value)
|
||||
} while(idx && !ok);
|
||||
|
||||
// If not predefined attempt to set it.
|
||||
if(!ok && (ok = strlen(name) < NGC_MAX_PARAM_LENGTH)) {
|
||||
if(!ok && (ok = strlen(name) <= NGC_MAX_PARAM_LENGTH)) {
|
||||
|
||||
void *context = *name == '_' ? NULL : call_context;
|
||||
ngc_named_rw_param_t *rw_param = rw_global_params, *rw_param_last = rw_global_params;
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
|
||||
#include "gcode.h"
|
||||
|
||||
#ifndef NGC_MAX_PARAM_LENGTH
|
||||
#define NGC_MAX_PARAM_LENGTH 20
|
||||
#endif
|
||||
|
||||
typedef uint16_t ngc_param_id_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Reference in New Issue
Block a user