mirror of
https://github.com/grblHAL/core.git
synced 2026-02-06 00:52:35 +08:00
Internal changes that may affect developers, see the changelog for details.
This commit is contained in:
24
changelog.md
24
changelog.md
@@ -1,3 +1,25 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20240125"/>Build 20240125
|
||||
|
||||
Core, for developers:
|
||||
|
||||
* Simplified [regstration](http://svn.io-engineering.com/grblHAL/html/system_8c.html#a480cedc4c3840cfebb4d5fdce898dd3b) of additional system commands, deprecated original method.
|
||||
* Added [improved call](http://svn.io-engineering.com/grblHAL/html/protocol_8c.html#a869dff1f8d0b3965578eb3e6a94729c1) for registering single run tasks to be executed in the foreground, deprecated [original call](http://svn.io-engineering.com/grblHAL/html/protocol_8c.html#a78fa9a198df36192acec52d28d760a6c).
|
||||
* Moved VFS events from `grbl.*` to [vfs.*](http://svn.io-engineering.com/grblHAL/html/vfs_8h.html#ab87cc94daec156bea722f9f05d7eeb0c).
|
||||
|
||||
Drivers:
|
||||
|
||||
* Most: updated to use new method for registering single run tasks. Updated ioports code for improved core compliance.
|
||||
|
||||
* LPC176x: fix for [issue #44](https://github.com/grblHAL/LPC176x/issues/44), non-existing probe pin.
|
||||
|
||||
Plugins:
|
||||
|
||||
* Many: updated to use new method for registering single run tasks. Some bug fixes.
|
||||
|
||||
---
|
||||
|
||||
<a name="20240123"/>Build 20240123
|
||||
|
||||
Core:
|
||||
@@ -39,8 +61,6 @@ These are based on original work by @wakass and might be published by him if a P
|
||||
|
||||
---
|
||||
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20240118"/>Build 20240118
|
||||
|
||||
Core:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2020-2023 Terje Io
|
||||
Copyright (c) 2020-2024 Terje Io
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -116,8 +116,6 @@ typedef bool (*on_spindle_select_ptr)(spindle_ptrs_t *spindle);
|
||||
typedef void (*on_spindle_selected_ptr)(spindle_ptrs_t *spindle);
|
||||
typedef void (*on_gcode_message_ptr)(char *msg);
|
||||
typedef void (*on_rt_reports_added_ptr)(report_tracking_flags_t report);
|
||||
typedef void (*on_vfs_mount_ptr)(const char *path, const vfs_t *fs);
|
||||
typedef void (*on_vfs_unmount_ptr)(const char *path);
|
||||
typedef const char *(*on_set_axis_setting_unit_ptr)(setting_id_t setting_id, uint_fast8_t axis_idx);
|
||||
typedef status_code_t (*on_file_open_ptr)(const char *fname, vfs_file_t *handle, bool stream);
|
||||
typedef status_code_t (*on_unknown_sys_command_ptr)(sys_state_t state, char *line); // return Status_Unhandled.
|
||||
@@ -155,7 +153,7 @@ typedef struct {
|
||||
on_execute_realtime_ptr on_execute_delay;
|
||||
on_unknown_accessory_override_ptr on_unknown_accessory_override;
|
||||
on_report_options_ptr on_report_options;
|
||||
on_report_command_help_ptr on_report_command_help;
|
||||
on_report_command_help_ptr on_report_command_help; //!< Deprecated, use system_register_commands() to register new commands.
|
||||
on_rt_reports_added_ptr on_rt_reports_added;
|
||||
on_global_settings_restore_ptr on_global_settings_restore;
|
||||
on_setting_get_description_ptr on_setting_get_description;
|
||||
@@ -166,7 +164,7 @@ typedef struct {
|
||||
on_unknown_feedback_message_ptr on_unknown_feedback_message;
|
||||
on_unknown_realtime_cmd_ptr on_unknown_realtime_cmd;
|
||||
on_unknown_sys_command_ptr on_unknown_sys_command; //!< return Status_Unhandled if not handled.
|
||||
on_get_commands_ptr on_get_commands;
|
||||
on_get_commands_ptr on_get_commands; //!< Deprecated, use system_register_commands() to register new commands.
|
||||
on_user_command_ptr on_user_command;
|
||||
on_stream_changed_ptr on_stream_changed;
|
||||
on_homing_rate_set_ptr on_homing_rate_set;
|
||||
@@ -185,8 +183,6 @@ typedef struct {
|
||||
on_spindle_select_ptr on_spindle_select; //!< Called before spindle is selected, hook in HAL overrides here
|
||||
on_spindle_selected_ptr on_spindle_selected; //!< Called when spindle is selected, do not change HAL pointers here!
|
||||
on_reset_ptr on_reset; //!< Called from interrupt context.
|
||||
on_vfs_mount_ptr on_vfs_mount; //!< Called when a file system is mounted.
|
||||
on_vfs_unmount_ptr on_vfs_unmount; //!< Called when a file system is unmounted.
|
||||
on_file_open_ptr on_file_open; //!< Called when a file is opened for streaming.
|
||||
// core entry points - set up by core before driver_init() is called.
|
||||
home_machine_ptr home_machine;
|
||||
|
||||
25
gcode.c
25
gcode.c
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2023 Terje Io
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -420,15 +420,18 @@ static status_code_t init_sync_motion (plan_line_data_t *pl_data, float pitch)
|
||||
}
|
||||
|
||||
// Output and free previously allocated message
|
||||
static void output_message (char *message)
|
||||
void gc_output_message (char *message)
|
||||
{
|
||||
if(grbl.on_gcode_message)
|
||||
grbl.on_gcode_message(message);
|
||||
if(message) {
|
||||
|
||||
if(*message)
|
||||
report_message(message, Message_Plain);
|
||||
if(grbl.on_gcode_message)
|
||||
grbl.on_gcode_message(message);
|
||||
|
||||
free(message);
|
||||
if(*message)
|
||||
report_message(message, Message_Plain);
|
||||
|
||||
free(message);
|
||||
}
|
||||
}
|
||||
|
||||
#if NGC_EXPRESSIONS_ENABLE
|
||||
@@ -747,7 +750,7 @@ status_code_t gc_execute_block (char *block)
|
||||
|
||||
if(block[0] == '\0') {
|
||||
if(message)
|
||||
output_message(message);
|
||||
gc_output_message(message);
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
@@ -760,7 +763,7 @@ status_code_t gc_execute_block (char *block)
|
||||
if (block[0] == CMD_PROGRAM_DEMARCATION && block[1] == '\0') {
|
||||
gc_state.file_run = !gc_state.file_run;
|
||||
if(message)
|
||||
output_message(message);
|
||||
gc_output_message(message);
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
@@ -3109,7 +3112,7 @@ status_code_t gc_execute_block (char *block)
|
||||
protocol_buffer_synchronize();
|
||||
|
||||
if(plan_data.message) {
|
||||
output_message(plan_data.message);
|
||||
gc_output_message(plan_data.message);
|
||||
plan_data.message = NULL;
|
||||
}
|
||||
|
||||
@@ -3535,7 +3538,7 @@ status_code_t gc_execute_block (char *block)
|
||||
}
|
||||
|
||||
if(plan_data.message)
|
||||
output_message(plan_data.message);
|
||||
gc_output_message(plan_data.message);
|
||||
|
||||
// [21. Program flow ]:
|
||||
// M0,M1,M2,M30,M60: Perform non-running program flow actions. During a program pause, the buffer may
|
||||
|
||||
2
grbl.h
2
grbl.h
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20240123
|
||||
#define GRBL_BUILD 20240125
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ static bool dummy_irq_claim (irq_type_t irq, uint_fast8_t id, irq_callback_ptr c
|
||||
return false;
|
||||
}
|
||||
|
||||
static void report_driver_error (sys_state_t state)
|
||||
static void report_driver_error (void *data)
|
||||
{
|
||||
char msg[40];
|
||||
|
||||
@@ -266,7 +266,7 @@ int grbl_enter (void)
|
||||
|
||||
if(driver.ok != 0xFF) {
|
||||
sys.alarm = Alarm_SelftestFailed;
|
||||
protocol_enqueue_rt_command(report_driver_error);
|
||||
protocol_enqueue_foreground_task(report_driver_error, NULL);
|
||||
}
|
||||
|
||||
hal.stepper.enable(settings.steppers.deenergize);
|
||||
|
||||
@@ -514,7 +514,7 @@ static void delta_limits_set_machine_positions (axes_signals_t cycle)
|
||||
*/
|
||||
}
|
||||
|
||||
static void delta_go_home (sys_state_t state)
|
||||
static void delta_go_home (void *data)
|
||||
{
|
||||
plan_line_data_t plan_data;
|
||||
|
||||
@@ -542,7 +542,7 @@ static void delta_homing_complete (bool success)
|
||||
: machine.home_z - settings.homing.pulloff;
|
||||
|
||||
if(machine.cfg.flags.home_to_cuboid_top)
|
||||
protocol_enqueue_rt_command(delta_go_home);
|
||||
protocol_enqueue_foreground_task(delta_go_home);
|
||||
}
|
||||
|
||||
if(on_homing_completed)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2023 Terje Io
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -212,11 +212,6 @@ static nvs_transfer_result_t memcpy_from_ram (uint8_t *destination, uint32_t sou
|
||||
return with_checksum ? (checksum == ram_get_byte(source) ? NVS_TransferResult_OK : NVS_TransferResult_Failed) : NVS_TransferResult_OK;
|
||||
}
|
||||
|
||||
static void nvs_warning (sys_state_t state)
|
||||
{
|
||||
report_message("Not enough heap for NVS buffer!", Message_Warning);
|
||||
}
|
||||
|
||||
// Try to allocate RAM from heap for buffer/emulation.
|
||||
bool nvs_buffer_alloc (void)
|
||||
{
|
||||
@@ -273,7 +268,7 @@ bool nvs_buffer_init (void)
|
||||
grbl.report.status_message(Status_SettingReadFail);
|
||||
}
|
||||
} else
|
||||
protocol_enqueue_rt_command(nvs_warning);
|
||||
protocol_enqueue_foreground_task(report_warning, "Not enough heap for NVS buffer!");
|
||||
|
||||
// Clear settings dirty flags
|
||||
memset(&settings_dirty, 0, sizeof(settings_dirty_t));
|
||||
|
||||
20
planner.c
20
planner.c
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2023 Terje Io
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
Copyright (c) 2011 Jens Geisler
|
||||
@@ -217,11 +217,6 @@ inline static void plan_reset_buffer (void)
|
||||
block_buffer_planned = block_buffer_tail; // = block_buffer_tail
|
||||
}
|
||||
|
||||
static void planner_warning (sys_state_t state)
|
||||
{
|
||||
report_message("Planner buffer size was reduced!", Message_Plain);
|
||||
}
|
||||
|
||||
uint_fast16_t plan_get_buffer_size (void)
|
||||
{
|
||||
return block_buffer_size;
|
||||
@@ -242,7 +237,7 @@ bool plan_reset (void)
|
||||
}
|
||||
|
||||
if(block_buffer_size != settings.planner_buffer_blocks)
|
||||
protocol_enqueue_rt_command(planner_warning);
|
||||
protocol_enqueue_foreground_task(report_plain, "Planner buffer size was reduced!");
|
||||
|
||||
if(block_buffer == NULL)
|
||||
return false;
|
||||
@@ -402,7 +397,6 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
|
||||
block->line_number = pl_data->line_number;
|
||||
block->output_commands = pl_data->output_commands;
|
||||
block->message = pl_data->message;
|
||||
pl_data->message = NULL;
|
||||
|
||||
// Copy position data based on type of motion being planned.
|
||||
memcpy(position_steps, block->condition.system_motion ? sys.position : pl.position, sizeof(position_steps));
|
||||
@@ -455,13 +449,15 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
|
||||
block->spindle.css->delta_rpm = block->spindle.css->target_rpm - block->spindle.rpm;
|
||||
}
|
||||
|
||||
// Bail if this is a zero-length block. Highly unlikely to occur.
|
||||
if (block->step_event_count == 0)
|
||||
return false;
|
||||
|
||||
pl_data->message = NULL; // Indicate message is already queued for display on execution
|
||||
pl_data->output_commands = NULL; // Indicate commands are already queued for execution
|
||||
|
||||
// Bail if this is a zero-length block. Highly unlikely to occur.
|
||||
if(block->step_event_count == 0) {
|
||||
plan_cleanup(block); // TODO: output message and execute output_commands?
|
||||
return false;
|
||||
}
|
||||
|
||||
#if N_AXIS > 3 && ROTARY_FIX
|
||||
|
||||
// NIST RS274 (2.1.2.5 A & 2.1.2.6) states that G94 linear motion with simultaneous angular motion
|
||||
|
||||
59
protocol.c
59
protocol.c
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2017-2023 Terje Io
|
||||
Copyright (c) 2017-2024 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -49,10 +49,18 @@ typedef union {
|
||||
};
|
||||
} line_flags_t;
|
||||
|
||||
typedef struct {
|
||||
void *data;
|
||||
union {
|
||||
foreground_task_ptr fn;
|
||||
on_execute_realtime_ptr fn_deprecated;
|
||||
};
|
||||
} delayed_task_t;
|
||||
|
||||
typedef struct {
|
||||
volatile uint_fast8_t head;
|
||||
volatile uint_fast8_t tail;
|
||||
on_execute_realtime_ptr fn[RT_QUEUE_SIZE];
|
||||
delayed_task_t task[RT_QUEUE_SIZE];
|
||||
} realtime_queue_t;
|
||||
|
||||
static uint_fast16_t char_counter = 0;
|
||||
@@ -190,7 +198,7 @@ bool protocol_main_loop (void)
|
||||
if(realtime_queue.head != realtime_queue.tail)
|
||||
system_set_exec_state_flag(EXEC_RT_COMMAND); // execute any boot up commands
|
||||
sys.cold_start = false;
|
||||
} else
|
||||
} else // TODO: if flushing entries from the queue that has allocated data associated then these will be orphaned/leaked.
|
||||
memset(&realtime_queue, 0, sizeof(realtime_queue_t));
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
@@ -1010,31 +1018,54 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(char c)
|
||||
return drop;
|
||||
}
|
||||
|
||||
// Enqueue a function to be called once by the
|
||||
// foreground process, typically enqueued from an interrupt handler.
|
||||
ISR_CODE bool ISR_FUNC(protocol_enqueue_rt_command)(on_execute_realtime_ptr fn)
|
||||
static const uint32_t dummy_data = 0;
|
||||
|
||||
|
||||
/*! \brief Enqueue a function to be called once by the foreground process.
|
||||
\param fn pointer to a \a foreground_task_ptr type of function.
|
||||
\param data pointer to data to be passed to the callee.
|
||||
\returns true if successful, false otherwise.
|
||||
*/
|
||||
bool protocol_enqueue_foreground_task (foreground_task_ptr fn, void *data)
|
||||
{
|
||||
bool ok;
|
||||
uint_fast8_t bptr = (realtime_queue.head + 1) & (RT_QUEUE_SIZE - 1); // Get next head pointer
|
||||
|
||||
if((ok = bptr != realtime_queue.tail)) { // If not buffer full
|
||||
realtime_queue.fn[realtime_queue.head] = fn; // add function pointer to buffer,
|
||||
realtime_queue.head = bptr; // update pointer and
|
||||
system_set_exec_state_flag(EXEC_RT_COMMAND); // flag it for execute
|
||||
if((ok = bptr != realtime_queue.tail)) { // If not buffer full
|
||||
realtime_queue.task[realtime_queue.head].data = data;
|
||||
realtime_queue.task[realtime_queue.head].fn = fn; // add function pointer to buffer,
|
||||
realtime_queue.head = bptr; // update pointer and
|
||||
system_set_exec_state_flag(EXEC_RT_COMMAND); // flag it for execute
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*! \brief Enqueue a function to be called once by the foreground process.
|
||||
\param fn pointer to a \a on_execute_realtime_ptr type of function.
|
||||
\returns true if successful, false otherwise.
|
||||
__NOTE:__ Deprecated, use protocol_enqueue_foreground_task instead.
|
||||
*/
|
||||
ISR_CODE bool ISR_FUNC(protocol_enqueue_rt_command)(on_execute_realtime_ptr fn)
|
||||
{
|
||||
return protocol_enqueue_foreground_task((foreground_task_ptr)fn, (void *)&dummy_data);
|
||||
}
|
||||
|
||||
// Execute enqueued functions.
|
||||
static void protocol_execute_rt_commands (void)
|
||||
{
|
||||
while(realtime_queue.tail != realtime_queue.head) {
|
||||
uint_fast8_t bptr = realtime_queue.tail;
|
||||
on_execute_realtime_ptr call;
|
||||
if((call = realtime_queue.fn[bptr])) {
|
||||
realtime_queue.fn[bptr] = NULL;
|
||||
call(state_get());
|
||||
if(realtime_queue.task[bptr].fn) {
|
||||
if(realtime_queue.task[bptr].data == (void *)&dummy_data) {
|
||||
on_execute_realtime_ptr call = realtime_queue.task[bptr].fn_deprecated;
|
||||
realtime_queue.task[bptr].fn = NULL;
|
||||
call(state_get());
|
||||
} else {
|
||||
foreground_task_ptr call = realtime_queue.task[bptr].fn;
|
||||
realtime_queue.task[bptr].fn = NULL;
|
||||
call(realtime_queue.task[bptr].data);
|
||||
}
|
||||
}
|
||||
realtime_queue.tail = (bptr + 1) & (RT_QUEUE_SIZE - 1);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#define LINE_BUFFER_SIZE 257 // 256 characters plus terminator
|
||||
#endif
|
||||
|
||||
typedef void (*foreground_task_ptr)(void *data);
|
||||
|
||||
// Starts Grbl main loop. It handles all incoming characters from the input stream and executes
|
||||
// them as they complete. It is also responsible for finishing the initialization procedures.
|
||||
bool protocol_main_loop (void);
|
||||
@@ -42,6 +44,7 @@ bool protocol_execute_realtime (void);
|
||||
bool protocol_exec_rt_system (void);
|
||||
void protocol_execute_noop (uint_fast16_t state);
|
||||
bool protocol_enqueue_rt_command (on_execute_realtime_ptr fn);
|
||||
bool protocol_enqueue_foreground_task (foreground_task_ptr fn, void *data);
|
||||
|
||||
// Executes the auto cycle feature, if enabled.
|
||||
void protocol_auto_cycle_start (void);
|
||||
|
||||
18
report.c
18
report.c
@@ -272,6 +272,24 @@ void report_message (const char *msg, message_type_t type)
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
}
|
||||
|
||||
// Message helper to be run as foreground task
|
||||
void report_plain (void *message)
|
||||
{
|
||||
report_message((char *)message, Message_Plain);
|
||||
}
|
||||
|
||||
// Message helper to be run as foreground task
|
||||
void report_info (void *message)
|
||||
{
|
||||
report_message((char *)message, Message_Info);
|
||||
}
|
||||
|
||||
// Message helper to be run as foreground task
|
||||
void report_warning (void *message)
|
||||
{
|
||||
report_message((char *)message, Message_Warning);
|
||||
}
|
||||
|
||||
// Prints feedback messages. This serves as a centralized method to provide additional
|
||||
// user feedback for things that are not of the status/alarm message protocol. These are
|
||||
// messages such as setup warnings, switch toggling, and how to exit alarms.
|
||||
|
||||
11
report.h
11
report.h
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2018-2023 Terje Io
|
||||
Copyright (c) 2018-2024 Terje Io
|
||||
Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
@@ -40,6 +40,15 @@ void report_init_fns (void);
|
||||
// Prints feedback message, typically from gcode.
|
||||
void report_message (const char *msg, message_type_t type);
|
||||
|
||||
// Message helper to be run as foreground task.
|
||||
void report_plain (void *message);
|
||||
|
||||
// Message helper to be run as foreground task.
|
||||
void report_info (void *message);
|
||||
|
||||
// Message helper to be run as foreground task.
|
||||
void report_warning (void *message);
|
||||
|
||||
// Prints Grbl help.
|
||||
status_code_t report_help (char *args);
|
||||
|
||||
|
||||
34
stepper.c
34
stepper.c
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2016-2023 Terje Io
|
||||
Copyright (c) 2016-2024 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -84,9 +84,6 @@ typedef struct {
|
||||
static amass_t amass;
|
||||
#endif
|
||||
|
||||
// Message to be output by foreground process
|
||||
static char *message = NULL; // TODO: do we need a queue for this?
|
||||
|
||||
// Used for blocking new segments being added to the seqment buffer until deceleration starts
|
||||
// after probe signal has been asserted.
|
||||
static volatile bool probe_asserted = false;
|
||||
@@ -140,6 +137,7 @@ typedef struct {
|
||||
|
||||
static st_prep_t prep;
|
||||
|
||||
extern void gc_output_message (char *message);
|
||||
|
||||
/* BLOCK VELOCITY PROFILE DEFINITION
|
||||
__________________________
|
||||
@@ -181,22 +179,6 @@ static st_prep_t prep;
|
||||
|
||||
//
|
||||
|
||||
// Output message in sync with motion, called by foreground process.
|
||||
static void output_message (sys_state_t state)
|
||||
{
|
||||
if(message) {
|
||||
|
||||
if(grbl.on_gcode_message)
|
||||
grbl.on_gcode_message(message);
|
||||
|
||||
if(*message)
|
||||
report_message(message, Message_Plain);
|
||||
|
||||
free(message);
|
||||
message = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Callback from delay to deenergize steppers after movement, might been cancelled
|
||||
void st_deenergize (void)
|
||||
{
|
||||
@@ -351,11 +333,8 @@ ISR_CODE void ISR_FUNC(stepper_driver_interrupt_handler)(void)
|
||||
|
||||
// Enqueue any message to be printed (by foreground process)
|
||||
if(st.exec_block->message) {
|
||||
if(message == NULL) {
|
||||
message = st.exec_block->message;
|
||||
protocol_enqueue_rt_command(output_message);
|
||||
} else
|
||||
free(st.exec_block->message); //
|
||||
if(!protocol_enqueue_foreground_task((foreground_task_ptr)gc_output_message, st.exec_block->message))
|
||||
free(st.exec_block->message);
|
||||
st.exec_block->message = NULL;
|
||||
}
|
||||
|
||||
@@ -559,11 +538,6 @@ void st_reset (void)
|
||||
if(hal.probe.configure)
|
||||
hal.probe.configure(false, false);
|
||||
|
||||
if(message) {
|
||||
free(message);
|
||||
message = NULL;
|
||||
}
|
||||
|
||||
// Initialize stepper driver idle state, clear step and direction port pins.
|
||||
st_go_idle();
|
||||
// hal.stepper.go_idle(true);
|
||||
|
||||
7
stream.c
7
stream.c
@@ -605,11 +605,6 @@ const io_stream_t *stream_null_init (uint32_t baud_rate)
|
||||
|
||||
static stream_write_ptr dbg_write = NULL;
|
||||
|
||||
static void debug_stream_warning (uint_fast16_t state)
|
||||
{
|
||||
report_message("Failed to initialize debug stream!", Message_Warning);
|
||||
}
|
||||
|
||||
void debug_write (const char *s)
|
||||
{
|
||||
if(dbg_write) {
|
||||
@@ -654,7 +649,7 @@ bool debug_stream_init (void)
|
||||
if(stream_enumerate_streams(debug_claim_stream))
|
||||
hal.debug.write(ASCII_EOL "UART debug active:" ASCII_EOL);
|
||||
else
|
||||
protocol_enqueue_rt_command(debug_stream_warning);
|
||||
protocol_enqueue_foreground_task(report_warning, "Failed to initialize debug stream!");
|
||||
|
||||
return hal.debug.write == debug_write;
|
||||
}
|
||||
|
||||
89
system.c
89
system.c
@@ -923,36 +923,65 @@ PROGMEM static const sys_command_t sys_commands[] = {
|
||||
#endif
|
||||
};
|
||||
|
||||
void system_output_help (const sys_command_t *commands, uint32_t num_commands)
|
||||
static sys_commands_t core_commands = {
|
||||
.n_commands = sizeof(sys_commands) / sizeof(sys_command_t),
|
||||
.commands = sys_commands,
|
||||
};
|
||||
|
||||
static sys_commands_t *commands_root = &core_commands;
|
||||
|
||||
void system_register_commands (sys_commands_t *commands)
|
||||
{
|
||||
commands->next = commands_root;
|
||||
commands_root = commands;
|
||||
}
|
||||
|
||||
void _system_output_help (sys_commands_t *commands, bool traverse)
|
||||
{
|
||||
const char *help;
|
||||
uint_fast8_t idx;
|
||||
|
||||
for(idx = 0; idx < num_commands; idx++) {
|
||||
while(commands) {
|
||||
for(idx = 0; idx < commands->n_commands; idx++) {
|
||||
|
||||
if(commands[idx].help.str) {
|
||||
if(commands->commands[idx].help.str) {
|
||||
|
||||
if(commands[idx].flags.help_fn)
|
||||
help = commands[idx].help.fn(commands[idx].command);
|
||||
else
|
||||
help = commands[idx].help.str;
|
||||
if(commands->commands[idx].flags.help_fn)
|
||||
help = commands->commands[idx].help.fn(commands->commands[idx].command);
|
||||
else
|
||||
help = commands->commands[idx].help.str;
|
||||
|
||||
if(help) {
|
||||
if(*help != '$') {
|
||||
hal.stream.write_char('$');
|
||||
hal.stream.write(commands[idx].command);
|
||||
hal.stream.write(" - ");
|
||||
if(help) {
|
||||
if(*help != '$') {
|
||||
hal.stream.write_char('$');
|
||||
hal.stream.write(commands->commands[idx].command);
|
||||
hal.stream.write(" - ");
|
||||
}
|
||||
hal.stream.write(help);
|
||||
hal.stream.write("." ASCII_EOL);
|
||||
}
|
||||
hal.stream.write(help);
|
||||
hal.stream.write("." ASCII_EOL);
|
||||
}
|
||||
}
|
||||
commands = traverse && commands->next != &core_commands ? commands->next : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated, to be removed.
|
||||
void system_output_help (const sys_command_t *commands, uint32_t num_commands)
|
||||
{
|
||||
sys_commands_t cmd = {
|
||||
.commands = commands,
|
||||
.n_commands = num_commands
|
||||
};
|
||||
|
||||
_system_output_help(&cmd, false);
|
||||
}
|
||||
|
||||
void system_command_help (void)
|
||||
{
|
||||
system_output_help(sys_commands, sizeof(sys_commands) / sizeof(sys_command_t));
|
||||
_system_output_help(&core_commands, false);
|
||||
if(commands_root != &core_commands)
|
||||
_system_output_help(commands_root, true);
|
||||
}
|
||||
|
||||
/*! \brief Directs and executes one line of input from protocol_process.
|
||||
@@ -981,12 +1010,6 @@ status_code_t system_execute_line (char *line)
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
sys_commands_t base = {
|
||||
.n_commands = sizeof(sys_commands) / sizeof(sys_command_t),
|
||||
.commands = sys_commands,
|
||||
.on_get_commands = grbl.on_get_commands
|
||||
};
|
||||
|
||||
status_code_t retval = Status_Unhandled;
|
||||
|
||||
char c, *s1, *s2;
|
||||
@@ -1014,7 +1037,7 @@ status_code_t system_execute_line (char *line)
|
||||
*args++ = '\0';
|
||||
|
||||
uint_fast8_t idx;
|
||||
sys_commands_t *cmd = &base;
|
||||
sys_commands_t *cmd = commands_root;
|
||||
do {
|
||||
for(idx = 0; idx < cmd->n_commands; idx++) {
|
||||
if(!strcmp(line, cmd->commands[idx].command)) {
|
||||
@@ -1027,9 +1050,29 @@ status_code_t system_execute_line (char *line)
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd = retval == Status_Unhandled && cmd->on_get_commands ? cmd->on_get_commands() : NULL;
|
||||
cmd = retval == Status_Unhandled ? cmd->next : NULL;
|
||||
} while(cmd);
|
||||
|
||||
// deprecated, to be removed
|
||||
if(retval == Status_Unhandled && (cmd = grbl.on_get_commands ? grbl.on_get_commands() : NULL)) {
|
||||
|
||||
do {
|
||||
for(idx = 0; idx < cmd->n_commands; idx++) {
|
||||
if(!strcmp(line, cmd->commands[idx].command)) {
|
||||
if(sys.blocking_event && !cmd->commands[idx].flags.allow_blocking) {
|
||||
retval = Status_NotAllowedCriticalEvent;
|
||||
break;
|
||||
} else if(!cmd->commands[idx].flags.noargs || args == NULL) {
|
||||
if((retval = cmd->commands[idx].execute(state_get(), args)) != Status_Unhandled)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
cmd = retval == Status_Unhandled && cmd->on_get_commands ? cmd->on_get_commands() : NULL;
|
||||
} while(cmd);
|
||||
}
|
||||
// end of to be removed
|
||||
|
||||
// Let user code have a peek at system commands before check for global setting
|
||||
if(retval == Status_Unhandled && grbl.on_unknown_sys_command) {
|
||||
if(args)
|
||||
|
||||
4
system.h
4
system.h
@@ -338,7 +338,8 @@ typedef struct
|
||||
typedef struct sys_commands_str {
|
||||
const uint8_t n_commands;
|
||||
const sys_command_t *commands;
|
||||
struct sys_commands_str *(*on_get_commands)(void);
|
||||
struct sys_commands_str *next;
|
||||
struct sys_commands_str *(*on_get_commands)(void); //!< deprecated, to be removed
|
||||
} sys_commands_t;
|
||||
|
||||
extern system_t sys;
|
||||
@@ -352,6 +353,7 @@ void system_raise_alarm (alarm_code_t alarm);
|
||||
void system_init_switches (void);
|
||||
void system_command_help (void);
|
||||
void system_output_help (const sys_command_t *commands, uint32_t num_commands);
|
||||
void system_register_commands (sys_commands_t *commands);
|
||||
|
||||
void system_add_rt_report (report_tracking_t report);
|
||||
report_tracking_flags_t system_get_rt_report_flags (void);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2020-2023 Terje Io
|
||||
Copyright (c) 2020-2024 Terje Io
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -147,14 +147,14 @@ static bool restore (void)
|
||||
|
||||
// Issue warning on cycle start event if touch off by $TPW is pending.
|
||||
// Used in Manual and Manual_G59_3 modes ($341=1 or $341=2). Called from the foreground process.
|
||||
static void execute_warning (sys_state_t state)
|
||||
static void execute_warning (void *data)
|
||||
{
|
||||
grbl.report.feedback_message(Message_ExecuteTPW);
|
||||
}
|
||||
|
||||
// Execute restore position after touch off (on cycle start event).
|
||||
// Used in Manual and Manual_G59_3 modes ($341=1 or $341=2). Called from the foreground process.
|
||||
static void execute_restore (sys_state_t state)
|
||||
static void execute_restore (void *data)
|
||||
{
|
||||
// Get current position.
|
||||
system_convert_array_steps_to_mpos(target.values, sys.position);
|
||||
@@ -171,7 +171,7 @@ static void execute_restore (sys_state_t state)
|
||||
|
||||
// Execute touch off on cycle start event from @ G59.3 position.
|
||||
// Used in SemiAutomatic mode ($341=3) only. Called from the foreground process.
|
||||
static void execute_probe (sys_state_t state)
|
||||
static void execute_probe (void *data)
|
||||
{
|
||||
#if COMPATIBILITY_LEVEL <= 1
|
||||
bool ok;
|
||||
@@ -245,9 +245,9 @@ ISR_CODE static void ISR_FUNC(trap_control_cycle_start)(control_signals_t signal
|
||||
if(signals.cycle_start) {
|
||||
if(!execute_posted) {
|
||||
if(!block_cycle_start)
|
||||
execute_posted = protocol_enqueue_rt_command(settings.tool_change.mode == ToolChange_SemiAutomatic ? execute_probe : execute_restore);
|
||||
execute_posted = protocol_enqueue_foreground_task(settings.tool_change.mode == ToolChange_SemiAutomatic ? execute_probe : execute_restore, NULL);
|
||||
else
|
||||
protocol_enqueue_rt_command(execute_warning);
|
||||
protocol_enqueue_foreground_task(execute_warning, NULL);
|
||||
}
|
||||
signals.cycle_start = Off;
|
||||
} else
|
||||
@@ -265,9 +265,9 @@ ISR_CODE static bool ISR_FUNC(trap_stream_cycle_start)(char c)
|
||||
if((drop = (c == CMD_CYCLE_START || c == CMD_CYCLE_START_LEGACY))) {
|
||||
if(!execute_posted) {
|
||||
if(!block_cycle_start)
|
||||
execute_posted = protocol_enqueue_rt_command(settings.tool_change.mode == ToolChange_SemiAutomatic ? execute_probe : execute_restore);
|
||||
execute_posted = protocol_enqueue_foreground_task(settings.tool_change.mode == ToolChange_SemiAutomatic ? execute_probe : execute_restore, NULL);
|
||||
else
|
||||
protocol_enqueue_rt_command(execute_warning);
|
||||
protocol_enqueue_foreground_task(execute_warning, NULL);
|
||||
}
|
||||
} else
|
||||
drop = enqueue_realtime_command(c);
|
||||
|
||||
63
vfs.c
63
vfs.c
@@ -5,7 +5,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2022-2023 Terje Io
|
||||
Copyright (c) 2022-2024 Terje Io
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -130,6 +130,7 @@ static vfs_mount_t *cwdmount = &root;
|
||||
static char cwd[100] = "/";
|
||||
|
||||
int vfs_errno = 0;
|
||||
vfs_events_t vfs = {0};
|
||||
|
||||
// Strip trailing directory separator, FatFS dont't like it (WinSCP adds it)
|
||||
char *vfs_fixpath (char *path)
|
||||
@@ -210,6 +211,8 @@ void vfs_close (vfs_file_t *file)
|
||||
vfs_errno = 0;
|
||||
|
||||
((vfs_t *)(file->fs))->fclose(file);
|
||||
|
||||
// TODO: somehow raise vfs.on_fs_changed event when a file openened for writing is closed
|
||||
}
|
||||
|
||||
size_t vfs_read (void *buffer, size_t size, size_t count, vfs_file_t *file)
|
||||
@@ -261,30 +264,54 @@ bool vfs_eof (vfs_file_t *file)
|
||||
|
||||
int vfs_rename (const char *from, const char *to)
|
||||
{
|
||||
int ret;
|
||||
|
||||
vfs_mount_t *mount_from = get_mount(from), *mount_to = get_mount(to);
|
||||
|
||||
return mount_from == mount_to ? mount_from->vfs->frename(get_filename(mount_from, from), get_filename(mount_to, to)) : -1;
|
||||
if((ret = mount_from == mount_to ? mount_from->vfs->frename(get_filename(mount_from, from), get_filename(mount_to, to)) : -1) != -1 &&
|
||||
vfs.on_fs_changed && !mount_from->mode.hidden) {
|
||||
vfs.on_fs_changed(mount_from->vfs);
|
||||
if(mount_from != mount_to && !mount_to->mode.hidden)
|
||||
vfs.on_fs_changed(mount_to->vfs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfs_unlink (const char *filename)
|
||||
{
|
||||
int ret;
|
||||
|
||||
vfs_mount_t *mount = get_mount(filename); // TODO: test for dir?
|
||||
|
||||
return mount ? mount->vfs->funlink(get_filename(mount, filename)) : -1;
|
||||
if((ret = mount ? mount->vfs->funlink(get_filename(mount, filename)) : -1) != -1 && vfs.on_fs_changed && !mount->mode.hidden)
|
||||
vfs.on_fs_changed(mount->vfs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfs_mkdir (const char *path)
|
||||
{
|
||||
int ret;
|
||||
|
||||
vfs_mount_t *mount = get_mount(path);
|
||||
|
||||
return mount ? mount->vfs->fmkdir(get_filename(mount, path)) : -1;
|
||||
if((ret = mount ? mount->vfs->fmkdir(get_filename(mount, path)) : -1) != -1 && vfs.on_fs_changed && !mount->mode.hidden)
|
||||
vfs.on_fs_changed(mount->vfs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfs_rmdir (const char *path)
|
||||
{
|
||||
int ret;
|
||||
|
||||
vfs_mount_t *mount = get_mount(path);
|
||||
|
||||
return mount ? mount->vfs->frmdir(get_filename(mount, path)) : -1;
|
||||
if((ret = mount ? mount->vfs->frmdir(get_filename(mount, path)) : -1) != -1 && vfs.on_fs_changed && !mount->mode.hidden)
|
||||
vfs.on_fs_changed(mount->vfs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vfs_chdir (const char *path)
|
||||
@@ -460,31 +487,31 @@ vfs_free_t *vfs_fgetfree (const char *path)
|
||||
|
||||
bool vfs_mount (const char *path, const vfs_t *fs, vfs_st_mode_t mode)
|
||||
{
|
||||
vfs_mount_t *vfs;
|
||||
vfs_mount_t *mount;
|
||||
|
||||
if(!strcmp(path, "/")) {
|
||||
root.vfs = fs;
|
||||
root.mode = mode;
|
||||
} else if((vfs = (vfs_mount_t *)malloc(sizeof(vfs_mount_t)))) {
|
||||
} else if((mount = (vfs_mount_t *)malloc(sizeof(vfs_mount_t)))) {
|
||||
|
||||
strcpy(vfs->path, path);
|
||||
if(vfs->path[strlen(path) - 1] != '/')
|
||||
strcat(vfs->path, "/");
|
||||
strcpy(mount->path, path);
|
||||
if(mount->path[strlen(path) - 1] != '/')
|
||||
strcat(mount->path, "/");
|
||||
|
||||
vfs->vfs = fs;
|
||||
vfs->mode = mode;
|
||||
vfs->next = NULL;
|
||||
mount->vfs = fs;
|
||||
mount->mode = mode;
|
||||
mount->next = NULL;
|
||||
|
||||
vfs_mount_t *mount = &root;
|
||||
|
||||
while(mount->next)
|
||||
mount = mount->next;
|
||||
|
||||
mount->next = vfs;
|
||||
mount->next = mount;
|
||||
}
|
||||
|
||||
if(fs && grbl.on_vfs_mount)
|
||||
grbl.on_vfs_mount(path, fs);
|
||||
if(fs && vfs.on_mount)
|
||||
vfs.on_mount(path, fs);
|
||||
|
||||
return fs != NULL;
|
||||
}
|
||||
@@ -513,8 +540,8 @@ bool vfs_unmount (const char *path)
|
||||
}
|
||||
}
|
||||
|
||||
if(grbl.on_vfs_unmount)
|
||||
grbl.on_vfs_unmount(path);
|
||||
if(vfs.on_unmount)
|
||||
vfs.on_unmount(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
13
vfs.h
13
vfs.h
@@ -5,7 +5,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2022-2023 Terje Io
|
||||
Copyright (c) 2022-2024 Terje Io
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -152,6 +152,16 @@ typedef struct
|
||||
vfs_format_ptr format;
|
||||
} vfs_t;
|
||||
|
||||
typedef void (*on_vfs_changed_ptr)(const vfs_t *fs);
|
||||
typedef void (*on_vfs_mount_ptr)(const char *path, const vfs_t *fs);
|
||||
typedef void (*on_vfs_unmount_ptr)(const char *path);
|
||||
|
||||
typedef struct {
|
||||
on_vfs_mount_ptr on_mount; //!< Called when a file system is mounted.
|
||||
on_vfs_unmount_ptr on_unmount; //!< Called when a file system is unmounted.
|
||||
on_vfs_changed_ptr on_fs_changed; //!< Called when file system content is changed.
|
||||
} vfs_events_t;
|
||||
|
||||
typedef struct vfs_mount
|
||||
{
|
||||
char path[64];
|
||||
@@ -185,6 +195,7 @@ struct vfs_dir {
|
||||
};
|
||||
|
||||
extern int vfs_errno;
|
||||
extern vfs_events_t vfs;
|
||||
|
||||
char *vfs_fixpath (char *path);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user