mirror of
https://github.com/grblHAL/core.git
synced 2026-03-26 17:16:39 +08:00
"hardened" task deregistration code and changed signature of setting available and ioport_find_free() calls.
Some low-level ioport improvements, added definition for virtual pins/ports. Deprecated direct access to number of the different ioport ports in hal.port struct, use ioports_unclaimed() instead.
This commit is contained in:
26
changelog.md
26
changelog.md
@@ -1,5 +1,31 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20250114">Build 20250114
|
||||
|
||||
Core:
|
||||
|
||||
* "hardened" task deregistration code and changed signature of setting available and `ioport_find_free()` calls.
|
||||
|
||||
* Some low-level ioport improvements, added definition for virtual pins/ports.
|
||||
Deprecated direct access to number of the different ioport ports in `hal.port` struct, use `ioports_unclaimed()` instead.
|
||||
|
||||
Drivers:
|
||||
|
||||
* ESP32: some fixes for Trinamic SPI comms.
|
||||
|
||||
Plugins:
|
||||
|
||||
* Many: updated for setting call signature changes and to take advandage of latest core functionality.
|
||||
Plugins claiming auxiliary ports changed to use `-1` for port number settings that are to be ignored/not claimed.
|
||||
|
||||
* Plasma: refactored, uses new task functionality for processing and has improved settings handling. Virtual auxiliary ports disabled for now.
|
||||
|
||||
Templates:
|
||||
|
||||
* Many: updated to take advandage of latest core functionality etc. Removed some superfluous ones.
|
||||
|
||||
---
|
||||
|
||||
<a name="20250111">Build 20250111
|
||||
|
||||
Core:
|
||||
|
||||
@@ -213,6 +213,7 @@ typedef enum {
|
||||
Input_QEI_B,
|
||||
Input_QEI_Select,
|
||||
Input_QEI_Index,
|
||||
Virtual_Pin,
|
||||
// Single pin bidirectional peripherals
|
||||
Bidirectional_MotorUARTX,
|
||||
Bidirectional = Bidirectional_MotorUARTX,
|
||||
@@ -421,6 +422,7 @@ PROGMEM static const pin_name_t pin_names[] = {
|
||||
{ .function = Input_QEI_B, .name = "QEI B" },
|
||||
{ .function = Input_QEI_Select, .name = "QEI select" },
|
||||
{ .function = Input_QEI_Index, .name = "QEI index" },
|
||||
{ .function = Virtual_Pin, .name = "Virtual" },
|
||||
{ .function = Bidirectional_MotorUARTX, .name = "UART X" },
|
||||
{ .function = Bidirectional_MotorUARTY, .name = "UART Y" },
|
||||
{ .function = Bidirectional_MotorUARTZ, .name = "UART Z" },
|
||||
@@ -458,6 +460,7 @@ typedef enum {
|
||||
PinGroup_CAN,
|
||||
PinGroup_LED,
|
||||
PinGroup_Home,
|
||||
PinGroup_Virtual,
|
||||
// Interrupt capable pins that may have debounce processing enabled
|
||||
PinGroup_Control = (1<<8),
|
||||
PinGroup_Limit = (1<<9),
|
||||
|
||||
3
errors.c
3
errors.c
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2017-2025 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -87,6 +87,7 @@ PROGMEM static const status_detail_t status_detail[] = {
|
||||
#if COMPATIBILITY_LEVEL <= 1
|
||||
{ Status_GCodeCoordSystemLocked, "Coordinate system is locked." },
|
||||
#endif
|
||||
{ Status_UnexpectedDemarcation, "Unexpected file demarcation." },
|
||||
#if NGC_EXPRESSIONS_ENABLE
|
||||
{ Status_ExpressionUknownOp, "Unknown operation found in expression." },
|
||||
{ Status_ExpressionDivideByZero, "Divide by zero in expression attempted." },
|
||||
|
||||
3
errors.h
3
errors.h
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2017-2025 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -86,6 +86,7 @@ typedef enum {
|
||||
Status_GcodeInvalidRetractPosition = 54,
|
||||
Status_IllegalHomingConfiguration = 55,
|
||||
Status_GCodeCoordSystemLocked = 56,
|
||||
Status_UnexpectedDemarcation = 57,
|
||||
|
||||
// Some error codes as defined in bdring's ESP32 port
|
||||
Status_SDMountError = 60,
|
||||
|
||||
44
gcode.c
44
gcode.c
@@ -798,34 +798,42 @@ status_code_t gc_execute_block (char *block)
|
||||
tool_id_t t;
|
||||
} single_meaning_value = {0};
|
||||
|
||||
block = gc_normalize_block(block, &status, &message);
|
||||
bool fs_changed;
|
||||
if((fs_changed = gc_state.file_stream ? hal.stream.file == NULL : hal.stream.file != NULL))
|
||||
gc_state.file_stream = hal.stream.file != NULL;
|
||||
|
||||
block = gc_normalize_block(block, &status, &message);
|
||||
if(status != Status_OK)
|
||||
FAIL(status);
|
||||
|
||||
// Determine if the line is a program start/end marker.
|
||||
if(block[0] == CMD_PROGRAM_DEMARCATION && block[1] == '\0') {
|
||||
|
||||
block[0] = '\0';
|
||||
|
||||
if(gc_state.file_stream) {
|
||||
|
||||
if(!fs_changed && !gc_state.file_run)
|
||||
status = Status_UnexpectedDemarcation;
|
||||
else if(!(gc_state.file_run = fs_changed)) {
|
||||
protocol_buffer_synchronize(); // Empty planner buffer
|
||||
grbl.report.feedback_message(Message_ProgramEnd);
|
||||
if(grbl.on_program_completed)
|
||||
grbl.on_program_completed(ProgramFlow_EndPercent, state_get() == STATE_CHECK_MODE);
|
||||
}
|
||||
} else
|
||||
gc_state.file_run = !gc_state.file_run;
|
||||
|
||||
if(status == Status_OK && grbl.on_file_demarcate)
|
||||
grbl.on_file_demarcate(gc_state.file_run);
|
||||
}
|
||||
|
||||
if(block[0] == '\0') {
|
||||
if(message)
|
||||
gc_output_message(message);
|
||||
return status;
|
||||
}
|
||||
|
||||
// Determine if the line is a program start/end marker.
|
||||
// Old comment from protocol.c:
|
||||
// NOTE: This maybe installed to tell grblHAL when a program is running vs manual input,
|
||||
// where, during a program, the system auto-cycle start will continue to execute
|
||||
// everything until the next '%' sign. This will help fix resuming issues with certain
|
||||
// functions that empty the planner buffer to execute its task on-time.
|
||||
if (block[0] == CMD_PROGRAM_DEMARCATION && block[1] == '\0') {
|
||||
gc_state.file_run = !gc_state.file_run;
|
||||
if(message)
|
||||
gc_output_message(message);
|
||||
|
||||
if(grbl.on_file_demarcate)
|
||||
grbl.on_file_demarcate(gc_state.file_run);
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------------------
|
||||
STEP 1: Initialize parser block struct and copy current g-code state modes. The parser
|
||||
updates these modes and commands as the block line is parsed and will only be used and
|
||||
|
||||
6
gcode.h
6
gcode.h
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2017-2025 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -207,7 +207,8 @@ typedef enum {
|
||||
ProgramFlow_CompletedM2 = 2, //!< 2 - M2
|
||||
ProgramFlow_CompletedM30 = 30, //!< 30 - M30
|
||||
ProgramFlow_CompletedM60 = 60, //!< 60 - M60
|
||||
ProgramFlow_Return = 99 //!< 99 - M99
|
||||
ProgramFlow_Return = 99, //!< 99 - M99
|
||||
ProgramFlow_EndPercent = 255 //!< 255 - %
|
||||
} program_flow_t;
|
||||
|
||||
// Modal Group M9: Override control
|
||||
@@ -625,6 +626,7 @@ typedef struct {
|
||||
uint32_t g43_pending; //!< Tool offset to be selected on next M6, for macro ATC
|
||||
#endif
|
||||
bool file_run; //!< Tracks % command
|
||||
bool file_stream; //!< Tracks streaming from file
|
||||
bool is_laser_ppi_mode;
|
||||
bool is_rpm_rate_adjusted;
|
||||
bool tool_change;
|
||||
|
||||
2
grbl.h
2
grbl.h
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20250111
|
||||
#define GRBL_BUILD 20250114
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
12
grbllib.c
12
grbllib.c
@@ -420,7 +420,7 @@ int grbl_enter (void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline core_task_t *task_alloc (void)
|
||||
__attribute__((always_inline)) static inline core_task_t *task_alloc (void)
|
||||
{
|
||||
core_task_t *task = NULL;
|
||||
uint_fast8_t idx = CORE_TASK_POOL_SIZE;
|
||||
@@ -436,7 +436,7 @@ static inline core_task_t *task_alloc (void)
|
||||
return task;
|
||||
}
|
||||
|
||||
static inline void task_free (core_task_t *task)
|
||||
__attribute__((always_inline)) static inline void task_free (core_task_t *task)
|
||||
{
|
||||
task->fn = NULL;
|
||||
if(last_freed == NULL)
|
||||
@@ -525,6 +525,8 @@ void task_delete (foreground_task_ptr fn, void *data)
|
||||
{
|
||||
core_task_t *task, *prev = NULL;
|
||||
|
||||
hal.irq_disable();
|
||||
|
||||
if((task = next_task)) do {
|
||||
if(fn == task->fn && data == task->data) {
|
||||
if(prev)
|
||||
@@ -536,6 +538,8 @@ void task_delete (foreground_task_ptr fn, void *data)
|
||||
}
|
||||
prev = task;
|
||||
} while((task = task->next));
|
||||
|
||||
hal.irq_enable();
|
||||
}
|
||||
|
||||
ISR_CODE bool ISR_FUNC(task_add_systick)(foreground_task_ptr fn, void *data)
|
||||
@@ -569,6 +573,8 @@ void task_delete_systick (foreground_task_ptr fn, void *data)
|
||||
{
|
||||
core_task_t *task, *prev = NULL;
|
||||
|
||||
hal.irq_disable();
|
||||
|
||||
if((task = systick_task)) do {
|
||||
if(fn == task->fn && data == task->data) {
|
||||
if(prev)
|
||||
@@ -580,6 +586,8 @@ void task_delete_systick (foreground_task_ptr fn, void *data)
|
||||
}
|
||||
prev = task;
|
||||
} while((task = task->next));
|
||||
|
||||
hal.irq_enable();
|
||||
}
|
||||
|
||||
/*! \brief Enqueue a function to be called once by the foreground process.
|
||||
|
||||
105
ioports.c
105
ioports.c
@@ -96,39 +96,57 @@ uint8_t ioports_available (io_port_type_t type, io_port_direction_t dir)
|
||||
return ports;
|
||||
}
|
||||
|
||||
/*! \brief Get number of unclaimed digital or analog ports available.
|
||||
\param type as an \a #io_port_type_t enum value.
|
||||
\param dir as an \a #io_port_direction_t enum value.
|
||||
\returns number of ports available.
|
||||
*/
|
||||
uint8_t ioports_unclaimed (io_port_type_t type, io_port_direction_t dir)
|
||||
{
|
||||
xbar_t *port;
|
||||
uint8_t idx = 0, n_ports = 0;
|
||||
|
||||
if(hal.port.get_pin_info) do {
|
||||
if((port = hal.port.get_pin_info(type, dir, idx++)) && !port->mode.claimed)
|
||||
n_ports++;
|
||||
} while(port);
|
||||
|
||||
return n_ports;
|
||||
}
|
||||
|
||||
static struct ff_data {
|
||||
uint8_t port;
|
||||
const char *description;
|
||||
} ff_data;
|
||||
|
||||
static bool match_port (xbar_t *properties, uint8_t port, void *data)
|
||||
{
|
||||
if(((struct ff_data *)data)->description && (!properties->description || strcmp(properties->description, ((struct ff_data *)data)->description)))
|
||||
return false;
|
||||
|
||||
((struct ff_data *)data)->port = port;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*! \brief find first free or claimed digital or analog port.
|
||||
\param type as an \a #io_port_type_t enum value.
|
||||
\param dir as an \a #io_port_direction_t enum value.
|
||||
\param description pointer to a \a char constant for the pin description of a previousely claimed port or NULL if searching for the first free port.
|
||||
\returns the port number if successful, 255 if not.
|
||||
\returns the port number if successful, 0xFF (255) if not.
|
||||
*/
|
||||
uint8_t ioport_find_free (io_port_type_t type, io_port_direction_t dir, const char *description)
|
||||
uint8_t ioport_find_free (io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, const char *description)
|
||||
{
|
||||
uint8_t port;
|
||||
bool found = false;
|
||||
xbar_t *pin;
|
||||
ff_data.port = 0xFF;
|
||||
ff_data.description = (description && *description) ? description : NULL;
|
||||
|
||||
if(description) {
|
||||
port = ioports_available(type, dir);
|
||||
do {
|
||||
if((pin = hal.port.get_pin_info(type, dir, --port))) {
|
||||
if((found = pin->description && !strcmp(pin->description, description)))
|
||||
port = pin->id;
|
||||
}
|
||||
} while(port && !found);
|
||||
// TODO: pass modified filter with .claimable off when looking for description match?
|
||||
if(ff_data.description && !ioports_enumerate(type, dir, (pin_cap_t){}, match_port, (void *)&ff_data)) {
|
||||
ff_data.description = NULL;
|
||||
ioports_enumerate(type, dir, filter, match_port, (void *)&ff_data);
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
port = ioports_available(type, dir);
|
||||
do {
|
||||
if((pin = hal.port.get_pin_info(type, dir, --port))) {
|
||||
if((found = !pin->mode.claimed))
|
||||
port = pin->id;
|
||||
}
|
||||
} while(port && !found);
|
||||
}
|
||||
|
||||
return found ? port : 255;
|
||||
return ff_data.port;
|
||||
}
|
||||
|
||||
/*! \brief Return information about a digital or analog port.
|
||||
@@ -170,15 +188,24 @@ bool ioport_claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port,
|
||||
|
||||
ok = (portinfo = ioport_get_info(type, dir, *port)) && !portinfo->mode.claimed && hal.port.claim(type, dir, port, description);
|
||||
|
||||
} else if((ok = ioports_available(type, dir) > 0)) {
|
||||
} else {
|
||||
|
||||
if(type == Port_Digital)
|
||||
*port = dir == Port_Input ? --hal.port.num_digital_in : --hal.port.num_digital_out;
|
||||
else
|
||||
*port = dir == Port_Input ? --hal.port.num_analog_in : --hal.port.num_analog_out;
|
||||
uint_fast8_t count;
|
||||
get_pin_info_ptr get_pin_info = hal.port.get_pin_info;
|
||||
|
||||
if(hal.port.set_pin_description)
|
||||
hal.port.set_pin_description(type, dir, *port, description);
|
||||
hal.port.get_pin_info = NULL; // Force count of unclaimed ports only.
|
||||
|
||||
if((ok = (count = ioports_available(type, dir)) > 0 && *port == count - 1 )) {
|
||||
if(type == Port_Digital)
|
||||
*port = dir == Port_Input ? --hal.port.num_digital_in : --hal.port.num_digital_out;
|
||||
else
|
||||
*port = dir == Port_Input ? --hal.port.num_analog_in : --hal.port.num_analog_out;
|
||||
|
||||
if(hal.port.set_pin_description)
|
||||
hal.port.set_pin_description(type, dir, *port, description);
|
||||
}
|
||||
|
||||
hal.port.get_pin_info = get_pin_info;
|
||||
}
|
||||
|
||||
return ok;
|
||||
@@ -296,39 +323,41 @@ bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uin
|
||||
if(type == Port_Digital) {
|
||||
|
||||
cfg = &digital;
|
||||
digital_in = digital_out = -1;
|
||||
|
||||
if(n_in) {
|
||||
ports->in.n_start = hal.port.num_digital_in;
|
||||
ports->in.n_start = ioports_available(Port_Digital, Port_Input);
|
||||
hal.port.num_digital_in += (ports->in.n_ports = n_in);
|
||||
ports->in.map = malloc(ports->in.n_ports * sizeof(ports->in.n_ports));
|
||||
digital.in.ports = &ports->in;
|
||||
digital_in = -1;
|
||||
}
|
||||
|
||||
if(n_out) {
|
||||
ports->out.n_start = hal.port.num_digital_out;
|
||||
ports->out.n_start = ioports_available(Port_Digital, Port_Output);
|
||||
hal.port.num_digital_out += (ports->out.n_ports = n_out);
|
||||
ports->out.map = malloc(ports->out.n_ports * sizeof(ports->out.n_ports));
|
||||
digital.out.ports = &ports->out;
|
||||
digital_out = -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
cfg = &analog;
|
||||
analog_in = analog_out = -1;
|
||||
|
||||
if(n_in) {
|
||||
ports->in.n_start = hal.port.num_analog_in;
|
||||
ports->in.n_start = ioports_available(Port_Analog, Port_Input);
|
||||
hal.port.num_analog_in += (ports->in.n_ports = n_in);
|
||||
ports->in.map = malloc(ports->in.n_ports * sizeof(ports->in.n_ports));
|
||||
analog.in.ports = &ports->in;
|
||||
analog_in = -1;
|
||||
}
|
||||
|
||||
if(n_out) {
|
||||
ports->out.n_start = hal.port.num_analog_out;
|
||||
ports->out.n_start = ioports_available(Port_Analog, Port_Output);
|
||||
hal.port.num_analog_out += (ports->out.n_ports = n_out);
|
||||
ports->out.map = malloc(ports->out.n_ports * sizeof(ports->out.n_ports));
|
||||
analog.out.ports = &ports->out;
|
||||
analog_out = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,7 +525,7 @@ void ioport_save_output_settings (xbar_t *xbar, gpio_out_config_t *config)
|
||||
settings_write_global();
|
||||
}
|
||||
|
||||
static bool is_setting_available (const setting_detail_t *setting)
|
||||
static bool is_setting_available (const setting_detail_t *setting, uint_fast16_t offset)
|
||||
{
|
||||
bool available = false;
|
||||
|
||||
|
||||
11
ioports.h
11
ioports.h
@@ -109,10 +109,10 @@ typedef bool (*ioports_enumerate_callback_ptr)(xbar_t *properties, uint8_t port,
|
||||
|
||||
//! Properties and handlers for auxiliary digital and analog I/O.
|
||||
typedef struct {
|
||||
uint8_t num_digital_in; //!< Number of digital inputs available.
|
||||
uint8_t num_digital_out; //!< Number of digital outputs available.
|
||||
uint8_t num_analog_in; //!< Number of analog inputs available.
|
||||
uint8_t num_analog_out; //!< Number of analog outputs available.
|
||||
uint8_t num_digital_in; //!< Deprecated, use ioports_unclaimed() to get count.
|
||||
uint8_t num_digital_out; //!< Deprecated, use ioports_unclaimed() to get count.
|
||||
uint8_t num_analog_in; //!< Deprecated, use ioports_unclaimed() to get count.
|
||||
uint8_t num_analog_out; //!< Deprecated, use ioports_unclaimed() to get count.
|
||||
digital_out_ptr digital_out; //!< Optional handler for setting a digital output.
|
||||
analog_out_ptr analog_out; //!< Optional handler for setting an analog output.
|
||||
wait_on_input_ptr wait_on_input; //!< Optional handler for reading a digital or analog input.
|
||||
@@ -124,10 +124,11 @@ typedef struct {
|
||||
} io_port_t;
|
||||
|
||||
uint8_t ioports_available (io_port_type_t type, io_port_direction_t dir);
|
||||
uint8_t ioports_unclaimed (io_port_type_t type, io_port_direction_t dir);
|
||||
xbar_t *ioport_get_info (io_port_type_t type, io_port_direction_t dir, uint8_t port);
|
||||
bool ioport_claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port, const char *description);
|
||||
bool ioport_can_claim_explicit (void);
|
||||
uint8_t ioport_find_free (io_port_type_t type, io_port_direction_t dir, const char *description);
|
||||
uint8_t ioport_find_free (io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, const char *description);
|
||||
bool ioports_enumerate (io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, ioports_enumerate_callback_ptr callback, void *data);
|
||||
void ioport_assign_function (aux_ctrl_t *aux_ctrl, pin_function_t *function);
|
||||
void ioport_assign_out_function (aux_ctrl_out_t *aux_ctrl, pin_function_t *function);
|
||||
|
||||
23
report.c
23
report.c
@@ -502,7 +502,7 @@ void report_grbl_settings (bool all, void *data)
|
||||
for(idx = 0; idx < details->n_settings; idx++) {
|
||||
setting = &details->settings[idx];
|
||||
if(!is_hidden(setting) && (all || setting->type == Setting_IsLegacy || setting->type == Setting_IsLegacyFn) &&
|
||||
(setting->is_available == NULL ||setting->is_available(setting))) {
|
||||
(setting->is_available == NULL ||setting->is_available(setting, 0))) {
|
||||
*psetting++ = (setting_detail_t *)setting;
|
||||
n_settings++;
|
||||
}
|
||||
@@ -512,7 +512,7 @@ void report_grbl_settings (bool all, void *data)
|
||||
if(all && (details = details->next)) do {
|
||||
for(idx = 0; idx < details->n_settings; idx++) {
|
||||
setting = &details->settings[idx];
|
||||
if(!setting->flags.hidden && (setting->is_available == NULL || setting->is_available(setting))) {
|
||||
if(!setting->flags.hidden && (setting->is_available == NULL || setting->is_available(setting, 0))) {
|
||||
*psetting++ = (setting_detail_t *)setting;
|
||||
n_settings++;
|
||||
}
|
||||
@@ -1101,15 +1101,20 @@ void report_build_info (char *line, bool extended)
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
#endif
|
||||
|
||||
if(hal.port.num_digital_in + hal.port.num_digital_out + hal.port.num_analog_in + hal.port.num_analog_out > 0) {
|
||||
uint8_t digital_in = ioports_unclaimed(Port_Digital, Port_Input),
|
||||
digital_out = ioports_unclaimed(Port_Digital, Port_Output),
|
||||
analog_in = ioports_unclaimed(Port_Analog, Port_Input),
|
||||
analog_out = ioports_unclaimed(Port_Analog, Port_Output);
|
||||
|
||||
if(digital_in || digital_out || analog_in || analog_out) {
|
||||
hal.stream.write("[AUX IO:");
|
||||
hal.stream.write(uitoa(hal.port.num_digital_in));
|
||||
hal.stream.write(uitoa(digital_in));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(uitoa(hal.port.num_digital_out));
|
||||
hal.stream.write(uitoa(digital_out));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(uitoa(hal.port.num_analog_in));
|
||||
hal.stream.write(uitoa(analog_in));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(uitoa(hal.port.num_analog_out));
|
||||
hal.stream.write(uitoa(analog_out));
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
}
|
||||
|
||||
@@ -1844,7 +1849,7 @@ static bool print_sorted (const setting_detail_t *setting, uint_fast16_t offset,
|
||||
static bool print_unsorted (const setting_detail_t *setting, uint_fast16_t offset, void *args)
|
||||
{
|
||||
if(!(((report_args_t *)args)->group == setting->group && ((report_args_t *)args)->offset != offset) &&
|
||||
(setting->is_available == NULL ||setting->is_available(setting)))
|
||||
(setting->is_available == NULL ||setting->is_available(setting, 0)))
|
||||
report_settings_detail(((report_args_t *)args)->format, setting, offset);
|
||||
|
||||
return true;
|
||||
@@ -1881,7 +1886,7 @@ static status_code_t print_settings_details (settings_format_t format, setting_g
|
||||
do {
|
||||
for(idx = 0; idx < details->n_settings; idx++) {
|
||||
setting = &details->settings[idx];
|
||||
if(!is_hidden(setting) && (group == Group_All || setting->group == args.group) && (setting->is_available == NULL || setting->is_available(setting))) {
|
||||
if(!is_hidden(setting) && (group == Group_All || setting->group == args.group) && (setting->is_available == NULL || setting->is_available(setting, 0))) {
|
||||
*psetting++ = (setting_detail_t *)setting;
|
||||
n_settings++;
|
||||
}
|
||||
|
||||
20
settings.c
20
settings.c
@@ -1716,16 +1716,16 @@ float setting_get_float_value (const setting_detail_t *setting, uint_fast16_t of
|
||||
return value;
|
||||
}
|
||||
|
||||
static bool is_group_available (const setting_detail_t *setting)
|
||||
static bool is_group_available (const setting_detail_t *setting, uint_fast16_t offset)
|
||||
{
|
||||
return settings_is_group_available(setting->group);
|
||||
}
|
||||
|
||||
static bool is_setting_available (const setting_detail_t *setting)
|
||||
static bool is_setting_available (const setting_detail_t *setting, uint_fast16_t offset)
|
||||
{
|
||||
bool available = false;
|
||||
|
||||
if(setting) switch(normalize_id(setting->id)) {
|
||||
if(setting) switch(setting->id) {
|
||||
|
||||
case Setting_GangedDirInvertMask:
|
||||
available = hal.stepper.get_ganged && hal.stepper.get_ganged(false).mask != 0;
|
||||
@@ -1843,7 +1843,7 @@ static bool is_setting_available (const setting_detail_t *setting)
|
||||
break;
|
||||
|
||||
case Setting_CoolantOnDelay:
|
||||
available = !hal.signals_cap.safety_door_ajar && hal.coolant_cap.mask;
|
||||
available = hal.coolant_cap.mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1853,7 +1853,7 @@ static bool is_setting_available (const setting_detail_t *setting)
|
||||
return available;
|
||||
}
|
||||
|
||||
static bool toolsetter_available (const setting_detail_t *setting)
|
||||
static bool toolsetter_available (const setting_detail_t *setting, uint_fast16_t offset)
|
||||
{
|
||||
bool available = false;
|
||||
|
||||
@@ -1878,7 +1878,7 @@ static bool toolsetter_available (const setting_detail_t *setting)
|
||||
return available;
|
||||
}
|
||||
|
||||
static bool no_toolsetter_available (const setting_detail_t *setting)
|
||||
static bool no_toolsetter_available (const setting_detail_t *setting, uint_fast16_t offset)
|
||||
{
|
||||
#if COMPATIBILITY_LEVEL <= 1
|
||||
|
||||
@@ -2563,9 +2563,9 @@ void settings_restore (settings_restore_t restore)
|
||||
nvs_buffer_sync_physical();
|
||||
}
|
||||
|
||||
inline static bool is_available (const setting_detail_t *setting)
|
||||
inline static bool is_available (const setting_detail_t *setting, uint_fast16_t offset)
|
||||
{
|
||||
return setting->is_available == NULL || setting->is_available(setting);
|
||||
return setting->is_available == NULL || setting->is_available(setting, offset);
|
||||
}
|
||||
|
||||
bool settings_is_group_available (setting_group_t id)
|
||||
@@ -2611,7 +2611,7 @@ bool settings_is_group_available (setting_group_t id)
|
||||
do {
|
||||
if(details->settings) {
|
||||
for(idx = 0; idx < details->n_settings; idx++) {
|
||||
if(details->settings[idx].group == id && (available = is_available(&details->settings[idx])))
|
||||
if(details->settings[idx].group == id && (available = is_available(&details->settings[idx], 0)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2664,7 +2664,7 @@ const setting_detail_t *setting_get_details (setting_id_t id, setting_details_t
|
||||
|
||||
do {
|
||||
for(idx = 0; idx < details->n_settings; idx++) {
|
||||
if(details->settings[idx].id == id && is_available(&details->settings[idx])) {
|
||||
if(details->settings[idx].id == id && is_available(&details->settings[idx], offset)) {
|
||||
|
||||
if(details->settings[idx].group == Group_Axis0 && grbl.on_set_axis_setting_unit)
|
||||
set_axis_unit(&details->settings[idx], grbl.on_set_axis_setting_unit(details->settings[idx].id, offset));
|
||||
|
||||
@@ -985,7 +985,7 @@ typedef struct setting_detail {
|
||||
setting_type_t type;
|
||||
void *value;
|
||||
void *get_value;
|
||||
bool (*is_available)(const struct setting_detail *setting);
|
||||
bool (*is_available)(const struct setting_detail *setting, uint_fast16_t offset);
|
||||
setting_detail_flags_t flags;
|
||||
} setting_detail_t;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2024 Terje Io
|
||||
Copyright (c) 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
|
||||
@@ -120,6 +120,13 @@ static void onReportHandlersInit (void)
|
||||
grbl.report.status_message = trap_status_messages;
|
||||
}
|
||||
|
||||
void stream_set_type (stream_type_t type, vfs_file_t *file)
|
||||
{
|
||||
hal.stream.type = type;
|
||||
if(!(hal.stream.file = file))
|
||||
gc_state.file_stream = false;
|
||||
}
|
||||
|
||||
bool stream_is_file (void)
|
||||
{
|
||||
return hal.stream.type == StreamType_File;
|
||||
@@ -141,9 +148,8 @@ vfs_file_t *stream_redirect_read (char *filename, status_message_ptr status_hand
|
||||
rd_stream->eof_handler = eof_handler;
|
||||
rd_stream->status_handler = status_handler;
|
||||
rd_stream->next = NULL;
|
||||
hal.stream.file = file;
|
||||
hal.stream.type = StreamType_File;
|
||||
hal.stream.read = stream_read_file;
|
||||
stream_set_type(StreamType_File, file);
|
||||
if(streams == NULL)
|
||||
rd_streams = rd_stream;
|
||||
else do {
|
||||
@@ -181,9 +187,8 @@ void stream_redirect_close (vfs_file_t *file)
|
||||
if(stream) do {
|
||||
if(stream->file_new == file) {
|
||||
vfs_close(file);
|
||||
hal.stream.file = stream->file;
|
||||
hal.stream.read = stream->read;
|
||||
hal.stream.type = stream->type;
|
||||
stream_set_type(stream->type, stream->file);
|
||||
if(stream == rd_streams)
|
||||
rd_streams = stream->next;
|
||||
else
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2024 Terje Io
|
||||
Copyright (c) 2024-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
|
||||
@@ -26,4 +26,5 @@
|
||||
|
||||
bool stream_is_file (void);
|
||||
void stream_redirect_close (vfs_file_t *file);
|
||||
void stream_set_type (stream_type_t type, vfs_file_t *file);
|
||||
vfs_file_t *stream_redirect_read (char *filename, status_message_ptr status_handler, on_file_end_ptr eof_handler);
|
||||
|
||||
Reference in New Issue
Block a user