Skip to content

Commit 0c6f3f6

Browse files
committed
Added support for traversing directory structure across file system mounts. Allows access to littlefs mount via ftp.
Fixed inconsistent (random) real-time reporting of cycle start signal by adding a latch to ensure it is reported at least once.
1 parent 8f5fa90 commit 0c6f3f6

11 files changed

+146
-39
lines changed

changelog.md

+21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
## grblHAL changelog
22

3+
<a name="20230714"/>20230714
4+
5+
Core:
6+
7+
* Added support for traversing directory structure across file system mounts. Allows access to littlefs mount via ftp.
8+
* Fixed inconsistent \(random\) real-time reporting of cycle start signal by adding a latch to ensure it is reported at least once.
9+
10+
Drivers:
11+
12+
* ESP32: added WiFi settings for country, AP channel and BSSID. Changed default AP password to make it legal, was too short.
13+
14+
* STM32F7xx: added EStop signal handling. Driver now defaults to this for the reset input.
15+
16+
Plugins:
17+
18+
* Networking: improved telnet transmit handling.
19+
20+
* WebUI: added file seek function for embedded files, may be used later by gcode macros.
21+
22+
---
23+
324
<a name="20230711"/>20230711
425

526
Core:

driver_opts.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@
430430
#define NETWORK_AP_SSID "grblHAL_AP"
431431
#endif
432432
#ifndef NETWORK_AP_PASSWORD
433-
#define NETWORK_AP_PASSWORD "grblHAL"
433+
#define NETWORK_AP_PASSWORD "grblHALpwd"
434434
#endif
435435
#ifndef NETWORK_AP_HOSTNAME
436436
#define NETWORK_AP_HOSTNAME "grblHAL_AP"

gcode.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,7 @@ status_code_t gc_execute_block (char *block)
17161716
gc_block.values.t = (uint32_t)gc_block.values.q;
17171717
gc_block.words.q = Off;
17181718
#if NGC_EXPRESSIONS_ENABLE
1719-
if(sys.macro_file) {
1719+
if(hal.stream.file) {
17201720
gc_state.tool_pending = 0; // force set tool
17211721
#if N_TOOLS
17221722
if(gc_state.g43_pending) {

grbl.h

+1-1
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 20230711
45+
#define GRBL_BUILD 20230714
4646

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

ngc_flowctrl.c

+13-13
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ static status_code_t stack_push (uint32_t o_label, ngc_cmd_t operation)
170170
{
171171
if(stack_idx < (NGC_STACK_DEPTH - 1)) {
172172
stack[++stack_idx].o_label = o_label;
173-
stack[stack_idx].file = sys.macro_file;
173+
stack[stack_idx].file = hal.stream.file;
174174
stack[stack_idx].operation = operation;
175175
return Status_OK;
176176
}
@@ -259,17 +259,17 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
259259
break;
260260

261261
case NGCFlowCtrl_Do:
262-
if(sys.macro_file) {
262+
if(hal.stream.file) {
263263
if(!skipping && (status = stack_push(o_label, operation)) == Status_OK) {
264-
stack[stack_idx].file_pos = vfs_tell(sys.macro_file);
264+
stack[stack_idx].file_pos = vfs_tell(hal.stream.file);
265265
stack[stack_idx].skip = false;
266266
}
267267
} else
268268
status = Status_FlowControlNotExecutingMacro;
269269
break;
270270

271271
case NGCFlowCtrl_While:
272-
if(sys.macro_file) {
272+
if(hal.stream.file) {
273273
char *expr = line + *pos;
274274
if(stack[stack_idx].brk) {
275275
if(last_op == NGCFlowCtrl_Do && o_label == stack[stack_idx].o_label)
@@ -286,8 +286,8 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
286286
if(!(stack[stack_idx].skip = value == 0.0f)) {
287287
if((stack[stack_idx].expr = malloc(strlen(expr) + 1))) {
288288
strcpy(stack[stack_idx].expr, expr);
289-
stack[stack_idx].file = sys.macro_file;
290-
stack[stack_idx].file_pos = vfs_tell(sys.macro_file);
289+
stack[stack_idx].file = hal.stream.file;
290+
stack[stack_idx].file_pos = vfs_tell(hal.stream.file);
291291
} else
292292
status = Status_FlowControlOutOfMemory;
293293
}
@@ -298,7 +298,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
298298
break;
299299

300300
case NGCFlowCtrl_EndWhile:
301-
if(sys.macro_file) {
301+
if(hal.stream.file) {
302302
if(last_op == NGCFlowCtrl_While) {
303303
if(o_label == stack[stack_idx].o_label) {
304304
uint_fast8_t pos = 0;
@@ -316,12 +316,12 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
316316
break;
317317

318318
case NGCFlowCtrl_Repeat:
319-
if(sys.macro_file) {
319+
if(hal.stream.file) {
320320
if(!skipping && (status = ngc_eval_expression(line, pos, &value)) == Status_OK) {
321321
if((status = stack_push(o_label, operation)) == Status_OK) {
322322
if(!(stack[stack_idx].skip = value == 0.0f)) {
323-
stack[stack_idx].file = sys.macro_file;
324-
stack[stack_idx].file_pos = vfs_tell(sys.macro_file);
323+
stack[stack_idx].file = hal.stream.file;
324+
stack[stack_idx].file_pos = vfs_tell(hal.stream.file);
325325
stack[stack_idx].repeats = (uint32_t)value;
326326
}
327327
}
@@ -331,7 +331,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
331331
break;
332332

333333
case NGCFlowCtrl_EndRepeat:
334-
if(sys.macro_file) {
334+
if(hal.stream.file) {
335335
if(last_op == NGCFlowCtrl_Repeat) {
336336
if(o_label == stack[stack_idx].o_label) {
337337
if(stack[stack_idx].repeats && --stack[stack_idx].repeats)
@@ -346,7 +346,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
346346
break;
347347

348348
case NGCFlowCtrl_Break:
349-
if(sys.macro_file) {
349+
if(hal.stream.file) {
350350
if(!skipping) {
351351
while(o_label != stack[stack_idx].o_label && stack_pull());
352352
last_op = stack_idx >= 0 ? stack[stack_idx].operation : NGCFlowCtrl_NoOp;
@@ -363,7 +363,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo
363363
break;
364364

365365
case NGCFlowCtrl_Continue:
366-
if(sys.macro_file) {
366+
if(hal.stream.file) {
367367
if(!skipping) {
368368
while(o_label != stack[stack_idx].o_label && stack_pull());
369369
if(stack_idx >= 0 && o_label == stack[stack_idx].o_label) switch(stack[stack_idx].operation) {

report.c

+3
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,9 @@ void report_realtime_status (void)
12051205
axes_signals_t lim_pin_state = limit_signals_merge(hal.limits.get_state());
12061206
control_signals_t ctrl_pin_state = hal.control.get_state();
12071207

1208+
if(sys.report.cycle_start)
1209+
ctrl_pin_state.cycle_start = On;
1210+
12081211
if (lim_pin_state.value | ctrl_pin_state.value | probe_state.triggered | !probe_state.connected | sys.flags.block_delete_enabled) {
12091212

12101213
char *append = &buf[4];

state_machine.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,10 @@ bool state_door_reopened (void)
191191

192192
void state_update (rt_exec_t rt_exec)
193193
{
194-
if ((rt_exec & EXEC_SAFETY_DOOR) && sys_state != STATE_SAFETY_DOOR)
194+
if((rt_exec & EXEC_SAFETY_DOOR) && sys_state != STATE_SAFETY_DOOR)
195195
state_set(STATE_SAFETY_DOOR);
196+
else if(rt_exec & EXEC_CYCLE_START)
197+
sys.report.cycle_start = settings.status_report.pin_state;
196198

197199
stateHandler(rt_exec);
198200
}

stream.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ typedef struct {
247247
get_stream_buffer_count_ptr get_tx_buffer_count; //!< Optional handler for getting number of characters in the output buffer(s). Count shall include any unsent characters in any transmit FIFO and/or transmit register. Required for Modbus support.
248248
flush_stream_buffer_ptr reset_write_buffer; //!< Optional handler for flushing the output buffer. Any transmit FIFO shall be flushed as well. Required for Modbus support.
249249
set_baud_rate_ptr set_baud_rate; //!< Optional handler for setting the stream baud rate. Required for Modbus support, recommended for Bluetooth support.
250-
// vfs_file_t *file; //!< File handle, non-null if streaming from a file.
250+
vfs_file_t *file; //!< File handle, non-null if streaming from a file.
251251
} io_stream_t;
252252

253253
typedef const io_stream_t *(*stream_claim_ptr)(uint32_t baud_rate);

system.h

+7-8
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ typedef enum {
186186
Report_Encoder = (1 << 14),
187187
Report_TLOReference = (1 << 15),
188188
Report_Fan = (1 << 16),
189+
Report_CycleStart = (1 << 30),
189190
Report_All = 0x8001FFFF
190191
} report_tracking_t;
191192

@@ -207,17 +208,18 @@ typedef union {
207208
pwm :1, //!< Add PWM information (optional: to be added by driver).
208209
motor :1, //!< Add motor information (optional: to be added by driver).
209210
encoder :1, //!< Add encoder information (optional: to be added by driver).
210-
tlo_reference :1, //!< Tool length offset reference changed
211-
fan :1, //!< Fan on/off changed
212-
unassigned :14, //
213-
all :1; //!< Set when CMD_STATUS_REPORT_ALL is requested, may be used by user code
211+
tlo_reference :1, //!< Tool length offset reference changed.
212+
fan :1, //!< Fan on/off changed.
213+
unassigned :13, //
214+
cycle_start :1, //!< Cycle start signal triggered. __NOTE:__ do __NOT__ add to Report_All enum above!
215+
all :1; //!< Set when CMD_STATUS_REPORT_ALL is requested, may be used by user code.
214216
};
215217
} report_tracking_flags_t;
216218

217219
typedef struct {
218220
override_t feed_rate; //!< Feed rate override value in percent
219221
override_t rapid_rate; //!< Rapids override value in percent
220-
override_t spindle_rpm; //!< __NOTE:_ Not used by the core, it maintain per spindle override in \ref spindle_param_t
222+
override_t spindle_rpm; //!< __NOTE:__ Not used by the core, it maintain per spindle override in \ref spindle_param_t
221223
spindle_stop_t spindle_stop; //!< Tracks spindle stop override states
222224
gc_override_flags_t control; //!< Tracks override control states.
223225
} overrides_t;
@@ -286,9 +288,6 @@ typedef struct system {
286288
volatile rt_exec_t rt_exec_state; //!< Realtime executor bitflag variable for state management. See EXEC bitmasks.
287289
volatile uint_fast16_t rt_exec_alarm; //!< Realtime executor bitflag variable for setting various alarms.
288290
int32_t var5399; //!< Last result from M66 - wait on input.
289-
#if NGC_EXPRESSIONS_ENABLE
290-
vfs_file_t *macro_file; //!< File handle of current G65 macro executing.
291-
#endif
292291
#ifdef PID_LOG
293292
pid_data_t pid_log;
294293
#endif

vfs.c

+81-9
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ static const char *get_filename (vfs_mount_t *mount, const char *filename)
191191
{
192192
if(*filename == '/') {
193193
size_t len = strlen(mount->path);
194-
return filename + (len == 1 ? 0 : len);
194+
return filename + (len == 1 ? 0 : len - 1);
195195
} else
196196
return filename;
197197
}
@@ -306,8 +306,18 @@ int vfs_chdir (const char *path)
306306
*s = '\0';
307307
}
308308
} else {
309+
309310
strcpy(cwd, path);
310-
cwdmount = get_mount(cwd);
311+
312+
if((cwdmount = get_mount(path)) && strchr(path + 1, '/') == NULL && cwdmount != &root) {
313+
314+
strcpy(cwd, cwdmount->path);
315+
char *s;
316+
if((s = strrchr(cwd, '/')))
317+
*s = '\0';
318+
319+
return 0;
320+
}
311321
}
312322

313323
if((ret = cwdmount ? cwdmount->vfs->fchdir(path) : -1) != 0) { // + strlen(mount->path));))
@@ -322,10 +332,30 @@ int vfs_chdir (const char *path)
322332
vfs_dir_t *vfs_opendir (const char *path)
323333
{
324334
vfs_dir_t *dir = NULL;
325-
vfs_mount_t *mount = get_mount(path);
335+
vfs_mount_t *mount = get_mount(path), *add_mount;
336+
vfs_mount_ll_entry_t *ml = NULL, *mln;
337+
338+
if(mount && (dir = mount->vfs->fopendir(get_filename(mount, path)))) {
326339

327-
if(mount && (dir = mount->vfs->fopendir(get_filename(mount, path))))
328340
dir->fs = mount->vfs;
341+
dir->mounts = NULL;
342+
add_mount = root.next;
343+
344+
do {
345+
if(add_mount != mount && !strncmp(add_mount->path, path, strlen(path))) {
346+
if(!add_mount->vfs->mode.hidden && (mln = malloc(sizeof(vfs_mount_ll_entry_t)))) {
347+
mln->mount = add_mount;
348+
mln->next = NULL;
349+
if(dir->mounts == NULL)
350+
dir->mounts = ml = mln;
351+
else {
352+
ml->next = mln;
353+
ml = mln;
354+
}
355+
}
356+
}
357+
} while((add_mount = add_mount->next));
358+
}
329359

330360
return dir;
331361
}
@@ -338,36 +368,78 @@ vfs_dirent_t *vfs_readdir (vfs_dir_t *dir)
338368

339369
((vfs_t *)dir->fs)->readdir(dir, &dirent);
340370

371+
if(*dirent.name == '\0' && dir->mounts) {
372+
373+
char *s;
374+
vfs_mount_ll_entry_t *ml = dir->mounts;
375+
376+
strcpy(dirent.name, ml->mount->path + 1);
377+
if((s = strrchr(dirent.name, '/')))
378+
*s = '\0';
379+
380+
dirent.st_mode = ml->mount->vfs->mode;
381+
dirent.st_mode.directory = true;
382+
dir->mounts = dir->mounts->next;
383+
free(ml);
384+
}
385+
341386
return *dirent.name == '\0' ? NULL : &dirent;
342387
}
343388

344389
void vfs_closedir (vfs_dir_t *dir)
345390
{
346391
vfs_errno = 0;
347392

393+
while(dir->mounts) {
394+
vfs_mount_ll_entry_t *ml = dir->mounts;
395+
dir->mounts = dir->mounts->next;
396+
free(ml);
397+
}
398+
348399
((vfs_t *)dir->fs)->fclosedir(dir);
349400
}
350401

351402
char *vfs_getcwd (char *buf, size_t len)
352403
{
353-
char *cwd = root.vfs->fgetcwd(NULL, len);
404+
char *cwds = cwdmount->vfs->fgetcwd ? cwdmount->vfs->fgetcwd(NULL, len) : cwd;
354405

355406
vfs_errno = 0;
356407

357408
if(buf == NULL)
358-
buf = (char *)malloc(strlen(cwd) + 1);
409+
buf = (char *)malloc(strlen(cwds) + 1);
359410

360411
if(buf)
361-
strcpy(buf, cwd);
412+
strcpy(buf, cwds);
362413

363-
return buf ? buf : cwd;
414+
return buf ? buf : cwds;
364415
}
365416

366417
int vfs_stat (const char *filename, vfs_stat_t *st)
367418
{
368419
vfs_mount_t *mount = get_mount(filename);
369420

370-
return mount ? mount->vfs->fstat(get_filename(mount, filename), st) : -1;
421+
int ret = mount ? mount->vfs->fstat(get_filename(mount, filename), st) : -1;
422+
423+
if(ret == -1 && strchr(filename, '/') == NULL && !strcmp("/", cwd)) {
424+
425+
strcat(cwd, filename);
426+
mount = get_mount(cwd);
427+
cwd[1] = '\0';
428+
429+
if(mount) {
430+
st->st_size = 0;
431+
st->st_mode.mode = 0;
432+
st->st_mode.directory = true;
433+
#if defined(ESP_PLATFORM)
434+
st->st_mtim = (time_t)0;
435+
#else
436+
st->st_mtime = (time_t)0;
437+
#endif
438+
ret = 0;
439+
}
440+
}
441+
442+
return ret;
371443
}
372444

373445
int vfs_utime (const char *filename, struct tm *modified)

0 commit comments

Comments
 (0)