Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tmc2240: adjustable current scaler and current range #556

Merged
merged 7 commits into from
Feb 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ See the [Danger Features document](https://docs.kalico.gg/Danger_Features.html)

- [danger_options: configurable homing constants](https://github.com/KalicoCrew/kalico/pull/378)

- [tmc2240: adjustable driver_CS and current_range](https://github.com/KalicoCrew/kalico/pull/556)

If you're feeling adventurous, take a peek at the extra features in the bleeding-edge-v2 branch [feature documentation](docs/Bleeding_Edge.md)
and [feature configuration reference](docs/Config_Reference_Bleeding_Edge.md):

Expand Down
11 changes: 9 additions & 2 deletions docs/Config_Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2634,11 +2634,11 @@ for more detailed information regarding symptoms, configuration and setup.
calibrate_start_x: 20
# Defines the minimum X coordinate of the calibration
# This should be the X coordinate that positions the nozzle at the starting
# calibration position.
# calibration position.
calibrate_end_x: 200
# Defines the maximum X coordinate of the calibration
# This should be the X coordinate that positions the nozzle at the ending
# calibration position.
# calibration position.
calibrate_y: 112.5
# Defines the Y coordinate of the calibration
# This should be the Y coordinate that positions the nozzle during the
Expand Down Expand Up @@ -4427,6 +4427,13 @@ run_current:
# velocity" threshold (THIGH) to. This is typically used to disable
# the "CoolStep" feature at high speeds. The default is to not set a
# TMC "high velocity" threshold.
#current_range:
# The current_range bit value for the driver. Valid values are 0 and 32-255.
# The defaul is to auto-calculate to match the requested run_current.
# For further information consult the tmc2240 datasheet and tuning table.
#driver_CS: 31
# The current_scaler value for the driver. The default is 31.
# For further information consult the tmc2240 datasheet and tuning table.
#driver_MSLUT0: 2863314260
#driver_MSLUT1: 1251300522
#driver_MSLUT2: 608774441
Expand Down
5 changes: 5 additions & 0 deletions docs/Kalico_Additions.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@
- [`[temperature_fan] reverse: True`](./Config_Reference.md#temperature_fan) will let you control a fan in reverse to temperature control. The lower the temperature, the higher the fan runs.
- Fans now normalize PWM power within `off_below` and `max_power`, so setting a fan to 10% will get you 10% fan speed within your configured off/max range.


## TMC Drivers

- [`[tmc2240] driver_CS and current_range`](./Config_Reference.md#tmc2240) let you tune the current scaler and current range of your tmc2240 drivers.

## Macros

- The jinja `do` extension has been enabled. You can now call functions in your macros without resorting to dirty hacks: `{% do array.append(5) %}`
Expand Down
5 changes: 3 additions & 2 deletions klippy/extras/tmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,13 +773,14 @@ def TMCStealthchopHelper(config, mcu_tmc, tmc_freq):


class BaseTMCCurrentHelper:
def __init__(self, config, mcu_tmc, max_current):
def __init__(self, config, mcu_tmc, max_current, has_sense_resistor=True):
self.printer = config.get_printer()
self.name = config.get_name().split()[-1]
self.mcu_tmc = mcu_tmc
self.fields = mcu_tmc.get_fields()

self.sense_resistor = config.getfloat("sense_resistor", above=0.0)
if has_sense_resistor:
self.sense_resistor = config.getfloat("sense_resistor", above=0.0)

# config_{run|hold|home}_current
# represents an initial value set via config file
Expand Down
77 changes: 37 additions & 40 deletions klippy/extras/tmc2240.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,37 +263,30 @@
# TMC stepper current config helper
######################################################################

KIFS = [11750.0, 24000.0, 36000.0, 36000.0]
GLOBALSCALER_ERROR = (
"[tmc2240 %s]\n"
"GLOBALSCALER(%d) calculation out of bounds.\n"
"The target current can't be achieved with the given RREF(%f) "
"and CS(%d). Please adjust your configuration.\n"
"Calculated current_range bit: %s\n"
"Calculated KIFS: %s"
)


class TMC2240CurrentHelper(tmc.BaseTMCCurrentHelper):
def __init__(self, config, mcu_tmc):
self.printer = config.get_printer()
self.name = config.get_name().split()[-1]
self.mcu_tmc = mcu_tmc
self.fields = mcu_tmc.get_fields()
self.Rref = config.getfloat("rref", minval=12000.0, maxval=60000.0)
self.max_current = self._get_ifs_rms(3)
self.config_run_current = config.getfloat(
"run_current", above=0.0, maxval=self.max_current
)
self.config_hold_current = config.getfloat(
"hold_current", self.max_current, above=0.0, maxval=self.max_current
)
self.config_home_current = config.getfloat(
"home_current",
self.config_run_current,
above=0.0,
maxval=self.max_current,
super().__init__(
config, mcu_tmc, self._get_ifs_rms(3), has_sense_resistor=False
)
self.current_change_dwell_time = config.getfloat(
"current_change_dwell_time", 0.5, above=0.0
)
self.req_run_current = self.config_run_current
self.req_hold_current = self.config_hold_current
self.req_home_current = self.config_home_current

self.actual_current = self.req_run_current
current_range = self._calc_current_range(self.actual_current)
self.fields.set_field("current_range", current_range)
self.current_range = config.getint(
"current_range", current_range, minval=current_range, maxval=3
)
self.fields.set_field("current_range", self.current_range)
self.cs = config.getint("driver_CS", 31, minval=0, maxval=31)
gscaler, irun, ihold = self._calc_current(
self.req_run_current, self.req_hold_current
)
Expand All @@ -304,7 +297,6 @@ def __init__(self, config, mcu_tmc):
def _get_ifs_rms(self, current_range=None):
if current_range is None:
current_range = self.fields.get_field("current_range")
KIFS = [11750.0, 24000.0, 36000.0, 36000.0]
return (KIFS[current_range] / self.Rref) / math.sqrt(2.0)

def _calc_current_range(self, current):
Expand All @@ -315,25 +307,30 @@ def _calc_current_range(self, current):

def _calc_globalscaler(self, current):
ifs_rms = self._get_ifs_rms()
globalscaler = int(((current * 256.0) / ifs_rms) + 0.5)
globalscaler = max(32, globalscaler)
if globalscaler >= 256:
globalscaler = 0
return globalscaler

def _calc_current_bits(self, current, globalscaler):
ifs_rms = self._get_ifs_rms()
if not globalscaler:
globalscaler = 256
cs = int(
(current * 256.0 * 32.0) / (globalscaler * ifs_rms) - 1.0 + 0.5
globalscaler = math.floor(
(current * 256.0 * 32) / (ifs_rms * (self.cs + 1))
)
return max(0, min(31, cs))
if globalscaler == 256:
return 0
if 1 <= globalscaler <= 31 or globalscaler > 256:
current_range = self.fields.get_field("current_range")
self.printer.invoke_shutdown(
GLOBALSCALER_ERROR
% (
self.name,
globalscaler,
self.Rref,
self.cs,
f"{current_range:02b}",
f"{(KIFS[current_range] / 1000):.2f}",
)
)
return globalscaler

def _calc_current(self, run_current, hold_current):
gscaler = self._calc_globalscaler(run_current)
irun = self._calc_current_bits(run_current, gscaler)
ihold = self._calc_current_bits(min(hold_current, run_current), gscaler)
irun = self.cs
ihold = math.floor((min((hold_current / run_current) * irun, irun)))
return gscaler, irun, ihold

def _calc_current_from_field(self, field_name):
Expand Down
2 changes: 2 additions & 0 deletions test/klippy/tmc.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ rotation_distance: 8
cs_pin: PK3
run_current: .5
rref: 12000
driver_CS: 30
current_range: 0

[mcu]
serial: /dev/ttyACM0
Expand Down