Revised core setting structures, changed from 8-bit to 16-bit CRC checksums for improved detection of corruption/version mismatches.

Added option to homing enable setting ($22) for per axis homing feedrates.

!! Backup and restore settings over an update is recommended since all settings will be reset to default. Any odometer data will also be lost.
This commit is contained in:
Terje Io
2024-12-09 19:24:20 +01:00
parent 795ced52f7
commit a41790dada
25 changed files with 1251 additions and 833 deletions
+1
View File
@@ -4,6 +4,7 @@ target_sources(grbl INTERFACE
${CMAKE_CURRENT_LIST_DIR}/grbllib.c
${CMAKE_CURRENT_LIST_DIR}/coolant_control.c
${CMAKE_CURRENT_LIST_DIR}/crossbar.c
${CMAKE_CURRENT_LIST_DIR}/crc.c
${CMAKE_CURRENT_LIST_DIR}/nvs_buffer.c
${CMAKE_CURRENT_LIST_DIR}/gcode.c
${CMAKE_CURRENT_LIST_DIR}/machine_limits.c
+19 -20
View File
@@ -1,32 +1,31 @@
## grblHAL ##
__New:__ A web app for [building for some drivers](http://svn.io-engineering.com:8080/) is now available, feedback will be appreciated.
Latest build date is 20241208, see the [changelog](changelog.md) for details.
grblHAL has [many extensions](https://github.com/grblHAL/core/wiki) that may cause issues with some senders. As a workaround for these a [compile time option](https://github.com/grblHAL/core/wiki/Changes-from-grbl-1.1#workaround) has been added that disables extensions selectively.
> [!NOTE]
> A settings reset will be performed on an update of builds prior to 20241208. Backup and restore of settings is recommended.
__IMPORTANT!__ grblHAL defaults to normally closed \(NC\) switches for inputs, if none are connected when testing it is likely that the controller will start in alarm mode.
Temporarily short the Reset, E-Stop and Safety Door<sup>4</sup> inputs to ground or invert the corresponding inputs by setting `$14=73` to avoid that.
Please check out [this Wiki page](https://github.com/grblHAL/core/wiki/Changes-from-grbl-1.1) for additional important information.
> [!NOTE]
> Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.
---
A web app for [building for some drivers](http://svn.io-engineering.com:8080/) is now available, feedback will be appreciated.
grblHAL has [many extensions](https://github.com/grblHAL/core/wiki) that may cause issues with some senders.
As a workaround for these a [compile time option](https://github.com/grblHAL/core/wiki/Changes-from-grbl-1.1#workaround) has been added that disables extensions selectively.
> [!NOTE]
> grblHAL defaults to normally closed \(NC\) switches for inputs, if none are connected when testing it is likely that the controller will start in alarm mode.
> Temporarily short the Reset, E-Stop and Safety Door<sup>4</sup> inputs to ground or invert the corresponding inputs by setting `$14=73` to avoid that.
> Please check out [this Wiki page](https://github.com/grblHAL/core/wiki/Changes-from-grbl-1.1) for additional important information.
Windows users may try [ioSender](https://github.com/terjeio/Grbl-GCode-Sender), binary releases can be found [here](https://github.com/terjeio/Grbl-GCode-Sender/releases).
It has been written to complement grblHAL and has features such as proper keyboard jogging, advanced probing, automatic reconfiguration of DRO display for up to 6 axes, lathe mode including conversational G-Code generation, 3D rendering, macro support etc. etc.
---
Latest build date is 20241120, see the [changelog](changelog.md) for details.
__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.
__NOTE:__ A settings reset will be performed on an update of builds earlier than 20230125. Backup and restore of settings is recommended.
---
Updated for latest core changes.
__NOTE:__ Arduino drivers has now been converted to Arduino libraries, [installation and compilation procedure](https://github.com/grblHAL/core/wiki/Compiling-GrblHAL) has been changed!
---
grblHAL is a no-compromise, high performance, low cost alternative to parallel-port-based motion control for CNC milling and is based on the [Arduino version of grbl](https://github.com/gnea/grbl). It is mainly aimed at ARM processors \(or other 32-bit MCUs\) with ample amounts of RAM and flash \(compared to AVR 328p\) and requires a [hardware driver](https://github.com/grblHAL/drivers) to be functional.
Currently drivers are available for more than 15 different processors/processor families all of which share the same core codebase.
@@ -94,4 +93,4 @@ G/M-codes not supported by [legacy Grbl](https://github.com/gnea/grbl/wiki) are
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
---
20241120
20241209
+29 -1
View File
@@ -1,10 +1,38 @@
## grblHAL changelog
<a name="20241208"> Build 20241208
Core:
* Revised core setting structures, changed from 8-bit to 16-bit CRC checksums for improved detection of corruption/version mismatches.
__NOTE:__ Backup and restore settings over an update since _all_ settings will be reset to default. Any odometer data will also be lost.
* Added option to homing enable setting (`$22`) for per axis homing feedrates.
When this option is selected setting `$24` and $`25` will be disabled and new axis settings made available;
`$18<n>` replaces `$24` and `$19<n>` replaces `$25`. `<n>` is the axis number; `0` for X, `1` for Y, ...
__NOTE:__ if axes are set up for simultaneous homing and they do not have the same feedrates they will be homed separately.
__NOTE:__ `$18<n>` and `$19<n>` were previousely implemented by the Trinamic motor plugin, the implementation is now in the core.
__NOTE:__ core settings will now overflow the legacy 1024 byte boundary when > 5 axes are configured, in the previous version when > 6 axes were configured..
Drivers:
* All: updated for the revised settings structures.
* iMXRT1062, RP2040 and SAM3X8E: improved step injection option used by the Plasma plugin and stepper spindle option.
* RP2040: tuning for the new RP2350 MCU, fixes step timings.
Plugins:
* Some updated for the revised settings structures.
---
<a name="20241205"> 20241205
Drivers:
* RP2040: initial support for RP2350 \(Pico 2\) added.
* RP2040: initial support for RP2350 \(Pico 2\) added to Web Builder.
Plugins:
+11 -5
View File
@@ -1,22 +1,23 @@
/*
coolant_control.h - spindle control methods
coolant_control.h - coolant control methods
Part of grblHAL
Copyright (c) 2017-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
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _COOLANT_CONTROL_H_
@@ -35,6 +36,11 @@ typedef union {
};
} coolant_state_t;
typedef struct {
coolant_state_t invert;
uint16_t on_delay;
} coolant_settings_t;
// Sets the coolant pins according to state specified.
void coolant_set_state(coolant_state_t mode);
+73
View File
@@ -0,0 +1,73 @@
/*
crc.c - crc implementations used by grblHAL
Part of grblHAL
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
uint16_t grbl_crc8 (const uint8_t *buf, uint32_t size)
{
uint8_t checksum = 0;
while(size--) {
checksum = (checksum << 1) | (checksum >> 7);
checksum += *(buf++);
}
return (uint16_t)checksum;
}
// Copyright (c) 2006 Christian Walter <wolti@sil.at>
// Lifted from his FreeModbus Libary
uint16_t modbus_crc16x (const uint8_t *buf, uint_fast16_t len)
{
uint16_t crc = 0xFFFF;
uint_fast8_t pos, i;
for (pos = 0; pos < len; pos++) {
crc ^= (uint16_t)buf[pos]; // XOR byte into least sig. byte of crc
for (i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
} else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
return crc;
}
// Fast CRC16 implementation
// Original Code: Ashley Roll
// Optimisations: Scott Dattalo
// From http://www.ccsinfo.com/forum/viewtopic.php?t=24977
uint16_t ccitt_crc16 (const uint8_t *buf, uint_fast16_t len)
{
uint16_t x, crc = 0;
while(len--) {
x = (crc >> 8) ^ *buf++;
x ^= x >> 4;
crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ x;
}
return crc;
}
+26
View File
@@ -0,0 +1,26 @@
/*
crc.h - crc implementations used by grblHAL
Part of grblHAL
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
uint16_t grbl_crc8 (const uint8_t *data, uint32_t size);
uint16_t modbus_crc16x (const uint8_t *buf, uint_fast16_t len);
uint16_t ccitt_crc16 (const uint8_t *buf, uint_fast16_t len);
+10 -4
View File
@@ -30,6 +30,12 @@
#include "hal.h"
#include "nuts_bolts.h"
#ifdef OPTS_POSTPROCESSING
#define NO_OPTS_POST 0
#else
#define NO_OPTS_POST 1
#endif
#ifndef X_GANGED
#define X_GANGED 0
#endif
@@ -107,7 +113,7 @@
#undef I2C_STROBE_ENABLE
#endif
#define I2C_STROBE_ENABLE 1
#elif KEYPAD_ENABLE == 2 && !defined(KEYPAD_STREAM)
#elif NO_OPTS_POST && KEYPAD_ENABLE == 2 && !defined(KEYPAD_STREAM)
#if USB_SERIAL_CDC
#define KEYPAD_STREAM 0
#else
@@ -123,7 +129,7 @@
#define MPG_ENABLE 0
#endif
#if MPG_ENABLE && !defined(MPG_STREAM)
#if NO_OPTS_POST && MPG_ENABLE && !defined(MPG_STREAM)
#if USB_SERIAL_CDC
#define MPG_STREAM 0
#else
@@ -172,7 +178,7 @@
#ifndef TRINAMIC_UART_ENABLE
#define TRINAMIC_UART_ENABLE 1
#endif
#if !defined(TRINAMIC_STREAM) && TRINAMIC_UART_ENABLE == 1
#if NO_OPTS_POST && !defined(TRINAMIC_STREAM) && TRINAMIC_UART_ENABLE == 1
#define TRINAMIC_STREAM 1
#endif
#else
@@ -226,7 +232,7 @@
#endif
#ifndef SPINDLE0_ENABLE
#define SPINDLE0_ENABLE SPINDLE_PWM0
#define SPINDLE0_ENABLE DEFAULT_SPINDLE
#endif
#ifndef SPINDLE1_ENABLE
+149
View File
@@ -0,0 +1,149 @@
/*
driver_opts2.h - for preprocessing options from my_machine.h, compiler symbols or from the board map file
NOTE: This file is not used by the core, it may be included by drivers after the map file is included
Part of grblHAL
Copyright (c) 2024 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
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
//
// NOTE: do NOT change options here - edit the driver specific my_machine.h instead!
//
#if DRIVER_SPINDLE_ENABLE && !defined(SPINDLE_ENABLE_PIN)
#warning "Selected spindle is not supported!"
#undef DRIVER_SPINDLE_ENABLE
#define DRIVER_SPINDLE_ENABLE 0
#endif
#if DRIVER_SPINDLE_DIR_ENABLE && !defined(SPINDLE_DIRECTION_PIN)
#warning "Selected spindle is not fully supported - no direction output!"
#undef DRIVER_SPINDLE_DIR_ENABLE
#define DRIVER_SPINDLE_DIR_ENABLE 0
#endif
#if DRIVER_SPINDLE_PWM_ENABLE && (!DRIVER_SPINDLE_ENABLE || !defined(SPINDLE_PWM_PIN))
#warning "Selected spindle is not supported!"
#undef DRIVER_SPINDLE_PWM_ENABLE
#define DRIVER_SPINDLE_PWM_ENABLE 0
#endif
#if DRIVER_SPINDLE_PWM1_ENABLE && (!DRIVER_SPINDLE1_ENABLE || !defined(SPINDLE1_PWM_PIN))
#warning "Selected spindle 1 is not supported!"
#undef DRIVER_SPINDLE_PWM1_ENABLE
#define DRIVER_SPINDLE_PWM1_ENABLE 0
#endif
#if MPG_ENABLE == 1 && !defined(MPG_MODE_PIN)
#error "MPG_MODE_PIN must be defined!"
#endif
#if KEYPAD_ENABLE == 1 && !defined(I2C_STROBE_PORT)
#error Keypad plugin not supported!
#elif I2C_STROBE_ENABLE && !defined(I2C_STROBE_PORT)
#error I2C strobe not supported!
#endif
#if EEPROM_ENABLE == 0
#define FLASH_ENABLE 1
#else
#define FLASH_ENABLE 0
#endif
#if TRINAMIC_ENABLE
#include "motors/trinamic.h"
#ifndef TRINAMIC_MIXED_DRIVERS
#define TRINAMIC_MIXED_DRIVERS 1
#endif
#if TRINAMIC_UART_ENABLE == 1 && !defined(TRINAMIC_STREAM)
#define TRINAMIC_STREAM 1
#endif
#endif
#if USB_SERIAL_CDC && defined(SERIAL_PORT)
#define SP0 1
#else
#define SP0 0
#endif
#ifdef SERIAL1_PORT
#define SP1 1
#else
#define SP1 0
#endif
#ifdef SERIAL2_PORT
#define SP2 1
#else
#define SP2 0
#endif
#if MODBUS_ENABLE & MODBUS_RTU_ENABLED
#define MODBUS_TEST 1
#else
#define MODBUS_TEST 0
#endif
#if TRINAMIC_ENABLE && TRINAMIC_UART_ENABLE == 1
#define TRINAMIC_TEST 1
#else
#define TRINAMIC_TEST 0
#endif
#if KEYPAD_ENABLE == 2 && MPG_ENABLE == 0
#define KEYPAD_TEST 1
#else
#define KEYPAD_TEST 0
#endif
#if (MODBUS_TEST + KEYPAD_TEST + (MPG_ENABLE ? 1 : 0) + TRINAMIC_TEST + (BLUETOOTH_ENABLE == 2 ? 1 : 0)) > (SP0 + SP1 + SP2)
#error "Too many options that uses a serial port are enabled!"
#endif
#undef SP0
#undef SP1
#undef SP2
#undef MODBUS_TEST
#undef KEYPAD_TEST
#undef TRINAMIC_TEST
#if KEYPAD_ENABLE == 2 && !defined(KEYPAD_STREAM)
#if USB_SERIAL_CDC
#define KEYPAD_STREAM 0
#else
#define KEYPAD_STREAM 1
#endif
#if (MODBUS_ENABLE & MODBUS_RTU_ENABLED) && defined(MODBUS_RTU_STREAM) && MODBUS_RTU_STREAM == MPG_STREAM
#undef KEYPAD_STREAM
#define KEYPAD_STREAM (MODBUS_RTU_STREAM + 1)
#endif
#endif
#if MPG_ENABLE && !defined(MPG_STREAM)
#if USB_SERIAL_CDC
#define MPG_STREAM 0
#else
#define MPG_STREAM 1
#endif
#if (MODBUS_ENABLE & MODBUS_RTU_ENABLED) && defined(MODBUS_RTU_STREAM) && MODBUS_RTU_STREAM == MPG_STREAM
#undef MPG_STREAM
#define MPG_STREAM (MODBUS_RTU_STREAM + 1)
#endif
#endif
/**/
+1 -1
View File
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20241128
#define GRBL_BUILD 20241208
#define GRBL_URL "https://github.com/grblHAL"
+7 -12
View File
@@ -279,24 +279,19 @@ int grbl_enter (void)
if(driver.ok == 0xFF)
driver.setup = hal.driver_setup(&settings);
uint8_t n_spindle = spindle_get_count();
#if N_SPINDLE < 2
spindle_id_t spindle_id = 0;
#else
spindle_id_t spindle_id = setting_get_int_value(setting_get_details(Setting_SpindleType, NULL), 0);
#endif
spindle_id_t spindle_id, encoder_spindle;
// Sanity checks
if(spindle_id >= n_spindle) {
if(!spindle_get_id(settings.spindle.ref_id, &spindle_id)) {
spindle_ptrs_t *spindle = spindle_get_hal(0, SpindleHAL_Raw);
spindle_ptrs_t *spindle = spindle_get_hal(spindle_get_default(), SpindleHAL_Raw);
spindle_id = 0;
settings.spindle.flags.type = spindle ? spindle->id : 0; // TODO: change to ref_id in next settings revision
spindle_id = spindle ? spindle->id : spindle->ref_id;
settings.spindle.ref_id = spindle ? spindle->ref_id : DEFAULT_SPINDLE;
}
if(settings.offset_lock.encoder_spindle >= n_spindle)
settings.offset_lock.encoder_spindle = settings.spindle.flags.type;
if(!spindle_get_id(settings.spindle.encoder_spindle, &encoder_spindle))
settings.spindle.encoder_spindle = settings.spindle.ref_id;
//
if((driver.spindle = spindle_select(spindle_id))) {
+25 -21
View File
@@ -35,6 +35,7 @@
typedef struct {
io_ports_detail_t *ports;
char port_names[50];
ioport_bus_t enabled;
} io_ports_private_t;
typedef struct {
@@ -357,6 +358,9 @@ bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uin
if(pn)
pn += i > 9 ? 4 : 3;
}
cfg->in.enabled.mask = cfg->inx.mask;
cfg->out.enabled.mask = cfg->outx.mask;
}
return n_ports > 0;
@@ -511,7 +515,7 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
case Settings_IoPort_InvertIn:
change.mask = (uint8_t)value & digital.inx.mask;
change.mask = value & digital.inx.mask;
if((changed.mask = settings.ioport.invert_in.mask ^ change.mask)) {
@@ -537,7 +541,7 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
case Settings_IoPort_Pullup_Disable:
change.mask = (uint8_t)value & digital.inx.mask;
change.mask = value & digital.inx.mask;
if((changed.mask = settings.ioport.pullup_disable_in.mask ^ change.mask)) {
@@ -564,7 +568,7 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
case Settings_IoPort_InvertOut:
change.mask = (uint8_t)value & digital.outx.mask;
change.mask = value & digital.outx.mask;
if((changed.mask = settings.ioport.invert_out.mask ^ change.mask)) {
@@ -590,7 +594,7 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
case Settings_IoPort_OD_Enable:
change.mask = (uint8_t)value & digital.outx.mask;
change.mask = value & digital.outx.mask;
if((changed.mask = settings.ioport.od_enable_out.mask ^ change.mask)) {
@@ -628,19 +632,19 @@ static uint32_t aux_get_value (setting_id_t id)
switch(id) {
case Settings_IoPort_InvertIn:
value = settings.ioport.invert_in.mask;
value = settings.ioport.invert_in.mask & digital.in.enabled.mask;
break;
case Settings_IoPort_Pullup_Disable:
value = settings.ioport.pullup_disable_in.mask;
value = settings.ioport.pullup_disable_in.mask & digital.in.enabled.mask;
break;
case Settings_IoPort_InvertOut:
value = settings.ioport.invert_out.mask;
value = settings.ioport.invert_out.mask & digital.out.enabled.mask;
break;
case Settings_IoPort_OD_Enable:
value = settings.ioport.od_enable_out.mask;
value = settings.ioport.od_enable_out.mask & digital.out.enabled.mask;
break;
default:
@@ -731,19 +735,6 @@ static void ioport_settings_load (void)
on_settings_loaded();
}
static setting_details_t setting_details = {
.groups = ioport_groups,
.n_groups = sizeof(ioport_groups) / sizeof(setting_group_detail_t),
.settings = ioport_settings,
.n_settings = sizeof(ioport_settings) / sizeof(setting_detail_t),
#ifndef NO_SETTINGS_DESCRIPTIONS
.descriptions = ioport_settings_descr,
.n_descriptions = sizeof(ioport_settings_descr) / sizeof(setting_descr_t),
#endif
.load = ioport_settings_load,
.save = settings_write_global
};
void ioport_setting_changed (setting_id_t id)
{
if(on_setting_changed)
@@ -830,6 +821,19 @@ void ioport_setting_changed (setting_id_t id)
void ioports_add_settings (driver_settings_load_ptr settings_loaded, setting_changed_ptr setting_changed)
{
static setting_details_t setting_details = {
.groups = ioport_groups,
.n_groups = sizeof(ioport_groups) / sizeof(setting_group_detail_t),
.settings = ioport_settings,
.n_settings = sizeof(ioport_settings) / sizeof(setting_detail_t),
#ifndef NO_SETTINGS_DESCRIPTIONS
.descriptions = ioport_settings_descr,
.n_descriptions = sizeof(ioport_settings_descr) / sizeof(setting_descr_t),
#endif
.load = ioport_settings_load,
.save = settings_write_global
};
if(settings_loaded)
on_settings_loaded = settings_loaded;
+51 -2
View File
@@ -201,7 +201,7 @@ static bool limits_pull_off (axes_signals_t axis, coord_data_t *distance, float
}
} while(idx);
plan_data.feed_rate = settings.homing.seek_rate * sqrtf(n_axis); // Adjust so individual axes all move at pull-off rate.
plan_data.feed_rate = settings.axis[0].homing_seek_rate * sqrtf(n_axis); // Adjust so individual axes all move at pull-off rate.
plan_data.condition.coolant = gc_state.modal.coolant;
#ifdef KINEMATICS_API
@@ -536,6 +536,45 @@ status_code_t limits_go_home (axes_signals_t cycle)
{
axes_signals_t auto_square = {0}, auto_squared = {0};
if(settings.homing.flags.per_axis_feedrates && bit_count(cycle.mask) > 1) {
uint_fast8_t idx = 0, axis0 = 255;
axes_signals_t _cycle = cycle;
while(_cycle.mask) {
if(_cycle.mask & 1) {
if(axis0 == 255)
axis0 = idx;
else if(settings.axis[axis0].homing_feed_rate != settings.axis[idx].homing_feed_rate ||
settings.axis[axis0].homing_seek_rate != settings.axis[idx].homing_seek_rate) {
axis0 = 254;
break;
}
}
idx++;
_cycle.mask >>= 1;
}
// If axes in cycle has different feed rates home them separately
if(axis0 == 254) {
status_code_t status;
idx = 0;
while(cycle.mask) {
if(cycle.mask & 1) {
_cycle.mask = bit(idx);
if((status = limits_go_home(_cycle)) != Status_OK)
break;
}
idx++;
cycle.mask >>= 1;
}
return status;
}
}
hal.limits.enable(settings.limits.flags.hard_enabled, cycle); // Disable hard limits pin change register for cycle duration
if(hal.stepper.get_ganged)
@@ -612,9 +651,19 @@ bool limits_homing_required (void)
sys.homing.mask && (sys.homing.mask & sys.homed.mask) != sys.homing.mask;
}
// Get homing rate from the first axis in the cycle.
static float get_homing_rate (axes_signals_t cycle, homing_mode_t mode)
{
return mode == HomingMode_Locate ? settings.homing.feed_rate : settings.homing.seek_rate;
uint_fast8_t idx = 0;
while(cycle.mask) {
if(cycle.mask & 1)
break;
idx++;
cycle.mask >>= 1;
}
return mode == HomingMode_Locate ? settings.axis[idx].homing_feed_rate : settings.axis[idx].homing_seek_rate;
}
// Checks and reports if target array exceeds machine travel limits. Returns false if check failed.
+1 -1
View File
@@ -61,7 +61,7 @@ typedef struct {
bool crc_check;
uint8_t tx_length;
uint8_t rx_length;
char adu[MODBUS_MAX_ADU_SIZE];
uint8_t adu[MODBUS_MAX_ADU_SIZE];
} modbus_message_t;
typedef struct {
+1 -1
View File
@@ -838,7 +838,7 @@ status_code_t mc_homing_cycle (axes_signals_t cycle)
#endif
} else {
if(settings.homing.seek_rate <= 0.0f)
if(settings.axis[0].homing_seek_rate <= 0.0f)
return Status_HomingDisabled;
// Check and abort homing cycle, if hard limits are already enabled. Helps prevent problems
+12 -13
View File
@@ -411,19 +411,6 @@ struct tm *get_datetime (const char *s)
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) {
uint8_t checksum = 0;
while(size--) {
checksum = (checksum << 1) | (checksum >> 7);
checksum += *(data++);
}
return checksum;
}
// Remove spaces from and convert string to uppercase (in situ)
char *strcaps (char *s)
{
@@ -441,6 +428,18 @@ char *strcaps (char *s)
return s;
}
uint_fast8_t bit_count (uint32_t bits)
{
uint_fast8_t count = 0;
while(bits) {
bits &= (bits - 1);
count++;
}
return count;
}
void dummy_handler (void)
{
// NOOP
+2 -3
View File
@@ -228,11 +228,10 @@ 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);
char *strcaps (char *s);
uint_fast8_t bit_count (uint32_t bits);
void dummy_handler (void);
#endif
+29 -13
View File
@@ -6,18 +6,18 @@
Copyright (c) 2017-2023 Terje Io
Copyright (c) 2009-2011 Simen Svale Skogsrud
Grbl is free software: you can redistribute it and/or modify
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _NVS_H_
@@ -25,22 +25,34 @@
#ifndef NVS_SIZE
/*! \brief Total size in bytes of the NVS.
Minimum 1024 bytes required, more if space for driver and/or plugin data and settings is required.
Minimum 1024 bytes required, more if > 5 axes enabled, space for driver and/or plugin data and settings is required.
*/
#define NVS_SIZE 2048
#endif
//! Number of bytes used for storing CRC values. Do not change this!
#ifndef NVS_CRC_BYTES
#define NVS_CRC_BYTES 2
#endif
#define NVS_SIZE_PARAMETERS ((sizeof(coord_data_t) + NVS_CRC_BYTES) * N_CoordinateSystems)
#define NVS_SIZE_BUILD_INFO (sizeof(stored_line_t) + NVS_CRC_BYTES)
#define NVS_SIZE_STARTUP_BLOCK (N_STARTUP_LINE * (sizeof(stored_line_t) + NVS_CRC_BYTES))
/*! \brief Number of bytes at the start of the NVS area reserved for core settings and parameters.
Minimum 1024 bytes required.
Minimum 1024 bytes required, more if > 5 axes enabled.
*/
#if N_AXIS > 6
#define GRBL_NVS_END 1151
#if N_AXIS > 5
#define GRBL_NVS_END (NVS_ADDR_GLOBAL + ((sizeof(settings_t) + NVS_CRC_BYTES + 4) & 0xFFFC) + NVS_SIZE_PARAMETERS + NVS_SIZE_BUILD_INFO + NVS_SIZE_STARTUP_BLOCK + 1)
#else
#define GRBL_NVS_END 1023
#endif
//! Number of bytes used for storing CRC values. Do not change this!
#define NVS_CRC_BYTES 1
#if NVS_CRC_BYTES > 1
#define calc_checksum(data, length) modbus_crc16x(data, length)
#else
#define calc_checksum(data, length) grbl_crc8(data, length)
#endif
/*! @name Define persistent storage memory address location values for core settings and parameters.
The upper half is reserved for parameters and the startup script.
@@ -50,12 +62,16 @@ __NOTE:__ 1024 bytes of persistent storage is the minimum required.
*/
///@{
#define NVS_ADDR_GLOBAL 1U
#if N_AXIS > 5
#define NVS_ADDR_PARAMETERS ((sizeof(settings_t) + NVS_CRC_BYTES + 4) & 0xFFFC) // align to word boundary
#else
#define NVS_ADDR_PARAMETERS 512U
#define NVS_ADDR_BUILD_INFO (GRBL_NVS_END - 81U)
#define NVS_ADDR_STARTUP_BLOCK (NVS_ADDR_BUILD_INFO - 1 - N_STARTUP_LINE * (sizeof(stored_line_t) + NVS_CRC_BYTES))
#endif
#define NVS_ADDR_BUILD_INFO (GRBL_NVS_END - NVS_SIZE_BUILD_INFO)
#define NVS_ADDR_STARTUP_BLOCK (NVS_ADDR_BUILD_INFO - NVS_SIZE_STARTUP_BLOCK - 1)
#if N_TOOLS
#define NVS_ADDR_TOOL_TABLE (GRBL_NVS_END + 1)
#define GRBL_NVS_SIZE (GRBL_NVS_END + 1 + N_TOOLS * (sizeof(tool_data_t) + NVS_CRC_BYTES))
#define GRBL_NVS_SIZE (GRBL_NVS_END + 1 + N_TOOLS * (sizeof(tool_data_t) + NVS_CRC_BYTES))
#else
#define GRBL_NVS_SIZE (GRBL_NVS_END + 1)
#endif
+30 -9
View File
@@ -7,18 +7,18 @@
Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
Grbl is free software: you can redistribute it and/or modify
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License.
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
//
@@ -34,6 +34,7 @@
#include "protocol.h"
#include "settings.h"
#include "gcode.h"
#include "crc.h"
#include "nvs.h"
static uint8_t *nvsbuffer = NULL;
@@ -141,15 +142,19 @@ static nvs_transfer_result_t memcpy_to_ram (uint32_t destination, uint8_t *sourc
return physical_nvs.memcpy_to_nvs(destination, source, size, with_checksum);
uint32_t dest = destination;
uint8_t checksum = with_checksum ? calc_checksum(source, size) : 0;
uint16_t checksum = with_checksum ? calc_checksum(source, size) : 0;
dirty = false;
for(; size > 0; size--)
ram_put_byte(dest++, *(source++));
if(with_checksum)
ram_put_byte(dest, checksum);
if(with_checksum) {
ram_put_byte(dest, checksum & 0xFF);
#if NVS_CRC_BYTES > 1
ram_put_byte(++dest, checksum >> 8);
#endif
}
if(settings_dirty.version || source == hal.nvs.driver_area.mem_address)
dirty = true;
@@ -203,12 +208,16 @@ static nvs_transfer_result_t memcpy_from_ram (uint8_t *destination, uint32_t sou
if(hal.nvs.driver_area.address && source > hal.nvs.driver_area.address + hal.nvs.driver_area.size)
return physical_nvs.memcpy_from_nvs(destination, source, size, with_checksum);
uint8_t checksum = with_checksum ? calc_checksum(&nvsbuffer[source], size) : 0;
uint16_t checksum = with_checksum ? calc_checksum(&nvsbuffer[source], size) : 0;
for(; size > 0; size--)
*(destination++) = ram_get_byte(source++);
#if NVS_CRC_BYTES == 1
return with_checksum ? (checksum == ram_get_byte(source) ? NVS_TransferResult_OK : NVS_TransferResult_Failed) : NVS_TransferResult_OK;
#else
return with_checksum ? (checksum == (ram_get_byte(source) | (ram_get_byte(source + 1) << 8)) ? NVS_TransferResult_OK : NVS_TransferResult_Failed) : NVS_TransferResult_OK;
#endif
}
// Try to allocate RAM from heap for buffer/emulation.
@@ -403,30 +412,38 @@ void nvs_memmap (void)
{
char buf[30];
report_message("NVS Area: addr size", Message_Plain);
report_message("NVS Area: addr size end", Message_Plain);
strcpy(buf, "Global: ");
strcat(buf, uitoa(NVS_ADDR_GLOBAL));
strcat(buf, " ");
strcat(buf, uitoa(sizeof(settings_t) + NVS_CRC_BYTES));
strcat(buf, " ");
strcat(buf, uitoa(NVS_ADDR_GLOBAL + sizeof(settings_t) + NVS_CRC_BYTES));
report_message(buf, Message_Plain);
strcpy(buf, "Parameters: ");
strcat(buf, uitoa(NVS_ADDR_PARAMETERS));
strcat(buf, " ");
strcat(buf, uitoa(N_CoordinateSystems * (sizeof(coord_data_t) + NVS_CRC_BYTES)));
strcat(buf, " ");
strcat(buf, uitoa(NVS_ADDR_PARAMETERS + N_CoordinateSystems * (sizeof(coord_data_t) + NVS_CRC_BYTES)));
report_message(buf, Message_Plain);
strcpy(buf, "Startup block: ");
strcat(buf, uitoa(NVS_ADDR_STARTUP_BLOCK));
strcat(buf, " ");
strcat(buf, uitoa(N_STARTUP_LINE * (sizeof(stored_line_t) + NVS_CRC_BYTES)));
strcat(buf, " ");
strcat(buf, uitoa(NVS_ADDR_STARTUP_BLOCK + N_STARTUP_LINE * (sizeof(stored_line_t) + NVS_CRC_BYTES)));
report_message(buf, Message_Plain);
strcpy(buf, "Build info: ");
strcat(buf, uitoa(NVS_ADDR_BUILD_INFO));
strcat(buf, " ");
strcat(buf, uitoa(sizeof(stored_line_t) + NVS_CRC_BYTES));
strcat(buf, " ");
strcat(buf, uitoa(NVS_ADDR_BUILD_INFO + sizeof(stored_line_t) + NVS_CRC_BYTES));
report_message(buf, Message_Plain);
#if N_TOOLS
@@ -434,6 +451,8 @@ void nvs_memmap (void)
strcat(buf, uitoa(NVS_ADDR_TOOL_TABLE));
strcat(buf, " ");
strcat(buf, uitoa(N_TOOLS * (sizeof(tool_data_t) + NVS_CRC_BYTES)));
strcat(buf, " ");
strcat(buf, uitoa(NVS_ADDR_TOOL_TABLE + N_TOOLS * (sizeof(tool_data_t) + NVS_CRC_BYTES)));
report_message(buf, Message_Plain);
#endif
@@ -441,6 +460,8 @@ void nvs_memmap (void)
strcat(buf, uitoa(hal.nvs.driver_area.address));
strcat(buf, " ");
strcat(buf, uitoa(hal.nvs.driver_area.size));
strcat(buf, " ");
strcat(buf, uitoa(hal.nvs.driver_area.address + hal.nvs.driver_area.size));
report_message(buf, Message_Plain);
}
+15 -11
View File
@@ -475,8 +475,14 @@ static bool print_setting (const setting_detail_t *setting, uint_fast16_t offset
return true;
}
static inline bool is_hidden (const setting_detail_t *setting)
{
return (setting->id == Setting_HomingFeedRate || setting->id == Setting_HomingSeekRate) ? settings.homing.flags.per_axis_feedrates : setting->flags.hidden;
}
void report_grbl_settings (bool all, void *data)
{
uint_fast16_t idx, n_settings = 0;
const setting_detail_t *setting;
setting_detail_t **all_settings, **psetting;
@@ -495,7 +501,7 @@ void report_grbl_settings (bool all, void *data)
// Report core settings
for(idx = 0; idx < details->n_settings; idx++) {
setting = &details->settings[idx];
if(!setting->flags.hidden && (all || setting->type == Setting_IsLegacy || setting->type == Setting_IsLegacyFn) &&
if(!is_hidden(setting) && (all || setting->type == Setting_IsLegacy || setting->type == Setting_IsLegacyFn) &&
(setting->is_available == NULL ||setting->is_available(setting))) {
*psetting++ = (setting_detail_t *)setting;
n_settings++;
@@ -887,7 +893,7 @@ void report_build_info (char *line, bool extended)
if(spindle && !spindle->cap.direction) // NOTE: Shown when disabled.
*append++ = 'D';
if(settings.spindle.flags.enable_rpm_controlled)
if(settings.pwm_spindle.flags.enable_rpm_controlled)
*append++ = '0';
if(hal.driver_cap.software_debounce)
@@ -1875,7 +1881,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(!setting->flags.hidden && (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))) {
*psetting++ = (setting_detail_t *)setting;
n_settings++;
}
@@ -1896,7 +1902,7 @@ static status_code_t print_settings_details (settings_format_t format, setting_g
setting = &details->settings[idx];
if(!setting->flags.hidden && (group == Group_All || setting->group == args.group)) {
if(!is_hidden(setting) && (group == Group_All || setting->group == args.group)) {
if(settings_iterator(setting, print_unsorted, &args))
reported = true;
}
@@ -1913,7 +1919,7 @@ status_code_t report_settings_details (settings_format_t format, setting_id_t id
const setting_detail_t *setting = setting_get_details(id, NULL);
if(setting && !setting->flags.hidden)
if(setting && !is_hidden(setting))
report_settings_detail(format, setting, id - setting->id);
else
status = Status_SettingDisabled;
@@ -1930,7 +1936,7 @@ status_code_t report_setting_description (settings_format_t format, setting_id_t
{
const setting_detail_t *setting;
if((setting = setting_get_details(id, NULL)) && !setting->flags.hidden) {
if((setting = setting_get_details(id, NULL)) && !is_hidden(setting)) {
const char *description = setting_get_description(id);
@@ -2585,15 +2591,13 @@ static int cmp_spindles (const void *a, const void *b)
status_code_t report_spindles (bool machine_readable)
{
bool has_spindles;
#if N_SPINDLE > 1
spindle_rdata_t spindle_data = {0};
if((spindle_data.spindles = malloc(N_SPINDLE * sizeof(spindle_info_t)))) {
has_spindles = spindle_enumerate_spindles(get_spindles, &spindle_data);
spindle_enumerate_spindles(get_spindles, &spindle_data);
spindle_data.n_spindles = spindle_data.idx;
@@ -2607,9 +2611,9 @@ status_code_t report_spindles (bool machine_readable)
#endif
has_spindles = spindle_enumerate_spindles(report_spindle, (void *)machine_readable);
spindle_enumerate_spindles(report_spindle, (void *)machine_readable);
if(!has_spindles && !machine_readable)
if(!machine_readable && spindle_get_count() == 0)
hal.stream.write("No spindles registered." ASCII_EOL);
return Status_OK;
+584 -591
View File
File diff suppressed because it is too large Load Diff
+72 -66
View File
@@ -29,7 +29,7 @@
#include "plugins.h"
// Version of the persistent storage data. Always stored in byte 0 of non-volatile storage.
#define SETTINGS_VERSION 22 // NOTE: Check settings_reset() when moving to next version.
#define SETTINGS_VERSION 23 // NOTE: Check settings_reset() when moving to next version.
// Define axis settings numbering scheme. Starts at Setting_AxisSettingsBase, every INCREMENT, over N_SETTINGS.
#define AXIS_SETTINGS_INCREMENT 10 // Must be greater than the number of axis settings.
@@ -498,6 +498,11 @@ typedef enum {
// 772-779 - reserved for spindle offset settings
//
// Reserving settings in the range 800 - 899 for axis settings.
Setting_AxisSettingsBase1 = 800, // Reserved for driver/plugin settings
Setting_AxisSettingsMax1 = Setting_AxisSettingsBase1 + AXIS_SETTINGS_INCREMENT * 9 + N_AXIS,
//
//
// 900-999 - reserved for automatic tool changers (ATC)
//
@@ -505,7 +510,6 @@ typedef enum {
// ---
Setting_SettingsMax,
Setting_SettingsAll = Setting_SettingsMax,
// ---
// Calculated base values for core stepper settings
@@ -513,13 +517,15 @@ typedef enum {
Setting_AxisMaxRate = Setting_AxisSettingsBase + AXIS_SETTINGS_INCREMENT,
Setting_AxisAcceleration = Setting_AxisSettingsBase + 2 * AXIS_SETTINGS_INCREMENT,
Setting_AxisMaxTravel = Setting_AxisSettingsBase + 3 * AXIS_SETTINGS_INCREMENT,
Setting_AxisStepperCurrent = Setting_AxisSettingsBase + 4 * AXIS_SETTINGS_INCREMENT,
Setting_AxisMicroSteps = Setting_AxisSettingsBase + 5 * AXIS_SETTINGS_INCREMENT,
Setting_AxisStepperCurrent = Setting_AxisSettingsBase + 4 * AXIS_SETTINGS_INCREMENT, // Not used by the core
Setting_AxisMicroSteps = Setting_AxisSettingsBase + 5 * AXIS_SETTINGS_INCREMENT, // Not used by the core
Setting_AxisBacklash = Setting_AxisSettingsBase + 6 * AXIS_SETTINGS_INCREMENT,
Setting_AxisAutoSquareOffset = Setting_AxisSettingsBase + 7 * AXIS_SETTINGS_INCREMENT,
Setting_AxisHomingFeedRate = Setting_AxisSettingsBase + 8 * AXIS_SETTINGS_INCREMENT,
Setting_AxisHomingSeekRate = Setting_AxisSettingsBase + 9 * AXIS_SETTINGS_INCREMENT,
Setting_AxisJerk = Setting_AxisSettingsBase1,
// Calculated base values for driver/plugin stepper settings
Setting_AxisExtended0 = Setting_AxisSettingsBase2,
Setting_AxisExtended1 = Setting_AxisSettingsBase2 + AXIS_SETTINGS_INCREMENT,
@@ -557,9 +563,9 @@ extern const settings_restore_t settings_all;
typedef char stored_line_t[MAX_STORED_LINE_LENGTH];
typedef union {
uint16_t value;
uint32_t value;
struct {
uint16_t report_inches :1,
uint32_t report_inches :1,
restore_overrides :1,
dst_active :1, // Daylight savings time
sleep_enable :1,
@@ -571,23 +577,26 @@ typedef union {
g92_is_volatile :1,
compatibility_level :4,
no_restore_position_after_M6 :1,
no_unlock_after_estop :1;
no_unlock_after_estop :1,
settings_downgrade :1,
unassigned :15;
};
} settingflags_t; // TODO: -> 16 bit
} settingflags_t;
typedef union {
uint8_t value;
uint16_t value;
struct {
uint8_t invert_probe_pin :1,
disable_probe_pullup :1,
invert_connected_pin :1,
disable_connected_pullup :1,
allow_feed_override :1,
enable_protection :1,
invert_toolsetter_input :1,
disable_toolsetter_pullup :1;
uint16_t invert_probe_pin :1,
disable_probe_pullup :1,
invert_connected_pin :1,
disable_connected_pullup :1,
allow_feed_override :1,
enable_protection :1,
invert_toolsetter_input :1,
disable_toolsetter_pullup :1,
unassigned :8;
};
} probeflags_t; // TODO: change to uint16_t for more toolsetter flags?
} probeflags_t;
typedef union {
uint16_t mask;
@@ -630,8 +639,7 @@ typedef union {
uint8_t enabled :1,
deactivate_upon_init :1,
enable_override_control :1,
unassigned :2,
offset_lock :3;
unassigned :5;
};
} parking_setting_flags_t;
@@ -648,22 +656,6 @@ typedef struct {
pid_values_t pid;
} position_pid_t; // Used for synchronized motion
typedef union {
uint8_t value;
struct {
uint8_t enabled :1,
single_axis_commands :1,
init_lock :1,
force_set_origin :1,
manual :1,
override_locks :1,
keep_on_reset :1,
use_limit_switches :1;
};
} homing_settings_flags_t;
// Used internally in settings.c only.
// TODO: replace homing_settings_flags_t with this on a settings struct revision?
typedef union {
uint16_t value;
struct {
@@ -671,14 +663,15 @@ typedef union {
single_axis_commands :1,
init_lock :1,
force_set_origin :1,
two_switches :1, // is a limits setting
two_switches :1, // -> limits.flags.two_switches, never set
manual :1,
override_locks :1,
keep_on_reset :1,
use_limit_switches :1,
unused :7;
per_axis_feedrates :1,
unused :6;
};
} homing_flags_t;
} homing_settings_flags_t;
typedef struct {
float fail_length_percent; // DEFAULT_DUAL_AXIS_HOMING_FAIL_AXIS_LENGTH_PERCENT
@@ -687,15 +680,13 @@ typedef struct {
} homing_dual_axis_t;
typedef struct {
float feed_rate;
float seek_rate;
float pulloff;
axes_signals_t dir_mask;
uint8_t locate_cycles;
homing_dual_axis_t dual_axis;
uint16_t debounce_delay;
homing_settings_flags_t flags;
axes_signals_t dir_mask;
uint8_t locate_cycles;
axes_signals_t cycle[N_AXIS];
homing_dual_axis_t dual_axis;
} homing_settings_t;
typedef struct {
@@ -705,7 +696,7 @@ typedef struct {
axes_signals_t enable_invert;
axes_signals_t energize;
#if N_AXIS > 3
axes_signals_t is_rotary; // rotary axes distances are not scaled in imperial mode
axes_signals_t is_rotary; // rotary axes distances are not scaled in imperial mode
axes_signals_t rotary_wrap; // rotary axes that allows G28 wrap for faster move to home position
#endif
float pulse_microseconds;
@@ -719,6 +710,9 @@ typedef struct {
float acceleration;
float max_travel;
float dual_axis_offset;
float homing_seek_rate;
float homing_feed_rate;
float jerk;
#if ENABLE_BACKLASH_COMPENSATION
float backlash;
#endif
@@ -728,12 +722,11 @@ typedef union {
uint8_t value;
struct {
uint8_t hard_enabled :1,
soft_enabled :1,
check_at_init :1,
jog_soft_limited :1,
two_switches :1,
hard_disabled_rotary :1,
unassigned :2;
unassigned :3;
};
} limit_settings_flags_t;
@@ -741,7 +734,7 @@ typedef struct {
limit_settings_flags_t flags;
axes_signals_t invert;
axes_signals_t disable_pullup;
// axes_signals_t soft_enabled; // TODO: add per axis soft limits, replace soft_enabled flag
axes_signals_t soft_enabled;
} limit_settings_t;
typedef union {
@@ -750,8 +743,7 @@ typedef union {
struct {
uint8_t sd_mount_on_boot :1,
lfs_hidden :1,
unused :5,
downgrading :1; // TODO: move to system flags
unused :6;
};
} fs_options_t;
@@ -762,22 +754,30 @@ typedef union {
uint8_t g59_1 :1,
g59_2 :1,
g59_3 :1,
encoder_spindle :5; // TODO: move to spindle settings
unused :5;
};
} offset_lock_t;
typedef union {
uint8_t value;
uint8_t mask;
uint32_t value;
uint32_t mask;
struct {
uint8_t bit0 :1,
bit1 :1,
bit2 :1,
bit3 :1,
bit4 :1,
bit5 :1,
bit6 :1,
bit7 :1;
uint32_t bit0 :1,
bit1 :1,
bit2 :1,
bit3 :1,
bit4 :1,
bit5 :1,
bit6 :1,
bit7 :1,
bit8 :1,
bit9 :1,
bit10 :1,
bit11 :1,
bit12 :1,
bit13 :1,
bit14 :1,
bit15 :1;
};
} ioport_bus_t;
@@ -797,11 +797,16 @@ typedef enum {
} toolchange_mode_t;
typedef struct {
uint8_t length0;
uint8_t length1;
} rgb_strip_settings_t;
typedef struct {
toolchange_mode_t mode;
float feed_rate;
float seek_rate;
float pulloff_rate;
float probing_distance;
toolchange_mode_t mode;
} tool_change_settings_t;
typedef union {
@@ -827,25 +832,26 @@ typedef struct {
axis_settings_t axis[N_AXIS];
control_signals_t control_invert;
control_signals_t control_disable_pullup;
coolant_state_t coolant_invert;
axes_signals_t home_invert;
coolant_settings_t coolant;
uint8_t modbus_baud;
uint8_t canbus_baud;
spindle_settings_t spindle;
spindle_pwm_settings_t pwm_spindle;
stepper_settings_t steppers;
reportmask_t status_report; // Mask to indicate desired report data.
settingflags_t flags; // Contains default boolean settings
probeflags_t probe;
uint8_t rgb_strip0_length;
rgb_strip_settings_t rgb_strip;
offset_lock_t offset_lock;
fs_options_t fs_options;
homing_settings_t homing;
limit_settings_t limits;
uint8_t rgb_strip1_length;
parking_settings_t parking;
safety_door_settings_t safety_door;
position_pid_t position; // Used for synchronized motion
ioport_signals_t ioport;
homing_settings_t homing;
char reserved[24]; // Reserved For future expansion
} settings_t;
typedef enum {
+51 -39
View File
@@ -67,8 +67,8 @@ static bool spindle_activate (spindle_id_t spindle_id, spindle_num_t spindle_num
if(pwm_spindle && pwm_spindle->cfg->config && pwm_spindle != &spindles[spindle_id]) {
if(!pwm_spindle->hal.cap.rpm_range_locked) {
pwm_spindle->hal.rpm_min = settings.spindle.rpm_min;
pwm_spindle->hal.rpm_max = settings.spindle.rpm_max;
pwm_spindle->hal.rpm_min = settings.pwm_spindle.rpm_min;
pwm_spindle->hal.rpm_max = settings.pwm_spindle.rpm_max;
}
if((pwm_spindle->init_ok = pwm_spindle->hal.config == NULL || pwm_spindle->hal.config(&pwm_spindle->hal)))
@@ -84,8 +84,8 @@ static bool spindle_activate (spindle_id_t spindle_id, spindle_num_t spindle_num
gc_spindle_off(); // TODO: switch off only the default spindle?
if(!spindle->hal.cap.rpm_range_locked) {
spindle->hal.rpm_min = settings.spindle.rpm_min;
spindle->hal.rpm_max = settings.spindle.rpm_max;
spindle->hal.rpm_min = settings.pwm_spindle.rpm_min;
spindle->hal.rpm_max = settings.pwm_spindle.rpm_max;
}
if(!spindle->init_ok)
@@ -290,6 +290,23 @@ uint8_t spindle_get_count (void)
return n_spindle == 1 && spindles[0].cfg->type == SpindleType_Null ? 0 : n_spindle;
}
bool spindle_get_id (uint8_t ref_id, spindle_id_t *spindle_id)
{
bool ok = false;
uint_fast8_t idx;
*spindle_id = 0;
for(idx = 0; idx < n_spindle; idx++) {
if((ok = spindles[idx].cfg->ref_id == ref_id)) {
*spindle_id = idx;
break;
}
}
return ok;
}
static spindle_num_t spindle_get_num (spindle_id_t spindle_id)
{
spindle_num_t spindle_num;
@@ -323,7 +340,7 @@ void spindle_bind_encoder (const spindle_data_ptrs_t *encoder_data)
spindle = spindle_get((spindle_num = spindle_get_num(idx)));
if(encoder_data && spindle_num == settings.offset_lock.encoder_spindle) {
if(encoder_data && spindle_num == settings.spindle.encoder_spindle) {
spindles[idx].hal.get_data = encoder_data->get;
spindles[idx].hal.reset_data = encoder_data->reset;
spindles[idx].hal.cap.at_speed = spindles[idx].hal.cap.variable;
@@ -723,7 +740,7 @@ bool spindle_is_on (void)
*/
static inline uint_fast16_t invert_pwm (spindle_pwm_t *pwm_data, uint_fast16_t pwm_value)
{
return pwm_data->invert_pwm ? pwm_data->period - pwm_value - 1 : pwm_value;
return pwm_data->flags.invert_pwm ? pwm_data->period - pwm_value - 1 : pwm_value;
}
/*! \brief Spindle RPM to PWM conversion.
@@ -786,7 +803,7 @@ static uint_fast16_t compute_dummy_pwm_value (spindle_pwm_t *pwm_data, float rpm
\param clock_hz timer clock frequency used for PWM generation.
\returns \a true if successful, \a false if no PWM range possible - driver should then revert to simple on/off spindle control.
*/
bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_data, spindle_settings_t *settings, uint32_t clock_hz)
bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_data, spindle_pwm_settings_t *settings, uint32_t clock_hz)
{
pwm_data->settings = settings;
spindle->rpm_min = pwm_data->rpm_min = settings->rpm_min;
@@ -798,7 +815,7 @@ bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_
pwm_data->f_clock = clock_hz;
pwm_data->period = (uint_fast16_t)((float)clock_hz / settings->pwm_freq);
if(settings->pwm_off_value == 0.0f)
pwm_data->off_value = pwm_data->invert_pwm ? pwm_data->period : 0;
pwm_data->off_value = pwm_data->flags.invert_pwm ? pwm_data->period : 0;
else
pwm_data->off_value = invert_pwm(pwm_data, (uint_fast16_t)(pwm_data->period * settings->pwm_off_value / 100.0f));
pwm_data->max_value = (uint_fast16_t)(pwm_data->period * settings->pwm_max_value / 100.0f) + pwm_data->offset;
@@ -806,17 +823,17 @@ bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_
pwm_data->min_value = (uint_fast16_t)((float)pwm_data->max_value * 0.004f);
pwm_data->pwm_gradient = (float)(pwm_data->max_value - pwm_data->min_value) / (spindle->rpm_max - spindle->rpm_min);
pwm_data->always_on = settings->pwm_off_value != 0.0f;
pwm_data->flags.always_on = settings->pwm_off_value != 0.0f;
pwm_data->compute_value = spindle_compute_pwm_value;
} else {
pwm_data->off_value = 0;
pwm_data->always_on = false;
pwm_data->flags.always_on = false;
pwm_data->compute_value = compute_dummy_pwm_value;
}
pwm_data->flags.invert_pwm = pwm_data->invert_pwm;
pwm_data->flags.always_on = pwm_data->always_on;
pwm_data->flags.cloned = pwm_data->cloned;
pwm_data->flags.invert_pwm = pwm_data->flags.invert_pwm;
pwm_data->flags.always_on = pwm_data->flags.always_on;
pwm_data->flags.cloned = pwm_data->flags.cloned;
spindle->context.pwm = pwm_data;
@@ -840,7 +857,7 @@ bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_
#include "grbl/nvs_buffer.h"
static spindle1_settings_t sp1_settings;
static spindle1_pwm_settings_t sp1_settings;
static uint32_t nvs_address;
static char spindle_signals[] = "Spindle enable,Spindle direction,PWM";
static bool ports_ok = false;
@@ -1027,12 +1044,12 @@ static void spindle1_settings_changed (settings_t *settings, settings_changed_fl
static void spindle1_settings_save (void)
{
hal.nvs.memcpy_to_nvs(nvs_address, (uint8_t *)&sp1_settings, sizeof(spindle1_settings_t), true);
hal.nvs.memcpy_to_nvs(nvs_address, (uint8_t *)&sp1_settings, sizeof(spindle1_pwm_settings_t), true);
}
static void spindle1_settings_restore (void)
{
static const spindle_settings_t defaults = {
static const spindle_pwm_settings_t defaults = {
.rpm_max = DEFAULT_SPINDLE1_RPM_MAX,
.rpm_min = DEFAULT_SPINDLE1_RPM_MIN,
.flags.pwm_disable = false,
@@ -1046,11 +1063,6 @@ static void spindle1_settings_restore (void)
.pwm_min_value = DEFAULT_SPINDLE1_PWM_MIN_VALUE,
.pwm_max_value = DEFAULT_SPINDLE1_PWM_MAX_VALUE,
.at_speed_tolerance = DEFAULT_SPINDLE_AT_SPEED_TOLERANCE,
.ppr = DEFAULT_SPINDLE_PPR,
.pid.p_gain = DEFAULT_SPINDLE_P_GAIN,
.pid.i_gain = DEFAULT_SPINDLE_I_GAIN,
.pid.d_gain = DEFAULT_SPINDLE_D_GAIN,
.pid.i_max_error = DEFAULT_SPINDLE_I_MAX,
#if ENABLE_SPINDLE_LINEARIZATION
#if SPINDLE_NPWM_PIECES > 0
.pwm_piece[0] = { .rpm = DEFAULT_RPM_POINT01, .start = DEFAULT_RPM_LINE_A1, .end = DEFAULT_RPM_LINE_B1 },
@@ -1080,30 +1092,17 @@ static void spindle1_settings_restore (void)
#endif
};
memcpy(&sp1_settings.cfg, &defaults, sizeof(spindle_settings_t));
memcpy(&sp1_settings.cfg, &defaults, sizeof(spindle_pwm_settings_t));
hal.nvs.memcpy_to_nvs(nvs_address, (uint8_t *)&sp1_settings, sizeof(spindle1_settings_t), true);
hal.nvs.memcpy_to_nvs(nvs_address, (uint8_t *)&sp1_settings, sizeof(spindle1_pwm_settings_t), true);
}
static void spindle1_settings_load (void)
{
if((hal.nvs.memcpy_from_nvs((uint8_t *)&sp1_settings, nvs_address, sizeof(spindle1_settings_t), true) != NVS_TransferResult_OK))
if((hal.nvs.memcpy_from_nvs((uint8_t *)&sp1_settings, nvs_address, sizeof(spindle1_pwm_settings_t), true) != NVS_TransferResult_OK))
spindle1_settings_restore();
}
static setting_details_t spindle1_setting_details = {
.settings = spindle1_settings,
.n_settings = sizeof(spindle1_settings) / sizeof(setting_detail_t),
#ifndef NO_SETTINGS_DESCRIPTIONS
.descriptions = spindle1_settings_descr,
.n_descriptions = sizeof(spindle1_settings_descr) / sizeof(setting_descr_t),
#endif
.load = spindle1_settings_load,
.restore = spindle1_settings_restore,
.save = spindle1_settings_save,
.on_changed = spindle1_settings_changed
};
static bool pwm_count (xbar_t *properties, uint8_t port, void *data)
{
*((uint32_t *)data) += 1;
@@ -1122,7 +1121,7 @@ static bool check_pwm_ports (void)
return n_pwm_out != 0;
}
spindle1_settings_t *spindle1_settings_add (bool claim_ports)
spindle1_pwm_settings_t *spindle1_settings_add (bool claim_ports)
{
if((ports_ok = claim_ports && hal.port.num_digital_out > 0 && check_pwm_ports())) {
@@ -1133,11 +1132,24 @@ spindle1_settings_t *spindle1_settings_add (bool claim_ports)
strcpy(max_dport, uitoa(hal.port.num_digital_out - 1));
}
return nvs_address == 0 && (!claim_ports || ports_ok) && (nvs_address = nvs_alloc(sizeof(spindle1_settings_t))) ? &sp1_settings : NULL;
return nvs_address == 0 && (!claim_ports || ports_ok) && (nvs_address = nvs_alloc(sizeof(spindle1_pwm_settings_t))) ? &sp1_settings : NULL;
}
void spindle1_settings_register (spindle_cap_t cap, spindle1_settings_changed_ptr on_changed)
{
static setting_details_t spindle1_setting_details = {
.settings = spindle1_settings,
.n_settings = sizeof(spindle1_settings) / sizeof(setting_detail_t),
#ifndef NO_SETTINGS_DESCRIPTIONS
.descriptions = spindle1_settings_descr,
.n_descriptions = sizeof(spindle1_settings_descr) / sizeof(setting_descr_t),
#endif
.load = spindle1_settings_load,
.restore = spindle1_settings_restore,
.save = spindle1_settings_save,
.on_changed = spindle1_settings_changed
};
on_settings_changed = on_changed;
settings_register(&spindle1_setting_details);
+19 -15
View File
@@ -202,33 +202,38 @@ typedef union {
struct {
uint8_t enable_rpm_controlled :1, // PWM spindle only
laser_mode_disable :1, // PWM spindle only
type :5,
pwm_disable :1; // PWM spindle only
pwm_disable :1, // PWM spindle only
unassigned :5;
};
} spindle_settings_flags_t;
typedef struct {
spindle_state_t invert;
spindle_settings_flags_t flags;
float rpm_max;
float rpm_min;
float pwm_freq;
float pwm_period; // currently unused
float pwm_off_value;
float pwm_min_value;
float pwm_max_value;
float at_speed_tolerance; //!< Tolerance in percent of programmed speed.
pwm_piece_t pwm_piece[SPINDLE_NPWM_PIECES];
pid_values_t pid;
} spindle_pwm_settings_t;
typedef struct {
uint8_t ref_id;
uint8_t encoder_spindle;
uint16_t ppr; //!< Spindle encoder pulses per revolution (PPR).
spindle_state_t invert;
spindle_settings_flags_t flags;
uint16_t on_delay;
float at_speed_tolerance; //!< Tolerance in percent of programmed speed.
} spindle_settings_t;
typedef struct {
uint8_t port_on;
uint8_t port_dir;
uint8_t port_pwm;
spindle_settings_t cfg;
} spindle1_settings_t;
spindle_pwm_settings_t cfg;
} spindle1_pwm_settings_t;
typedef union {
uint8_t value;
@@ -244,16 +249,13 @@ typedef union {
//!* \brief Precalculated values that may be set/used by HAL driver to speed up RPM to PWM conversions if variable spindle is supported. */
typedef struct spindle_pwm {
uint32_t f_clock;
spindle_settings_t *settings;
spindle_pwm_settings_t *settings;
uint_fast16_t period;
uint_fast16_t off_value; //!< NOTE: this value holds the inverted version if software PWM inversion is enabled by the driver.
uint_fast16_t min_value;
uint_fast16_t max_value;
float rpm_min; //!< Minimum spindle RPM.
float pwm_gradient;
bool invert_pwm; //!< deprecated, use bit in flags instead
bool always_on; //!< deprecated, use bit in flags instead
bool cloned; //!< deprecated, use bit in flags instead
spindle_pwm_flags_t flags;
int_fast16_t offset;
uint_fast16_t n_pieces;
@@ -365,7 +367,7 @@ __attribute__((always_inline)) static inline void spindle_validate_at_speed (spi
}
*/
bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_data, spindle_settings_t *settings, uint32_t clock_hz);
bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_data, spindle_pwm_settings_t *settings, uint32_t clock_hz);
spindle_id_t spindle_register (const spindle_ptrs_t *spindle, const char *name);
@@ -373,6 +375,8 @@ spindle_id_t spindle_add_null (void);
uint8_t spindle_get_count (void);
bool spindle_get_id (uint8_t ref_id, spindle_id_t *spindle_id);
bool spindle_select (spindle_id_t spindle_id);
spindle_cap_t spindle_get_caps (bool active);
@@ -403,9 +407,9 @@ spindle_ptrs_t *spindle_get (spindle_num_t spindle_num);
#if N_SPINDLE > 1
typedef void (*spindle1_settings_changed_ptr)(spindle1_settings_t *settings);
typedef void (*spindle1_settings_changed_ptr)(spindle1_pwm_settings_t *settings);
spindle1_settings_t *spindle1_settings_add (bool claim_ports);
spindle1_pwm_settings_t *spindle1_settings_add (bool claim_ports);
void spindle1_settings_register (spindle_cap_t cap, spindle1_settings_changed_ptr on_changed);
#endif
+15 -1
View File
@@ -4,7 +4,7 @@
Part of grblHAL
Copyright (c) 2017-2024 Terje Io
Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea mResearch LLC
Copyright (c) 2014-2016 Sungeun K. Jeon for Gnea Research LLC
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -604,6 +604,19 @@ static status_code_t output_all_build_info (sys_state_t state, char *args)
return Status_OK;
}
static status_code_t settings_downgrade (sys_state_t state, char *args)
{
settings.version.build = settings.version.build == 0 ? (GRBL_BUILD - 20000000UL) : 0;
if((settings.flags.settings_downgrade = settings.version.build == 0)) {
}
settings_write_global();
return Status_OK;
}
static status_code_t settings_reset (sys_state_t state, char *args)
{
settings_restore_t restore = {0};
@@ -926,6 +939,7 @@ PROGMEM static const sys_command_t sys_commands[] = {
{ "SD", report_spindle_data, { .help_fn = On }, { .fn = help_spindle } },
{ "SR", spindle_reset_data, { .help_fn = On }, { .fn = help_spindle } },
{ "RTC", rtc_action, { .allow_blocking = On, .help_fn = On }, { .fn = help_rtc } },
{ "DWNGRD", settings_downgrade, { .noargs = On, .allow_blocking = On }, { .str = "toggle setting flags for downgrade" } },
#ifdef DEBUGOUT
{ "Q", output_memmap, { .noargs = On }, { .str = "output NVS memory allocation" } },
#endif
+18 -4
View File
@@ -84,12 +84,26 @@ __NOTE:__ flags are mutually exclusive, bit map allows testing for multiple stat
#define STATE_TOOL_CHANGE bit(9) //!< Manual tool change, similar to #STATE_HOLD - but stops spindle and allows jogging.
///@}
typedef enum {
Mode_Standard = 0,
Mode_Laser,
Mode_Lathe
#ifdef ARDUINO
typedef enum {
Mode_Standard = 0, //!< 0
Mode_Laser, //!< 1
Mode_Lathe //!< 2
} machine_mode_t;
#else
typedef uint8_t machine_mode_t;
enum machine_mode_t {
Mode_Standard = 0, //!< 0
Mode_Laser, //!< 1
Mode_Lathe //!< 2
};
#endif
typedef enum {
Parking_DoorClosed = 0, //!< 0
Parking_DoorAjar, //!< 1