Fix for M62 - M68 regression. Ref. issue #600.

Fixed incorrect handling of G65 call parameters, axis words had offsets added. Ref. issue #594.
Refactored handling of multiple spindles. There are still some limitations but should work better now. Disabled override delays for now, needs investigation. Ref. issue #598.
NOTE: Please report any erratic behaviour after installing this version since it is a rather major change.
This commit is contained in:
Terje Io
2024-10-06 20:24:34 +07:00
parent 323dd84b79
commit 5825b36ef6
15 changed files with 366 additions and 215 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa
---
Latest build date is 20240928, see the [changelog](changelog.md) for details.
Latest build date is 20241006, see the [changelog](changelog.md) for details.
__NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured.
The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds.
+26
View File
@@ -1,7 +1,33 @@
## grblHAL changelog
<a name="2024106">Build 2024106
Core:
* Fix for `M62` - `M68` regression. Ref. [issue #600](https://github.com/grblHAL/core/issues/600).
* Fixed incorrect handling of `G65` call parameters, axis words had offsets added. Ref. [issue #594](https://github.com/grblHAL/core/issues/594).
* Refactored handling of multiple spindles. There are still some limitations but should work better now. Disabled override delays for now, needs investigation. Ref. [issue #598](https://github.com/grblHAL/core/issues/598).
__NOTE:__ Please report any erratic behaviour after installing this version since it is a rather major change.
Drivers:
* ESP32: fix for compilation error. Ref. [issue #122](https://github.com/grblHAL/ESP32/issues/122).
Fixes for handling multiple devices on a single SPI port. Fixed xPro v5 map for Modbus comms. Ref. [issue #121](https://github.com/grblHAL/ESP32/issues/121).
* STM32F4xx: fix for compilation error for some boards when configured for Trinamic drivers.
Plugins:
* BLTouch: implemented `$BLTEST` command, verified.
---
<a name="20240928">Build 20240928
Core:
* Added `(PRINT, <msg>)` support and parameter formatting for `DEBUG` and `PRINT` commands. Available when expression support is enabled.
* Added named parameters for getting absolute \(G53\) position: `_abs_x`, `abs_y`, ... Available when expression support is enabled.
+264 -151
View File
File diff suppressed because it is too large Load Diff
+17 -13
View File
@@ -498,9 +498,17 @@ typedef struct {
} gc_value_ptr_t;
typedef struct {
float rpm; //!< Spindle speed
spindle_state_t state; //!< {M3,M4,M5}
spindle_rpm_mode_t rpm_mode; //!< {G96,G97}
} spindle_mode_t;
spindle_css_data_t *css; //!< Data used for Constant Surface Speed Mode calculations
spindle_ptrs_t *hal; //!< Spindle function pointers etc. Must be last!
} spindle_t;
typedef struct {
spindle_state_t state; //!< {M3,M4,M5}
spindle_rpm_mode_t rpm_mode; //!< {G96,G97}
} spindle_modal_t;
// NOTE: When this struct is zeroed, the above defines set the defaults for the system.
typedef struct {
@@ -519,7 +527,11 @@ typedef struct {
#endif
program_flow_t program_flow; //!< {M0,M1,M2,M30,M60}
coolant_state_t coolant; //!< {M7,M8,M9}
spindle_mode_t spindle; //!< {M3,M4,M5 and G96,G97}
#if N_SYS_SPINDLE > 1
spindle_t spindle[N_SYS_SPINDLE];
#else
spindle_t spindle; //!< {M3,M4,M5 and G96,G97}
#endif
gc_override_flags_t override_ctrl; //!< {M48,M49,M50,M51,M53,M56}
cc_retract_mode_t retract_mode; //!< {G98,G99}
bool scaling_active; //!< {G50,G51}
@@ -528,7 +540,6 @@ typedef struct {
#if NGC_PARAMETERS_ENABLE
bool auto_restore;
float feed_rate; //!< {F} NOTE: only set when saving modal state
float rpm; //!< {S} NOTE: only set when saving modal state
#endif
} gc_modal_t;
@@ -575,20 +586,13 @@ typedef struct {
tool_id_t tool_id; //!< Tool number
} tool_data_t;
typedef struct {
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;
gc_canned_t canned;
spindle_t spindle; //!< RPM
spindle_t *spindle; //!< Last referenced spindle
float feed_rate; //!< Millimeters/min
float distance_per_rev; //!< Millimeters/rev
float position[N_AXIS]; //!< Where the interpreter considers the tool to be at this point in the code
@@ -636,11 +640,11 @@ typedef struct {
user_mcode_t user_mcode; //!< Set > #UserMCode_Ignore if a user M-code is found.
bool user_mcode_sync; //!< Set to \a true by M-code validation handler if M-code is to be executed after synchronization.
gc_modal_t modal; //!< The current modal state is copied here before parsing starts.
spindle_modal_t spindle_modal;
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; //
spindle_ptrs_t *spindle; //!< Spindle to control, NULL for all
#if NGC_PARAMETERS_ENABLE
modal_state_action_t state_action; //!< M70-M73 modal state action
#endif
@@ -676,7 +680,7 @@ float *gc_get_scaling (void);
// Get current axis offset.
float gc_get_offset (uint_fast8_t idx, bool real_time);
spindle_ptrs_t *gc_spindle_get (void);
spindle_t *gc_spindle_get (spindle_num_t spindle);
void gc_spindle_off (void);
void gc_coolant (coolant_state_t state);
+1 -1
View File
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20240928
#define GRBL_BUILD 20241006
#define GRBL_URL "https://github.com/grblHAL"
+1 -1
View File
@@ -627,7 +627,7 @@ void mc_canned_drill (motion_mode_t motion, float *target, plan_line_data_t *pl_
return;
if(canned->spindle_off)
spindle_sync(pl_data->spindle.hal, gc_state.modal.spindle.state, pl_data->spindle.rpm);
spindle_sync(pl_data->spindle.hal, pl_data->spindle.state, pl_data->spindle.rpm);
}
pl_data->condition.rapid_motion = On; // Set rapid motion condition flag.
+5 -5
View File
@@ -488,11 +488,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_spindle_get(0)->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_spindle_get(0)->rpm_mode == SpindleSpeedMode_CSS ? 1.0f : 0.0f;
break;
case NGCParam_ijk_absolute_mode:
@@ -508,11 +508,11 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
break;
case NGCParam_spindle_on:
value = gc_state.modal.spindle.state.on ? 1.0f : 0.0f;
value = gc_spindle_get(0)->state.on ? 1.0f : 0.0f;
break;
case NGCParam_spindle_cw:
value = gc_state.modal.spindle.state.ccw ? 1.0f : 0.0f;
value = gc_spindle_get(0)->state.ccw ? 1.0f : 0.0f;
break;
case NGCParam_mist:
@@ -544,7 +544,7 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id)
break;
case NGCParam_rpm:
value = gc_state.spindle.rpm;
value = gc_spindle_get(0)->rpm;
break;
case NGCParam_x:
+1 -1
View File
@@ -691,7 +691,7 @@ void plan_data_init (plan_line_data_t *plan_data)
{
memset(plan_data, 0, sizeof(plan_line_data_t));
plan_data->offset_id = gc_state.offset_id;
plan_data->spindle.hal = gc_state.spindle.hal ? gc_state.spindle.hal : spindle_get(0);
plan_data->spindle.hal = gc_spindle_get(-1)->hal;
plan_data->condition.target_validated = plan_data->condition.target_valid = sys.soft_limits.mask == 0;
#ifdef KINEMATICS_API
plan_data->rate_multiplier = 1.0f;
+2 -3
View File
@@ -566,7 +566,6 @@ 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;
// Tell driver/plugins about reset.
hal.driver_reset();
@@ -684,7 +683,7 @@ bool protocol_exec_rt_system (void)
if(!sys.override_delay.spindle && (rt_exec = get_spindle_override())) {
bool spindle_stop = false;
spindle_ptrs_t *spindle = gc_spindle_get();
spindle_ptrs_t *spindle = gc_spindle_get(-1)->hal;
override_t last_s_override = spindle->param->override_pct;
do {
@@ -727,7 +726,7 @@ bool protocol_exec_rt_system (void)
spindle_set_override(spindle, last_s_override);
if (spindle_stop && state_get() == STATE_HOLD && gc_state.modal.spindle.state.on) {
if (spindle_stop && state_get() == STATE_HOLD && gc_spindle_get(-1)->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)
+13 -12
View File
@@ -724,8 +724,8 @@ void report_gcode_modes (void)
hal.stream.write(" G");
hal.stream.write(uitoa((uint32_t)(93 + (gc_state.modal.feed_mode == FeedMode_UnitsPerRev ? 2 : gc_state.modal.feed_mode ^ 1))));
if(settings.mode == Mode_Lathe && gc_spindle_get()->cap.variable)
hal.stream.write(gc_state.modal.spindle.rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
if(settings.mode == Mode_Lathe && gc_spindle_get(0)->hal->cap.variable)
hal.stream.write(gc_spindle_get(0)->rpm_mode == SpindleSpeedMode_RPM ? " G97" : " G96");
#if COMPATIBILITY_LEVEL < 10
@@ -777,7 +777,7 @@ void report_gcode_modes (void)
}
}
hal.stream.write(gc_state.modal.spindle.state.on ? (gc_state.modal.spindle.state.ccw ? " M4" : " M3") : " M5");
hal.stream.write(gc_spindle_get(0)->state.on ? (gc_spindle_get(0)->state.ccw ? " M4" : " M3") : " M5");
if(gc_state.tool_change)
hal.stream.write(" M6");
@@ -809,8 +809,8 @@ void report_gcode_modes (void)
hal.stream.write(appendbuf(2, " F", get_rate_value(gc_state.feed_rate)));
if(gc_spindle_get()->cap.variable)
hal.stream.write(appendbuf(2, " S", ftoa(gc_state.spindle.rpm, N_DECIMAL_RPMVALUE)));
if(gc_spindle_get(0)->hal->cap.variable)
hal.stream.write(appendbuf(2, " S", ftoa(gc_spindle_get(0)->rpm, N_DECIMAL_RPMVALUE)));
hal.stream.write("]" ASCII_EOL);
}
@@ -1450,12 +1450,13 @@ void report_realtime_status (void)
static gc_modal_t last_state;
static bool g92_active;
bool is_changed = feed_rate != gc_state.feed_rate || spindle_rpm != gc_state.spindle.rpm || tool_id != gc_state.tool->tool_id;
spindle_t *spindle = gc_spindle_get(0);
bool is_changed = feed_rate != gc_state.feed_rate || spindle_rpm != spindle->rpm || tool_id != gc_state.tool->tool_id;
if(is_changed) {
feed_rate = gc_state.feed_rate;
tool_id = gc_state.tool->tool_id;
spindle_rpm = gc_state.spindle.rpm;
spindle_rpm = spindle->rpm;
} else if ((is_changed = g92_active != is_g92_active()))
g92_active = !g92_active;
else if(memcmp(&last_state, &gc_state.modal, sizeof(gc_modal_t))) {
@@ -2199,12 +2200,12 @@ status_code_t report_current_home_signal_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)
{
spindle_ptrs_t *spindle = gc_spindle_get();
spindle_t *spindle = gc_spindle_get(-1);
if(spindle->get_data) {
if(spindle->hal->get_data) {
float apos = spindle->get_data(SpindleData_AngularPosition)->angular_position;
spindle_data_t *data = spindle->get_data(SpindleData_Counters);
float apos = spindle->hal->get_data(SpindleData_AngularPosition)->angular_position;
spindle_data_t *data = spindle->hal->get_data(SpindleData_Counters);
hal.stream.write("[SPINDLEENCODER:");
hal.stream.write(uitoa(data->index_count));
@@ -2217,7 +2218,7 @@ status_code_t report_spindle_data (sys_state_t state, char *args)
hal.stream.write("]" ASCII_EOL);
}
return spindle->get_data ? Status_OK : Status_InvalidStatement;
return spindle->hal->get_data ? Status_OK : Status_InvalidStatement;
}
// Prints info about registered pins.
+1 -1
View File
@@ -75,7 +75,7 @@ void sleep_check (void)
// 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 (!(slumber || sys.steppers_deenergize || sys.flags.auto_reporting) && (gc_state.modal.spindle.state.value || gc_state.modal.coolant.value)) {
if (!(slumber || sys.steppers_deenergize || sys.flags.auto_reporting) && (gc_spindle_get(0)->state.value || gc_state.modal.coolant.value)) {
switch(state_get()) {
case STATE_IDLE:
+15 -9
View File
@@ -510,19 +510,22 @@ void spindle_set_override (spindle_ptrs_t *spindle, override_t speed_override)
speed_override = constrain(speed_override, MIN_SPINDLE_RPM_OVERRIDE, MAX_SPINDLE_RPM_OVERRIDE);
if ((uint8_t)speed_override != spindle->param->override_pct) {
if((uint8_t)speed_override != spindle->param->override_pct) {
spindle->param->override_pct = speed_override;
spindle_set_rpm(spindle, spindle->param->rpm, speed_override);
if(state_get() == STATE_IDLE)
spindle_set_state(spindle, gc_state.modal.spindle.state, gc_state.spindle.rpm);
else
if(state_get() == STATE_IDLE) {
if(spindle->get_pwm && spindle->update_pwm)
spindle->update_pwm(spindle, spindle->get_pwm(spindle, spindle->param->rpm_overridden));
else if(spindle->update_rpm)
spindle->update_rpm(spindle, spindle->param->rpm_overridden);
} else
sys.step_control.update_spindle_rpm = On;
system_add_rt_report(Report_Overrides); // Set to report change immediately
if(grbl.on_spindle_programmed)
grbl.on_spindle_programmed(spindle, gc_state.modal.spindle.state, spindle_set_rpm(spindle, gc_state.spindle.rpm, speed_override), gc_state.modal.spindle.rpm_mode);
// if(grbl.on_spindle_programmed)
// grbl.on_spindle_programmed(spindle, spindle->param->state, spindle->param->rpm, spindle->param->rpm_mode);
if(grbl.on_override_changed)
grbl.on_override_changed(OverrideChanged_SpindleRPM);
@@ -542,10 +545,10 @@ static bool set_state (spindle_ptrs_t *spindle, spindle_state_t state, float rpm
if (!ABORTED) { // Block during abort.
if (!state.on) { // Halt or set spindle direction and rpm.
spindle->param->rpm = rpm = 0.0f;
rpm = 0.0f;
spindle->set_state(spindle, (spindle_state_t){0}, 0.0f);
} else {
// NOTE: Assumes all calls to this function is when Grbl is not moving or must remain off.
// NOTE: Assumes all calls to this function is when grblHAL is not moving or must remain off.
// TODO: alarm/interlock if going from CW to CCW directly in non-laser mode?
if (spindle->cap.laser && state.ccw)
rpm = 0.0f; // TODO: May need to be rpm_min*(100/MAX_SPINDLE_RPM_OVERRIDE);
@@ -553,6 +556,9 @@ static bool set_state (spindle_ptrs_t *spindle, spindle_state_t state, float rpm
spindle->set_state(spindle, state, spindle_set_rpm(spindle, rpm, spindle->param->override_pct));
}
spindle->param->rpm = rpm;
spindle->param->state = state;
system_add_rt_report(Report_Spindle); // Set to report change immediately
st_rpm_changed(rpm);
+11 -11
View File
@@ -122,7 +122,7 @@ static void enter_sleep (void)
static bool initiate_hold (uint_fast16_t new_state)
{
spindle_ptrs_t *spindle;
spindle_t *spindle;
spindle_num_t spindle_num = N_SYS_SPINDLE;
if (settings.parking.flags.enabled) {
@@ -137,21 +137,21 @@ static bool initiate_hold (uint_fast16_t new_state)
restore_condition.spindle_num = 0;
do {
if((spindle = spindle_get(--spindle_num))) {
if(block && block->spindle.hal == spindle) {
if((spindle = gc_spindle_get(--spindle_num))) {
if(block && block->spindle.hal == spindle->hal) {
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) {
} else if(spindle->hal) {
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;
restore_condition.spindle[spindle_num].hal = spindle->hal;
restore_condition.spindle[spindle_num].rpm = spindle->rpm;
restore_condition.spindle[spindle_num].state = 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;
restore_condition.spindle[spindle_num].hal = NULL;
// 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;
@@ -352,7 +352,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.state.on)
if (stateHandler != state_await_resume || !gc_spindle_get(0)->state.on)
return;
if (sys.override.spindle_stop.value) {
+5 -5
View File
@@ -167,12 +167,12 @@ static status_code_t read_int (char *s, int32_t *value)
// Reset spindle encoder data
static status_code_t spindle_reset_data (sys_state_t state, char *args)
{
spindle_ptrs_t *spindle = gc_spindle_get();
spindle_t *spindle = gc_spindle_get(-1);
if(spindle->reset_data)
spindle->reset_data();
if(spindle->hal->reset_data)
spindle->hal->reset_data();
return spindle->reset_data ? Status_OK : Status_InvalidStatement;
return spindle->hal->reset_data ? Status_OK : Status_InvalidStatement;
}
static status_code_t jog (sys_state_t state, char *args)
@@ -767,7 +767,7 @@ const char *help_rtc (const char *cmd)
const char *help_spindle (const char *cmd)
{
spindle_ptrs_t *spindle = gc_spindle_get();
spindle_ptrs_t *spindle = gc_spindle_get(0)->hal;
if(cmd[1] == 'R' && spindle->reset_data)
hal.stream.write("$SR - reset spindle encoder data." ASCII_EOL);
+3 -1
View File
@@ -137,10 +137,12 @@ static bool restore (void)
if(protocol_buffer_synchronize()) {
sync_position();
coolant_sync(gc_state.modal.coolant);
spindle_restore(plan_data.spindle.hal, gc_state.modal.spindle.state, gc_state.spindle.rpm);
spindle_t *spindle = gc_spindle_get(-1);
spindle_restore(spindle->hal, spindle->state, spindle->rpm);
if(!settings.flags.no_restore_position_after_M6) {
previous.values[plane.axis_linear] += gc_get_offset(plane.axis_linear, false);