From 9ee891c4a602b8cbdf1f477e28b4e1bc9003fd99 Mon Sep 17 00:00:00 2001 From: Giuliano Zaro <3684609+GMagician@users.noreply.github.com> Date: Tue, 7 Jul 2020 00:32:33 +0200 Subject: [PATCH] Fix TMC homing phase coils alignment (#18528) Co-authored-by: Fabio Santos --- Marlin/src/feature/tmc_util.cpp | 22 +++++++++- Marlin/src/module/motion.cpp | 71 +++++++++++++++++---------------- 2 files changed, 57 insertions(+), 36 deletions(-) diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index fe8fe06d6f..a8a1f5075b 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -480,6 +480,10 @@ TMC_GLOBAL_SCALER, TMC_CS_ACTUAL, TMC_PWM_SCALE, + TMC_PWM_SCALE_SUM, + TMC_PWM_SCALE_AUTO, + TMC_PWM_OFS_AUTO, + TMC_PWM_GRAD_AUTO, TMC_VSENSE, TMC_STEALTHCHOP, TMC_MICROSTEPS, @@ -492,7 +496,8 @@ TMC_TBL, TMC_HEND, TMC_HSTRT, - TMC_SGT + TMC_SGT, + TMC_MSCNT }; enum TMC_drv_status_enum : char { TMC_DRV_CODES, @@ -591,7 +596,10 @@ #if HAS_TMC220x static void _tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) { switch (i) { - case TMC_PWM_SCALE: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break; + case TMC_PWM_SCALE_SUM: SERIAL_PRINT(st.pwm_scale_sum(), DEC); break; + case TMC_PWM_SCALE_AUTO: SERIAL_PRINT(st.pwm_scale_auto(), DEC); break; + case TMC_PWM_OFS_AUTO: SERIAL_PRINT(st.pwm_ofs_auto(), DEC); break; + case TMC_PWM_GRAD_AUTO: SERIAL_PRINT(st.pwm_grad_auto(), DEC); break; case TMC_STEALTHCHOP: serialprint_truefalse(st.stealth()); break; case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('*'); break; case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('*'); break; @@ -680,6 +688,7 @@ case TMC_TBL: SERIAL_PRINT(st.blank_time(), DEC); break; case TMC_HEND: SERIAL_PRINT(st.hysteresis_end(), DEC); break; case TMC_HSTRT: SERIAL_PRINT(st.hysteresis_start(), DEC); break; + case TMC_MSCNT: SERIAL_PRINT(st.get_microstep_counter(), DEC); break; default: _tmc_status(st, i); break; } } @@ -900,11 +909,20 @@ #if ENABLED(MONITOR_DRIVER_STATUS) TMC_REPORT("triggered\n OTP\t", TMC_OTPW_TRIGGERED); #endif + + #if HAS_TMC220x + TMC_REPORT("pwm scale sum", TMC_PWM_SCALE_SUM); + TMC_REPORT("pwm scale auto", TMC_PWM_SCALE_AUTO); + TMC_REPORT("pwm offset auto", TMC_PWM_OFS_AUTO); + TMC_REPORT("pwm grad auto", TMC_PWM_GRAD_AUTO); + #endif + TMC_REPORT("off time", TMC_TOFF); TMC_REPORT("blank time", TMC_TBL); TMC_REPORT("hysteresis\n -end\t", TMC_HEND); TMC_REPORT(" -start\t", TMC_HSTRT); TMC_REPORT("Stallguard thrs", TMC_SGT); + TMC_REPORT("uStep count", TMC_MSCNT); DRV_REPORT("DRVSTATUS", TMC_DRV_CODES); #if HAS_TMCX1X0 || HAS_TMC220x DRV_REPORT("sg_result", TMC_SG_RESULT); diff --git a/Marlin/src/module/motion.cpp b/Marlin/src/module/motion.cpp index 1994280a2c..f7732f577f 100644 --- a/Marlin/src/module/motion.cpp +++ b/Marlin/src/module/motion.cpp @@ -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