🐛 Fix FT Motion TMC2208 shutdown (#28257)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
David Buezas 2026-01-11 02:44:51 +01:00 committed by GitHub
parent 75f0939b44
commit 1e457650f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 106 additions and 20 deletions

View file

@ -359,6 +359,34 @@
#if ANY(FTM_SHAPER_EI, FTM_SHAPER_2HEI, FTM_SHAPER_3HEI)
#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
#endif
// Standard Motion

View file

@ -75,6 +75,10 @@ xyze_pos_t FTMotion::startPos, // (mm) Start position of bl
xyze_float_t FTMotion::ratio; // (ratio) Axis move ratio of block
float FTMotion::tau = 0.0f; // (s) Time since start of block
bool FTMotion::fastForwardUntilMotion = false; // Fast forward time if there is no motion
#if HAS_FTM_DIR_CHANGE_HOLD
xyze_uint_t FTMotion::hold_frames; // Briefly hold motion after direction changes to fix TMC2208 bug
AxisBits FTMotion::last_traj_dir; // Direction of the last trajectory point after shaping, smoothing, ...
#endif
// Trajectory generators
TrapezoidalTrajectoryGenerator FTMotion::trapezoidalGenerator;
@ -245,7 +249,11 @@ void FTMotion::reset() {
TERN_(DISTINCT_E_FACTORS, block_extruder_axis = E_AXIS);
moving_axis_flags.reset();
last_target_traj.reset();
#if HAS_FTM_DIR_CHANGE_HOLD
last_traj_dir.reset();
hold_frames.reset();
#endif
if (did_suspend) stepper.wake_up();
}
@ -412,7 +420,7 @@ bool FTMotion::plan_next_block() {
TERN_(FTM_HAS_LIN_ADVANCE, use_advance_lead = current_block->use_advance_lead);
axis_move_dir = current_block->direction_bits;
#define _SET_MOVE_END(A) moving_axis_flags.A = moveDist.A ? true : false;
#define _SET_MOVE_END(A) moving_axis_flags.A = bool(moveDist.A);
LOGICAL_AXIS_MAP(_SET_MOVE_END);
@ -612,7 +620,38 @@ void FTMotion::fill_stepper_plan_buffer() {
// It eliminates idle time when changing smoothing time or shapers and speeds up homing and bed leveling.
}
else {
#if HAS_FTM_DIR_CHANGE_HOLD
// When a flip is detected (and the axis is in stealthChop or is standalone),
// hold that axis' trajectory coordinate constant for at least 750µs.
#define DIR_FLIP_HOLD_S 0.000'750f
static constexpr uint32_t dir_flip_hold_frames = DIR_FLIP_HOLD_S / (FTM_TS + 1);
auto start_hold_if_dir_flip = [&](const AxisEnum a) {
const bool dir = traj_coords[a] > last_target_traj[a],
moved = traj_coords[a] != last_target_traj[a],
flipped = moved && (dir != last_traj_dir[a]),
hold = !moved || (flipped && hold_frames[a] > 0);
if (hold) {
if (hold_frames[a]) hold_frames[a]--;
traj_coords[a] = last_target_traj[a];
}
else {
last_traj_dir[a] = dir;
hold_frames[a] = dir_flip_hold_frames;
}
};
#define START_HOLD_IF_DIR_FLIP(A) TERN_(FTM_DIR_CHANGE_HOLD_##A, start_hold_if_dir_flip(_AXIS(A)));
LOGICAL_AXIS_MAP(START_HOLD_IF_DIR_FLIP);
#endif // HAS_FTM_DIR_CHANGE_HOLD
fastForwardUntilMotion = false;
// Calculate and store stepper plan in buffer
stepping_enqueue(traj_coords);
}

View file

@ -332,6 +332,11 @@ class FTMotion {
static float tau; // (s) Time since start of block
static bool fastForwardUntilMotion; // Fast forward time if there is no motion
#if HAS_FTM_DIR_CHANGE_HOLD
static xyze_uint_t hold_frames; // Briefly hold motion after direction changes to fix TMC2208 bug
static AxisBits last_traj_dir; // Direction of the last trajectory point after shaping, smoothing, ...
#endif
// Trajectory generators
static TrapezoidalTrajectoryGenerator trapezoidalGenerator;
#if ENABLED(FTM_POLYS)

View file

@ -3376,6 +3376,10 @@ void Stepper::init() {
#endif // HAS_ZV_SHAPING
/**
* Position
*/
/**
* Set the stepper positions directly in steps
*
@ -3502,20 +3506,11 @@ void Stepper::set_axis_position(const AxisEnum a, const int32_t &v) {
AVR_ATOMIC_SECTION_END();
}
#endif // HAS_EXTRUDERS
#endif
#if ENABLED(FT_MOTION)
void Stepper::ftMotion_syncPosition() {
planner.synchronize();
// Update stepper positions from the planner
AVR_ATOMIC_SECTION_START();
count_position = planner.position;
AVR_ATOMIC_SECTION_END();
}
#endif // FT_MOTION
/**
* Endstops
*/
/**
* Record stepper positions and discard the rest of the current block
@ -3561,6 +3556,10 @@ int32_t Stepper::triggered_position(const AxisEnum axis) {
return v;
}
/**
* Reporting
*/
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX, IS_SCARA, DELTA)
#define SAYS_A 1
#endif
@ -3592,6 +3591,15 @@ void Stepper::report_positions() {
#if ENABLED(FT_MOTION)
void Stepper::ftMotion_syncPosition() {
planner.synchronize();
// Update stepper positions from the planner
AVR_ATOMIC_SECTION_START();
count_position = planner.position;
AVR_ATOMIC_SECTION_END();
}
/**
* Run stepping for FT Motion from the Stepper ISR at regular short intervals.
*
@ -3686,6 +3694,10 @@ void Stepper::report_positions() {
#endif // FT_MOTION
/**
* Babystepping
*/
#if ENABLED(BABYSTEPPING)
#define _ENABLE_AXIS(A) enable_axis(_AXIS(A))

View file

@ -11,11 +11,13 @@ set -e
#
restore_configs
opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V1_0 SERIAL_PORT 1 SERIAL_PORT_2 -1 \
X_DRIVER_TYPE TMC2209 Y_DRIVER_TYPE TMC2209 Z_DRIVER_TYPE TMC2209 E0_DRIVER_TYPE TMC2209 \
X_DRIVER_TYPE TMC2208 Y_DRIVER_TYPE TMC2208 Z_DRIVER_TYPE TMC2208 E0_DRIVER_TYPE TMC2208 \
X_CURRENT_HOME X_CURRENT/2 Y_CURRENT_HOME Y_CURRENT/2 Z_CURRENT_HOME Y_CURRENT/2
opt_enable CR10_STOCKDISPLAY PINS_DEBUGGING Z_IDLE_HEIGHT EDITABLE_HOMING_CURRENT \
INPUT_SHAPING_X INPUT_SHAPING_Y FT_MOTION FT_MOTION_MENU FTM_RESONANCE_TEST EMERGENCY_PARSER \
opt_enable CR10_STOCKDISPLAY EMERGENCY_PARSER Z_IDLE_HEIGHT EDITABLE_HOMING_CURRENT \
INPUT_SHAPING_X INPUT_SHAPING_Y \
FT_MOTION FT_MOTION_MENU FTM_RESONANCE_TEST \
BIQU_MICROPROBE_V1 PROBE_ENABLE_DISABLE Z_SAFE_HOMING AUTO_BED_LEVELING_BILINEAR \
ADAPTIVE_STEP_SMOOTHING LIN_ADVANCE SMOOTH_LIN_ADVANCE NONLINEAR_EXTRUSION
ADAPTIVE_STEP_SMOOTHING LIN_ADVANCE SMOOTH_LIN_ADVANCE NONLINEAR_EXTRUSION \
PINS_DEBUGGING
opt_disable FTM_POLYS
exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - TMC2209 HW Serial, FT_MOTION w/out FTM_POLYS" "$3"
exec_test $1 $2 "BigTreeTech SKR Mini E3 1.0 - TMC2208 HW Serial, FT_MOTION w/out FTM_POLYS" "$3"