Added $RTC system command for outputting or setting current real time clock date and time. Uses ISO8601 format.

Driver developers: check the changelog!
This commit is contained in:
Terje Io
2022-09-07 21:08:11 +02:00
parent e009f47116
commit 180f9fa9fc
21 changed files with 282 additions and 44 deletions

View File

@@ -5,7 +5,7 @@ target_sources(grbl INTERFACE
${CMAKE_CURRENT_LIST_DIR}/coolant_control.c
${CMAKE_CURRENT_LIST_DIR}/nvs_buffer.c
${CMAKE_CURRENT_LIST_DIR}/gcode.c
${CMAKE_CURRENT_LIST_DIR}/limits.c
${CMAKE_CURRENT_LIST_DIR}/machine_limits.c
${CMAKE_CURRENT_LIST_DIR}/motion_control.c
${CMAKE_CURRENT_LIST_DIR}/my_plugin.c
${CMAKE_CURRENT_LIST_DIR}/nuts_bolts.c

View File

@@ -11,7 +11,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
---
Latest build date is 20220904, see the [changelog](changelog.md) for details.
Latest build date is 20220907, see the [changelog](changelog.md) for details.
__NOTE:__ A settings reset will be performed on an update for versions earlier than 20211122. Backup and restore of settings is recommended.
__IMPORTANT!__ A new setting has been introduced for ganged axes motors in version 20211121.
I have only bench tested this for a couple of drivers, correct function should be verified after updating by those who have more than three motors configured.
@@ -84,4 +84,4 @@ List of Supported G-Codes:
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
---
2022-09-04
2022-09-07

View File

@@ -1,20 +1,46 @@
## grblHAL changelog
20220905:
Core:
* Added `$RTC` system command for outputting or setting current real time clock date and time. Uses ISO8601 format.
__Driver developers:__
_grbl/limits.h_ has been renamed to _grbl/machine_limits.h_ (along with the _.c_ counterpart).
[hal.enumerate_pins](http://svn.io-engineering.com/grblHAL/html/structgrbl__hal__t.html#a661c9aa458a2e6fc5fb1657e121999a3) and the associated [callback function](http://svn.io-engineering.com/grblHAL/html/hal_8h.html#a41e902cfc3da615f9494aba956d895ba) parameter has a new signature, a void pointer has been added. Driver implementations should pass this on to the callback.
The HAL version number has been increased to 10 due to this, update _driver.c_ to match!
Plugins:
* WebUI: added many ESP commands to v3 command handler, some code refactoring. Still WIP.
* Networking: some minor bug fixes.
Drivers:
* All: updated for _grbl/limits.h_ name change and HAL version number increase.
* iMXRT1062, STM32F4xx, STM32F7xx and ESP32: Added RTC support.
* ESP32: WebUI backend support improved.
---
20220904:
Core:
* Added optional RTC (Real Time Clock) support to the HAL. VFS improvements.
* Added optional RTC \(Real Time Clock\) support to the HAL. VFS improvements.
Plugins:
* Networking: improved websocket protocol handling.
* Networking: improved websocket subprotocol handling.
* WebUI: separated command handlers for v2 and v3 and improved detection of v3 clients. Now sets RTC from ESP800 if HAL allows.
Drivers:
* RP2040: Added RTC support++.
* RP2040: Added RTC support++.
* iMXRT1062: updated uSDFS patch - needed for VFS changes.

2
grbl.h
View File

@@ -34,7 +34,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20220904
#define GRBL_BUILD 20220906
// The following symbols are set here if not already set by the compiler or in config.h
// Do NOT change here!

View File

@@ -30,7 +30,7 @@
#include "tool_change.h"
#include "override.h"
#include "protocol.h"
#include "limits.h"
#include "machine_limits.h"
#include "report.h"
#include "state_machine.h"
#include "nvs_buffer.h"

10
hal.h
View File

@@ -40,7 +40,7 @@
#include "ioports.h"
#include "plugins.h"
#define HAL_VERSION 9
#define HAL_VERSION 10
/// Bitmap flags for driver capabilities, to be set by driver in driver_init(), flags may be cleared after to switch off option.
typedef union {
@@ -104,14 +104,15 @@ typedef struct {
/*! \brief Pointer to callback function for pin enumerations.
\param pin pointer to the \a xbar_t structure holding the pin information.
*/
typedef void (*pin_info_ptr)(xbar_t *pin);
typedef void (*pin_info_ptr)(xbar_t *pin, void *data);
/*! \brief Pointer to function for enumerate pin information.
\param low_level true if low level information is required, false if used for reporting.
\param callback pointer to a \a pin_info_ptr type function to receive the pin information.
The callback function will be called for each pin.
*/
typedef void (*enumerate_pins_ptr)(bool low_level, pin_info_ptr callback);
typedef void (*enumerate_pins_ptr)(bool low_level, pin_info_ptr callback, void *data);
/*************
* Coolant *
@@ -359,6 +360,7 @@ typedef struct {
probe_connected_toggle_ptr connected_toggle; //!< Optional handler for toggling probe connected status.
} probe_ptrs_t;
/*******************************
* Tool selection and change *
*******************************/
@@ -385,6 +387,7 @@ typedef struct {
tool_change_ptr change; //!< Optional handler for executing a tool change (M6).
} tool_ptrs_t;
/*****************
* User M-code *
*****************/
@@ -439,6 +442,7 @@ typedef struct {
user_mcode_execute_ptr execute; //!< Handler for executing a user defined M-code.
} user_mcode_ptrs_t;
/*******************
* Encoder input *
*******************/

View File

@@ -1,5 +1,5 @@
/*
limits.c - code pertaining to limit-switches and performing the homing cycle
machine_limits.c - code pertaining to limit-switches and performing the homing cycle
Part of grblHAL
@@ -29,7 +29,7 @@
#include "nuts_bolts.h"
#include "protocol.h"
#include "motion_control.h"
#include "limits.h"
#include "machine_limits.h"
#include "tool_change.h"
#include "state_machine.h"
#ifdef KINEMATICS_API

View File

@@ -1,9 +1,9 @@
/*
limits.h - code pertaining to limit-switches and performing the homing cycle
machine_limits.h - code pertaining to limit-switches and performing the homing cycle
Part of grblHAL
Copyright (c) 2017-2018 Terje Io
Copyright (c) 2017-2022 Terje Io
Copyright (c) 2012-2015 Sungeun K. Jeon
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -21,8 +21,8 @@
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _LIMITS_H_
#define _LIMITS_H_
#ifndef _MACHINE_LIMITS_H_
#define _MACHINE_LIMITS_H_
#include "nuts_bolts.h"

View File

@@ -32,7 +32,7 @@
#include "hal.h"
#include "nuts_bolts.h"
#include "protocol.h"
#include "limits.h"
#include "machine_limits.h"
#include "state_machine.h"
#include "motion_control.h"
#include "tool_change.h"

View File

@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2021 Terje Io
Copyright (c) 2017-2022 Terje Io
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -24,6 +24,8 @@
#include <math.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include "hal.h"
#include "protocol.h"
@@ -263,6 +265,66 @@ float convert_delta_vector_to_unit_vector (float *vector)
return magnitude;
}
// parse ISO8601 datetime: YYYY-MM-DDTHH:MM:SSZxxx
struct tm *get_datetime (const char *s)
{
static struct tm dt;
PROGMEM static const uint8_t mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char *s1 = (char *)s, c;
uint_fast16_t idx = 0, value = 0;
memset(&dt, 0, sizeof(struct tm));
dt.tm_year = dt.tm_mon = dt.tm_mday = dt.tm_hour = dt.tm_min = dt.tm_sec = -1;
do {
c = *s1++;
if(isdigit(c))
value = (value * 10) + c - '0';
else if(!(c == '-' || c == ':' || c == 'T' || c == 'Z' || c == '\0'))
break;
else {
switch(idx) {
case 0:
if(c == '-' && value >= 1970 && value <= 2099)
dt.tm_year = value - 1900;
break;
case 1:
if(c == '-' && value >= 1 && value <= 12)
dt.tm_mon = value - 1;
break;
case 2:
if(c == 'T' && value >= 1 && value <= (mdays[dt.tm_mon >= 0 ? dt.tm_mon : 0] + (dt.tm_mon == 1 && dt.tm_year != 100 && (dt.tm_year % 4) == 0 ? 1 : 0)))
dt.tm_mday = value;
break;
case 3:
if(c == ':' && value <= 23)
dt.tm_hour = value;
break;
case 4:
if(c == ':' && value <= 59)
dt.tm_min = value;
break;
case 5:
if((c == 'Z' || c == '\0') && value <= 59)
dt.tm_sec = value;
break;
}
idx++;
value = 0;
}
} while(c);
return (dt.tm_year | dt.tm_mon | dt.tm_mday | dt.tm_hour | dt.tm_min | dt.tm_sec) > 0 ? &dt : NULL;
}
// calculate checksum byte for data
uint8_t calc_checksum (uint8_t *data, uint32_t size) {

View File

@@ -206,6 +206,9 @@ void delay_sec(float seconds, delaymode_t mode);
float convert_delta_vector_to_unit_vector(float *vector);
// parse ISO8601 datetime
struct tm *get_datetime (const char *s);
// calculate checksum byte for data
uint8_t calc_checksum (uint8_t *data, uint32_t size);

View File

@@ -67,6 +67,7 @@ typedef union {
typedef char ssid_t[65];
typedef char password_t[33];
typedef char hostname_t[33];
typedef char sntp_server_t[129]; // URI
typedef struct {
char ip[16];

View File

@@ -32,7 +32,7 @@
#include "motion_control.h"
#include "sleep.h"
#include "protocol.h"
#include "limits.h"
#include "machine_limits.h"
#ifndef RT_QUEUE_SIZE
#define RT_QUEUE_SIZE 8 // must be a power of 2

View File

@@ -36,7 +36,7 @@
#include "hal.h"
#include "report.h"
#include "nvs_buffer.h"
#include "limits.h"
#include "machine_limits.h"
#include "state_machine.h"
#include "regex.h"
@@ -842,6 +842,8 @@ void report_execute_startup_message (char *line, status_code_t status_code)
// Prints build info line
void report_build_info (char *line, bool extended)
{
char buf[100];
hal.stream.write("[VER:" GRBL_VERSION ".");
hal.stream.write(uitoa(GRBL_BUILD));
hal.stream.write(":");
@@ -997,6 +999,9 @@ void report_build_info (char *line, bool extended)
strcat(buf, "SED,");
#endif
if(hal.rtc.get_datetime)
strcat(buf, "RTC,");
#ifdef PID_LOG
strcat(buf, "PID,");
#endif
@@ -2072,7 +2077,7 @@ static const char *get_pinname (pin_function_t function)
return name ? name : "N/A";
}
static void report_pin (xbar_t *pin)
static void report_pin (xbar_t *pin, void *data)
{
hal.stream.write("[PIN:");
if(pin->port)
@@ -2090,11 +2095,40 @@ static void report_pin (xbar_t *pin)
status_code_t report_pins (sys_state_t state, char *args)
{
if(hal.enumerate_pins)
hal.enumerate_pins(false, report_pin);
hal.enumerate_pins(false, report_pin, NULL);
return Status_OK;
}
static void print_uito2a (char *prefix, uint32_t v)
{
hal.stream.write(prefix);
if(v < 10)
hal.stream.write("0");
hal.stream.write(uitoa(v));
}
status_code_t report_time (void)
{
bool ok = false;
if(hal.rtc.get_datetime) {
struct tm time;
if((ok = !!hal.rtc.get_datetime(&time))) {
hal.stream.write("[RTC:");
hal.stream.write(uitoa(time.tm_year + 1900));
print_uito2a("-", time.tm_mon + 1);
print_uito2a("-", time.tm_mday);
print_uito2a("T", time.tm_hour);
print_uito2a(":", time.tm_min);
print_uito2a(":", time.tm_sec);
hal.stream.write("]" ASCII_EOL);
}
}
return ok ? Status_OK : Status_InvalidStatement;
}
void report_pid_log (void)
{
#ifdef PID_LOG

View File

@@ -117,6 +117,9 @@ status_code_t report_spindle_data (sys_state_t state, char *args);
// Prints pin assignments
status_code_t report_pins (sys_state_t state, char *args);
// Prints current RTC datetime in ISO8601 format (when available)
status_code_t report_time (void);
// Prints current PID log.
void report_pid_log (void);

View File

@@ -29,7 +29,7 @@
#include "hal.h"
#include "defaults.h"
#include "limits.h"
#include "machine_limits.h"
#include "nvs_buffer.h"
#include "tool_change.h"
#include "state_machine.h"

View File

@@ -197,6 +197,11 @@ typedef enum {
Setting_AdminPassword = 330,
Setting_UserPassword = 331,
Setting_NTPServerURI = 332,
Setting_NTPServerURI_2 = 333,
Setting_NTPServerURI_3 = 334,
Setting_Timezone = 335,
Setting_DSTActive = 336,
Setting_TrinamicDriver = 338,
Setting_TrinamicHoming = 339,
@@ -344,7 +349,7 @@ typedef union {
struct {
uint16_t report_inches :1,
restore_overrides :1,
unused0 :1,
dst_active :1, // Daylight savings time
sleep_enable :1,
disable_laser_during_hold :1,
force_initialization_alarm :1,

View File

@@ -82,8 +82,8 @@ typedef enum {
StreamType_Bluetooth,
StreamType_Telnet,
StreamType_WebSocket,
StreamType_SDCard,
StreamType_FlashFs,
StreamType_SDCard, // deprecated, use StreamType_File instead
StreamType_File = StreamType_SDCard,
StreamType_Redirected,
StreamType_Null
} stream_type_t;

View File

@@ -28,7 +28,7 @@
#include "protocol.h"
#include "tool_change.h"
#include "state_machine.h"
#include "limits.h"
#include "machine_limits.h"
#ifdef KINEMATICS_API
#include "kinematics.h"
#endif
@@ -79,6 +79,7 @@ static status_code_t settings_reset (sys_state_t state, char *args);
static status_code_t output_startup_lines (sys_state_t state, char *args);
static status_code_t set_startup_line0 (sys_state_t state, char *args);
static status_code_t set_startup_line1 (sys_state_t state, char *args);
static status_code_t rtc_action (sys_state_t state, char *args);
#ifdef DEBUGOUT
static status_code_t output_memmap (sys_state_t state, char *args);
#endif
@@ -232,6 +233,7 @@ PROGMEM static const sys_command_t sys_commands[] = {
{ "LIM", true, report_current_limit_state },
{ "SD", false, report_spindle_data },
{ "SR", false, spindle_reset_data },
{ "RTC", false, rtc_action },
#ifdef DEBUGOUT
{ "Q", true, output_memmap },
#endif
@@ -286,6 +288,10 @@ void system_command_help (void)
hal.stream.write("$PINS - enumerate pin bindings" ASCII_EOL);
hal.stream.write("$LEV - output last control signal events" ASCII_EOL);
hal.stream.write("$LIM - output current limit pins state" ASCII_EOL);
if(hal.rtc.get_datetime) {
hal.stream.write("$RTC - output current time" ASCII_EOL);
hal.stream.write("$RTC=<ISO8601 datetime> - set current time" ASCII_EOL);
}
#ifndef NO_SETTINGS_DESCRIPTIONS
hal.stream.write("$SED=<n> - output settings description for setting <n>" ASCII_EOL);
#endif
@@ -869,6 +875,24 @@ static status_code_t set_startup_line1 (sys_state_t state, char *args)
return set_startup_line(state, args, 1);
}
static status_code_t rtc_action (sys_state_t state, char *args)
{
status_code_t retval = Status_OK;
if(args) {
struct tm *time = get_datetime(args);
if(time)
hal.rtc.set_datetime(time);
else
retval = Status_BadNumberFormat;
} else
retval = report_time();
return retval;
}
#ifdef DEBUGOUT
#include "nvs_buffer.h"

83
vfs.c
View File

@@ -101,6 +101,9 @@ static char *fs_getcwd (char *buf, size_t size)
}
static const vfs_t fs_null = {
.mode.directory = true,
.mode.hidden = true,
.mode.read_only = true,
.fopen = fs_open,
.fclose = fs_close,
.fread = fs_read,
@@ -412,19 +415,73 @@ bool vfs_unmount (const char *path)
return true;
}
#endif
/*
struct tm *gmtime (const time_t *c_t)
vfs_drives_t *vfs_drives_open (void)
{
static struct tm dummy = {
.tm_year = 70,
.tm_mon = 0,
.tm_mday = 1,
.tm_hour = 0,
.tm_min = 0
};
vfs_drives_t *handle;
vfs_mount_t *mount = &root;
return &dummy;
if((handle = malloc(sizeof(vfs_drives_t)))) {
handle->mount = NULL;
do {
if(mount->vfs->mode.hidden)
mount = mount->next;
else
handle->mount = mount;
} while(mount && handle->mount == NULL);
if(handle->mount == NULL) {
free(handle);
handle = NULL;
}
}
return handle;
}
*/
vfs_drive_t *vfs_drives_read (vfs_drives_t *handle)
{
static vfs_drive_t drive;
bool ok;
if((ok = handle->mount != NULL)) {
drive.name = handle->mount->vfs->fs_name;
drive.path = (const char *)handle->mount->path;
drive.mode = handle->mount->vfs->mode;
drive.fs = handle->mount->vfs;
handle->mount = handle->mount->next;
if(handle->mount) do {
if(!handle->mount->vfs->mode.hidden && handle->mount->vfs->fs_name)
break;
} while((handle->mount = handle->mount->next));
}
return ok ? &drive : NULL;
}
void vfs_drives_close (vfs_drives_t *handle)
{
free(handle);
}
vfs_free_t *vfs_drive_getfree (vfs_drive_t *drive)
{
static vfs_free_t free;
const vfs_t *fs = drive->fs;
return fs->fgetfree && fs->fgetfree(&free) ? &free : NULL;
}
int vfs_drive_format (vfs_drive_t *drive)
{
const vfs_t *fs = drive->fs;
return fs->format ? fs->format() : -1;
}
#endif

25
vfs.h
View File

@@ -92,8 +92,8 @@ typedef struct {
} vfs_dirent_t;
typedef struct {
uint64_t size;
uint64_t used;
size_t size;
size_t used;
} vfs_free_t;
typedef struct {
@@ -123,6 +123,7 @@ typedef int (*vfs_stat_ptr)(const char *filename, vfs_stat_t *st);
typedef int (*vfs_utime_ptr)(const char *filename, struct tm *modified);
typedef bool (*vfs_getfree_ptr)(vfs_free_t *free);
typedef int (*vfs_format_ptr)(void);
typedef struct
{
@@ -147,6 +148,7 @@ typedef struct
vfs_utime_ptr futime;
vfs_getcwd_ptr fgetcwd;
vfs_getfree_ptr fgetfree;
vfs_format_ptr format;
} vfs_t;
typedef struct vfs_mount
@@ -156,6 +158,17 @@ typedef struct vfs_mount
struct vfs_mount *next;
} vfs_mount_t;
typedef struct {
vfs_mount_t *mount;
} vfs_drives_t;
typedef struct {
const char *name;
const char *path;
vfs_st_mode_t mode;
const void *fs;
} vfs_drive_t;
extern int vfs_errno;
char *vfs_fixpath (char *path);
@@ -183,4 +196,10 @@ int vfs_stat (const char *filename, vfs_stat_t *st);
int vfs_utime (const char *filename, struct tm *modified);
vfs_free_t *vfs_fgetfree (const char *path);
#endif
vfs_drives_t *vfs_drives_open (void);
vfs_drive_t *vfs_drives_read (vfs_drives_t *handle);
void vfs_drives_close (vfs_drives_t *handle);
vfs_free_t *vfs_drive_getfree (vfs_drive_t *drive);
int vfs_drive_format (vfs_drive_t *drive);
#endif // INCLUDE_VFS_H