aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/extras/tmc2130.py
diff options
context:
space:
mode:
Diffstat (limited to 'klippy/extras/tmc2130.py')
-rw-r--r--klippy/extras/tmc2130.py320
1 files changed, 211 insertions, 109 deletions
diff --git a/klippy/extras/tmc2130.py b/klippy/extras/tmc2130.py
index 181fe07a..88c7fcf4 100644
--- a/klippy/extras/tmc2130.py
+++ b/klippy/extras/tmc2130.py
@@ -6,109 +6,183 @@
import math, logging
from . import bus, tmc
-TMC_FREQUENCY=13200000.
+TMC_FREQUENCY = 13200000.0
Registers = {
- "GCONF": 0x00, "GSTAT": 0x01, "IOIN": 0x04, "IHOLD_IRUN": 0x10,
- "TPOWERDOWN": 0x11, "TSTEP": 0x12, "TPWMTHRS": 0x13, "TCOOLTHRS": 0x14,
- "THIGH": 0x15, "XDIRECT": 0x2d, "MSLUT0": 0x60, "MSLUT1": 0x61,
- "MSLUT2": 0x62, "MSLUT3": 0x63, "MSLUT4": 0x64, "MSLUT5": 0x65,
- "MSLUT6": 0x66, "MSLUT7": 0x67, "MSLUTSEL": 0x68, "MSLUTSTART": 0x69,
- "MSCNT": 0x6a, "MSCURACT": 0x6b, "CHOPCONF": 0x6c, "COOLCONF": 0x6d,
- "DCCTRL": 0x6e, "DRV_STATUS": 0x6f, "PWMCONF": 0x70, "PWM_SCALE": 0x71,
- "ENCM_CTRL": 0x72, "LOST_STEPS": 0x73,
+ "GCONF": 0x00,
+ "GSTAT": 0x01,
+ "IOIN": 0x04,
+ "IHOLD_IRUN": 0x10,
+ "TPOWERDOWN": 0x11,
+ "TSTEP": 0x12,
+ "TPWMTHRS": 0x13,
+ "TCOOLTHRS": 0x14,
+ "THIGH": 0x15,
+ "XDIRECT": 0x2D,
+ "MSLUT0": 0x60,
+ "MSLUT1": 0x61,
+ "MSLUT2": 0x62,
+ "MSLUT3": 0x63,
+ "MSLUT4": 0x64,
+ "MSLUT5": 0x65,
+ "MSLUT6": 0x66,
+ "MSLUT7": 0x67,
+ "MSLUTSEL": 0x68,
+ "MSLUTSTART": 0x69,
+ "MSCNT": 0x6A,
+ "MSCURACT": 0x6B,
+ "CHOPCONF": 0x6C,
+ "COOLCONF": 0x6D,
+ "DCCTRL": 0x6E,
+ "DRV_STATUS": 0x6F,
+ "PWMCONF": 0x70,
+ "PWM_SCALE": 0x71,
+ "ENCM_CTRL": 0x72,
+ "LOST_STEPS": 0x73,
}
ReadRegisters = [
- "GCONF", "GSTAT", "IOIN", "TSTEP", "XDIRECT", "MSCNT", "MSCURACT",
- "CHOPCONF", "DRV_STATUS", "PWM_SCALE", "LOST_STEPS",
+ "GCONF",
+ "GSTAT",
+ "IOIN",
+ "TSTEP",
+ "XDIRECT",
+ "MSCNT",
+ "MSCURACT",
+ "CHOPCONF",
+ "DRV_STATUS",
+ "PWM_SCALE",
+ "LOST_STEPS",
]
Fields = {}
Fields["GCONF"] = {
- "i_scale_analog": 1<<0, "internal_rsense": 1<<1, "en_pwm_mode": 1<<2,
- "enc_commutation": 1<<3, "shaft": 1<<4, "diag0_error": 1<<5,
- "diag0_otpw": 1<<6, "diag0_stall": 1<<7, "diag1_stall": 1<<8,
- "diag1_index": 1<<9, "diag1_onstate": 1<<10, "diag1_steps_skipped": 1<<11,
- "diag0_int_pushpull": 1<<12, "diag1_pushpull": 1<<13,
- "small_hysteresis": 1<<14, "stop_enable": 1<<15, "direct_mode": 1<<16,
- "test_mode": 1<<17
+ "i_scale_analog": 1 << 0,
+ "internal_rsense": 1 << 1,
+ "en_pwm_mode": 1 << 2,
+ "enc_commutation": 1 << 3,
+ "shaft": 1 << 4,
+ "diag0_error": 1 << 5,
+ "diag0_otpw": 1 << 6,
+ "diag0_stall": 1 << 7,
+ "diag1_stall": 1 << 8,
+ "diag1_index": 1 << 9,
+ "diag1_onstate": 1 << 10,
+ "diag1_steps_skipped": 1 << 11,
+ "diag0_int_pushpull": 1 << 12,
+ "diag1_pushpull": 1 << 13,
+ "small_hysteresis": 1 << 14,
+ "stop_enable": 1 << 15,
+ "direct_mode": 1 << 16,
+ "test_mode": 1 << 17,
}
-Fields["GSTAT"] = { "reset": 1<<0, "drv_err": 1<<1, "uv_cp": 1<<2 }
+Fields["GSTAT"] = {"reset": 1 << 0, "drv_err": 1 << 1, "uv_cp": 1 << 2}
Fields["IOIN"] = {
- "step": 1<<0, "dir": 1<<1, "dcen_cfg4": 1<<2, "dcin_cfg5": 1<<3,
- "drv_enn_cfg6": 1<<4, "dco": 1<<5, "version": 0xff << 24
+ "step": 1 << 0,
+ "dir": 1 << 1,
+ "dcen_cfg4": 1 << 2,
+ "dcin_cfg5": 1 << 3,
+ "drv_enn_cfg6": 1 << 4,
+ "dco": 1 << 5,
+ "version": 0xFF << 24,
}
-Fields["IHOLD_IRUN"] = {
- "ihold": 0x1f << 0, "irun": 0x1f << 8, "iholddelay": 0x0f << 16
-}
-Fields["TPOWERDOWN"] = { "tpowerdown": 0xff }
-Fields["TSTEP"] = { "tstep": 0xfffff }
-Fields["TPWMTHRS"] = { "tpwmthrs": 0xfffff }
-Fields["TCOOLTHRS"] = { "tcoolthrs": 0xfffff }
-Fields["THIGH"] = { "thigh": 0xfffff }
-Fields["MSLUT0"] = { "mslut0": 0xffffffff }
-Fields["MSLUT1"] = { "mslut1": 0xffffffff }
-Fields["MSLUT2"] = { "mslut2": 0xffffffff }
-Fields["MSLUT3"] = { "mslut3": 0xffffffff }
-Fields["MSLUT4"] = { "mslut4": 0xffffffff }
-Fields["MSLUT5"] = { "mslut5": 0xffffffff }
-Fields["MSLUT6"] = { "mslut6": 0xffffffff }
-Fields["MSLUT7"] = { "mslut7": 0xffffffff }
+Fields["IHOLD_IRUN"] = {"ihold": 0x1F << 0, "irun": 0x1F << 8, "iholddelay": 0x0F << 16}
+Fields["TPOWERDOWN"] = {"tpowerdown": 0xFF}
+Fields["TSTEP"] = {"tstep": 0xFFFFF}
+Fields["TPWMTHRS"] = {"tpwmthrs": 0xFFFFF}
+Fields["TCOOLTHRS"] = {"tcoolthrs": 0xFFFFF}
+Fields["THIGH"] = {"thigh": 0xFFFFF}
+Fields["MSLUT0"] = {"mslut0": 0xFFFFFFFF}
+Fields["MSLUT1"] = {"mslut1": 0xFFFFFFFF}
+Fields["MSLUT2"] = {"mslut2": 0xFFFFFFFF}
+Fields["MSLUT3"] = {"mslut3": 0xFFFFFFFF}
+Fields["MSLUT4"] = {"mslut4": 0xFFFFFFFF}
+Fields["MSLUT5"] = {"mslut5": 0xFFFFFFFF}
+Fields["MSLUT6"] = {"mslut6": 0xFFFFFFFF}
+Fields["MSLUT7"] = {"mslut7": 0xFFFFFFFF}
Fields["MSLUTSEL"] = {
- "x3": 0xFF << 24,
- "x2": 0xFF << 16,
- "x1": 0xFF << 8,
- "w3": 0x03 << 6,
- "w2": 0x03 << 4,
- "w1": 0x03 << 2,
- "w0": 0x03 << 0,
+ "x3": 0xFF << 24,
+ "x2": 0xFF << 16,
+ "x1": 0xFF << 8,
+ "w3": 0x03 << 6,
+ "w2": 0x03 << 4,
+ "w1": 0x03 << 2,
+ "w0": 0x03 << 0,
}
Fields["MSLUTSTART"] = {
- "start_sin": 0xFF << 0,
- "start_sin90": 0xFF << 16,
+ "start_sin": 0xFF << 0,
+ "start_sin90": 0xFF << 16,
}
-Fields["MSCNT"] = { "mscnt": 0x3ff }
-Fields["MSCURACT"] = { "cur_a": 0x1ff, "cur_b": 0x1ff << 16 }
+Fields["MSCNT"] = {"mscnt": 0x3FF}
+Fields["MSCURACT"] = {"cur_a": 0x1FF, "cur_b": 0x1FF << 16}
Fields["CHOPCONF"] = {
- "toff": 0x0f, "hstrt": 0x07 << 4, "hend": 0x0f << 7, "fd3": 1<<11,
- "disfdcc": 1<<12, "rndtf": 1<<13, "chm": 1<<14, "tbl": 0x03 << 15,
- "vsense": 1<<17, "vhighfs": 1<<18, "vhighchm": 1<<19, "sync": 0x0f << 20,
- "mres": 0x0f << 24, "intpol": 1<<28, "dedge": 1<<29, "diss2g": 1<<30
+ "toff": 0x0F,
+ "hstrt": 0x07 << 4,
+ "hend": 0x0F << 7,
+ "fd3": 1 << 11,
+ "disfdcc": 1 << 12,
+ "rndtf": 1 << 13,
+ "chm": 1 << 14,
+ "tbl": 0x03 << 15,
+ "vsense": 1 << 17,
+ "vhighfs": 1 << 18,
+ "vhighchm": 1 << 19,
+ "sync": 0x0F << 20,
+ "mres": 0x0F << 24,
+ "intpol": 1 << 28,
+ "dedge": 1 << 29,
+ "diss2g": 1 << 30,
}
Fields["COOLCONF"] = {
- "semin": 0x0f, "seup": 0x03 << 5, "semax": 0x0f << 8, "sedn": 0x03 << 13,
- "seimin": 1<<15, "sgt": 0x7f << 16, "sfilt": 1<<24
+ "semin": 0x0F,
+ "seup": 0x03 << 5,
+ "semax": 0x0F << 8,
+ "sedn": 0x03 << 13,
+ "seimin": 1 << 15,
+ "sgt": 0x7F << 16,
+ "sfilt": 1 << 24,
}
Fields["DRV_STATUS"] = {
- "sg_result": 0x3ff, "fsactive": 1<<15, "cs_actual": 0x1f << 16,
- "stallguard": 1<<24, "ot": 1<<25, "otpw": 1<<26, "s2ga": 1<<27,
- "s2gb": 1<<28, "ola": 1<<29, "olb": 1<<30, "stst": 1<<31
+ "sg_result": 0x3FF,
+ "fsactive": 1 << 15,
+ "cs_actual": 0x1F << 16,
+ "stallguard": 1 << 24,
+ "ot": 1 << 25,
+ "otpw": 1 << 26,
+ "s2ga": 1 << 27,
+ "s2gb": 1 << 28,
+ "ola": 1 << 29,
+ "olb": 1 << 30,
+ "stst": 1 << 31,
}
Fields["PWMCONF"] = {
- "pwm_ampl": 0xff, "pwm_grad": 0xff << 8, "pwm_freq": 0x03 << 16,
- "pwm_autoscale": 1<<18, "pwm_symmetric": 1<<19, "freewheel": 0x03 << 20
+ "pwm_ampl": 0xFF,
+ "pwm_grad": 0xFF << 8,
+ "pwm_freq": 0x03 << 16,
+ "pwm_autoscale": 1 << 18,
+ "pwm_symmetric": 1 << 19,
+ "freewheel": 0x03 << 20,
}
-Fields["PWM_SCALE"] = { "pwm_scale": 0xff }
-Fields["LOST_STEPS"] = { "lost_steps": 0xfffff }
+Fields["PWM_SCALE"] = {"pwm_scale": 0xFF}
+Fields["LOST_STEPS"] = {"lost_steps": 0xFFFFF}
SignedFields = ["cur_a", "cur_b", "sgt"]
FieldFormatters = {
- "i_scale_analog": (lambda v: "1(ExtVREF)" if v else ""),
- "shaft": (lambda v: "1(Reverse)" if v else ""),
- "reset": (lambda v: "1(Reset)" if v else ""),
- "drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
- "uv_cp": (lambda v: "1(Undervoltage!)" if v else ""),
- "version": (lambda v: "%#x" % v),
- "mres": (lambda v: "%d(%dusteps)" % (v, 0x100 >> v)),
- "otpw": (lambda v: "1(OvertempWarning!)" if v else ""),
- "ot": (lambda v: "1(OvertempError!)" if v else ""),
- "s2ga": (lambda v: "1(ShortToGND_A!)" if v else ""),
- "s2gb": (lambda v: "1(ShortToGND_B!)" if v else ""),
- "ola": (lambda v: "1(OpenLoad_A!)" if v else ""),
- "olb": (lambda v: "1(OpenLoad_B!)" if v else ""),
- "cs_actual": (lambda v: ("%d" % v) if v else "0(Reset?)"),
+ "i_scale_analog": (lambda v: "1(ExtVREF)" if v else ""),
+ "shaft": (lambda v: "1(Reverse)" if v else ""),
+ "reset": (lambda v: "1(Reset)" if v else ""),
+ "drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
+ "uv_cp": (lambda v: "1(Undervoltage!)" if v else ""),
+ "version": (lambda v: "%#x" % v),
+ "mres": (lambda v: "%d(%dusteps)" % (v, 0x100 >> v)),
+ "otpw": (lambda v: "1(OvertempWarning!)" if v else ""),
+ "ot": (lambda v: "1(OvertempError!)" if v else ""),
+ "s2ga": (lambda v: "1(ShortToGND_A!)" if v else ""),
+ "s2gb": (lambda v: "1(ShortToGND_B!)" if v else ""),
+ "ola": (lambda v: "1(OpenLoad_A!)" if v else ""),
+ "olb": (lambda v: "1(OpenLoad_B!)" if v else ""),
+ "cs_actual": (lambda v: ("%d" % v) if v else "0(Reset?)"),
}
@@ -118,35 +192,39 @@ FieldFormatters = {
MAX_CURRENT = 2.000
+
class TMCCurrentHelper:
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()
- run_current = config.getfloat('run_current',
- above=0., maxval=MAX_CURRENT)
- hold_current = config.getfloat('hold_current', MAX_CURRENT,
- above=0., maxval=MAX_CURRENT)
+ run_current = config.getfloat("run_current", above=0.0, maxval=MAX_CURRENT)
+ hold_current = config.getfloat(
+ "hold_current", MAX_CURRENT, above=0.0, maxval=MAX_CURRENT
+ )
self.req_hold_current = hold_current
- self.sense_resistor = config.getfloat('sense_resistor', 0.110, above=0.)
+ self.sense_resistor = config.getfloat("sense_resistor", 0.110, above=0.0)
vsense, irun, ihold = self._calc_current(run_current, hold_current)
self.fields.set_field("vsense", vsense)
self.fields.set_field("ihold", ihold)
self.fields.set_field("irun", irun)
+
def _calc_current_bits(self, current, vsense):
sense_resistor = self.sense_resistor + 0.020
vref = 0.32
if vsense:
vref = 0.18
- cs = int(32. * sense_resistor * current * math.sqrt(2.) / vref + .5) - 1
+ cs = int(32.0 * sense_resistor * current * math.sqrt(2.0) / vref + 0.5) - 1
return max(0, min(31, cs))
+
def _calc_current_from_bits(self, cs, vsense):
sense_resistor = self.sense_resistor + 0.020
vref = 0.32
if vsense:
vref = 0.18
- return (cs + 1) * vref / (32. * sense_resistor * math.sqrt(2.))
+ return (cs + 1) * vref / (32.0 * sense_resistor * math.sqrt(2.0))
+
def _calc_current(self, run_current, hold_current):
vsense = True
irun = self._calc_current_bits(run_current, True)
@@ -160,6 +238,7 @@ class TMCCurrentHelper:
irun = irun2
ihold = self._calc_current_bits(min(hold_current, run_current), vsense)
return vsense, irun, ihold
+
def get_current(self):
irun = self.fields.get_field("irun")
ihold = self.fields.get_field("ihold")
@@ -167,6 +246,7 @@ class TMCCurrentHelper:
run_current = self._calc_current_from_bits(irun, vsense)
hold_current = self._calc_current_from_bits(ihold, vsense)
return run_current, hold_current, self.req_hold_current, MAX_CURRENT
+
def set_current(self, run_current, hold_current, print_time):
self.req_hold_current = hold_current
vsense, irun, ihold = self._calc_current(run_current, hold_current)
@@ -182,6 +262,7 @@ class TMCCurrentHelper:
# TMC2130 SPI
######################################################################
+
class MCU_TMC_SPI_chain:
def __init__(self, config, chain_len=1):
self.printer = config.get_printer()
@@ -190,25 +271,30 @@ class MCU_TMC_SPI_chain:
share = None
if chain_len > 1:
share = "tmc_spi_cs"
- self.spi = bus.MCU_SPI_from_config(config, 3, default_speed=4000000,
- share_type=share)
+ self.spi = bus.MCU_SPI_from_config(
+ config, 3, default_speed=4000000, share_type=share
+ )
self.taken_chain_positions = []
+
def _build_cmd(self, data, chain_pos):
- return ([0x00] * ((self.chain_len - chain_pos) * 5) +
- data + [0x00] * ((chain_pos - 1) * 5))
+ return (
+ [0x00] * ((self.chain_len - chain_pos) * 5)
+ + data
+ + [0x00] * ((chain_pos - 1) * 5)
+ )
+
def reg_read(self, reg, chain_pos):
cmd = self._build_cmd([reg, 0x00, 0x00, 0x00, 0x00], chain_pos)
self.spi.spi_send(cmd)
- if self.printer.get_start_args().get('debugoutput') is not None:
+ if self.printer.get_start_args().get("debugoutput") is not None:
return {
"spi_status": 0,
"data": 0,
- "#receive_time": .0,
+ "#receive_time": 0.0,
}
params = self.spi.spi_transfer(cmd)
- pr = bytearray(params['response'])
- pr = pr[(self.chain_len - chain_pos) * 5 :
- (self.chain_len - chain_pos + 1) * 5]
+ pr = bytearray(params["response"])
+ pr = pr[(self.chain_len - chain_pos) * 5 : (self.chain_len - chain_pos + 1) * 5]
return {
"spi_status": pr[0],
"data": (pr[1] << 24) | (pr[2] << 16) | (pr[3] << 8) | pr[4],
@@ -219,44 +305,51 @@ class MCU_TMC_SPI_chain:
minclock = 0
if print_time is not None:
minclock = self.spi.get_mcu().print_time_to_clock(print_time)
- data = [(reg | 0x80) & 0xff, (val >> 24) & 0xff, (val >> 16) & 0xff,
- (val >> 8) & 0xff, val & 0xff]
- if self.printer.get_start_args().get('debugoutput') is not None:
+ data = [
+ (reg | 0x80) & 0xFF,
+ (val >> 24) & 0xFF,
+ (val >> 16) & 0xFF,
+ (val >> 8) & 0xFF,
+ val & 0xFF,
+ ]
+ if self.printer.get_start_args().get("debugoutput") is not None:
self.spi.spi_send(self._build_cmd(data, chain_pos), minclock)
return val
write_cmd = self._build_cmd(data, chain_pos)
dummy_read = self._build_cmd([0x00, 0x00, 0x00, 0x00, 0x00], chain_pos)
- params = self.spi.spi_transfer_with_preface(write_cmd, dummy_read,
- minclock=minclock)
- pr = bytearray(params['response'])
- pr = pr[(self.chain_len - chain_pos) * 5 :
- (self.chain_len - chain_pos + 1) * 5]
+ params = self.spi.spi_transfer_with_preface(
+ write_cmd, dummy_read, minclock=minclock
+ )
+ pr = bytearray(params["response"])
+ pr = pr[(self.chain_len - chain_pos) * 5 : (self.chain_len - chain_pos + 1) * 5]
return (pr[1] << 24) | (pr[2] << 16) | (pr[3] << 8) | pr[4]
+
def get_mcu(self):
return self.spi.get_mcu()
+
# Helper to setup an spi daisy chain bus from settings in a config section
def lookup_tmc_spi_chain(config):
- chain_len = config.getint('chain_length', None, minval=2)
+ chain_len = config.getint("chain_length", None, minval=2)
if chain_len is None:
# Simple, non daisy chained SPI connection
return MCU_TMC_SPI_chain(config, 1), 1
# Shared SPI bus - lookup existing MCU_TMC_SPI_chain
ppins = config.get_printer().lookup_object("pins")
- cs_pin_params = ppins.lookup_pin(config.get('cs_pin'),
- share_type="tmc_spi_cs")
- tmc_spi = cs_pin_params.get('class')
+ cs_pin_params = ppins.lookup_pin(config.get("cs_pin"), share_type="tmc_spi_cs")
+ tmc_spi = cs_pin_params.get("class")
if tmc_spi is None:
- tmc_spi = cs_pin_params['class'] = MCU_TMC_SPI_chain(config, chain_len)
+ tmc_spi = cs_pin_params["class"] = MCU_TMC_SPI_chain(config, chain_len)
if chain_len != tmc_spi.chain_len:
raise config.error("TMC SPI chain must have same length")
- chain_pos = config.getint('chain_position', minval=1, maxval=chain_len)
+ chain_pos = config.getint("chain_position", minval=1, maxval=chain_len)
if chain_pos in tmc_spi.taken_chain_positions:
raise config.error("TMC SPI chain can not have duplicate position")
tmc_spi.taken_chain_positions.append(chain_pos)
return tmc_spi, chain_pos
+
# Helper code for working with TMC devices via SPI
class MCU_TMC_SPI:
def __init__(self, config, name_to_reg, fields, tmc_frequency):
@@ -267,22 +360,27 @@ class MCU_TMC_SPI:
self.name_to_reg = name_to_reg
self.fields = fields
self.tmc_frequency = tmc_frequency
+
def get_fields(self):
return self.fields
+
def get_register_raw(self, reg_name):
reg = self.name_to_reg[reg_name]
with self.mutex:
resp = self.tmc_spi.reg_read(reg, self.chain_pos)
return resp
+
def decode_spi_status(spi_status):
return {
"standstill": spi_status >> 3 & 0x1,
"sg2": spi_status >> 2 & 0x1,
"driver_error": spi_status >> 1 & 0x1,
- "reset_flag": spi_status & 0x1
+ "reset_flag": spi_status & 0x1,
}
+
def get_register(self, reg_name):
return self.get_register_raw(reg_name)["data"]
+
def set_register(self, reg_name, val, print_time=None):
reg = self.name_to_reg[reg_name]
with self.mutex:
@@ -291,9 +389,12 @@ class MCU_TMC_SPI:
if v == val:
return
raise self.printer.command_error(
- "Unable to write tmc spi '%s' register %s" % (self.name, reg_name))
+ "Unable to write tmc spi '%s' register %s" % (self.name, reg_name)
+ )
+
def get_tmc_frequency(self):
return self.tmc_frequency
+
def get_mcu(self):
return self.tmc_spi.get_mcu()
@@ -302,12 +403,12 @@ class MCU_TMC_SPI:
# TMC2130 printer object
######################################################################
+
class TMC2130:
def __init__(self, config):
# Setup mcu communication
self.fields = tmc.FieldHelper(Fields, SignedFields, FieldFormatters)
- self.mcu_tmc = MCU_TMC_SPI(config, Registers, self.fields,
- TMC_FREQUENCY)
+ self.mcu_tmc = MCU_TMC_SPI(config, Registers, self.fields, TMC_FREQUENCY)
# Allow virtual pins to be created
tmc.TMCVirtualPinHelper(config, self.mcu_tmc)
# Register commands
@@ -349,5 +450,6 @@ class TMC2130:
# TPOWERDOWN
set_config_field(config, "tpowerdown", 0)
+
def load_config_prefix(config):
return TMC2130(config)