diff --git a/Marlin/src/feature/backlash.cpp b/Marlin/src/feature/backlash.cpp index 256488762a..8d180c7a4a 100644 --- a/Marlin/src/feature/backlash.cpp +++ b/Marlin/src/feature/backlash.cpp @@ -99,15 +99,15 @@ 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 = dm[axis]; + const bool forward = dm[axis]; // When an axis changes direction, add axis backlash to the residual error if (changed_dir[axis]) - residual_error[axis] += (reverse ? -f_corr : f_corr) * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; + residual_error[axis] += (forward ? 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 int32_t error_correction = residual_error[axis]; - if (reverse != (error_correction < 0)) + if (forward == (error_correction < 0)) error_correction = 0; // Don't take up any backlash in this segment, as it would subtract steps #ifdef BACKLASH_SMOOTHING_MM @@ -147,14 +147,14 @@ 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 = last_direction_bits[axis]; + const bool forward = last_direction_bits[axis]; const int32_t residual_error_axis = residual_error[axis]; // At startup it is assumed the last move was forwards. So the applied // steps will always be a non-positive number. - if (!reverse) return -residual_error_axis; + if (forward) return -residual_error_axis; const float f_corr = float(correction) / all_on; const int32_t full_error_axis = -f_corr * distance_mm[axis] * planner.settings.axis_steps_per_mm[axis]; diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index e6ca9f78cd..e160f88905 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 = (b->direction_bits.e ? -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/gcode/feature/ft_motion/M493.cpp b/Marlin/src/gcode/feature/ft_motion/M493.cpp index 31e16a194d..f7b8f1e752 100644 --- a/Marlin/src/gcode/feature/ft_motion/M493.cpp +++ b/Marlin/src/gcode/feature/ft_motion/M493.cpp @@ -102,8 +102,10 @@ void GcodeSuite::M493() { } switch (val) { - case ftMotionMode_ENABLED: fxdTiCtrl.reset(); break; #if HAS_X_AXIS + //case ftMotionMode_ULENDO_FBS: + //case ftMotionMode_DISCTF: + // break; case ftMotionMode_ZV: case ftMotionMode_ZVD: case ftMotionMode_EI: @@ -114,9 +116,10 @@ void GcodeSuite::M493() { fxdTiCtrl.updateShapingA(); fxdTiCtrl.reset(); break; - //case ftMotionMode_ULENDO_FBS: - //case ftMotionMode_DISCTF: #endif + case ftMotionMode_ENABLED: + fxdTiCtrl.reset(); + break; default: break; } } @@ -195,7 +198,7 @@ void GcodeSuite::M493() { fxdTiCtrl.reset(); if (fxdTiCtrl.cfg_dynFreqMode) { SERIAL_ECHOPGM("Compensator base dynamic frequency (X/A axis) set to:"); } else { SERIAL_ECHOPGM("Compensator static frequency (X/A axis) set to: "); } - SERIAL_ECHO_F( fxdTiCtrl.cfg_baseFreq[0], 2 ); + SERIAL_ECHO_F(fxdTiCtrl.cfg_baseFreq[0], 2); SERIAL_ECHOLNPGM("."); } else { // Frequency out of range. @@ -243,7 +246,7 @@ void GcodeSuite::M493() { fxdTiCtrl.reset(); if (fxdTiCtrl.cfg_dynFreqMode) { SERIAL_ECHOPGM("Compensator base dynamic frequency (Y/B axis) set to:"); } else { SERIAL_ECHOPGM("Compensator static frequency (Y/B axis) set to: "); } - SERIAL_ECHO_F( fxdTiCtrl.cfg_baseFreq[1], 2 ); + SERIAL_ECHO_F(fxdTiCtrl.cfg_baseFreq[1], 2); SERIAL_ECHOLNPGM("."); } else { // Frequency out of range. diff --git a/Marlin/src/gcode/motion/G6.cpp b/Marlin/src/gcode/motion/G6.cpp index fb6281707b..342741e634 100644 --- a/Marlin/src/gcode/motion/G6.cpp +++ b/Marlin/src/gcode/motion/G6.cpp @@ -38,10 +38,13 @@ void GcodeSuite::G6() { planner.last_page_step_rate = parser.value_ulong(); if (!DirectStepping::Config::DIRECTIONAL) { - if (parser.seen('X')) planner.last_page_dir.x = !!parser.value_byte(); - if (parser.seen('Y')) planner.last_page_dir.y = !!parser.value_byte(); - if (parser.seen('Z')) planner.last_page_dir.z = !!parser.value_byte(); - if (parser.seen('E')) planner.last_page_dir.e = !!parser.value_byte(); + #define PAGE_DIR_SET(N,A) do{ if (parser.seen(N)) planner.last_page_dir.A = !!parser.value_byte(); } while(0) + LOGICAL_AXIS_CODE( + PAGE_DIR_SET('E',E), + PAGE_DIR_SET('X',X), PAGE_DIR_SET('Y',Y), PAGE_DIR_SET('Z',Z), + PAGE_DIR_SET(AXIS4_NAME,I), PAGE_DIR_SET(AXIS5_NAME,J), PAGE_DIR_SET(AXIS6_NAME,K), + PAGE_DIR_SET(AXIS5_NAME,U), PAGE_DIR_SET(AXIS6_NAME,V), PAGE_DIR_SET(AXIS7_NAME,W) + ); } // No index means we just set the state diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 2a9fdde2dc..67d11d93e0 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -4037,8 +4037,12 @@ static_assert(_PLUS_TEST(3), "DEFAULT_MAX_ACCELERATION values must be positive." /** * Fixed-Time Motion limitations */ -#if ENABLED(FT_MOTION) && (NUM_AXES > 3 || E_STEPPERS > 1 || NUM_Z_STEPPERS > 1 || ANY(DUAL_X_CARRIAGE, HAS_SYNCED_X_STEPPERS, HAS_SYNCED_Y_STEPPERS, HAS_MULTI_EXTRUDER, MIXING_EXTRUDER)) - #error "FT_MOTION is currently limited to machines with 3 linear axes and a single extruder." +#if ENABLED(FT_MOTION) + #if NUM_AXES > 3 + #error "FT_MOTION is currently limited to machines with 3 linear axes." + #elif ENABLED(MIXING_EXTRUDER) + #error "FT_MOTION is incompatible with MIXING_EXTRUDER." + #endif #endif // Multi-Stepping Limit diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp index 0a12e1041d..a22c4f0381 100644 --- a/Marlin/src/module/endstops.cpp +++ b/Marlin/src/module/endstops.cpp @@ -872,7 +872,7 @@ void Endstops::update() { #if HAS_X_AXIS if (stepper.axis_is_moving(X_AXIS)) { - if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(X_AXIS_HEAD)) { // -direction #if USE_X_MIN || (X_SPI_SENSORLESS && X_HOME_TO_MIN) PROCESS_ENDSTOP_X(MIN); #if CORE_DIAG(XY, Y, MIN) @@ -905,7 +905,7 @@ void Endstops::update() { #if HAS_Y_AXIS if (stepper.axis_is_moving(Y_AXIS)) { - if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(Y_AXIS_HEAD)) { // -direction #if USE_Y_MIN || (Y_SPI_SENSORLESS && Y_HOME_TO_MIN) PROCESS_ENDSTOP_Y(MIN); #if CORE_DIAG(XY, X, MIN) @@ -938,7 +938,7 @@ void Endstops::update() { #if HAS_Z_AXIS if (stepper.axis_is_moving(Z_AXIS)) { - if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. + if (!stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up. #if USE_Z_MIN || (Z_SPI_SENSORLESS && Z_HOME_TO_MIN) if ( TERN1(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, z_probe_enabled) @@ -983,7 +983,7 @@ void Endstops::update() { #if HAS_I_AXIS if (stepper.axis_is_moving(I_AXIS)) { - if (stepper.motor_direction(I_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(I_AXIS_HEAD)) { // -direction #if USE_I_MIN || (I_SPI_SENSORLESS && I_HOME_TO_MIN) PROCESS_ENDSTOP(I, MIN); #endif @@ -998,7 +998,7 @@ void Endstops::update() { #if HAS_J_AXIS if (stepper.axis_is_moving(J_AXIS)) { - if (stepper.motor_direction(J_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(J_AXIS_HEAD)) { // -direction #if USE_J_MIN || (J_SPI_SENSORLESS && J_HOME_TO_MIN) PROCESS_ENDSTOP(J, MIN); #endif @@ -1013,7 +1013,7 @@ void Endstops::update() { #if HAS_K_AXIS if (stepper.axis_is_moving(K_AXIS)) { - if (stepper.motor_direction(K_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(K_AXIS_HEAD)) { // -direction #if USE_K_MIN || (K_SPI_SENSORLESS && K_HOME_TO_MIN) PROCESS_ENDSTOP(K, MIN); #endif @@ -1028,7 +1028,7 @@ void Endstops::update() { #if HAS_U_AXIS if (stepper.axis_is_moving(U_AXIS)) { - if (stepper.motor_direction(U_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(U_AXIS_HEAD)) { // -direction #if USE_U_MIN || (U_SPI_SENSORLESS && U_HOME_TO_MIN) PROCESS_ENDSTOP(U, MIN); #endif @@ -1043,7 +1043,7 @@ void Endstops::update() { #if HAS_V_AXIS if (stepper.axis_is_moving(V_AXIS)) { - if (stepper.motor_direction(V_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(V_AXIS_HEAD)) { // -direction #if USE_V_MIN || (V_SPI_SENSORLESS && V_HOME_TO_MIN) PROCESS_ENDSTOP(V, MIN); #endif @@ -1058,7 +1058,7 @@ void Endstops::update() { #if HAS_W_AXIS if (stepper.axis_is_moving(W_AXIS)) { - if (stepper.motor_direction(W_AXIS_HEAD)) { // -direction + if (!stepper.motor_direction(W_AXIS_HEAD)) { // -direction #if USE_W_MIN || (W_SPI_SENSORLESS && W_HOME_TO_MIN) PROCESS_ENDSTOP(W, MIN); #endif diff --git a/Marlin/src/module/ft_motion.cpp b/Marlin/src/module/ft_motion.cpp index 97dae881f8..407296f030 100644 --- a/Marlin/src/module/ft_motion.cpp +++ b/Marlin/src/module/ft_motion.cpp @@ -422,9 +422,9 @@ void FxdTiCtrl::reset() { stepperCmdBuff_produceIdx = stepperCmdBuff_consumeIdx = 0; for (uint32_t i = 0U; i < (FTM_BATCH_SIZE); i++) { // Reset trajectory history - TERN_(HAS_X_AXIS, xd[i] = 0.0f); - TERN_(HAS_Y_AXIS, yd[i] = 0.0f); - TERN_(HAS_Z_AXIS, zd[i] = 0.0f); + TERN_(HAS_X_AXIS, xd[i] = 0.0f); + TERN_(HAS_Y_AXIS, yd[i] = 0.0f); + TERN_(HAS_Z_AXIS, zd[i] = 0.0f); TERN_(HAS_EXTRUDERS, ed[i] = 0.0f); } @@ -432,23 +432,26 @@ void FxdTiCtrl::reset() { batchRdy = batchRdyForInterp = false; runoutEna = false; - TERN_(HAS_X_AXIS, x_endPosn_prevBlock = 0.0f); - TERN_(HAS_Y_AXIS, y_endPosn_prevBlock = 0.0f); - TERN_(HAS_Z_AXIS, z_endPosn_prevBlock = 0.0f); + TERN_(HAS_X_AXIS, x_endPosn_prevBlock = 0.0f); + TERN_(HAS_Y_AXIS, y_endPosn_prevBlock = 0.0f); + TERN_(HAS_Z_AXIS, z_endPosn_prevBlock = 0.0f); TERN_(HAS_EXTRUDERS, e_endPosn_prevBlock = 0.0f); makeVector_idx = makeVector_idx_z1 = 0; makeVector_batchIdx = FTM_BATCH_SIZE; - TERN_(HAS_X_AXIS, x_steps = 0); - TERN_(HAS_Y_AXIS, y_steps = 0); - TERN_(HAS_Z_AXIS, z_steps = 0); + TERN_(HAS_X_AXIS, x_steps = 0); + TERN_(HAS_Y_AXIS, y_steps = 0); + TERN_(HAS_Z_AXIS, z_steps = 0); TERN_(HAS_EXTRUDERS, e_steps = 0); + interpIdx = interpIdx_z1 = 0; - TERN_(HAS_X_AXIS, x_dirState = stepDirState_NOT_SET); - TERN_(HAS_Y_AXIS, y_dirState = stepDirState_NOT_SET); - TERN_(HAS_Z_AXIS, z_dirState = stepDirState_NOT_SET); + + TERN_(HAS_X_AXIS, x_dirState = stepDirState_NOT_SET); + TERN_(HAS_Y_AXIS, y_dirState = stepDirState_NOT_SET); + TERN_(HAS_Z_AXIS, z_dirState = stepDirState_NOT_SET); TERN_(HAS_EXTRUDERS, e_dirState = stepDirState_NOT_SET); + nextStepTicks = FTM_MIN_TICKS; #if HAS_X_AXIS @@ -486,28 +489,28 @@ void FxdTiCtrl::loadBlockData(block_t * const current_block) { #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 (direction.x) 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 (direction.y) 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 (direction.z) 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 (direction.e) extrusion *= -1.0f; + if (!direction.e) extrusion *= -1.0f; e_Ratio = extrusion * oneOverLength; #endif @@ -568,31 +571,31 @@ void FxdTiCtrl::loadBlockData(block_t * const current_block) { // One less than (Accel + Coasting + Decel) datapoints max_intervals = N1 + N2 + N3 - 1U; - TERN_(HAS_X_AXIS, x_endPosn_prevBlock += x_moveDist); - TERN_(HAS_Y_AXIS, y_endPosn_prevBlock += y_moveDist); - TERN_(HAS_Z_AXIS, z_endPosn_prevBlock += z_moveDist); + TERN_(HAS_X_AXIS, x_endPosn_prevBlock += x_moveDist); + TERN_(HAS_Y_AXIS, y_endPosn_prevBlock += y_moveDist); + TERN_(HAS_Z_AXIS, z_endPosn_prevBlock += z_moveDist); TERN_(HAS_EXTRUDERS, e_endPosn_prevBlock += extrusion); } // Generate data points of the trajectory. void FxdTiCtrl::makeVector() { - float accel_k = 0.0f; // (mm/s^2) Acceleration K factor - float tau = (makeVector_idx + 1) * (FTM_TS); // (s) Time since start of block - float dist = 0.0f; // (mm) Distance traveled + float accel_k = 0.0f; // (mm/s^2) Acceleration K factor + float tau = (makeVector_idx + 1) * (FTM_TS); // (s) Time since start of block + float dist = 0.0f; // (mm) Distance traveled if (makeVector_idx < N1) { // Acceleration phase - dist = (f_s * tau) + (0.5f * accel_P * sq(tau)); // (mm) Distance traveled for acceleration phase - accel_k = accel_P; // (mm/s^2) Acceleration K factor from Accel phase + dist = (f_s * tau) + (0.5f * accel_P * sq(tau)); // (mm) Distance traveled for acceleration phase + accel_k = accel_P; // (mm/s^2) Acceleration K factor from Accel phase } else if (makeVector_idx >= N1 && makeVector_idx < (N1 + N2)) { // Coasting phase - dist = s_1e + F_P * (tau - N1 * (FTM_TS)); // (mm) Distance traveled for coasting phase + dist = s_1e + F_P * (tau - N1 * (FTM_TS)); // (mm) Distance traveled for coasting phase //accel_k = 0.0f; } else { // Deceleration phase - const float tau_ = tau - (N1 + N2) * (FTM_TS); // (s) Time since start of decel phase + const float tau_ = tau - (N1 + N2) * (FTM_TS); // (s) Time since start of decel phase dist = s_2e + F_P * tau_ + 0.5f * decel_P * sq(tau_); // (mm) Distance traveled for deceleration phase accel_k = decel_P; // (mm/s^2) Acceleration K factor from Decel phase } @@ -614,7 +617,7 @@ void FxdTiCtrl::makeVector() { } else { ed[makeVector_batchIdx] = new_raw_z1; - // Alternatively: coordArray_e[makeVector_batchIdx] = e_startDist + extrusion / (N1 + N2 + N3); + // Alternatively: ed[makeVector_batchIdx] = e_startPosn + (e_Ratio * dist) / (N1 + N2 + N3); } #endif diff --git a/Marlin/src/module/planner.cpp b/Marlin/src/module/planner.cpp index a2d7e6843b..b0d0b3e353 100644 --- a/Marlin/src/module/planner.cpp +++ b/Marlin/src/module/planner.cpp @@ -169,7 +169,7 @@ float Planner::mm_per_step[DISTINCT_AXES]; // (mm) Millimeters per step #if ENABLED(DIRECT_STEPPING) uint32_t Planner::last_page_step_rate = 0; - xyze_bool_t Planner::last_page_dir{0}; + AxisBits Planner::last_page_dir; // = 0 #endif #if HAS_EXTRUDERS @@ -1887,67 +1887,56 @@ bool Planner::_populate_block( OPTARG(HAS_DIST_MM_ARG, const xyze_float_t &cart_dist_mm) , feedRate_t fr_mm_s, const uint8_t extruder, const PlannerHints &hints ) { - int32_t LOGICAL_AXIS_LIST( - de = target.e - position.e, - da = target.a - position.a, - db = target.b - position.b, - dc = target.c - position.c, - di = target.i - position.i, - dj = target.j - position.j, - dk = target.k - position.k, - du = target.u - position.u, - dv = target.v - position.v, - dw = target.w - position.w - ); + xyze_long_t dist = target - position; /* <-- add a slash to enable SERIAL_ECHOLNPGM( " _populate_block FR:", fr_mm_s, #if HAS_X_AXIS - " A:", target.a, " (", da, " steps)" + " A:", target.a, " (", dist.a, " steps)" #endif #if HAS_Y_AXIS - " B:", target.b, " (", db, " steps)" + " B:", target.b, " (", dist.b, " steps)" #endif #if HAS_Z_AXIS - " C:", target.c, " (", dc, " steps)" + " C:", target.c, " (", dist.c, " steps)" #endif #if HAS_I_AXIS - " " STR_I ":", target.i, " (", di, " steps)" + " " STR_I ":", target.i, " (", dist.i, " steps)" #endif #if HAS_J_AXIS - " " STR_J ":", target.j, " (", dj, " steps)" + " " STR_J ":", target.j, " (", dist.j, " steps)" #endif #if HAS_K_AXIS - " " STR_K ":", target.k, " (", dk, " steps)" + " " STR_K ":", target.k, " (", dist.k, " steps)" #endif #if HAS_U_AXIS - " " STR_U ":", target.u, " (", du, " steps)" + " " STR_U ":", target.u, " (", dist.u, " steps)" #endif #if HAS_V_AXIS - " " STR_V ":", target.v, " (", dv, " steps)" + " " STR_V ":", target.v, " (", dist.v, " steps)" #endif #if HAS_W_AXIS - " " STR_W ":", target.w, " (", dw, " steps)" + " " STR_W ":", target.w, " (", dist.w, " steps)" #endif #if HAS_EXTRUDERS - " E:", target.e, " (", de, " steps)" + " E:", target.e, " (", dist.e, " steps)" #endif ); //*/ #if EITHER(PREVENT_COLD_EXTRUSION, PREVENT_LENGTHY_EXTRUDE) - if (de) { + if (dist.e) { #if ENABLED(PREVENT_COLD_EXTRUSION) if (thermalManager.tooColdToExtrude(extruder)) { position.e = target.e; // Behave as if the move really took place, but ignore E part TERN_(HAS_POSITION_FLOAT, position_float.e = target_float.e); - de = 0; // no difference + dist.e = 0; // no difference SERIAL_ECHO_MSG(STR_ERR_COLD_EXTRUDE_STOP); } #endif // PREVENT_COLD_EXTRUSION #if ENABLED(PREVENT_LENGTHY_EXTRUDE) - const float e_steps = ABS(de * e_factor[extruder]); + const float e_steps = ABS(dist.e * e_factor[extruder]); const float max_e_steps = settings.axis_steps_per_mm[E_AXIS_N(extruder)] * (EXTRUDE_MAXLENGTH); if (e_steps > max_e_steps) { #if ENABLED(MIXING_EXTRUDER) @@ -1962,7 +1951,7 @@ bool Planner::_populate_block( if (ignore_e) { position.e = target.e; // Behave as if the move really took place, but ignore E part TERN_(HAS_POSITION_FLOAT, position_float.e = target_float.e); - de = 0; // no difference + dist.e = 0; // no difference SERIAL_ECHO_MSG(STR_ERR_LONG_EXTRUDE_STOP); } } @@ -1973,49 +1962,49 @@ bool Planner::_populate_block( // Compute direction bit-mask for this block AxisBits dm; #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - 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)); + dm.hx = (dist.a > 0); // Save the toolhead's true direction in X + dm.hy = (dist.b > 0); // ...and Y + TERN_(HAS_Z_AXIS, dm.z = (dist.c > 0)); #endif #if IS_CORE #if CORE_IS_XY - dm.a = (da + db < 0); // Motor A direction - dm.b = (CORESIGN(da - db) < 0); // Motor B direction + dm.a = (dist.a + dist.b > 0); // Motor A direction + dm.b = (CORESIGN(dist.a - dist.b) > 0); // Motor B direction #elif CORE_IS_XZ - 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 + dm.hx = (dist.a > 0); // Save the toolhead's true direction in X + dm.y = (dist.b > 0); + dm.hz = (dist.c > 0); // ...and Z + dm.a = (dist.a + dist.c > 0); // Motor A direction + dm.c = (CORESIGN(dist.a - dist.c) > 0); // Motor C direction #elif CORE_IS_YZ - 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 + dm.x = (dist.a > 0); + dm.hy = (dist.b > 0); // Save the toolhead's true direction in Y + dm.hz = (dist.c > 0); // ...and Z + dm.b = (dist.b + dist.c > 0); // Motor B direction + dm.c = (CORESIGN(dist.b - dist.c) > 0); // Motor C direction #endif #elif ENABLED(MARKFORGED_XY) - dm.a = (da + db < 0); // Motor A direction - dm.b = (db < 0); // Motor B direction + dm.a = (dist.a + dist.b > 0); // Motor A direction + dm.b = (dist.b > 0); // Motor B direction #elif ENABLED(MARKFORGED_YX) - dm.a = (da < 0); // Motor A direction - dm.b = (db + da < 0); // Motor B direction + dm.a = (dist.a > 0); // Motor A direction + dm.b = (dist.b + dist.a > 0); // Motor B direction #else XYZ_CODE( - dm.x = (da < 0), - dm.y = (db < 0), - dm.z = (dc < 0) + dm.x = (dist.a > 0), + dm.y = (dist.b > 0), + dm.z = (dist.c > 0) ); #endif SECONDARY_AXIS_CODE( - dm.i = (di < 0), dm.j = (dj < 0), dm.k = (dk < 0), - dm.u = (du < 0), dm.v = (dv < 0), dm.w = (dw < 0) + dm.i = (dist.i > 0), dm.j = (dist.j > 0), dm.k = (dist.k > 0), + dm.u = (dist.u > 0), dm.v = (dist.v > 0), dm.w = (dist.w > 0) ); #if HAS_EXTRUDERS - dm.e = (de < 0); - const float esteps_float = de * e_factor[extruder]; + dm.e = (dist.e > 0); + const float esteps_float = dist.e * e_factor[extruder]; const uint32_t esteps = ABS(esteps_float) + 0.5f; #else constexpr uint32_t esteps = 0; @@ -2061,21 +2050,21 @@ bool Planner::_populate_block( // See https://www.corexy.com/theory.html block->steps.set(NUM_AXIS_LIST( #if CORE_IS_XY - ABS(da + db), ABS(da - db), ABS(dc) + ABS(dist.a + dist.b), ABS(dist.a - dist.b), ABS(dist.c) #elif CORE_IS_XZ - ABS(da + dc), ABS(db), ABS(da - dc) + ABS(dist.a + dist.c), ABS(dist.b), ABS(dist.a - dist.c) #elif CORE_IS_YZ - ABS(da), ABS(db + dc), ABS(db - dc) + ABS(dist.a), ABS(dist.b + dist.c), ABS(dist.b - dist.c) #elif ENABLED(MARKFORGED_XY) - ABS(da + db), ABS(db), ABS(dc) + ABS(dist.a + dist.b), ABS(dist.b), ABS(dist.c) #elif ENABLED(MARKFORGED_YX) - ABS(da), ABS(db + da), ABS(dc) + ABS(dist.a), ABS(dist.b + dist.a), ABS(dist.c) #elif IS_SCARA - ABS(da), ABS(db), ABS(dc) + ABS(dist.a), ABS(dist.b), ABS(dist.c) #else // default non-h-bot planning - ABS(da), ABS(db), ABS(dc) + ABS(dist.a), ABS(dist.b), ABS(dist.c) #endif - , ABS(di), ABS(dj), ABS(dk), ABS(du), ABS(dv), ABS(dw) + , ABS(dist.i), ABS(dist.j), ABS(dist.k), ABS(dist.u), ABS(dist.v), ABS(dist.w) )); /** @@ -2090,104 +2079,82 @@ bool Planner::_populate_block( #if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX) struct { float x, y, z; } head; #endif - } steps_dist_mm; + } dist_mm; #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - steps_dist_mm.head.x = da * mm_per_step[A_AXIS]; - steps_dist_mm.head.y = db * mm_per_step[B_AXIS]; - TERN_(HAS_Z_AXIS, steps_dist_mm.z = dc * mm_per_step[Z_AXIS]); + dist_mm.head.x = dist.a * mm_per_step[A_AXIS]; + dist_mm.head.y = dist.b * mm_per_step[B_AXIS]; + TERN_(HAS_Z_AXIS, dist_mm.z = dist.c * mm_per_step[Z_AXIS]); #endif #if IS_CORE #if CORE_IS_XY - steps_dist_mm.a = (da + db) * mm_per_step[A_AXIS]; - steps_dist_mm.b = CORESIGN(da - db) * mm_per_step[B_AXIS]; + dist_mm.a = (dist.a + dist.b) * mm_per_step[A_AXIS]; + dist_mm.b = CORESIGN(dist.a - dist.b) * mm_per_step[B_AXIS]; #elif CORE_IS_XZ - steps_dist_mm.head.x = da * mm_per_step[A_AXIS]; - steps_dist_mm.y = db * mm_per_step[Y_AXIS]; - steps_dist_mm.head.z = dc * mm_per_step[C_AXIS]; - steps_dist_mm.a = (da + dc) * mm_per_step[A_AXIS]; - steps_dist_mm.c = CORESIGN(da - dc) * mm_per_step[C_AXIS]; + dist_mm.head.x = dist.a * mm_per_step[A_AXIS]; + dist_mm.y = dist.b * mm_per_step[Y_AXIS]; + dist_mm.head.z = dist.c * mm_per_step[C_AXIS]; + dist_mm.a = (dist.a + dist.c) * mm_per_step[A_AXIS]; + dist_mm.c = CORESIGN(dist.a - dist.c) * mm_per_step[C_AXIS]; #elif CORE_IS_YZ - steps_dist_mm.x = da * mm_per_step[X_AXIS]; - steps_dist_mm.head.y = db * mm_per_step[B_AXIS]; - steps_dist_mm.head.z = dc * mm_per_step[C_AXIS]; - steps_dist_mm.b = (db + dc) * mm_per_step[B_AXIS]; - steps_dist_mm.c = CORESIGN(db - dc) * mm_per_step[C_AXIS]; + dist_mm.x = dist.a * mm_per_step[X_AXIS]; + dist_mm.head.y = dist.b * mm_per_step[B_AXIS]; + dist_mm.head.z = dist.c * mm_per_step[C_AXIS]; + dist_mm.b = (dist.b + dist.c) * mm_per_step[B_AXIS]; + dist_mm.c = CORESIGN(dist.b - dist.c) * mm_per_step[C_AXIS]; #endif #elif ENABLED(MARKFORGED_XY) - steps_dist_mm.a = (da - db) * mm_per_step[A_AXIS]; - steps_dist_mm.b = db * mm_per_step[B_AXIS]; + dist_mm.a = (dist.a - dist.b) * mm_per_step[A_AXIS]; + dist_mm.b = dist.b * mm_per_step[B_AXIS]; #elif ENABLED(MARKFORGED_YX) - steps_dist_mm.a = da * mm_per_step[A_AXIS]; - steps_dist_mm.b = (db - da) * mm_per_step[B_AXIS]; + dist_mm.a = dist.a * mm_per_step[A_AXIS]; + dist_mm.b = (dist.b - dist.a) * mm_per_step[B_AXIS]; #else XYZ_CODE( - steps_dist_mm.a = da * mm_per_step[A_AXIS], - steps_dist_mm.b = db * mm_per_step[B_AXIS], - steps_dist_mm.c = dc * mm_per_step[C_AXIS] + dist_mm.a = dist.a * mm_per_step[A_AXIS], + dist_mm.b = dist.b * mm_per_step[B_AXIS], + dist_mm.c = dist.c * mm_per_step[C_AXIS] ); #endif SECONDARY_AXIS_CODE( - steps_dist_mm.i = di * mm_per_step[I_AXIS], - steps_dist_mm.j = dj * mm_per_step[J_AXIS], - steps_dist_mm.k = dk * mm_per_step[K_AXIS], - steps_dist_mm.u = du * mm_per_step[U_AXIS], - steps_dist_mm.v = dv * mm_per_step[V_AXIS], - steps_dist_mm.w = dw * mm_per_step[W_AXIS] + dist_mm.i = dist.i * mm_per_step[I_AXIS], dist_mm.j = dist.j * mm_per_step[J_AXIS], dist_mm.k = dist.k * mm_per_step[K_AXIS], + dist_mm.u = dist.u * mm_per_step[U_AXIS], dist_mm.v = dist.v * mm_per_step[V_AXIS], dist_mm.w = dist.w * mm_per_step[W_AXIS] ); - TERN_(HAS_EXTRUDERS, steps_dist_mm.e = esteps_float * mm_per_step[E_AXIS_N(extruder)]); + TERN_(HAS_EXTRUDERS, dist_mm.e = esteps_float * mm_per_step[E_AXIS_N(extruder)]); - TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator += steps_dist_mm.e); + TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator += dist_mm.e); #if HAS_ROTATIONAL_AXES bool cartesian_move = hints.cartesian_move; #endif if (true NUM_AXIS_GANG( - && block->steps.a < MIN_STEPS_PER_SEGMENT, - && block->steps.b < MIN_STEPS_PER_SEGMENT, - && block->steps.c < MIN_STEPS_PER_SEGMENT, - && block->steps.i < MIN_STEPS_PER_SEGMENT, - && block->steps.j < MIN_STEPS_PER_SEGMENT, - && block->steps.k < MIN_STEPS_PER_SEGMENT, - && block->steps.u < MIN_STEPS_PER_SEGMENT, - && block->steps.v < MIN_STEPS_PER_SEGMENT, - && block->steps.w < MIN_STEPS_PER_SEGMENT + && block->steps.a < MIN_STEPS_PER_SEGMENT, && block->steps.b < MIN_STEPS_PER_SEGMENT, && block->steps.c < MIN_STEPS_PER_SEGMENT, + && block->steps.i < MIN_STEPS_PER_SEGMENT, && block->steps.j < MIN_STEPS_PER_SEGMENT, && block->steps.k < MIN_STEPS_PER_SEGMENT, + && block->steps.u < MIN_STEPS_PER_SEGMENT, && block->steps.v < MIN_STEPS_PER_SEGMENT, && block->steps.w < MIN_STEPS_PER_SEGMENT ) ) { - block->millimeters = TERN0(HAS_EXTRUDERS, ABS(steps_dist_mm.e)); + block->millimeters = TERN0(HAS_EXTRUDERS, ABS(dist_mm.e)); } else { if (hints.millimeters) block->millimeters = hints.millimeters; else { const xyze_pos_t displacement = LOGICAL_AXIS_ARRAY( - steps_dist_mm.e, + dist_mm.e, #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) - steps_dist_mm.head.x, - steps_dist_mm.head.y, - steps_dist_mm.z, + dist_mm.head.x, dist_mm.head.y, dist_mm.z, #elif CORE_IS_XZ - steps_dist_mm.head.x, - steps_dist_mm.y, - steps_dist_mm.head.z, + dist_mm.head.x, dist_mm.y, dist_mm.head.z, #elif CORE_IS_YZ - steps_dist_mm.x, - steps_dist_mm.head.y, - steps_dist_mm.head.z, + dist_mm.x, dist_mm.head.y, dist_mm.head.z, #else - steps_dist_mm.x, - steps_dist_mm.y, - steps_dist_mm.z, + dist_mm.x, dist_mm.y, dist_mm.z, #endif - steps_dist_mm.i, - steps_dist_mm.j, - steps_dist_mm.k, - steps_dist_mm.u, - steps_dist_mm.v, - steps_dist_mm.w + dist_mm.i, dist_mm.j, dist_mm.k, + dist_mm.u, dist_mm.v, dist_mm.w ); block->millimeters = get_move_distance(displacement OPTARG(HAS_ROTATIONAL_AXES, cartesian_move)); @@ -2202,7 +2169,7 @@ bool Planner::_populate_block( * A correction function is permitted to add steps to an axis, it * should *never* remove steps! */ - TERN_(BACKLASH_COMPENSATION, backlash.add_correction_steps(da, db, dc, dm, block)); + TERN_(BACKLASH_COMPENSATION, backlash.add_correction_steps(dist.a, dist.b, dist.c, dm, block)); } TERN_(HAS_EXTRUDERS, block->steps.e = esteps); @@ -2279,12 +2246,9 @@ bool Planner::_populate_block( #endif #if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) SECONDARY_AXIS_CODE( - if (block->steps.i) stepper.enable_axis(I_AXIS), - if (block->steps.j) stepper.enable_axis(J_AXIS), - if (block->steps.k) stepper.enable_axis(K_AXIS), - if (block->steps.u) stepper.enable_axis(U_AXIS), - if (block->steps.v) stepper.enable_axis(V_AXIS), - if (block->steps.w) stepper.enable_axis(W_AXIS) + if (block->steps.i) stepper.enable_axis(I_AXIS), if (block->steps.j) stepper.enable_axis(J_AXIS), + if (block->steps.k) stepper.enable_axis(K_AXIS), if (block->steps.u) stepper.enable_axis(U_AXIS), + if (block->steps.v) stepper.enable_axis(V_AXIS), if (block->steps.w) stepper.enable_axis(W_AXIS) ); #endif @@ -2383,7 +2347,7 @@ bool Planner::_populate_block( #if ENABLED(FILAMENT_WIDTH_SENSOR) if (extruder == FILAMENT_SENSOR_EXTRUDER_NUM) // Only for extruder with filament sensor - filwidth.advance_e(steps_dist_mm.e); + filwidth.advance_e(dist_mm.e); #endif // Calculate and limit speed in mm/sec (linear) or degrees/sec (rotational) @@ -2393,7 +2357,7 @@ bool Planner::_populate_block( // Linear axes first with less logic LOOP_NUM_AXES(i) { - current_speed[i] = steps_dist_mm[i] * inverse_secs; + current_speed[i] = dist_mm[i] * inverse_secs; const feedRate_t cs = ABS(current_speed[i]), max_fr = settings.max_feedrate_mm_s[i]; if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); @@ -2402,7 +2366,7 @@ bool Planner::_populate_block( // Limit speed on extruders, if any #if HAS_EXTRUDERS { - current_speed.e = steps_dist_mm.e * inverse_secs; + current_speed.e = dist_mm.e * inverse_secs; #if HAS_MIXER_SYNC_CHANNEL // Move all mixing extruders at the specified rate if (mixer.get_current_vtool() == MIXER_AUTORETRACT_TOOL) @@ -2519,9 +2483,9 @@ bool Planner::_populate_block( * * extruder_advance_K[extruder] : There is an advance factor set for this extruder. * - * de > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) + * dist.e > 0 : Extruder is running forward (e.g., for "Wipe while retracting" (Slic3r) or "Combing" (Cura) moves) */ - use_advance_lead = esteps && extruder_advance_K[E_INDEX_N(extruder)] && de > 0; + use_advance_lead = esteps && extruder_advance_K[E_INDEX_N(extruder)] && dist.e > 0; if (use_advance_lead) { float e_D_ratio = (target_float.e - position_float.e) / @@ -2632,10 +2596,10 @@ bool Planner::_populate_block( #if HAS_DIST_MM_ARG cart_dist_mm #else - LOGICAL_AXIS_ARRAY(steps_dist_mm.e, - steps_dist_mm.x, steps_dist_mm.y, steps_dist_mm.z, - steps_dist_mm.i, steps_dist_mm.j, steps_dist_mm.k, - steps_dist_mm.u, steps_dist_mm.v, steps_dist_mm.w) + LOGICAL_AXIS_ARRAY(dist_mm.e, + dist_mm.x, dist_mm.y, dist_mm.z, + dist_mm.i, dist_mm.j, dist_mm.k, + dist_mm.u, dist_mm.v, dist_mm.w) #endif ; @@ -2804,7 +2768,7 @@ bool Planner::_populate_block( #ifndef TRAVEL_EXTRA_XYJERK #define TRAVEL_EXTRA_XYJERK 0 #endif - const float extra_xyjerk = TERN0(HAS_EXTRUDERS, de <= 0) ? TRAVEL_EXTRA_XYJERK : 0; + const float extra_xyjerk = TERN0(HAS_EXTRUDERS, dist.e <= 0) ? TRAVEL_EXTRA_XYJERK : 0; uint8_t limited = 0; TERN(HAS_LINEAR_E_JERK, LOOP_NUM_AXES, LOOP_LOGICAL_AXES)(i) { @@ -3239,16 +3203,11 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s block->decelerate_after = block->step_event_count; // Will be set to last direction later if directional format. - block->direction_bits = 0; - - #define PAGE_UPDATE_DIR(AXIS) \ - if (!last_page_dir[_AXIS(AXIS)]) SBI(block->direction_bits, _AXIS(AXIS)); + block->direction_bits.reset(); if (!DirectStepping::Config::DIRECTIONAL) { - PAGE_UPDATE_DIR(X); - PAGE_UPDATE_DIR(Y); - PAGE_UPDATE_DIR(Z); - PAGE_UPDATE_DIR(E); + #define PAGE_UPDATE_DIR(AXIS) do{ if (last_page_dir.AXIS) block->direction_bits.AXIS = true; }while(0); + LOGICAL_AXIS_MAP(PAGE_UPDATE_DIR); } // If this is the first added movement, reload the delay, otherwise, cancel it. diff --git a/Marlin/src/module/planner.h b/Marlin/src/module/planner.h index eb0f072f4b..4b68c5f656 100644 --- a/Marlin/src/module/planner.h +++ b/Marlin/src/module/planner.h @@ -417,7 +417,7 @@ class Planner { #if ENABLED(DIRECT_STEPPING) static uint32_t last_page_step_rate; // Last page step rate given - static xyze_bool_t last_page_dir; // Last page direction given + static AxisBits last_page_dir; // Last page direction given, where 1 represents forward or positive motion #endif #if HAS_EXTRUDERS diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index c811bf5e38..b23667b820 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -383,111 +383,114 @@ xyze_int8_t Stepper::count_direction{0}; } #if HAS_SYNCED_X_STEPPERS - #define X_APPLY_DIR(v,Q) do{ X_DIR_WRITE(v); X2_DIR_WRITE(INVERT_DIR(X2_VS_X, v)); }while(0) + #define X_APPLY_DIR(FWD,Q) do{ X_DIR_WRITE(FWD); X2_DIR_WRITE(INVERT_DIR(X2_VS_X, FWD)); }while(0) #if ENABLED(X_DUAL_ENDSTOPS) - #define X_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(X,v) + #define X_APPLY_STEP(FWD,Q) DUAL_ENDSTOP_APPLY_STEP(X,FWD) #else - #define X_APPLY_STEP(v,Q) do{ X_STEP_WRITE(v); X2_STEP_WRITE(v); }while(0) + #define X_APPLY_STEP(FWD,Q) do{ X_STEP_WRITE(FWD); X2_STEP_WRITE(FWD); }while(0) #endif #elif ENABLED(DUAL_X_CARRIAGE) - #define X_APPLY_DIR(v,ALWAYS) do{ \ - if (extruder_duplication_enabled || ALWAYS) { X_DIR_WRITE(v); X2_DIR_WRITE((v) ^ idex_mirrored_mode); } \ - else if (last_moved_extruder) X2_DIR_WRITE(v); else X_DIR_WRITE(v); \ + #define X_APPLY_DIR(FWD,ALWAYS) do{ \ + if (extruder_duplication_enabled || ALWAYS) { X_DIR_WRITE(FWD); X2_DIR_WRITE((FWD) ^ idex_mirrored_mode); } \ + else if (last_moved_extruder) X2_DIR_WRITE(FWD); else X_DIR_WRITE(FWD); \ }while(0) - #define X_APPLY_STEP(v,ALWAYS) do{ \ - if (extruder_duplication_enabled || ALWAYS) { X_STEP_WRITE(v); X2_STEP_WRITE(v); } \ - else if (last_moved_extruder) X2_STEP_WRITE(v); else X_STEP_WRITE(v); \ + #define X_APPLY_STEP(FWD,ALWAYS) do{ \ + if (extruder_duplication_enabled || ALWAYS) { X_STEP_WRITE(FWD); X2_STEP_WRITE(FWD); } \ + else if (last_moved_extruder) X2_STEP_WRITE(FWD); else X_STEP_WRITE(FWD); \ }while(0) #elif HAS_X_AXIS - #define X_APPLY_DIR(v,Q) X_DIR_WRITE(v) - #define X_APPLY_STEP(v,Q) X_STEP_WRITE(v) + #define X_APPLY_DIR(FWD,Q) X_DIR_WRITE(FWD) + #define X_APPLY_STEP(FWD,Q) X_STEP_WRITE(FWD) #endif #if HAS_SYNCED_Y_STEPPERS - #define Y_APPLY_DIR(v,Q) do{ Y_DIR_WRITE(v); Y2_DIR_WRITE(INVERT_DIR(Y2_VS_Y, v)); }while(0) + #define Y_APPLY_DIR(FWD,Q) do{ Y_DIR_WRITE(FWD); Y2_DIR_WRITE(INVERT_DIR(Y2_VS_Y, FWD)); }while(0) #if ENABLED(Y_DUAL_ENDSTOPS) - #define Y_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Y,v) + #define Y_APPLY_STEP(FWD,Q) DUAL_ENDSTOP_APPLY_STEP(Y,FWD) #else - #define Y_APPLY_STEP(v,Q) do{ Y_STEP_WRITE(v); Y2_STEP_WRITE(v); }while(0) + #define Y_APPLY_STEP(FWD,Q) do{ Y_STEP_WRITE(FWD); Y2_STEP_WRITE(FWD); }while(0) #endif #elif HAS_Y_AXIS - #define Y_APPLY_DIR(v,Q) Y_DIR_WRITE(v) - #define Y_APPLY_STEP(v,Q) Y_STEP_WRITE(v) + #define Y_APPLY_DIR(FWD,Q) Y_DIR_WRITE(FWD) + #define Y_APPLY_STEP(FWD,Q) Y_STEP_WRITE(FWD) #endif #if NUM_Z_STEPPERS == 4 - #define Z_APPLY_DIR(v,Q) do{ \ - Z_DIR_WRITE(v); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, v)); \ - Z3_DIR_WRITE(INVERT_DIR(Z3_VS_Z, v)); Z4_DIR_WRITE(INVERT_DIR(Z4_VS_Z, v)); \ + #define Z_APPLY_DIR(FWD,Q) do{ \ + Z_DIR_WRITE(FWD); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, FWD)); \ + Z3_DIR_WRITE(INVERT_DIR(Z3_VS_Z, FWD)); Z4_DIR_WRITE(INVERT_DIR(Z4_VS_Z, FWD)); \ }while(0) #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z_APPLY_STEP(v,Q) QUAD_ENDSTOP_APPLY_STEP(Z,v) + #define Z_APPLY_STEP(FWD,Q) QUAD_ENDSTOP_APPLY_STEP(Z,FWD) #elif ENABLED(Z_STEPPER_AUTO_ALIGN) - #define Z_APPLY_STEP(v,Q) QUAD_SEPARATE_APPLY_STEP(Z,v) + #define Z_APPLY_STEP(FWD,Q) QUAD_SEPARATE_APPLY_STEP(Z,FWD) #else - #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); Z3_STEP_WRITE(v); Z4_STEP_WRITE(v); }while(0) + #define Z_APPLY_STEP(FWD,Q) do{ Z_STEP_WRITE(FWD); Z2_STEP_WRITE(FWD); Z3_STEP_WRITE(FWD); Z4_STEP_WRITE(FWD); }while(0) #endif #elif NUM_Z_STEPPERS == 3 - #define Z_APPLY_DIR(v,Q) do{ \ - Z_DIR_WRITE(v); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, v)); Z3_DIR_WRITE(INVERT_DIR(Z3_VS_Z, v)); \ + #define Z_APPLY_DIR(FWD,Q) do{ \ + Z_DIR_WRITE(FWD); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, FWD)); Z3_DIR_WRITE(INVERT_DIR(Z3_VS_Z, FWD)); \ }while(0) #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z_APPLY_STEP(v,Q) TRIPLE_ENDSTOP_APPLY_STEP(Z,v) + #define Z_APPLY_STEP(FWD,Q) TRIPLE_ENDSTOP_APPLY_STEP(Z,FWD) #elif ENABLED(Z_STEPPER_AUTO_ALIGN) - #define Z_APPLY_STEP(v,Q) TRIPLE_SEPARATE_APPLY_STEP(Z,v) + #define Z_APPLY_STEP(FWD,Q) TRIPLE_SEPARATE_APPLY_STEP(Z,FWD) #else - #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); Z3_STEP_WRITE(v); }while(0) + #define Z_APPLY_STEP(FWD,Q) do{ Z_STEP_WRITE(FWD); Z2_STEP_WRITE(FWD); Z3_STEP_WRITE(FWD); }while(0) #endif #elif NUM_Z_STEPPERS == 2 - #define Z_APPLY_DIR(v,Q) do{ Z_DIR_WRITE(v); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, v)); }while(0) + #define Z_APPLY_DIR(FWD,Q) do{ Z_DIR_WRITE(FWD); Z2_DIR_WRITE(INVERT_DIR(Z2_VS_Z, FWD)); }while(0) #if ENABLED(Z_MULTI_ENDSTOPS) - #define Z_APPLY_STEP(v,Q) DUAL_ENDSTOP_APPLY_STEP(Z,v) + #define Z_APPLY_STEP(FWD,Q) DUAL_ENDSTOP_APPLY_STEP(Z,FWD) #elif ENABLED(Z_STEPPER_AUTO_ALIGN) - #define Z_APPLY_STEP(v,Q) DUAL_SEPARATE_APPLY_STEP(Z,v) + #define Z_APPLY_STEP(FWD,Q) DUAL_SEPARATE_APPLY_STEP(Z,FWD) #else - #define Z_APPLY_STEP(v,Q) do{ Z_STEP_WRITE(v); Z2_STEP_WRITE(v); }while(0) + #define Z_APPLY_STEP(FWD,Q) do{ Z_STEP_WRITE(FWD); Z2_STEP_WRITE(FWD); }while(0) #endif #elif HAS_Z_AXIS - #define Z_APPLY_DIR(v,Q) Z_DIR_WRITE(v) - #define Z_APPLY_STEP(v,Q) Z_STEP_WRITE(v) + #define Z_APPLY_DIR(FWD,Q) Z_DIR_WRITE(FWD) + #define Z_APPLY_STEP(FWD,Q) Z_STEP_WRITE(FWD) #endif #if HAS_I_AXIS - #define I_APPLY_DIR(v,Q) I_DIR_WRITE(v) - #define I_APPLY_STEP(v,Q) I_STEP_WRITE(v) + #define I_APPLY_DIR(FWD,Q) I_DIR_WRITE(FWD) + #define I_APPLY_STEP(FWD,Q) I_STEP_WRITE(FWD) #endif #if HAS_J_AXIS - #define J_APPLY_DIR(v,Q) J_DIR_WRITE(v) - #define J_APPLY_STEP(v,Q) J_STEP_WRITE(v) + #define J_APPLY_DIR(FWD,Q) J_DIR_WRITE(FWD) + #define J_APPLY_STEP(FWD,Q) J_STEP_WRITE(FWD) #endif #if HAS_K_AXIS - #define K_APPLY_DIR(v,Q) K_DIR_WRITE(v) - #define K_APPLY_STEP(v,Q) K_STEP_WRITE(v) + #define K_APPLY_DIR(FWD,Q) K_DIR_WRITE(FWD) + #define K_APPLY_STEP(FWD,Q) K_STEP_WRITE(FWD) #endif #if HAS_U_AXIS - #define U_APPLY_DIR(v,Q) U_DIR_WRITE(v) - #define U_APPLY_STEP(v,Q) U_STEP_WRITE(v) + #define U_APPLY_DIR(FWD,Q) U_DIR_WRITE(FWD) + #define U_APPLY_STEP(FWD,Q) U_STEP_WRITE(FWD) #endif #if HAS_V_AXIS - #define V_APPLY_DIR(v,Q) V_DIR_WRITE(v) - #define V_APPLY_STEP(v,Q) V_STEP_WRITE(v) + #define V_APPLY_DIR(FWD,Q) V_DIR_WRITE(FWD) + #define V_APPLY_STEP(FWD,Q) V_STEP_WRITE(FWD) #endif #if HAS_W_AXIS - #define W_APPLY_DIR(v,Q) W_DIR_WRITE(v) - #define W_APPLY_STEP(v,Q) W_STEP_WRITE(v) + #define W_APPLY_DIR(FWD,Q) W_DIR_WRITE(FWD) + #define W_APPLY_STEP(FWD,Q) W_STEP_WRITE(FWD) #endif -#define E0_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(0) : REV_E_DIR(0); }while(0) -#define E1_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(1) : REV_E_DIR(1); }while(0) -#define E2_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(2) : REV_E_DIR(2); }while(0) -#define E3_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(3) : REV_E_DIR(3); }while(0) -#define E4_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(4) : REV_E_DIR(4); }while(0) -#define E5_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(5) : REV_E_DIR(5); }while(0) -#define E6_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(6) : REV_E_DIR(6); }while(0) -#define E7_APPLY_DIR(REV) do{ (REV) ? FWD_E_DIR(7) : REV_E_DIR(7); }while(0) +//#define E0_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(0) : REV_E_DIR(0); }while(0) +//#define E1_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(1) : REV_E_DIR(1); }while(0) +//#define E2_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(2) : REV_E_DIR(2); }while(0) +//#define E3_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(3) : REV_E_DIR(3); }while(0) +//#define E4_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(4) : REV_E_DIR(4); }while(0) +//#define E5_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(5) : REV_E_DIR(5); }while(0) +//#define E6_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(6) : REV_E_DIR(6); }while(0) +//#define E7_APPLY_DIR(FWD) do{ (FWD) ? FWD_E_DIR(7) : REV_E_DIR(7); }while(0) -#if DISABLED(MIXING_EXTRUDER) - #define E_APPLY_STEP(v,Q) E_STEP_WRITE(stepper_extruder, v) +#if ENABLED(MIXING_EXTRUDER) + #define E_APPLY_DIR(FWD,Q) do{ if (FWD) { MIXER_STEPPER_LOOP(j) FWD_E_DIR(j); } else { MIXER_STEPPER_LOOP(j) REV_E_DIR(j); } }while(0) +#else + #define E_APPLY_STEP(FWD,Q) E_STEP_WRITE(stepper_extruder, FWD) + #define E_APPLY_DIR(FWD,Q) do{ if (FWD) { FWD_E_DIR(stepper_extruder); } else { REV_E_DIR(stepper_extruder); } }while(0) #endif #define CYCLES_TO_NS(CYC) (1000UL * (CYC) / ((F_CPU) / 1000000)) @@ -602,16 +605,12 @@ void Stepper::disable_all_steppers() { } // Set a single axis direction based on the last set flags. -// A direction bit of "1" indicates reverse or negative motion. -#define SET_STEP_DIR(A) \ - if (motor_direction(_AXIS(A))) { \ - A##_APPLY_DIR(LOW, false); \ - count_direction[_AXIS(A)] = -1; \ - } \ - else { \ - A##_APPLY_DIR(HIGH, false); \ - count_direction[_AXIS(A)] = 1; \ - } +// A direction bit of "1" indicates forward or positive motion. +#define SET_STEP_DIR(A) do{ \ + const bool fwd = motor_direction(_AXIS(A)); \ + A##_APPLY_DIR(fwd, false); \ + count_direction[_AXIS(A)] = fwd ? 1 : -1; \ + }while(0) /** * Set the stepper direction of each axis @@ -621,36 +620,15 @@ void Stepper::disable_all_steppers() { * COREYZ: Y_AXIS=B_AXIS and Z_AXIS=C_AXIS */ void Stepper::apply_directions() { - DIR_WAIT_BEFORE(); - NUM_AXIS_CODE( + LOGICAL_AXIS_CODE( + SET_STEP_DIR(E), 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 - // what E steppers will step. Likely all. Set all. - if (motor_direction(E_AXIS)) { - #if ENABLED(MIXING_EXTRUDER) - MIXER_STEPPER_LOOP(j) REV_E_DIR(j); - #else - REV_E_DIR(stepper_extruder); - #endif - count_direction.e = -1; - } - else { - #if ENABLED(MIXING_EXTRUDER) - MIXER_STEPPER_LOOP(j) FWD_E_DIR(j); - #else - FWD_E_DIR(stepper_extruder); - #endif - count_direction.e = 1; - } - #endif // HAS_EXTRUDERS - DIR_WAIT_AFTER(); } @@ -1858,8 +1836,8 @@ void Stepper::pulse_phase_isr() { #if STEPPER_PAGE_FORMAT == SP_4x4D_128 #define PAGE_SEGMENT_UPDATE(AXIS, VALUE) do{ \ - if ((VALUE) < 7) dm[_AXIS(AXIS)] = true; \ - else if ((VALUE) > 7) dm[_AXIS(AXIS)] = false; \ + if ((VALUE) < 7) dm[_AXIS(AXIS)] = false; \ + else if ((VALUE) > 7) dm[_AXIS(AXIS)] = true; \ page_step_state.sd[_AXIS(AXIS)] = VALUE; \ page_step_state.bd[_AXIS(AXIS)] += VALUE; \ }while(0) @@ -1884,8 +1862,7 @@ void Stepper::pulse_phase_isr() { PAGE_SEGMENT_UPDATE(Z, high >> 4); PAGE_SEGMENT_UPDATE(E, high & 0xF); - if (dm != last_direction_bits) - set_directions(dm); + if (dm != last_direction_bits) set_directions(dm); } break; @@ -2409,29 +2386,16 @@ hal_timer_t Stepper::block_phase_isr() { if (la_active) { const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0; if (la_step_rate != step_rate) { - const bool reverse_e = la_step_rate > step_rate; - la_interval = calc_timer_interval((reverse_e ? la_step_rate - step_rate : step_rate - la_step_rate) >> current_block->la_scaling); + const bool forward_e = la_step_rate < step_rate; + la_interval = calc_timer_interval((forward_e ? step_rate - la_step_rate : la_step_rate - step_rate) >> current_block->la_scaling); - if (reverse_e != motor_direction(E_AXIS)) { + if (forward_e != motor_direction(E_AXIS)) { last_direction_bits.toggle(E_AXIS); count_direction.e = -count_direction.e; DIR_WAIT_BEFORE(); - if (reverse_e) { - #if ENABLED(MIXING_EXTRUDER) - MIXER_STEPPER_LOOP(j) REV_E_DIR(j); - #else - REV_E_DIR(stepper_extruder); - #endif - } - else { - #if ENABLED(MIXING_EXTRUDER) - MIXER_STEPPER_LOOP(j) FWD_E_DIR(j); - #else - FWD_E_DIR(stepper_extruder); - #endif - } + E_APPLY_DIR(forward_e, false); DIR_WAIT_AFTER(); } @@ -2688,13 +2652,13 @@ hal_timer_t Stepper::block_phase_isr() { #if ENABLED(INPUT_SHAPING_X) if (shaping_x.enabled) { - const int64_t steps = current_block->direction_bits.x ? -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 = !current_block->direction_bits.x; + shaping_x.forward = current_block->direction_bits.x; if (!ShapingQueue::empty_x()) current_block->direction_bits.x = last_direction_bits.x; } #endif @@ -2702,9 +2666,9 @@ hal_timer_t Stepper::block_phase_isr() { // 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 = current_block->direction_bits.y ? -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 = !current_block->direction_bits.y; + shaping_y.forward = current_block->direction_bits.y; if (!ShapingQueue::empty_y()) current_block->direction_bits.y = last_direction_bits.y; } #endif @@ -3450,36 +3414,36 @@ void Stepper::report_positions() { #if HAS_Z_AXIS // Z is handled differently to update the stepper // counts (needed by Marlin for bed level probing). - const bool z_dir = TEST(command, FT_BIT_DIR_Z), + const bool z_fwd = TEST(command, FT_BIT_DIR_Z), z_step = TEST(command, FT_BIT_STEP_Z); #endif if (applyDir) { - TERN_(HAS_X_AXIS, X_DIR_WRITE(TEST(command, FT_BIT_DIR_X))); - TERN_(HAS_Y_AXIS, Y_DIR_WRITE(TEST(command, FT_BIT_DIR_Y))); - TERN_(HAS_Z_AXIS, Z_DIR_WRITE(z_dir)); - TERN_(HAS_EXTRUDERS, E0_DIR_WRITE(TEST(command, FT_BIT_DIR_E))); + TERN_(HAS_X_AXIS, X_APPLY_DIR(TEST(command, FT_BIT_DIR_X), false)); + TERN_(HAS_Y_AXIS, Y_APPLY_DIR(TEST(command, FT_BIT_DIR_Y), false)); + TERN_(HAS_Z_AXIS, Z_APPLY_DIR(z_fwd, false)); + TERN_(HAS_EXTRUDERS, E_APPLY_DIR(TEST(command, FT_BIT_DIR_E), false)); DIR_WAIT_AFTER(); } - TERN_(HAS_X_AXIS, X_STEP_WRITE(TEST(command, FT_BIT_STEP_X))); - TERN_(HAS_Y_AXIS, Y_STEP_WRITE(TEST(command, FT_BIT_STEP_Y))); - TERN_(HAS_Z_AXIS, Z_STEP_WRITE(z_step)); - TERN_(HAS_EXTRUDERS, E0_STEP_WRITE(TEST(command, FT_BIT_STEP_E))); + TERN_(HAS_X_AXIS, X_APPLY_STEP(TEST(command, FT_BIT_STEP_X), false)); + TERN_(HAS_Y_AXIS, Y_APPLY_STEP(TEST(command, FT_BIT_STEP_Y), false)); + TERN_(HAS_Z_AXIS, Z_APPLY_STEP(z_step, false)); + TERN_(HAS_EXTRUDERS, E_APPLY_STEP(TEST(command, FT_BIT_STEP_E), false)); START_TIMED_PULSE(); #if HAS_Z_AXIS // Update step counts - if (z_step) count_position.z += z_dir ? 1 : -1; + if (z_step) count_position.z += z_fwd ? 1 : -1; #endif AWAIT_HIGH_PULSE(); - X_STEP_WRITE(0); - TERN_(HAS_Y_AXIS, Y_STEP_WRITE(0)); - TERN_(HAS_Z_AXIS, Z_STEP_WRITE(0)); - TERN_(HAS_EXTRUDERS, E0_STEP_WRITE(0)); + TERN_(HAS_X_AXIS, X_APPLY_STEP(0, false)); + TERN_(HAS_Y_AXIS, Y_APPLY_STEP(0, false)); + TERN_(HAS_Z_AXIS, Z_APPLY_STEP(0, false)); + TERN_(HAS_EXTRUDERS, E_APPLY_STEP(0, false)); } // Stepper::fxdTiCtrl_stepper @@ -3565,7 +3529,7 @@ void Stepper::report_positions() { #define _ENABLE_AXIS(A) enable_axis(_AXIS(A)) #define _READ_DIR(AXIS) AXIS ##_DIR_READ() - #define _APPLY_DIR(AXIS, INVERT) AXIS ##_APPLY_DIR(INVERT, true) + #define _APPLY_DIR(AXIS, FWD) AXIS ##_APPLY_DIR(FWD, true) #if MINIMUM_STEPPER_PULSE #define STEP_PULSE_CYCLES ((MINIMUM_STEPPER_PULSE) * CYCLES_PER_MICROSECOND) diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index 134bee7ac6..a2c9861abc 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -524,7 +524,7 @@ class Stepper { // Quickly stop all steppers FORCE_INLINE static void quick_stop() { abort_current_block = true; } - // The direction of a single motor. A true result indicates reversed or negative motion. + // The direction of a single motor. A true result indicates forward or positive motion. 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.