Skip to content

Commit e272f77

Browse files
committed
Refactored the tool table HAL API a bit to improve functionality.
Added tool name, pocket number and some lathe specific data fields to the $# tool output when available from the tool table. If name is available it will be output as a push message on M6 if there is no message in the same block. Added support for directory up, .., to VFS. Added new option to $650 - File systems options to enable hierarchical listing of files and directories via $F and $F+ commands.
1 parent 18d6272 commit e272f77

File tree

13 files changed

+173
-55
lines changed

13 files changed

+173
-55
lines changed

changelog.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
## grblHAL changelog
22

3+
<a name="20251111">Build 20251111
4+
5+
Core:
6+
7+
* Refactored the tool table HAL API a bit to improve functionality.
8+
Added tool name, pocket number and some lathe specific data fields to the `$#` tool output when available from the tool table.
9+
If name is available it will be output as a push message on `M6` if there is no message in the same block.
10+
11+
* Added support for directory up, `..`, to VFS.
12+
13+
* Added new option to `$650` - _File systems options_ to enable hierarchical listing of files and directories via `$F` and `$F+` commands.
14+
When enabled directories are added to the output with file size set to `-1` and only the contents of the current directory is reported.
15+
The `$F=<dirname>` command can then be used to set the current working direcory \(CWD\). `$F=..` can be used to move up one level and `$F=/` to move to the root directory.
16+
Files or directory names for `$F`, `$F+` `$F<` and `$FD` commands not starting with `/` will executed be relative to the CWD.
17+
18+
Plugins:
19+
20+
* Misc, tooltable: removed limit on max number of tools, it is now constrained by available RAM. Added name \(remark, comment\) to imported data and
21+
a new command, `$TTLOAD`, that can be used to reload the tool table after it has been updated.
22+
23+
* EEPROM: added experimental code that allows mounting unused part of large EEPROM as littlefs file system. This may then be used to store a file based tooltable etc.
24+
25+
* SD Card, littlefs VFS wrapper: added support for `vfs_chdir()` \(change directory\) to allow ftp access to subdirectories.
26+
27+
---
28+
329
<a name="20251109">Build 20251109
430

531
Core:

config.h

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ Set to \ref On or 1 to enable experimental support for expressions.
542542
Some LinuxCNC extensions are supported, conditionals and subroutines are not.
543543
*/
544544
#if !defined NGC_EXPRESSIONS_ENABLE || defined __DOXYGEN__
545-
#define NGC_EXPRESSIONS_ENABLE Off
545+
#define NGC_EXPRESSIONS_ENABLE On
546546
#endif
547547

548548
/*! \def NGC_PARAMETERS_ENABLE
@@ -1467,11 +1467,14 @@ and less range over the total 255 PWM levels to signal different spindle speeds.
14671467
// Homing settings (Group_Homing)
14681468

14691469
/*! @name $22 - Setting_HomingEnable
1470-
\brief Enable homing.
1470+
\brief Enable and control homing functionality.
14711471
Requires homing cycles to be defined by \ref DEFAULT_HOMING_CYCLE_0 - \ref DEFAULT_HOMING_CYCLE_2 +.
1472-
\internal Bit 0 in settings.homing.flags.
14731472
*/
14741473
///@{
1474+
/*! /def DEFAULT_HOMING_ENABLE
1475+
\brief Enables homing overall.
1476+
\internal Bit 0 in settings.homing.flags.
1477+
*/
14751478
#if !defined DEFAULT_HOMING_ENABLE || defined __DOXYGEN__
14761479
#define DEFAULT_HOMING_ENABLE Off // Default disabled. Set to \ref On or 1 to enable.
14771480
#endif
@@ -2119,6 +2122,46 @@ Default stream format settings for ModBus RTU stream.
21192122
#endif
21202123
///@}
21212124

2125+
/*! @name $681 - Setting_ModBus_StreamFormat
2126+
Default stream format settings for ModBus RTU stream.
2127+
*/
2128+
///@{
2129+
#if !defined DEFAULT_MODBUS_STREAM_PARITY || defined __DOXYGEN__
2130+
#define DEFAULT_MODBUS_STREAM_PARITY 0 // 0 = None, 1 = Even, 2 = Odd
2131+
#endif
2132+
///@}
2133+
2134+
/*! @name $650 - Setting_FSOptions
2135+
Filing systems options.
2136+
*/
2137+
///@{
2138+
/*! /def DEFAULT_FS_SD_AUTOMOUNT
2139+
\brief Auto mount SD card on startup.
2140+
\internal Bit 0 in settings.fs_options.mask.
2141+
*/
2142+
#if !defined DEFAULT_FS_SD_AUTOMOUNT || defined __DOXYGEN__
2143+
#define DEFAULT_FS_SD_AUTOMOUNT Off // Default disabled. Set to \ref On or 1 to enable.
2144+
#endif
2145+
2146+
/*! /def DEFAULT_FS_LITLLEFS_HIDDEN
2147+
\brief Hides LittleFS mount from directory listings.
2148+
\internal Bit 1 in settings.fs_options.mask.
2149+
*/
2150+
#if !defined DEFAULT_FS_LITLLEFS_HIDDEN || defined __DOXYGEN__
2151+
#define DEFAULT_FS_LITLLEFS_HIDDEN Off // Default disabled. Set to \ref On or 1 to enable.
2152+
#endif
2153+
2154+
/*! /def DEFAULT_FS_HIERACHICAL_LISTING
2155+
\brief
2156+
Adds directory entries in $F and $F+ output to allow hierarchical navigation of the directoy tree.
2157+
\internal Bit 2 in settings.fs_options.mask.
2158+
*/
2159+
#if !defined DEFAULT_FS_HIERACHICAL_LISTING || defined __DOXYGEN__
2160+
#define DEFAULT_FS_HIERACHICAL_LISTING Off // Default disabled. Set to \ref On or 1 to enable.
2161+
#endif
2162+
///@}
2163+
2164+
21222165
// Axis settings (Group_XAxis - Group_VAxis)
21232166

21242167
/*! @name $10x - Setting_AxisStepsPerMM

core_handlers.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,16 @@ typedef status_code_t (*on_macro_execute_ptr)(macro_id_t macro); // macro implem
136136
typedef void (*on_macro_return_ptr)(void);
137137
typedef void (*on_file_demarcate_ptr)(bool start);
138138

139-
typedef tool_data_t *(*get_tool_ptr)(tool_id_t tool_id);
140-
typedef tool_data_t *(*get_tool_by_idx_ptr)(uint32_t idx);
139+
typedef tool_table_entry_t *(*get_tool_ptr)(tool_id_t tool_id);
140+
typedef tool_table_entry_t *(*get_tool_by_idx_ptr)(uint32_t idx);
141141
typedef bool (*set_tool_data_ptr)(tool_data_t *tool_data);
142-
typedef pocket_id_t (*get_pocket_ptr)(tool_id_t tool_id);
143142
typedef bool (*clear_tool_data_ptr)(void);
144143

145144
typedef struct {
146145
uint32_t n_tools;
147146
get_tool_ptr get_tool;
148147
get_tool_by_idx_ptr get_tool_by_idx;
149148
set_tool_data_ptr set_tool;
150-
get_pocket_ptr get_pocket;
151149
clear_tool_data_ptr clear;
152150
} tool_table_t;
153151

gcode.c

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -373,16 +373,16 @@ void gc_init (bool stop)
373373
{
374374
#if COMPATIBILITY_LEVEL > 1
375375
memset(&gc_state, 0, sizeof(parser_state_t));
376-
gc_state.tool = grbl.tool_table.get_tool(0);
376+
gc_state.tool = grbl.tool_table.get_tool(0)->data;
377377
if(grbl.tool_table.n_tools == 0)
378378
memset(gc_state.tool, 0, sizeof(tool_data_t));
379379
#else
380380
if(sys.cold_start) {
381381
memset(&gc_state, 0, sizeof(parser_state_t));
382382
if(settings.flags.tool_persistent)
383-
gc_state.tool = grbl.tool_table.get_tool(settings.tool_id);
383+
gc_state.tool = grbl.tool_table.get_tool(settings.tool_id)->data;
384384
if(gc_state.tool == NULL)
385-
gc_state.tool = grbl.tool_table.get_tool(0);
385+
gc_state.tool = grbl.tool_table.get_tool(0)->data;
386386
if(grbl.tool_table.n_tools == 0) {
387387
memset(gc_state.tool, 0, sizeof(tool_data_t));
388388
if(settings.flags.tool_persistent)
@@ -503,12 +503,21 @@ static void add_offset (const coord_data_t *offset)
503503
system_flag_wco_change();
504504
}
505505

506-
static tool_data_t *tool_get_pending (tool_id_t tool_id)
506+
static tool_data_t *tool_get_pending (tool_id_t tool_id, char **message)
507507
{
508508
static tool_data_t tool_data = {0};
509509

510-
if(grbl.tool_table.n_tools)
511-
return grbl.tool_table.get_tool(tool_id);
510+
if(grbl.tool_table.n_tools) {
511+
512+
tool_table_entry_t *tool = grbl.tool_table.get_tool(tool_id);
513+
514+
if(message && tool->name) {
515+
if((*message = malloc(strlen(tool->name) + 1)))
516+
strcpy(*message, tool->name);
517+
}
518+
519+
return tool->data;
520+
}
512521

513522
memcpy(&tool_data, gc_state.tool, sizeof(tool_data_t));
514523
tool_data.tool_id = tool_id;
@@ -1711,7 +1720,7 @@ status_code_t gc_execute_block (char *block)
17111720
case 'T':
17121721
if(mantissa > 0)
17131722
FAIL(Status_GcodeCommandValueNotInteger);
1714-
if(grbl.tool_table.n_tools ? (grbl.tool_table.get_tool((tool_id_t)int_value) == NULL) : (int_value > MAX_TOOL_NUMBER))
1723+
if(grbl.tool_table.n_tools ? (grbl.tool_table.get_tool((tool_id_t)int_value)->data == NULL) : (int_value > MAX_TOOL_NUMBER))
17151724
FAIL(Status_GcodeIllegalToolTableEntry);
17161725
word_bit.parameter.t = On;
17171726
gc_block.values.t = isnan(value) ? 0xFFFFFFFF : int_value;
@@ -2059,7 +2068,7 @@ status_code_t gc_execute_block (char *block)
20592068
FAIL(Status_GcodeValueWordMissing);
20602069
if(!isintf(gc_block.values.q))
20612070
FAIL(Status_GcodeCommandValueNotInteger);
2062-
if(grbl.tool_table.n_tools ? grbl.tool_table.get_tool((tool_id_t)gc_block.values.q) == NULL : gc_block.values.q > MAX_TOOL_NUMBER)
2071+
if(grbl.tool_table.n_tools ? grbl.tool_table.get_tool((tool_id_t)gc_block.values.q)->data == NULL : gc_block.values.q > MAX_TOOL_NUMBER)
20632072
FAIL(Status_GcodeIllegalToolTableEntry);
20642073

20652074
gc_block.values.t = (uint32_t)gc_block.values.q;
@@ -2402,7 +2411,7 @@ status_code_t gc_execute_block (char *block)
24022411
if(gc_block.words.h) {
24032412
if(gc_block.values.h == 0 && !settings.macro_atc_flags.random_toolchanger)
24042413
gc_block.values.h = gc_block.values.t; // !! no tool clear offset
2405-
if(!grbl.tool_table.get_tool((tool_id_t)gc_block.values.h))
2414+
if(!grbl.tool_table.get_tool((tool_id_t)gc_block.values.h)->data)
24062415
FAIL(Status_GcodeIllegalToolTableEntry);
24072416
gc_block.words.h = Off;
24082417
} else
@@ -2414,7 +2423,7 @@ status_code_t gc_execute_block (char *block)
24142423
case ToolLengthOffset_ApplyAdditional:
24152424
if(grbl.tool_table.n_tools) {
24162425
if(gc_block.words.h) {
2417-
if(gc_block.values.h == 0 || !grbl.tool_table.get_tool((tool_id_t)gc_block.values.h))
2426+
if(gc_block.values.h == 0 || !grbl.tool_table.get_tool((tool_id_t)gc_block.values.h)->data)
24182427
FAIL(Status_GcodeIllegalToolTableEntry);
24192428
gc_block.words.h = Off;
24202429
} else
@@ -2532,8 +2541,8 @@ status_code_t gc_execute_block (char *block)
25322541

25332542
tool_data_t *tool_data;
25342543

2535-
if((tool_data = grbl.tool_table.get_tool((tool_id_t)p_value)) == NULL)
2536-
FAIL(Status_GcodeIllegalToolTableEntry); // [Greater than max allowed tool number]
2544+
if((tool_data = grbl.tool_table.get_tool((tool_id_t)p_value)->data) == NULL)
2545+
FAIL(Status_GcodeIllegalToolTableEntry); // [Greater than max allowed tool number or not in tool table]
25372546

25382547
if(gc_block.words.r) {
25392548
tool_data->radius = gc_block.values.r;
@@ -2546,9 +2555,6 @@ status_code_t gc_execute_block (char *block)
25462555
FAIL(Status_SettingReadFail);
25472556
#endif
25482557

2549-
if(gc_block.values.l == 1)
2550-
tool_data = grbl.tool_table.get_tool((tool_id_t)p_value);
2551-
25522558
idx = N_AXIS;
25532559
do {
25542560
if(bit_istrue(axis_words.mask, bit(--idx))) {
@@ -3427,7 +3433,7 @@ status_code_t gc_execute_block (char *block)
34273433

34283434
if(!check_mode) {
34293435

3430-
tool_data_t *pending_tool = tool_get_pending(gc_state.tool_pending);
3436+
tool_data_t *pending_tool = tool_get_pending(gc_state.tool_pending, NULL);
34313437

34323438
// If M6 not available or M61 commanded set new tool immediately
34333439
if(set_tool || (hal.driver_cap.atc ? !hal.tool.change : settings.tool_change.mode == ToolChange_Ignore || !(hal.stream.suspend_read || hal.tool.change))) {
@@ -3494,7 +3500,7 @@ status_code_t gc_execute_block (char *block)
34943500
// [6. Change tool ]: Delegated to (possible) driver implementation
34953501
if(command_words.M6 && !set_tool && !check_mode) {
34963502

3497-
tool_data_t *pending_tool = tool_get_pending(gc_state.tool_pending);
3503+
tool_data_t *pending_tool = tool_get_pending(gc_state.tool_pending, plan_data.message ? NULL : &plan_data.message);
34983504

34993505
protocol_buffer_synchronize();
35003506

@@ -3760,7 +3766,7 @@ status_code_t gc_execute_block (char *block)
37603766
gc_state.modal.tool_offset_mode = gc_block.modal.tool_offset_mode;
37613767

37623768
if(gc_state.modal.tool_offset_mode == ToolLengthOffset_Enable || gc_state.modal.tool_offset_mode == ToolLengthOffset_ApplyAdditional)
3763-
tool_data = grbl.tool_table.get_tool((tool_id_t)gc_block.values.h);
3769+
tool_data = grbl.tool_table.get_tool((tool_id_t)gc_block.values.h)->data;
37643770

37653771
do {
37663772

gcode.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,9 +589,17 @@ typedef struct {
589589
tool_id_t tool_id; //!< Tool number
590590
} tool_data_t;
591591

592+
//! Tool table entry.
593+
typedef struct {
594+
const char *name;
595+
tool_data_t *data;
596+
pocket_id_t pocket;
597+
} tool_table_entry_t;
598+
592599
typedef struct {
593600
tool_data_t tool;
594601
pocket_id_t pocket_id;
602+
char name[101];
595603
} tool_pocket_t;
596604

597605
/*! \brief Parser state

grbl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#else
4343
#define GRBL_VERSION "1.1f"
4444
#endif
45-
#define GRBL_BUILD 20251109
45+
#define GRBL_BUILD 20251111
4646

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

grbllib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ int grbl_enter (void)
432432
task_add_delayed(auto_realtime_report, NULL, settings.report_interval);
433433

434434
if(hal.driver_cap.sd_card || hal.driver_cap.littlefs) {
435-
fs_options_t fs_options = {0};
435+
fs_options_t fs_options = { .hierarchical_listing = On };
436436
fs_options.lfs_hidden = hal.driver_cap.littlefs;
437437
fs_options.sd_mount_on_boot = hal.driver_cap.sd_card;
438438
setting_remove_elements(Setting_FSOptions, fs_options.mask);

ngc_params.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,15 +596,15 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
596596
break;
597597

598598
case NGCParam_current_pocket:
599-
value = (float)grbl.tool_table.get_pocket(gc_state.tool->tool_id);
599+
value = (float)grbl.tool_table.get_tool(gc_state.tool->tool_id)->pocket;
600600
break;
601601

602602
case NGCParam_selected_tool:
603603
value = gc_state.tool_pending != gc_state.tool->tool_id ? (float)gc_state.tool_pending : -1.0f;
604604
break;
605605

606606
case NGCParam_selected_pocket:
607-
value = gc_state.tool_pending != gc_state.tool->tool_id ? (float)grbl.tool_table.get_pocket(gc_state.tool_pending) : -1.0f;
607+
value = gc_state.tool_pending != gc_state.tool->tool_id ? (float)grbl.tool_table.get_tool(gc_state.tool_pending)->pocket : -1.0f;
608608
break;
609609

610610
case NGCParam_call_level:
@@ -1094,7 +1094,7 @@ static status_code_t macro_get_tool_offset (void)
10941094
status = Status_GcodeValueWordMissing;
10951095
else if(grbl.tool_table.n_tools && ngc_param_get(17 /* Q word */, &tool_id) && ngc_param_get(18 /* R word */, &axis_id)) {
10961096

1097-
tool_data_t *tool_data = grbl.tool_table.get_tool((tool_id_t)tool_id);
1097+
tool_data_t *tool_data = grbl.tool_table.get_tool((tool_id_t)tool_id)->data;
10981098

10991099
if(tool_data && (uint8_t)axis_id < N_AXIS) {
11001100
ngc_named_param_set("_value", tool_data->offset.values[(uint8_t)axis_id]);

report.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,17 +646,26 @@ void report_ngc_parameters (void)
646646
hal.stream.write("]" ASCII_EOL);
647647

648648
tool_data_t *tool_data;
649+
tool_table_entry_t *tool;
649650

650651
for (idx = 1; idx <= grbl.tool_table.n_tools; idx++) {
651-
if((tool_data = grbl.tool_table.get_tool_by_idx((uint32_t)idx)) &&
652+
if((tool_data = (tool = grbl.tool_table.get_tool_by_idx((uint32_t)idx))->data) &&
652653
(settings.macro_atc_flags.random_toolchanger ? tool_data->tool_id >= 0 : tool_data->tool_id > 0)) {
653654
hal.stream.write("[T:");
654655
hal.stream.write(uitoa(tool_data->tool_id));
655656
hal.stream.write("|");
656657
hal.stream.write(get_axis_values(tool_data->offset.values));
657658
hal.stream.write("|");
658659
hal.stream.write(get_axis_value(tool_data->radius));
660+
hal.stream.write("|6,0,0|");
661+
hal.stream.write(tool->name ? tool->name : ""); // TODO: sanitize name? (| not allowed)
662+
if(tool->pocket >= 0) {
663+
hal.stream.write("|");
664+
hal.stream.write(uitoa((uint32_t)tool->pocket));
665+
}
659666
hal.stream.write("]" ASCII_EOL);
667+
if(tool->name)
668+
hal.delay_ms(5, NULL);
660669
}
661670
}
662671

0 commit comments

Comments
 (0)