mirror of
https://github.com/grblHAL/core.git
synced 2026-08-18 08:57:24 +08:00
Large spindle handling refactoring and enhancement++, see the changelog for more.
This commit is contained in:
@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
|
||||
|
||||
---
|
||||
|
||||
Latest build date is 20230129, see the [changelog](changelog.md) for details.
|
||||
Latest build date is 20230213, see the [changelog](changelog.md) for details.
|
||||
__NOTE:__ A settings reset will be performed on an update of builds earlier than 20230125. Backup and restore of settings is recommended.
|
||||
__IMPORTANT!__ A new setting has been introduced for ganged axes motors in build 20211121.
|
||||
I have only bench tested this for a couple of drivers, correct function should be verified after updating by those who have more than three motors configured.
|
||||
@@ -87,4 +87,4 @@ List of Supported G-Codes:
|
||||
Some [plugins](https://github.com/grblHAL/plugins) implements additional M-codes.
|
||||
|
||||
---
|
||||
2023-01-28
|
||||
2023-02-13
|
||||
|
||||
@@ -64,3 +64,20 @@ alarm_details_t *alarms_get_details (void)
|
||||
{
|
||||
return &details;
|
||||
}
|
||||
|
||||
const char *alarms_get_description (alarm_code_t id)
|
||||
{
|
||||
uint_fast16_t n_alarms;
|
||||
const char *description = NULL;
|
||||
alarm_details_t *details = grbl.on_get_alarms();
|
||||
|
||||
do {
|
||||
n_alarms = details->n_alarms;
|
||||
do {
|
||||
if(details->alarms[--n_alarms].id == id)
|
||||
description = details->alarms[n_alarms].description;
|
||||
} while(description == NULL && n_alarms);
|
||||
} while(description == NULL && (details = details->next));
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
@@ -61,8 +61,9 @@ typedef struct alarm_details {
|
||||
|
||||
typedef alarm_details_t *(*on_get_alarms_ptr)(void);
|
||||
|
||||
void alarms_register (alarm_details_t *details);
|
||||
alarm_details_t *alarms_get_details (void);
|
||||
const char *alarms_get_description (alarm_code_t id);
|
||||
void alarms_register (alarm_details_t *details);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+40
-1
@@ -1,11 +1,50 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20230213"/>Build 20230213
|
||||
|
||||
Core:
|
||||
|
||||
* First phase of spindle handling refactoring with the aim to support multiple \(up to four\) _simultaneously_ active spindles.
|
||||
Spindle selection by tool number has also been implemented as an option. More details can be found in the [spindle plugin readme](https://github.com/grblHAL/Plugins_spindle/blob/master/README.md).
|
||||
__NOTE:__ This change is quite large, bugs may have sneaked in. Please report any issues encountered ASAP.
|
||||
|
||||
Drivers:
|
||||
|
||||
* All: updated for spindle handling refactoring.
|
||||
|
||||
* iMXRT1062: updated readme for links to updated/patched libraries for SD card \(uSDFS\) and ethernet. User should switch to the updated/patched libraries if used.
|
||||
|
||||
* MSP432P401R: fix for missing file include and serial stream registration.
|
||||
|
||||
* RP2040: switched to SDK v1.5.0. Added new settings for RP2040, `$78` for wifi country code and `$337` for AP BSSID of AP to connect to. Both are optional.
|
||||
|
||||
* STMF4xx: fix for issue [#110](https://github.com/grblHAL/STM32F4xx/issues/110), incorrect NVIC grouping.
|
||||
|
||||
Plugins:
|
||||
|
||||
* SD Card: fixed some minor inconsistencies.
|
||||
|
||||
* Spindle: updated for spindle handling refactoring. Improved ModBus exception handling in some.
|
||||
New spindle select settings and improved functionality, see the [spindle plugin readme](https://github.com/grblHAL/Plugins_spindle/blob/master/README.md) for more.
|
||||
|
||||
* Odometer and PPI: updated for spindle handling refactoring.
|
||||
|
||||
* Networking: wifi \(ESP32 and RP2040\), changed networking settings from `$30x` range to `$32x` range for station mode.
|
||||
Added [MQTT](https://en.wikipedia.org/wiki/MQTT) API for plugin developers, example code using this can be found [here](https://github.com/grblHAL/Templates/tree/master/my_plugin/MQTT%20example).
|
||||
__NOTE:__ networking and other plugin settings will be reset on update for ESP32 and RP2040, backup and restore.
|
||||
|
||||
---
|
||||
|
||||
<a name="20230129"/>Build 20230129
|
||||
|
||||
Core:
|
||||
|
||||
* Fixed regression in tool change handling related to refactoring of _config.h_ in build 20230125.
|
||||
|
||||
Drivers:
|
||||
|
||||
* ESP32: Added all supported VFD spindles as options in CMakeLists.txt, some code cleanup.
|
||||
|
||||
---
|
||||
|
||||
<a name="20230128"/>Build 20230128
|
||||
@@ -96,7 +135,7 @@ Core:
|
||||
|
||||
* Added single axis homing commands for U and V, remapping of ABC homing commands to UVW when configured.
|
||||
|
||||
Plugins
|
||||
Plugins:
|
||||
|
||||
* WebUI and Networking: fixes for compiler warnings.
|
||||
|
||||
|
||||
@@ -58,6 +58,13 @@ If more than 3 axes are configured a compliant driver and board map file is need
|
||||
#define N_SPINDLE 1
|
||||
#endif
|
||||
|
||||
/*! \def N_SYS_SPINDLE
|
||||
\brief Defines number of simultaneously active spindles supported - minimum 1 (none), maximum 8.
|
||||
*/
|
||||
#if !defined N_SYS_SPINDLE || defined __DOXYGEN__
|
||||
#define N_SYS_SPINDLE 1
|
||||
#endif
|
||||
|
||||
/*! \def BUILD_INFO
|
||||
\brief Defines string to be output as part of the `$I` or `$I+` command response.
|
||||
*/
|
||||
@@ -871,19 +878,6 @@ not throw an alarm message.
|
||||
#if !defined DEFAULT_CHECK_LIMITS_AT_INIT || defined __DOXYGEN__
|
||||
#define DEFAULT_CHECK_LIMITS_AT_INIT Off
|
||||
#endif
|
||||
/*! \def DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES
|
||||
\brief
|
||||
If your machine has two limits switches wired in parallel to one axis, you will need to enable
|
||||
this feature. Since the two switches are sharing a single pin, there is no way for grblHAL to tell
|
||||
which one is enabled. This option only effects homing, where if a limit is engaged, grblHAL will
|
||||
alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one
|
||||
limit switch for each axis, don't enable this option. By keeping it disabled, you can perform a
|
||||
homing cycle while on the limit switch and not have to move the machine off of it.
|
||||
*/
|
||||
#if !defined DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES || defined __DOXYGEN__
|
||||
#define DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#endif
|
||||
///@}
|
||||
|
||||
/*! @name Group_Limits_DualAxis
|
||||
\brief Dual axis limits settings (Group_Limits_DualAxis)
|
||||
@@ -1126,15 +1120,15 @@ Requires homing cycles to be defined by \ref DEFAULT_HOMING_CYCLE_0 - \ref DEFAU
|
||||
#define DEFAULT_HOMING_ENABLE Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#endif
|
||||
|
||||
/*! /def HOMING_SINGLE_AXIS_COMMANDS
|
||||
/*! /def DEFAULT_HOMING_SINGLE_AXIS_COMMANDS
|
||||
\brief Enables single axis homing commands.
|
||||
`$HX`, `$HY`, `$HZ` etc. for homing the respective axes.The full homing
|
||||
cycle is still invoked by the `$H` command. This is disabled by default.
|
||||
If you have a two-axis machine, _DON'T USE THIS_. Instead, just alter the homing cycle for two-axes.
|
||||
\internal Bit 1 in settings.homing.flags.
|
||||
*/
|
||||
#if !defined HOMING_SINGLE_AXIS_COMMANDS || defined __DOXYGEN__
|
||||
#define HOMING_SINGLE_AXIS_COMMANDS Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#if !defined DEFAULT_HOMING_SINGLE_AXIS_COMMANDS || defined __DOXYGEN__
|
||||
#define DEFAULT_HOMING_SINGLE_AXIS_COMMANDS Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#endif
|
||||
|
||||
/*! /def DEFAULT_HOMING_INIT_LOCK
|
||||
@@ -1148,17 +1142,32 @@ mainly a safety feature to remind the user to home, since position is unknown to
|
||||
#define DEFAULT_HOMING_INIT_LOCK Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#endif
|
||||
|
||||
/*! /def HOMING_FORCE_SET_ORIGIN
|
||||
/*! /def DEFAULT_HOMING_FORCE_SET_ORIGIN
|
||||
\brief
|
||||
After homing, grblHAL will set by default the entire machine space into negative space, as is typical
|
||||
for professional CNC machines, regardless of where the limit switches are located. Set this
|
||||
define to \ref On or 1 to force grblHAL to always set the machine origin at the homed location despite switch orientation.
|
||||
\internal Bit 3 in settings.homing.flags.
|
||||
*/
|
||||
#if !defined HOMING_FORCE_SET_ORIGIN || defined __DOXYGEN__
|
||||
#define HOMING_FORCE_SET_ORIGIN Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#if !defined DEFAULT_HOMING_FORCE_SET_ORIGIN || defined __DOXYGEN__
|
||||
#define DEFAULT_HOMING_FORCE_SET_ORIGIN Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#endif
|
||||
|
||||
/*! \def DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES
|
||||
\brief
|
||||
If your machine has two limits switches wired in parallel to one axis, you will need to enable
|
||||
this feature. Since the two switches are sharing a single pin, there is no way for grblHAL to tell
|
||||
which one is enabled. This option only effects homing, where if a limit is engaged, grblHAL will
|
||||
alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one
|
||||
limit switch for each axis, don't enable this option. By keeping it disabled, you can perform a
|
||||
homing cycle while on the limit switch and not have to move the machine off of it.
|
||||
\internal Bit 4 in settings.limits.flags.
|
||||
*/
|
||||
#if !defined DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES || defined __DOXYGEN__
|
||||
#define DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES Off // Default disabled. Set to \ref On or 1 to enable.
|
||||
#endif
|
||||
///@}
|
||||
|
||||
/*! /def DEFAULT_HOMING_ALLOW_MANUAL
|
||||
\brief
|
||||
If enabled this allows using the homing $-commands to set the home position to the
|
||||
@@ -1365,7 +1374,7 @@ greater.
|
||||
// pull-out position, power-up with a time-out, and plunge back to the original position at the
|
||||
// slower pull-out rate.
|
||||
// NOTE: Still a work-in-progress. Machine coordinates must be in all negative space and
|
||||
// does not work with HOMING_FORCE_SET_ORIGIN enabled. Parking motion also moves only in
|
||||
// does not work with DEFAULT_HOMING_FORCE_SET_ORIGIN enabled. Parking motion also moves only in
|
||||
// positive direction.
|
||||
* // Default disabled. Uncomment to enable.
|
||||
*/
|
||||
@@ -1571,7 +1580,7 @@ second motor for ganged/auto squared axes.
|
||||
*/
|
||||
///@{
|
||||
#if !defined DEFAULT_STEP_PULSE_DELAY || defined __DOXYGEN__
|
||||
#define DEFAULT_STEP_PULSE_DELAY 5.0f // uncomment to set default > 0.0f
|
||||
#define DEFAULT_STEP_PULSE_DELAY 0.0f
|
||||
#endif
|
||||
///@}
|
||||
|
||||
@@ -1778,6 +1787,21 @@ __NOTE:__ Must be a positive values.
|
||||
#define N_TOOLS 16
|
||||
#endif
|
||||
|
||||
#if N_SYS_SPINDLE > N_SPINDLE
|
||||
#undef N_SYS_SPINDLE
|
||||
#define N_SYS_SPINDLE N_SPINDLE
|
||||
#endif
|
||||
|
||||
#if N_SYS_SPINDLE < 1
|
||||
#undef N_SYS_SPINDLE
|
||||
#define N_SYS_SPINDLE 1
|
||||
#endif
|
||||
|
||||
#if N_SYS_SPINDLE > 8
|
||||
#undef N_SYS_SPINDLE
|
||||
#define N_SYS_SPINDLE 8
|
||||
#endif
|
||||
|
||||
#if (REPORT_WCO_REFRESH_BUSY_COUNT < REPORT_WCO_REFRESH_IDLE_COUNT)
|
||||
#error "WCO busy refresh is less than idle refresh."
|
||||
#endif
|
||||
@@ -1822,13 +1846,13 @@ __NOTE:__ Must be a positive values.
|
||||
|
||||
#if DEFAULT_PARKING_ENABLE > 0
|
||||
#if DEFAULT_HOMING_FORCE_SET_ORIGIN > 0
|
||||
#error "HOMING_FORCE_SET_ORIGIN is not supported with PARKING_ENABLE at this time."
|
||||
#error "DEFAULT_HOMING_FORCE_SET_ORIGIN is not supported with DEFAULT_PARKING_ENABLE at this time."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DEFAULT_ENABLE_PARKING_OVERRIDE_CONTROL > 0
|
||||
#if DEFAULT_PARKING_ENABLE < 1
|
||||
#error "ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with PARKING_ENABLE."
|
||||
#error "DEFAULT_ENABLE_PARKING_OVERRIDE_CONTROL must be enabled with DEFAULT_PARKING_ENABLE."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
+14
-10
@@ -43,7 +43,7 @@ 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 driver?
|
||||
/* TODO: add to grbl pointers so that a different formatting (xml, json etc) of reports may be implemented by a plugin?
|
||||
typedef struct {
|
||||
status_code_t (*report_status_message)(status_code_t status_code);
|
||||
alarm_code_t (*report_alarm_message)(alarm_code_t alarm_code);
|
||||
@@ -67,8 +67,8 @@ typedef message_code_t (*feedback_message_ptr)(message_code_t message_code);
|
||||
|
||||
typedef struct {
|
||||
setting_output_ptr setting;
|
||||
status_message_ptr status_message;
|
||||
feedback_message_ptr feedback_message;
|
||||
status_message_ptr status_message; //<! Prints system status messages.
|
||||
feedback_message_ptr feedback_message; //<! Prints miscellaneous feedback messages.
|
||||
} report_t;
|
||||
|
||||
// Core event handler and other entry points.
|
||||
@@ -79,7 +79,7 @@ typedef bool (*protocol_enqueue_realtime_command_ptr)(char c);
|
||||
|
||||
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_state_t spindle, float rpm, spindle_rpm_mode_t mode);
|
||||
typedef void (*on_spindle_programmed_ptr)(spindle_ptrs_t *spindle, spindle_state_t state, float rpm, spindle_rpm_mode_t mode);
|
||||
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);
|
||||
@@ -97,10 +97,12 @@ typedef void (*on_homing_completed_ptr)(void);
|
||||
typedef bool (*on_probe_fixture_ptr)(tool_data_t *tool, bool at_g59_3, bool on);
|
||||
typedef bool (*on_probe_start_ptr)(axes_signals_t axes, float *target, plan_line_data_t *pl_data);
|
||||
typedef void (*on_probe_completed_ptr)(void);
|
||||
typedef void (*on_tool_selected_ptr)(tool_data_t *tool);
|
||||
typedef void (*on_toolchange_ack_ptr)(void);
|
||||
typedef void (*on_reset_ptr)(void);
|
||||
typedef void (*on_jog_cancel_ptr)(sys_state_t state);
|
||||
typedef bool (*on_spindle_select_ptr)(spindle_id_t spindle_id);
|
||||
typedef bool (*on_spindle_select_ptr)(spindle_ptrs_t *spindle);
|
||||
typedef void (*on_spindle_selected_ptr)(spindle_ptrs_t *spindle);
|
||||
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);
|
||||
@@ -126,7 +128,7 @@ typedef struct {
|
||||
on_realtime_report_ptr on_realtime_report;
|
||||
on_unknown_feedback_message_ptr on_unknown_feedback_message;
|
||||
on_unknown_realtime_cmd_ptr on_unknown_realtime_cmd;
|
||||
on_unknown_sys_command_ptr on_unknown_sys_command; // return Status_Unhandled if not handled.
|
||||
on_unknown_sys_command_ptr on_unknown_sys_command; //!< return Status_Unhandled if not handled.
|
||||
on_get_commands_ptr on_get_commands;
|
||||
on_user_command_ptr on_user_command;
|
||||
on_stream_changed_ptr on_stream_changed;
|
||||
@@ -135,11 +137,13 @@ typedef struct {
|
||||
on_probe_fixture_ptr on_probe_fixture;
|
||||
on_probe_start_ptr on_probe_start;
|
||||
on_probe_completed_ptr on_probe_completed;
|
||||
on_toolchange_ack_ptr on_toolchange_ack; // Called from interrupt context.
|
||||
on_jog_cancel_ptr on_jog_cancel; // Called from interrupt context.
|
||||
on_tool_selected_ptr on_tool_selected; //!< Called prior to executing M6 or after executing M61.
|
||||
on_toolchange_ack_ptr on_toolchange_ack; //!< Called from interrupt context.
|
||||
on_jog_cancel_ptr on_jog_cancel; //!< Called from interrupt context.
|
||||
on_laser_ppi_enable_ptr on_laser_ppi_enable;
|
||||
on_spindle_select_ptr on_spindle_select;
|
||||
on_reset_ptr on_reset; // Called from interrupt context.
|
||||
on_spindle_select_ptr on_spindle_select; //!< Called before spindle is selected, hook in HAL overrides here
|
||||
on_spindle_selected_ptr on_spindle_selected; //!< Called when spindle is selected, do not change HAL pointers here!
|
||||
on_reset_ptr on_reset; //!< Called from interrupt context.
|
||||
// core entry points - set up by core before driver_init() is called.
|
||||
enqueue_gcode_ptr enqueue_gcode;
|
||||
enqueue_realtime_command_ptr enqueue_realtime_command;
|
||||
|
||||
+15
-2
@@ -132,6 +132,13 @@
|
||||
#define I2C_STROBE_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if DISPLAY_ENABLE == 2
|
||||
#ifdef I2C_ENABLE
|
||||
#undef I2C_ENABLE
|
||||
#endif
|
||||
#define I2C_ENABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_ENABLE
|
||||
#define EEPROM_ENABLE 0
|
||||
#endif
|
||||
@@ -333,10 +340,13 @@
|
||||
#define FTP_ENABLE 0
|
||||
#endif
|
||||
#ifndef MDNS_ENABLE
|
||||
#define MDNS_ENABLE 0
|
||||
#define MDNS_ENABLE 0
|
||||
#endif
|
||||
#ifndef SSDP_ENABLE
|
||||
#define SSDP_ENABLE 0
|
||||
#define SSDP_ENABLE 0
|
||||
#endif
|
||||
#ifndef MQTT_ENABLE
|
||||
#define MQTT_ENABLE 0
|
||||
#endif
|
||||
|
||||
#if ETHERNET_ENABLE || WIFI_ENABLE
|
||||
@@ -364,6 +374,9 @@
|
||||
#ifndef NETWORK_HTTP_PORT
|
||||
#define NETWORK_HTTP_PORT 80
|
||||
#endif
|
||||
#ifndef NETWORK_MQTT_PORT
|
||||
#define NETWORK_MQTT_PORT 1883
|
||||
#endif
|
||||
#ifndef NETWORK_WEBSOCKET_PORT
|
||||
#if HTTP_ENABLE
|
||||
#define NETWORK_WEBSOCKET_PORT 81
|
||||
|
||||
@@ -196,8 +196,19 @@ typedef enum {
|
||||
Override_Parking = 56 //!< 56 - M56
|
||||
} override_mode_t;
|
||||
|
||||
/*! Modal Group M10: User/driver/plugin defined M commands
|
||||
/*! Modal Group M10: i/o control */
|
||||
|
||||
typedef enum {
|
||||
IoMCode_OutputOnSynced = 62, //!< 62 - M62
|
||||
IoMCode_OutputOffSynced = 63, //!< 63 - M63
|
||||
IoMCode_OutputOnImmediate = 64, //!< 64 - M64
|
||||
IoMCode_OutputOffImmediate = 65, //!< 65 - M65
|
||||
IoMCode_WaitOnInput = 66, //!< 66 - M66
|
||||
IoMCode_AnalogOutSynced = 67, //!< 67 - M67
|
||||
IoMCode_AnalogOutImmediate = 68, //!< 68 - M68
|
||||
} io_mcode_t;
|
||||
|
||||
/*! Modal Group M10: User/driver/plugin defined M commands
|
||||
__NOTE:__ Not used by the core, may be used by private user code, drivers or plugins.
|
||||
*/
|
||||
typedef enum {
|
||||
@@ -213,8 +224,8 @@ typedef enum {
|
||||
OpenPNP_GetCurrentPosition = 114, //!< 114 - M114
|
||||
OpenPNP_FirmwareInfo = 115, //!< 115 - M115
|
||||
Trinamic_DebugReport = 122, //!< 122 - M122, Marlin format
|
||||
Trinamic_ReadRegister = 123, //!< 123 - M123,
|
||||
Trinamic_WriteRegister = 124, //!< 124 - M124,
|
||||
Trinamic_ReadRegister = 123, //!< 123 - M123
|
||||
Trinamic_WriteRegister = 124, //!< 124 - M124
|
||||
LaserPPI_Enable = 126, //!< 126 - M126
|
||||
LaserPPI_Rate = 127, //!< 127 - M127
|
||||
LaserPPI_PulseLength = 128, //!< 128 - M128
|
||||
@@ -405,6 +416,11 @@ typedef union {
|
||||
};
|
||||
} parameter_words_t;
|
||||
|
||||
typedef struct {
|
||||
spindle_state_t state; //!< {M3,M4,M5}
|
||||
spindle_rpm_mode_t rpm_mode; //!< {G96,G97}
|
||||
} spindle_mode_t;
|
||||
|
||||
// NOTE: When this struct is zeroed, the above defines set the defaults for the system.
|
||||
typedef struct {
|
||||
motion_mode_t motion; //!< {G0,G1,G2,G3,G38.2,G80}
|
||||
@@ -420,9 +436,8 @@ typedef struct {
|
||||
// control_mode_t control; //!< {G61} NOTE: Don't track. Only default supported.
|
||||
program_flow_t program_flow; //!< {M0,M1,M2,M30,M60}
|
||||
coolant_state_t coolant; //!< {M7,M8,M9}
|
||||
spindle_state_t spindle; //!< {M3,M4,M5}
|
||||
spindle_mode_t spindle; //!< {M3,M4,M5 and G96,G97}
|
||||
gc_override_flags_t override_ctrl; //!< {M48,M49,M50,M51,M53,M56}
|
||||
spindle_rpm_mode_t spindle_rpm_mode; //!< {G96,G97}
|
||||
cc_retract_mode_t retract_mode; //!< {G98,G99}
|
||||
bool scaling_active; //!< {G50,G51}
|
||||
bool canned_cycle_active;
|
||||
@@ -472,24 +487,15 @@ typedef struct {
|
||||
uint32_t tool; //!< Tool number
|
||||
} tool_data_t;
|
||||
|
||||
// Data used for Constant Surface Speed (CSS) mode calculations.
|
||||
typedef struct {
|
||||
float surface_speed; //!< Surface speed in millimeters/min
|
||||
float target_rpm; //!< Target RPM at end of movement
|
||||
float max_rpm; //!< Maximum spindle RPM
|
||||
float tool_offset; //!< Tool offset
|
||||
uint_fast8_t axis; //!< Linear (tool) axis
|
||||
bool active;
|
||||
} css_data_t;
|
||||
|
||||
typedef struct {
|
||||
float rpm; //!< RPM
|
||||
css_data_t css; //!< Data used for Constant Surface Speed Mode calculations
|
||||
float rpm; //!< Spindle speed
|
||||
spindle_state_t state;
|
||||
spindle_css_data_t *css; //!< Data used for Constant Surface Speed Mode calculations
|
||||
spindle_ptrs_t *hal;
|
||||
} spindle_t;
|
||||
|
||||
/*! \brief Parser state
|
||||
|
||||
|
||||
*/
|
||||
typedef struct {
|
||||
gc_modal_t modal;
|
||||
@@ -541,8 +547,8 @@ typedef struct {
|
||||
gc_values_t values; //!< Parameter values for block.
|
||||
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; //
|
||||
int32_t spindle_id; //!< Spindle to control, -1 for all
|
||||
uint32_t arc_turns; //
|
||||
spindle_ptrs_t *spindle; //!< Spindle to control, NULL for all
|
||||
} parser_block_t;
|
||||
|
||||
// Initialize the parser
|
||||
@@ -572,6 +578,8 @@ float *gc_get_scaling (void);
|
||||
// Get current axis offset.
|
||||
float gc_get_offset (uint_fast8_t idx);
|
||||
|
||||
spindle_ptrs_t *gc_spindle_get (void);
|
||||
|
||||
void gc_spindle_off (void);
|
||||
void gc_coolant_off (void);
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20230129
|
||||
#define GRBL_BUILD 20230213
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
@@ -163,8 +163,12 @@
|
||||
// allowable override values and the coarse and fine increments per command received. Please
|
||||
// note the allowable values in the descriptions following each define.
|
||||
#define DEFAULT_FEED_OVERRIDE 100 // 100%. Don't change this value.
|
||||
#define MAX_FEED_RATE_OVERRIDE 200 // Percent of programmed feed rate (100-255). Usually 120% or 200%
|
||||
#ifndef MAX_FEED_RATE_OVERRIDE
|
||||
#define MAX_FEED_RATE_OVERRIDE 200 // Percent of programmed feed rate (100-65535). Usually 120% or 200%
|
||||
#endif
|
||||
#ifndef MIN_FEED_RATE_OVERRIDE
|
||||
#define MIN_FEED_RATE_OVERRIDE 10 // Percent of programmed feed rate (1-100). Usually 50% or 1%
|
||||
#endif
|
||||
#define FEED_OVERRIDE_COARSE_INCREMENT 10 // (1-99). Usually 10%.
|
||||
#define FEED_OVERRIDE_FINE_INCREMENT 1 // (1-99). Usually 1%.
|
||||
|
||||
@@ -176,8 +180,12 @@
|
||||
// #define ENABLE_SPINDLE_LINEARIZATION // Uncomment to enable spindle RPM linearization. Requires compatible driver if enabled.
|
||||
#define SPINDLE_NPWM_PIECES 4 // Maximum number of pieces for spindle RPM linearization, do not change unless more are needed.
|
||||
#define DEFAULT_SPINDLE_RPM_OVERRIDE 100 // 100%. Don't change this value.
|
||||
#define MAX_SPINDLE_RPM_OVERRIDE 200 // Percent of programmed spindle speed (100-255). Usually 200%.
|
||||
#ifndef MAX_SPINDLE_RPM_OVERRIDE
|
||||
#define MAX_SPINDLE_RPM_OVERRIDE 200 // Percent of programmed spindle speed (100-65535). Usually 200%.
|
||||
#endif
|
||||
#ifndef MIN_SPINDLE_RPM_OVERRIDE
|
||||
#define MIN_SPINDLE_RPM_OVERRIDE 10 // Percent of programmed spindle speed (1-100). Usually 10%.
|
||||
#endif
|
||||
#define SPINDLE_OVERRIDE_COARSE_INCREMENT 10 // (1-99). Usually 10%.
|
||||
#define SPINDLE_OVERRIDE_FINE_INCREMENT 1 // (1-99). Usually 1%.
|
||||
|
||||
@@ -221,4 +229,12 @@
|
||||
#define MAX_STORED_LINE_LENGTH 70 // do not set > 70 unless less than 5 axes are enabled or COMPATIBILITY_LEVEL > 1
|
||||
#endif
|
||||
|
||||
#if N_SPINDLE > 4
|
||||
#define N_SPINDLE_SELECTABLE 4 // Max 4. for now!
|
||||
#else
|
||||
#define N_SPINDLE_SELECTABLE N_SPINDLE
|
||||
#endif
|
||||
|
||||
typedef uint_fast16_t override_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -203,13 +203,15 @@ int grbl_enter (void)
|
||||
if(driver.ok == 0xFF)
|
||||
driver.setup = hal.driver_setup(&settings);
|
||||
|
||||
spindle_select(settings.spindle.flags.type);
|
||||
|
||||
#ifdef ENABLE_SPINDLE_LINEARIZATION
|
||||
driver.linearization = hal.driver_cap.spindle_pwm_linearization;
|
||||
#endif
|
||||
|
||||
driver.spindle = hal.spindle.get_pwm == NULL || hal.spindle.update_pwm != NULL;
|
||||
if((driver.spindle = spindle_select(settings.spindle.flags.type))) {
|
||||
spindle_ptrs_t *spindle = spindle_get(0);
|
||||
driver.spindle = spindle->get_pwm == NULL || spindle->update_pwm != NULL;
|
||||
} else
|
||||
driver.spindle = spindle_select(spindle_add_null());
|
||||
|
||||
if(driver.ok != 0xFF) {
|
||||
sys.alarm = Alarm_SelftestFailed;
|
||||
@@ -218,9 +220,7 @@ int grbl_enter (void)
|
||||
|
||||
hal.stepper.enable(settings.steppers.deenergize);
|
||||
|
||||
if(hal.spindle.set_state)
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
|
||||
spindle_all_off();
|
||||
hal.coolant.set_state((coolant_state_t){0});
|
||||
|
||||
if(hal.get_position)
|
||||
@@ -253,6 +253,8 @@ int grbl_enter (void)
|
||||
// will return to this loop to be cleanly re-initialized.
|
||||
while(looping) {
|
||||
|
||||
spindle_num_t spindle_num = N_SYS_SPINDLE;
|
||||
|
||||
// Reset report entry points
|
||||
report_init_fns();
|
||||
|
||||
@@ -264,7 +266,10 @@ int grbl_enter (void)
|
||||
sys.var5399 = -2; // Clear last M66 result
|
||||
sys.override.feed_rate = DEFAULT_FEED_OVERRIDE; // Set to 100%
|
||||
sys.override.rapid_rate = DEFAULT_RAPID_OVERRIDE; // Set to 100%
|
||||
sys.override.spindle_rpm = DEFAULT_SPINDLE_RPM_OVERRIDE; // Set to 100%
|
||||
do {
|
||||
if(spindle_is_enabled(--spindle_num))
|
||||
spindle_get(spindle_num)->param->override_pct = DEFAULT_SPINDLE_RPM_OVERRIDE; // Set to 100%
|
||||
} while(spindle_num);
|
||||
sys.flags.auto_reporting = settings.report_interval != 0;
|
||||
|
||||
if(settings.parking.flags.enabled)
|
||||
|
||||
@@ -583,7 +583,7 @@ typedef struct {
|
||||
homing_ptrs_t homing; //!< Handlers for limit switches, used by homing cycle.
|
||||
control_signals_ptrs_t control; //!< Handlers for control switches.
|
||||
coolant_ptrs_t coolant; //!< Handlers for coolant.
|
||||
spindle_ptrs_t spindle; //!< Handlers for spindle.
|
||||
spindle_data_ptrs_t spindle_data; //!< Handlers for getting/resetting spindle data (RPM, angular position, ...).
|
||||
stepper_ptrs_t stepper; //!< Handlers for stepper motors.
|
||||
io_stream_t stream; //!< Handlers for stream I/O.
|
||||
stream_select_ptr stream_select; //!< Optional handler for switching between I/O streams.
|
||||
|
||||
+5
-8
@@ -161,7 +161,6 @@ static bool limits_pull_off (axes_signals_t axis, float distance)
|
||||
} while(idx);
|
||||
|
||||
plan_data.feed_rate = settings.homing.seek_rate * sqrtf(n_axis); // Adjust so individual axes all move at pull-off rate.
|
||||
plan_data.condition.spindle = gc_state.modal.spindle;
|
||||
plan_data.condition.coolant = gc_state.modal.coolant;
|
||||
memcpy(&plan_data.spindle, &gc_state.spindle, sizeof(spindle_t));
|
||||
|
||||
@@ -250,16 +249,14 @@ static bool limits_homing_cycle (axes_signals_t cycle, axes_signals_t auto_squar
|
||||
limit_signals_t limits_state;
|
||||
squaring_mode_t squaring_mode = SquaringMode_Both;
|
||||
coord_data_t target;
|
||||
plan_line_data_t plan_data;
|
||||
plan_line_data_t plan_data = {
|
||||
.condition.system_motion = On,
|
||||
.condition.no_feed_override = On,
|
||||
.line_number = DEFAULT_HOMING_CYCLE_LINE_NUMBER
|
||||
};
|
||||
|
||||
// Initialize plan data struct for homing motion.
|
||||
|
||||
memset(&plan_data, 0, sizeof(plan_line_data_t));
|
||||
plan_data.condition.system_motion = On;
|
||||
plan_data.condition.no_feed_override = On;
|
||||
plan_data.line_number = DEFAULT_HOMING_CYCLE_LINE_NUMBER;
|
||||
memcpy(&plan_data.spindle, &gc_state.spindle, sizeof(spindle_t));
|
||||
plan_data.condition.spindle = gc_state.modal.spindle;
|
||||
plan_data.condition.coolant = gc_state.modal.coolant;
|
||||
|
||||
uint_fast8_t idx = N_AXIS;
|
||||
|
||||
+11
-11
@@ -176,9 +176,9 @@ bool mc_line (float *target, plan_line_data_t *pl_data)
|
||||
// Plan and queue motion into planner buffer.
|
||||
// While in M3 laser mode also set spindle state and force a buffer sync
|
||||
// if there is a coincident position passed.
|
||||
if(!plan_buffer_line(target, pl_data) && sys.mode == Mode_Laser && pl_data->condition.spindle.on && !pl_data->condition.spindle.ccw) {
|
||||
if(!plan_buffer_line(target, pl_data) && pl_data->spindle.hal->cap.laser && pl_data->spindle.state.on && !pl_data->spindle.state.ccw) {
|
||||
protocol_buffer_synchronize();
|
||||
hal.spindle.set_state(pl_data->condition.spindle, pl_data->spindle.rpm);
|
||||
pl_data->spindle.hal->set_state(pl_data->spindle.state, pl_data->spindle.rpm);
|
||||
}
|
||||
|
||||
#ifdef KINEMATICS_API
|
||||
@@ -582,7 +582,7 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
|
||||
mc_dwell(canned->dwell);
|
||||
|
||||
if(canned->spindle_off)
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
pl_data->spindle.hal->set_state((spindle_state_t){0}, 0.0f);
|
||||
|
||||
// rapid retract
|
||||
switch(motion) {
|
||||
@@ -603,7 +603,7 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
|
||||
return;
|
||||
|
||||
if(canned->spindle_off)
|
||||
spindle_sync(0, gc_state.modal.spindle, pl_data->spindle.rpm);
|
||||
spindle_sync(pl_data->spindle.hal, gc_state.modal.spindle.state, pl_data->spindle.rpm);
|
||||
}
|
||||
|
||||
// rapid move to next position if incremental mode
|
||||
@@ -670,7 +670,7 @@ void mc_thread (plan_line_data_t *pl_data, float *position, gc_thread_data *thre
|
||||
|
||||
// TODO: Add to initial move to compensate for acceleration distance?
|
||||
/*
|
||||
float acc_distance = pl_data->feed_rate * hal.spindle.get_data(SpindleData_RPM)->rpm / settings.acceleration[Z_AXIS];
|
||||
float acc_distance = pl_data->feed_rate * pl_data->spindle.hal->get_data(SpindleData_RPM)->rpm / settings.acceleration[Z_AXIS];
|
||||
acc_distance = acc_distance * acc_distance * settings.acceleration[Z_AXIS] * 0.5f;
|
||||
*/
|
||||
|
||||
@@ -694,9 +694,9 @@ void mc_thread (plan_line_data_t *pl_data, float *position, gc_thread_data *thre
|
||||
if(!protocol_buffer_synchronize() && state_get() != STATE_IDLE) // Wait until any previous moves are finished.
|
||||
return;
|
||||
|
||||
pl_data->condition.rapid_motion = Off; // Clear rapid motion condition flag,
|
||||
pl_data->condition.spindle.synchronized = On; // enable spindle sync for cut
|
||||
pl_data->overrides.feed_hold_disable = On; // and disable feed hold
|
||||
pl_data->condition.rapid_motion = Off; // Clear rapid motion condition flag,
|
||||
pl_data->spindle.state.synchronized = On; // enable spindle sync for cut
|
||||
pl_data->overrides.feed_hold_disable = On; // and disable feed hold
|
||||
|
||||
// Cut thread pass
|
||||
|
||||
@@ -723,8 +723,8 @@ void mc_thread (plan_line_data_t *pl_data, float *position, gc_thread_data *thre
|
||||
return;
|
||||
}
|
||||
|
||||
pl_data->condition.rapid_motion = On; // Set rapid motion condition flag and
|
||||
pl_data->condition.spindle.synchronized = Off; // disable spindle sync for retract & reposition
|
||||
pl_data->condition.rapid_motion = On; // Set rapid motion condition flag and
|
||||
pl_data->spindle.state.synchronized = Off; // disable spindle sync for retract & reposition
|
||||
|
||||
if(passes > 1) {
|
||||
|
||||
@@ -861,7 +861,7 @@ status_code_t mc_homing_cycle (axes_signals_t cycle)
|
||||
hal.limits.enable(false, true); // Disable hard limits pin change register for cycle duration
|
||||
|
||||
// Turn off spindle and coolant (and update parser state)
|
||||
if(hal.spindle.get_state().on)
|
||||
if(spindle_is_on())
|
||||
gc_spindle_off();
|
||||
|
||||
if(hal.coolant.get_state().mask)
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2021 Terje Io
|
||||
Copyright (c) 2021-2023 Terje Io
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -424,11 +424,11 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
|
||||
break;
|
||||
|
||||
case NGCParam_spindle_rpm_mode:
|
||||
value = gc_state.modal.spindle_rpm_mode == SpindleSpeedMode_RPM ? 1.0f : 0.0f;
|
||||
value = gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_RPM ? 1.0f : 0.0f;
|
||||
break;
|
||||
|
||||
case NGCParam_spindle_css_mode:
|
||||
value = gc_state.modal.spindle_rpm_mode == SpindleSpeedMode_CSS ? 1.0f : 0.0f;
|
||||
value = gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_CSS ? 1.0f : 0.0f;
|
||||
break;
|
||||
|
||||
case NGCParam_ijk_absolute_mode:
|
||||
@@ -444,11 +444,11 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
|
||||
break;
|
||||
|
||||
case NGCParam_spindle_on:
|
||||
value = gc_state.modal.spindle.on ? 1.0f : 0.0f;
|
||||
value = gc_state.modal.spindle.state.on ? 1.0f : 0.0f;
|
||||
break;
|
||||
|
||||
case NGCParam_spindle_cw:
|
||||
value = gc_state.modal.spindle.ccw ? 1.0f : 0.0f;
|
||||
value = gc_state.modal.spindle.state.ccw ? 1.0f : 0.0f;
|
||||
break;
|
||||
|
||||
case NGCParam_mist:
|
||||
|
||||
@@ -315,13 +315,13 @@ bool plan_check_full_buffer (void)
|
||||
// NOTE: All system motion commands, such as homing/parking, are not subject to overrides.
|
||||
float plan_compute_profile_nominal_speed (plan_block_t *block)
|
||||
{
|
||||
float nominal_speed = block->condition.spindle.synchronized ? block->programmed_rate * hal.spindle.get_data(SpindleData_RPM)->rpm : block->programmed_rate;
|
||||
float nominal_speed = block->spindle.state.synchronized ? block->programmed_rate * block->spindle.hal->get_data(SpindleData_RPM)->rpm : block->programmed_rate;
|
||||
|
||||
if (block->condition.rapid_motion)
|
||||
nominal_speed *= (0.01f * sys.override.rapid_rate);
|
||||
nominal_speed *= (0.01f * (float)sys.override.rapid_rate);
|
||||
else {
|
||||
if (!block->condition.no_feed_override)
|
||||
nominal_speed *= (0.01f * sys.override.feed_rate);
|
||||
nominal_speed *= (0.01f * (float)sys.override.feed_rate);
|
||||
if (nominal_speed > block->rapid_rate)
|
||||
nominal_speed = block->rapid_rate;
|
||||
}
|
||||
@@ -465,21 +465,24 @@ bool plan_buffer_line (float *target, plan_line_data_t *pl_data)
|
||||
|
||||
} while(idx);
|
||||
|
||||
// Calculate RPMs to be used for Constant Surface Speed calculations
|
||||
if(block->condition.is_rpm_pos_adjusted) {
|
||||
// Calculate RPMs to be used for Constant Surface Speed (CSS) calculations.
|
||||
if(block->spindle.css) {
|
||||
|
||||
float pos;
|
||||
if((pos = (float)position_steps[block->spindle.css.axis] / settings.axis[block->spindle.css.axis].steps_per_mm - block->spindle.css.tool_offset) > 0.0f) {
|
||||
block->spindle.rpm = block->spindle.css.surface_speed / (pos * (float)(2.0f * M_PI));
|
||||
if(block->spindle.rpm > block->spindle.css.max_rpm)
|
||||
block->spindle.rpm = block->spindle.css.max_rpm;
|
||||
|
||||
if((pos = (float)position_steps[block->spindle.css->axis] / settings.axis[block->spindle.css->axis].steps_per_mm - block->spindle.css->tool_offset) > 0.0f) {
|
||||
if((block->spindle.rpm = block->spindle.css->surface_speed / (pos * (float)(2.0f * M_PI))) > block->spindle.css->max_rpm)
|
||||
block->spindle.rpm = block->spindle.css->max_rpm;
|
||||
} else
|
||||
block->spindle.rpm = block->spindle.css.max_rpm;
|
||||
if((pos = target[block->spindle.css.axis] - block->spindle.css.tool_offset) > 0.0f) {
|
||||
block->spindle.css.target_rpm = block->spindle.css.surface_speed / (pos * (float)(2.0f * M_PI));
|
||||
if(block->spindle.css.target_rpm > block->spindle.css.max_rpm)
|
||||
block->spindle.css.target_rpm = block->spindle.css.max_rpm;
|
||||
block->spindle.rpm = block->spindle.css->max_rpm;
|
||||
|
||||
if((pos = target[block->spindle.css->axis] - block->spindle.css->tool_offset) > 0.0f) {
|
||||
if((block->spindle.css->target_rpm = block->spindle.css->surface_speed / (pos * (float)(2.0f * M_PI))) > block->spindle.css->max_rpm)
|
||||
block->spindle.css->target_rpm = block->spindle.css->max_rpm;
|
||||
} else
|
||||
block->spindle.css.target_rpm = block->spindle.css.max_rpm;
|
||||
block->spindle.css->target_rpm = block->spindle.css->max_rpm;
|
||||
|
||||
block->spindle.css->delta_rpm = block->spindle.css->target_rpm - block->spindle.rpm;
|
||||
}
|
||||
|
||||
// Bail if this is a zero-length block. Highly unlikely to occur.
|
||||
@@ -662,7 +665,7 @@ void plan_cycle_reinitialize (void)
|
||||
}
|
||||
|
||||
// Set feed overrides
|
||||
void plan_feed_override (uint_fast8_t feed_override, uint_fast8_t rapid_override)
|
||||
void plan_feed_override (override_t feed_override, override_t rapid_override)
|
||||
{
|
||||
bool feedrate_changed = false, rapidrate_changed = false;
|
||||
|
||||
@@ -673,8 +676,8 @@ void plan_feed_override (uint_fast8_t feed_override, uint_fast8_t rapid_override
|
||||
|
||||
if ((feedrate_changed = feed_override != sys.override.feed_rate) ||
|
||||
(rapidrate_changed = rapid_override != sys.override.rapid_rate)) {
|
||||
sys.override.feed_rate = (uint8_t)feed_override;
|
||||
sys.override.rapid_rate = (uint8_t)rapid_override;
|
||||
sys.override.feed_rate = feed_override;
|
||||
sys.override.rapid_rate = rapid_override;
|
||||
sys.report.overrides = On; // Set to report change immediately
|
||||
plan_update_velocity_profile_parameters();
|
||||
plan_cycle_reinitialize();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2019-2022 Terje Io
|
||||
Copyright (c) 2019-2023 Terje Io
|
||||
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
Copyright (c) 2009-2011 Simen Svale Skogsrud
|
||||
|
||||
@@ -34,10 +34,8 @@ typedef union {
|
||||
no_feed_override :1,
|
||||
inverse_time :1,
|
||||
is_rpm_rate_adjusted :1,
|
||||
is_rpm_pos_adjusted :1,
|
||||
is_laser_ppi_mode :1,
|
||||
unassigned :7;
|
||||
spindle_state_t spindle;
|
||||
unassigned :8;
|
||||
coolant_state_t coolant;
|
||||
};
|
||||
} planner_cond_t;
|
||||
@@ -58,22 +56,22 @@ typedef struct plan_block {
|
||||
|
||||
// Fields used by the motion planner to manage acceleration. Some of these values may be updated
|
||||
// by the stepper module during execution of special motion cases for replanning purposes.
|
||||
float entry_speed_sqr; // The current planned entry speed at block junction in (mm/min)^2
|
||||
float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and
|
||||
// neighboring nominal speeds with overrides in (mm/min)^2
|
||||
float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
|
||||
float millimeters; // The remaining distance for this block to be executed in (mm).
|
||||
// NOTE: This value may be altered by stepper algorithm during execution.
|
||||
float entry_speed_sqr; // The current planned entry speed at block junction in (mm/min)^2
|
||||
float max_entry_speed_sqr; // Maximum allowable entry speed based on the minimum of junction limit and
|
||||
// neighboring nominal speeds with overrides in (mm/min)^2
|
||||
float acceleration; // Axis-limit adjusted line acceleration in (mm/min^2). Does not change.
|
||||
float millimeters; // The remaining distance for this block to be executed in (mm).
|
||||
// NOTE: This value may be altered by stepper algorithm during execution.
|
||||
|
||||
// Stored rate limiting data used by planner when changes occur.
|
||||
float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2
|
||||
float rapid_rate; // Axis-limit adjusted maximum rate for this block direction in (mm/min)
|
||||
float programmed_rate; // Programmed rate of this block (mm/min).
|
||||
float max_junction_speed_sqr; // Junction entry speed limit based on direction vectors in (mm/min)^2
|
||||
float rapid_rate; // Axis-limit adjusted maximum rate for this block direction in (mm/min)
|
||||
float programmed_rate; // Programmed rate of this block (mm/min).
|
||||
|
||||
// Stored spindle speed data used by spindle overrides and resuming methods.
|
||||
spindle_t spindle; // Block spindle speed. Copied from pl_line_data.
|
||||
spindle_t spindle; // Block spindle parameters. Copied from pl_line_data.
|
||||
|
||||
char *message; // Message to be displayed when block is executed.
|
||||
char *message; // Message to be displayed when block is executed.
|
||||
output_command_t *output_commands;
|
||||
struct plan_block *prev, *next; // Linked list pointers, DO NOT MOVE - these MUST be the last elements in the struct!
|
||||
} plan_block_t;
|
||||
@@ -83,7 +81,7 @@ typedef struct plan_block {
|
||||
typedef struct {
|
||||
float feed_rate; // Desired feed rate for line motion. Value is ignored, if rapid motion.
|
||||
// float blending_tolerance; // Motion blending tolerance
|
||||
spindle_t spindle; // Desired spindle speed through line motion.
|
||||
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
|
||||
int32_t line_number; // Desired line number to report when executing.
|
||||
@@ -143,6 +141,6 @@ uint_fast16_t plan_get_block_buffer_available (void);
|
||||
// Returns the status of the block ring buffer. True, if buffer is full.
|
||||
bool plan_check_full_buffer (void);
|
||||
|
||||
void plan_feed_override (uint_fast8_t feed_override, uint_fast8_t rapid_override);
|
||||
void plan_feed_override (override_t feed_override, override_t rapid_override);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -65,9 +65,18 @@ typedef union {
|
||||
} network_services_t;
|
||||
|
||||
typedef char ssid_t[65];
|
||||
typedef uint8_t bssid_t[6];
|
||||
typedef char username_t[33];
|
||||
typedef char password_t[33];
|
||||
typedef char hostname_t[33];
|
||||
typedef char sntp_server_t[129]; // URI
|
||||
typedef char uri_t[65];
|
||||
|
||||
typedef struct {
|
||||
char ip[16];
|
||||
uint16_t port;
|
||||
username_t user;
|
||||
password_t password;
|
||||
} mqtt_settings_t;
|
||||
|
||||
typedef struct {
|
||||
char ip[16];
|
||||
@@ -80,6 +89,9 @@ typedef struct {
|
||||
uint16_t ftp_port;
|
||||
ip_mode_t ip_mode;
|
||||
network_services_t services;
|
||||
#if MQTT_ENABLE
|
||||
mqtt_settings_t mqtt;
|
||||
#endif
|
||||
} network_settings_t;
|
||||
|
||||
typedef enum {
|
||||
@@ -94,12 +106,14 @@ typedef struct {
|
||||
bool link_up;
|
||||
uint16_t mbps;
|
||||
char mac[18];
|
||||
char mqtt_client_id[18];
|
||||
grbl_wifi_mode_t wifi_mode;
|
||||
network_settings_t status;
|
||||
} network_info_t;
|
||||
|
||||
typedef struct {
|
||||
ssid_t ssid;
|
||||
bssid_t bssid;
|
||||
password_t password;
|
||||
char country[4];
|
||||
uint8_t channel;
|
||||
@@ -149,11 +163,13 @@ typedef enum {
|
||||
typedef union {
|
||||
uint8_t events;
|
||||
struct {
|
||||
uint8_t position_changed :1,
|
||||
click :1,
|
||||
dbl_click :1,
|
||||
long_click :1,
|
||||
index_pulse :1;
|
||||
uint8_t position_changed :1,
|
||||
direction_changed :1,
|
||||
click :1,
|
||||
dbl_click :1,
|
||||
long_click :1,
|
||||
index_pulse :1,
|
||||
unused :2;
|
||||
};
|
||||
} encoder_event_t;
|
||||
|
||||
|
||||
+10
-5
@@ -43,11 +43,6 @@
|
||||
vfd_init();
|
||||
#endif
|
||||
|
||||
#if N_SPINDLE > 1
|
||||
extern void spindle_select_init(void);
|
||||
spindle_select_init();
|
||||
#endif
|
||||
|
||||
#ifndef GRBL_ESP32 // ESP32 has its own bluetooth_init
|
||||
#if BLUETOOTH_ENABLE
|
||||
extern void bluetooth_init (void);
|
||||
@@ -93,6 +88,11 @@
|
||||
extern void my_plugin_init (void);
|
||||
my_plugin_init();
|
||||
|
||||
#if N_SPINDLE > 1
|
||||
extern void spindle_select_init(void);
|
||||
spindle_select_init();
|
||||
#endif
|
||||
|
||||
// Third party plugin definitions.
|
||||
// The code for these has to be downloaded from the source and placed in the same folder as driver.c
|
||||
// Note: Third party plugins may have more than one implementation, there is no "owner" of plugins listed here.
|
||||
@@ -108,6 +108,11 @@
|
||||
probe_relay_init();
|
||||
#endif
|
||||
|
||||
#if DISPLAY_ENABLE
|
||||
void display_init (void);
|
||||
display_init();
|
||||
#endif
|
||||
|
||||
#if STATUS_LIGHT_ENABLE
|
||||
extern void status_light_init (void);
|
||||
status_light_init();
|
||||
|
||||
+16
-14
@@ -180,7 +180,7 @@ bool protocol_main_loop (void)
|
||||
|
||||
// Ensure spindle and coolant is switched off on a cold start
|
||||
if(sys.cold_start) {
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
spindle_all_off();
|
||||
hal.coolant.set_state((coolant_state_t){0});
|
||||
if(realtime_queue.head != realtime_queue.tail)
|
||||
system_set_exec_state_flag(EXEC_RT_COMMAND); // execute any boot up commands
|
||||
@@ -411,7 +411,7 @@ bool protocol_exec_rt_system (void)
|
||||
if((sys.reset_pending = !!(sys.rt_exec_state & EXEC_RESET))) {
|
||||
// Kill spindle and coolant.
|
||||
killed = true;
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
spindle_all_off();
|
||||
hal.coolant.set_state((coolant_state_t){0});
|
||||
}
|
||||
|
||||
@@ -468,7 +468,7 @@ bool protocol_exec_rt_system (void)
|
||||
|
||||
if(!killed) {
|
||||
// Kill spindle and coolant.
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
spindle_all_off();
|
||||
hal.coolant.set_state((coolant_state_t){0});
|
||||
}
|
||||
|
||||
@@ -500,11 +500,7 @@ bool protocol_exec_rt_system (void)
|
||||
sys.override.control = gc_state.modal.override_ctrl;
|
||||
|
||||
gc_state.tool_change = false;
|
||||
gc_state.modal.spindle_rpm_mode = SpindleSpeedMode_RPM;
|
||||
|
||||
// Kill spindle and coolant. TODO: Check Mach3 behaviour?
|
||||
gc_spindle_off();
|
||||
gc_coolant_off();
|
||||
gc_state.modal.spindle.rpm_mode = SpindleSpeedMode_RPM;
|
||||
|
||||
// Tell driver/plugins about reset.
|
||||
hal.driver_reset();
|
||||
@@ -523,6 +519,11 @@ bool protocol_exec_rt_system (void)
|
||||
} else*/
|
||||
st_reset();
|
||||
sync_position();
|
||||
|
||||
// Kill spindle and coolant. TODO: Check Mach3 behaviour?
|
||||
gc_spindle_off();
|
||||
gc_coolant_off();
|
||||
|
||||
flush_override_buffers();
|
||||
if(!((state_get() == STATE_ALARM) && (sys.alarm == Alarm_LimitsEngaged || sys.alarm == Alarm_HomingRequried)))
|
||||
state_set(hal.control.get_state().safety_door_ajar ? STATE_SAFETY_DOOR : STATE_IDLE);
|
||||
@@ -567,8 +568,8 @@ bool protocol_exec_rt_system (void)
|
||||
|
||||
if((rt_exec = get_feed_override())) {
|
||||
|
||||
int_fast16_t new_f_override = sys.override.feed_rate;
|
||||
uint_fast8_t new_r_override = sys.override.rapid_rate;
|
||||
override_t new_f_override = sys.override.feed_rate;
|
||||
override_t new_r_override = sys.override.rapid_rate;
|
||||
|
||||
do {
|
||||
|
||||
@@ -611,13 +612,14 @@ bool protocol_exec_rt_system (void)
|
||||
|
||||
} while((rt_exec = get_feed_override()));
|
||||
|
||||
plan_feed_override((uint_fast8_t)new_f_override, new_r_override);
|
||||
plan_feed_override(new_f_override, new_r_override);
|
||||
}
|
||||
|
||||
if((rt_exec = get_accessory_override())) {
|
||||
|
||||
bool spindle_stop = false;
|
||||
int_fast16_t last_s_override = sys.override.spindle_rpm;
|
||||
spindle_ptrs_t *spindle = gc_spindle_get();
|
||||
override_t last_s_override = spindle->param->override_pct;
|
||||
coolant_state_t coolant_state = gc_state.modal.coolant;
|
||||
|
||||
do {
|
||||
@@ -670,7 +672,7 @@ bool protocol_exec_rt_system (void)
|
||||
|
||||
} while((rt_exec = get_accessory_override()));
|
||||
|
||||
spindle_set_override((uint_fast8_t)last_s_override);
|
||||
spindle_set_override(spindle, last_s_override);
|
||||
|
||||
// NOTE: Since coolant state always performs a planner sync whenever it changes, the current
|
||||
// run state can be determined by checking the parser state.
|
||||
@@ -681,7 +683,7 @@ bool protocol_exec_rt_system (void)
|
||||
grbl.on_override_changed(OverrideChanged_CoolantState);
|
||||
}
|
||||
|
||||
if (spindle_stop && state_get() == STATE_HOLD && gc_state.modal.spindle.on) {
|
||||
if (spindle_stop && state_get() == STATE_HOLD && gc_state.modal.spindle.state.on) {
|
||||
// Spindle stop override allowed only while in HOLD state.
|
||||
// NOTE: Report flag is set in spindle_set_state() when spindle stop is executed.
|
||||
if (!sys.override.spindle_stop.value)
|
||||
|
||||
@@ -53,6 +53,8 @@ static uint8_t wco_counter = 0; // Tracks when to add work coordinate offse
|
||||
static const char vbar[2] = { '|', '\0' };
|
||||
|
||||
static bool report_setting (const setting_detail_t *setting, uint_fast16_t offset, void *data);
|
||||
static status_code_t report_status_message (status_code_t status_code);
|
||||
static message_code_t report_feedback_message (message_code_t id);
|
||||
|
||||
static const report_t report_fns = {
|
||||
.setting = report_setting,
|
||||
@@ -230,7 +232,7 @@ void report_init_fns (void)
|
||||
// operation. Errors events can originate from the g-code parser, settings module, or asynchronously
|
||||
// from a critical error, such as a triggered hard limit. Interface should always monitor for these
|
||||
// responses.
|
||||
status_code_t report_status_message (status_code_t status_code)
|
||||
static status_code_t report_status_message (status_code_t status_code)
|
||||
{
|
||||
switch(status_code) {
|
||||
|
||||
@@ -284,7 +286,7 @@ void report_message (const char *msg, message_type_t type)
|
||||
// messages such as setup warnings, switch toggling, and how to exit alarms.
|
||||
// NOTE: For interfaces, messages are always placed within brackets. And if silent mode
|
||||
// is installed, the message number codes are less than zero.
|
||||
message_code_t report_feedback_message (message_code_t id)
|
||||
static message_code_t report_feedback_message (message_code_t id)
|
||||
{
|
||||
const char *msg = NULL;
|
||||
uint_fast16_t idx = 0;
|
||||
@@ -681,7 +683,7 @@ void report_gcode_modes (void)
|
||||
|
||||
#endif
|
||||
|
||||
if(sys.mode == Mode_Lathe)
|
||||
if(settings.mode == Mode_Lathe)
|
||||
hal.stream.write(gc_state.modal.diameter_mode ? " G7" : " G8");
|
||||
|
||||
hal.stream.write(" G");
|
||||
@@ -694,8 +696,8 @@ void report_gcode_modes (void)
|
||||
hal.stream.write(" G");
|
||||
hal.stream.write(uitoa((uint32_t)(94 - gc_state.modal.feed_mode)));
|
||||
|
||||
if(sys.mode == Mode_Lathe && hal.spindle.cap.variable)
|
||||
hal.stream.write(gc_state.modal.spindle_rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
|
||||
if(settings.mode == Mode_Lathe && gc_spindle_get()->cap.variable)
|
||||
hal.stream.write(gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
|
||||
|
||||
#if COMPATIBILITY_LEVEL < 10
|
||||
|
||||
@@ -747,7 +749,7 @@ void report_gcode_modes (void)
|
||||
}
|
||||
}
|
||||
|
||||
hal.stream.write(gc_state.modal.spindle.on ? (gc_state.modal.spindle.ccw ? " M4" : " M3") : " M5");
|
||||
hal.stream.write(gc_state.modal.spindle.state.on ? (gc_state.modal.spindle.state.ccw ? " M4" : " M3") : " M5");
|
||||
|
||||
if(gc_state.tool_change)
|
||||
hal.stream.write(" M6");
|
||||
@@ -779,7 +781,7 @@ void report_gcode_modes (void)
|
||||
|
||||
hal.stream.write(appendbuf(2, " F", get_rate_value(gc_state.feed_rate)));
|
||||
|
||||
if(hal.spindle.cap.variable)
|
||||
if(gc_spindle_get()->cap.variable)
|
||||
hal.stream.write(appendbuf(2, " S", ftoa(gc_state.spindle.rpm, N_DECIMAL_RPMVALUE)));
|
||||
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
@@ -1177,19 +1179,41 @@ void report_realtime_status (void)
|
||||
hal.stream.write_all(appendbuf(2, "|Ln:", uitoa((uint32_t)cur_block->line_number)));
|
||||
}
|
||||
|
||||
spindle_state_t sp_state = hal.spindle.get_state();
|
||||
spindle_ptrs_t *spindle_0;
|
||||
spindle_state_t spindle_0_state;
|
||||
|
||||
spindle_0 = spindle_get(0);
|
||||
spindle_0_state = spindle_0->get_state();
|
||||
|
||||
// Report realtime feed speed
|
||||
if(settings.status_report.feed_speed) {
|
||||
if(hal.spindle.cap.variable) {
|
||||
if(spindle_0->cap.variable) {
|
||||
hal.stream.write_all(appendbuf(2, "|FS:", get_rate_value(st_get_realtime_rate())));
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa(sp_state.on ? lroundf(sys.spindle_rpm) : 0)));
|
||||
if(hal.spindle.get_data /* && sys.mpg_mode */)
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa(lroundf(hal.spindle.get_data(SpindleData_RPM)->rpm))));
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa(spindle_0_state.on ? lroundf(spindle_0->param->rpm_overridden) : 0)));
|
||||
if(spindle_0->get_data /* && sys.mpg_mode */)
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa(lroundf(spindle_0->get_data(SpindleData_RPM)->rpm))));
|
||||
} else
|
||||
hal.stream.write_all(appendbuf(2, "|F:", get_rate_value(st_get_realtime_rate())));
|
||||
}
|
||||
|
||||
#if N_SYS_SPINDLE > 1
|
||||
|
||||
for(idx = 1; idx < N_SYS_SPINDLE; idx++) {
|
||||
|
||||
spindle_ptrs_t *spindle_n;
|
||||
spindle_state_t spindle_n_state;
|
||||
|
||||
if((spindle_n = spindle_get(idx))) {
|
||||
spindle_n_state = spindle_n->get_state();
|
||||
hal.stream.write_all(appendbuf(3, "|SP", uitoa(idx), ":"));
|
||||
hal.stream.write_all(appendbuf(3, uitoa(spindle_n_state.on ? lroundf(spindle_n->param->rpm_overridden) : 0), ",,", spindle_n_state.on ? (spindle_n_state.ccw ? "C" : "S") : ""));
|
||||
if(settings.status_report.overrides)
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa(spindle_n->param->override_pct)));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(settings.status_report.pin_state) {
|
||||
|
||||
axes_signals_t lim_pin_state = limit_signals_merge(hal.limits.get_state());
|
||||
@@ -1236,7 +1260,7 @@ void report_realtime_status (void)
|
||||
if (override_counter > 0 && !sys.report.overrides)
|
||||
override_counter--;
|
||||
else if((sys.report.overrides = !sys.report.wco)) {
|
||||
sys.report.spindle = sys.report.spindle || hal.spindle.get_state().on;
|
||||
sys.report.spindle = sys.report.spindle || spindle_0_state.on;
|
||||
sys.report.coolant = sys.report.coolant || hal.coolant.get_state().value != 0;
|
||||
override_counter = state_get() & (STATE_HOMING|STATE_CYCLE|STATE_HOLD|STATE_JOG|STATE_SAFETY_DOOR)
|
||||
? (REPORT_OVERRIDE_REFRESH_BUSY_COUNT - 1) // Reset counter for slow refresh
|
||||
@@ -1260,7 +1284,7 @@ void report_realtime_status (void)
|
||||
if(sys.report.overrides) {
|
||||
hal.stream.write_all(appendbuf(2, "|Ov:", uitoa((uint32_t)sys.override.feed_rate)));
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa((uint32_t)sys.override.rapid_rate)));
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa((uint32_t)sys.override.spindle_rpm)));
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa((uint32_t)spindle_0->param->override_pct)));
|
||||
}
|
||||
|
||||
if(sys.report.spindle || sys.report.coolant || sys.report.tool || gc_state.tool_change) {
|
||||
@@ -1271,12 +1295,12 @@ void report_realtime_status (void)
|
||||
|
||||
strcpy(buf, "|A:");
|
||||
|
||||
if (sp_state.on)
|
||||
if (spindle_0_state.on)
|
||||
|
||||
*append++ = sp_state.ccw ? 'C' : 'S';
|
||||
*append++ = spindle_0_state.ccw ? 'C' : 'S';
|
||||
|
||||
#if COMPATIBILITY_LEVEL == 0
|
||||
if(sp_state.encoder_error && hal.driver_cap.spindle_sync)
|
||||
if(spindle_0_state.encoder_error && hal.driver_cap.spindle_sync)
|
||||
*append++ = 'E';
|
||||
#endif
|
||||
|
||||
@@ -1309,7 +1333,7 @@ void report_realtime_status (void)
|
||||
hal.stream.write_all(appendbuf(2, ",", uitoa(sys.homed.mask)));
|
||||
}
|
||||
|
||||
if(sys.report.xmode && sys.mode == Mode_Lathe)
|
||||
if(sys.report.xmode && settings.mode == Mode_Lathe)
|
||||
hal.stream.write_all(gc_state.modal.diameter_mode ? "|D:1" : "|D:0");
|
||||
|
||||
if(sys.report.tool)
|
||||
@@ -2038,23 +2062,25 @@ status_code_t report_current_limit_state (sys_state_t state, char *args)
|
||||
// Prints spindle data (encoder pulse and index count, angular position).
|
||||
status_code_t report_spindle_data (sys_state_t state, char *args)
|
||||
{
|
||||
if(hal.spindle.get_data) {
|
||||
spindle_ptrs_t *spindle = gc_spindle_get();
|
||||
|
||||
float apos = hal.spindle.get_data(SpindleData_AngularPosition)->angular_position;
|
||||
spindle_data_t *spindle = hal.spindle.get_data(SpindleData_Counters);
|
||||
if(spindle->get_data) {
|
||||
|
||||
float apos = spindle->get_data(SpindleData_AngularPosition)->angular_position;
|
||||
spindle_data_t *data = spindle->get_data(SpindleData_Counters);
|
||||
|
||||
hal.stream.write("[SPINDLE:");
|
||||
hal.stream.write(uitoa(spindle->index_count));
|
||||
hal.stream.write(uitoa(data->index_count));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(uitoa(spindle->pulse_count));
|
||||
hal.stream.write(uitoa(data->pulse_count));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(uitoa(spindle->error_count));
|
||||
hal.stream.write(uitoa(data->error_count));
|
||||
hal.stream.write(",");
|
||||
hal.stream.write(ftoa(apos, 3));
|
||||
hal.stream.write("]" ASCII_EOL);
|
||||
}
|
||||
|
||||
return hal.spindle.get_data ? Status_OK : Status_InvalidStatement;
|
||||
return spindle->get_data ? Status_OK : Status_InvalidStatement;
|
||||
}
|
||||
|
||||
static const char *get_pinname (pin_function_t function)
|
||||
@@ -2122,6 +2148,30 @@ status_code_t report_time (void)
|
||||
return ok ? Status_OK : Status_InvalidStatement;
|
||||
}
|
||||
|
||||
static void report_spindle (spindle_info_t *spindle)
|
||||
{
|
||||
hal.stream.write(uitoa(spindle->id));
|
||||
hal.stream.write(" - ");
|
||||
hal.stream.write(spindle->name);
|
||||
if(spindle->enabled) {
|
||||
#if N_SPINDLE > 1
|
||||
hal.stream.write(", enabled as spindle ");
|
||||
hal.stream.write(uitoa(spindle->num));
|
||||
#else
|
||||
hal.stream.write(", active");
|
||||
#endif
|
||||
}
|
||||
hal.stream.write(ASCII_EOL);
|
||||
}
|
||||
|
||||
status_code_t report_spindles (void)
|
||||
{
|
||||
if(!spindle_enumerate_spindles(report_spindle))
|
||||
hal.stream.write("No spindles registered." ASCII_EOL);
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
void report_pid_log (void)
|
||||
{
|
||||
#ifdef PID_LOG
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2018-2021 Terje Io
|
||||
Copyright (c) 2018-2023 Terje Io
|
||||
Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
@@ -44,8 +44,6 @@ typedef enum {
|
||||
void report_init (void);
|
||||
void report_init_fns (void);
|
||||
|
||||
// Prints system status messages.
|
||||
status_code_t report_status_message (status_code_t status_code);
|
||||
|
||||
// Prints system alarm messages.
|
||||
alarm_code_t report_alarm_message (alarm_code_t alarm_code);
|
||||
@@ -53,9 +51,6 @@ alarm_code_t report_alarm_message (alarm_code_t alarm_code);
|
||||
// Prints feedback message, typically from gcode.
|
||||
void report_message (const char *msg, message_type_t type);
|
||||
|
||||
// Prints miscellaneous feedback messages.
|
||||
message_code_t report_feedback_message (message_code_t message_code);
|
||||
|
||||
// Prints welcome message.
|
||||
void report_init_message (void);
|
||||
|
||||
@@ -114,9 +109,12 @@ status_code_t report_current_limit_state (sys_state_t state, char *args);
|
||||
// Prints spindle data (encoder pulse and index count, angular position).
|
||||
status_code_t report_spindle_data (sys_state_t state, char *args);
|
||||
|
||||
// Prints pin assignments
|
||||
// Prints pin assignments.
|
||||
status_code_t report_pins (sys_state_t state, char *args);
|
||||
|
||||
// Prints registered spindles.
|
||||
status_code_t report_spindles (void);
|
||||
|
||||
// Prints current RTC datetime in ISO8601 format (when available)
|
||||
status_code_t report_time (void);
|
||||
|
||||
|
||||
+138
-47
@@ -107,8 +107,8 @@ PROGMEM const settings_t defaults = {
|
||||
#if DEFAULT_HOMING_ENABLE
|
||||
.homing.flags.enabled = DEFAULT_HOMING_ENABLE,
|
||||
.homing.flags.init_lock = DEFAULT_HOMING_INIT_LOCK,
|
||||
.homing.flags.single_axis_commands = HOMING_SINGLE_AXIS_COMMANDS,
|
||||
.homing.flags.force_set_origin = HOMING_FORCE_SET_ORIGIN,
|
||||
.homing.flags.single_axis_commands = DEFAULT_HOMING_SINGLE_AXIS_COMMANDS,
|
||||
.homing.flags.force_set_origin = DEFAULT_HOMING_FORCE_SET_ORIGIN,
|
||||
.homing.flags.manual = DEFAULT_HOMING_ALLOW_MANUAL,
|
||||
.homing.flags.override_locks = DEFAULT_HOMING_OVERRIDE_LOCKS,
|
||||
.homing.flags.keep_on_reset = DEFAULT_HOMING_KEEP_STATUS_ON_RESET,
|
||||
@@ -392,6 +392,7 @@ static uint32_t get_int (setting_id_t id);
|
||||
static bool is_setting_available (const setting_detail_t *setting);
|
||||
static bool is_group_available (const setting_detail_t *setting);
|
||||
|
||||
static bool machine_mode_changed = false;
|
||||
static char control_signals[] = "Reset,Feed hold,Cycle start,Safety door,Block delete,Optional stop,EStop,Probe connected,Motor fault";
|
||||
static char spindle_signals[] = "Spindle enable,Spindle direction,PWM";
|
||||
static char coolant_signals[] = "Flood,Mist";
|
||||
@@ -808,7 +809,7 @@ static status_code_t set_enable_invert_mask (setting_id_t id, uint_fast16_t int_
|
||||
|
||||
static status_code_t set_limits_invert_mask (setting_id_t id, uint_fast16_t int_value)
|
||||
{
|
||||
settings.limits.invert.mask = (int_value ? ~(INVERT_LIMIT_BIT_MASK) : INVERT_LIMIT_BIT_MASK) & AXES_BITMASK;
|
||||
settings.limits.invert.mask = (int_value ? ~(DEFAULT_LIMIT_SIGNALS_INVERT_MASK) : DEFAULT_LIMIT_SIGNALS_INVERT_MASK) & AXES_BITMASK;
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
@@ -981,6 +982,13 @@ static status_code_t set_homing_enable (setting_id_t id, uint_fast16_t int_value
|
||||
if (bit_istrue(int_value, bit(0))) {
|
||||
#if COMPATIBILITY_LEVEL > 1
|
||||
settings.homing.flags.enabled = On;
|
||||
settings.homing.flags.init_lock = DEFAULT_HOMING_INIT_LOCK;
|
||||
settings.homing.flags.single_axis_commands = DEFAULT_HOMING_SINGLE_AXIS_COMMANDS;
|
||||
settings.homing.flags.force_set_origin = DEFAULT_HOMING_FORCE_SET_ORIGIN;
|
||||
settings.homing.flags.manual = DEFAULT_HOMING_ALLOW_MANUAL;
|
||||
settings.homing.flags.override_locks = DEFAULT_HOMING_OVERRIDE_LOCKS;
|
||||
settings.homing.flags.keep_on_reset = DEFAULT_HOMING_KEEP_STATUS_ON_RESET;
|
||||
settings.limits.flags.two_switches = DEFAULT_LIMITS_TWO_SWITCHES_ON_AXES;
|
||||
#else
|
||||
settings.homing.flags.value = int_value & 0x0F;
|
||||
settings.limits.flags.two_switches = bit_istrue(int_value, bit(4));
|
||||
@@ -1022,8 +1030,8 @@ static status_code_t set_mode (setting_id_t id, uint_fast16_t int_value)
|
||||
break;
|
||||
|
||||
case Mode_Laser:
|
||||
if(!spindle_get_caps().laser)
|
||||
return Status_SettingDisabledLaser;
|
||||
// if(!spindle_get_caps().laser)
|
||||
// return Status_SettingDisabledLaser;
|
||||
if(settings.mode != Mode_Laser)
|
||||
settings.flags.disable_laser_during_hold = DEFAULT_ENABLE_LASER_DURING_HOLD;
|
||||
gc_state.modal.diameter_mode = false;
|
||||
@@ -1037,8 +1045,8 @@ static status_code_t set_mode (setting_id_t id, uint_fast16_t int_value)
|
||||
return Status_InvalidStatement;
|
||||
}
|
||||
|
||||
machine_mode_changed = true;
|
||||
settings.mode = (machine_mode_t)int_value;
|
||||
sys.mode = settings.mode == Mode_Laser && !hal.spindle.cap.laser ? Mode_Standard : settings.mode;
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
@@ -1374,7 +1382,7 @@ static uint32_t get_int (setting_id_t id)
|
||||
|
||||
#if COMPATIBILITY_LEVEL > 1
|
||||
case Setting_LimitPinsInvertMask:
|
||||
value = settings.limits.invert.mask == INVERT_LIMIT_BIT_MASK ? 0 : 1;
|
||||
value = settings.limits.invert.mask == DEFAULT_LIMIT_SIGNALS_INVERT_MASK ? 0 : 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -1759,11 +1767,11 @@ static bool is_setting_available (const setting_detail_t *setting)
|
||||
#endif
|
||||
|
||||
case Setting_SpindleAtSpeedTolerance:
|
||||
available = hal.spindle.cap.at_speed || hal.driver_cap.spindle_sync;
|
||||
available = spindle_get_caps().at_speed || hal.driver_cap.spindle_sync;
|
||||
break;
|
||||
|
||||
case Setting_SpindleOnDelay:
|
||||
available = !hal.signals_cap.safety_door_ajar && hal.spindle.cap.at_speed;
|
||||
available = !hal.signals_cap.safety_door_ajar && spindle_get_caps().at_speed;
|
||||
break;
|
||||
|
||||
case Setting_AutoReportInterval:
|
||||
@@ -1902,8 +1910,6 @@ bool read_global_settings ()
|
||||
if(settings.planner_buffer_blocks < 30 || settings.planner_buffer_blocks > 1000)
|
||||
settings.planner_buffer_blocks = 35;
|
||||
|
||||
sys.mode = settings.mode;
|
||||
|
||||
if(!(hal.driver_cap.spindle_sync || hal.driver_cap.spindle_pid))
|
||||
settings.spindle.ppr = 0;
|
||||
|
||||
@@ -1948,7 +1954,6 @@ void settings_restore (settings_restore_t restore)
|
||||
|
||||
memcpy(&settings, &defaults, sizeof(settings_t));
|
||||
|
||||
sys.mode = settings.mode == Mode_Laser && !hal.spindle.cap.laser ? Mode_Standard : settings.mode;
|
||||
settings.control_invert.mask &= hal.signals_cap.mask;
|
||||
settings.spindle.invert.ccw &= spindle_get_caps().direction;
|
||||
settings.spindle.invert.pwm &= spindle_get_caps().pwm_invert;
|
||||
@@ -2263,6 +2268,35 @@ static status_code_t validate_value (const setting_detail_t *setting, float valu
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
static status_code_t validate_uint_value (const setting_detail_t *setting, uint32_t value)
|
||||
{
|
||||
uint32_t val;
|
||||
uint_fast8_t set_idx = 0;
|
||||
status_code_t status;
|
||||
|
||||
if(setting->min_value) {
|
||||
if((status = read_uint((char *)setting->min_value, &set_idx, &val)) != Status_OK)
|
||||
return status;
|
||||
|
||||
if(!(value >= val || (setting->flags.allow_null && value == 0)))
|
||||
return Status_SettingValueOutOfRange;
|
||||
|
||||
} else if(value < 0.0f)
|
||||
return Status_NegativeValue;
|
||||
|
||||
if(setting->max_value) {
|
||||
set_idx = 0;
|
||||
|
||||
if((status = read_uint((char *)setting->max_value, &set_idx, &val)) != Status_OK)
|
||||
return Status_BadNumberFormat;
|
||||
|
||||
if(value > val)
|
||||
return Status_SettingValueOutOfRange;
|
||||
}
|
||||
|
||||
return Status_OK;
|
||||
}
|
||||
|
||||
static uint32_t strnumentries (const char *s, const char delimiter)
|
||||
{
|
||||
if(s == NULL || *s == '\0')
|
||||
@@ -2362,11 +2396,56 @@ inline static bool setting_is_string (setting_datatype_t datatype)
|
||||
return datatype == Format_String || datatype == Format_Password || datatype == Format_IPv4;
|
||||
}
|
||||
|
||||
inline static bool setting_is_core (setting_type_t type)
|
||||
inline static bool setting_is_core (setting_type_t type)
|
||||
{
|
||||
return !(type == Setting_NonCore || type == Setting_NonCoreFn);
|
||||
}
|
||||
|
||||
static status_code_t setting_validate_me_uint (const setting_detail_t *setting, char *svalue)
|
||||
{
|
||||
uint_fast8_t idx = 0;
|
||||
uint32_t value;
|
||||
status_code_t status;
|
||||
|
||||
if((status = read_uint(svalue, &idx, &value)) != Status_OK)
|
||||
return status;
|
||||
|
||||
switch(setting->datatype) {
|
||||
|
||||
case Format_Bool:
|
||||
if(!(value == 0 || value == 1))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_Bitfield:
|
||||
case Format_XBitfield:;
|
||||
if(value >= (1UL << strnumentries(setting->format, ',')))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_RadioButtons:
|
||||
if(value >= strnumentries(setting->format, ','))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_AxisMask:
|
||||
if(value >= (1 << N_AXIS))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_Int8:
|
||||
case Format_Int16:
|
||||
case Format_Integer:
|
||||
status = validate_uint_value(setting, value);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_code_t setting_validate_me (const setting_detail_t *setting, float value, char *svalue)
|
||||
{
|
||||
status_code_t status = Status_OK;
|
||||
@@ -2374,33 +2453,18 @@ status_code_t setting_validate_me (const setting_detail_t *setting, float value,
|
||||
switch(setting->datatype) {
|
||||
|
||||
case Format_Bool:
|
||||
if(!(value == 0.0f || value == 1.0f))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_Bitfield:
|
||||
case Format_XBitfield:;
|
||||
if(!(isintf(value) && ((uint32_t)value < (1UL << strnumentries(setting->format, ','))))) //)
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_RadioButtons:
|
||||
if(!(isintf(value) && (uint32_t)value < strnumentries(setting->format, ',')))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_AxisMask:
|
||||
if(!(isintf(value) && (uint32_t)value < (1 << N_AXIS)))
|
||||
status = Status_SettingValueOutOfRange;
|
||||
break;
|
||||
|
||||
case Format_Int8:
|
||||
case Format_Int16:
|
||||
case Format_Integer:
|
||||
status = setting_validate_me_uint(setting, svalue);
|
||||
break;
|
||||
|
||||
case Format_Decimal:
|
||||
status = validate_value(setting, value);
|
||||
if(setting->datatype == Format_Integer && status == Status_OK && !isintf(value))
|
||||
status = Status_BadNumberFormat;
|
||||
break;
|
||||
|
||||
case Format_Password:
|
||||
@@ -2436,10 +2500,23 @@ status_code_t setting_validate (setting_id_t id, float value, char *svalue)
|
||||
return setting == NULL ? Status_OK : setting_validate_me(setting, value, svalue);
|
||||
}
|
||||
|
||||
static bool settings_changed_spindle (void)
|
||||
{
|
||||
static spindle_settings_t spindle_settings = {0};
|
||||
|
||||
bool changed;
|
||||
|
||||
if((changed = memcmp(&spindle_settings, &settings.spindle, sizeof(spindle_settings_t))) != 0)
|
||||
memcpy(&spindle_settings, &settings.spindle, sizeof(spindle_settings_t));
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
// A helper method to set settings from command line
|
||||
status_code_t settings_store_setting (setting_id_t id, char *svalue)
|
||||
{
|
||||
uint_fast8_t set_idx = 0;
|
||||
uint32_t int_value = 0;
|
||||
float value = NAN;
|
||||
status_code_t status = Status_OK;
|
||||
setting_details_t *set;
|
||||
@@ -2457,7 +2534,10 @@ status_code_t settings_store_setting (setting_id_t id, char *svalue)
|
||||
while(*svalue == ' ')
|
||||
svalue++;
|
||||
|
||||
if(!setting_is_string(setting->datatype) && !read_float(svalue, &set_idx, &value) && setting_is_core(setting->type))
|
||||
if(setting->datatype == Format_Decimal) {
|
||||
if(!read_float(svalue, &set_idx, &value) && setting_is_core(setting->type))
|
||||
return Status_BadNumberFormat;
|
||||
} else if(!setting_is_string(setting->datatype) && read_uint(svalue, &set_idx, &int_value) != Status_OK && setting_is_core(setting->type))
|
||||
return Status_BadNumberFormat;
|
||||
|
||||
if((status = setting_validate_me(setting, value, svalue)) != Status_OK) {
|
||||
@@ -2485,23 +2565,23 @@ status_code_t settings_store_setting (setting_id_t id, char *svalue)
|
||||
break;
|
||||
|
||||
case Format_AxisMask:
|
||||
*((uint8_t *)(setting->value)) = (uint8_t)truncf(value) & AXES_BITMASK;
|
||||
*((uint8_t *)(setting->value)) = (uint8_t)int_value & AXES_BITMASK;
|
||||
break;
|
||||
|
||||
case Format_Int8:
|
||||
case Format_Bool:
|
||||
case Format_Bitfield:
|
||||
case Format_XBitfield:
|
||||
case Format_RadioButtons:
|
||||
*((uint8_t *)(setting->value)) = (uint8_t)truncf(value);
|
||||
case Format_Int8:
|
||||
*((uint8_t *)(setting->value)) = (uint8_t)int_value;
|
||||
break;
|
||||
|
||||
case Format_Int16:
|
||||
*((uint16_t *)(setting->value)) = (uint16_t)truncf(value);
|
||||
*((uint16_t *)(setting->value)) = (uint16_t)int_value;
|
||||
break;
|
||||
|
||||
case Format_Integer:
|
||||
*((uint32_t *)(setting->value)) = (uint32_t)truncf(value);
|
||||
*((uint32_t *)(setting->value)) = (uint32_t)int_value;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2527,7 +2607,7 @@ status_code_t settings_store_setting (setting_id_t id, char *svalue)
|
||||
break;
|
||||
|
||||
default:
|
||||
status = ((setting_set_int_ptr)(setting->value))(id, (uint_fast16_t)truncf(value));
|
||||
status = ((setting_set_int_ptr)(setting->value))(id, (uint_fast16_t)int_value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -2535,16 +2615,18 @@ status_code_t settings_store_setting (setting_id_t id, char *svalue)
|
||||
|
||||
if(status == Status_OK) {
|
||||
|
||||
if(!hal.spindle.cap.rpm_range_locked) {
|
||||
hal.spindle.rpm_min = settings.spindle.rpm_min;
|
||||
hal.spindle.rpm_max = settings.spindle.rpm_max;
|
||||
}
|
||||
|
||||
if(set->save)
|
||||
set->save();
|
||||
|
||||
if(set->on_changed)
|
||||
set->on_changed(&settings);
|
||||
if(set->on_changed) {
|
||||
|
||||
settings_changed_flags_t changed = {0};
|
||||
|
||||
changed.spindle = settings_changed_spindle() || machine_mode_changed;
|
||||
machine_mode_changed = false;
|
||||
|
||||
set->on_changed(&settings, changed);
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -2573,11 +2655,16 @@ void settings_clear (void)
|
||||
// Initialize the config subsystem
|
||||
void settings_init (void)
|
||||
{
|
||||
settings_changed_flags_t changed = {0};
|
||||
|
||||
if(!read_global_settings()) {
|
||||
|
||||
settings_restore_t settings = settings_all;
|
||||
settings.defaults = 1; // Ensure global settings get restored
|
||||
|
||||
if(hal.nvs.type != NVS_None)
|
||||
grbl.report.status_message(Status_SettingReadFail);
|
||||
|
||||
settings_restore(settings); // Force restore all non-volatile storage data.
|
||||
report_init();
|
||||
#if COMPATIBILITY_LEVEL <= 1
|
||||
@@ -2585,7 +2672,9 @@ void settings_init (void)
|
||||
#else
|
||||
report_grbl_settings(false, NULL);
|
||||
#endif
|
||||
changed.spindle = settings_changed_spindle();
|
||||
} else {
|
||||
|
||||
memset(&tool_table, 0, sizeof(tool_data_t)); // First entry is for tools not in tool table
|
||||
#if N_TOOLS
|
||||
uint_fast8_t idx;
|
||||
@@ -2594,7 +2683,9 @@ void settings_init (void)
|
||||
#endif
|
||||
report_init();
|
||||
|
||||
hal.settings_changed(&settings);
|
||||
changed.spindle = settings_changed_spindle();
|
||||
|
||||
hal.settings_changed(&settings, changed);
|
||||
|
||||
if(hal.probe.configure) // Initialize probe invert mask.
|
||||
hal.probe.configure(false, false);
|
||||
@@ -2625,7 +2716,7 @@ void settings_init (void)
|
||||
if(details->load)
|
||||
details->load();
|
||||
if(details->on_changed)
|
||||
details->on_changed(&settings);
|
||||
details->on_changed(&settings, changed);
|
||||
} while((details = details->next));
|
||||
|
||||
setting_details.on_changed = hal.settings_changed;
|
||||
|
||||
+42
-2
@@ -162,7 +162,7 @@ typedef enum {
|
||||
|
||||
// Optional driver implemented settings
|
||||
|
||||
// Normally used for Ethernet or WiFi Station
|
||||
// Normally used for Ethernet
|
||||
Setting_Hostname = 300,
|
||||
Setting_IpMode = 301,
|
||||
Setting_IpAddress = 302,
|
||||
@@ -184,6 +184,7 @@ typedef enum {
|
||||
Setting_WebSocketPort2 = 317,
|
||||
Setting_FtpPort2 = 318,
|
||||
|
||||
// Normally used for WiFi Station
|
||||
Setting_Hostname3 = 320,
|
||||
Setting_IpMode3 = 321,
|
||||
Setting_IpAddress3 = 322,
|
||||
@@ -202,6 +203,8 @@ typedef enum {
|
||||
Setting_Timezone = 335,
|
||||
Setting_DSTActive = 336,
|
||||
|
||||
Setting_Wifi_AP_BSSID = 337,
|
||||
|
||||
Setting_TrinamicDriver = 338,
|
||||
Setting_TrinamicHoming = 339,
|
||||
|
||||
@@ -299,6 +302,11 @@ typedef enum {
|
||||
Setting_VFD_20 = 472,
|
||||
Setting_VFD_21 = 473,
|
||||
|
||||
Setting_VFD_ModbusAddress0 = 476,
|
||||
Setting_VFD_ModbusAddress1 = 477,
|
||||
Setting_VFD_ModbusAddress2 = 478,
|
||||
Setting_VFD_ModbusAddress3 = 479,
|
||||
|
||||
Setting_Fan0OffDelay = 480,
|
||||
Setting_AutoReportInterval = 481,
|
||||
Setting_TimeZoneOffset = 482,
|
||||
@@ -326,6 +334,29 @@ typedef enum {
|
||||
Setting_MacroPort8 = 508,
|
||||
Setting_MacroPort9 = 509,
|
||||
|
||||
Setting_SpindleEnable0 = 510,
|
||||
Setting_SpindleEnable1 = 511,
|
||||
Setting_SpindleEnable2 = 512,
|
||||
Setting_SpindleEnable3 = 513,
|
||||
Setting_SpindleEnable4 = 514,
|
||||
Setting_SpindleEnable5 = 515,
|
||||
Setting_SpindleEnable6 = 516,
|
||||
Setting_SpindleEnable7 = 517,
|
||||
|
||||
Setting_SpindleToolStart0 = 520,
|
||||
Setting_SpindleToolStart1 = 521,
|
||||
Setting_SpindleToolStart2 = 522,
|
||||
Setting_SpindleToolStart3 = 523,
|
||||
Setting_SpindleToolStart4 = 524,
|
||||
Setting_SpindleToolStart5 = 525,
|
||||
Setting_SpindleToolStart6 = 526,
|
||||
Setting_SpindleToolStart7 = 527,
|
||||
|
||||
Setting_MQTTBrokerIpAddress = 530,
|
||||
Setting_MQTTBrokerPort = 531,
|
||||
Setting_MQTTBrokerUserName = 532,
|
||||
Setting_MQTTBrokerPassword = 533,
|
||||
|
||||
Setting_SettingsMax,
|
||||
Setting_SettingsAll = Setting_SettingsMax,
|
||||
|
||||
@@ -770,6 +801,14 @@ typedef struct {
|
||||
const char *description;
|
||||
} setting_descr_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t value;
|
||||
struct {
|
||||
uint8_t spindle :1,
|
||||
unassigned :7;
|
||||
};
|
||||
} settings_changed_flags_t;
|
||||
|
||||
typedef status_code_t (*setting_set_int_ptr)(setting_id_t id, uint_fast16_t value);
|
||||
typedef status_code_t (*setting_set_float_ptr)(setting_id_t id, float value);
|
||||
typedef status_code_t (*setting_set_string_ptr)(setting_id_t id, char *value);
|
||||
@@ -780,8 +819,9 @@ typedef bool (*setting_output_ptr)(const setting_detail_t *setting, uint_fast16_
|
||||
|
||||
/*! \brief Pointer to callback function to be called when settings are loaded or changed.
|
||||
\param settings pointer to \a settings_t struct containing the settings.
|
||||
\param changed a \a settings_changed_flags_t union containing the changed setting groups.
|
||||
*/
|
||||
typedef void (*settings_changed_ptr)(settings_t *settings);
|
||||
typedef void (*settings_changed_ptr)(settings_t *settings, settings_changed_flags_t changed);
|
||||
|
||||
typedef void (*driver_settings_load_ptr)(void);
|
||||
typedef void (*driver_settings_save_ptr)(void);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Part of grblHAL
|
||||
|
||||
Copyright (c) 2018-2021 Terje Io
|
||||
Copyright (c) 2018-2023 Terje Io
|
||||
Copyright (c) 2016 Sungeun K. Jeon
|
||||
|
||||
Grbl is free software: you can redistribute it and/or modify
|
||||
@@ -67,7 +67,7 @@ void sleep_check()
|
||||
// has any powered components enabled.
|
||||
// NOTE: With overrides or in laser mode, modal spindle and coolant state are not guaranteed. Need
|
||||
// to directly monitor and record running state during parking to ensure proper function.
|
||||
if (!sys.steppers_deenergize && (gc_state.modal.spindle.value || gc_state.modal.coolant.value)) {
|
||||
if (!sys.steppers_deenergize && (gc_state.modal.spindle.state.value || gc_state.modal.coolant.value)) {
|
||||
switch(state_get()) {
|
||||
|
||||
case STATE_IDLE:
|
||||
|
||||
+424
-124
File diff suppressed because it is too large
Load Diff
+95
-56
@@ -25,24 +25,25 @@
|
||||
#define _SPINDLE_CONTROL_H_
|
||||
|
||||
typedef int8_t spindle_id_t;
|
||||
typedef int8_t spindle_num_t;
|
||||
|
||||
// if changed to > 8 bits planner_cond_t needs to be changed too
|
||||
typedef union {
|
||||
uint8_t value;
|
||||
uint8_t mask;
|
||||
struct {
|
||||
uint8_t on :1,
|
||||
ccw :1,
|
||||
pwm :1, // NOTE: only used for PWM inversion setting
|
||||
reserved3 :1,
|
||||
reserved4 :1,
|
||||
encoder_error :1,
|
||||
at_speed :1, //!< Spindle is at speed.
|
||||
synchronized :1;
|
||||
uint8_t on :1,
|
||||
ccw :1,
|
||||
pwm :1, //!< NOTE: only used for PWM inversion setting
|
||||
reserved :1,
|
||||
override_disable :1,
|
||||
encoder_error :1,
|
||||
at_speed :1, //!< Spindle is at speed.
|
||||
synchronized :1;
|
||||
};
|
||||
} spindle_state_t;
|
||||
|
||||
/// Bitmap flags for spindle capabilities.
|
||||
/*! \brief Bitmap flags for spindle capabilities. */
|
||||
typedef union {
|
||||
uint8_t value; //!< All bitmap flags.
|
||||
struct {
|
||||
@@ -57,12 +58,12 @@ typedef union {
|
||||
};
|
||||
} spindle_cap_t;
|
||||
|
||||
// Used when HAL driver supports spindle synchronization
|
||||
/*! \brief Used when HAL driver supports spindle synchronization. */
|
||||
typedef struct {
|
||||
float rpm;
|
||||
float rpm_low_limit;
|
||||
float rpm_high_limit;
|
||||
float angular_position; // Number of revolutions since last reset
|
||||
float angular_position; //!< Number of revolutions since last reset
|
||||
float rpm_programmed;
|
||||
uint32_t index_count;
|
||||
uint32_t pulse_count;
|
||||
@@ -84,11 +85,11 @@ typedef enum {
|
||||
SpindleType_Null, //!< 4
|
||||
} spindle_type_t;
|
||||
|
||||
/*! \brief Pointer to function for configuring the spindle.
|
||||
\returns state in a \a spindle_state_t union variable.
|
||||
*/
|
||||
typedef bool (*spindle_config_ptr)(void);
|
||||
|
||||
typedef enum {
|
||||
SpindleHAL_Raw, //!< 0 - NOTE: read-only
|
||||
SpindleHAL_Configured, //!< 1
|
||||
SpindleHAL_Active, //!< 2
|
||||
} spindle_hal_t;
|
||||
|
||||
/*! \brief Pointer to function for setting the spindle state.
|
||||
\param state a \a spindle_state_t union variable.
|
||||
@@ -141,14 +142,18 @@ Used for Pulses Per Inch (PPI) laser mode.
|
||||
*/
|
||||
typedef void (*spindle_pulse_on_ptr)(uint_fast16_t pulse_length);
|
||||
|
||||
//! Handlers for spindle support.
|
||||
typedef struct {
|
||||
struct spindle_param; // members defined below
|
||||
|
||||
/*! \brief Handlers and data for spindle support. */
|
||||
struct spindle_ptrs {
|
||||
spindle_id_t id; //!< Spindle id, assingned on spindle registration .
|
||||
struct spindle_param *param; //!< Pointer to current spindle parameters, assigned when spindle is enabled.
|
||||
spindle_type_t type; //!< Spindle type.
|
||||
spindle_cap_t cap; //!< Spindle capabilities.
|
||||
uint_fast16_t pwm_off_value; //!< Value for switching PWM signal off.
|
||||
float rpm_min; //!< Minimum spindle RPM.
|
||||
float rpm_max; //!< Maximum spindle RPM.
|
||||
spindle_config_ptr config; //!< Optional handler for configuring the spindle.
|
||||
bool (*config)(struct spindle_ptrs *spindle); //!< Optional handler for configuring the spindle.
|
||||
spindle_set_state_ptr set_state; //!< Handler for setting spindle state.
|
||||
spindle_get_state_ptr get_state; //!< Handler for getting spindle state.
|
||||
spindle_get_pwm_ptr get_pwm; //!< Handler for calculating spindle PWM value from RPM.
|
||||
@@ -157,14 +162,50 @@ typedef struct {
|
||||
#ifdef GRBL_ESP32
|
||||
void (*esp32_off)(void); //!< Workaround handler for snowflake ESP32 Guru awaken by floating point data in ISR context.
|
||||
#endif
|
||||
// Optional entry points:
|
||||
// Optional entry points.
|
||||
spindle_pulse_on_ptr pulse_on; //!< Optional handler for Pulses Per Inch (PPI) mode. Required for the laser PPI plugin.
|
||||
spindle_get_data_ptr get_data; //!< Optional handler for getting spindle data. Required for spindle sync.
|
||||
spindle_reset_data_ptr reset_data; //!< Optional handler for resetting spindle data. Required for spindle sync.
|
||||
} spindle_ptrs_t;
|
||||
spindle_get_data_ptr get_data; //!< Optional handler for getting spindle data. Required for spindle sync, copied from hal.spindle_data.get on selection.
|
||||
spindle_reset_data_ptr reset_data; //!< Optional handler for resetting spindle data. Required for spindle sync, copied from hal.spindle_data.reset on selection.
|
||||
};
|
||||
|
||||
typedef struct spindle_ptrs spindle_ptrs_t;
|
||||
|
||||
//! \brief Data used for Constant Surface Speed (CSS) mode calculations.
|
||||
typedef struct {
|
||||
float surface_speed; //!< Surface speed in millimeters/min
|
||||
float target_rpm; //!< Target RPM at end of movement
|
||||
float delta_rpm; //!< Delta between start and target RPM
|
||||
float max_rpm; //!< Maximum spindle RPM
|
||||
float tool_offset; //!< Tool offset
|
||||
uint_fast8_t axis; //!< Linear (tool) axis
|
||||
} spindle_css_data_t;
|
||||
|
||||
/*! \brief Structure used for holding the current state of an enabled spindle. */
|
||||
typedef struct spindle_param {
|
||||
float rpm;
|
||||
float rpm_overridden;
|
||||
spindle_state_t state;
|
||||
override_t override_pct; //!< Spindle RPM override value in percent
|
||||
spindle_css_data_t css; //!< Data used for Constant Surface Speed Mode (CSS) calculations, NULL if not in CSS mode.
|
||||
spindle_ptrs_t *hal;
|
||||
} spindle_param_t;
|
||||
|
||||
typedef struct {
|
||||
spindle_get_data_ptr get; //!< Optional handler for getting spindle data. Required for spindle sync.
|
||||
spindle_reset_data_ptr reset; //!< Optional handler for resetting spindle data. Required for spindle sync.
|
||||
} spindle_data_ptrs_t;
|
||||
|
||||
/*! \brief Pointer to function for configuring the spindle.
|
||||
\returns state in a \a spindle_state_t union variable.
|
||||
*/
|
||||
typedef bool (*spindle_config_ptr)(spindle_ptrs_t *spindle);
|
||||
|
||||
/*! \brief Structure holding data passed to the callback function called by spindle_enumerate_spindles(). */
|
||||
typedef struct {
|
||||
spindle_id_t id;
|
||||
spindle_num_t num;
|
||||
const char *name;
|
||||
bool enabled;
|
||||
bool is_current;
|
||||
const spindle_ptrs_t *hal;
|
||||
} spindle_info_t;
|
||||
@@ -175,64 +216,53 @@ typedef struct {
|
||||
float end;
|
||||
} pwm_piece_t;
|
||||
|
||||
// Precalculated values that may be set/used by HAL driver to speed up RPM to PWM conversions if variable spindle is supported
|
||||
//!* \brief Precalculated values that may be set/used by HAL driver to speed up RPM to PWM conversions if variable spindle is supported. */
|
||||
typedef struct {
|
||||
uint_fast16_t period;
|
||||
uint_fast16_t off_value; // NOTE: this value holds the inverted version if software PWM inversion is enabled by the driver.
|
||||
uint_fast16_t off_value; //!< NOTE: this value holds the inverted version if software PWM inversion is enabled by the driver.
|
||||
uint_fast16_t min_value;
|
||||
uint_fast16_t max_value;
|
||||
float rpm_min; //!< Minimum spindle RPM.
|
||||
float pwm_gradient;
|
||||
bool invert_pwm; // NOTE: set (by driver) when inversion is done in code
|
||||
bool invert_pwm; //!< NOTE: set (by driver) when inversion is done in code
|
||||
bool always_on;
|
||||
int_fast16_t offset;
|
||||
uint_fast16_t n_pieces;
|
||||
pwm_piece_t piece[SPINDLE_NPWM_PIECES];
|
||||
} spindle_pwm_t;
|
||||
|
||||
/*! \brief Pointer to callback function called by spindle_enumerate_spindles().
|
||||
\param spindle prointer to a \a spindle_info_t struct.
|
||||
*/
|
||||
typedef void (*spindle_enumerate_callback_ptr)(spindle_info_t *spindle);
|
||||
|
||||
void spindle_set_override (uint_fast8_t speed_override);
|
||||
void spindle_set_override (spindle_ptrs_t *spindle, override_t speed_override);
|
||||
|
||||
// Called by g-code parser when setting spindle state and requires a buffer sync.
|
||||
// Immediately sets spindle running state with direction and spindle RPM, if enabled.
|
||||
// Called by spindle_sync() after sync and parking motion/spindle stop override during restore.
|
||||
|
||||
// Called by g-code parser when setting spindle state and requires a buffer sync.
|
||||
bool spindle_sync (spindle_id_t spindle_id, spindle_state_t state, float rpm);
|
||||
bool spindle_sync (spindle_ptrs_t *spindle, spindle_state_t state, float rpm);
|
||||
|
||||
// Sets spindle running state with direction, enable, and spindle RPM.
|
||||
bool spindle_set_state (spindle_id_t spindle_id, spindle_state_t state, float rpm);
|
||||
bool spindle_set_state (spindle_ptrs_t *spindle, spindle_state_t state, float rpm);
|
||||
|
||||
// Spindle speed calculation and limit handling
|
||||
float spindle_set_rpm (float rpm, uint8_t speed_override);
|
||||
float spindle_set_rpm (spindle_ptrs_t *spindle, float rpm, override_t speed_override);
|
||||
|
||||
// Restore spindle running state with direction, enable, spindle RPM and appropriate delay.
|
||||
bool spindle_restore (spindle_state_t state, float rpm);
|
||||
bool spindle_restore (spindle_ptrs_t *spindle, spindle_state_t state, float rpm);
|
||||
|
||||
void spindle_all_off (void);
|
||||
|
||||
//
|
||||
// The following functions are not called by the core, may be called by driver code.
|
||||
//
|
||||
|
||||
/*! \brief Precompute PWM values for faster conversion.
|
||||
\param pwm_data pointer t a \a spindle_pwm_t structure.
|
||||
\param clock_hz timer clock frequency used for PWM generation.
|
||||
\returns true if successful, false if no PWM range possible - driver should revert to simple on/off spindle control if so.
|
||||
*/
|
||||
bool spindle_precompute_pwm_values (spindle_pwm_t *pwm_data, uint32_t clock_hz);
|
||||
bool spindle_precompute_pwm_values (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_data, uint32_t clock_hz);
|
||||
|
||||
/*! \brief Spindle RPM to PWM conversion.
|
||||
\param pwm_data pointer t a \a spindle_pwm_t structure.
|
||||
\param rpm spindle RPM.
|
||||
\param pid_limit boolean, true if PID based spindle sync is used, false otherwise.
|
||||
|
||||
__NOTE:__ \a spindle_precompute_pwm_values() must be called to precompute values before this function is called.
|
||||
Typically this is done in the \a hal.driver_setup handler.
|
||||
*/
|
||||
uint_fast16_t spindle_compute_pwm_value (spindle_pwm_t *pwm_data, float rpm, bool pid_limit);
|
||||
|
||||
spindle_id_t spindle_register (const spindle_ptrs_t *spindle, const char *name);
|
||||
|
||||
void spindle_add_null (void);
|
||||
spindle_id_t spindle_add_null (void);
|
||||
|
||||
uint8_t spindle_get_count (void);
|
||||
|
||||
@@ -240,16 +270,25 @@ bool spindle_select (spindle_id_t spindle_id);
|
||||
|
||||
spindle_cap_t spindle_get_caps (void);
|
||||
|
||||
/*! \brief Update PWM spindle capabilities with run-time determined parameters.
|
||||
\param pwm_caps pointer to \a spindle_pwm_t struct, NULL if spindle if not PWM capable.
|
||||
void spindle_update_caps (spindle_ptrs_t *spindle, spindle_pwm_t *pwm_caps);
|
||||
|
||||
*/
|
||||
void spindle_update_caps (spindle_pwm_t *pwm_caps);
|
||||
|
||||
const spindle_ptrs_t *spindle_get (spindle_id_t spindle_id);
|
||||
spindle_ptrs_t *spindle_get_hal (spindle_id_t spindle_id, spindle_hal_t hal);
|
||||
|
||||
spindle_id_t spindle_get_current (void);
|
||||
const char *spindle_get_name (spindle_id_t spindle_id);
|
||||
|
||||
spindle_id_t spindle_get_default (void);
|
||||
|
||||
spindle_num_t spindle_enable (spindle_id_t spindle_id);
|
||||
|
||||
bool spindle_enumerate_spindles (spindle_enumerate_callback_ptr callback);
|
||||
|
||||
//
|
||||
|
||||
bool spindle_is_enabled (spindle_num_t spindle_num);
|
||||
|
||||
bool spindle_is_on (void);
|
||||
|
||||
spindle_ptrs_t *spindle_get (spindle_num_t spindle_num);
|
||||
|
||||
#endif
|
||||
|
||||
+83
-39
@@ -43,8 +43,13 @@ static void state_await_resumed (uint_fast16_t rt_exec);
|
||||
|
||||
static void (* volatile stateHandler)(uint_fast16_t rt_exec) = state_idle;
|
||||
|
||||
static float restore_spindle_rpm;
|
||||
static planner_cond_t restore_condition;
|
||||
typedef struct {
|
||||
coolant_state_t coolant;
|
||||
spindle_num_t spindle_num; // Active spindle
|
||||
spindle_t spindle[N_SYS_SPINDLE];
|
||||
} restore_condition_t;
|
||||
|
||||
static restore_condition_t restore_condition;
|
||||
static sys_state_t pending_state = STATE_IDLE, sys_state = STATE_IDLE;
|
||||
|
||||
typedef union {
|
||||
@@ -69,17 +74,33 @@ typedef struct {
|
||||
// Declare and initialize parking local variables
|
||||
static parking_data_t park = {0};
|
||||
|
||||
static void state_restore_conditions (planner_cond_t *condition, float rpm)
|
||||
static void state_spindle_restore (spindle_t *spindle)
|
||||
{
|
||||
if(spindle->hal)
|
||||
spindle_restore(spindle->hal, spindle->state, spindle->rpm);
|
||||
}
|
||||
|
||||
static void state_spindle_set_state (spindle_t *spindle)
|
||||
{
|
||||
if(spindle->hal)
|
||||
spindle_set_state(spindle->hal, spindle->state, spindle->rpm);
|
||||
}
|
||||
|
||||
static void state_restore_conditions (restore_condition_t *condition)
|
||||
{
|
||||
if (!settings.parking.flags.enabled || !park.flags.restart) {
|
||||
|
||||
spindle_num_t spindle_num = N_SYS_SPINDLE;
|
||||
|
||||
park.flags.restoring = On; //
|
||||
|
||||
spindle_restore(condition->spindle, rpm);
|
||||
do {
|
||||
state_spindle_restore(&condition->spindle[--spindle_num]);
|
||||
} while(spindle_num);
|
||||
|
||||
// Block if safety door re-opened during prior restore actions.
|
||||
if (gc_state.modal.coolant.value != hal.coolant.get_state().value) {
|
||||
// NOTE: Laser mode will honor this delay. An exhaust system is often controlled by this pin.
|
||||
// NOTE: Laser mode will honor this delay. An exhaust system is often controlled by this signal.
|
||||
coolant_set_state(condition->coolant);
|
||||
delay_sec(settings.safety_door.coolant_on_delay, DelayMode_SysSuspend);
|
||||
}
|
||||
@@ -92,6 +113,9 @@ static void state_restore_conditions (planner_cond_t *condition, float rpm)
|
||||
|
||||
bool initiate_hold (uint_fast16_t new_state)
|
||||
{
|
||||
spindle_ptrs_t *spindle;
|
||||
spindle_num_t spindle_num = N_SYS_SPINDLE;
|
||||
|
||||
if (settings.parking.flags.enabled) {
|
||||
memset(&park.plan_data, 0, sizeof(plan_line_data_t));
|
||||
park.plan_data.condition.system_motion = On;
|
||||
@@ -101,16 +125,35 @@ bool initiate_hold (uint_fast16_t new_state)
|
||||
|
||||
plan_block_t *block = plan_get_current_block();
|
||||
|
||||
if (block == NULL) {
|
||||
restore_condition.spindle = gc_state.modal.spindle;
|
||||
restore_condition.coolant.mask = gc_state.modal.coolant.mask | hal.coolant.get_state().mask;
|
||||
restore_spindle_rpm = gc_state.spindle.rpm;
|
||||
} else {
|
||||
restore_condition = block->condition;
|
||||
restore_spindle_rpm = block->spindle.rpm;
|
||||
}
|
||||
restore_condition.spindle_num = 0;
|
||||
|
||||
if (sys.mode == Mode_Laser && settings.flags.disable_laser_during_hold)
|
||||
do {
|
||||
if((spindle = spindle_get(--spindle_num))) {
|
||||
if(block && block->spindle.hal == spindle) {
|
||||
restore_condition.spindle_num = spindle_num;
|
||||
restore_condition.spindle[spindle_num].hal = block->spindle.hal;
|
||||
restore_condition.spindle[spindle_num].rpm = block->spindle.rpm;
|
||||
restore_condition.spindle[spindle_num].state = block->spindle.state;
|
||||
} else if(gc_state.spindle.hal == spindle) {
|
||||
restore_condition.spindle_num = spindle_num;
|
||||
restore_condition.spindle[spindle_num].hal = gc_state.spindle.hal;
|
||||
restore_condition.spindle[spindle_num].rpm = gc_state.spindle.rpm;
|
||||
restore_condition.spindle[spindle_num].state = gc_state.modal.spindle.state;
|
||||
} else {
|
||||
restore_condition.spindle[spindle_num].hal = spindle;
|
||||
restore_condition.spindle[spindle_num].rpm = spindle->param->rpm;
|
||||
restore_condition.spindle[spindle_num].state = spindle->param->state;
|
||||
}
|
||||
} else
|
||||
restore_condition.spindle[spindle_num].hal = NULL;
|
||||
} while(spindle_num);
|
||||
|
||||
if (block)
|
||||
restore_condition.coolant.mask = block->condition.coolant.mask;
|
||||
else
|
||||
restore_condition.coolant.mask = gc_state.modal.coolant.mask | hal.coolant.get_state().mask;
|
||||
|
||||
if (restore_condition.spindle[restore_condition.spindle_num].hal->cap.laser && settings.flags.disable_laser_during_hold)
|
||||
enqueue_accessory_override(CMD_OVERRIDE_SPINDLE_STOP);
|
||||
|
||||
if (sys_state & (STATE_CYCLE|STATE_JOG)) {
|
||||
@@ -174,14 +217,14 @@ void state_set (sys_state_t new_state)
|
||||
sys_state = new_state;
|
||||
sys.steppers_deenergize = false; // Cancel stepper deenergize if pending.
|
||||
st_prep_buffer(); // Initialize step segment buffer before beginning cycle.
|
||||
if (block->condition.spindle.synchronized) {
|
||||
if (block->spindle.state.synchronized) {
|
||||
|
||||
if (hal.spindle.reset_data)
|
||||
hal.spindle.reset_data();
|
||||
if (block->spindle.hal->reset_data)
|
||||
block->spindle.hal->reset_data();
|
||||
|
||||
uint32_t index = hal.spindle.get_data(SpindleData_Counters)->index_count + 2;
|
||||
uint32_t index = block->spindle.hal->get_data(SpindleData_Counters)->index_count + 2;
|
||||
|
||||
while(index != hal.spindle.get_data(SpindleData_Counters)->index_count); // check for abort in this loop?
|
||||
while(index != block->spindle.hal->get_data(SpindleData_Counters)->index_count); // check for abort in this loop?
|
||||
|
||||
}
|
||||
st_wake_up();
|
||||
@@ -252,7 +295,7 @@ void state_set (sys_state_t new_state)
|
||||
// Suspend manager. Controls spindle overrides in hold states.
|
||||
void state_suspend_manager (void)
|
||||
{
|
||||
if (stateHandler != state_await_resume || !gc_state.modal.spindle.on)
|
||||
if (stateHandler != state_await_resume || !gc_state.modal.spindle.state.on)
|
||||
return;
|
||||
|
||||
if (sys.override.spindle_stop.value) {
|
||||
@@ -260,7 +303,7 @@ void state_suspend_manager (void)
|
||||
// Handles beginning of spindle stop
|
||||
if (sys.override.spindle_stop.initiate) {
|
||||
sys.override.spindle_stop.value = 0; // Clear stop override state
|
||||
spindle_set_state(0, (spindle_state_t){0}, 0.0f); // De-energize
|
||||
spindle_set_state(restore_condition.spindle[restore_condition.spindle_num].hal, (spindle_state_t){0}, 0.0f); // De-energize
|
||||
sys.override.spindle_stop.enabled = On; // Set stop override state to enabled, if de-energized.
|
||||
if(grbl.on_override_changed)
|
||||
grbl.on_override_changed(OverrideChanged_SpindleState);
|
||||
@@ -269,18 +312,18 @@ void state_suspend_manager (void)
|
||||
// Handles restoring of spindle state
|
||||
if (sys.override.spindle_stop.restore) {
|
||||
grbl.report.feedback_message(Message_SpindleRestore);
|
||||
if (sys.mode == Mode_Laser) // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts.
|
||||
if (restore_condition.spindle[restore_condition.spindle_num].hal->cap.laser) // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts.
|
||||
sys.step_control.update_spindle_rpm = On;
|
||||
else
|
||||
spindle_set_state(0, restore_condition.spindle, restore_spindle_rpm);
|
||||
state_spindle_set_state(&restore_condition.spindle[restore_condition.spindle_num]);
|
||||
sys.override.spindle_stop.value = 0; // Clear stop override state
|
||||
if(grbl.on_override_changed)
|
||||
grbl.on_override_changed(OverrideChanged_SpindleState);
|
||||
}
|
||||
|
||||
} else if (sys.step_control.update_spindle_rpm && hal.spindle.get_state().on) {
|
||||
} else if (sys.step_control.update_spindle_rpm && restore_condition.spindle[0].hal->get_state().on) {
|
||||
// Handles spindle state during hold. NOTE: Spindle speed overrides may be altered during hold state.
|
||||
spindle_set_state(0, restore_condition.spindle, restore_spindle_rpm);
|
||||
state_spindle_set_state(&restore_condition.spindle[restore_condition.spindle_num]);;
|
||||
sys.step_control.update_spindle_rpm = Off;
|
||||
}
|
||||
}
|
||||
@@ -394,7 +437,7 @@ static void state_await_hold (uint_fast16_t rt_exec)
|
||||
switch (sys_state) {
|
||||
|
||||
case STATE_TOOL_CHANGE:
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f); // De-energize
|
||||
spindle_all_off(); // De-energize
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
break;
|
||||
|
||||
@@ -410,7 +453,7 @@ static void state_await_hold (uint_fast16_t rt_exec)
|
||||
|
||||
// Parking requires parking axis homed, the current location not exceeding the???
|
||||
// parking target location, and laser mode disabled.
|
||||
if (settings.parking.flags.enabled && !sys.override.control.parking_disable && sys.mode != Mode_Laser) {
|
||||
if (settings.parking.flags.enabled && !sys.override.control.parking_disable && settings.mode != Mode_Laser) {
|
||||
|
||||
// Get current position and store as restore location.
|
||||
if (!park.flags.active) {
|
||||
@@ -441,8 +484,9 @@ static void state_await_hold (uint_fast16_t rt_exec)
|
||||
park.target[settings.parking.axis] = park.retract_waypoint;
|
||||
park.plan_data.feed_rate = settings.parking.pullout_rate;
|
||||
park.plan_data.condition.coolant = restore_condition.coolant; // Retain coolant state
|
||||
park.plan_data.condition.spindle = restore_condition.spindle; // Retain spindle state
|
||||
park.plan_data.spindle.rpm = restore_spindle_rpm;
|
||||
park.plan_data.spindle.state = restore_condition.spindle[restore_condition.spindle_num].state; // Retain spindle state
|
||||
park.plan_data.spindle.hal = restore_condition.spindle[restore_condition.spindle_num].hal;
|
||||
park.plan_data.spindle.rpm = restore_condition.spindle[restore_condition.spindle_num].rpm;
|
||||
await_motion = mc_parking_motion(park.target, &park.plan_data);
|
||||
}
|
||||
|
||||
@@ -455,13 +499,13 @@ static void state_await_hold (uint_fast16_t rt_exec)
|
||||
} else {
|
||||
// Parking motion not possible. Just disable the spindle and coolant.
|
||||
// NOTE: Laser mode does not start a parking motion to ensure the laser stops immediately.
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f); // De-energize
|
||||
spindle_all_off(); // De-energize
|
||||
if (!settings.safety_door.flags.keep_coolant_on)
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
sys.parking_state = hal.control.get_state().safety_door_ajar ? Parking_DoorAjar : Parking_DoorClosed;
|
||||
}
|
||||
} else {
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f); // De-energize
|
||||
spindle_all_off(); // De-energize
|
||||
if (!settings.safety_door.flags.keep_coolant_on)
|
||||
hal.coolant.set_state((coolant_state_t){0}); // De-energize
|
||||
sys.parking_state = hal.control.get_state().safety_door_ajar ? Parking_DoorAjar : Parking_DoorClosed;
|
||||
@@ -540,14 +584,14 @@ static void state_await_resume (uint_fast16_t rt_exec)
|
||||
|
||||
default:
|
||||
if (!settings.flags.restore_after_feed_hold) {
|
||||
if (!hal.spindle.get_state().on)
|
||||
if (!restore_condition.spindle[restore_condition.spindle_num].hal->get_state().on)
|
||||
gc_spindle_off();
|
||||
sys.override.spindle_stop.value = 0; // Clear spindle stop override states
|
||||
} else {
|
||||
|
||||
if (restore_condition.spindle.on != hal.spindle.get_state().on) {
|
||||
if (restore_condition.spindle[restore_condition.spindle_num].state.on != restore_condition.spindle[restore_condition.spindle_num].hal->get_state().on) {
|
||||
grbl.report.feedback_message(Message_SpindleRestore);
|
||||
spindle_restore(restore_condition.spindle, restore_spindle_rpm);
|
||||
state_spindle_restore(&restore_condition.spindle[restore_condition.spindle_num]);
|
||||
}
|
||||
|
||||
if (restore_condition.coolant.value != hal.coolant.get_state().value) {
|
||||
@@ -631,9 +675,9 @@ static void state_await_waypoint_retract (uint_fast16_t rt_exec)
|
||||
}
|
||||
|
||||
// NOTE: Clear accessory state after retract and after an aborted restore motion.
|
||||
park.plan_data.condition.spindle.value = 0;
|
||||
park.plan_data.spindle.state.value = 0;
|
||||
park.plan_data.spindle.rpm = 0.0f;
|
||||
hal.spindle.set_state(park.plan_data.condition.spindle, 0.0f); // De-energize
|
||||
park.plan_data.spindle.hal->set_state(park.plan_data.spindle.state, 0.0f); // De-energize
|
||||
|
||||
if (!settings.safety_door.flags.keep_coolant_on) {
|
||||
park.plan_data.condition.coolant.value = 0;
|
||||
@@ -682,7 +726,7 @@ static void state_restore (uint_fast16_t rt_exec)
|
||||
stateHandler = state_await_resumed;
|
||||
|
||||
// Restart spindle and coolant, delay to power-up.
|
||||
state_restore_conditions(&restore_condition, restore_spindle_rpm);
|
||||
state_restore_conditions(&restore_condition);
|
||||
|
||||
if(park.flags.restart) {
|
||||
// Restart flag was set by a safety door event during
|
||||
@@ -702,8 +746,8 @@ static void state_restore (uint_fast16_t rt_exec)
|
||||
// original position through valid machine space or by not moving at all.
|
||||
park.plan_data.feed_rate = settings.parking.pullout_rate;
|
||||
park.plan_data.condition.coolant = restore_condition.coolant;
|
||||
park.plan_data.condition.spindle = restore_condition.spindle;
|
||||
park.plan_data.spindle.rpm = restore_spindle_rpm;
|
||||
park.plan_data.spindle.state = restore_condition.spindle[restore_condition.spindle_num].state;
|
||||
park.plan_data.spindle.rpm = restore_condition.spindle[restore_condition.spindle_num].rpm;
|
||||
await_motion = mc_parking_motion(park.restore_target, &park.plan_data);
|
||||
}
|
||||
|
||||
|
||||
@@ -395,16 +395,16 @@ ISR_CODE void ISR_FUNC(stepper_driver_interrupt_handler)(void)
|
||||
#endif
|
||||
|
||||
if(st.exec_segment->update_pwm)
|
||||
hal.spindle.update_pwm(st.exec_segment->spindle_pwm);
|
||||
st.exec_segment->update_pwm(st.exec_segment->spindle_pwm);
|
||||
else if(st.exec_segment->update_rpm)
|
||||
hal.spindle.update_rpm(st.exec_segment->spindle_rpm);
|
||||
st.exec_segment->update_rpm(st.exec_segment->spindle_rpm);
|
||||
} else {
|
||||
// Segment buffer empty. Shutdown.
|
||||
st_go_idle();
|
||||
|
||||
// Ensure pwm is set properly upon completion of rate-controlled motion.
|
||||
if (st.exec_block->dynamic_rpm && sys.mode == Mode_Laser)
|
||||
hal.spindle.update_pwm(hal.spindle.pwm_off_value);
|
||||
if (st.exec_block->dynamic_rpm && st.exec_block->spindle->cap.laser)
|
||||
st.exec_block->spindle->update_pwm(st.exec_block->spindle->pwm_off_value);
|
||||
|
||||
st.exec_block = NULL;
|
||||
system_set_exec_state_flag(EXEC_CYCLE_COMPLETE); // Flag main program for cycle complete
|
||||
@@ -741,11 +741,12 @@ void st_prep_buffer (void)
|
||||
|
||||
// Setup laser mode variables. RPM rate adjusted motions will always complete a motion with the
|
||||
// spindle off.
|
||||
if ((st_prep_block->dynamic_rpm = pl_block->condition.is_rpm_rate_adjusted))
|
||||
if ((st_prep_block->dynamic_rpm = pl_block->condition.is_rpm_rate_adjusted)) {
|
||||
// Pre-compute inverse programmed rate to speed up RPM updating per step segment.
|
||||
st_prep_block->spindle = pl_block->spindle.hal;
|
||||
prep.inv_feedrate = pl_block->condition.is_laser_ppi_mode ? 1.0f : 1.0f / pl_block->programmed_rate;
|
||||
else
|
||||
st_prep_block->dynamic_rpm = pl_block->condition.is_rpm_pos_adjusted;
|
||||
} else
|
||||
st_prep_block->dynamic_rpm = !!pl_block->spindle.css;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------
|
||||
@@ -842,7 +843,7 @@ void st_prep_buffer (void)
|
||||
}
|
||||
|
||||
if(state_get() != STATE_HOMING)
|
||||
sys.step_control.update_spindle_rpm |= (sys.mode == Mode_Laser); // Force update whenever updating block in laser mode.
|
||||
sys.step_control.update_spindle_rpm |= pl_block->spindle.hal->cap.laser; // Force update whenever updating block in laser mode.
|
||||
|
||||
probe_asserted = false;
|
||||
}
|
||||
@@ -856,7 +857,8 @@ void st_prep_buffer (void)
|
||||
|
||||
// Set new segment to point to the current segment data block.
|
||||
prep_segment->exec_block = st_prep_block;
|
||||
prep_segment->update_rpm = prep_segment->update_pwm = false;
|
||||
prep_segment->update_rpm = NULL;
|
||||
prep_segment->update_pwm = NULL;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
Compute the average velocity of this new segment by determining the total distance
|
||||
@@ -969,27 +971,31 @@ void st_prep_buffer (void)
|
||||
|
||||
if (sys.step_control.update_spindle_rpm || st_prep_block->dynamic_rpm) {
|
||||
float rpm;
|
||||
if (pl_block->condition.spindle.on) {
|
||||
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
|
||||
// If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_RPM_OVERRIDE)
|
||||
// but this would be instantaneous only and during a motion. May not matter at all.
|
||||
rpm = spindle_set_rpm(pl_block->condition.is_rpm_rate_adjusted && !pl_block->condition.is_laser_ppi_mode
|
||||
? pl_block->spindle.rpm * prep.current_speed * prep.inv_feedrate
|
||||
: pl_block->spindle.rpm, sys.override.spindle_rpm);
|
||||
|
||||
if(pl_block->condition.is_rpm_pos_adjusted) {
|
||||
if (pl_block->spindle.state.on) {
|
||||
if(pl_block->spindle.css) {
|
||||
float npos = (float)(pl_block->step_event_count - prep.steps_remaining) / (float)pl_block->step_event_count;
|
||||
rpm += (spindle_set_rpm(pl_block->spindle.css.target_rpm, sys.override.spindle_rpm) - prep.current_spindle_rpm) * npos;
|
||||
rpm = spindle_set_rpm(pl_block->spindle.hal,
|
||||
pl_block->spindle.rpm + pl_block->spindle.css->delta_rpm * npos,
|
||||
pl_block->spindle.hal->param->override_pct);
|
||||
} else {
|
||||
// NOTE: Feed and rapid overrides are independent of PWM value and do not alter laser power/rate.
|
||||
// If current_speed is zero, then may need to be rpm_min*(100/MAX_SPINDLE_RPM_OVERRIDE)
|
||||
// but this would be instantaneous only and during a motion. May not matter at all.
|
||||
rpm = spindle_set_rpm(pl_block->spindle.hal,
|
||||
pl_block->condition.is_rpm_rate_adjusted && !pl_block->condition.is_laser_ppi_mode
|
||||
? pl_block->spindle.rpm * prep.current_speed * prep.inv_feedrate
|
||||
: pl_block->spindle.rpm, pl_block->spindle.hal->param->override_pct);
|
||||
}
|
||||
} else
|
||||
sys.spindle_rpm = rpm = 0.0f;
|
||||
pl_block->spindle.hal->param->rpm = rpm = 0.0f;
|
||||
|
||||
if(rpm != prep.current_spindle_rpm) {
|
||||
if((prep_segment->update_pwm = hal.spindle.get_pwm != NULL)) {
|
||||
if(pl_block->spindle.hal->get_pwm != NULL) {
|
||||
prep.current_spindle_rpm = rpm;
|
||||
prep_segment->spindle_pwm = hal.spindle.get_pwm(rpm);
|
||||
prep_segment->update_pwm = pl_block->spindle.hal->update_pwm;
|
||||
prep_segment->spindle_pwm = pl_block->spindle.hal->get_pwm(rpm);
|
||||
} else {
|
||||
prep_segment->update_rpm = true;
|
||||
prep_segment->update_rpm = pl_block->spindle.hal->update_rpm;
|
||||
prep.current_spindle_rpm = prep_segment->spindle_rpm = rpm;
|
||||
}
|
||||
sys.step_control.update_spindle_rpm = Off;
|
||||
@@ -1036,7 +1042,7 @@ void st_prep_buffer (void)
|
||||
uint32_t cycles = (uint32_t)ceilf(cycles_per_min * inv_rate); // (cycles/step)
|
||||
|
||||
// Record end position of segment relative to block if spindle synchronized motion
|
||||
if((prep_segment->spindle_sync = pl_block->condition.spindle.synchronized)) {
|
||||
if((prep_segment->spindle_sync = pl_block->spindle.state.synchronized)) {
|
||||
prep.target_position += dt * prep.target_feed;
|
||||
prep_segment->cruising = prep.ramp_type == Ramp_Cruise;
|
||||
prep_segment->target_position = prep.target_position; //st_prep_block->millimeters - pl_block->millimeters;
|
||||
|
||||
@@ -50,24 +50,25 @@ typedef struct st_block {
|
||||
char *message; //!< Message to be displayed when block is executed
|
||||
output_command_t *output_commands; //!< Output commands (linked list) to be performed when block is executed
|
||||
bool dynamic_rpm; //!< Tracks motions that require dynamic RPM adjustment
|
||||
spindle_ptrs_t *spindle; //!< Pointer to current spindle for motions that require dynamic RPM adjustment
|
||||
bool backlash_motion;
|
||||
} st_block_t;
|
||||
|
||||
typedef struct st_segment {
|
||||
uint_fast8_t id; //!< Id may be used by driver to track changes
|
||||
struct st_segment *next; //!< Pointer to next element in cirular list of segments
|
||||
st_block_t *exec_block; //!< Pointer to the block data for the segment
|
||||
uint32_t cycles_per_tick; //!< Step distance traveled per ISR tick, aka step rate.
|
||||
uint_fast8_t id; //!< Id may be used by driver to track changes
|
||||
struct st_segment *next; //!< Pointer to next element in cirular list of segments
|
||||
st_block_t *exec_block; //!< Pointer to the block data for the segment
|
||||
uint32_t cycles_per_tick; //!< Step distance traveled per ISR tick, aka step rate.
|
||||
float current_rate;
|
||||
float target_position; //!< Target position of segment relative to block start, used by spindle sync code
|
||||
uint_fast16_t n_step; //!< Number of step events to be executed for this segment
|
||||
uint_fast16_t spindle_pwm; //!< Spindle PWM to be set at the start of segment execution
|
||||
float spindle_rpm; //!< Spindle RPM to be set at the start of the segment execution
|
||||
bool update_pwm; //!< True if set spindle speed at the start of the segment execution
|
||||
bool update_rpm; //!< True if set spindle speed at the start of the segment execution
|
||||
bool spindle_sync; //!< True if block is spindle synchronized
|
||||
bool cruising; //!< True when in cruising part of profile, only set for spindle synced moves
|
||||
uint_fast8_t amass_level; //!< Indicates AMASS level for the ISR to execute this segment
|
||||
float target_position; //!< Target position of segment relative to block start, used by spindle sync code
|
||||
uint_fast16_t n_step; //!< Number of step events to be executed for this segment
|
||||
uint_fast16_t spindle_pwm; //!< Spindle PWM to be set at the start of segment execution
|
||||
float spindle_rpm; //!< Spindle RPM to be set at the start of the segment execution
|
||||
bool spindle_sync; //!< True if block is spindle synchronized
|
||||
bool cruising; //!< True when in cruising part of profile, only set for spindle synced moves
|
||||
uint_fast8_t amass_level; //!< Indicates AMASS level for the ISR to execute this segment
|
||||
spindle_update_pwm_ptr update_pwm; //!< Valid pointer to spindle.update_pwm() if set spindle speed at the start of the segment execution
|
||||
spindle_update_rpm_ptr update_rpm; //!< Valid pointer to spindle.update_rmp() if set spindle speed at the start of the segment execution
|
||||
} segment_t;
|
||||
|
||||
//! Stepper ISR data struct. Contains the running data for the main stepper ISR.
|
||||
|
||||
@@ -56,6 +56,7 @@ static status_code_t toggle_optional_stop (sys_state_t state, char *args);
|
||||
static status_code_t check_mode (sys_state_t state, char *args);
|
||||
static status_code_t disable_lock (sys_state_t state, char *args);
|
||||
static status_code_t output_help (sys_state_t state, char *args);
|
||||
static status_code_t output_spindles (sys_state_t state, char *args);
|
||||
static status_code_t home (sys_state_t state, char *args);
|
||||
static status_code_t home_x (sys_state_t state, char *args);
|
||||
static status_code_t home_y (sys_state_t state, char *args);
|
||||
@@ -120,8 +121,8 @@ ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
|
||||
// NOTE: at least for lasers there should be an external interlock blocking laser power.
|
||||
if(state_get() != STATE_IDLE && state_get() != STATE_JOG)
|
||||
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
|
||||
if(sys.mode == Mode_Laser) // Turn off spindle immediately (laser) when in laser mode
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
if(settings.mode == Mode_Laser) // Turn off spindle immediately (laser) when in laser mode
|
||||
spindle_all_off();
|
||||
} else
|
||||
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
|
||||
}
|
||||
@@ -166,10 +167,12 @@ void system_execute_startup (void)
|
||||
// Reset spindle encoder data
|
||||
status_code_t spindle_reset_data (sys_state_t state, char *args)
|
||||
{
|
||||
if(hal.spindle.reset_data)
|
||||
hal.spindle.reset_data();
|
||||
spindle_ptrs_t *spindle = gc_spindle_get();
|
||||
|
||||
return hal.spindle.reset_data ? Status_OK : Status_InvalidStatement;
|
||||
if(spindle->reset_data)
|
||||
spindle->reset_data();
|
||||
|
||||
return spindle->reset_data ? Status_OK : Status_InvalidStatement;
|
||||
}
|
||||
|
||||
status_code_t read_int (char *s, int32_t *value)
|
||||
@@ -233,6 +236,7 @@ PROGMEM static const sys_command_t sys_commands[] = {
|
||||
{ "HV", false, home_v },
|
||||
#endif
|
||||
{ "HELP", false, output_help },
|
||||
{ "SPINDLES", false, output_spindles },
|
||||
{ "SLP", true, enter_sleep },
|
||||
{ "TLR", true, set_tool_reference },
|
||||
{ "TPW", true, tool_probe_workpiece },
|
||||
@@ -284,6 +288,7 @@ void system_command_help (void)
|
||||
hal.stream.write("$SLP - enter sleep mode" ASCII_EOL);
|
||||
hal.stream.write("$HELP - output help topics" ASCII_EOL);
|
||||
hal.stream.write("$HELP <topic> - output help for <topic>" ASCII_EOL);
|
||||
hal.stream.write("$SPINDLES - output spindle list" ASCII_EOL);
|
||||
hal.stream.write("$RST=* - restore/reset all settings" ASCII_EOL);
|
||||
hal.stream.write("$RST=$ - restore default settings" ASCII_EOL);
|
||||
if(settings_get_details()->next)
|
||||
@@ -293,10 +298,13 @@ void system_command_help (void)
|
||||
#else
|
||||
hal.stream.write("$RST=# - reset offsets" ASCII_EOL);
|
||||
#endif
|
||||
if(hal.spindle.reset_data)
|
||||
|
||||
spindle_ptrs_t *spindle = gc_spindle_get();
|
||||
if(spindle->reset_data)
|
||||
hal.stream.write("$SR - reset spindle encoder data" ASCII_EOL);
|
||||
if(hal.spindle.get_data)
|
||||
if(spindle->get_data)
|
||||
hal.stream.write("$SD - output spindle encoder data" ASCII_EOL);
|
||||
|
||||
hal.stream.write("$TLR - set tool offset reference" ASCII_EOL);
|
||||
hal.stream.write("$TPW - probe tool plate" ASCII_EOL);
|
||||
hal.stream.write("$EA - enumerate alarms" ASCII_EOL);
|
||||
@@ -626,6 +634,11 @@ static status_code_t output_help (sys_state_t state, char *args)
|
||||
return report_help(args);
|
||||
}
|
||||
|
||||
static status_code_t output_spindles (sys_state_t state, char *args)
|
||||
{
|
||||
return report_spindles();
|
||||
}
|
||||
|
||||
static status_code_t go_home (sys_state_t state, axes_signals_t axes)
|
||||
{
|
||||
if(axes.mask && !settings.homing.flags.single_axis_commands)
|
||||
@@ -661,7 +674,7 @@ static status_code_t go_home (sys_state_t state, axes_signals_t axes)
|
||||
if (retval == Status_OK && !sys.abort) {
|
||||
state_set(STATE_IDLE); // Set to IDLE when complete.
|
||||
st_go_idle(); // Set steppers to the settings idle state before returning.
|
||||
report_feedback_message(Message_None);
|
||||
grbl.report.feedback_message(Message_None);
|
||||
// Execute startup scripts after successful homing.
|
||||
if (sys.homing.mask && (sys.homing.mask & sys.homed.mask) == sys.homing.mask)
|
||||
system_execute_startup();
|
||||
|
||||
@@ -190,9 +190,9 @@ typedef union {
|
||||
} report_tracking_flags_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t feed_rate; //!< Feed rate override value in percent
|
||||
uint8_t rapid_rate; //!< Rapids override value in percent
|
||||
uint8_t spindle_rpm; //!< Spindle speed override value in percent
|
||||
override_t feed_rate; //!< Feed rate override value in percent
|
||||
override_t rapid_rate; //!< Rapids override value in percent
|
||||
// Spindle override has been moved to per spindle in spindle_param_t
|
||||
spindle_stop_t spindle_stop; //!< Tracks spindle stop override states
|
||||
gc_override_flags_t control; //!< Tracks override control states.
|
||||
} overrides_t;
|
||||
@@ -245,7 +245,6 @@ typedef struct system {
|
||||
volatile probing_state_t probing_state; //!< Probing state value. Used to coordinate the probing cycle with stepper ISR.
|
||||
volatile rt_exec_t rt_exec_state; //!< Realtime executor bitflag variable for state management. See EXEC bitmasks.
|
||||
volatile uint_fast16_t rt_exec_alarm; //!< Realtime executor bitflag variable for setting various alarms.
|
||||
float spindle_rpm; //!< Current spindle RPM
|
||||
int32_t var5399; //!< Last result from M66 - wait on input
|
||||
#ifdef PID_LOG
|
||||
pid_data_t pid_log;
|
||||
@@ -261,7 +260,6 @@ typedef struct system {
|
||||
bool cold_start; //!< Set to true on boot, is false on subsequent soft resets.
|
||||
bool driver_started; //!< Set to true when driver initialization is completed.
|
||||
bool mpg_mode; //!< To be moved to system_flags_t
|
||||
machine_mode_t mode; //!< Current machine mode, copied from settings.mode on startup.
|
||||
signal_event_t last_event; //!< Last signal events (control and limits signal).
|
||||
int32_t position[N_AXIS]; //!< Real-time machine (aka home) position vector in steps.
|
||||
//@}
|
||||
|
||||
+6
-5
@@ -128,7 +128,7 @@ static bool restore (void)
|
||||
sync_position();
|
||||
|
||||
coolant_sync(gc_state.modal.coolant);
|
||||
spindle_restore(gc_state.modal.spindle, gc_state.spindle.rpm);
|
||||
spindle_restore(spindle_get(0), gc_state.modal.spindle.state, gc_state.spindle.rpm);
|
||||
|
||||
if(!settings.flags.no_restore_position_after_M6) {
|
||||
previous.values[plane.axis_linear] += gc_get_offset(plane.axis_linear);
|
||||
@@ -162,7 +162,7 @@ static void execute_restore (sys_state_t state)
|
||||
|
||||
change_completed();
|
||||
|
||||
report_feedback_message(Message_None);
|
||||
grbl.report.feedback_message(Message_None);
|
||||
|
||||
if(ok)
|
||||
system_set_exec_state_flag(EXEC_CYCLE_START);
|
||||
@@ -196,6 +196,7 @@ static void execute_probe (sys_state_t state)
|
||||
|
||||
plan_data.feed_rate = settings.tool_change.seek_rate;
|
||||
plan_data.condition.value = 0;
|
||||
plan_data.spindle.state.value = 0;
|
||||
target.values[plane.axis_linear] -= settings.tool_change.probing_distance;
|
||||
|
||||
if((ok = ok && mc_probe_cycle(target.values, &plan_data, flags) == GCProbe_Found))
|
||||
@@ -217,7 +218,7 @@ static void execute_probe (sys_state_t state)
|
||||
sys.tlo_reference[plane.axis_linear] = sys.probe_position[plane.axis_linear];
|
||||
sys.tlo_reference_set.mask |= bit(plane.axis_linear);
|
||||
sys.report.tlo_reference = On;
|
||||
report_feedback_message(Message_ReferenceTLOEstablished);
|
||||
grbl.report.feedback_message(Message_ReferenceTLOEstablished);
|
||||
} else
|
||||
gc_set_tool_offset(ToolLengthOffset_EnableDynamic, plane.axis_linear,
|
||||
sys.probe_position[plane.axis_linear] - sys.tlo_reference[plane.axis_linear]);
|
||||
@@ -332,7 +333,7 @@ static status_code_t tool_change (parser_state_t *parser_state)
|
||||
block_cycle_start = settings.tool_change.mode != ToolChange_SemiAutomatic;
|
||||
|
||||
// Stop spindle and coolant.
|
||||
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
|
||||
spindle_all_off();
|
||||
hal.coolant.set_state((coolant_state_t){0});
|
||||
|
||||
execute_posted = false;
|
||||
@@ -434,7 +435,7 @@ void tc_clear_tlo_reference (axes_signals_t homing_cycle)
|
||||
#else
|
||||
gc_get_plane_data(&plane, gc_state.modal.plane_select);
|
||||
#endif
|
||||
if(homing_cycle.mask & (sys.mode == Mode_Lathe ? (X_AXIS_BIT|Z_AXIS_BIT) : bit(plane.axis_linear))) {
|
||||
if(homing_cycle.mask & (settings.mode == Mode_Lathe ? (X_AXIS_BIT|Z_AXIS_BIT) : bit(plane.axis_linear))) {
|
||||
sys.report.tlo_reference = sys.tlo_reference_set.mask != 0;
|
||||
sys.tlo_reference_set.mask = 0; // Invalidate tool length offset reference
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user