mirror of
https://github.com/grblHAL/core.git
synced 2026-08-17 08:31:43 +08:00
Improved ioport remapping of auxiliary pins (used by plasma plugin).
Changed signature of limit check functions, grbl.travel_limits() et. al. to include a pointer to the work envelope to use. Updated spindle off handling to check for "at speed" on deceleration when spindle is "at speed" capable.
This commit is contained in:
+22
-1
@@ -1,5 +1,26 @@
|
||||
## grblHAL changelog
|
||||
|
||||
<a name="20250806">Build 20250806
|
||||
|
||||
Core:
|
||||
|
||||
* Improved ioport remapping of auxiliary pins \(used by plasma plugin\).
|
||||
|
||||
* Changed signature of limit check functions, [grbl.travel_limits()](https://svn.io-engineering.com/grblHAL/html/core__handlers_8h.html#a56eced06d1c379782d86c2f139cd3f96) et. al. to include a pointer to the work envelope to use.
|
||||
This may simplify implementations of plugins that want to alter the envelope.
|
||||
|
||||
* Updated spindle off handling to check for "at speed" on deceleration when spindle is "at speed" capable
|
||||
|
||||
Drivers:
|
||||
|
||||
* STM32F4xx, STM32F7xx: fix for I2C transmits sometimes blocking when they should not. Will cause I2C displays to fail.
|
||||
|
||||
Plugins:
|
||||
|
||||
* Plasma: improved/fixed handling of virtual auxiliary ports.
|
||||
|
||||
---
|
||||
|
||||
<a name="20250802">20250802
|
||||
|
||||
Core:
|
||||
@@ -10,7 +31,7 @@ Drivers:
|
||||
|
||||
* ESP32: added missing define for I2C for MKS DLC 32 v2.0 board. Ref. discussion comment in [#645](https://github.com/grblHAL/core/discussions/645#discussioncomment-13960933)
|
||||
|
||||
* RP2040: added tentative support for Mesa THCAD2 voltage to frequency converter. Not complete!
|
||||
* RP2040: added tentative support for [Mesa THCAD2](https://mesaus.com/product/thcad2/) voltage to frequency converter. Not complete!
|
||||
Added option for using Aux out 1 for Neopixels on the RP23U5XBB board. Ref. discussion [#143](https://github.com/grblHAL/RP2040/discussions/143).
|
||||
|
||||
Plugins:
|
||||
|
||||
+3
-3
@@ -78,10 +78,10 @@ typedef struct {
|
||||
|
||||
typedef bool (*enqueue_gcode_ptr)(char *data);
|
||||
typedef bool (*protocol_enqueue_realtime_command_ptr)(char c);
|
||||
typedef bool (*travel_limits_ptr)(float *target, axes_signals_t axes, bool is_cartesian);
|
||||
typedef bool (*arc_limits_ptr)(coord_data_t *target, coord_data_t *position, point_2d_t center, float radius, plane_t plane, int32_t turns);
|
||||
typedef bool (*travel_limits_ptr)(float *target, axes_signals_t axes, bool is_cartesian, work_envelope_t *envelope);
|
||||
typedef bool (*arc_limits_ptr)(coord_data_t *target, coord_data_t *position, point_2d_t center, float radius, plane_t plane, int32_t turns, work_envelope_t *envelope);
|
||||
|
||||
typedef void (*apply_travel_limits_ptr)(float *target, float *position);
|
||||
typedef void (*apply_travel_limits_ptr)(float *target, float *position, work_envelope_t *envelope);
|
||||
typedef bool (*home_machine_ptr)(axes_signals_t cycle, axes_signals_t auto_square);
|
||||
|
||||
typedef void (*on_parser_init_ptr)(parser_state_t *gc_state);
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#else
|
||||
#define GRBL_VERSION "1.1f"
|
||||
#endif
|
||||
#define GRBL_BUILD 20250731
|
||||
#define GRBL_BUILD 20250806
|
||||
|
||||
#define GRBL_URL "https://github.com/grblHAL"
|
||||
|
||||
|
||||
@@ -553,31 +553,6 @@ bool ioport_digital_pwm_config (uint8_t port, pwm_config_t *config)
|
||||
return ok && pin->config(pin, config, false);
|
||||
}
|
||||
|
||||
/*! \brief Remap (virtual) port.
|
||||
\param type as an \a #io_port_type_t enum value.
|
||||
\param dir as an \a #io_port_direction_t enum value.
|
||||
\param port_from the assigned port number.
|
||||
\param port_to the remapped port number. The original port number will be shadowed.
|
||||
\returns \a true if successful, \a false if original port is already claimed.
|
||||
*/
|
||||
bool ioport_remap (io_port_type_t type, io_port_direction_t dir, uint8_t port_from, uint8_t port_to)
|
||||
{
|
||||
uint8_t org_port;
|
||||
bool ok;
|
||||
io_ports_private_t *cfg = get_port_data(type, dir);
|
||||
|
||||
if((ok = (cfg->claimed.mask & (1UL << port_to))) == 0) {
|
||||
|
||||
if((org_port = map_reverse(cfg, port_from)) != port_to)
|
||||
cfg->map[org_port] = 255;
|
||||
|
||||
cfg->free = -1;
|
||||
cfg->map[port_to] = port_from;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// HAL wrapper/veneers
|
||||
|
||||
__STATIC_FORCEINLINE bool is_match (io_ports_list_t *io_port, io_port_type_t type, io_port_direction_t dir, uint8_t port)
|
||||
@@ -902,6 +877,33 @@ static bool _ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n
|
||||
return n_ports > 0;
|
||||
}
|
||||
|
||||
/*! \brief Remap (virtual) port.
|
||||
\param type as an \a #io_port_type_t enum value.
|
||||
\param dir as an \a #io_port_direction_t enum value.
|
||||
\param port_from the assigned port number.
|
||||
\param port_to the remapped port number. The original port number will be swapped with \a port_from.
|
||||
\returns \a true if successful, \a false if original port is already claimed.
|
||||
*/
|
||||
bool ioport_remap (io_port_type_t type, io_port_direction_t dir, uint8_t port_from, uint8_t port_to)
|
||||
{
|
||||
uint8_t org_port;
|
||||
bool ok;
|
||||
io_ports_private_t *cfg = get_port_data(type, dir);
|
||||
|
||||
if((ok = (cfg->claimed.mask & (1UL << cfg->map[port_to])) == 0)) {
|
||||
|
||||
if((org_port = map_reverse(cfg, port_from)) != port_to) {
|
||||
cfg->map[org_port] = cfg->map[port_to];
|
||||
hal.port.set_pin_description(type, dir, org_port, pnum_to_string(org_port, cfg->pnum));
|
||||
}
|
||||
|
||||
cfg->free = -1;
|
||||
cfg->map[port_to] = port_from;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool ioports_add (io_ports_data_t *ports, io_port_type_t type, uint8_t n_in, uint8_t n_out)
|
||||
{
|
||||
return hal.port.get_pin_info != io_get_pin_info && _ioports_add(ports, type, n_in, n_out, hal.port.set_pin_description);
|
||||
|
||||
+3
-3
@@ -118,16 +118,16 @@ static void corexy_limits_set_target_pos (uint_fast8_t idx) // fn name?
|
||||
|
||||
// Checks and reports if target array exceeds machine travel limits. Returns false if check failed.
|
||||
// NOTE: target for axes X and Y are in motor coordinates if is_cartesian is false.
|
||||
static bool corexy_check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian)
|
||||
static bool corexy_check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian, work_envelope_t *envelope)
|
||||
{
|
||||
if(is_cartesian)
|
||||
return check_travel_limits(target, axes, true);
|
||||
return check_travel_limits(target, axes, true, envelope);
|
||||
|
||||
float cartesian_coords[N_AXIS];
|
||||
|
||||
transform_to_cartesian(cartesian_coords, target);
|
||||
|
||||
return check_travel_limits(cartesian_coords, axes, true);
|
||||
return check_travel_limits(cartesian_coords, axes, true, envelope);
|
||||
}
|
||||
|
||||
// Set machine positions for homed limit switches. Don't update non-homed axes.
|
||||
|
||||
+6
-6
@@ -234,7 +234,7 @@ static float *delta_segment_line (float *target, float *position, plan_line_data
|
||||
|
||||
if(!pl_data->condition.target_validated) {
|
||||
pl_data->condition.target_validated = On;
|
||||
pl_data->condition.target_valid = grbl.check_travel_limits(mpos.values, sys.soft_limits, false);
|
||||
pl_data->condition.target_valid = grbl.check_travel_limits(mpos.values, sys.soft_limits, false, &sys.work_envelope);
|
||||
}
|
||||
|
||||
transform_to_cartesian(segment_target.values, position);
|
||||
@@ -576,14 +576,14 @@ static inline bool pos_ok (coord_data_t *pos)
|
||||
}
|
||||
|
||||
// Checks and reports if target array exceeds machine travel limits. Returns false if check failed.
|
||||
static bool delta_check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian)
|
||||
static bool delta_check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian, work_envelope_t *envelope)
|
||||
{
|
||||
bool failed = false;
|
||||
uint_fast8_t idx = N_AXIS;
|
||||
coord_data_t pos;
|
||||
|
||||
#if N_AXIS > 3
|
||||
if((axes.mask & ~0b111) && !check_travel_limits(target, (axes_signals_t){ axes.mask & ~0b111 }, is_cartesian))
|
||||
if((axes.mask & ~0b111) && !check_travel_limits(target, (axes_signals_t){ axes.mask & ~0b111 }, is_cartesian, envelope))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -607,7 +607,7 @@ static bool delta_check_travel_limits (float *target, axes_signals_t axes, bool
|
||||
idx--;
|
||||
if(bit_istrue(sys.homed.mask, bit(idx)) && settings.axis[idx].max_travel < -0.0f) {
|
||||
if(idx > Z_AXIS)
|
||||
failed = target[idx] < sys.work_envelope.min.values[idx] || target[idx] > sys.work_envelope.max.values[idx];
|
||||
failed = target[idx] < envelope->min.values[idx] || target[idx] > envelope->max.values[idx];
|
||||
else
|
||||
failed = pos.values[idx] < machine.min_angle[idx] || pos.values[idx] > machine.max_angle[idx];
|
||||
}
|
||||
@@ -616,13 +616,13 @@ static bool delta_check_travel_limits (float *target, axes_signals_t axes, bool
|
||||
return !failed;
|
||||
}
|
||||
|
||||
static void delta_apply_travel_limits (float *target, float *position)
|
||||
static void delta_apply_travel_limits (float *target, float *position, work_envelope_t *envelope)
|
||||
{
|
||||
if(sys.homed.mask == 0)
|
||||
return;
|
||||
|
||||
if(machine.cfg.flags.limit_to_cuboid)
|
||||
apply_travel_limits(target, position);
|
||||
apply_travel_limits(target, position, envelope);
|
||||
|
||||
else if(position && !is_target_inside_cuboid(target, true)) {
|
||||
|
||||
|
||||
+11
-11
@@ -607,9 +607,9 @@ status_code_t limits_go_home (axes_signals_t cycle)
|
||||
void limits_soft_check (float *target, planner_cond_t condition)
|
||||
{
|
||||
#ifdef KINEMATICS_API
|
||||
if(condition.target_validated ? !condition.target_valid : !grbl.check_travel_limits(target, sys.soft_limits, false)) {
|
||||
if(condition.target_validated ? !condition.target_valid : !grbl.check_travel_limits(target, sys.soft_limits, false, &sys.work_envelope)) {
|
||||
#else
|
||||
if(condition.target_validated ? !condition.target_valid : !grbl.check_travel_limits(target, sys.soft_limits, true)) {
|
||||
if(condition.target_validated ? !condition.target_valid : !grbl.check_travel_limits(target, sys.soft_limits, true, &sys.work_envelope)) {
|
||||
#endif
|
||||
|
||||
sys.flags.soft_limit = On;
|
||||
@@ -663,7 +663,7 @@ static float get_homing_rate (axes_signals_t cycle, homing_mode_t mode)
|
||||
}
|
||||
|
||||
// Checks and reports if target array exceeds machine travel limits. Returns false if check failed.
|
||||
static bool check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian)
|
||||
static bool check_travel_limits (float *target, axes_signals_t axes, bool is_cartesian, work_envelope_t *envelope)
|
||||
{
|
||||
bool failed = false;
|
||||
uint_fast8_t idx = N_AXIS;
|
||||
@@ -671,7 +671,7 @@ static bool check_travel_limits (float *target, axes_signals_t axes, bool is_car
|
||||
if(is_cartesian && (sys.homed.mask & axes.mask)) do {
|
||||
idx--;
|
||||
if(bit_istrue(sys.homed.mask, bit(idx)) && bit_istrue(axes.mask, bit(idx)))
|
||||
failed = target[idx] < sys.work_envelope.min.values[idx] || target[idx] > sys.work_envelope.max.values[idx];
|
||||
failed = target[idx] < envelope->min.values[idx] || target[idx] > envelope->max.values[idx];
|
||||
} while(!failed && idx);
|
||||
|
||||
return is_cartesian && !failed;
|
||||
@@ -679,7 +679,7 @@ static bool check_travel_limits (float *target, axes_signals_t axes, bool is_car
|
||||
|
||||
// Checks and reports if the arc exceeds machine travel limits. Returns false if check failed.
|
||||
// NOTE: needs the work envelope to be a cuboid!
|
||||
static bool check_arc_travel_limits (coord_data_t *target, coord_data_t *position, point_2d_t center, float radius, plane_t plane, int32_t turns)
|
||||
static bool check_arc_travel_limits (coord_data_t *target, coord_data_t *position, point_2d_t center, float radius, plane_t plane, int32_t turns, work_envelope_t *envelope)
|
||||
{
|
||||
typedef union {
|
||||
uint_fast8_t value;
|
||||
@@ -694,7 +694,7 @@ static bool check_arc_travel_limits (coord_data_t *target, coord_data_t *positio
|
||||
static const axes_signals_t xyz = { .x = On, .y = On, .z = On };
|
||||
|
||||
if((sys.soft_limits.mask & xyz.mask) == 0)
|
||||
return grbl.check_travel_limits(target->values, sys.soft_limits, true);
|
||||
return grbl.check_travel_limits(target->values, sys.soft_limits, true, envelope);
|
||||
|
||||
arc_x_t x = {0};
|
||||
point_2d_t start, end;
|
||||
@@ -764,14 +764,14 @@ static bool check_arc_travel_limits (coord_data_t *target, coord_data_t *positio
|
||||
corner1.values[plane.axis_0] = x.neg_x ? center.x - radius : min(position->values[plane.axis_0], target->values[plane.axis_0]);
|
||||
corner1.values[plane.axis_1] = x.neg_y ? center.y - radius : max(position->values[plane.axis_1], target->values[plane.axis_1]);
|
||||
|
||||
if(!grbl.check_travel_limits(corner1.values, sys.soft_limits, true))
|
||||
if(!grbl.check_travel_limits(corner1.values, sys.soft_limits, true, envelope))
|
||||
return false;
|
||||
|
||||
memcpy(&corner2, turns > 0 ? target : position, sizeof(coord_data_t));
|
||||
corner2.values[plane.axis_0] = x.pos_x ? center.x + radius : max(position->values[plane.axis_0], target->values[plane.axis_0]);
|
||||
corner2.values[plane.axis_1] = x.pos_y ? center.y + radius : min(position->values[plane.axis_1], target->values[plane.axis_1]);
|
||||
|
||||
return grbl.check_travel_limits(corner2.values, sys.soft_limits, true);
|
||||
return grbl.check_travel_limits(corner2.values, sys.soft_limits, true, envelope);
|
||||
}
|
||||
|
||||
// Derived from code by Dimitrios Matthes & Vasileios Drakopoulos
|
||||
@@ -815,7 +815,7 @@ static void clip_3d_target (coord_data_t *position, coord_data_t *target, work_e
|
||||
|
||||
// Limits jog commands to be within machine limits, homed axes only.
|
||||
// If position is non-null clip XYZ motion.
|
||||
static void apply_travel_limits (float *target, float *position)
|
||||
static void apply_travel_limits (float *target, float *position, work_envelope_t *envelope)
|
||||
{
|
||||
if(sys.homed.mask == 0)
|
||||
return;
|
||||
@@ -834,14 +834,14 @@ static void apply_travel_limits (float *target, float *position)
|
||||
} while(idx && n_axes < 2);
|
||||
|
||||
if(n_axes > 1)
|
||||
clip_3d_target((coord_data_t *)position, (coord_data_t *)target, &sys.work_envelope);
|
||||
clip_3d_target((coord_data_t *)position, (coord_data_t *)target, envelope);
|
||||
}
|
||||
|
||||
idx = N_AXIS;
|
||||
do {
|
||||
idx--;
|
||||
if(bit_istrue(sys.homed.mask, bit(idx)) && settings.axis[idx].max_travel < -0.0f)
|
||||
target[idx] = max(min(target[idx], sys.work_envelope.max.values[idx]), sys.work_envelope.min.values[idx]);
|
||||
target[idx] = max(min(target[idx], envelope->max.values[idx]), envelope->min.values[idx]);
|
||||
} while(idx);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -246,7 +246,7 @@ void mc_arc (float *target, plan_line_data_t *pl_data, float *position, float *o
|
||||
pl_data->condition.target_validated = On;
|
||||
pl_data->condition.target_valid = grbl.check_arc_travel_limits((coord_data_t *)target, (coord_data_t *)position,
|
||||
(point_2d_t){ .x = (float)center.x, .y = (float)center.y },
|
||||
radius, plane, turns);
|
||||
radius, plane, turns, &sys.work_envelope);
|
||||
}
|
||||
|
||||
if(labs(turns) > 1) {
|
||||
@@ -795,8 +795,8 @@ status_code_t mc_jog_execute (plan_line_data_t *pl_data, parser_block_t *gc_bloc
|
||||
pl_data->line_number = gc_block->values.n;
|
||||
|
||||
if(settings.limits.flags.jog_soft_limited)
|
||||
grbl.apply_travel_limits(gc_block->values.xyz, position);
|
||||
else if(sys.soft_limits.mask && !grbl.check_travel_limits(gc_block->values.xyz, sys.soft_limits, true))
|
||||
grbl.apply_travel_limits(gc_block->values.xyz, position, &sys.work_envelope);
|
||||
else if(sys.soft_limits.mask && !grbl.check_travel_limits(gc_block->values.xyz, sys.soft_limits, true, &sys.work_envelope))
|
||||
return Status_TravelExceeded;
|
||||
|
||||
// Valid jog command. Plan, set state, and execute.
|
||||
@@ -987,7 +987,7 @@ gc_probe_t mc_probe_cycle (float *target, plan_line_data_t *pl_data, gc_parser_f
|
||||
return GCProbe_CheckMode;
|
||||
|
||||
if(settings.probe.soft_limited)
|
||||
grbl.apply_travel_limits(target, NULL);
|
||||
grbl.apply_travel_limits(target, NULL, &sys.work_envelope);
|
||||
|
||||
do {
|
||||
idx--;
|
||||
|
||||
+1
-1
@@ -631,7 +631,7 @@ static bool spindle_set_state_wait (spindle_ptrs_t *spindle, spindle_state_t sta
|
||||
|
||||
if((ok = spindle_set_state(spindle, state, rpm))) {
|
||||
|
||||
bool at_speed = !state.on || spindle->cap.torch || !spindle->cap.at_speed || spindle->at_speed_tolerance <= 0.0f;
|
||||
bool at_speed = !spindle->cap.at_speed || spindle->cap.torch || spindle->at_speed_tolerance <= 0.0f;
|
||||
|
||||
if(at_speed)
|
||||
ok = delay_ms == 0 || spindle->cap.torch || delay_sec((float)delay_ms / 1000.0f, delay_mode);
|
||||
|
||||
Reference in New Issue
Block a user