✨ INPUT_SHAPING_Z (#27073)
This commit is contained in:
@@ -281,20 +281,16 @@ uint32_t Stepper::advance_divisor = 0,
|
||||
shaping_echo_axis_t ShapingQueue::echo_axes[shaping_echoes];
|
||||
uint16_t ShapingQueue::tail = 0;
|
||||
|
||||
#if ENABLED(INPUT_SHAPING_X)
|
||||
shaping_time_t ShapingQueue::delay_x;
|
||||
shaping_time_t ShapingQueue::peek_x_val = shaping_time_t(-1);
|
||||
uint16_t ShapingQueue::head_x = 0;
|
||||
uint16_t ShapingQueue::_free_count_x = shaping_echoes - 1;
|
||||
ShapeParams Stepper::shaping_x;
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
shaping_time_t ShapingQueue::delay_y;
|
||||
shaping_time_t ShapingQueue::peek_y_val = shaping_time_t(-1);
|
||||
uint16_t ShapingQueue::head_y = 0;
|
||||
uint16_t ShapingQueue::_free_count_y = shaping_echoes - 1;
|
||||
ShapeParams Stepper::shaping_y;
|
||||
#endif
|
||||
#define SHAPING_VAR_DEFS(AXIS) \
|
||||
shaping_time_t ShapingQueue::delay_##AXIS; \
|
||||
shaping_time_t ShapingQueue::_peek_##AXIS = shaping_time_t(-1); \
|
||||
uint16_t ShapingQueue::head_##AXIS = 0; \
|
||||
uint16_t ShapingQueue::_free_count_##AXIS = shaping_echoes - 1; \
|
||||
ShapeParams Stepper::shaping_##AXIS;
|
||||
|
||||
TERN_(INPUT_SHAPING_X, SHAPING_VAR_DEFS(x))
|
||||
TERN_(INPUT_SHAPING_Y, SHAPING_VAR_DEFS(y))
|
||||
TERN_(INPUT_SHAPING_Z, SHAPING_VAR_DEFS(z))
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
@@ -1610,6 +1606,7 @@ void Stepper::isr() {
|
||||
interval = _MIN(nextMainISR, uint32_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase
|
||||
TERN_(INPUT_SHAPING_X, NOMORE(interval, ShapingQueue::peek_x())); // Time until next input shaping echo for X
|
||||
TERN_(INPUT_SHAPING_Y, NOMORE(interval, ShapingQueue::peek_y())); // Time until next input shaping echo for Y
|
||||
TERN_(INPUT_SHAPING_Z, NOMORE(interval, ShapingQueue::peek_z())); // Time until next input shaping echo for Z
|
||||
TERN_(LIN_ADVANCE, NOMORE(interval, nextAdvanceISR)); // Come back early for Linear Advance?
|
||||
TERN_(BABYSTEPPING, NOMORE(interval, nextBabystepISR)); // Come back early for Babystepping?
|
||||
|
||||
@@ -1754,6 +1751,10 @@ void Stepper::pulse_phase_isr() {
|
||||
shaping_y.delta_error = 0;
|
||||
shaping_y.last_block_end_pos = count_position.y;
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
shaping_z.delta_error = 0;
|
||||
shaping_z.last_block_end_pos = count_position.z;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1813,6 +1814,12 @@ void Stepper::pulse_phase_isr() {
|
||||
#else
|
||||
#define HYSTERESIS_Y 0
|
||||
#endif
|
||||
#if AXIS_DRIVER_TYPE_Z(TMC2208) || AXIS_DRIVER_TYPE_Z(TMC2208_STANDALONE) || \
|
||||
AXIS_DRIVER_TYPE_Z(TMC5160) || AXIS_DRIVER_TYPE_Z(TMC5160_STANDALONE)
|
||||
#define HYSTERESIS_Z 64
|
||||
#else
|
||||
#define HYSTERESIS_Z 0
|
||||
#endif
|
||||
#define _HYSTERESIS(AXIS) HYSTERESIS_##AXIS
|
||||
#define HYSTERESIS(AXIS) _HYSTERESIS(AXIS)
|
||||
|
||||
@@ -2005,9 +2012,10 @@ void Stepper::pulse_phase_isr() {
|
||||
#if HAS_ZV_SHAPING
|
||||
// record an echo if a step is needed in the primary bresenham
|
||||
const bool x_step = TERN0(INPUT_SHAPING_X, step_needed.x && shaping_x.enabled),
|
||||
y_step = TERN0(INPUT_SHAPING_Y, step_needed.y && shaping_y.enabled);
|
||||
if (x_step || y_step)
|
||||
ShapingQueue::enqueue(x_step, TERN0(INPUT_SHAPING_X, shaping_x.forward), y_step, TERN0(INPUT_SHAPING_Y, shaping_y.forward));
|
||||
y_step = TERN0(INPUT_SHAPING_Y, step_needed.y && shaping_y.enabled),
|
||||
z_step = TERN0(INPUT_SHAPING_Z, step_needed.z && shaping_z.enabled);
|
||||
if (x_step || y_step || z_step)
|
||||
ShapingQueue::enqueue(x_step, TERN0(INPUT_SHAPING_X, shaping_x.forward), y_step, TERN0(INPUT_SHAPING_Y, shaping_y.forward), z_step, TERN0(INPUT_SHAPING_Z, shaping_z.forward));
|
||||
|
||||
// do the first part of the secondary bresenham
|
||||
#if ENABLED(INPUT_SHAPING_X)
|
||||
@@ -2018,6 +2026,10 @@ void Stepper::pulse_phase_isr() {
|
||||
if (y_step)
|
||||
PULSE_PREP_SHAPING(Y, shaping_y.delta_error, shaping_y.forward ? shaping_y.factor1 : -shaping_y.factor1);
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
if (z_step)
|
||||
PULSE_PREP_SHAPING(Z, shaping_z.delta_error, shaping_z.forward ? shaping_z.factor1 : -shaping_z.factor1);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2124,6 +2136,7 @@ void Stepper::pulse_phase_isr() {
|
||||
// Clear the echoes that are ready to process. If the buffers are too full and risk overflow, also apply echoes early.
|
||||
TERN_(INPUT_SHAPING_X, step_needed.x = !ShapingQueue::peek_x() || ShapingQueue::free_count_x() < steps_per_isr);
|
||||
TERN_(INPUT_SHAPING_Y, step_needed.y = !ShapingQueue::peek_y() || ShapingQueue::free_count_y() < steps_per_isr);
|
||||
TERN_(INPUT_SHAPING_Z, step_needed.z = !ShapingQueue::peek_z() || ShapingQueue::free_count_z() < steps_per_isr);
|
||||
|
||||
if (bool(step_needed)) while (true) {
|
||||
#if ENABLED(INPUT_SHAPING_X)
|
||||
@@ -2142,6 +2155,14 @@ void Stepper::pulse_phase_isr() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
if (step_needed.z) {
|
||||
const bool forward = ShapingQueue::dequeue_z();
|
||||
PULSE_PREP_SHAPING(Z, shaping_z.delta_error, (forward ? shaping_z.factor2 : -shaping_z.factor2));
|
||||
PULSE_START(Z);
|
||||
}
|
||||
#endif
|
||||
|
||||
TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
|
||||
|
||||
USING_TIMED_PULSE();
|
||||
@@ -2156,10 +2177,14 @@ void Stepper::pulse_phase_isr() {
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
PULSE_STOP(Y);
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
PULSE_STOP(Z);
|
||||
#endif
|
||||
}
|
||||
|
||||
TERN_(INPUT_SHAPING_X, step_needed.x = !ShapingQueue::peek_x() || ShapingQueue::free_count_x() < steps_per_isr);
|
||||
TERN_(INPUT_SHAPING_Y, step_needed.y = !ShapingQueue::peek_y() || ShapingQueue::free_count_y() < steps_per_isr);
|
||||
TERN_(INPUT_SHAPING_Z, step_needed.z = !ShapingQueue::peek_z() || ShapingQueue::free_count_z() < steps_per_isr);
|
||||
|
||||
if (!bool(step_needed)) break;
|
||||
|
||||
@@ -2708,7 +2733,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Y follows the same logic as X (but the comments aren't repeated)
|
||||
// Y and Z follow the same logic as X (but the comments aren't repeated)
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
if (shaping_y.enabled) {
|
||||
const int64_t steps = current_block->direction_bits.y ? int64_t(current_block->steps.y) : -int64_t(current_block->steps.y);
|
||||
@@ -2718,6 +2743,15 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
if (shaping_z.enabled) {
|
||||
const int64_t steps = current_block->direction_bits.z ? int64_t(current_block->steps.z) : -int64_t(current_block->steps.z);
|
||||
shaping_z.last_block_end_pos += steps;
|
||||
shaping_z.forward = current_block->direction_bits.z;
|
||||
if (!ShapingQueue::empty_z()) current_block->direction_bits.z = last_direction_bits.z;
|
||||
}
|
||||
#endif
|
||||
|
||||
// No step events completed so far
|
||||
step_events_completed = 0;
|
||||
|
||||
@@ -3220,12 +3254,14 @@ void Stepper::init() {
|
||||
hal.isr_off();
|
||||
TERN_(INPUT_SHAPING_X, if (axis == X_AXIS) { shaping_x.factor2 = factor2; shaping_x.factor1 = 128 - factor2; shaping_x.zeta = zeta; })
|
||||
TERN_(INPUT_SHAPING_Y, if (axis == Y_AXIS) { shaping_y.factor2 = factor2; shaping_y.factor1 = 128 - factor2; shaping_y.zeta = zeta; })
|
||||
TERN_(INPUT_SHAPING_Z, if (axis == Z_AXIS) { shaping_z.factor2 = factor2; shaping_z.factor1 = 128 - factor2; shaping_z.zeta = zeta; })
|
||||
if (was_on) hal.isr_on();
|
||||
}
|
||||
|
||||
float Stepper::get_shaping_damping_ratio(const AxisEnum axis) {
|
||||
TERN_(INPUT_SHAPING_X, if (axis == X_AXIS) return shaping_x.zeta);
|
||||
TERN_(INPUT_SHAPING_Y, if (axis == Y_AXIS) return shaping_y.zeta);
|
||||
TERN_(INPUT_SHAPING_Z, if (axis == Z_AXIS) return shaping_z.zeta);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3237,24 +3273,18 @@ void Stepper::init() {
|
||||
hal.isr_off();
|
||||
|
||||
const shaping_time_t delay = freq ? float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1);
|
||||
#if ENABLED(INPUT_SHAPING_X)
|
||||
if (axis == X_AXIS) {
|
||||
ShapingQueue::set_delay(X_AXIS, delay);
|
||||
shaping_x.frequency = freq;
|
||||
shaping_x.enabled = !!freq;
|
||||
shaping_x.delta_error = 0;
|
||||
shaping_x.last_block_end_pos = count_position.x;
|
||||
#define SHAPING_SET_FREQ_FOR_AXIS(AXISN, AXISL) \
|
||||
if (axis == AXISN) { \
|
||||
ShapingQueue::set_delay(AXISN, delay); \
|
||||
shaping_##AXISL.frequency = freq; \
|
||||
shaping_##AXISL.enabled = !!freq; \
|
||||
shaping_##AXISL.delta_error = 0; \
|
||||
shaping_##AXISL.last_block_end_pos = count_position.AXISL; \
|
||||
}
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
if (axis == Y_AXIS) {
|
||||
ShapingQueue::set_delay(Y_AXIS, delay);
|
||||
shaping_y.frequency = freq;
|
||||
shaping_y.enabled = !!freq;
|
||||
shaping_y.delta_error = 0;
|
||||
shaping_y.last_block_end_pos = count_position.y;
|
||||
}
|
||||
#endif
|
||||
|
||||
TERN_(INPUT_SHAPING_X, SHAPING_SET_FREQ_FOR_AXIS(X_AXIS, x))
|
||||
TERN_(INPUT_SHAPING_Y, SHAPING_SET_FREQ_FOR_AXIS(Y_AXIS, y))
|
||||
TERN_(INPUT_SHAPING_Z, SHAPING_SET_FREQ_FOR_AXIS(Z_AXIS, z))
|
||||
|
||||
if (was_on) hal.isr_on();
|
||||
}
|
||||
@@ -3262,6 +3292,7 @@ void Stepper::init() {
|
||||
float Stepper::get_shaping_frequency(const AxisEnum axis) {
|
||||
TERN_(INPUT_SHAPING_X, if (axis == X_AXIS) return shaping_x.frequency);
|
||||
TERN_(INPUT_SHAPING_Y, if (axis == Y_AXIS) return shaping_y.frequency);
|
||||
TERN_(INPUT_SHAPING_Z, if (axis == Z_AXIS) return shaping_z.frequency);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3283,6 +3314,9 @@ void Stepper::_set_position(const abce_long_t &spos) {
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
const int32_t y_shaping_delta = count_position.y - shaping_y.last_block_end_pos;
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
const int32_t z_shaping_delta = count_position.z - shaping_z.last_block_end_pos;
|
||||
#endif
|
||||
|
||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||
// Core equations follow the form of the dA and dB equations at https://www.corexy.com/theory.html
|
||||
@@ -3323,6 +3357,12 @@ void Stepper::_set_position(const abce_long_t &spos) {
|
||||
shaping_y.last_block_end_pos = spos.y;
|
||||
}
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
if (shaping_z.enabled) {
|
||||
count_position.z += z_shaping_delta;
|
||||
shaping_z.last_block_end_pos = spos.z;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3364,6 +3404,7 @@ void Stepper::set_axis_position(const AxisEnum a, const int32_t &v) {
|
||||
count_position[a] = v;
|
||||
TERN_(INPUT_SHAPING_X, if (a == X_AXIS) shaping_x.last_block_end_pos = v);
|
||||
TERN_(INPUT_SHAPING_Y, if (a == Y_AXIS) shaping_y.last_block_end_pos = v);
|
||||
TERN_(INPUT_SHAPING_Z, if (a == Z_AXIS) shaping_z.last_block_end_pos = v);
|
||||
|
||||
#ifdef __AVR__
|
||||
// Reenable Stepper ISR
|
||||
|
Reference in New Issue
Block a user