|
|
@ -1443,65 +1443,69 @@ void set_axis_not_trusted(const AxisEnum axis) { |
|
|
|
TERN_(I2C_POSITION_ENCODERS, I2CPEM.unhomed(axis)); |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* Move the axis back to its home_phase if set and driver is capable (TMC) |
|
|
|
* |
|
|
|
* Improves homing repeatability by homing to stepper coil's nearest absolute |
|
|
|
* phase position. Trinamic drivers use a stepper phase table with 1024 values |
|
|
|
* spanning 4 full steps with 256 positions each (ergo, 1024 positions). |
|
|
|
*/ |
|
|
|
void backout_to_tmc_homing_phase(const AxisEnum axis) { |
|
|
|
#ifdef TMC_HOME_PHASE |
|
|
|
const abc_long_t home_phase = TMC_HOME_PHASE; |
|
|
|
#ifdef TMC_HOME_PHASE |
|
|
|
/**
|
|
|
|
* Move the axis back to its home_phase if set and driver is capable (TMC) |
|
|
|
* |
|
|
|
* Improves homing repeatability by homing to stepper coil's nearest absolute |
|
|
|
* phase position. Trinamic drivers use a stepper phase table with 1024 values |
|
|
|
* spanning 4 full steps with 256 positions each (ergo, 1024 positions). |
|
|
|
*/ |
|
|
|
void backout_to_tmc_homing_phase(const AxisEnum axis) { |
|
|
|
const xyz_long_t home_phase = TMC_HOME_PHASE; |
|
|
|
|
|
|
|
// check if home phase is disabled for this axis.
|
|
|
|
if (home_phase[axis] < 0) return; |
|
|
|
|
|
|
|
int16_t axisMicrostepSize; |
|
|
|
int16_t phaseCurrent; |
|
|
|
bool invertDir; |
|
|
|
int16_t phasePerUStep, // TMC µsteps(phase) per Marlin µsteps
|
|
|
|
phaseCurrent, // The TMC µsteps(phase) count of the current position
|
|
|
|
effectorBackoutDir, // Direction in which the effector mm coordinates move away from endstop.
|
|
|
|
stepperBackoutDir; // Direction in which the TMC µstep count(phase) move away from endstop.
|
|
|
|
|
|
|
|
switch (axis) { |
|
|
|
#ifdef X_MICROSTEPS |
|
|
|
case X_AXIS: |
|
|
|
axisMicrostepSize = 256 / (X_MICROSTEPS); |
|
|
|
phasePerUStep = 256 / (X_MICROSTEPS); |
|
|
|
phaseCurrent = stepperX.get_microstep_counter(); |
|
|
|
invertDir = INVERT_X_DIR; |
|
|
|
effectorBackoutDir = -X_HOME_DIR; |
|
|
|
stepperBackoutDir = INVERT_X_DIR ? effectorBackoutDir : -effectorBackoutDir; |
|
|
|
break; |
|
|
|
#endif |
|
|
|
#ifdef Y_MICROSTEPS |
|
|
|
case Y_AXIS: |
|
|
|
axisMicrostepSize = 256 / (Y_MICROSTEPS); |
|
|
|
phasePerUStep = 256 / (Y_MICROSTEPS); |
|
|
|
phaseCurrent = stepperY.get_microstep_counter(); |
|
|
|
invertDir = INVERT_Y_DIR; |
|
|
|
effectorBackoutDir = -Y_HOME_DIR; |
|
|
|
stepperBackoutDir = INVERT_Y_DIR ? effectorBackoutDir : -effectorBackoutDir; |
|
|
|
break; |
|
|
|
#endif |
|
|
|
#ifdef Z_MICROSTEPS |
|
|
|
case Z_AXIS: |
|
|
|
axisMicrostepSize = 256 / (Z_MICROSTEPS); |
|
|
|
phasePerUStep = 256 / (Z_MICROSTEPS); |
|
|
|
phaseCurrent = stepperZ.get_microstep_counter(); |
|
|
|
invertDir = INVERT_Z_DIR; |
|
|
|
effectorBackoutDir = -Z_HOME_DIR; |
|
|
|
stepperBackoutDir = INVERT_Z_DIR ? effectorBackoutDir : -effectorBackoutDir; |
|
|
|
break; |
|
|
|
#endif |
|
|
|
default: return; |
|
|
|
} |
|
|
|
|
|
|
|
// Depending on invert dir measure the distance to nearest home phase.
|
|
|
|
int16_t phaseDelta = (invertDir ? -1 : 1) * (home_phase[axis] - phaseCurrent); |
|
|
|
// Phase distance to nearest home phase position when moving in the backout direction from endstop(may be negative).
|
|
|
|
int16_t phaseDelta = (home_phase[axis] - phaseCurrent) * stepperBackoutDir; |
|
|
|
|
|
|
|
// Check if home distance within endstop assumed repeatability noise of .05mm and warn.
|
|
|
|
if (ABS(phaseDelta) * planner.steps_to_mm[axis] / axisMicrostepSize < 0.05f) |
|
|
|
DEBUG_ECHOLNPAIR("Selected home phase ", home_phase[axis], |
|
|
|
if (ABS(phaseDelta) * planner.steps_to_mm[axis] / phasePerUStep < 0.05f) |
|
|
|
SERIAL_ECHOLNPAIR("Selected home phase ", home_phase[axis], |
|
|
|
" too close to endstop trigger phase ", phaseCurrent, |
|
|
|
". Pick a different phase for ", axis_codes[axis]); |
|
|
|
|
|
|
|
// Skip to next if target position is behind current. So it only moves away from endstop.
|
|
|
|
if (phaseDelta < 0) phaseDelta += 1024; |
|
|
|
|
|
|
|
// Get the integer µsteps to target. Unreachable phase? Consistently stop at the µstep before / after based on invertDir.
|
|
|
|
const float mmDelta = -(int16_t(phaseDelta / axisMicrostepSize) * planner.steps_to_mm[axis] * (Z_HOME_DIR)); |
|
|
|
// Convert TMC µsteps(phase) to whole Marlin µsteps to effector backout direction to mm
|
|
|
|
const float mmDelta = int16_t(phaseDelta / phasePerUStep) * effectorBackoutDir * planner.steps_to_mm[axis]; |
|
|
|
|
|
|
|
// optional debug messages.
|
|
|
|
// Optional debug messages
|
|
|
|
if (DEBUGGING(LEVELING)) { |
|
|
|
DEBUG_ECHOLNPAIR( |
|
|
|
"Endstop ", axis_codes[axis], " hit at Phase:", phaseCurrent, |
|
|
@ -1510,14 +1514,11 @@ void backout_to_tmc_homing_phase(const AxisEnum axis) { |
|
|
|
} |
|
|
|
|
|
|
|
if (mmDelta != 0) { |
|
|
|
// retrace by the amount computed in mmDelta.
|
|
|
|
// Retrace by the amount computed in mmDelta.
|
|
|
|
do_homing_move(axis, mmDelta, get_homing_bump_feedrate(axis)); |
|
|
|
} |
|
|
|
#else |
|
|
|
UNUSED(axis); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
/**
|
|
|
|
* Home an individual "raw axis" to its endstop. |
|
|
@ -1748,8 +1749,10 @@ void homeaxis(const AxisEnum axis) { |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
// move back to homing phase if configured and capable
|
|
|
|
backout_to_tmc_homing_phase(axis); |
|
|
|
#ifdef TMC_HOME_PHASE |
|
|
|
// move back to homing phase if configured and capable
|
|
|
|
backout_to_tmc_homing_phase(axis); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if IS_SCARA |
|
|
|
|
|
|
|