Skip to content

Commit e4b83ad

Browse files
thinkyheadtombrazier
andcommittedMar 13, 2023
⚡️ Major shaper optimization
Co-Authored-By: tombrazier <[email protected]>
1 parent e1a209d commit e4b83ad

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed
 

‎Marlin/src/module/stepper.cpp

+21-15
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,7 @@ void Stepper::pulse_phase_isr() {
16761676
int32_t de = delta_error[_AXIS(AXIS)] + advance_dividend[_AXIS(AXIS)]; \
16771677
if (de >= 0) { \
16781678
step_needed.set(_AXIS(AXIS)); \
1679-
de -= advance_divisor; \
1679+
de -= advance_divisor_cached; \
16801680
} \
16811681
delta_error[_AXIS(AXIS)] = de; \
16821682
}while(0)
@@ -1702,19 +1702,22 @@ void Stepper::pulse_phase_isr() {
17021702
#define HYSTERESIS(AXIS) _HYSTERESIS(AXIS)
17031703

17041704
#define PULSE_PREP_SHAPING(AXIS, DELTA_ERROR, DIVIDEND) do{ \
1705-
if (step_needed.test(_AXIS(AXIS))) { \
1706-
DELTA_ERROR += (DIVIDEND); \
1707-
if ((MAXDIR(AXIS) && DELTA_ERROR <= -(64 + HYSTERESIS(AXIS))) || (MINDIR(AXIS) && DELTA_ERROR >= (64 + HYSTERESIS(AXIS)))) { \
1705+
int16_t de = DELTA_ERROR + (DIVIDEND); \
1706+
const bool step_fwd = de >= (64 + HYSTERESIS(AXIS)), \
1707+
step_bak = de <= -(64 + HYSTERESIS(AXIS)); \
1708+
if (step_fwd || step_bak) { \
1709+
de += step_fwd ? -128 : 128; \
1710+
if ((MAXDIR(AXIS) && step_bak) || (MINDIR(AXIS) && step_fwd)) { \
17081711
{ USING_TIMED_PULSE(); START_TIMED_PULSE(); AWAIT_LOW_PULSE(); } \
17091712
TBI(last_direction_bits, _AXIS(AXIS)); \
17101713
DIR_WAIT_BEFORE(); \
17111714
SET_STEP_DIR(AXIS); \
17121715
DIR_WAIT_AFTER(); \
17131716
} \
1714-
step_needed.set(_AXIS(AXIS), DELTA_ERROR <= -(64 + HYSTERESIS(AXIS)) || DELTA_ERROR >= (64 + HYSTERESIS(AXIS))); \
1715-
if (step_needed.test(_AXIS(AXIS))) \
1716-
DELTA_ERROR += MAXDIR(AXIS) ? -128 : 128; \
17171717
} \
1718+
else \
1719+
step_needed.clear(_AXIS(AXIS)); \
1720+
DELTA_ERROR = de; \
17181721
}while(0)
17191722

17201723
// Start an active pulse if needed
@@ -1839,6 +1842,9 @@ void Stepper::pulse_phase_isr() {
18391842
#endif // DIRECT_STEPPING
18401843

18411844
if (!is_page) {
1845+
// Give the compiler a clue to store advance_divisor in registers for what follows
1846+
const uint32_t advance_divisor_cached = advance_divisor;
1847+
18421848
// Determine if pulses are needed
18431849
#if HAS_X_STEP
18441850
PULSE_PREP(X);
@@ -1883,19 +1889,19 @@ void Stepper::pulse_phase_isr() {
18831889

18841890
#if HAS_SHAPING
18851891
// record an echo if a step is needed in the primary bresenham
1886-
const bool x_step = TERN0(INPUT_SHAPING_X, shaping_x.enabled && step_needed.x),
1887-
y_step = TERN0(INPUT_SHAPING_Y, shaping_y.enabled && step_needed.y);
1892+
const bool x_step = TERN0(INPUT_SHAPING_X, step_needed.x && shaping_x.enabled),
1893+
y_step = TERN0(INPUT_SHAPING_Y, step_needed.y && shaping_y.enabled);
18881894
if (x_step || y_step)
18891895
ShapingQueue::enqueue(x_step, TERN0(INPUT_SHAPING_X, shaping_x.forward), y_step, TERN0(INPUT_SHAPING_Y, shaping_y.forward));
18901896

18911897
// do the first part of the secondary bresenham
18921898
#if ENABLED(INPUT_SHAPING_X)
1893-
if (shaping_x.enabled)
1894-
PULSE_PREP_SHAPING(X, shaping_x.delta_error, shaping_x.factor1 * (shaping_x.forward ? 1 : -1));
1899+
if (x_step)
1900+
PULSE_PREP_SHAPING(X, shaping_x.delta_error, shaping_x.forward ? shaping_x.factor1 : -shaping_x.factor1);
18951901
#endif
18961902
#if ENABLED(INPUT_SHAPING_Y)
1897-
if (shaping_y.enabled)
1898-
PULSE_PREP_SHAPING(Y, shaping_y.delta_error, shaping_y.factor1 * (shaping_y.forward ? 1 : -1));
1903+
if (y_step)
1904+
PULSE_PREP_SHAPING(Y, shaping_y.delta_error, shaping_y.forward ? shaping_y.factor1 : -shaping_y.factor1);
18991905
#endif
19001906
#endif
19011907
}
@@ -2008,15 +2014,15 @@ void Stepper::pulse_phase_isr() {
20082014
#if ENABLED(INPUT_SHAPING_X)
20092015
if (step_needed.x) {
20102016
const bool forward = ShapingQueue::dequeue_x();
2011-
PULSE_PREP_SHAPING(X, shaping_x.delta_error, shaping_x.factor2 * (forward ? 1 : -1));
2017+
PULSE_PREP_SHAPING(X, shaping_x.delta_error, (forward ? shaping_x.factor2 : -shaping_x.factor2));
20122018
PULSE_START(X);
20132019
}
20142020
#endif
20152021

20162022
#if ENABLED(INPUT_SHAPING_Y)
20172023
if (step_needed.y) {
20182024
const bool forward = ShapingQueue::dequeue_y();
2019-
PULSE_PREP_SHAPING(Y, shaping_y.delta_error, shaping_y.factor2 * (forward ? 1 : -1));
2025+
PULSE_PREP_SHAPING(Y, shaping_y.delta_error, (forward ? shaping_y.factor2 : -shaping_y.factor2));
20202026
PULSE_START(Y);
20212027
}
20222028
#endif

‎Marlin/src/module/stepper.h

+30-10
Original file line numberDiff line numberDiff line change
@@ -392,16 +392,36 @@ constexpr ena_mask_t enable_overlap[] = {
392392
TERN_(INPUT_SHAPING_Y, if (axis == Y_AXIS) delay_y = delay);
393393
}
394394
static void enqueue(const bool x_step, const bool x_forward, const bool y_step, const bool y_forward) {
395-
TERN_(INPUT_SHAPING_X, if (head_x == tail && x_step) peek_x_val = delay_x);
396-
TERN_(INPUT_SHAPING_Y, if (head_y == tail && y_step) peek_y_val = delay_y);
395+
#if ENABLED(INPUT_SHAPING_X)
396+
if (x_step) {
397+
if (head_x == tail) peek_x_val = delay_x;
398+
echo_axes[tail].x = x_forward ? ECHO_FWD : ECHO_BWD;
399+
_free_count_x--;
400+
}
401+
else {
402+
echo_axes[tail].x = ECHO_NONE;
403+
if (head_x != tail)
404+
_free_count_x--;
405+
else if (++head_x == shaping_echoes)
406+
head_x = 0;
407+
}
408+
#endif
409+
#if ENABLED(INPUT_SHAPING_Y)
410+
if (y_step) {
411+
if (head_y == tail) peek_y_val = delay_y;
412+
echo_axes[tail].y = y_forward ? ECHO_FWD : ECHO_BWD;
413+
_free_count_y--;
414+
}
415+
else {
416+
echo_axes[tail].y = ECHO_NONE;
417+
if (head_y != tail)
418+
_free_count_y--;
419+
else if (++head_y == shaping_echoes)
420+
head_y = 0;
421+
}
422+
#endif
397423
times[tail] = now;
398-
TERN_(INPUT_SHAPING_X, echo_axes[tail].x = x_step ? (x_forward ? ECHO_FWD : ECHO_BWD) : ECHO_NONE);
399-
TERN_(INPUT_SHAPING_Y, echo_axes[tail].y = y_step ? (y_forward ? ECHO_FWD : ECHO_BWD) : ECHO_NONE);
400424
if (++tail == shaping_echoes) tail = 0;
401-
TERN_(INPUT_SHAPING_X, _free_count_x--);
402-
TERN_(INPUT_SHAPING_Y, _free_count_y--);
403-
TERN_(INPUT_SHAPING_X, if (echo_axes[head_x].x == ECHO_NONE) dequeue_x());
404-
TERN_(INPUT_SHAPING_Y, if (echo_axes[head_y].y == ECHO_NONE) dequeue_y());
405425
}
406426
#if ENABLED(INPUT_SHAPING_X)
407427
static shaping_time_t peek_x() { return peek_x_val; }
@@ -445,11 +465,11 @@ constexpr ena_mask_t enable_overlap[] = {
445465
struct ShapeParams {
446466
float frequency;
447467
float zeta;
448-
bool enabled;
468+
bool enabled : 1;
469+
bool forward : 1;
449470
int16_t delta_error = 0; // delta_error for seconday bresenham mod 128
450471
uint8_t factor1;
451472
uint8_t factor2;
452-
bool forward;
453473
int32_t last_block_end_pos = 0;
454474
};
455475

0 commit comments

Comments
 (0)
Please sign in to comment.