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 <fabiosan@live.com>
---
 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