From ed8dca8df08924e7df9291d5e4ff88c9fee4ca4e Mon Sep 17 00:00:00 2001
From: Alex Voinea <voinea.dragos.alexandru@gmail.com>
Date: Tue, 14 May 2024 22:23:06 +0200
Subject: [PATCH] tmc: Implement high_velocity_threshold for drivers that
 support it

Signed-off-by: Alex Voinea <voinea.dragos.alexandru@gmail.com>
---
 docs/Config_Reference.md | 24 ++++++++++++++++++++++++
 klippy/extras/tmc.py     | 17 +++++++++++++++++
 klippy/extras/tmc2130.py |  1 +
 klippy/extras/tmc2240.py |  1 +
 klippy/extras/tmc5160.py |  4 ++++
 5 files changed, 47 insertions(+)

diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md
index d48715d87..9a26556f0 100644
--- a/docs/Config_Reference.md
+++ b/docs/Config_Reference.md
@@ -3324,6 +3324,14 @@ run_current:
 #   - if coolstep_threshold is set and "sensorless homing" is used,
 #   then one must ensure that the homing speed is above the coolstep
 #   threshold! The default is to not enable the coolstep feature.
+#high_velocity_threshold:
+#   The velocity (in mm/s) to set the TMC driver internal "high
+#   velocity" threshold (THIGH) to. This is typically used to disable
+#   the "CoolStep" feature at high speeds. Important - if
+#   high_velocity_threshold is set and "sensorless homing" is used,
+#   then one must ensure that the homing speed is below the high
+#   velocity threshold! The default is to not set a TMC "high
+#   velocity" threshold.
 #driver_MSLUT0: 2863314260
 #driver_MSLUT1: 1251300522
 #driver_MSLUT2: 608774441
@@ -3635,6 +3643,14 @@ run_current:
 #   - if coolstep_threshold is set and "sensorless homing" is used,
 #   then one must ensure that the homing speed is above the coolstep
 #   threshold! The default is to not enable the coolstep feature.
+#high_velocity_threshold:
+#   The velocity (in mm/s) to set the TMC driver internal "high
+#   velocity" threshold (THIGH) to. This is typically used to disable
+#   the "CoolStep" feature at high speeds. Important - if
+#   high_velocity_threshold is set and "sensorless homing" is used,
+#   then one must ensure that the homing speed is below the high
+#   velocity threshold! The default is to not set a TMC "high
+#   velocity" threshold.
 #driver_MSLUT0: 2863314260
 #driver_MSLUT1: 1251300522
 #driver_MSLUT2: 608774441
@@ -3763,6 +3779,14 @@ run_current:
 #   - if coolstep_threshold is set and "sensorless homing" is used,
 #   then one must ensure that the homing speed is above the coolstep
 #   threshold! The default is to not enable the coolstep feature.
+#high_velocity_threshold:
+#   The velocity (in mm/s) to set the TMC driver internal "high
+#   velocity" threshold (THIGH) to. This is typically used to disable
+#   the "CoolStep" feature at high speeds. Important - if
+#   high_velocity_threshold is set and "sensorless homing" is used,
+#   then one must ensure that the homing speed is below the high
+#   velocity threshold! The default is to not set a TMC "high
+#   velocity" threshold.
 #driver_MSLUT0: 2863314260
 #driver_MSLUT1: 1251300522
 #driver_MSLUT2: 608774441
diff --git a/klippy/extras/tmc.py b/klippy/extras/tmc.py
index e7c0239f0..366e00b15 100644
--- a/klippy/extras/tmc.py
+++ b/klippy/extras/tmc.py
@@ -632,3 +632,20 @@ def TMCVcoolthrsHelper(config, mcu_tmc):
         tcoolthrs = TMCtstepHelper(step_dist, mres,
                                    mcu_tmc.get_tmc_frequency(), velocity)
     fields.set_field("tcoolthrs", tcoolthrs)
+
+# Helper to configure StallGuard and CoolStep maximum velocity and
+# SpreadCycle-FullStepping (High velocity) mode threshold.
+def TMCVhighHelper(config, mcu_tmc):
+    fields = mcu_tmc.get_fields()
+    velocity = config.getfloat('high_velocity_threshold', None, minval=0.)
+    thigh = 0
+
+    if velocity is not None:
+        stepper_name = " ".join(config.get_name().split()[1:])
+        sconfig = config.getsection(stepper_name)
+        rotation_dist, steps_per_rotation = stepper.parse_step_distance(sconfig)
+        step_dist = rotation_dist / steps_per_rotation
+        mres = fields.get_field("mres")
+        thigh = TMCtstepHelper(step_dist, mres,
+                                   mcu_tmc.get_tmc_frequency(), velocity)
+    fields.set_field("thigh", thigh)
diff --git a/klippy/extras/tmc2130.py b/klippy/extras/tmc2130.py
index 44d4342ba..20a25c66c 100644
--- a/klippy/extras/tmc2130.py
+++ b/klippy/extras/tmc2130.py
@@ -298,6 +298,7 @@ class TMC2130:
         tmc.TMCWaveTableHelper(config, self.mcu_tmc)
         tmc.TMCStealthchopHelper(config, self.mcu_tmc)
         tmc.TMCVcoolthrsHelper(config, self.mcu_tmc)
+        tmc.TMCVhighHelper(config, self.mcu_tmc)
         # Allow other registers to be set from the config
         set_config_field = self.fields.set_config_field
         # CHOPCONF
diff --git a/klippy/extras/tmc2240.py b/klippy/extras/tmc2240.py
index 3989b9021..1e2a49157 100644
--- a/klippy/extras/tmc2240.py
+++ b/klippy/extras/tmc2240.py
@@ -366,6 +366,7 @@ class TMC2240:
         self.fields.set_config_field(config, "offset_sin90", 0)
         tmc.TMCStealthchopHelper(config, self.mcu_tmc)
         tmc.TMCVcoolthrsHelper(config, self.mcu_tmc)
+        tmc.TMCVhighHelper(config, self.mcu_tmc)
         # Allow other registers to be set from the config
         set_config_field = self.fields.set_config_field
         #   GCONF
diff --git a/klippy/extras/tmc5160.py b/klippy/extras/tmc5160.py
index 97d2d6f94..02e16cd4d 100644
--- a/klippy/extras/tmc5160.py
+++ b/klippy/extras/tmc5160.py
@@ -242,6 +242,9 @@ Fields["TCOOLTHRS"] = {
 Fields["TSTEP"] = {
     "tstep":                    0xfffff << 0
 }
+Fields["THIGH"] = {
+    "thigh":                    0xfffff << 0
+}
 
 SignedFields = ["cur_a", "cur_b", "sgt", "xactual", "vactual", "pwm_scale_auto"]
 
@@ -337,6 +340,7 @@ class TMC5160:
         tmc.TMCWaveTableHelper(config, self.mcu_tmc)
         tmc.TMCStealthchopHelper(config, self.mcu_tmc)
         tmc.TMCVcoolthrsHelper(config, self.mcu_tmc)
+        tmc.TMCVhighHelper(config, self.mcu_tmc)
         # Allow other registers to be set from the config
         set_config_field = self.fields.set_config_field
         #   GCONF