From c8a6f816f41660da5023659c12bbf53f7f69ddd3 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Fri, 5 May 2023 03:03:33 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Replace=20a?= =?UTF-8?q?xis=5Fbits=5Ft=20with=20AxisBits=20class=20(#25761)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/core/types.h | 152 +++++++++++++++++++++++++++++++- Marlin/src/feature/backlash.cpp | 36 ++++---- Marlin/src/feature/backlash.h | 4 +- Marlin/src/feature/runout.h | 2 +- Marlin/src/module/ft_motion.cpp | 10 +-- Marlin/src/module/planner.cpp | 60 ++++++------- Marlin/src/module/planner.h | 2 +- Marlin/src/module/stepper.cpp | 70 ++++++--------- Marlin/src/module/stepper.h | 16 ++-- 9 files changed, 239 insertions(+), 113 deletions(-) diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index af6834c666b3e..c403e7439e2b4 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -199,8 +199,6 @@ enum AxisEnum : uint8_t { , ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF }; -typedef bits_t(NUM_AXIS_ENUMS) axis_bits_t; - // // Loop over axes // @@ -789,6 +787,156 @@ struct XYZEval { FI bool operator!=(const XYZEval &rs) const { return !operator==(rs); } }; +#include // for memset + +class AxisBits; + +class AxisBits { +public: + typedef bits_t(NUM_AXIS_ENUMS) el; + union { + el bits; + struct { + union { + bool NUM_AXIS_LIST(x:1, y:1, z:1, i:1, j:1, k:1, u:1, v:1, w:1); + bool NUM_AXIS_LIST(X:1, Y:1, Z:1, I:1, J:1, K:1, U:1, V:1, W:1); + bool NUM_AXIS_LIST(a:1, b:1, c:1, _i:1, _j:1, _k:1, _u:1, _v:1, _w:1); + bool NUM_AXIS_LIST(A:1, B:1, C:1, _I:1, _J:1, _K:1, _U:1, _V:1, _W:1); + }; + #if HAS_EXTRUDERS + union { bool e:1; bool e0:1; }; + #define _EN_ITEM(N) bool e##N:1; + REPEAT_S(1,EXTRUDERS,_EN_ITEM) + #undef _EN_ITEM + #endif + #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) + bool hx:1, hy:1, hz:1; + #endif + }; + }; + + AxisBits() { bits = 0; } + + // Constructor, setter, and operator= for bit mask + AxisBits(const el p) { set(p); } + void set(const el p) { bits = el(p); } + FI AxisBits& operator=(const el p) { set(p); return *this; } + + #define MSET(pE,pX,pY,pZ,pI,pJ,pK,pU,pV,pW) LOGICAL_AXIS_CODE(e=pE, x=pX, y=pY, z=pZ, i=pI, j=pJ, k=pK, u=pU, v=pV, w=pW) + + // Constructor, setter, and operator= for XYZE type + AxisBits(const xyze_bool_t &p) { set(p); } + void set(const xyze_bool_t &p) { + MSET(p.e, p.x, p.y, p.z, p.i, p.j, p.k, p.u, p.v, p.w); + } + FI AxisBits& operator=(const xyze_bool_t &p) { set(p); return *this; } + + // Constructor, setter, and operator= for bool array + AxisBits(const bool (&p)[LOGICAL_AXES]) { set(p); } + void set(const bool (&p)[LOGICAL_AXES]) { + MSET(p[E_AXIS], p[X_AXIS], p[Y_AXIS], p[Z_AXIS], + p[I_AXIS], p[J_AXIS], p[K_AXIS], + p[U_AXIS], p[V_AXIS], p[W_AXIS]); + } + FI AxisBits& operator=(const bool (&p)[LOGICAL_AXES]) { set(p); return *this; } + + // Constructor, setter, and operator= for undersized bool arrays + #if LOGICAL_AXES > 1 + AxisBits(const bool (&p)[1]) { set(p); } + FI void set(const bool (&p)[1]) { + MSET(0, p[X_AXIS], 0, 0, 0, 0, 0, 0, 0, 0); + } + FI AxisBits& operator=(const bool (&p)[1]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 2 + AxisBits(const bool (&p)[2]) { set(p); } + FI void set(const bool (&p)[2]) { + MSET(0, p[X_AXIS], p[Y_AXIS], 0, 0, 0, 0, 0, 0, 0); + } + FI AxisBits& operator=(const bool (&p)[2]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 3 + AxisBits(const bool (&p)[3]) { set(p); } + FI void set(const bool (&p)[3]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], 0, 0, 0, 0, 0, 0); + } + FI AxisBits& operator=(const bool (&p)[3]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 4 + AxisBits(const bool (&p)[4]) { set(p); } + FI void set(const bool (&p)[4]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], p[I_AXIS], 0, 0, 0, 0, 0); + } + FI AxisBits& operator=(const bool (&p)[4]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 5 + AxisBits(const bool (&p)[5]) { set(p); } + FI void set(const bool (&p)[5]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], p[I_AXIS], p[J_AXIS], 0, 0, 0, 0); + } + FI AxisBits& operator=(const bool (&p)[5]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 6 + AxisBits(const bool (&p)[6]) { set(p); } + FI void set(const bool (&p)[6]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], p[I_AXIS], p[J_AXIS], p[K_AXIS], 0, 0, 0); + } + FI AxisBits& operator=(const bool (&p)[6]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 7 + AxisBits(const bool (&p)[7]) { set(p); } + FI void set(const bool (&p)[7]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], p[I_AXIS], p[J_AXIS], p[K_AXIS], p[U_AXIS], 0, 0); + } + FI AxisBits& operator=(const bool (&p)[7]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 8 + AxisBits(const bool (&p)[8]) { set(p); } + FI void set(const bool (&p)[8]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], p[I_AXIS], p[J_AXIS], p[K_AXIS], p[U_AXIS], p[V_AXIS], 0); + } + FI AxisBits& operator=(const bool (&p)[8]) { set(p); return *this; } + #endif + #if LOGICAL_AXES > 9 + AxisBits(const bool (&p)[9]) { set(p); } + FI void set(const bool (&p)[9]) { + MSET(0, p[X_AXIS], p[Y_AXIS], p[Z_AXIS], p[I_AXIS], p[J_AXIS], p[K_AXIS], p[U_AXIS], p[V_AXIS], p[W_AXIS]); + } + FI AxisBits& operator=(const bool (&p)[9]) { set(p); return *this; } + #endif + #undef MSET + + FI const bool toggle(const AxisEnum n) { return TBI(bits, n); } + + // Accessor via an AxisEnum (or any integer) [index] + FI const bool operator[](const int n) const { return TEST(bits, n); } + FI const bool operator[](const AxisEnum n) const { return TEST(bits, n); } + + FI AxisBits& operator|=(const el &p) { bits |= el(p); return *this; } + FI AxisBits& operator&=(const el &p) { bits &= el(p); return *this; } + FI AxisBits& operator^=(const el &p) { bits ^= el(p); return *this; } + + FI AxisBits& operator|=(const AxisBits &p) { bits |= p.bits; return *this; } + FI AxisBits& operator&=(const AxisBits &p) { bits &= p.bits; return *this; } + FI AxisBits& operator^=(const AxisBits &p) { bits ^= p.bits; return *this; } + + FI bool operator==(const AxisBits &p) const { return p.bits == bits; } + FI bool operator!=(const AxisBits &p) const { return p.bits != bits; } + + FI el operator|(const el &p) const { return bits | el(p); } + FI el operator&(const el &p) const { return bits & el(p); } + FI el operator^(const el &p) const { return bits ^ el(p); } + + FI AxisBits operator|(const AxisBits &p) const { return AxisBits(bits | p.bits); } + FI AxisBits operator&(const AxisBits &p) const { return AxisBits(bits & p.bits); } + FI AxisBits operator^(const AxisBits &p) const { return AxisBits(bits ^ p.bits); } + + FI operator bool() const { return !!bits; } + FI operator uint16_t() const { return uint16_t(bits & 0xFFFF); } + FI operator uint32_t() const { return uint32_t(bits); } + +}; + #undef _RECIP #undef _ABS #undef _LS diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp index 13e2cd99eccb6..256488762a7d2 100644 --- a/Marlin/src/feature/backlash.cpp +++ b/Marlin/src/feature/backlash.cpp @@ -29,7 +29,7 @@ #include "../module/motion.h" #include "../module/planner.h" -axis_bits_t Backlash::last_direction_bits; +AxisBits Backlash::last_direction_bits; xyz_long_t Backlash::residual_error{0}; #ifdef BACKLASH_DISTANCE_MM @@ -63,25 +63,25 @@ Backlash backlash; * spread over multiple segments, smoothing out artifacts even more. */ -void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block) { - axis_bits_t changed_dir = last_direction_bits ^ dm; +void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const AxisBits dm, block_t * const block) { + AxisBits changed_dir = last_direction_bits ^ dm; // Ignore direction change unless steps are taken in that direction #if DISABLED(CORE_BACKLASH) || EITHER(MARKFORGED_XY, MARKFORGED_YX) - if (!da) CBI(changed_dir, X_AXIS); - if (!db) CBI(changed_dir, Y_AXIS); - if (!dc) CBI(changed_dir, Z_AXIS); + if (!da) changed_dir.x = false; + if (!db) changed_dir.y = false; + if (!dc) changed_dir.z = false; #elif CORE_IS_XY - if (!(da + db)) CBI(changed_dir, X_AXIS); - if (!(da - db)) CBI(changed_dir, Y_AXIS); - if (!dc) CBI(changed_dir, Z_AXIS); + if (!(da + db)) changed_dir.x = false; + if (!(da - db)) changed_dir.y = false; + if (!dc) changed_dir.z = false; #elif CORE_IS_XZ - if (!(da + dc)) CBI(changed_dir, X_AXIS); - if (!(da - dc)) CBI(changed_dir, Z_AXIS); - if (!db) CBI(changed_dir, Y_AXIS); + if (!(da + dc)) changed_dir.x = false; + if (!(da - dc)) changed_dir.z = false; + if (!db) changed_dir.y = false; #elif CORE_IS_YZ - if (!(db + dc)) CBI(changed_dir, Y_AXIS); - if (!(db - dc)) CBI(changed_dir, Z_AXIS); - if (!da) CBI(changed_dir, X_AXIS); + if (!(db + dc)) changed_dir.y = false; + if (!(db - dc)) changed_dir.z = false; + if (!da) changed_dir.x = false; #endif last_direction_bits ^= changed_dir; @@ -99,10 +99,10 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const LOOP_NUM_AXES(axis) { if (distance_mm[axis]) { - const bool reverse = TEST(dm, axis); + const bool reverse = dm[axis]; // When an axis changes direction, add axis backlash to the residual error - if (TEST(changed_dir, axis)) + if (changed_dir[axis]) residual_error[axis] += (reverse ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; // Decide how much of the residual error to correct in this segment @@ -147,7 +147,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const int32_t Backlash::get_applied_steps(const AxisEnum axis) { if (axis >= NUM_AXES) return 0; - const bool reverse = TEST(last_direction_bits, axis); + const bool reverse = last_direction_bits[axis]; const int32_t residual_error_axis = residual_error[axis]; diff --git a/Marlin/src/feature/backlash.h b/Marlin/src/feature/backlash.h index 0bace526e53f4..14c0fe20e378e 100644 --- a/Marlin/src/feature/backlash.h +++ b/Marlin/src/feature/backlash.h @@ -29,7 +29,7 @@ class Backlash { static constexpr uint8_t all_on = 0xFF, all_off = 0x00; private: - static axis_bits_t last_direction_bits; + static AxisBits last_direction_bits; static xyz_long_t residual_error; #if ENABLED(BACKLASH_GCODE) @@ -72,7 +72,7 @@ class Backlash { return has_measurement(X_AXIS) || has_measurement(Y_AXIS) || has_measurement(Z_AXIS); } - static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const axis_bits_t dm, block_t * const block); + static void add_correction_steps(const int32_t &da, const int32_t &db, const int32_t &dc, const AxisBits dm, block_t * const block); static int32_t get_applied_steps(const AxisEnum axis); #if ENABLED(BACKLASH_GCODE) diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index fb4d0c269479f..e6ca9f78cdd9f 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -411,7 +411,7 @@ class FilamentSensorBase { // Only trigger on extrusion with XYZ movement to allow filament change and retract/recover. const uint8_t e = b->extruder; const int32_t steps = b->steps.e; - const float mm = (TEST(b->direction_bits, E_AXIS) ? -steps : steps) * planner.mm_per_step[E_AXIS_N(e)]; + const float mm = (b->direction_bits.e ? -steps : steps) * planner.mm_per_step[E_AXIS_N(e)]; if (e < NUM_RUNOUT_SENSORS) mm_countdown.runout[e] -= mm; #if ENABLED(FILAMENT_SWITCH_AND_MOTION) if (e < NUM_MOTION_SENSORS) mm_countdown.motion[e] -= mm; diff --git a/Marlin/src/module/ft_motion.cpp b/Marlin/src/module/ft_motion.cpp index dfef961c7968a..2fe38025296d3 100644 --- a/Marlin/src/module/ft_motion.cpp +++ b/Marlin/src/module/ft_motion.cpp @@ -484,33 +484,33 @@ void FxdTiCtrl::loadBlockData(block_t * const current_block) { const float totalLength = current_block->millimeters, oneOverLength = 1.0f / totalLength; - const axis_bits_t direction = current_block->direction_bits; + const AxisBits direction = current_block->direction_bits; #if HAS_X_AXIS x_startPosn = x_endPosn_prevBlock; float x_moveDist = current_block->steps.a / planner.settings.axis_steps_per_mm[X_AXIS]; - if (TEST(direction, X_AXIS)) x_moveDist *= -1.0f; + if (direction.x) x_moveDist *= -1.0f; x_Ratio = x_moveDist * oneOverLength; #endif #if HAS_Y_AXIS y_startPosn = y_endPosn_prevBlock; float y_moveDist = current_block->steps.b / planner.settings.axis_steps_per_mm[Y_AXIS]; - if (TEST(direction, Y_AXIS)) y_moveDist *= -1.0f; + if (direction.y) y_moveDist *= -1.0f; y_Ratio = y_moveDist * oneOverLength; #endif #if HAS_Z_AXIS z_startPosn = z_endPosn_prevBlock; float z_moveDist = current_block->steps.c / planner.settings.axis_steps_per_mm[Z_AXIS]; - if (TEST(direction, Z_AXIS)) z_moveDist *= -1.0f; + if (direction.z) z_moveDist *= -1.0f; z_Ratio = z_moveDist * oneOverLength; #endif #if HAS_EXTRUDERS e_startPosn = e_endPosn_prevBlock; float extrusion = current_block->steps.e / planner.settings.axis_steps_per_mm[E_AXIS_N(current_block->extruder)]; - if (TEST(direction, E_AXIS_N(current_block->extruder))) extrusion *= -1.0f; + if (direction.e) extrusion *= -1.0f; e_Ratio = extrusion * oneOverLength; #endif diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index ccf27a502ac13..52519b805c1b5 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -1968,54 +1968,50 @@ bool Planner::_populate_block( #endif // PREVENT_COLD_EXTRUSION || PREVENT_LENGTHY_EXTRUDE // Compute direction bit-mask for this block - axis_bits_t dm = 0; + AxisBits dm; #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X - if (db < 0) SBI(dm, Y_HEAD); // ...and Y - TERN_(HAS_Z_AXIS, if (dc < 0) SBI(dm, Z_AXIS)); + dm.hx = (da < 0); // Save the toolhead's true direction in X + dm.hy = (db < 0); // ...and Y + TERN_(HAS_Z_AXIS, dm.z = (dc < 0)); #endif #if IS_CORE #if CORE_IS_XY - if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction - if (CORESIGN(da - db) < 0) SBI(dm, B_AXIS); // Motor B direction + dm.a = (da + db < 0); // Motor A direction + dm.b = (CORESIGN(da - db) < 0); // Motor B direction #elif CORE_IS_XZ - if (da < 0) SBI(dm, X_HEAD); // Save the toolhead's true direction in X - if (db < 0) SBI(dm, Y_AXIS); - if (dc < 0) SBI(dm, Z_HEAD); // ...and Z - if (da + dc < 0) SBI(dm, A_AXIS); // Motor A direction - if (CORESIGN(da - dc) < 0) SBI(dm, C_AXIS); // Motor C direction + dm.hx = (da < 0); // Save the toolhead's true direction in X + dm.y = (db < 0); + dm.hz = (dc < 0); // ...and Z + dm.a = (da + dc < 0); // Motor A direction + dm.c = (CORESIGN(da - dc) < 0); // Motor C direction #elif CORE_IS_YZ - if (da < 0) SBI(dm, X_AXIS); - if (db < 0) SBI(dm, Y_HEAD); // Save the toolhead's true direction in Y - if (dc < 0) SBI(dm, Z_HEAD); // ...and Z - if (db + dc < 0) SBI(dm, B_AXIS); // Motor B direction - if (CORESIGN(db - dc) < 0) SBI(dm, C_AXIS); // Motor C direction + dm.x = (da < 0); + dm.hy = (db < 0); // Save the toolhead's true direction in Y + dm.hz = (dc < 0); // ...and Z + dm.b = (db + dc < 0); // Motor B direction + dm.c = (CORESIGN(db - dc) < 0); // Motor C direction #endif #elif ENABLED(MARKFORGED_XY) - if (da + db < 0) SBI(dm, A_AXIS); // Motor A direction - if (db < 0) SBI(dm, B_AXIS); // Motor B direction + dm.a = (da + db < 0); // Motor A direction + dm.b = (db < 0); // Motor B direction #elif ENABLED(MARKFORGED_YX) - if (da < 0) SBI(dm, A_AXIS); // Motor A direction - if (db + da < 0) SBI(dm, B_AXIS); // Motor B direction + dm.a = (da < 0); // Motor A direction + dm.b = (db + da < 0); // Motor B direction #else XYZ_CODE( - if (da < 0) SBI(dm, X_AXIS), - if (db < 0) SBI(dm, Y_AXIS), - if (dc < 0) SBI(dm, Z_AXIS) + dm.x = (da < 0), + dm.y = (db < 0), + dm.z = (dc < 0) ); #endif SECONDARY_AXIS_CODE( - if (di < 0) SBI(dm, I_AXIS), - if (dj < 0) SBI(dm, J_AXIS), - if (dk < 0) SBI(dm, K_AXIS), - if (du < 0) SBI(dm, U_AXIS), - if (dv < 0) SBI(dm, V_AXIS), - if (dw < 0) SBI(dm, W_AXIS) + dm.i = (di < 0), dm.j = (dj < 0), dm.k = (dk < 0), + dm.u = (du < 0), dm.v = (dv < 0), dm.w = (dw < 0) ); #if HAS_EXTRUDERS - if (de < 0) SBI(dm, E_AXIS); + dm.e = (de < 0); const float esteps_float = de * e_factor[extruder]; const uint32_t esteps = ABS(esteps_float) + 0.5f; #else @@ -2435,11 +2431,11 @@ bool Planner::_populate_block( #ifdef XY_FREQUENCY_LIMIT - static axis_bits_t old_direction_bits; // = 0 + static AxisBits old_direction_bits; // = 0 if (xy_freq_limit_hz) { // Check and limit the xy direction change frequency - const axis_bits_t direction_change = block->direction_bits ^ old_direction_bits; + const AxisBits direction_change = block->direction_bits ^ old_direction_bits; old_direction_bits = block->direction_bits; segment_time_us = LROUND(float(segment_time_us) / speed_factor); diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index e072e94dbd862..eb0f072f4bf07 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -246,7 +246,7 @@ typedef struct PlannerBlock { uint32_t acceleration_rate; // The acceleration rate used for acceleration calculation #endif - axis_bits_t direction_bits; // Direction bits set for this block, where 1 is negative motion + AxisBits direction_bits; // Direction bits set for this block, where 1 is negative motion // Advance extrusion #if ENABLED(LIN_ADVANCE) diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 8a4d801e76559..140a539ef36cc 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -166,8 +166,8 @@ stepper_flags_t Stepper::axis_enabled; // {0} block_t* Stepper::current_block; // (= nullptr) A pointer to the block currently being traced -axis_bits_t Stepper::last_direction_bits, // = 0 - Stepper::axis_did_move; // = 0 +AxisBits Stepper::last_direction_bits, // = 0 + Stepper::axis_did_move; // = 0 bool Stepper::abort_current_block; @@ -624,15 +624,11 @@ void Stepper::apply_directions() { DIR_WAIT_BEFORE(); - TERN_(HAS_X_DIR, SET_STEP_DIR(X)); // A - TERN_(HAS_Y_DIR, SET_STEP_DIR(Y)); // B - TERN_(HAS_Z_DIR, SET_STEP_DIR(Z)); // C - TERN_(HAS_I_DIR, SET_STEP_DIR(I)); - TERN_(HAS_J_DIR, SET_STEP_DIR(J)); - TERN_(HAS_K_DIR, SET_STEP_DIR(K)); - TERN_(HAS_U_DIR, SET_STEP_DIR(U)); - TERN_(HAS_V_DIR, SET_STEP_DIR(V)); - TERN_(HAS_W_DIR, SET_STEP_DIR(W)); + NUM_AXIS_CODE( + SET_STEP_DIR(X), SET_STEP_DIR(Y), SET_STEP_DIR(Z), // ABC + SET_STEP_DIR(I), SET_STEP_DIR(J), SET_STEP_DIR(K), + SET_STEP_DIR(U), SET_STEP_DIR(V), SET_STEP_DIR(W) + ); #if HAS_EXTRUDERS // Because this is valid for the whole block we don't know @@ -1829,7 +1825,7 @@ void Stepper::pulse_phase_isr() { de += step_fwd ? -128 : 128; \ if ((MAXDIR(AXIS) && step_bak) || (MINDIR(AXIS) && step_fwd)) { \ { USING_TIMED_PULSE(); START_TIMED_PULSE(); AWAIT_LOW_PULSE(); } \ - TBI(last_direction_bits, _AXIS(AXIS)); \ + last_direction_bits.toggle(_AXIS(AXIS)); \ DIR_WAIT_BEFORE(); \ SET_STEP_DIR(AXIS); \ DIR_WAIT_AFTER(); \ @@ -1861,11 +1857,11 @@ void Stepper::pulse_phase_isr() { #if STEPPER_PAGE_FORMAT == SP_4x4D_128 - #define PAGE_SEGMENT_UPDATE(AXIS, VALUE) do{ \ - if ((VALUE) < 7) SBI(dm, _AXIS(AXIS)); \ - else if ((VALUE) > 7) CBI(dm, _AXIS(AXIS)); \ - page_step_state.sd[_AXIS(AXIS)] = VALUE; \ - page_step_state.bd[_AXIS(AXIS)] += VALUE; \ + #define PAGE_SEGMENT_UPDATE(AXIS, VALUE) do{ \ + if ((VALUE) < 7) dm[_AXIS(AXIS)] = true; \ + else if ((VALUE) > 7) dm[_AXIS(AXIS)] = false; \ + page_step_state.sd[_AXIS(AXIS)] = VALUE; \ + page_step_state.bd[_AXIS(AXIS)] += VALUE; \ }while(0) #define PAGE_PULSE_PREP(AXIS) do{ \ @@ -1881,7 +1877,7 @@ void Stepper::pulse_phase_isr() { case 0: { const uint8_t low = page_step_state.page[page_step_state.segment_idx], high = page_step_state.page[page_step_state.segment_idx + 1]; - axis_bits_t dm = last_direction_bits; + const AxisBits dm = last_direction_bits; PAGE_SEGMENT_UPDATE(X, low >> 4); PAGE_SEGMENT_UPDATE(Y, low & 0xF); @@ -2417,7 +2413,7 @@ hal_timer_t Stepper::block_phase_isr() { la_interval = calc_timer_interval((reverse_e ? la_step_rate - step_rate : step_rate - la_step_rate) >> current_block->la_scaling); if (reverse_e != motor_direction(E_AXIS)) { - TBI(last_direction_bits, E_AXIS); + last_direction_bits.toggle(E_AXIS); count_direction.e = -count_direction.e; DIR_WAIT_BEFORE(); @@ -2648,7 +2644,7 @@ hal_timer_t Stepper::block_phase_isr() { #define Z_MOVE_TEST !!current_block->steps.c #endif - axis_bits_t axis_bits = 0; + AxisBits axis_bits; NUM_AXIS_CODE( if (X_MOVE_TEST) SBI(axis_bits, A_AXIS), if (Y_MOVE_TEST) SBI(axis_bits, B_AXIS), @@ -2692,24 +2688,24 @@ hal_timer_t Stepper::block_phase_isr() { #if ENABLED(INPUT_SHAPING_X) if (shaping_x.enabled) { - const int64_t steps = TEST(current_block->direction_bits, X_AXIS) ? -int64_t(current_block->steps.x) : int64_t(current_block->steps.x); + const int64_t steps = current_block->direction_bits.x ? -int64_t(current_block->steps.x) : int64_t(current_block->steps.x); shaping_x.last_block_end_pos += steps; // If there are any remaining echos unprocessed, then direction change must // be delayed and processed in PULSE_PREP_SHAPING. This will cause half a step // to be missed, which will need recovering and this can be done through shaping_x.remainder. - shaping_x.forward = !TEST(current_block->direction_bits, X_AXIS); - if (!ShapingQueue::empty_x()) SET_BIT_TO(current_block->direction_bits, X_AXIS, TEST(last_direction_bits, X_AXIS)); + shaping_x.forward = !current_block->direction_bits.x; + if (!ShapingQueue::empty_x()) current_block->direction_bits.x = last_direction_bits.x; } #endif // Y follows the same logic as X (but the comments aren't repeated) #if ENABLED(INPUT_SHAPING_Y) if (shaping_y.enabled) { - const int64_t steps = TEST(current_block->direction_bits, Y_AXIS) ? -int64_t(current_block->steps.y) : int64_t(current_block->steps.y); + const int64_t steps = current_block->direction_bits.y ? -int64_t(current_block->steps.y) : int64_t(current_block->steps.y); shaping_y.last_block_end_pos += steps; - shaping_y.forward = !TEST(current_block->direction_bits, Y_AXIS); - if (!ShapingQueue::empty_y()) SET_BIT_TO(current_block->direction_bits, Y_AXIS, TEST(last_direction_bits, Y_AXIS)); + shaping_y.forward = !current_block->direction_bits.y; + if (!ShapingQueue::empty_y()) current_block->direction_bits.y = last_direction_bits.y; } #endif @@ -2912,24 +2908,10 @@ void Stepper::init() { Z4_DIR_INIT(); #endif #endif - #if HAS_I_DIR - I_DIR_INIT(); - #endif - #if HAS_J_DIR - J_DIR_INIT(); - #endif - #if HAS_K_DIR - K_DIR_INIT(); - #endif - #if HAS_U_DIR - U_DIR_INIT(); - #endif - #if HAS_V_DIR - V_DIR_INIT(); - #endif - #if HAS_W_DIR - W_DIR_INIT(); - #endif + SECONDARY_AXIS_CODE( + I_DIR_INIT(), J_DIR_INIT(), K_DIR_INIT(), + U_DIR_INIT(), V_DIR_INIT(), W_DIR_INIT() + ); #if HAS_E0_DIR E0_DIR_INIT(); #endif diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 532db65dd93cf..9e45ffa45f6e9 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -317,17 +317,17 @@ class Stepper { #endif #if ENABLED(FREEZE_FEATURE) - static bool frozen; // Set this flag to instantly freeze motion + static bool frozen; // Set this flag to instantly freeze motion #endif private: - static block_t* current_block; // A pointer to the block currently being traced + static block_t* current_block; // A pointer to the block currently being traced - static axis_bits_t last_direction_bits, // The next stepping-bits to be output - axis_did_move; // Last Movement in the given direction is not null, as computed when the last movement was fetched from planner + static AxisBits last_direction_bits, // The next stepping-bits to be output + axis_did_move; // Last Movement in the given direction is not null, as computed when the last movement was fetched from planner - static bool abort_current_block; // Signals to the stepper that current block should be aborted + static bool abort_current_block; // Signals to the stepper that current block should be aborted #if ENABLED(X_DUAL_ENDSTOPS) static bool locked_X_motor, locked_X2_motor; @@ -523,10 +523,10 @@ class Stepper { FORCE_INLINE static void quick_stop() { abort_current_block = true; } // The direction of a single motor. A true result indicates reversed or negative motion. - FORCE_INLINE static bool motor_direction(const AxisEnum axis) { return TEST(last_direction_bits, axis); } + FORCE_INLINE static bool motor_direction(const AxisEnum axis) { return last_direction_bits[axis]; } // The last movement direction was not null on the specified axis. Note that motor direction is not necessarily the same. - FORCE_INLINE static bool axis_is_moving(const AxisEnum axis) { return TEST(axis_did_move, axis); } + FORCE_INLINE static bool axis_is_moving(const AxisEnum axis) { return axis_did_move[axis]; } // Handle a triggered endstop static void endstop_triggered(const AxisEnum axis); @@ -626,7 +626,7 @@ class Stepper { static void apply_directions(); // Set direction bits and update all stepper DIR states - static void set_directions(const axis_bits_t bits) { + static void set_directions(const AxisBits bits) { last_direction_bits = bits; apply_directions(); }