Refactored offset handling, for improved readability and in preparation for rotation support.

Added experimental support for G66 (modal macro call) and G67 (end modal macro call).
Made axis letter to axis/motor assignment for axes ABCUVW freely changeable at compile time.
Fix for some G65 arguments being incorrectly validated for normal use (sign, range).
Added repeat support to G65 macro call via the optional L parameter word.
Changed default setting for ABC-axes to rotary.
Changed defaults for jerk settings to 10x acceleration settings.
Disabled jerk for jog, probe and spindle synchronized motion.
Added _active_probe system parameter, returns -1 if no probe inputs available.
Minor bug fix, G5.1 and G33.1 motion commands were not coverted to the correct string equivalent in $G output.
This commit is contained in:
Terje Io
2026-01-25 07:51:44 +01:00
parent f8867e7ea3
commit 64c35930c7
59 changed files with 2899 additions and 2351 deletions
+2 -1
View File
@@ -46,7 +46,8 @@ PROGMEM static const alarm_detail_t alarm_detail[] = {
{ Alarm_MotorFault, "Motor fault." },
{ Alarm_HomingFail, "Homing fail. Bad configuration." },
{ Alarm_ModbusException, "Modbus exception. Timeout or message error." },
{ Alarm_ExpanderException, "I/O expander communication failed." }
{ Alarm_ExpanderException, "I/O expander communication failed." },
{ Alarm_NVS_Failed, "Non Volatile Storage (EEPROM) failure." }
};
static alarm_details_t details = {
+5 -3
View File
@@ -24,7 +24,8 @@
#ifndef _ALARMS_H_
#define _ALARMS_H_
// Alarm executor codes. Valid values (1-255). Zero is reserved.
// Alarm codes. Valid values (1-255). Zero is reserved.
// Code 0 - 9 is equal to legacy Grbl codes, 15 equals to legacy Grbl code 10
typedef enum {
Alarm_None = 0, //!< 0
Alarm_HardLimit = 1, //!< 1
@@ -47,8 +48,9 @@ typedef enum {
Alarm_HomingFail = 18, //!< 18
Alarm_ModbusException = 19, //!< 19
Alarm_ExpanderException = 20, //!< 20
Alarm_AlarmMax = Alarm_ExpanderException
} alarm_code_t;
Alarm_NVS_Failed = 21, //!< 21
Alarm_AlarmMax = Alarm_NVS_Failed
} __attribute__ ((__packed__)) alarm_code_t;
typedef struct {
alarm_code_t id;
+50
View File
@@ -1,5 +1,55 @@
## grblHAL changelog
<a name="20260125">Build 20260125
Core:
* Refactored offset handling, for improved readability and in preparation for rotation support.
* Added experimental support for `G66` \(modal macro call\) and `G67` \(end modal macro call\).
* Made axis letter to axis/motor assignment for axes ABCUVW freely changeable at compile time.
Axes configurations such as XYZC and XYZAW is now possible.
> [!NOTE]
> Axis letter to motor assignment has to be in ascending order, e.g. XYZWA will not work.
> Max. number of axes is still limited to 8, capped by the board map.
* Fix for some `G65` arguments being incorrectly validated for normal use \(sign, range\).
* Added repeat support to `G65` macro call via the optional `L` parameter word.
* Changed default setting for ABC-axes to rotary.
* Changed defaults for jerk settings to 10x acceleration settings.
* Disabled jerk for jog, probe and spindle synchronized motion.
* Added `_active_probe` system parameter, returns -1 if no probe inputs available.
* Minor bug fix, `G5.1` and `G33.1` motion commands were not coverted to the correct string equivalent in `$G` output.
Drivers:
* All: updated for new axis letter assigment scheme.
For boards with EEPROM/FRAM an alarm will now be raised if the EEPROM/FRAM cannot be accessed.
* RP2040: fix for LED strips not working. Ref. issue [#167](https://github.com/grblHAL/RP2040/issues/167).
Fix for second serial port not working on the RP23U5XBB board. Ref. issue [#160](https://github.com/grblHAL/RP2040/issues/160).
Plugins:
* Some: updated for new axis letter assigment scheme and other core changes.
* Networking: ftpd - changed CWD \(Current Working Directory\) handling to be per connection. Ref. PR [#17](https://github.com/grblHAL/Plugin_networking/pull/17).
httpd - added CORS support and some new content types. Ref. PR [#19](https://github.com/grblHAL/Plugin_networking/pull/19).
Some minor bugfixes and general improvements.
* 3rd party: added M800 plugin to core list. Ref. issue [#30](https://github.com/grblHAL/plugins/issues/30).
* Misc: removed LED strip configuration plugin, settings `$536` and `$537` are now handled by the core.
---
<a name="20260107">Build 20260107
Core:
+64 -12
View File
@@ -65,6 +65,13 @@ If more than 3 axes are configured a compliant driver and board map file is need
#define N_SYS_SPINDLE 1
#endif
/*! \def PLANNER_ADD_MOTION_MODE
\brief Enables passing the motion mode used to the planner.
*/
#if !defined PLANNER_ADD_MOTION_MODE || defined __DOXYGEN__
#define PLANNER_ADD_MOTION_MODE Off // Default disabled. Set to \ref On or 1 to enable.
#endif
/*! \def BUILD_INFO
\brief Defines string to be output as part of the `$I` or `$I+` command response.
*/
@@ -1673,7 +1680,7 @@ greater.
/*! @name $47 - Setting_HomingCycle_4
*/
///@{
#if (defined A_AXIS && !defined DEFAULT_HOMING_CYCLE_3) || defined __DOXYGEN__
#if (N_AXIS > 3 && !defined DEFAULT_HOMING_CYCLE_3) || defined __DOXYGEN__
#define DEFAULT_HOMING_CYCLE_3 0 // OPTIONAL: Uncomment and add axes mask to enable
#endif
///@}
@@ -1682,7 +1689,7 @@ greater.
\ref axismask
*/
///@{
#if (defined B_AXIS && !defined DEFAULT_HOMING_CYCLE_4) || defined __DOXYGEN__
#if (N_AXIS > 4 && !defined DEFAULT_HOMING_CYCLE_4) || defined __DOXYGEN__
#define DEFAULT_HOMING_CYCLE_4 0 // OPTIONAL: Uncomment and add axes mask to enable
#endif
///@}
@@ -1690,7 +1697,7 @@ greater.
/*! @name $49 - Setting_HomingCycle_6
*/
///@{
#if (defined C_AXIS && !defined DEFAULT_HOMING_CYCLE_5) || defined __DOXYGEN__
#if (N_AXIS > 5 && !defined DEFAULT_HOMING_CYCLE_5) || defined __DOXYGEN__
#define DEFAULT_HOMING_CYCLE_5 0 // OPTIONAL: Uncomment and add axes mask to enable
#endif
///@}
@@ -1992,8 +1999,36 @@ Set steps/mm for the axes to the value that represent the desired movement per u
For the controller the distance is unitless and and can be in degrees, radians, rotations, ...
*/
///@{
#define IS_ROTARY_LETTER(c) (c == 'A' || c == 'B' || c == 'C')
#if !defined DEFAULT_AXIS_ROTATIONAL_MASK || defined __DOXYGEN__
#define DEFAULT_AXIS_ROTATIONAL_MASK 0
#if N_AXIS > 3 && IS_ROTARY_LETTER(AXIS3_LETTER)
#define RA3 (1<<3)
#else
#define RA3 0
#endif
#if N_AXIS > 4 && IS_ROTARY_LETTER(AXIS4_LETTER)
#define RA4 (1<<4)
#else
#define RA4 0
#endif
#if N_AXIS > 5 && IS_ROTARY_LETTER(AXIS5_LETTER)
#define RA5 (1<<5)
#else
#define RA5 0
#endif
#if N_AXIS > 6 && IS_ROTARY_LETTER(AXIS6_LETTER)
#define RA6 (1<<6)
#else
#define RA6 0
#endif
#if N_AXIS > 7 && IS_ROTARY_LETTER(AXIS7_LETTER)
#define RA7 (1<<7)
#else
#define RA7 0
#endif
#define DEFAULT_AXIS_ROTATIONAL_MASK (RA3|RA4|RA5|RA6|RA7)
#endif
///@}
@@ -2117,20 +2152,19 @@ Default baud rate for ModBus RTU stream.
Default stream format settings for ModBus RTU stream.
*/
///@{
#if !defined DEFAULT_MODBUS_STREAM_PARITY || defined __DOXYGEN__
#define DEFAULT_MODBUS_STREAM_PARITY 0 // 0 = None, 1 = Even, 2 = Odd
#if !defined DEFAULT_MODBUS_STREAM_DATA_BITS || defined __DOXYGEN__
#define DEFAULT_MODBUS_STREAM_DATA_BITS 0 // 0 = 8, 1 = 7
#endif
///@}
/*! @name $681 - Setting_ModBus_StreamFormat
Default stream format settings for ModBus RTU stream.
*/
///@{
#if !defined DEFAULT_MODBUS_STREAM_STOP_BITS || defined __DOXYGEN__
#define DEFAULT_MODBUS_STREAM_STOP_BITS 0 // 0 = 1, 1 = 1.5, 2 = 2, 3 = 0.5
#endif
///@}///@{
#if !defined DEFAULT_MODBUS_STREAM_PARITY || defined __DOXYGEN__
#define DEFAULT_MODBUS_STREAM_PARITY 0 // 0 = None, 1 = Even, 2 = Odd
#endif
///@}
/*! @name $650 - Setting_FSOptions
Filing systems options.
*/
@@ -2192,6 +2226,9 @@ Adds directory entries in $F and $F+ output to allow hierarchical navigation of
#if (defined V_AXIS && !defined DEFAULT_V_STEPS_PER_MM) || defined __DOXYGEN__
#define DEFAULT_V_STEPS_PER_MM 250.0f
#endif
#if (defined W_AXIS && !defined DEFAULT_W_STEPS_PER_MM) || defined __DOXYGEN__
#define DEFAULT_W_STEPS_PER_MM 250.0f
#endif
///@}
/*! @name $11x - Setting_AxisMaxRate
@@ -2222,6 +2259,9 @@ Adds directory entries in $F and $F+ output to allow hierarchical navigation of
#if (defined V_AXIS && !defined DEFAULT_V_MAX_RATE) || defined __DOXYGEN__
#define DEFAULT_V_MAX_RATE 500.0f // mm/min
#endif
#if (defined W_AXIS && !defined DEFAULT_W_MAX_RATE) || defined __DOXYGEN__
#define DEFAULT_W_MAX_RATE 500.0f // mm/min
#endif
///@}
/*! @name 12x - Setting_AxisAcceleration
@@ -2251,6 +2291,9 @@ Adds directory entries in $F and $F+ output to allow hierarchical navigation of
#if (defined V_AXIS && !defined DEFAULT_V_ACCELERATION) || defined __DOXYGEN__
#define DEFAULT_V_ACCELERATION 10.0f // mm/sec^2
#endif
#if (defined W_AXIS && !defined DEFAULT_W_ACCELERATION) || defined __DOXYGEN__
#define DEFAULT_W_ACCELERATION 10.0f // mm/sec^2
#endif
///@}
/*! @name 22x - Setting_AxisJerk
@@ -2280,6 +2323,9 @@ Adds directory entries in $F and $F+ output to allow hierarchical navigation of
#if (defined V_AXIS && !defined DEFAULT_V_JERK) || defined __DOXYGEN__
#define DEFAULT_V_JERK (DEFAULT_V_ACCELERATION * 10.0f) // mm/sec^3
#endif
#if (defined W_AXIS && !defined DEFAULT_W_JERK) || defined __DOXYGEN__
#define DEFAULT_W_JERK (DEFAULT_W_ACCELERATION * 10.0f) // mm/sec^3
#endif
///@}
/*! @name 13x - Setting_AxisMaxTravel
@@ -2310,6 +2356,9 @@ __NOTE:__ Must be a positive values.
#if (defined V_AXIS && !defined DEFAULT_V_MAX_TRAVEL) || defined __DOXYGEN__
#define DEFAULT_V_MAX_TRAVEL 200.0f // mm
#endif
#if (defined W_AXIS && !defined DEFAULT_W_MAX_TRAVEL) || defined __DOXYGEN__
#define DEFAULT_W_MAX_TRAVEL 200.0f // mm
#endif
///@}
/*! @name 14x - Setting_AxisStepperCurrent
@@ -2340,6 +2389,9 @@ __NOTE:__ Must be a positive values.
#if (defined V_AXIS && !defined DEFAULT_V_CURRENT) || defined __DOXYGEN__
#define DEFAULT_V_CURRENT 500.0f // mA RMS
#endif
#if (defined W_AXIS && !defined DEFAULT_W_CURRENT) || defined __DOXYGEN__
#define DEFAULT_W_CURRENT 500.0f // mA RMS
#endif
///@}
// Sanity checks
@@ -2389,7 +2441,7 @@ __NOTE:__ Must be a positive values.
#error "Cannot enable laser and lathe mode at the same time!"
#endif
#if LATHE_UVW_OPTION && (N_AXIS > 6 || AXIS_REMAP_ABC2UVW)
#if LATHE_UVW_OPTION && AXIS_REMAP_ABC2UVW
#warning "Cannot enable lathe UVW option when N_AXIS > 6 or ABC words are remapped!"
#undef LATHE_UVW_OPTION
#define LATHE_UVW_OPTION Off
+9 -7
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2020-2025 Terje Io
Copyright (c) 2020-2026 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
@@ -31,6 +31,7 @@
#include "errors.h"
#include "settings.h"
#include "report.h"
#include "ioports.h"
#include "planner.h"
#include "machine_limits.h"
#include "vfs.h"
@@ -44,13 +45,13 @@ typedef enum {
OverrideChanged_FanState = 0
} override_changed_t;
/* TODO: add to grbl pointers so that a different formatting (xml, json etc) of reports may be implemented by a plugin?
/* TODO: add to grblHAL pointers so that a different formatting (xml, json etc) of reports may be implemented by a plugin?
typedef struct {
void (*report_echo_line_received)(char *line);
void (*report_realtime_status)(stream_write_ptr stream_write);
void (*report_realtime_status)(stream_write_ptr stream_write, );
void (*report_probe_parameters)(void);
void (*report_ngc_parameters)(void);
void (*report_gcode_modes)(void);
void (*report_gcode_modes)(stream_write_ptr stream_write);
void (*report_startup_line)(uint8_t n, char *line);
void (*report_execute_startup_message)(char *line, status_code_t status_code);
} grbl_report_t;
@@ -89,8 +90,9 @@ typedef void (*on_state_change_ptr)(sys_state_t state);
typedef void (*on_override_changed_ptr)(override_changed_t override);
typedef void (*on_spindle_programmed_ptr)(spindle_ptrs_t *spindle, spindle_state_t state, float rpm, spindle_rpm_mode_t mode);
typedef void (*on_spindle_at_speed_ptr)(spindle_ptrs_t *spindle, spindle_state_t state);
typedef void (*on_port_out_ptr)(uint8_t port, io_port_type_t type, float value);
typedef void (*on_wco_changed_ptr)(void);
typedef void (*on_wco_saved_ptr)(coord_system_id_t id, coord_data_t *data);
typedef void (*on_wco_saved_ptr)(coord_system_id_t id, coord_system_data_t *data);
typedef void (*on_program_completed_ptr)(program_flow_t program_flow, bool check_mode);
typedef void (*on_execute_realtime_ptr)(sys_state_t state);
typedef void (*on_unknown_accessory_override_ptr)(uint8_t cmd);
@@ -132,7 +134,7 @@ typedef status_code_t (*on_file_end_ptr)(vfs_file_t *handle, status_code_t statu
typedef status_code_t (*on_unknown_sys_command_ptr)(sys_state_t state, char *line); // return Status_Unhandled.
typedef status_code_t (*on_user_command_ptr)(char *line);
typedef sys_commands_t *(*on_get_commands_ptr)(void);
typedef status_code_t (*on_macro_execute_ptr)(macro_id_t macro); // macro implementations _must_ claim hal.stream.read to stream macros!
typedef status_code_t (*on_macro_execute_ptr)(macro_id_t macro, parameter_words_t args, uint32_t repeats); // macro implementations _must_ claim hal.stream.read to stream macros!
typedef void (*on_macro_return_ptr)(void);
typedef void (*on_file_demarcate_ptr)(bool start);
@@ -225,6 +227,7 @@ typedef struct {
on_report_handlers_init_ptr on_report_handlers_init;
on_spindle_programmed_ptr on_spindle_programmed;
on_spindle_at_speed_ptr on_spindle_at_speed;
on_port_out_ptr on_port_out; //!< Might be called from interrupt context, only for unclaimed ports.
on_wco_changed_ptr on_wco_changed;
on_wco_saved_ptr on_wco_saved;
on_program_completed_ptr on_program_completed;
@@ -247,7 +250,6 @@ typedef struct {
on_control_signals_changed_ptr on_control_signals_changed; //!< Called from interrupt context. NOTE: this is only for cycle start and some of the optional signals.
on_unknown_realtime_cmd_ptr on_unknown_realtime_cmd; //!< Called from interrupt context.
on_unknown_sys_command_ptr on_unknown_sys_command; //!< Return Status_Unhandled if not handled.
on_get_commands_ptr on_get_commands; //!< Deprecated, use system_register_commands() to register new commands.
on_user_command_ptr on_user_command;
on_stream_changed_ptr on_stream_changed;
on_mpg_registered_ptr on_mpg_registered;
+27 -10
View File
@@ -37,20 +37,24 @@ axes_signals_t xbar_fn_to_axismask (pin_function_t fn)
mask.x = mask.y = On;
break;
#if N_AXIS > 3
#if defined(A_AXIS) || defined(B_AXIS)
case Output_StepperEnableAB:
#ifdef A_AXIS
mask.a = On;
#if N_AXIS > 4
#endif
#ifdef B_AXIS
mask.b = On;
#endif
break;
#endif
case Input_LimitX:
case Input_LimitX_Max:
case Input_LimitX_2:
case Input_HomeX:
case Input_MotorFaultX:
case Input_MotorFaultX_2:
case Output_StepperEnableX:
mask.x = On;
break;
@@ -60,6 +64,7 @@ axes_signals_t xbar_fn_to_axismask (pin_function_t fn)
case Input_HomeY:
case Input_MotorFaultY:
case Input_MotorFaultY_2:
case Output_StepperEnableY:
mask.y = On;
break;
@@ -69,53 +74,65 @@ axes_signals_t xbar_fn_to_axismask (pin_function_t fn)
case Input_HomeZ:
case Input_MotorFaultZ:
case Input_MotorFaultZ_2:
case Output_StepperEnableZ:
mask.z = On;
break;
#if N_AXIS > 3
#ifdef A_AXIS
case Input_LimitA:
case Input_LimitA_Max:
case Input_HomeA:
case Input_MotorFaultA:
case Output_StepperEnableA:
mask.a = On;
break;
#endif
#if N_AXIS > 4
#ifdef B_AXIS
case Input_LimitB:
case Input_LimitB_Max:
case Input_HomeB:
case Input_MotorFaultB:
case Output_StepperEnableB:
mask.b = On;
break;
#endif
#if N_AXIS > 5
#ifdef C_AXIS
case Input_LimitC:
case Input_LimitC_Max:
case Input_HomeC:
case Input_MotorFaultC:
case Output_StepperEnableC:
mask.c = On;
break;
#endif
#if N_AXIS > 6
#ifdef U_AXIS
case Input_LimitU:
case Input_LimitU_Max:
case Input_HomeU:
case Input_MotorFaultU:
case Output_StepperEnableU:
mask.u = On;
break;
#endif
#if N_AXIS == 8
#ifdef V_AXIS
case Input_LimitV:
case Input_LimitV_Max:
case Input_HomeV:
case Input_MotorFaultV:
case Output_StepperEnableV:
mask.v = On;
break;
#endif
#ifdef W_AXIS
case Input_LimitW:
case Input_LimitW_Max:
case Input_HomeW:
case Input_MotorFaultW:
case Output_StepperEnableW:
mask.w = On;
break;
#endif
default:
if(fn >= Output_StepperEnableX && fn <= Output_StepperEnableV)
mask.bits = (1 << (fn - Output_StepperEnableX));
break;
}
+16
View File
@@ -50,6 +50,7 @@ typedef enum {
Input_MotorFaultC,
Input_MotorFaultU,
Input_MotorFaultV,
Input_MotorFaultW,
Input_MotorFaultX_2,
Input_MotorFaultY_2,
Input_MotorFaultZ_2,
@@ -91,6 +92,9 @@ typedef enum {
Input_LimitV,
Input_LimitV_Max,
Input_HomeV,
Input_LimitW,
Input_LimitW_Max,
Input_HomeW,
Input_SpindleIndex,
Input_SpindlePulse,
Input_Aux0,
@@ -143,6 +147,7 @@ typedef enum {
Output_StepC,
Output_StepU,
Output_StepV,
Output_StepW,
Output_DirX,
Output_DirX2,
Output_DirX_2 = Output_DirX2, // deprecated
@@ -157,6 +162,7 @@ typedef enum {
Output_DirC,
Output_DirU,
Output_DirV,
Output_DirW,
Output_MotorChipSelect,
Output_MotorChipSelectX,
Output_MotorChipSelectY,
@@ -180,6 +186,7 @@ typedef enum {
Output_StepperEnableC,
Output_StepperEnableU,
Output_StepperEnableV,
Output_StepperEnableW,
Output_StepperEnableXY,
Output_StepperEnableAB,
Output_SpindleOn,
@@ -419,6 +426,15 @@ PROGMEM static const pin_name_t pin_names[] = {
{ .function = Input_LimitV_Max, .name = "V limit max" },
{ .function = Input_HomeV, .name = "V home" },
{ .function = Input_MotorFaultV, .name = "V motor fault" },
#endif
#ifdef W_AXIS
{ .function = Output_StepW, .name = "W step" },
{ .function = Output_DirW, .name = "W dir" },
{ .function = Output_StepperEnableW, .name = "W enable" },
{ .function = Input_LimitW, .name = "W limit min" },
{ .function = Input_LimitW_Max, .name = "W limit max" },
{ .function = Input_HomeW, .name = "W home" },
{ .function = Input_MotorFaultW, .name = "W motor fault" },
#endif
{ .function = Output_MotorChipSelect, .name = "Motor CS" },
{ .function = Output_MotorChipSelectX, .name = "Motor CSX" },
+1
View File
@@ -27,6 +27,7 @@
#include <stddef.h>
// Define grblHAL status codes. Valid values (0-255)
// Code 0 - 38 is equal to legacy Grbl codes
typedef enum {
Status_OK = 0,
Status_ExpectedCommandLetter = 1,
+1 -1
View File
@@ -5,7 +5,7 @@
io_expanders_init() should be called at the end of the drivers driver_init() implementation,
just before the driver claims ports.
These are NOT referenced in the core grbl code
These are NOT referenced in the core grblHAL code
Part of grblHAL
+16 -5
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -390,14 +390,10 @@ void gc_init (bool stop)
}
} else {
coord_data_t tlo;
coord_system_id_t coord_system_id = gc_state.modal.coord_system.id;
tool_offset_mode_t tool_offset_mode = gc_state.modal.tool_offset_mode;
memcpy(&tlo, gc_state.modal.tool_length_offset, sizeof(coord_data_t));
memset(&gc_state, 0, offsetof(parser_state_t, g92_coord_offset));
memcpy(gc_state.modal.tool_length_offset, &tlo, sizeof(coord_data_t));
gc_state.tool_pending = gc_state.tool->tool_id;
if(hal.tool.select)
hal.tool.select(gc_state.tool, false);
@@ -966,6 +962,16 @@ status_code_t gc_execute_block (char *block)
#endif // NGC_EXPRESSIONS_ENABLE
#ifdef ROTATION_ENABLE
static const axes_signals_t rotate_axes[] = {
{ .x = On, .y = On },
{ .x = On, .z = On },
{ .y = On, .z = On }
};
#endif
char *message = NULL;
status_code_t status = Status_OK;
struct {
@@ -3157,6 +3163,11 @@ status_code_t gc_execute_block (char *block)
} while(idx);
}
#ifdef ROTATION_ENABLE
if(gc_block.modal.g5x_offset.data.rotation != 0.0f)
rotate((coord_data_t *)gc_block.values.ijk, plane, gc_block.modal.g5x_offset.data.rotation);
#endif
// Arc radius from center to target
x -= gc_block.values.ijk[plane.axis_0]; // Delta x between circle center and target
y -= gc_block.values.ijk[plane.axis_1]; // Delta y between circle center and target
+110 -87
View File
@@ -57,6 +57,8 @@ typedef enum {
NonModal_SetHome_1 = 40, //!< 40 - G30.1
NonModal_AbsoluteOverride = 53, //!< 53 - G53
NonModal_MacroCall = 65, //!< 65 - G65
Modal_MacroCall = 66, //!< 66 - G66
Modal_MacroEnd = 67, //!< 67 - G67
NonModal_SetCoordinateOffset = 92, //!< 92 - G92
NonModal_ResetCoordinateOffset = 102, //!< 102 - G92.1
NonModal_ClearCoordinateOffset = 112, //!< 112 - G92.2
@@ -92,13 +94,13 @@ typedef enum {
MotionMode_RigidTapping = 331, //!< 331 - G33.1
MotionMode_DrillChipBreak = 73, //!< 73 - G73
MotionMode_Threading = 76, //!< 76 - G76
MotionMode_CannedCycle81 = 81, //!< 81 - G81
MotionMode_CannedCycle82 = 82, //!< 82 - G82
MotionMode_CannedCycle83 = 83, //!< 83 - G83
MotionMode_CannedCycle84 = 84, //!< 83 - G83
MotionMode_CannedCycle85 = 85, //!< 85 - G85
MotionMode_CannedCycle86 = 86, //!< 86 - G86
MotionMode_CannedCycle89 = 89, //!< 89 - G89
MotionMode_CannedCycle81 = 81, //!< 81 - G81, drill
MotionMode_CannedCycle82 = 82, //!< 82 - G82, drill with dwell
MotionMode_CannedCycle83 = 83, //!< 83 - G83, peck drill
MotionMode_CannedCycle84 = 84, //!< 83 - G84, right hand tapping - experimental
MotionMode_CannedCycle85 = 85, //!< 85 - G85, not implemented
MotionMode_CannedCycle86 = 86, //!< 86 - G86, not implemented
MotionMode_CannedCycle89 = 89, //!< 89 - G89, not implemented
MotionMode_ProbeToward = 140, //!< 140 - G38.2
MotionMode_ProbeTowardNoError = 141, //!< 141 - G38.3
MotionMode_ProbeAway = 142, //!< 142 - G38.4
@@ -365,67 +367,56 @@ typedef union {
//! Coordinate data including id.
typedef struct {
float xyz[N_AXIS];
coord_system_id_t id;
coord_system_data_t data;
} coord_system_t;
//! Axis index to plane assignment.
typedef union {
uint8_t axis[3];
struct {
uint8_t axis_0;
uint8_t axis_1;
uint8_t axis_linear;
};
} plane_t;
/*! \brief G- and M-code parameter values
After the parameters in a block is parsed into the parser blocks (parser_block_t) \a values its
corresponding \a words (#parameter_words_t) union holds which parameters were found.
__NOTE:__ Do not use single-meaning words in user defined M-codes.
__NOTE:__ Avoid using single-meaning words in user defined M-codes.
*/
typedef struct {
float d; //!< Max spindle RPM in Constant Surface Speed Mode (G96)
float e; //!< Thread taper length (G76), M67 output number
float f; //!< Feed rate - single-meaning word
float ijk[3]; //!< I,J,K Axis arc offsets
float k; //!< G33 distance per revolution
float m; //!< G65 argument.
float p; //!< G10, 664 or dwell parameters
float q; //!< User defined M-code parameter, M67 output value, G64 naive CAM tolerance, G83 delta increment
float r; //!< Arc radius or retract position
float s; //!< Spindle speed - single-meaning word
float d; //!< Max spindle RPM in Constant Surface Speed Mode (G96)
float e; //!< Thread taper length (G76), M67 output number
float f; //!< Feed rate - single-meaning word
float h; //!< Tool number or number of G76 thread spring passes
float ijk[3]; //!< I,J,K Axis arc offsets
float k; //!< G33 distance per revolution
float m; //!< G65 argument.
float p; //!< G10, 664 or dwell parameters
float q; //!< User defined M-code parameter, M67 output value, G64 naive CAM tolerance, G83 delta increment
float r; //!< Arc radius or retract position
float s; //!< Spindle speed - single-meaning word
float t; //!< Tool selection - single-meaning word //
#ifndef A_AXIS
float a;
float a; //!< G65 argument.
#endif
#ifndef B_AXIS
float b;
float b; //!< G65 argument.
#endif
#ifndef C_AXIS
float c;
float c; //!< G65 argument.
#endif
#if !defined(U_AXIS) && !AXIS_REMAP_ABC2UVW
float u;
#ifndef U_AXIS
float u; //!< G65 argument.
#endif
#if !defined(V_AXIS) && !AXIS_REMAP_ABC2UVW
float v;
#ifndef V_AXIS
float v; //!< G65 argument.
#endif
#if !AXIS_REMAP_ABC2UVW
float w;
#ifndef W_AXIS
float w; //!< G65 argument.
#endif
float xyz[N_AXIS]; //!< X,Y,Z (and A,B,C,U,V when enabled) translational axes
float xyz[N_AXIS]; //!< X,Y,Z (and A,B,C,U,V when enabled) translational axes
#if LATHE_UVW_OPTION
float uvw[3]; //!< U,V,W lathe mode incremental mode motion
float uvw[3]; //!< U,V,W lathe mode incremental mode motion
#endif
coord_system_t coord_data; //!< Coordinate data
int32_t $; //!< Spindle id - single-meaning word
int32_t n; //!< Line number - single-meaning word
uint32_t o; //!< Subroutine identifier - single-meaning word
uint32_t h; //!< Tool number or number of G76 thread spring passes
tool_id_t t; //!< Tool selection - single-meaning word
uint8_t l; //!< G10 or canned cycles parameters
int32_t $; //!< Spindle id - single-meaning word
int32_t n; //!< Line number - single-meaning word
uint32_t o; //!< Subroutine identifier - single-meaning word
uint32_t l; //!< G10, G65, G66 or canned cycles parameters
} gc_values_t;
//! Parameter words found by parser - do NOT change order!
@@ -434,9 +425,9 @@ typedef union {
uint32_t value; //!< Synonymous with \a mask.
struct {
uint32_t $ :1, //!< Spindle id.
a :1, //!< A-axis.
b :1, //!< B-axis.
c :1, //!< C-axis.
a :1, //!< A-axis or G65 argument.
b :1, //!< B-axis or G65 argument.
c :1, //!< C-axis or G65 argument.
i :1, //!< X-axis offset for arcs.
j :1, //!< Y-axis offset for arcs.
k :1, //!< Z-axis offset for arcs.
@@ -454,28 +445,15 @@ typedef union {
r :1, //!< Arc radius, canned cycle retract level.
s :1, //!< Spindle speed.
t :1, //!< Tool number.
u :1, //!< U-axis.
v :1, //!< V-axis.
w :1, //!< W-axis.
u :1, //!< U-axis or G65 argument.
v :1, //!< V-axis or G65 argument.
w :1, //!< W-axis or G65 argument.
x :1, //!< X-axis.
y :1, //!< Y-axis.
z :1; //!< Z-axis.
};
} parameter_words_t;
typedef enum {
ValueType_NA = 0,
ValueType_UInt8,
ValueType_UInt32,
ValueType_Int32,
ValueType_Float
} gc_value_type_t;
typedef struct {
const void *value;
const gc_value_type_t type;
} gc_value_ptr_t;
typedef union {
uint8_t value;
struct {
@@ -511,7 +489,7 @@ typedef struct {
plane_select_t plane_select; //!< {G17,G18,G19}
//< uint8_t cutter_comp; //!< {G40} NOTE: Don't track. Only default supported.
tool_offset_mode_t tool_offset_mode; //!< {G43,G43.1,G49}
coord_system_t coord_system; //!< {G54,G55,G56,G57,G58,G59,G59.1,G59.2,G59.3}
coord_system_t g5x_offset; //!< {G54,G55,G56,G57,G58,G59,G59.1,G59.2,G59.3}
#if ENABLE_PATH_BLENDING
control_mode_t control; //!< {G61} NOTE: Don't track. Only default supported.
#endif
@@ -603,40 +581,60 @@ typedef struct {
char name[101];
} tool_pocket_t;
typedef struct {
float angle;
point_2d_t offsets;
} rotation_t;
#if NGC_PARAMETERS_ENABLE
typedef struct g66_arguments
{
uint32_t call_level;
gc_values_t values;
parameter_words_t words;
struct g66_arguments *prev;
} g66_arguments_t;
#endif
/*! \brief Parser state
*/
typedef struct {
gc_modal_t modal;
gc_canned_t canned;
spindle_t *spindle; //!< Last referenced spindle
float feed_rate; //!< Millimeters/min
float distance_per_rev; //!< Millimeters/rev
float position[N_AXIS]; //!< Where the interpreter considers the tool to be at this point in the code
spindle_t *spindle; //!< Last referenced spindle
float feed_rate; //!< Millimeters/min
float distance_per_rev; //!< Millimeters/rev
float position[N_AXIS]; //!< Where the interpreter considers the tool to be at this point in the code
#if ENABLE_PATH_BLENDING
float path_tolerance; //!< Path blending tolerance
float cam_tolerance; //!< Naive CAM tolerance
float path_tolerance; //!< Path blending tolerance
float cam_tolerance; //!< Naive CAM tolerance
#endif
int32_t line_number; //!< Last line number sent
tool_id_t tool_pending; //!< Tool to be selected on next M6
uint32_t line_number; //!< Last line number sent
tool_id_t tool_pending; //!< Tool to be selected on next M6
#if NGC_EXPRESSIONS_ENABLE
uint32_t g43_pending; //!< Tool offset to be selected on next M6, for macro ATC
uint32_t g43_pending; //!< Tool offset to be selected on next M6, for macro ATC
#endif
bool file_run; //!< Tracks % command
bool file_stream; //!< Tracks streaming from file
bool file_run; //!< Tracks % command
bool file_stream; //!< Tracks streaming from file
bool is_laser_ppi_mode;
bool is_rpm_rate_adjusted;
bool tool_change;
bool skip_blocks; //!< true if skipping conditional blocks
status_code_t last_error; //!< last return value from parser
offset_id_t offset_id; //!< id(x) of last G92 coordinate offset (into circular buffer)
bool skip_blocks; //!< true if skipping conditional blocks
status_code_t last_error; //!< last return value from parser
offset_id_t offset_id; //!< id(x) of last G92 coordinate offset (into circular buffer)
coord_data_t offset_queue[MAX_OFFSET_ENTRIES];
//!< The following variables are not cleared upon warm restart when COMPATIBILITY_LEVEL <= 1
bool g92_coord_offset_applied; //!< true when G92 offset applied
float g92_coord_offset[N_AXIS]; //!< Retains the G92 coordinate offset (work coordinates) relative to
//!< machine zero in mm. Persistent and loaded from non-volatile storage
//!< on boot when COMPATIBILITY_LEVEL <= 1
tool_data_t *tool; //!< Tracks tool number and tool offset
bool g92_offset_applied; //!< true when G92 offset applied
coord_system_data_t g92_offset; //!< Retains the G92 coordinate offset (work coordinates) relative to
//!< machine zero in mm. Persistent and loaded from non-volatile storage
//!< on boot when COMPATIBILITY_LEVEL <= 1
tool_data_t *tool; //!< Tracks tool number and tool offset
#if NGC_PARAMETERS_ENABLE
g66_arguments_t *g66_args; //!< Linked list with G66 arguments, NULL if G66 is not active.
#endif
} parser_state_t;
typedef struct {
@@ -662,6 +660,7 @@ typedef struct {
parameter_words_t words; //!< Bitfield for tracking found parameter values.
output_command_t output_command; //!< Details about M62-M68 output command to execute if present in block.
uint32_t arc_turns; //
parameter_words_t g65_words; //!< Parameter words to pass to G65 macro.
#if NGC_PARAMETERS_ENABLE
modal_state_action_t state_action; //!< M70-M73 modal state action
#endif
@@ -675,8 +674,31 @@ static inline axes_signals_t gc_paramwords_to_axes (parameter_words_t p_words)
{
#if N_AXIS == 3
return (axes_signals_t){ (uint8_t)(p_words.mask >> 24) };
#else
#elif N_AXIS == 7
return (axes_signals_t){ (uint8_t)(((p_words.mask >> 24) | ((p_words.mask << 2) & 0b00111000) | ((p_words.mask >> (21 - 6)) & 0b11000000)) & AXES_BITMASK) };
#else
axes_signals_t axes = (axes_signals_t){ (uint8_t)(p_words.mask >> 24) };
#ifdef A_AXIS
axes.a = p_words.a;
#endif
#ifdef B_AXIS
axes.b = p_words.b;
#endif
#ifdef C_AXIS
axes.c = p_words.c;
#endif
#ifdef U_AXIS
axes.u = p_words.u;
#endif
#ifdef V_AXIS
axes.v = p_words.v;
#endif
#ifdef W_AXIS
axes.w = p_words.w;
#endif
return axes;
#endif
}
@@ -718,6 +740,7 @@ void gc_coolant (coolant_state_t state);
void gc_set_tool_offset (tool_offset_mode_t mode, uint_fast8_t idx, int32_t offset);
plane_t *gc_get_plane_data (plane_t *plane, plane_select_t select);
axes_signals_t gc_claim_axis_words (parser_block_t *gc_block, axes_signals_t validate);
#if NGC_PARAMETERS_ENABLE
parameter_words_t gc_get_g65_arguments (void);
+3 -3
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2015-2016 Sungeun K. Jeon for Gnea Research LLC
grblHAL is free software: you can redistribute it and/or modify
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20260107
#define GRBL_BUILD 20260126
#define GRBL_URL "https://github.com/grblHAL"
@@ -94,7 +94,7 @@
// Do not change unless you know what you are doing!
// Define realtime command special characters. These characters are 'picked-off' directly from the
// serial read data stream and are not passed to the grbl line execution parser. Select characters
// serial read data stream and are not passed to the grblHAL line execution parser. Select characters
// that do not and must not exist in the streamed g-code program. ASCII control characters may be
// used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in
// g-code programs, maybe selected for interface programs.
+7 -2
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2011-2015 Sungeun K. Jeon
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -447,7 +447,7 @@ int grbl_enter (void)
fs_options_t fs_options = { .hierarchical_listing = On };
fs_options.lfs_hidden = hal.driver_cap.littlefs;
fs_options.sd_mount_on_boot = hal.driver_cap.sd_card;
setting_remove_elements(Setting_FSOptions, fs_options.mask);
setting_remove_elements(Setting_FSOptions, fs_options.mask, true);
}
if(hal.stream.state.linestate_event && !hal.stream.state.passthru) {
@@ -816,3 +816,8 @@ void task_execute_on_startup (void)
grbl.on_execute_realtime(state_get());
}
}
void task_raise_alarm (void *data)
{
system_raise_alarm((alarm_code_t)data);
}
+4 -4
View File
@@ -6,18 +6,18 @@
Copyright (c) 2011-2015 Sungeun K. Jeon
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 _GRBLLIB_H_
+21 -13
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2021-2025 Terje Io
Copyright (c) 2021-2026 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
@@ -360,7 +360,7 @@ void ioport_assign_function (aux_ctrl_t *aux_ctrl, pin_function_t *function)
hal.signals_cap.mask |= aux_ctrl->signal.mask;
if(aux_ctrl->function == Input_Probe || xbar_fn_to_signals_mask(aux_ctrl->function).mask)
setting_remove_elements(Settings_IoPort_InvertIn, ports_cfg[Port_DigitalIn].bus.mask);
setting_remove_elements(Settings_IoPort_InvertIn, ports_cfg[Port_DigitalIn].bus.mask, false);
}
}
@@ -375,7 +375,7 @@ void ioport_assign_out_function (aux_ctrl_out_t *aux_ctrl, pin_function_t *funct
ports_cfg[Port_DigitalOut].bus.mask &= ~(1UL << output->id);
ports_cfg[Port_DigitalOut].count = ports_cfg[Port_DigitalOut].free = -1;
setting_remove_elements(Settings_IoPort_InvertOut, ports_cfg[Port_DigitalOut].bus.mask);
setting_remove_elements(Settings_IoPort_InvertOut, ports_cfg[Port_DigitalOut].bus.mask, false);
}
}
@@ -402,7 +402,7 @@ bool ioport_set_function (xbar_t *pin, pin_function_t function, driver_caps_t ca
if(caps.control)
hal.signals_cap.mask |= caps.control->mask;
if(function == Input_Probe || function == Input_Probe2 || function == Input_Toolsetter || xbar_fn_to_signals_mask(function).mask)
setting_remove_elements(Settings_IoPort_InvertIn, cfg->bus.mask);
setting_remove_elements(Settings_IoPort_InvertIn, cfg->bus.mask, false);
break;
case Port_DigitalOut:
@@ -418,7 +418,7 @@ bool ioport_set_function (xbar_t *pin, pin_function_t function, driver_caps_t ca
default: break;
}
setting_remove_elements(Settings_IoPort_InvertOut, cfg->bus.mask);
setting_remove_elements(Settings_IoPort_InvertOut, cfg->bus.mask, false);
break;
default: break;
@@ -744,11 +744,15 @@ static bool io_analog_out (uint8_t port, float value)
io_ports_list_t *io_port = ports;
io_ports_private_t *cfg = get_port_data(Port_Analog, Port_Output);
port = cfg->map[port];
uint8_t pn = cfg->map[port];
do {
if(io_port->hal.analog_out && is_match(io_port, Port_Analog, Port_Output, port))
return io_port->hal.analog_out(port - io_port->ports_id->cfg[Port_Output].n_start, value);
if(io_port->hal.analog_out && is_match(io_port, Port_Analog, Port_Output, pn)) {
bool ok = io_port->hal.analog_out(pn - io_port->ports_id->cfg[Port_Output].n_start, value);
if(ok && grbl.on_port_out && !(cfg->claimed.mask & (1 << pn)))
grbl.on_port_out(port, Port_Analog, value);
return ok;
}
} while((io_port = io_port->next));
return false;
@@ -759,11 +763,13 @@ static void io_digital_out (uint8_t port, bool on)
io_ports_list_t *io_port = ports;
io_ports_private_t *cfg = get_port_data(Port_Digital, Port_Output);
port = cfg->map[port];
uint8_t pn = cfg->map[port];
do {
if(io_port->hal.digital_out && is_match(io_port, Port_Digital, Port_Output, port)) {
io_port->hal.digital_out(port - io_port->ports_id->cfg[Port_Output].n_start, on);
if(io_port->hal.digital_out && is_match(io_port, Port_Digital, Port_Output, pn)) {
io_port->hal.digital_out(pn - io_port->ports_id->cfg[Port_Output].n_start, on);
if(grbl.on_port_out && !(cfg->claimed.mask & (1 << pn)))
grbl.on_port_out(port, Port_Digital, (float)on);
break;
}
} while((io_port = io_port->next));
@@ -886,8 +892,10 @@ static uint8_t add_ports (io_ports_detail_t *ports, uint8_t *map, io_port_type_t
if(p_data->ports == NULL)
p_data->ports = ports;
p_data->count = -1;
} else
} else {
ports->n_start = 255;
ports->idx_last = 0;
}
p_data->n_ports += n_ports;
ports->n_ports = n_ports;
@@ -1553,7 +1561,7 @@ static void ioports_configure (settings_t *settings)
out_config.open_drain = !!(settings->ioport.od_enable_out.mask & (1 << port));
xbar->config(xbar, &out_config, false);
} else // TODO: same for inputs?
setting_remove_elements(Settings_IoPort_InvertOut, cfg->bus.mask & ~(1 << port));
setting_remove_elements(Settings_IoPort_InvertOut, cfg->bus.mask & ~(1 << port), false);
}
} while(port);
+4 -4
View File
@@ -5,18 +5,18 @@
Copyright (c) 2019-2023 Terje Io
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 _KINEMATICS_H_
+4 -4
View File
@@ -6,18 +6,18 @@
Copyright (c) 2019 Terje Io
Copyright (c) 2011-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 _COREXY_H_
+4 -4
View File
@@ -5,18 +5,18 @@
Copyright (c) 2023 Terje Io
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 _delta_H_
+4 -4
View File
@@ -5,18 +5,18 @@
Copyright (c) 2023 Terje Io
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 _POLAR_H_
+4 -4
View File
@@ -5,18 +5,18 @@
Copyright (c) 2019 Terje Io
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 _WALL_PLOTTER_H_
+2 -2
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -438,7 +438,7 @@ static bool homing_cycle (axes_signals_t cycle, axes_signals_t auto_square)
if(rt_exec == EXEC_STATUS_REPORT) {
system_clear_exec_state_flag(EXEC_STATUS_REPORT);
report_realtime_status(hal.stream.write_all);
report_realtime_status(hal.stream.write_all, system_get_rt_report_flags());
} else {
// Homing failure condition: Reset issued during cycle.
+5 -5
View File
@@ -3,22 +3,22 @@
Part of grblHAL
Copyright (c) 2017-2023 Terje Io
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2012-2015 Sungeun K. Jeon
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 _MACHINE_LIMITS_H_
+2 -2
View File
@@ -75,7 +75,7 @@ void mc_sync_backlash_position (void)
// Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second
// unless invert_feed_rate is true. Then the feed_rate means that the motion should be completed in
// (1 minute)/feed_rate time.
// NOTE: This is the primary gateway to the grbl planner. All line motions, including arc line
// NOTE: This is the primary gateway to the grblHAL planner. All line motions, including arc line
// segments, must pass through this routine before being passed to the planner. The separation of
// mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being
// in the planner and to let backlash compensation or canned cycle integration simple and direct.
@@ -1006,7 +1006,7 @@ gc_probe_t mc_probe_cycle (float *target, plan_line_data_t *pl_data, gc_parser_f
sys.probe_position[idx] = lroundf(target[idx] * settings.axis[idx].steps_per_mm);
} while(idx);
sys.probe_coordsys_id = gc_state.modal.coord_system.id;
sys.probe_coordsys_id = gc_state.modal.g5x_offset.id;
// Finish all queued commands and empty planner buffer before starting probe cycle.
if (!protocol_buffer_synchronize())
+4 -4
View File
@@ -7,18 +7,18 @@
Copyright (c) 2011-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/>.
*/
#ifndef _MOTION_CONTROL_H_
+792 -1044
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -7,18 +7,18 @@
Copyright (c) 2020-2023 Terje Io
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 ADD_MY_PLUGIN
+155 -102
View File
@@ -95,6 +95,47 @@ static ngc_string_id_t ref_id = (uint32_t)-1;
static ngc_string_param_t *ngc_string_params = NULL;
static on_macro_execute_ptr on_macro_execute;
static const uint8_t axis_map[] = {
#ifdef ROTATION_ENABLE
10,
#else
255, // R - XY rotation angle around the Z axis. N/A.
#endif
X_AXIS,
Y_AXIS,
Z_AXIS,
#ifdef A_AXIS
A_AXIS,
#else
255,
#endif
#ifdef B_AXIS
B_AXIS,
#else
255,
#endif
#ifdef C_AXIS
C_AXIS,
#else
255,
#endif
#ifdef U_AXIS
U_AXIS,
#else
255,
#endif
#ifdef V_AXIS
V_AXIS,
#else
255,
#endif
#ifdef W_AXIS
W_AXIS
#else
255
#endif
};
#if N_AXIS > 3
static float _convert_pos (float value, uint_fast8_t axis)
@@ -113,12 +154,16 @@ static inline float _convert_pos (float value, uint_fast8_t axis)
static float _absolute_pos (uint_fast8_t axis)
{
return _convert_pos(axis < N_AXIS ? sys.position[axis] / settings.axis[axis].steps_per_mm : 0.0f, axis);
axis = axis_map[axis];
return _convert_pos(axis <= 9 ? sys.position[axis] / settings.axis[axis].steps_per_mm : 0.0f, axis);
}
static float _relative_pos (uint_fast8_t axis)
{
return _convert_pos(axis < N_AXIS ? sys.position[axis] / settings.axis[axis].steps_per_mm - gc_get_offset(axis, false) : 0.0f, axis);
axis = axis_map[axis];
return _convert_pos(axis <= 9 ? sys.position[axis] / settings.axis[axis].steps_per_mm - gc_get_offset(axis, false) : 0.0f, axis);
}
// numbered parameters
@@ -126,12 +171,12 @@ static float _relative_pos (uint_fast8_t axis)
static float probe_coord (ngc_param_id_t id)
{
float value = 0.0f;
uint_fast8_t axis = (id % 10) - 1;
coord_system_t data;
uint_fast8_t axis = axis_map[(id % 10)];
coord_system_data_t offset;
if(axis < N_AXIS && (sys.probe_coordsys_id == gc_state.modal.coord_system.id || settings_read_coord_data(sys.probe_coordsys_id, &data.xyz)))
if(axis <= 9 && (sys.probe_coordsys_id == gc_state.modal.g5x_offset.id || settings_read_coord_data(sys.probe_coordsys_id, &offset)))
value = sys.probe_position[axis] / settings.axis[axis].steps_per_mm -
(sys.probe_coordsys_id == gc_state.modal.coord_system.id ? gc_state.modal.coord_system.xyz[axis] : data.xyz[axis]);
(sys.probe_coordsys_id == gc_state.modal.g5x_offset.id ? gc_state.modal.g5x_offset.data.coord.values[axis] : offset.coord.values[axis]);
return _convert_pos(value, axis);
}
@@ -139,9 +184,9 @@ static float probe_coord (ngc_param_id_t id)
static float scaling_factors (ngc_param_id_t id)
{
float *factors = gc_get_scaling();
uint_fast8_t axis = id % 10;
uint_fast8_t axis = axis_map[(id % 10)];
return axis <= N_AXIS ? factors[axis - 1] : 0.0f;
return axis <= 9 ? factors[axis] : 0.0f;
}
static float probe_result (ngc_param_id_t id)
@@ -152,7 +197,7 @@ static float probe_result (ngc_param_id_t id)
/*
static float home_pos (ngc_param_id_t id)
{
uint_fast8_t axis = id % 10;
uint_fast8_t axis = axis_map[(id % 10)];
return axis <= N_AXIS ? sys.home_position[axis - 1] : 0.0f;
}
@@ -169,19 +214,19 @@ static float tool_number (ngc_param_id_t id)
static float tool_offset (ngc_param_id_t id)
{
uint_fast8_t axis = id % 10;
uint_fast8_t axis = axis_map[(id % 10)];
return axis <= N_AXIS ? gc_state.modal.tool_length_offset[axis] : 0.0f;
return axis <= 9 ? gc_state.modal.tool_length_offset[axis] : 0.0f;
}
static float g28_home (ngc_param_id_t id)
{
float value = 0.0f;
uint_fast8_t axis = id % 10;
coord_system_t data;
uint_fast8_t axis = axis_map[(id % 10)];
coord_system_data_t offset;
if(axis <= N_AXIS && settings_read_coord_data(CoordinateSystem_G28, &data.xyz))
value = data.xyz[axis - 1];
if(axis <= 9 && settings_read_coord_data(CoordinateSystem_G28, &offset))
value = offset.coord.values[axis];
return value;
}
@@ -189,55 +234,61 @@ static float g28_home (ngc_param_id_t id)
static float g30_home (ngc_param_id_t id)
{
float value = 0.0f;
uint_fast8_t axis = id % 10;
coord_system_t data;
uint_fast8_t axis = axis_map[(id % 10)];
coord_system_data_t offset;
#if COMPATIBILITY_LEVEL > 1
if(id <= CoordinateSystem_G59) {
#endif
if (axis <= N_AXIS && settings_read_coord_data(CoordinateSystem_G30, &data.xyz))
value = data.xyz[axis - 1];
#if COMPATIBILITY_LEVEL > 1
}
#endif
if(axis <= 9 && settings_read_coord_data(CoordinateSystem_G30, &offset))
value = offset.coord.values[axis];
return value;
}
static float coord_system (ngc_param_id_t id)
{
return (float)gc_state.modal.coord_system.id + 1;
return (float)gc_state.modal.g5x_offset.id + 1;
}
static float coord_system_offset (ngc_param_id_t id)
{
float value = 0.0f;
uint_fast8_t axis = id % 10;
coord_system_t data;
coord_system_data_t offset;
id = (id - 5220 - axis - (id == 0 ? 10 : 0)) / 20;
axis = axis_map[axis];
if (axis > 0 && axis <= N_AXIS && settings_read_coord_data((coord_system_id_t)id, &data.xyz))
value = data.xyz[axis - 1];
#if COMPATIBILITY_LEVEL > 1
if(id <= CoordinateSystem_G59) {
#endif
#ifdef ROTATION_ENABLE
if(axis <= 10 && settings_read_coord_data((coord_system_id_t)id, &offset))
value = axis == 10 ? offset.rotation : offset.coord.values[axis];
#else
if(axis <= 9 && settings_read_coord_data((coord_system_id_t)id, &offset))
value = offset.coord.values[axis];
#endif
#if COMPATIBILITY_LEVEL > 1
}
#endif
return value;
}
static float g92_offset_applied (ngc_param_id_t id)
{
return (float)gc_state.g92_coord_offset_applied;
return (float)gc_state.g92_offset_applied;
}
static float g92_offset (ngc_param_id_t id)
{
uint_fast8_t axis = id % 10;
uint_fast8_t axis = axis_map[(id % 10)];
return axis <= N_AXIS ? gc_state.g92_coord_offset [axis - 1] : 0.0f;
return axis <= 9 ? gc_state.g92_offset.coord.values[axis] : 0.0f;
}
static float work_position (ngc_param_id_t id)
{
return _relative_pos(id % 10);
return _relative_pos(id % 10 + 1);
}
static float debug_output (ngc_param_id_t id)
@@ -246,28 +297,28 @@ static float debug_output (ngc_param_id_t id)
}
PROGMEM static const ngc_ro_param_t ngc_ro_params[] = {
{ .id_min = 5061, .id_max = 5069, .get = probe_coord }, // LinuxCNC
{ .id_min = 5070, .id_max = 5070, .get = probe_result }, // LinuxCNC
{ .id_min = 5061, .id_max = 5069, .get = probe_coord }, // LinuxCNC
{ .id_min = 5070, .id_max = 5070, .get = probe_result }, // LinuxCNC
{ .id_min = 5161, .id_max = 5169, .get = g28_home },
{ .id_min = 5181, .id_max = 5189, .get = g30_home },
{ .id_min = 5191, .id_max = 5199, .get = scaling_factors }, // Mach3
{ .id_min = 5210, .id_max = 5210, .get = g92_offset_applied }, // LinuxCNC
{ .id_min = 5191, .id_max = 5199, .get = scaling_factors }, // Mach3
{ .id_min = 5210, .id_max = 5210, .get = g92_offset_applied }, // LinuxCNC
{ .id_min = 5211, .id_max = 5219, .get = g92_offset },
{ .id_min = 5220, .id_max = 5220, .get = coord_system },
{ .id_min = 5221, .id_max = 5230, .get = coord_system_offset },
{ .id_min = 5241, .id_max = 5250, .get = coord_system_offset },
{ .id_min = 5261, .id_max = 5270, .get = coord_system_offset },
{ .id_min = 5281, .id_max = 5290, .get = coord_system_offset },
{ .id_min = 5301, .id_max = 5310, .get = coord_system_offset },
{ .id_min = 5321, .id_max = 5330, .get = coord_system_offset },
{ .id_min = 5341, .id_max = 5350, .get = coord_system_offset },
{ .id_min = 5361, .id_max = 5370, .get = coord_system_offset },
{ .id_min = 5381, .id_max = 5390, .get = coord_system_offset },
{ .id_min = 5399, .id_max = 5399, .get = m66_result }, // LinuxCNC
{ .id_min = 5400, .id_max = 5400, .get = tool_number }, // LinuxCNC
{ .id_min = 5401, .id_max = 5409, .get = tool_offset }, // LinuxCNC
{ .id_min = 5420, .id_max = 5428, .get = work_position }, // LinuxCNC
{ .id_min = 5599, .id_max = 5599, .get = debug_output } // LinuxCNC
{ .id_min = 5221, .id_max = 5230, .get = coord_system_offset }, // G54
{ .id_min = 5241, .id_max = 5250, .get = coord_system_offset }, // G55
{ .id_min = 5261, .id_max = 5270, .get = coord_system_offset }, // G56
{ .id_min = 5281, .id_max = 5290, .get = coord_system_offset }, // G57
{ .id_min = 5301, .id_max = 5310, .get = coord_system_offset }, // G58
{ .id_min = 5321, .id_max = 5330, .get = coord_system_offset }, // G59
{ .id_min = 5341, .id_max = 5350, .get = coord_system_offset }, // G59.1
{ .id_min = 5361, .id_max = 5370, .get = coord_system_offset }, // G59.2
{ .id_min = 5381, .id_max = 5390, .get = coord_system_offset }, // G59.3
{ .id_min = 5399, .id_max = 5399, .get = m66_result }, // LinuxCNC
{ .id_min = 5400, .id_max = 5400, .get = tool_number }, // LinuxCNC
{ .id_min = 5401, .id_max = 5409, .get = tool_offset }, // LinuxCNC
{ .id_min = 5420, .id_max = 5428, .get = work_position }, // LinuxCNC
{ .id_min = 5599, .id_max = 5599, .get = debug_output } // LinuxCNC
};
bool ngc_param_get (ngc_param_id_t id, float *value)
@@ -402,6 +453,7 @@ PROGMEM static const ngc_named_ro_param_t ngc_named_ro_param[] = {
{ .name = "_probe_state", .id = NGCParam_probe_state },
{ .name = "_probe2_state", .id = NGCParam_probe2_state },
{ .name = "_toolsetter_state", .id = NGCParam_toolsetter_state },
{ .name = "_active_probe", .id = NGCParam_active_probe },
{ .name = "_homed_state", .id = NGCParam_homed_state },
{ .name = "_homed_axes", .id = NGCParam_homed_axes },
{ .name = "_tool_table_size", .id = NGCParam_tool_table_size },
@@ -470,10 +522,10 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
case NGCParam_coord_system:
{
uint_fast16_t id = gc_state.modal.coord_system.id * 10;
uint_fast16_t id = gc_state.modal.g5x_offset.id * 10;
if(id > (CoordinateSystem_G59 * 10))
id = (CoordinateSystem_G59 * 10) + gc_state.modal.coord_system.id - CoordinateSystem_G59;
id = (CoordinateSystem_G59 * 10) + gc_state.modal.g5x_offset.id - CoordinateSystem_G59;
value = (float)(540 + id);
}
@@ -568,7 +620,7 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
case NGCParam_v:
//no break
case NGCParam_w:
value = _relative_pos(id - NGCParam_x);
value = _relative_pos(id - NGCParam_x + 1);
break;
case NGCParam_abs_x:
@@ -588,7 +640,7 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
case NGCParam_abs_v:
//no break
case NGCParam_abs_w:
value = _absolute_pos(id - NGCParam_abs_x);
value = _absolute_pos(id - NGCParam_abs_x + 1);
break;
case NGCParam_current_tool:
@@ -625,6 +677,10 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
value = hal.driver_cap.toolsetter && hal.probe.is_triggered ? (float)hal.probe.is_triggered(Probe_Toolsetter) : -1.0f;
break;
case NGCParam_active_probe:
value = hal.probe.get_state ? (float)hal.probe.get_state().probe_id : -1.0f;
break;
case NGCParam_homed_state:
if(sys.homing.mask || settings.homing.flags.single_axis_commands || settings.homing.flags.manual) {
axes_signals_t homing = { sys.homing.mask ? sys.homing.mask : AXES_BITMASK };
@@ -917,7 +973,6 @@ gc_modal_snapshot_t *ngc_modal_state_get (void)
return call_level == -1 ? modal_state : call_levels[call_level].modal_state;
}
bool ngc_modal_state_restore (void)
{
return gc_modal_state_restore(call_level == -1 ? modal_state : call_levels[call_level].modal_state);
@@ -939,40 +994,40 @@ bool ngc_call_pop (void)
if(call_context) {
ngc_rw_param_t *rw_param = rw_params, *rw_param_last = rw_params;
ngc_rw_param_t *rw_param = rw_params, *rw_param_last = rw_params;
while(rw_param) {
if(rw_param->context == call_context) {
ngc_rw_param_t *rw_param_free = rw_param;
rw_param = rw_param->next;
if(rw_param_free == rw_params)
rw_params = rw_param_last = rw_param;
else
rw_param_last->next = rw_param;
free(rw_param_free);
} else {
rw_param_last = rw_param;
rw_param = rw_param->next;
while(rw_param) {
if(rw_param->context == call_context) {
ngc_rw_param_t *rw_param_free = rw_param;
rw_param = rw_param->next;
if(rw_param_free == rw_params)
rw_params = rw_param_last = rw_param;
else
rw_param_last->next = rw_param;
free(rw_param_free);
} else {
rw_param_last = rw_param;
rw_param = rw_param->next;
}
}
}
ngc_named_rw_param_t *rw_named_param = rw_global_params, *rw_named_param_last = rw_global_params;
ngc_named_rw_param_t *rw_named_param = rw_global_params, *rw_named_param_last = rw_global_params;
while(rw_named_param) {
if(rw_named_param->context == call_context) {
ngc_named_rw_param_t *rw_named_param_free = rw_named_param;
rw_named_param = rw_named_param->next;
if(rw_named_param_free == rw_global_params)
rw_global_params = rw_named_param_last = rw_named_param;
else
rw_named_param_last->next = rw_named_param;
free(rw_named_param_free);
} else {
rw_named_param_last = rw_named_param;
rw_named_param = rw_named_param->next;
while(rw_named_param) {
if(rw_named_param->context == call_context) {
ngc_named_rw_param_t *rw_named_param_free = rw_named_param;
rw_named_param = rw_named_param->next;
if(rw_named_param_free == rw_global_params)
rw_global_params = rw_named_param_last = rw_named_param;
else
rw_named_param_last->next = rw_named_param;
free(rw_named_param_free);
} else {
rw_named_param_last = rw_named_param;
rw_named_param = rw_named_param->next;
}
}
}
}
if(call_levels[call_level].modal_state) {
if(call_levels[call_level].modal_state->modal.auto_restore)
@@ -997,12 +1052,11 @@ uint8_t ngc_float_decimals (void)
return settings.flags.report_inches ? N_DECIMAL_COORDVALUE_INCH : N_DECIMAL_COORDVALUE_MM;
}
static status_code_t macro_set_get_setting (void)
static status_code_t macro_set_get_setting (parameter_words_t args)
{
float setting_id;
status_code_t status = Status_OK;
const setting_detail_t *setting;
parameter_words_t args = gc_get_g65_arguments();
if(!args.q)
status = Status_GcodeValueWordMissing;
@@ -1032,11 +1086,10 @@ static status_code_t macro_set_get_setting (void)
return status;
}
static status_code_t macro_ngc_parameter_rw (void)
static status_code_t macro_ngc_parameter_rw (parameter_words_t args)
{
float idx, value;
status_code_t status = Status_OK;
parameter_words_t args = gc_get_g65_arguments();
if(!args.i)
status = Status_GcodeValueWordMissing;
@@ -1060,7 +1113,7 @@ static status_code_t macro_ngc_parameter_rw (void)
return status;
}
static status_code_t macro_get_machine_state (void)
static status_code_t macro_get_machine_state (parameter_words_t args)
{
ngc_named_param_set("_value", (float)ffs(state_get()));
ngc_named_param_set("_value_returned", 1.0f);
@@ -1068,11 +1121,10 @@ static status_code_t macro_get_machine_state (void)
return Status_OK;
}
static status_code_t macro_select_probe (void)
static status_code_t macro_select_probe (parameter_words_t args)
{
float probe_id;
status_code_t status = Status_OK;
parameter_words_t args = gc_get_g65_arguments();
if(!args.q)
status = Status_GcodeValueWordMissing;
@@ -1084,11 +1136,10 @@ static status_code_t macro_select_probe (void)
return status;
}
static status_code_t macro_get_tool_offset (void)
static status_code_t macro_get_tool_offset (parameter_words_t args)
{
float tool_id, axis_id;
status_code_t status = Status_OK;
parameter_words_t args = gc_get_g65_arguments();
if(!(args.q && args.r))
status = Status_GcodeValueWordMissing;
@@ -1107,30 +1158,32 @@ static status_code_t macro_get_tool_offset (void)
return status;
}
static status_code_t onMacroExecute (macro_id_t macro_id)
static status_code_t onMacroExecute (macro_id_t macro_id, parameter_words_t args, uint32_t repeats)
{
status_code_t status = Status_Unhandled;
status_code_t status = repeats > 1 && macro_id >= 1 && macro_id <= G65Macro_LastInbuilt
? Status_GcodeValueOutOfRange
: Status_Unhandled;
switch((g65_inbuilt_t)macro_id) {
if(status == Status_Unhandled) switch((g65_inbuilt_t)macro_id) {
case G65Macro_GetSetting:
status = macro_set_get_setting();
status = macro_set_get_setting(args);
break;
case G65Macro_GetToolOffset:
status = macro_get_tool_offset();
status = macro_get_tool_offset(args);
break;
case G65Macro_ParameterRW:
status = macro_ngc_parameter_rw();
status = macro_ngc_parameter_rw(args);
break;
case G65Macro_GetMachineState:
status = macro_get_machine_state();
status = macro_get_machine_state(args);
break;
case G65Macro_SelectProbe:
status = macro_select_probe();
status = macro_select_probe(args);
break;
case G65Macro_SpindleDelayDisable:
@@ -1139,7 +1192,7 @@ static status_code_t onMacroExecute (macro_id_t macro_id)
break;
}
return status == Status_Unhandled && on_macro_execute ? on_macro_execute(macro_id) : status;
return status == Status_Unhandled && on_macro_execute ? on_macro_execute(macro_id, args, repeats) : status;
}
void ngc_params_init (void)
+3 -1
View File
@@ -103,6 +103,7 @@ typedef enum {
NGCParam_probe_state,
NGCParam_probe2_state,
NGCParam_toolsetter_state,
NGCParam_active_probe,
NGCParam_homed_state,
NGCParam_homed_axes,
NGCParam_tool_table_size,
@@ -116,7 +117,8 @@ typedef enum {
G65Macro_ParameterRW = 3,
G65Macro_GetMachineState = 4,
G65Macro_SelectProbe = 5,
G65Macro_SpindleDelayDisable = 6
G65Macro_SpindleDelayDisable = 6,
G65Macro_LastInbuilt = G65Macro_SpindleDelayDisable
} g65_inbuilt_t;
void ngc_params_init (void);
+40 -21
View File
@@ -61,36 +61,45 @@ static const float froundvalues[MAX_PRECISION + 1] =
const coord_data_t null_vector = {0};
char const *const axis_letter[N_AXIS] = {
"X",
"Y",
"Z"
static const char axis_letters[] = {
AXIS0_LETTER, '\0',
AXIS1_LETTER, '\0',
AXIS2_LETTER, '\0',
#if N_AXIS > 3
#if !AXIS_REMAP_ABC2UVW
,"A"
#else
,"U"
#endif
AXIS3_LETTER, '\0',
#endif
#if N_AXIS > 4
#if !AXIS_REMAP_ABC2UVW
,"B"
#else
,"V"
#endif
AXIS4_LETTER, '\0',
#endif
#if N_AXIS > 5
#if !AXIS_REMAP_ABC2UVW
,"C"
#else
,"W"
#endif
AXIS5_LETTER, '\0',
#endif
#if N_AXIS > 6
,"U"
AXIS6_LETTER, '\0',
#endif
#if N_AXIS > 7
,"V"
AXIS7_LETTER, '\0',
#endif
};
char const *const axis_letter[N_AXIS] = {
&axis_letters[0 << 1],
&axis_letters[1 << 1],
&axis_letters[2 << 1],
#if N_AXIS > 3
&axis_letters[3 << 1],
#endif
#if N_AXIS > 4
&axis_letters[4 << 1],
#endif
#if N_AXIS > 5
&axis_letters[5 << 1],
#endif
#if N_AXIS > 6
&axis_letters[6 << 1],
#endif
#if N_AXIS > 7
&axis_letters[7 << 1],
#endif
};
@@ -352,6 +361,16 @@ float convert_delta_vector_to_unit_vector (float *vector)
return magnitude;
}
void rotate (coord_data_t *pt, plane_t plane, float angle /*rad*/)
{
float cos = cosf(angle), sin = sinf(angle),
t0 = pt->values[plane.axis_0] * cos - pt->values[plane.axis_1] * sin,
t1 = pt->values[plane.axis_0] * sin + pt->values[plane.axis_1] * cos;
pt->values[plane.axis_0] = t0;
pt->values[plane.axis_1] = t1;
}
// parse ISO8601 datetime: YYYY-MM-DDTHH:MM:SSZxxx
struct tm *get_datetime (const char *s)
{
+236 -68
View File
@@ -53,6 +53,9 @@
#define TAN30_2 0.28867513459481288225f
#define ABORTED (sys.abort || sys.cancel)
#define IS_AXIS_LETTER(c) (AXIS3_LETTER == c || AXIS4_LETTER == c || AXIS5_LETTER == c || AXIS6_LETTER == c || AXIS7_LETTER == c)
#define IS_AXIS_LETTER_VALID(c) (c == 'A' || c == 'B' || c == 'C' || c == 'U' || c == 'V' || c == 'W')
//#define AXIS_LETTER_FN_IDX(c) ((c >= 'X' && c <= 'Z') ? ((c - 'X') << 1) : ((c >= 'A' && c <= 'C') ? c - 'A' + 6 : ((c >= 'U' && c <= 'W') ? c - 'U' + 9 : -1)))
// Convert character to uppercase
#define CAPS(c) ((c >= 'a' && c <= 'z') ? (c & 0x5F) : c)
@@ -72,54 +75,174 @@
#define Y_AXIS_BIT bit(Y_AXIS)
#define Z_AXIS_BIT bit(Z_AXIS)
#if N_AXIS > 3
#define A_AXIS 3
#define A_AXIS_BIT bit(A_AXIS)
#define AXIS3_IDX 3
#define AXIS3_BIT bit(AXIS3_IDX)
#endif
#if N_AXIS > 4
#define B_AXIS 4
#define B_AXIS_BIT bit(B_AXIS)
#define AXIS4_IDX 4
#define AXIS4_BIT bit(AXIS4_IDX)
#endif
#if N_AXIS > 5
#define C_AXIS 5
#define C_AXIS_BIT bit(C_AXIS)
#define AXIS5_IDX 5
#define AXIS5_BIT bit(AXIS5_IDX)
#endif
#if N_AXIS > 6
#define U_AXIS 6
#define U_AXIS_BIT bit(U_AXIS)
#define AXIS6_IDX 6
#define AXIS6_BIT bit(AXIS6_IDX)
#endif
#if N_AXIS == 8
#define V_AXIS 7
#define V_AXIS_BIT bit(V_AXIS)
#define AXIS7_IDX 7
#define AXIS7_BIT bit(AXIS7_IDX)
#endif
#if N_AXIS == 3
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT)
#elif N_AXIS == 4
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT)
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT)
#elif N_AXIS == 5
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT)
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT)
#elif N_AXIS == 6
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT)
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT|AXIS5_BIT)
#elif N_AXIS == 7
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT|U_AXIS_BIT)
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT|AXIS5_BIT|AXIS6_BIT)
#else
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|A_AXIS_BIT|B_AXIS_BIT|C_AXIS_BIT|U_AXIS_BIT|V_AXIS_BIT)
#define AXES_BITMASK (X_AXIS_BIT|Y_AXIS_BIT|Z_AXIS_BIT|AXIS3_BIT|AXIS4_BIT|AXIS5_BIT|AXIS6_BIT|AXIS7_BIT)
#endif
#ifdef V_AXIS
#ifdef AXIS7_IDX
#define N_ABC_AXIS 5
#elif defined(U_AXIS)
#elif defined(AXIS6_IDX)
#define N_ABC_AXIS 4
#elif defined(C_AXIS)
#elif defined(AXIS5_IDX)
#define N_ABC_AXIS 3
#elif defined(B_AXIS)
#elif defined(AXIS4_IDX)
#define N_ABC_AXIS 2
#elif defined(A_AXIS)
#elif defined(AXIS3_IDX)
#define N_ABC_AXIS 1
#else
#define N_ABC_AXIS 0
#endif
#define AXIS0_LETTER 'X'
#define AXIS1_LETTER 'Y'
#define AXIS2_LETTER 'Z'
#if N_AXIS > 3
#if AXIS_REMAP_ABC2UVW
#define AXIS3_LETTER 'U'
#elif !defined(AXIS3_LETTER)
#define AXIS3_LETTER 'A'
#elif !IS_AXIS_LETTER_VALID(AXIS3_LETTER)
#error "Illegal axis letter assigned!"
#endif
#else
#define AXIS3_LETTER 0
#endif
#if N_AXIS > 4
#if AXIS_REMAP_ABC2UVW
#define AXIS4_LETTER 'V'
#elif !defined(AXIS4_LETTER)
#define AXIS4_LETTER 'B'
#elif !IS_AXIS_LETTER_VALID(AXIS4_LETTER)
#error "Illegal axis letter assigned!"
#endif
#else
#define AXIS4_LETTER 0
#endif
#if N_AXIS > 5
#if AXIS_REMAP_ABC2UVW
#define AXIS5_LETTER 'W'
#elif !defined(AXIS5_LETTER)
#define AXIS5_LETTER 'C'
#elif !IS_AXIS_LETTER_VALID(AXIS5_LETTER)
#error "Illegal axis letter assigned!"
#endif
#else
#define AXIS5_LETTER 0
#endif
#if N_AXIS > 6
#if !defined(AXIS6_LETTER)
#define AXIS6_LETTER 'U'
#elif !IS_AXIS_LETTER_VALID(AXIS6_LETTER)
#error "Illegal axis letter assigned!"
#endif
#else
#define AXIS6_LETTER 0
#endif
#if N_AXIS > 7
#if !defined(AXIS7_LETTER)
#define AXIS7_LETTER 'V'
#elif !IS_AXIS_LETTER_VALID(AXIS7_LETTER)
#error "Illegal axis letter assigned!"
#endif
#else
#define AXIS7_LETTER 0
#endif
#if N_AXIS == 4
#define AXIS_LETTER_TO_IDX(c) AXIS3_IDX
#elif N_AXIS == 5
#define AXIS_LETTER_TO_IDX(c) \
(c == AXIS3_LETTER ? AXIS3_IDX : \
(c == AXIS4_LETTER ? AXIS4_IDX : -1))
#elif N_AXIS == 6
#define AXIS_LETTER_TO_IDX(c) \
(c == AXIS3_LETTER ? AXIS3_IDX : \
(c == AXIS4_LETTER ? AXIS4_IDX : \
(c == AXIS5_LETTER ? AXIS5_IDX : -1)))
#elif N_AXIS == 7
#define AXIS_LETTER_TO_IDX(c) \
(c == AXIS3_LETTER ? AXIS3_IDX : \
(c == AXIS4_LETTER ? AXIS4_IDX : \
(c == AXIS5_LETTER ? AXIS5_IDX : \
(c == AXIS6_LETTER ? AXIS6_IDX : -1))))
#elif N_AXIS == 8
#define AXIS_LETTER_TO_IDX(c) \
(c == AXIS3_LETTER ? AXIS3_IDX : \
(c == AXIS4_LETTER ? AXIS4_IDX : \
(c == AXIS5_LETTER ? AXIS5_IDX : \
(c == AXIS6_LETTER ? AXIS6_IDX : \
(c == AXIS7_LETTER ? AXIS7_IDX : -1)))))
#endif
#if IS_AXIS_LETTER('A')
#define A_AXIS AXIS_LETTER_TO_IDX('A')
#define A_AXIS_BIT bit(A_AXIS)
#endif
#if IS_AXIS_LETTER('B')
#define B_AXIS AXIS_LETTER_TO_IDX('B')
#define B_AXIS_BIT bit(B_AXIS)
#endif
#if IS_AXIS_LETTER('C')
#define C_AXIS AXIS_LETTER_TO_IDX('C')
#define C_AXIS_BIT bit(C_AXIS)
#endif
#if !LATHE_UVW_OPTION
#if IS_AXIS_LETTER('U')
#define U_AXIS AXIS_LETTER_TO_IDX('U')
#define U_AXIS_BIT bit(U_AXIS)
#endif
#if IS_AXIS_LETTER('V')
#define V_AXIS AXIS_LETTER_TO_IDX('V')
#define V_AXIS_BIT bit(V_AXIS)
#endif
#if IS_AXIS_LETTER('W')
#define W_AXIS AXIS_LETTER_TO_IDX('W')
#define W_AXIS_BIT bit(W_AXIS)
#endif
#endif
typedef union {
uint8_t mask;
uint8_t bits;
@@ -127,12 +250,38 @@ typedef union {
struct {
uint8_t x :1,
y :1,
z :1,
a :1,
b :1,
c :1,
u :1,
v :1;
z :1
#if N_AXIS > 3
#ifdef A_AXIS
, a :1
#endif
#ifdef B_AXIS
, b :1
#endif
#ifdef C_AXIS
, c :1
#endif
#ifdef U_AXIS
, u :1
#endif
#ifdef V_AXIS
, v :1
#endif
#ifdef W_AXIS
, w :1
#endif
#endif
;
};
struct {
uint8_t a0 :1,
a1 :1,
a2 :1,
a3 :1,
a4 :1,
a5 :1,
a6 :1,
a7 :1;
};
} axes_signals_t;
@@ -143,64 +292,62 @@ typedef union {
float x;
float y;
float z;
#ifdef A_AXIS
float a;
#endif
#ifdef B_AXIS
float b;
#endif
#ifdef C_AXIS
float c;
#endif
#ifdef U_AXIS
float u;
#endif
#ifdef V_AXIS
float v;
#endif
};
struct {
float m0;
float m1;
float m2;
#if N_AXIS > 3
float m3;
#endif
#if N_AXIS > 4
float m4;
#endif
#if N_AXIS > 5
float m5;
#endif
#if N_AXIS > 6
float m6;
#endif
#if N_AXIS == 8
float m7;
#ifdef A_AXIS
float a;
#endif
#ifdef B_AXIS
float b;
#endif
#ifdef C_AXIS
float c;
#endif
#ifdef U_AXIS
float u;
#endif
#ifdef V_AXIS
float v;
#endif
#ifdef W_AXIS
float w;
#endif
#endif
};
} coord_data_t;
//! Coordinate system data.
typedef struct {
coord_data_t coord;
#ifdef ROTATION_ENABLE
float rotation;
#endif
} coord_system_data_t;
typedef union {
int32_t value[N_AXIS];
struct {
int32_t x;
int32_t y;
int32_t z;
#ifdef A_AXIS
#if N_AXIS > 3
#ifdef B_AXIS
int32_t a;
#endif
#ifdef B_AXIS
#endif
#ifdef B_AXIS
int32_t b;
#endif
#ifdef C_AXIS
#endif
#ifdef C_AXIS
int32_t c;
#endif
#ifdef U_AXIS
#endif
#ifdef U_AXIS
int32_t u;
#endif
#ifdef V_AXIS
#endif
#ifdef V_AXIS
int32_t v;
#endif
#ifdef W_AXIS
int32_t w;
#endif
#endif
};
} mpos_t;
@@ -213,6 +360,25 @@ typedef union {
};
} point_2d_t;
typedef union {
float values[3];
struct {
float x;
float y;
float z;
};
} point_3d_t;
//! Axis index to plane assignment.
typedef union {
uint8_t axis[3];
struct {
uint8_t axis_0;
uint8_t axis_1;
uint8_t axis_linear;
};
} plane_t;
#pragma pack(push, 1)
//! \brief Limit switches struct, consists of four packed axes_signals_t structs in 32 bits.
@@ -335,6 +501,8 @@ bool delay_sec (float seconds, delaymode_t mode);
float convert_delta_vector_to_unit_vector(float *vector);
void rotate (coord_data_t *pt, plane_t plane, float angle /*rad*/);
// parse ISO8601 datetime
struct tm *get_datetime (const char *s);
+3 -3
View File
@@ -42,14 +42,14 @@ Must be >= NVS_SIZE.
#define NVS_CRC_BYTES 2
#endif
#define NVS_SIZE_PARAMETERS ((sizeof(coord_data_t) + NVS_CRC_BYTES) * N_CoordinateSystems)
#define NVS_SIZE_PARAMETERS ((sizeof(coord_system_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, more if > 5 axes enabled.
*/
#if N_AXIS > 5
#if N_AXIS > 5 || (N_AXIS > 4 && defined(ROTATION_ENABLE))
#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
@@ -69,7 +69,7 @@ __NOTE:__ 1024 bytes of persistent storage is the minimum required.
*/
///@{
#define NVS_ADDR_GLOBAL 1U
#if N_AXIS > 5
#if N_AXIS > 5 || (N_AXIS > 4 && defined(ROTATION_ENABLE))
#define NVS_ADDR_PARAMETERS ((sizeof(settings_t) + NVS_CRC_BYTES + 4) & 0xFFFC) // align to word boundary
#else
#define NVS_ADDR_PARAMETERS 512U
+4 -4
View File
@@ -58,7 +58,7 @@ typedef struct {
#define NVS_GROUP_STARTUP 3
#define NVS_GROUP_BUILD 4
#define PARAMETER_ADDR(n) (NVS_ADDR_PARAMETERS + n * (sizeof(coord_data_t) + NVS_CRC_BYTES))
#define PARAMETER_ADDR(n) (NVS_ADDR_PARAMETERS + n * (sizeof(coord_system_data_t) + NVS_CRC_BYTES))
#define STARTLINE_ADDR(n) (NVS_ADDR_STARTUP_BLOCK + n * (sizeof(stored_line_t) + NVS_CRC_BYTES))
#if N_TOOLS
#define TOOL_ADDR(n) (NVS_ADDR_TOOL_TABLE + n * (sizeof(tool_data_t) + NVS_CRC_BYTES))
@@ -352,8 +352,8 @@ void nvs_buffer_sync_physical (void)
idx = N_CoordinateSystems;
if(settings_dirty.coord_data) do {
if(bit_istrue(settings_dirty.coord_data, bit(idx))) {
offset = NVS_ADDR_PARAMETERS + idx * (sizeof(coord_data_t) + NVS_CRC_BYTES);
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer.addr + offset), sizeof(coord_data_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
offset = NVS_ADDR_PARAMETERS + idx * (sizeof(coord_system_data_t) + NVS_CRC_BYTES);
if(physical_nvs.memcpy_to_nvs(offset, (uint8_t *)(nvsbuffer.addr + offset), sizeof(coord_system_data_t) + NVS_CRC_BYTES, false) == NVS_TransferResult_OK)
bit_false(settings_dirty.coord_data, bit(idx));
}
} while(idx--);
@@ -425,7 +425,7 @@ void nvs_memmap (void)
strcat(buf, " ");
strcat(buf, uitoa(NVS_SIZE_PARAMETERS));
strcat(buf, " ");
strcat(buf, uitoa(NVS_ADDR_PARAMETERS + N_CoordinateSystems * (sizeof(coord_data_t) + NVS_CRC_BYTES)));
strcat(buf, uitoa(NVS_ADDR_PARAMETERS + N_CoordinateSystems * (sizeof(coord_system_data_t) + NVS_CRC_BYTES)));
report_message(buf, Message_Plain);
strcpy(buf, "Startup block: ");
+4 -4
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_BUFFER_H_
+4 -4
View File
@@ -7,18 +7,18 @@
Copyright (c) 2017-2023 Terje Io
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/>.
*/
#include "grbl.h"
+4 -4
View File
@@ -7,18 +7,18 @@
Copyright (c) 2016-2023 Terje Io
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 _OVERRIDE_H_
+5 -5
View File
@@ -3,24 +3,24 @@
PID algorithm for closed loop control
NOTE: not referenced in the core grbl code
NOTE: not referenced in the core grblHAL code
Part of grblHAL
Copyright (c) 2020-2021 Terje Io
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/>.
*/
#include <string.h>
+5 -5
View File
@@ -3,24 +3,24 @@
PID algorithm for closed loop control
NOTE: not referenced in the core grbl code
NOTE: not referenced in the core grblHAL code
Part of grblHAL
Copyright (c) 2020-2023 Terje Io
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 _PID_H_
+71 -4
View File
@@ -330,10 +330,12 @@ static inline void aux_ctrl_claim_ports (aux_claim_explicit_ptr aux_claim_explic
pin_cap_t cap = { .irq_mode = aux_ctrl[idx].irq_mode, .claimable = On };
if(aux_ctrl[idx].gpio.pin == 0xFE) // Toolsetter and Probe2
ioports_enumerate(Port_Digital, Port_Input, cap, __find_in_port, (void *)&aux_ctrl[idx]);
// Toolsetter and Probe2
if(aux_ctrl[idx].gpio.pin == 0xFE && ioports_enumerate(Port_Digital, Port_Input, cap, __find_in_port, (void *)&aux_ctrl[idx]))
aux_claim_explicit(&aux_ctrl[idx]);
#ifdef STM32_PLATFORM
if(aux_ctrl[idx].irq_mode == IRQ_Mode_None && !(aux_ctrl[idx].function == Input_Probe || aux_ctrl[idx].function == Input_LimitsOverride))
if(aux_ctrl[idx].irq_mode == IRQ_Mode_None && !(aux_ctrl_is_probe(aux_ctrl[idx].function) || aux_ctrl[idx].function == Input_LimitsOverride))
continue;
#endif
if(aux_ctrl[idx].gpio.pin == 0xFF) {
@@ -617,7 +619,72 @@ static inline void aux_ctrl_claim_out_ports (aux_claim_explicit_out_ptr aux_clai
#define DEVICES_IRQ_MASK_SUM (SPI_IRQ_BIT+SPINDLE_INDEX_BIT+QEI_A_BIT+QEI_B_BIT+SD_DETECT_BIT)
#endif
// Auxillary input signals
#ifdef STM32_PLATFORM
// Used for validating pins that requires IRQ capabilities
#ifdef RESET_PIN
#define RESET_BIT (1<<RESET_PIN)
#else
#define RESET_BIT 0
#endif
#ifdef FEED_HOLD_PIN
#define FEED_HOLD_BIT (1<<FEED_HOLD_PIN)
#else
#define FEED_HOLD_BIT 0
#endif
#ifdef CYCLE_START_PIN
#define CYCLE_START_BIT (1<<CYCLE_START_PIN)
#else
#define CYCLE_START_BIT 0
#endif
#ifdef PROBE_DISCONNECT_PIN
#define PROBE_DISCONNECT_BIT (1<<PROBE_DISCONNECT_PIN)
#else
#define PROBE_DISCONNECT_BIT 0
#endif
#ifdef STOP_DISABLE_PIN
#define STOP_DISABLE_BIT (1<<STOP_DISABLE_PIN)
#else
#define STOP_DISABLE_BIT 0
#endif
#ifdef BLOCK_DELETE_PIN
#define BLOCK_DELETE_BIT (1<<BLOCK_DELETE_PIN)
#else
#define BLOCK_DELETE_BIT 0
#endif
#ifdef SINGLE_BLOCK_PIN
#define SINGLE_BLOCK_BIT (1<<SINGLE_BLOCK_PIN)
#else
#define SINGLE_BLOCK_BIT 0
#endif
#ifdef MOTOR_FAULT_PIN
#define MOTOR_FAULT_BIT (1<<MOTOR_FAULT_PIN)
#else
#define MOTOR_FAULT_BIT 0
#endif
#ifdef MOTOR_WARNING_PIN
#define MOTOR_WARNING_BIT (1<<MOTOR_WARNING_PIN)
#else
#define MOTOR_WARNING_BIT 0
#endif
#ifndef CONTROL_MASK
#define CONTROL_MASK (RESET_BIT|FEED_HOLD_BIT|CYCLE_START_BIT|PROBE_DISCONNECT_BIT|STOP_DISABLE_BIT|BLOCK_DELETE_BIT|SINGLE_BLOCK_BIT|MOTOR_FAULT_BIT|MOTOR_WARNING_BIT)
#define CONTROL_MASK_SUM (RESET_BIT+FEED_HOLD_BIT+CYCLE_START_BIT+PROBE_DISCONNECT_BIT+STOP_DISABLE_BIT+BLOCK_DELETE_BIT+SINGLE_BLOCK_BIT+MOTOR_FAULT_BIT+MOTOR_WARNING_BIT)
#endif
#endif // STM32_PLATFORM
// Auxiliary input signals
#ifdef AUXINPUT0_PIN
#define AUXINPUT0_BIT (1<<AUXINPUT0_PIN)
+42 -29
View File
@@ -321,10 +321,10 @@ float plan_compute_profile_nominal_speed (plan_block_t *block)
nominal_speed *= (0.01f * (float)sys.override.rapid_rate);
else {
if(sys.override.feed_rate != 100 && !block->condition.no_feed_override) {
if(nominal_speed > block->rapid_rate)
nominal_speed = block->rapid_rate;
if(nominal_speed > block->rapid_rate)
nominal_speed = block->rapid_rate;
nominal_speed *= (0.01f * (float)sys.override.feed_rate);
}
}
if(nominal_speed > block->rapid_rate)
nominal_speed = block->rapid_rate;
}
@@ -424,6 +424,10 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
block->offset_id = pl_data->offset_id;
block->output_commands = pl_data->output_commands;
block->message = pl_data->message;
#if PLANNER_ADD_MOTION_MODE
if((block->motion_mode = pl_data->motion_mode) == MotionMode_Seek && !block->condition.rapid_motion)
block->motion_mode = MotionMode_Linear;
#endif
memcpy(block->target_mm, target, sizeof(float) * N_AXIS);
// Copy position data based on type of motion being planned.
@@ -528,24 +532,28 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
#endif
block->millimeters = convert_delta_vector_to_unit_vector(unit_vec);
#if ENABLE_JERK_ACCELERATION
block->max_acceleration = limit_acceleration_by_axis_maximum(unit_vec);
block->jerk = limit_jerk_by_axis_maximum(unit_vec);
#else
block->acceleration = limit_acceleration_by_axis_maximum(unit_vec);
#if ENABLE_ACCELERATION_PROFILES // recalculate the acceleration limits when enabled.
// block->acceleration_factor = pl_data->acceleration_factor;
#endif
#if ENABLE_JERK_ACCELERATION
if((block->condition.jerk = !(block->condition.jog_motion || block->condition.system_motion || block->spindle.state.synchronized))) {
block->max_acceleration = limit_acceleration_by_axis_maximum(unit_vec);
block->jerk = limit_jerk_by_axis_maximum(unit_vec);
#if ENABLE_ACCELERATION_PROFILES
block->max_acceleration *= pl_data->acceleration_factor;
block->jerk *= pl_data->acceleration_factor;
#endif
} else
#endif // ENABLE_JERK_ACCELERATION
{
block->acceleration = limit_acceleration_by_axis_maximum(unit_vec);
#if ENABLE_ACCELERATION_PROFILES
block->acceleration *= pl_data->acceleration_factor;
#endif
}
block->rapid_rate = limit_max_rate_by_axis_maximum(unit_vec);
#ifdef KINEMATICS_API
block->rate_multiplier = pl_data->rate_multiplier;
#endif
#if ENABLE_ACCELERATION_PROFILES // recalculate the acceleration limits when enabled.
block->acceleration_factor = pl_data->acceleration_factor;
#if ENABLE_JERK_ACCELERATION
block->max_acceleration *= block->acceleration_factor;
block->jerk *= block->acceleration_factor;
#else
block->acceleration *= block->acceleration_factor;
#endif
#endif
// Store programmed rate.
@@ -556,23 +564,28 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
if (block->condition.inverse_time)
block->programmed_rate *= block->millimeters;
}
#if ENABLE_JERK_ACCELERATION
// Calculate effective acceleration over block. Since jerk acceleration takes longer to execute due to ramp up and
// ramp down of the acceleration at the start and end of a ramp we need to adjust the acceleration value the planner
// uses so it still calculates reasonable entry speeds, exit speeds and times to decelerate/accelerate.
// 2 general cases emerge:
// -slow speed regime: uncomplete jerk ramp (max_acceleration is not reached)
// -slow speed regime: incomplete jerk ramp (max_acceleration is not reached)
// -high speed regime: complete jerk ramp + time at max_axcel to reach desired programmed_rates
// Profiles are calculated as symmetrical (calculate to 1/2 programmed rate, then double)
float time_to_max_accel = block->max_acceleration / block->jerk; // unit: min - time it takes to reach max acceleration
float speed_after_jerkramp = 0.5f * block->jerk * time_to_max_accel * time_to_max_accel; // unit: mm / min - velocity after one completed jerk ramp up - Vt = V0 + A0T + 1/2 jerk*T
if(0.5f * block->programmed_rate > speed_after_jerkramp)
// Profile time = 2x (1 complete jerk ramp + additional time at max_accel to reach desired speed)
block->acceleration = block->programmed_rate / (2.0f *(time_to_max_accel + (0.5f * block->programmed_rate - speed_after_jerkramp) / block->max_acceleration));
else
// Max Accel is not reached. time_to_halfvelocity = sqrt( 0.5 programmed_rate * 2 / jerk) -> derived from Vt = V0 + A0T + 1/2 jerk*T (v0 and a0t == 0 in this case)
block->acceleration = block->programmed_rate / (2.0f * sqrt(block->programmed_rate / block->jerk));
#endif
if(block->condition.jerk) {
float time_to_max_accel = block->max_acceleration / block->jerk; // unit: min - time it takes to reach max acceleration
float speed_after_jerkramp = 0.5f * block->jerk * time_to_max_accel * time_to_max_accel; // unit: mm / min - velocity after one completed jerk ramp up - Vt = V0 + A0T + 1/2 jerk*T
if(0.5f * block->programmed_rate > speed_after_jerkramp)
// Profile time = 2x (1 complete jerk ramp + additional time at max_accel to reach desired speed)
block->acceleration = block->programmed_rate / (2.0f * (time_to_max_accel + (0.5f * block->programmed_rate - speed_after_jerkramp) / block->max_acceleration));
else
// Max Accel is not reached. time_to_halfvelocity = sqrt(0.5 * programmed_rate * 2 / jerk) -> derived from Vt = V0 + A0T + 1/2 jerk*T (v0 and a0t == 0 in this case)
block->acceleration = block->programmed_rate / (2.0f * sqrt(block->programmed_rate / block->jerk));
}
#endif // ENABLE_JERK_ACCELERATION
// TODO: Need to check this method handling zero junction speeds when starting from rest.
if ((block_buffer_head == block_buffer_tail) || (block->condition.system_motion)) {
@@ -594,8 +607,8 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
// from path, but used as a robust way to compute cornering speeds, as it takes into account the
// nonlinearities of both the junction angle and junction velocity.
//
// NOTE: If the junction deviation value is finite, Grbl executes the motions in an exact path
// mode (G61). If the junction deviation value is zero, Grbl will execute the motion in an exact
// NOTE: If the junction deviation value is finite, grblHAL executes the motions in an exact path
// mode (G61). If the junction deviation value is zero, grblHAL will execute the motion in an exact
// stop mode (G61.1) manner. In the future, if continuous mode (G64) is desired, the math here
// is exactly the same. Instead of motioning all the way to junction point, the machine will
// just follow the arc circle defined here. The Arduino doesn't have the CPU cycles to perform
+18 -4
View File
@@ -39,7 +39,12 @@ typedef union {
target_valid :1,
target_validated :1,
probing_toolsetter :1,
#if ENABLE_JERK_ACCELERATION
jerk :1,
unassigned :3;
#else
unassigned :4;
#endif
coolant_state_t coolant;
};
} planner_cond_t;
@@ -64,6 +69,9 @@ typedef union {
#endif
#ifdef V_AXIS
uint32_t v;
#endif
#ifdef W_AXIS
uint32_t w;
#endif
};
} steps_t;
@@ -81,7 +89,7 @@ typedef struct plan_block {
// Block condition data to ensure correct execution depending on states and overrides.
gc_override_flags_t overrides; // Block bitfield variable for overrides
planner_cond_t condition; // Block bitfield variable defining block run conditions. Copied from pl_line_data.
int32_t line_number; // Block line number for real-time reporting. Copied from pl_line_data.
uint32_t line_number; // Block line number for real-time reporting. Copied from pl_line_data.
float target_mm[N_AXIS]; // Block target end location in mm for real-time reporting of distance to go.
// Fields used by the motion planner to manage acceleration. Some of these values may be updated
@@ -105,9 +113,12 @@ typedef struct plan_block {
float rate_multiplier; // Rate multiplier of this block.
#endif
#if ENABLE_ACCELERATION_PROFILES
float acceleration_factor; // Stores the currently used acceleration factor.
// float acceleration_factor; // Stores the currently used acceleration factor.
#endif
// Stored spindle speed data used by spindle overrides and resuming methods.
#if PLANNER_ADD_MOTION_MODE
motion_mode_t motion_mode;
#endif
// Stored spindle speed data used by spindle overrides and resuming methods.
spindle_t spindle; // Block spindle parameters. Copied from pl_line_data.
char *message; // Message to be displayed when block is executed.
@@ -128,12 +139,15 @@ typedef struct {
#if ENABLE_PATH_BLENDING
float path_tolerance; //!< Path blending tolerance.
float cam_tolerance; //!< Naive CAM tolerance.
#endif
#if PLANNER_ADD_MOTION_MODE
motion_mode_t motion_mode;
#endif
spindle_t spindle; // Desired spindle parameters, such as RPM, through line motion.
planner_cond_t condition; // Bitfield variable to indicate planner conditions. See defines above.
gc_override_flags_t overrides; // Block bitfield variable for overrides
offset_id_t offset_id;
int32_t line_number; // Desired line number to report when executing.
uint32_t line_number; // Desired line number to report when executing.
// void *parameters; // TODO: pointer to extra parameters, for canned cycles and threading?
char *message; // Message to be displayed when block is executed.
output_command_t *output_commands;
+5 -1
View File
@@ -3,7 +3,7 @@
Some data structures and function declarations for plugins that require driver code
These are NOT referenced in the core grbl code
These are NOT referenced in the core grblHAL code
Part of grblHAL
@@ -112,6 +112,7 @@ typedef struct {
const char *interface;
bool is_ethernet;
bool link_up;
bool dhcp; // TODO: move to network_services_t in next settings revision.
uint16_t mbps;
char mac[18];
char mqtt_client_id[18];
@@ -167,6 +168,9 @@ typedef enum {
Encoder_MPG_A,
Encoder_MPG_B,
Encoder_MPG_C,
Encoder_MPG_U,
Encoder_MPG_V,
Encoder_MPG_W,
Encoder_Spindle_Position
} encoder_mode_t;
+7 -3
View File
@@ -3,7 +3,7 @@
Calls the init function of enabled plugins, may be included at the end of the drivers driver_init() implementation.
These are NOT referenced in the core grbl code
These are NOT referenced in the core grblHAL code
Part of grblHAL
@@ -166,7 +166,7 @@
embroidery_init();
#endif
#if RGB_LED_ENABLE
#if RGB_LED_ENABLE > 1
extern void rgb_led_init (void);
rgb_led_init();
#endif
@@ -239,10 +239,14 @@
#endif
#if ATCI_ENABLE
extern void atci_init(void);
extern void atci_init (void);
atci_init();
#endif
#if M800_ENABLE
extern void keyway_init (void);
keyway_init();
#endif
// End third party plugin definitions.
+6 -15
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -388,7 +388,7 @@ void protocol_auto_cycle_start (void)
// from various check points in the main program, primarily where there may be a while loop waiting
// for a buffer to clear space or any point where the execution time from the last check point may
// be more than a fraction of a second. This is a way to execute realtime commands asynchronously
// (aka multitasking) with grbl's g-code parsing and planning functions. This function also serves
// (aka multitasking) with grblHAL's g-code parsing and planning functions. This function also serves
// as an interface for the interrupts to set the system realtime flags, where only the main program
// handles them, removing the need to define more computationally-expensive volatile variables. This
// also provides a controlled way to execute certain tasks without having two or more instances of
@@ -499,7 +499,7 @@ bool protocol_exec_rt_system (void)
if(bit_istrue(sys.rt_exec_state, EXEC_STATUS_REPORT)) {
system_clear_exec_state_flag(EXEC_STATUS_REPORT);
report_realtime_status(hal.stream.write_all);
report_realtime_status(hal.stream.write_all, system_get_rt_report_flags());
}
protocol_poll_cmd();
@@ -599,10 +599,10 @@ bool protocol_exec_rt_system (void)
// Execute and print status to output stream
if (rt_exec & EXEC_STATUS_REPORT)
report_realtime_status(hal.stream.write_all);
report_realtime_status(hal.stream.write_all, system_get_rt_report_flags());
if(rt_exec & EXEC_GCODE_REPORT)
report_gcode_modes();
report_gcode_modes(hal.stream.write);
if(rt_exec & EXEC_TLO_REPORT)
report_tool_offsets();
@@ -860,16 +860,7 @@ ISR_CODE bool ISR_FUNC(protocol_enqueue_realtime_command)(uint8_t c)
#endif
case CMD_STATUS_REPORT_ALL: // Add all statuses to report
{
report_tracking_flags_t report;
report.value = (uint32_t)Report_All;
report.tool_offset = sys.report.tool_offset;
report.m66result = sys.var5399 > -2;
report.probe_id = !!hal.probe.select;
system_add_rt_report((report_tracking_t)report.value);
}
system_add_rt_report(report_get_rt_flags_all().value);
system_set_exec_state_flag(EXEC_STATUS_REPORT);
drop = true;
break;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
protocol.h - controls Grbl execution protocol and procedures
protocol.h - controls grblHAL execution protocol and procedures
Part of grblHAL
+132 -67
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
grblHAL is free software: you can redistribute it and/or modify
@@ -598,7 +598,7 @@ status_code_t report_named_ngc_parameter (char *arg)
void report_ngc_parameters (void)
{
uint_fast8_t idx;
float coord_data[N_AXIS];
coord_system_data_t offset;
if(gc_state.modal.scaling_active) {
hal.stream.write("[G51:");
@@ -606,16 +606,16 @@ void report_ngc_parameters (void)
hal.stream.write("]" ASCII_EOL);
}
for (idx = 0; idx < N_CoordinateSystems; idx++) {
for(idx = 0; idx < N_CoordinateSystems; idx++) {
if (!(settings_read_coord_data((coord_system_id_t)idx, &coord_data))) {
if(!(settings_read_coord_data((coord_system_id_t)idx, &offset))) {
grbl.report.status_message(Status_SettingReadFail);
return;
}
hal.stream.write("[G");
switch (idx) {
switch(idx) {
case CoordinateSystem_G28:
hal.stream.write("28");
@@ -635,14 +635,20 @@ void report_ngc_parameters (void)
if(idx != CoordinateSystem_G92) {
hal.stream.write(":");
hal.stream.write(get_axis_values(coord_data));
hal.stream.write(get_axis_values(offset.coord.values));
#ifdef ROTATION_ENABLE
if(idx < N_WorkCoordinateSystems) {
hal.stream.write(":");
hal.stream.write(ftoa(offset.rotation * DEGRAD, 2));
}
#endif
hal.stream.write("]" ASCII_EOL);
}
}
// Print G92, G92.1 which are not persistent in memory
hal.stream.write("92:");
hal.stream.write(get_axis_values(gc_state.g92_coord_offset));
hal.stream.write(get_axis_values(gc_state.g92_offset.coord.values));
hal.stream.write("]" ASCII_EOL);
tool_data_t *tool_data;
@@ -695,66 +701,83 @@ static inline bool is_g92_active (void)
do {
idx--;
active = !(gc_state.g92_coord_offset[idx] == 0.0f || gc_state.g92_coord_offset[idx] == -0.0f);
active = !(gc_state.g92_offset.coord.values[idx] == 0.0f || gc_state.g92_offset.coord.values[idx] == -0.0f);
} while(idx && !active);
return active;
}
// Print current gcode parser mode state
void report_gcode_modes (void)
// Convert motion mode (G0, G1, ...) to string.
static char *motionmode_to_str (char *buf, motion_mode_t mode)
{
hal.stream.write("[GC:G");
if (gc_state.modal.motion >= MotionMode_ProbeToward) {
hal.stream.write("38.");
hal.stream.write(uitoa((uint32_t)(gc_state.modal.motion - (MotionMode_ProbeToward - 2))));
} else
hal.stream.write(uitoa((uint32_t)gc_state.modal.motion));
strcpy(buf, "G");
hal.stream.write(" ");
hal.stream.write(gc_coord_system_to_str(gc_state.modal.coord_system.id));
if(mode == MotionMode_QuadraticSpline || mode == MotionMode_RigidTapping) {
strcat(buf, uitoa(mode / 10));
strcat(buf, ".1");
} else if(mode >= MotionMode_ProbeToward) {
strcat(buf, "38.");
strcat(buf, uitoa((uint32_t)(mode - (MotionMode_ProbeToward - 2))));
} else
strcat(buf, uitoa((uint32_t)mode));
return buf;
}
// Print current gcode parser mode state
void report_gcode_modes (stream_write_ptr stream_write)
{
stream_write("[GC:");
stream_write(motionmode_to_str(buf, gc_state.modal.motion));
stream_write(" ");
stream_write(gc_coord_system_to_str(gc_state.modal.g5x_offset.id));
#if COMPATIBILITY_LEVEL < 10
if(is_g92_active())
hal.stream.write(" G92");
stream_write(" G92");
#endif
if(settings.mode == Mode_Lathe)
hal.stream.write(gc_state.modal.diameter_mode ? " G7" : " G8");
stream_write(gc_state.modal.diameter_mode ? " G7" : " G8");
hal.stream.write(" G");
hal.stream.write(uitoa((uint32_t)(gc_state.modal.plane_select + 17)));
stream_write(" G");
stream_write(uitoa((uint32_t)(gc_state.modal.plane_select + 17)));
hal.stream.write(gc_state.modal.units_imperial ? " G20" : " G21");
stream_write(gc_state.modal.units_imperial ? " G20" : " G21");
hal.stream.write(gc_state.modal.distance_incremental ? " G91" : " G90");
#if NGC_PARAMETERS_ENABLE
if(gc_state.g66_args)
stream_write(" G66");
#endif
hal.stream.write(" G");
hal.stream.write(uitoa((uint32_t)(93 + (gc_state.modal.feed_mode == FeedMode_UnitsPerRev ? 2 : gc_state.modal.feed_mode ^ 1))));
stream_write(gc_state.modal.distance_incremental ? " G91" : " G90");
stream_write(" G");
stream_write(uitoa((uint32_t)(93 + (gc_state.modal.feed_mode == FeedMode_UnitsPerRev ? 2 : gc_state.modal.feed_mode ^ 1))));
if(settings.mode == Mode_Lathe && gc_spindle_get(0)->hal->cap.variable)
hal.stream.write(gc_spindle_get(0)->rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
stream_write(gc_spindle_get(0)->rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
#if COMPATIBILITY_LEVEL < 10
if(gc_state.modal.tool_offset_mode == ToolLengthOffset_Cancel)
hal.stream.write(" G49");
stream_write(" G49");
else {
hal.stream.write(" G43");
stream_write(" G43");
if(gc_state.modal.tool_offset_mode != ToolLengthOffset_Enable)
hal.stream.write(gc_state.modal.tool_offset_mode == ToolLengthOffset_EnableDynamic ? ".1" : ".2");
stream_write(gc_state.modal.tool_offset_mode == ToolLengthOffset_EnableDynamic ? ".1" : ".2");
}
hal.stream.write(gc_state.modal.retract_mode == CCRetractMode_RPos ? " G99" : " G98");
stream_write(gc_state.modal.retract_mode == CCRetractMode_RPos ? " G99" : " G98");
if(gc_state.modal.scaling_active) {
hal.stream.write(" G51:");
stream_write(" G51:");
axis_signals_tostring(buf, gc_get_g51_state());
hal.stream.write(buf);
stream_write(buf);
} else
hal.stream.write(" G50");
stream_write(" G50");
#endif
@@ -763,23 +786,23 @@ void report_gcode_modes (void)
switch (gc_state.modal.program_flow) {
case ProgramFlow_Paused:
hal.stream.write(" M0");
stream_write(" M0");
break;
case ProgramFlow_OptionalStop:
hal.stream.write(" M1");
stream_write(" M1");
break;
case ProgramFlow_CompletedM2:
hal.stream.write(" M2");
stream_write(" M2");
break;
case ProgramFlow_CompletedM30:
hal.stream.write(" M30");
stream_write(" M30");
break;
case ProgramFlow_CompletedM60:
hal.stream.write(" M60");
stream_write(" M60");
break;
default:
@@ -787,42 +810,42 @@ void report_gcode_modes (void)
}
}
hal.stream.write(gc_spindle_get(0)->state.on ? (gc_spindle_get(0)->state.ccw ? " M4" : " M3") : " M5");
stream_write(gc_spindle_get(0)->state.on ? (gc_spindle_get(0)->state.ccw ? " M4" : " M3") : " M5");
if(gc_state.tool_change)
hal.stream.write(" M6");
stream_write(" M6");
if (gc_state.modal.coolant.value) {
if (gc_state.modal.coolant.mist)
hal.stream.write(" M7");
stream_write(" M7");
if (gc_state.modal.coolant.flood)
hal.stream.write(" M8");
stream_write(" M8");
} else
hal.stream.write(" M9");
stream_write(" M9");
if (sys.override.control.feed_rates_disable)
hal.stream.write(" M50");
stream_write(" M50");
if (sys.override.control.spindle_rpm_disable)
hal.stream.write(" M51");
stream_write(" M51");
if (sys.override.control.feed_hold_disable)
hal.stream.write(" M53");
stream_write(" M53");
if (settings.parking.flags.enable_override_control && sys.override.control.parking_disable)
hal.stream.write(" M56");
stream_write(" M56");
hal.stream.write(appendbuf(2, " T", uitoa((uint32_t)gc_state.tool->tool_id)));
stream_write(appendbuf(2, " T", uitoa((uint32_t)gc_state.tool->tool_id)));
hal.stream.write(appendbuf(2, " F", get_rate_value(gc_state.feed_rate)));
stream_write(appendbuf(2, " F", get_rate_value(gc_state.feed_rate)));
if(gc_spindle_get(0)->hal->cap.variable)
hal.stream.write(appendbuf(2, " S", ftoa(gc_spindle_get(0)->rpm, N_DECIMAL_RPMVALUE)));
stream_write(appendbuf(2, " S", ftoa(gc_spindle_get(0)->rpm, N_DECIMAL_RPMVALUE)));
hal.stream.write("]" ASCII_EOL);
stream_write("]" ASCII_EOL);
}
// Prints specified startup line
@@ -1139,12 +1162,17 @@ void report_echo_line_received (char *line)
#if N_SYS_SPINDLE == 1 && N_SPINDLE > 1
typedef struct {
spindle_id_t spindle_id;
stream_write_ptr stream_write;
} spindle_r_t;
static bool report_spindle_num (spindle_info_t *spindle, void *data)
{
bool ok;
if((ok = spindle->id == *((spindle_id_t *)data)))
hal.stream.write_all(appendbuf(2, "|S:", uitoa((uint32_t)spindle->num)));
if((ok = spindle->id == ((spindle_r_t *)data)->spindle_id))
((spindle_r_t *)data)->stream_write(appendbuf(2, "|S:", uitoa((uint32_t)spindle->num)));
return ok;
}
@@ -1156,13 +1184,13 @@ static bool report_spindle_num (spindle_info_t *spindle, void *data)
// specific needs, but the desired real-time data report must be as short as possible. This is
// requires as it minimizes the computational overhead and allows grblHAL to keep running smoothly,
// especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
void report_realtime_status (stream_write_ptr stream_write)
void report_realtime_status (stream_write_ptr stream_write, report_tracking_flags_t report)
{
static bool probing = false;
uint_fast8_t idx;
float print_position[N_AXIS], wco[N_AXIS], dist_remaining[N_AXIS];
report_tracking_flags_t report = system_get_rt_report_flags(), delayed_report = {};
report_tracking_flags_t delayed_report = {0};
probe_state_t probe_state = {
.connected = On,
.triggered = Off
@@ -1234,7 +1262,7 @@ void report_realtime_status (stream_write_ptr stream_write)
system_convert_array_steps_to_mpos(print_position, sys.position);
if((report.distance_to_go = settings.status_report.distance_to_go)) {
// Calulate distance-to-go in current block (i.e., difference between target / end-of-block) and current position)
// Calculate distance-to-go in current block (i.e., difference between target / end-of-block) and current position)
plan_block_t *cur_block = plan_get_current_block();
if((report.distance_to_go = !!cur_block)) {
for(idx = 0; idx < N_AXIS; idx++) {
@@ -1267,8 +1295,9 @@ void report_realtime_status (stream_write_ptr stream_write)
if(settings.status_report.line_numbers) {
// Report current line number
plan_block_t *cur_block = plan_get_current_block();
if (cur_block != NULL && cur_block->line_number > 0)
stream_write(appendbuf(2, "|Ln:", uitoa((uint32_t)cur_block->line_number)));
uint32_t line_number = cur_block ? cur_block->line_number : gc_state.line_number;
if(line_number)
stream_write(appendbuf(2, "|Ln:", uitoa(line_number)));
}
if(report.distance_to_go) {
@@ -1311,8 +1340,13 @@ void report_realtime_status (stream_write_ptr stream_write)
}
#elif N_SPINDLE > 1
if(report.spindle_id)
spindle_enumerate_spindles(report_spindle_num, &spindle_0->id);
if(report.spindle_id) {
spindle_r_t data = {
.spindle_id = spindle_0->id,
.stream_write = stream_write
};
spindle_enumerate_spindles(report_spindle_num, &data);
}
#endif
if(settings.status_report.pin_state) {
@@ -1402,11 +1436,15 @@ void report_realtime_status (stream_write_ptr stream_write)
}
stream_write("|WCO:");
stream_write(get_axis_values(wco));
#ifdef ROTATION_ENABLE
// stream_write(":");
// stream_write(ftoa(gc_state.modal.g5x_offset.data.rotation, 2));
#endif
}
if(report.gwco) {
stream_write("|WCS:");
stream_write(gc_coord_system_to_str(gc_state.modal.coord_system.id));
stream_write(gc_coord_system_to_str(gc_state.modal.g5x_offset.id));
}
if(report.overrides) {
@@ -1509,15 +1547,28 @@ void report_realtime_status (stream_write_ptr stream_write)
static float feed_rate, spindle_rpm;
static gc_modal_t last_state;
static bool g92_active;
#if NGC_PARAMETERS_ENABLE
static bool g66_active;
#endif
spindle_t *spindle = gc_spindle_get(0);
bool is_changed = feed_rate != gc_state.feed_rate || spindle_rpm != spindle->rpm || tool_id != gc_state.tool->tool_id;
bool is_changed = feed_rate != gc_state.feed_rate ||
spindle_rpm != spindle->rpm ||
tool_id != gc_state.tool->tool_id
#if NGC_PARAMETERS_ENABLE
|| g66_active != !!gc_state.g66_args;
#else
;
#endif
if(is_changed) {
feed_rate = gc_state.feed_rate;
tool_id = gc_state.tool->tool_id;
spindle_rpm = spindle->rpm;
} else if ((is_changed = g92_active != is_g92_active()))
#if NGC_PARAMETERS_ENABLE
g66_active = !!gc_state.g66_args;
#endif
} else if((is_changed = g92_active != is_g92_active()))
g92_active = !g92_active;
else if(memcmp(&last_state, &gc_state.modal, sizeof(gc_modal_t))) {
last_state = gc_state.modal;
@@ -1533,10 +1584,12 @@ void report_realtime_status (stream_write_ptr stream_write)
stream_write(">" ASCII_EOL);
system_add_rt_report(Report_ClearAll);
if(stream_write == hal.stream.write_all) {
system_add_rt_report(Report_ClearAll);
if(delayed_report.wco)
system_add_rt_report(Report_WCO); // Set to report on next request
if(delayed_report.wco)
system_add_rt_report(Report_WCO); // Set to report on next request
}
}
static void report_bitfield (const char *format, bool bitmap)
@@ -2845,3 +2898,15 @@ void report_init_fns (void)
if(grbl.on_report_handlers_init)
grbl.on_report_handlers_init();
}
report_tracking_flags_t report_get_rt_flags_all (void)
{
report_tracking_flags_t report;
report.value = (uint32_t)Report_All;
report.tool_offset = sys.report.tool_offset;
report.m66result = sys.var5399 > -2;
report.probe_id = !!hal.probe.select;
return report;
}
+13 -11
View File
@@ -3,21 +3,21 @@
Part of grblHAL
Copyright (c) 2018-2024 Terje Io
Copyright (c) 2018-2026 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 _REPORT_H_
@@ -49,22 +49,22 @@ void report_info (void *message);
// Message helper to be run as foreground task.
void report_warning (void *message);
// Prints Grbl help.
// Prints grblHAL help.
status_code_t report_help (char *args);
void report_plugin (const char *name, const char *version);
// Prints Grbl settings
// Prints grblHAL settings
void report_grbl_settings (bool all, void *data);
// Prints Grbl setting
// Prints grblHAL setting
status_code_t report_grbl_setting (setting_id_t id, void *data);
// Prints an echo of the pre-parsed line received right before execution.
void report_echo_line_received (char *line);
// Prints realtime status report.
void report_realtime_status (stream_write_ptr stream_write);
void report_realtime_status (stream_write_ptr stream_write, report_tracking_flags_t report);
// Prints recorded probe position.
void report_probe_parameters (void);
@@ -82,11 +82,11 @@ status_code_t report_named_ngc_parameter (char *arg);
#endif
// Prints Grbl NGC parameters (coordinate offsets, probe).
// Prints grblHAL NGC parameters (coordinate offsets, probe).
void report_ngc_parameters (void);
// Prints current g-code parser mode state.
void report_gcode_modes (void);
void report_gcode_modes (stream_write_ptr stream_write);
// Prints startup line when requested and executed.
void report_startup_line (uint8_t n, char *line);
@@ -127,4 +127,6 @@ status_code_t report_time (void);
// Prints current PID log.
void report_pid_log (void);
report_tracking_flags_t report_get_rt_flags_all (void);
#endif
+113 -89
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2011-2015 Sungeun K. Jeon
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -146,6 +146,15 @@ PROGMEM const settings_t defaults = {
.homing.cycle[0].mask = DEFAULT_HOMING_CYCLE_0,
.homing.cycle[1].mask = DEFAULT_HOMING_CYCLE_1,
.homing.cycle[2].mask = DEFAULT_HOMING_CYCLE_2,
#if N_AXIS > 3
.homing.cycle[3].mask = DEFAULT_HOMING_CYCLE_3,
#endif
#if N_AXIS > 4
.homing.cycle[4].mask = DEFAULT_HOMING_CYCLE_4,
#endif
#if N_AXIS > 5
.homing.cycle[5].mask = DEFAULT_HOMING_CYCLE_5,
#endif
.homing.dual_axis.fail_length_percent = DEFAULT_DUAL_AXIS_HOMING_FAIL_AXIS_LENGTH_PERCENT,
.homing.dual_axis.fail_distance_min = DEFAULT_DUAL_AXIS_HOMING_FAIL_DISTANCE_MIN,
.homing.dual_axis.fail_distance_max = DEFAULT_DUAL_AXIS_HOMING_FAIL_DISTANCE_MAX,
@@ -277,7 +286,6 @@ PROGMEM const settings_t defaults = {
#if ENABLE_BACKLASH_COMPENSATION
.axis[A_AXIS].backlash = 0.0f,
#endif
.homing.cycle[3].mask = DEFAULT_HOMING_CYCLE_3,
#endif
#ifdef B_AXIS
@@ -292,7 +300,6 @@ PROGMEM const settings_t defaults = {
#if ENABLE_BACKLASH_COMPENSATION
.axis[B_AXIS].backlash = 0.0f,
#endif
.homing.cycle[4].mask = DEFAULT_HOMING_CYCLE_4,
#endif
#ifdef C_AXIS
@@ -307,9 +314,9 @@ PROGMEM const settings_t defaults = {
#if ENABLE_BACKLASH_COMPENSATION
.axis[C_AXIS].backlash = 0.0f,
#endif
.homing.cycle[5].mask = DEFAULT_HOMING_CYCLE_5,
#endif
#if !LATHE_UVW_OPTION
#ifdef U_AXIS
.axis[U_AXIS].steps_per_mm = DEFAULT_U_STEPS_PER_MM,
.axis[U_AXIS].acceleration = (DEFAULT_U_ACCELERATION * 60.0f * 60.0f),
@@ -338,6 +345,21 @@ PROGMEM const settings_t defaults = {
#endif
#endif
#ifdef W_AXIS
.axis[W_AXIS].steps_per_mm = DEFAULT_W_STEPS_PER_MM,
.axis[W_AXIS].acceleration = (DEFAULT_W_ACCELERATION * 60.0f * 60.0f),
.axis[W_AXIS].jerk = (DEFAULT_W_JERK * 60.0f * 60.0f * 60.0f),
.axis[W_AXIS].max_rate = DEFAULT_W_MAX_RATE,
.axis[W_AXIS].max_travel = (-DEFAULT_W_MAX_TRAVEL),
.axis[W_AXIS].dual_axis_offset = 0.0f,
.axis[W_AXIS].homing_feed_rate = DEFAULT_HOMING_FEED_RATE,
.axis[W_AXIS].homing_seek_rate = DEFAULT_HOMING_SEEK_RATE,
#if ENABLE_BACKLASH_COMPENSATION
.axis[W_AXIS].backlash = 0.0f,
#endif
#endif
#endif // !LATHE_UVW_OPTION
.tool_change.mode = (toolchange_mode_t)DEFAULT_TOOLCHANGE_MODE,
.tool_change.probing_distance = DEFAULT_TOOLCHANGE_PROBING_DISTANCE,
.tool_change.feed_rate = DEFAULT_TOOLCHANGE_FEED_RATE,
@@ -363,7 +385,9 @@ PROGMEM const settings_t defaults = {
.fs_options.hierarchical_listing = DEFAULT_FS_HIERACHICAL_LISTING,
.modbus_baud = DEFAULT_MODBUS_STREAM_BAUD,
.modbus_stream_format.value = (DEFAULT_MODBUS_STREAM_PARITY << 4),
.modbus_stream_format.width = DEFAULT_MODBUS_STREAM_DATA_BITS,
.modbus_stream_format.stopbits = DEFAULT_MODBUS_STREAM_STOP_BITS,
.modbus_stream_format.parity = DEFAULT_MODBUS_STREAM_PARITY,
.rgb_strip.length0 = DEFAULT_RGB_STRIP0_LENGTH,
.rgb_strip.length1 = DEFAULT_RGB_STRIP1_LENGTH
@@ -394,32 +418,23 @@ PROGMEM static const setting_group_detail_t setting_group_detail [] = {
{ Group_Axis, Group_XAxis, "X-axis", group_is_available },
{ Group_Axis, Group_YAxis, "Y-axis", group_is_available },
{ Group_Axis, Group_ZAxis, "Z-axis", group_is_available },
#if !AXIS_REMAP_ABC2UVW
#ifdef A_AXIS
{ Group_Axis, Group_AAxis, "A-axis", group_is_available },
#endif
#ifdef B_AXIS
{ Group_Axis, Group_BAxis, "B-axis", group_is_available },
#endif
#ifdef C_AXIS
{ Group_Axis, Group_CAxis, "C-axis", group_is_available },
#endif
#ifdef U_AXIS
{ Group_Axis, Group_UAxis, "U-axis", group_is_available },
#endif
#ifdef V_AXIS
{ Group_Axis, Group_VAxis, "V-axis", group_is_available }
#endif
#else
#ifdef A_AXIS
{ Group_Axis, Group_AAxis, "U-axis", group_is_available },
#endif
#ifdef B_AXIS
{ Group_Axis, Group_BAxis, "V-axis", group_is_available },
#endif
#ifdef C_AXIS
{ Group_Axis, Group_CAxis, "W-axis", group_is_available },
#ifdef A_AXIS
{ Group_Axis, Group_Axis0 + A_AXIS, "A-axis", group_is_available },
#endif
#ifdef B_AXIS
{ Group_Axis, Group_Axis0 + B_AXIS, "B-axis", group_is_available },
#endif
#ifdef C_AXIS
{ Group_Axis, Group_Axis0 + C_AXIS, "C-axis", group_is_available },
#endif
#ifdef U_AXIS
{ Group_Axis, Group_Axis0 + U_AXIS, "U-axis", group_is_available },
#endif
#ifdef V_AXIS
{ Group_Axis, Group_Axis0 + V_AXIS, "V-axis", group_is_available },
#endif
#ifdef W_AXIS
{ Group_Axis, Group_Axis0 + W_AXIS, "W-axis", group_is_available }
#endif
};
@@ -436,26 +451,16 @@ static char spindle_signals[] = "Spindle enable,Spindle direction,PWM";
static char coolant_signals[] = "Flood,Mist";
static char door_options[] = "Ignore when idle,Keep coolant state on door open";
static char ganged_axes[] = "X-Axis,Y-Axis,Z-Axis";
#if !AXIS_REMAP_ABC2UVW
#if N_AXIS == 4
static const char rotary_axes[] = "A-Axis";
#elif N_AXIS == 5
static const char rotary_axes[] = "A-Axis,B-Axis";
#elif N_AXIS == 6
static const char rotary_axes[] = "A-Axis,B-Axis,C-Axis";
#elif N_AXIS == 7
static const char rotary_axes[] = "A-Axis,B-Axis,C-Axis,U-Axis";
#elif N_AXIS == 8
static const char rotary_axes[] = "A-Axis,B-Axis,C-Axis,U-Axis,V-Axis";
#endif
#else
#if N_AXIS == 4
static const char rotary_axes[] = "U-Axis";
#elif N_AXIS == 5
static const char rotary_axes[] = "U-Axis,V-Axis";
#elif N_AXIS == 6
static const char rotary_axes[] = "U-Axis,V-Axis,W-Axis";
#endif
#if N_AXIS == 4
static char rotary_axes[] = "A-Axis";
#elif N_AXIS == 5
static char rotary_axes[] = "A-Axis,B-Axis";
#elif N_AXIS == 6
static char rotary_axes[] = "A-Axis,B-Axis,C-Axis";
#elif N_AXIS == 7
static char rotary_axes[] = "A-Axis,B-Axis,C-Axis,U-Axis";
#elif N_AXIS == 8
static char rotary_axes[] = "A-Axis,B-Axis,C-Axis,U-Axis,V-Axis";
#endif
static on_file_demarcate_ptr on_file_demarcate;
@@ -951,7 +956,7 @@ static status_code_t set_parking_enable (setting_id_t id, uint_fast16_t int_valu
if(settings.parking.flags.deactivate_upon_init)
settings.parking.flags.enable_override_control = On;
//setting_remove_elements(Setting_ProbePullUpDisable, mask);
//setting_remove_elements(Setting_ProbePullUpDisable, mask, true);
return Status_OK;
}
@@ -1267,7 +1272,7 @@ setting_id_t settings_get_axis_base (setting_id_t id, uint_fast8_t *idx)
return *idx < N_AXIS ? base : Setting_SettingsMax;
}
static status_code_t set_float (setting_id_t setting, float value)
FLASHMEM static status_code_t set_float (setting_id_t setting, float value)
{
status_code_t status = Status_OK;
@@ -1296,7 +1301,7 @@ static status_code_t set_float (setting_id_t setting, float value)
return status;
}
static status_code_t set_axis_setting (setting_id_t setting, float value)
FLASHMEM static status_code_t set_axis_setting (setting_id_t setting, float value)
{
uint_fast8_t idx;
status_code_t status = Status_OK;
@@ -1384,7 +1389,7 @@ static status_code_t set_axis_setting (setting_id_t setting, float value)
return status;
}
static float get_float (setting_id_t setting)
FLASHMEM static float get_float (setting_id_t setting)
{
float value = 0.0f;
@@ -1482,7 +1487,7 @@ static float get_float (setting_id_t setting)
return value;
}
static uint32_t get_int (setting_id_t id)
FLASHMEM static uint32_t get_int (setting_id_t id)
{
uint32_t value = 0;
@@ -1872,7 +1877,7 @@ static bool is_group_available (const setting_detail_t *setting, uint_fast16_t o
return settings_is_group_available(setting->group);
}
static bool is_setting_available (const setting_detail_t *setting, uint_fast16_t offset)
FLASHMEM static bool is_setting_available (const setting_detail_t *setting, uint_fast16_t offset)
{
bool available = false;
@@ -1991,6 +1996,14 @@ static bool is_setting_available (const setting_detail_t *setting, uint_fast16_t
available = hal.driver_cap.spindle_encoder && spindle_get_count() > 1;
break;
case Setting_RGB_StripLengt0:
available = hal.rgb0.flags.is_strip;
break;
case Setting_RGB_StripLengt1:
available = hal.rgb1.flags.is_strip;
break;
case Setting_FSOptions:
available = hal.driver_cap.sd_card || hal.driver_cap.littlefs;
break;
@@ -2094,13 +2107,13 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ Setting_HomingCycle_1, Group_Homing, "Axes homing, first phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
{ Setting_HomingCycle_2, Group_Homing, "Axes homing, second phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
{ Setting_HomingCycle_3, Group_Homing, "Axes homing, third phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
#ifdef A_AXIS
#if N_AXIS > 3
{ Setting_HomingCycle_4, Group_Homing, "Axes homing, fourth phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
#endif
#ifdef B_AXIS
#if N_AXIS > 4
{ Setting_HomingCycle_5, Group_Homing, "Axes homing, fifth phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
#endif
#ifdef C_AXIS
#if N_AXIS > 5
{ Setting_HomingCycle_6, Group_Homing, "Axes homing, sixth phase", NULL, Format_AxisMask, NULL, NULL, NULL, Setting_IsExtendedFn, set_homing_cycle, get_int, NULL },
#endif
{ Setting_ParkingPulloutIncrement, Group_SafetyDoor, "Parking pull-out distance", "mm", Format_Decimal, "###0.0", NULL, NULL, Setting_IsExtended, &settings.parking.pullout_increment, NULL, NULL },
@@ -2176,6 +2189,8 @@ PROGMEM static const setting_detail_t setting_detail[] = {
{ Setting_OffsetLock, Group_General, "Lock coordinate systems", NULL, Format_Bitfield, "G59.1,G59.2,G59.3", NULL, NULL, Setting_IsExtended, &settings.offset_lock.mask, NULL, NULL },
#endif
{ Setting_EncoderSpindle, Group_Spindle, "Encoder spindle", NULL, Format_RadioButtons, spindle_types, NULL, NULL, Setting_IsExtendedFn, set_encoder_spindle, get_int, is_setting_available },
{ Setting_RGB_StripLengt0, Group_AuxPorts, "LED strip 1 length", NULL, Format_Int8, "##0", NULL, "255", Setting_NonCore, &settings.rgb_strip.length0, NULL, is_setting_available },
{ Setting_RGB_StripLengt1, Group_AuxPorts, "LED strip 2 length", NULL, Format_Int8, "##0", NULL, "255", Setting_NonCore, &settings.rgb_strip.length1, NULL, is_setting_available },
#if N_AXIS > 3
{ Setting_RotaryWrap, Group_Stepper, "Fast rotary go to G28", NULL, Format_Bitfield, rotary_axes, NULL, NULL, Setting_IsExtendedFn, set_rotary_wrap_axes, get_int, NULL },
#endif
@@ -2269,13 +2284,13 @@ PROGMEM static const setting_descr_t setting_descr[] = {
{ Setting_HomingCycle_1, "Axes to home in first phase." },
{ Setting_HomingCycle_2, "Axes to home in second phase." },
{ Setting_HomingCycle_3, "Axes to home in third phase." },
#ifdef A_AXIS
#if N_AXIS > 3
{ Setting_HomingCycle_4, "Axes to home in fourth phase." },
#endif
#ifdef B_AXIS
#if N_AXIS > 4
{ Setting_HomingCycle_5, "Axes to home in fifth phase." },
#endif
#ifdef C_AXIS
#if N_AXIS > 5
{ Setting_HomingCycle_6, "Axes to home in sixth phase." },
#endif
{ Setting_JogStepSpeed, "Step jogging speed in millimeters per minute." },
@@ -2332,8 +2347,8 @@ PROGMEM static const setting_descr_t setting_descr[] = {
{ Setting_AxisHomingFeedRate, "Feed rate to slowly engage limit switch to determine its location accurately." },
{ Setting_AxisHomingSeekRate, "Seek rate to quickly find the limit switch before the slower locating phase." },
{ Setting_SpindleAtSpeedTolerance, "Spindle at speed tolerance as percentage deviation from programmed speed, set to 0 to disable.\\n"
"If not within tolerance after timeout set by spindle on delay ($394) alarm 14 is raised.\\n"
"NOTE: if the spindle on delay is set to 0 the timeout defaults to one minute."
"If not within tolerance after timeout set by spindle delays ($392, $394 or $539) alarm 14 is raised.\\n"
"NOTE: if the delay is set to 0 the timeout defaults to one minute."
},
{ Setting_ToolChangeMode, "Normal: allows jogging for manual touch off. Set new position manually.\\n\\n"
"Manual touch off: rapids to tool change position, use jogging or $TPW for touch off.\\n\\n"
@@ -2382,6 +2397,8 @@ PROGMEM static const setting_descr_t setting_descr[] = {
"If spindle supports \"at speed\" functionality it is the time to wait before alarm 14 is raised."
},
{ Setting_EncoderSpindle, "Specifies which spindle has the encoder attached." },
{ Setting_RGB_StripLengt0, "Number of LEDS in strip 1." },
{ Setting_RGB_StripLengt1, "Number of LEDS in strip 2." },
#if N_AXIS > 3
{ Setting_RotaryWrap, "Perform fast move to angle stored in G28 position.\\n"
"Use:\\n"
@@ -2473,7 +2490,7 @@ bool settings_read_startup_line (uint8_t idx, char *line)
}
// Write selected coordinate data to persistent storage.
void settings_write_coord_data (coord_system_id_t id, const float (*coord_data)[N_AXIS])
void settings_write_coord_data (coord_system_id_t id, coord_system_data_t *data)
{
assert(id <= N_CoordinateSystems);
@@ -2482,23 +2499,24 @@ void settings_write_coord_data (coord_system_id_t id, const float (*coord_data)[
#endif
if(grbl.on_wco_saved)
grbl.on_wco_saved(id, (coord_data_t *)coord_data);
grbl.on_wco_saved(id, data);
if(hal.nvs.type != NVS_None)
hal.nvs.memcpy_to_nvs(NVS_ADDR_PARAMETERS + id * (sizeof(coord_data_t) + NVS_CRC_BYTES), (uint8_t *)coord_data, sizeof(coord_data_t), true);
hal.nvs.memcpy_to_nvs(NVS_ADDR_PARAMETERS + id * (sizeof(coord_system_data_t) + NVS_CRC_BYTES), (uint8_t *)data, sizeof(coord_system_data_t), true);
}
// Read selected coordinate data from persistent storage.
bool settings_read_coord_data (coord_system_id_t id, const float (*coord_data)[N_AXIS])
bool settings_read_coord_data (coord_system_id_t id, coord_system_data_t *data)
{
assert(id <= N_CoordinateSystems);
if (!(hal.nvs.type != NVS_None && hal.nvs.memcpy_from_nvs((uint8_t *)coord_data, NVS_ADDR_PARAMETERS + id * (sizeof(coord_data_t) + NVS_CRC_BYTES), sizeof(coord_data_t), true) == NVS_TransferResult_OK)) {
// Reset with default zero vector
memcpy((float *)coord_data, null_vector.values, sizeof(coord_data_t));
settings_write_coord_data(id, coord_data);
if(!(hal.nvs.type != NVS_None && hal.nvs.memcpy_from_nvs((uint8_t *)data, NVS_ADDR_PARAMETERS + id * (sizeof(coord_system_data_t) + NVS_CRC_BYTES), sizeof(coord_system_data_t), true) == NVS_TransferResult_OK)) {
// Reset with zero vector
memset(data, 0, sizeof(coord_system_data_t));
settings_write_coord_data(id, data);
return false;
}
return true;
}
@@ -2718,14 +2736,13 @@ void settings_restore (settings_restore_t restore)
}
if(restore.parameters) {
float coord_data[N_AXIS];
memset(coord_data, 0, sizeof(coord_data));
#if COMPATIBILITY_LEVEL <= 1
coord_system_data_t coord_data = {0};
for(idx = 0; idx <= N_WorkCoordinateSystems; idx++) {
#if COMPATIBILITY_LEVEL <= 1
if(idx < CoordinateSystem_G59_1 || idx > CoordinateSystem_G59_3 || bit_isfalse(settings.offset_lock.mask, bit(idx - CoordinateSystem_G59_1)))
#endif
settings_write_coord_data((coord_system_id_t)idx, &coord_data);
}
#endif
settings_write_coord_data(CoordinateSystem_G92, &coord_data); // Clear G92 offsets
#if N_TOOLS
@@ -3100,7 +3117,7 @@ static void setting_remove_element (setting_id_t id, uint_fast8_t pos)
// Flag setting elements for bitfields as N/A according to a mask
// Note: setting format string has to reside in RAM.
void setting_remove_elements (setting_id_t id, uint32_t mask)
void setting_remove_elements (setting_id_t id, uint32_t mask, bool trim)
{
const setting_detail_t *setting;
@@ -3116,7 +3133,7 @@ void setting_remove_elements (setting_id_t id, uint32_t mask)
}
// Strip trailing N/A's
while((s = strrchr(format, ','))) {
if(trim) while((s = strrchr(format, ','))) {
if(strncmp(s, ",N/A", 4))
break;
*s = '\0';
@@ -3250,7 +3267,7 @@ static bool settings_changed_spindle (void)
}
// A helper method to set settings from command line
status_code_t settings_store_setting (setting_id_t id, char *svalue)
FLASHMEM status_code_t settings_store_setting (setting_id_t id, char *svalue)
{
uint_fast8_t set_idx = 0;
uint32_t int_value = 0;
@@ -3483,27 +3500,30 @@ void settings_init (void)
spindle_state.ccw = spindle_cap.direction;
spindle_state.pwm = spindle_cap.pwm_invert;
setting_remove_elements(Setting_SpindleInvertMask, spindle_state.mask);
setting_remove_elements(Setting_SpindleInvertMask, spindle_state.mask, true);
}
setting_remove_elements(Setting_ControlInvertMask, hal.signals_cap.mask & ~limits_override.mask);
setting_remove_elements(Setting_ControlInvertMask, hal.signals_cap.mask & ~limits_override.mask, true);
if(hal.stepper.get_ganged)
setting_remove_elements(Setting_GangedDirInvertMask, hal.stepper.get_ganged(false).mask);
setting_remove_elements(Setting_GangedDirInvertMask, hal.stepper.get_ganged(false).mask, true);
setting_remove_elements(Setting_CoolantInvertMask, hal.coolant_cap.mask);
setting_remove_elements(Setting_CoolantInvertMask, hal.coolant_cap.mask, true);
#if COMPATIBILITY_LEVEL <= 1
if(hal.homing.get_state == NULL) {
homing_settings_flags_t homing;
homing.value = (uint16_t)-1;
homing.use_limit_switches = Off;
setting_remove_elements(Setting_HomingEnable, homing.value);
setting_remove_elements(Setting_HomingEnable, homing.value, true);
}
#endif
#if ENABLE_JERK_ACCELERATION
#if N_AXIS > 3 || ENABLE_JERK_ACCELERATION
uint_fast8_t idx = N_AXIS;
#endif
#if ENABLE_JERK_ACCELERATION
do {
if(settings.axis[--idx].jerk == 0.0f)
settings.axis[idx].jerk = settings.axis[idx].acceleration * 60.0f * 10.0f;
@@ -3520,10 +3540,14 @@ void settings_init (void)
} while((details = details->next));
uint32_t mask = 0b001 | (hal.driver_cap.toolsetter << 1) | (hal.driver_cap.probe2 << 2);
setting_remove_elements(Setting_InvertProbePin, mask);
setting_remove_elements(Setting_ProbePullUpDisable, mask);
setting_remove_elements(Setting_InvertProbePin, mask, true);
setting_remove_elements(Setting_ProbePullUpDisable, mask, true);
#ifndef NO_SAFETY_DOOR_SUPPORT
setting_remove_elements(Setting_DoorOptions, ((!settings.parking.flags.enabled || hal.signals_cap.safety_door_ajar) << 1) | hal.signals_cap.safety_door_ajar);
setting_remove_elements(Setting_DoorOptions, ((!settings.parking.flags.enabled || hal.signals_cap.safety_door_ajar) << 1) | hal.signals_cap.safety_door_ajar, true);
#endif
#if N_AXIS > 3
for(idx = 3; idx < N_AXIS; idx++)
*(rotary_axes + (idx - 3) * 7) = *axis_letter[idx];
#endif
mask = 0b00011 | (hal.probe.select ? ((hal.driver_cap.toolsetter << 3) | (hal.driver_cap.probe2 << 4)) : 0);
@@ -3535,7 +3559,7 @@ void settings_init (void)
#else
settings.probe.enable_protection = Off;
#endif
setting_remove_elements(Setting_ProbingFlags, mask);
setting_remove_elements(Setting_ProbingFlags, mask, true);
if(!settings.flags.settings_downgrade && settings.version.build != (GRBL_BUILD - 20000000UL)) {
+5 -14
View File
@@ -3,7 +3,7 @@
Part of grblHAL
Copyright (c) 2017-2025 Terje Io
Copyright (c) 2017-2026 Terje Io
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
@@ -969,21 +969,12 @@ typedef enum {
Group_XAxis = Group_Axis0, //!< 44
Group_YAxis, //!< 45
Group_ZAxis, //!< 46
#ifdef A_AXIS
Group_AAxis, //!< 47
#endif
#ifdef B_AXIS
Group_BAxis, //!< 48
#endif
#ifdef C_AXIS
Group_CAxis, //!< 49
#endif
#ifdef U_AXIS
Group_UAxis, //!< 50
#endif
#ifdef V_AXIS
Group_VAxis, //!< 51
#endif
Group_WAxis, //!< 52
Group_Unknown = 99, //!< 99
Group_All = Group_Root //!< 0
} setting_group_t;
@@ -1140,10 +1131,10 @@ void settings_write_build_info(char *line);
bool settings_read_build_info(char *line);
// Writes selected coordinate data to persistent storage
void settings_write_coord_data(coord_system_id_t id, const float (*coord_data)[N_AXIS]);
void settings_write_coord_data(coord_system_id_t id, coord_system_data_t *data);
// Reads selected coordinate data from persistent storage
bool settings_read_coord_data(coord_system_id_t id, const float (*coord_data)[N_AXIS]);
bool settings_read_coord_data(coord_system_id_t id, coord_system_data_t *data);
// Temporarily override acceleration, if 0 restore to configured setting value
bool settings_override_acceleration (uint8_t axis, float acceleration);
@@ -1168,7 +1159,7 @@ float setting_get_float_value (const setting_detail_t *setting, uint_fast16_t of
setting_id_t settings_get_axis_base (setting_id_t id, uint_fast8_t *idx);
bool setting_is_list (const setting_detail_t *setting);
bool setting_is_integer (const setting_detail_t *setting);
void setting_remove_elements (setting_id_t id, uint32_t mask);
void setting_remove_elements (setting_id_t id, uint32_t mask, bool trim);
bool settings_add_spindle_type (const char *type);
limit_signals_t settings_get_homing_source (void);
+1 -1
View File
@@ -53,7 +53,7 @@ static void sleep_execute (void)
} while(slumber);
// If reached, sleep counter has expired. Execute sleep procedures.
// Notify user that Grbl has timed out and will be parking.
// Notify user that grblHAL has timed out and will be parking.
// To exit sleep, resume or reset. Either way, the job will not be recoverable.
system_set_exec_state_flag(EXEC_SLEEP);
}
+4 -4
View File
@@ -5,18 +5,18 @@
Copyright (c) 2016 Sungeun K. Jeon
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 _SLEEP_H_

Some files were not shown because too many files have changed in this diff Show More