Tentative fix for lathe CSS/feed per rev modes (G96/G95), ref discussion #450.

Fixed incorrect reporting of feed rate modes in $G response.
Added some ioPorts call wrappers, full support for reconfiguring output auxillary pins for PWM output.
This commit is contained in:
Terje Io
2024-02-28 17:36:17 +01:00
parent 8fa4535444
commit 06f442643a
10 changed files with 132 additions and 77 deletions
+22
View File
@@ -1,5 +1,27 @@
## grblHAL changelog
<a name="20240228"/>Build 20240228
Core:
* Tentative fix for lathe CSS/feed per rev modes \(G96/G95\), ref discussion [#450](https://github.com/grblHAL/core/discussions/450).
* Fixed incorrect reporting of feed rate modes in `$G` response.
* Added some ioPorts call wrappers, full support for reconfiguring output auxillary pins for PWM output.
Drivers:
* STM32F1xx, ST32F4xx, STM32F7xx: fix for incorrect status returned from ioPort configuration call.
* STM32F7xx: added full support for reconfiguring capable auxillary output pins for PWM.
Plugins:
* WebUI: added update that did not make it in the previous one...
---
<a name="20240226"/>Build 20240226
Core:
+5
View File
@@ -81,6 +81,7 @@ typedef enum {
Input_Aux5,
Input_Aux6,
Input_Aux7,
Input_AuxMax = Input_Aux7,
Input_Analog_Aux0,
Input_Analog_Aux1,
Input_Analog_Aux2,
@@ -89,6 +90,7 @@ typedef enum {
Input_Analog_Aux5,
Input_Analog_Aux6,
Input_Analog_Aux7,
Input_Analog_AuxMax = Input_Analog_Aux7,
// Output pins
Output_StepX,
Outputs = Output_StepX,
@@ -147,6 +149,7 @@ typedef enum {
Output_Aux5,
Output_Aux6,
Output_Aux7,
Output_AuxMax = Output_Aux7,
Output_Analog_Aux0,
Output_Analog_Aux1,
Output_Analog_Aux2,
@@ -155,6 +158,7 @@ typedef enum {
Output_Analog_Aux5,
Output_Analog_Aux6,
Output_Analog_Aux7,
Output_Analog_AuxMax = Output_Analog_Aux7,
Output_LED,
Output_LED_R,
Output_LED_G,
@@ -537,6 +541,7 @@ typedef struct {
typedef struct {
bool inverted;
bool open_drain;
bool pwm;
} gpio_out_config_t;
//! /a cfg_data argument to /a xbar_config_ptr for PWM pins
+10 -7
View File
@@ -7,18 +7,18 @@
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
Grbl is free software: you can redistribute it and/or modify
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
@@ -3013,7 +3013,7 @@ status_code_t gc_execute_block (char *block)
gc_state.spindle.css->tool_offset = gc_get_offset(gc_state.spindle.css->axis);
float pos = gc_state.position[gc_state.spindle.css->axis] - gc_state.spindle.css->tool_offset;
gc_block.values.s = pos <= 0.0f ? gc_state.spindle.css->max_rpm : min(gc_state.spindle.css->max_rpm, gc_state.spindle.css->surface_speed / (pos * (float)(2.0f * M_PI)));
gc_parser_flags.spindle_force_sync = On;
//?? gc_parser_flags.spindle_force_sync = On;
} else {
if(gc_state.spindle.css) {
gc_state.spindle.css = NULL;
@@ -3413,7 +3413,8 @@ status_code_t gc_execute_block (char *block)
case MotionMode_Linear:
if(gc_state.modal.feed_mode == FeedMode_UnitsPerRev) {
plan_data.spindle.state.synchronized = On;
plan_data.condition.units_per_rev = On;
plan_data.spindle.state.synchronized = settings.mode != Mode_Lathe || gc_block.values.xyz[Z_AXIS] != gc_state.position[Z_AXIS];
//?? gc_state.distance_per_rev = plan_data.feed_rate;
// check initial feed rate - fail if zero?
}
@@ -3427,7 +3428,9 @@ status_code_t gc_execute_block (char *block)
case MotionMode_CwArc:
case MotionMode_CcwArc:
// fail if spindle synchronized motion?
if(gc_state.modal.feed_mode == FeedMode_UnitsPerRev)
plan_data.condition.units_per_rev = plan_data.spindle.state.synchronized = On;
mc_arc(gc_block.values.xyz, &plan_data, gc_state.position, gc_block.values.ijk, gc_block.values.r,
plane, gc_parser_flags.arc_is_clockwise ? -gc_block.arc_turns : gc_block.arc_turns);
break;
+1 -1
View File
@@ -42,7 +42,7 @@
#else
#define GRBL_VERSION "1.1f"
#endif
#define GRBL_BUILD 20240226
#define GRBL_BUILD 20240228
#define GRBL_URL "https://github.com/grblHAL"
+54 -41
View File
@@ -148,10 +148,24 @@ void ioport_assign_function (aux_ctrl_t *aux_ctrl, pin_function_t *function)
if((input = hal.port.get_pin_info(Port_Digital, Port_Input, aux_ctrl->aux_port))) {
*function = aux_ctrl->function;
digital.inx.mask &= ~(1 << input->id);
hal.signals_cap.mask |= aux_ctrl->cap.mask;
if(aux_ctrl->function == Input_Probe || xbar_fn_to_signals_mask(aux_ctrl->function).mask)
setting_remove_elements(Settings_IoPort_InvertIn, digital.inx.mask & ~(1 << input->id));
setting_remove_elements(Settings_IoPort_InvertIn, digital.inx.mask);
}
}
void ioport_assign_out_function (aux_ctrl_out_t *aux_ctrl, pin_function_t *function)
{
xbar_t *output;
if((output = hal.port.get_pin_info(Port_Digital, Port_Output, aux_ctrl->aux_port))) {
*function = aux_ctrl->function;
digital.outx.mask &= ~(1 << output->id);
setting_remove_elements(Settings_IoPort_InvertOut, digital.outx.mask);
}
}
@@ -180,24 +194,18 @@ bool ioports_enumerate (io_port_type_t type, io_port_direction_t dir, pin_cap_t
bool ioport_analog_out_config (uint8_t port, pwm_config_t *config)
{
bool ok;
xbar_t *pin;
bool ok = (pin = hal.port.get_pin_info(Port_Analog, Port_Output, port)) && pin->config;
if((ok = (pin = hal.port.get_pin_info(Port_Analog, Port_Output, port)) && pin->config))
pin->config(pin, config, false);
return ok;
return ok && pin->config(pin, config, false);
}
bool ioport_digital_in_config (uint8_t port, gpio_in_config_t *config)
{
bool ok;
xbar_t *pin;
bool ok = (pin = hal.port.get_pin_info(Port_Digital, Port_Input, port)) && pin->config;
if((ok = (pin = hal.port.get_pin_info(Port_Digital, Port_Input, port)) && pin->config))
pin->config(pin, config, false);
return ok;
return ok && pin->config(pin, config, false);
}
bool ioport_enable_irq (uint8_t port, pin_irq_mode_t irq_mode, ioport_interrupt_callback_ptr handler)
@@ -207,13 +215,18 @@ bool ioport_enable_irq (uint8_t port, pin_irq_mode_t irq_mode, ioport_interrupt_
bool ioport_digital_out_config (uint8_t port, gpio_out_config_t *config)
{
bool ok;
xbar_t *pin;
bool ok = (pin = hal.port.get_pin_info(Port_Digital, Port_Output, port)) && pin->config && !(pin->mode.pwm || pin->mode.servo_pwm);
if((ok = (pin = hal.port.get_pin_info(Port_Digital, Port_Output, port)) && pin->config))
pin->config(pin, config, false);
return ok && pin->config(pin, config, false);
}
return ok;
bool ioport_digital_pwm_config (uint8_t port, pwm_config_t *config)
{
xbar_t *pin;
bool ok = (pin = hal.port.get_pin_info(Port_Digital, Port_Output, port)) && pin->config && pin->mode.claimed && pin->cap.pwm;
return ok && pin->config(pin, config, false);
}
/* experimental code follows */
@@ -394,39 +407,38 @@ uint_fast16_t ioports_compute_pwm_value (ioports_pwm_t *pwm_data, float value)
return pwm_value;
}
static void sync_input_settings (pin_function_t function, gpio_in_config_t *config)
void ioport_save_input_settings (xbar_t *xbar, gpio_in_config_t *config)
{
if(function == Input_Probe)
if(digital.inx.mask & (1 << xbar->id)) {
if(config->inverted)
settings.ioport.invert_in.mask |= (1 << xbar->id);
else
settings.ioport.invert_in.mask &= ~(1 << xbar->id);
}
if(xbar->function == Input_Probe)
settings.probe.invert_probe_pin = config->inverted;
else if(function < Input_Probe) {
else if(xbar->function < Input_Probe) {
control_signals_t ctrl;
if((ctrl = xbar_fn_to_signals_mask(function)).mask) {
if((ctrl = xbar_fn_to_signals_mask(xbar->function)).mask) {
if(config->inverted)
settings.control_invert.mask |= ctrl.mask;
else
settings.control_invert.mask &= ~ctrl.mask;
}
}
}
void ioport_save_input_settings (xbar_t *xbar, gpio_in_config_t *config)
{
if(config->inverted)
settings.ioport.invert_in.mask |= (1 << xbar->id);
else
settings.ioport.invert_in.mask &= ~(1 << xbar->id);
sync_input_settings(xbar->function, config);
settings_write_global();
}
void ioport_save_output_settings (xbar_t *xbar, gpio_out_config_t *config)
{
if(config->inverted)
settings.ioport.invert_out.mask |= (1 << xbar->id);
else
settings.ioport.invert_out.mask &= ~(1 << xbar->id);
if(digital.outx.mask & (1 << xbar->id)) {
if(config->inverted)
settings.ioport.invert_out.mask |= (1 << xbar->id);
else
settings.ioport.invert_out.mask &= ~(1 << xbar->id);
}
settings_write_global();
}
@@ -439,12 +451,12 @@ static bool is_setting_available (const setting_detail_t *setting)
case Settings_IoPort_InvertIn:
case Settings_IoPort_Pullup_Disable:
available = digital.in.ports && digital.in.ports->n_ports > 0;
available = digital.in.ports && digital.inx.mask;
break;
case Settings_IoPort_InvertOut:
case Settings_IoPort_OD_Enable:
available = digital.out.ports && digital.out.ports->n_ports > 0;
available = digital.out.ports && digital.outx.mask;
break;
default:
@@ -476,7 +488,6 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
config.pull_mode = (pull_mode_t)xbar->mode.pull_mode;
config.inverted = !!(change.mask & (1 << xbar->id));
xbar->config(xbar, &config, false);
sync_input_settings(xbar->function, &config);
}
}
port++;
@@ -504,7 +515,6 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
config.inverted = xbar->mode.inverted;
config.debounce = xbar->mode.inverted;
xbar->config(xbar, &config, false);
sync_input_settings(xbar->function, &config);
}
}
port++;
@@ -527,7 +537,7 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
do {
if((changed.mask & 0x01) && (xbar = hal.port.get_pin_info(Port_Digital, Port_Output, ioports_map_reverse(digital.out.ports, port)))) {
if(xbar->config) {
if(xbar->config && !(xbar->mode.pwm || xbar->mode.servo_pwm)) {
config.inverted = !!(change.mask & (1 << xbar->id));
config.open_drain = xbar->mode.open_drain;
xbar->config(xbar, &config, false);
@@ -553,7 +563,7 @@ static status_code_t aux_set_value (setting_id_t id, uint_fast16_t value)
do {
if((changed.mask & 0x01) && (xbar = hal.port.get_pin_info(Port_Digital, Port_Output, ioports_map_reverse(digital.out.ports, port)))) {
if(xbar->config) {
if(xbar->config && !(xbar->mode.pwm || xbar->mode.servo_pwm)) {
config.inverted = xbar->mode.inverted;
config.open_drain = !!(change.mask & (1 << xbar->id));
xbar->config(xbar, &config, false);
@@ -636,7 +646,10 @@ static void ioport_settings_load (void)
gpio_in_config_t in_config = {0};
gpio_out_config_t out_config = {0};
// TODO: change labels for mapped settings?
settings.ioport.invert_in.mask &= digital.inx.mask;
settings.ioport.pullup_disable_in.mask &= digital.inx.mask;
settings.ioport.invert_out.mask &= digital.outx.mask;
settings.ioport.od_enable_out.mask &= digital.outx.mask;
if(digital.in.ports && (port = digital.in.ports->n_ports)) do {
if((xbar = hal.port.get_pin_info(Port_Digital, Port_Input, ioports_map_reverse(digital.in.ports, --port)))) {
@@ -671,7 +684,7 @@ static void ioport_settings_load (void)
if(digital.out.ports && (port = digital.out.ports->n_ports)) do {
if((xbar = hal.port.get_pin_info(Port_Digital, Port_Output, ioports_map_reverse(digital.in.ports, --port)))) {
if(xbar->config) {
if(xbar->config && !(xbar->mode.pwm || xbar->mode.servo_pwm)) {
out_config.inverted = !!(settings.ioport.invert_out.mask & (1 << xbar->id));
out_config.open_drain = !!(settings.ioport.od_enable_out.mask & (1 << xbar->id));
xbar->config(xbar, &out_config, false);
+2
View File
@@ -128,7 +128,9 @@ bool ioport_claim (io_port_type_t type, io_port_direction_t dir, uint8_t *port,
bool ioport_can_claim_explicit (void);
bool ioports_enumerate (io_port_type_t type, io_port_direction_t dir, pin_cap_t filter, ioports_enumerate_callback_ptr callback, void *data);
void ioport_assign_function (aux_ctrl_t *aux_ctrl, pin_function_t *function);
void ioport_assign_out_function (aux_ctrl_out_t *aux_ctrl, pin_function_t *function);
bool ioport_analog_out_config (uint8_t port, pwm_config_t *config);
bool ioport_digital_pwm_config (uint8_t port, pwm_config_t *config);
bool ioport_digital_in_config (uint8_t port, gpio_in_config_t *config);
bool ioport_enable_irq (uint8_t port, pin_irq_mode_t irq_mode, ioport_interrupt_callback_ptr handler);
bool ioport_digital_out_config (uint8_t port, gpio_out_config_t *config);
+10 -8
View File
@@ -8,18 +8,18 @@
Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2011 Jens Geisler
Grbl is free software: you can redistribute it and/or modify
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#include <math.h>
@@ -310,14 +310,16 @@ 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->spindle.state.synchronized ? block->programmed_rate * block->spindle.hal->get_data(SpindleData_RPM)->rpm : block->programmed_rate;
float nominal_speed = block->condition.units_per_rev || block->spindle.state.synchronized
? block->programmed_rate * block->spindle.hal->get_data(SpindleData_RPM)->rpm
: block->programmed_rate;
if (block->condition.rapid_motion)
if(block->condition.rapid_motion)
nominal_speed *= (0.01f * (float)sys.override.rapid_rate);
else {
if (!block->condition.no_feed_override)
if(!block->condition.no_feed_override)
nominal_speed *= (0.01f * (float)sys.override.feed_rate);
if (nominal_speed > block->rapid_rate)
if(nominal_speed > block->rapid_rate)
nominal_speed = block->rapid_rate;
}
+7 -6
View File
@@ -3,22 +3,22 @@
Part of grblHAL
Copyright (c) 2019-2023 Terje Io
Copyright (c) 2019-2024 Terje Io
Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
Copyright (c) 2009-2011 Simen Svale Skogsrud
Grbl is free software: you can redistribute it and/or modify
grblHAL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
grblHAL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
along with grblHAL. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PLANNER_H_
@@ -33,11 +33,12 @@ typedef union {
backlash_motion :1,
no_feed_override :1,
inverse_time :1,
units_per_rev :1,
is_rpm_rate_adjusted :1,
is_laser_ppi_mode :1,
target_valid :1,
target_validated :1,
unassigned :6;
unassigned :5;
coolant_state_t coolant;
};
} planner_cond_t;
+4 -2
View File
@@ -698,7 +698,7 @@ void report_gcode_modes (void)
hal.stream.write(gc_state.modal.distance_incremental ? " G91" : " G90");
hal.stream.write(" G");
hal.stream.write(uitoa((uint32_t)(94 - gc_state.modal.feed_mode)));
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");
@@ -2341,14 +2341,16 @@ status_code_t report_pin_states (sys_state_t state, char *args)
for(idx = 0; idx < ports; idx++) {
if((port = hal.port.get_pin_info(Port_Digital, Port_Output, idx))) {
hal.stream.write("[PINSTATE:DOUT|");
hal.stream.write(port->description);
hal.stream.write(port->description ? port->description : xbar_fn_to_pinname(port->function));
hal.stream.write("|");
hal.stream.write(uitoa(port->id));
hal.stream.write("|");
hal.stream.write(port->mode.inverted ? "I" : "N");
// hal.stream.write(port->mode.pwm ? "P" : (port->mode.servo_pwm ? "S" : "N"));
// hal.stream.write(port->mode.open_drain ? "O" : "-");
hal.stream.write("|");
hal.stream.write(port->cap.invert ? "I" : "-");
// hal.stream.write(port->cap.pwm ? "P" : (port->cap.servo_pwm ? "S" : "N"));
// hal.stream.write(port->cap.open_drain ? "O" : "-");
hal.stream.write("|");
hal.stream.write(port->get_value ? uitoa((uint32_t)port->get_value(port)) : "?");
+17 -12
View File
@@ -2561,20 +2561,25 @@ static void setting_remove_element (setting_id_t id, uint_fast8_t pos)
// Note: setting format string has to reside in RAM.
void setting_remove_elements (setting_id_t id, uint32_t mask)
{
char *format = (char *)setting_get_details(id, NULL)->format, *s;
uint_fast8_t idx, entries = strnumentries(format, ',');
const setting_detail_t *setting;
for(idx = 0; idx < entries; idx++ ) {
if(!(mask & 0x1))
setting_remove_element(id, idx);
mask >>= 1;
}
if((setting = setting_get_details(id, NULL))) {
// Strip trailing N/A's
while((s = strrchr(format, ','))) {
if(strncmp(s, ",N/A", 4))
break;
*s = '\0';
char *format = (char *)setting->format, *s;
uint_fast8_t idx, entries = strnumentries(format, ',');
for(idx = 0; idx < entries; idx++ ) {
if(!(mask & 0x1))
setting_remove_element(id, idx);
mask >>= 1;
}
// Strip trailing N/A's
while((s = strrchr(format, ','))) {
if(strncmp(s, ",N/A", 4))
break;
*s = '\0';
}
}
}