🐛 Fix FTM E value overflow; 🔧 FTM_DIR_CHANGE_HOLD_* (#28277)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
David Buezas
2026-01-14 00:27:20 +01:00
committed by GitHub
parent 2048e8b173
commit a73b08eba5
4 changed files with 25 additions and 27 deletions

View File

@@ -1238,6 +1238,25 @@
#define FTM_FS 1000 // (Hz) Frequency for trajectory generation.
#define FTM_MIN_SHAPE_FREQ 20 // (Hz) Minimum shaping frequency, lower consumes more RAM
/**
* TMC2208 / TMC2208_STANDALONE drivers require a brief pause after a DIR change
* to prevent a standstill shutdown when using StealthChop (the standalone default).
* These options cause FT Motion to delay for > 750µs after a DIR change on a given axis.
* Disable only if you are certain that this can never happen with your TMC2208s.
*/
#if AXIS_DRIVER_TYPE_X(TMC2208) || AXIS_DRIVER_TYPE_X(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_X
#endif
#if AXIS_DRIVER_TYPE_Y(TMC2208) || AXIS_DRIVER_TYPE_Y(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_Y
#endif
#if AXIS_DRIVER_TYPE_Z(TMC2208) || AXIS_DRIVER_TYPE_Z(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_Z
#endif
#if HAS_E_DRIVER(TMC2208) || HAS_E_DRIVER(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_E
#endif
#endif // FT_MOTION
/**

View File

@@ -360,30 +360,6 @@
#define HAS_FTM_EI_SHAPING 1
#endif
/**
* TMC2208 Direction-Flip Delay
*
* Some TMC2208 / TMC2208_STANDALONE drivers may require a short delay after a DIR change
* to prevent a standstill error, especially when using stealthChop (the standalone default).
*
* When enabled for an axis, FT Motion will hold that axis for > 750µs after a DIR change
* by holding its trajectory coordinate constant for a multiple of FTM_TS frames. For the
* default FTM_FS = 1000, it is a single 1ms frame.
*
* Other axes keep moving normally, and the wait is canceled if the axis flips again.
*/
#if AXIS_DRIVER_TYPE_X(TMC2208) || AXIS_DRIVER_TYPE_X(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_X 1
#endif
#if AXIS_DRIVER_TYPE_Y(TMC2208) || AXIS_DRIVER_TYPE_Y(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_Y 1
#endif
#if AXIS_DRIVER_TYPE_Z(TMC2208) || AXIS_DRIVER_TYPE_Z(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_Z 1
#endif
#if HAS_E_DRIVER(TMC2208) || HAS_E_DRIVER(TMC2208_STANDALONE)
#define FTM_DIR_CHANGE_HOLD_E 1
#endif
#if ANY(FTM_DIR_CHANGE_HOLD_X, FTM_DIR_CHANGE_HOLD_Y, FTM_DIR_CHANGE_HOLD_Z, FTM_DIR_CHANGE_HOLD_E)
#define HAS_FTM_DIR_CHANGE_HOLD 1
#endif

View File

@@ -380,7 +380,7 @@ bool FTMotion::plan_next_block() {
if (current_block->is_sync_pos()) stepper._set_position(current_block->position);
continue;
}
ensure_float_precision();
ensure_extruder_float_precision();
#if ENABLED(POWER_LOSS_RECOVERY)
recovery.info.sdpos = current_block->sdpos;
@@ -441,7 +441,7 @@ bool FTMotion::plan_next_block() {
* resolution = 2^(floor(log2(|x|)) - 23)
* By resetting at ±1'000mm (1 meter), we get a minimum resolution of ~ 0.00006mm, enough for smoothing to work well.
*/
void FTMotion::ensure_float_precision() {
void FTMotion::ensure_extruder_float_precision() {
constexpr float FTM_POSITION_WRAP_THRESHOLD = 1000; // (mm) Reset when position exceeds this to prevent floating point precision loss
if (ABS(endPos_prevBlock.E) < FTM_POSITION_WRAP_THRESHOLD) return;
@@ -462,6 +462,9 @@ bool FTMotion::plan_next_block() {
// Offset linear advance previous position
prev_traj_e += offset;
// Make sure the difference is accounted-for in the past
last_target_traj.e += offset;
// Offset stepper current position
const int64_t delta_steps_q48_16 = offset * planner.settings.axis_steps_per_mm[block_extruder_axis] * (1ULL << 16);
stepping.curr_steps_q48_16.E += delta_steps_q48_16;

View File

@@ -403,7 +403,7 @@ class FTMotion {
static void fill_stepper_plan_buffer();
static xyze_float_t calc_traj_point(const float dist);
static bool plan_next_block();
static void ensure_float_precision() IF_DISABLED(HAS_EXTRUDERS, {});
static void ensure_extruder_float_precision() IF_DISABLED(HAS_EXTRUDERS, {});
}; // class FTMotion