aboutsummaryrefslogtreecommitdiffstats
path: root/klippy
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2019-02-21 11:35:58 -0500
committerKevin O'Connor <kevin@koconnor.net>2019-02-21 11:35:58 -0500
commit5bc47d9416f7c8b7565a6e27ffd97ad9ad97cade (patch)
tree71b2586691729d4b4ce5cd65d2e8a10f23036305 /klippy
parent328bd89fc11cad86802c5a35055f6b6d4a8243f0 (diff)
downloadkutter-5bc47d9416f7c8b7565a6e27ffd97ad9ad97cade.tar.gz
kutter-5bc47d9416f7c8b7565a6e27ffd97ad9ad97cade.tar.xz
kutter-5bc47d9416f7c8b7565a6e27ffd97ad9ad97cade.zip
tmc2130: Use FieldHelper() to set/get driver fields
Use the field helper to simplify the bit manipulation in the driver. This also enables the extended DUMP_TMC output. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy')
-rw-r--r--klippy/extras/tmc2130.py142
-rw-r--r--klippy/extras/tmc2208.py21
2 files changed, 106 insertions, 57 deletions
diff --git a/klippy/extras/tmc2130.py b/klippy/extras/tmc2130.py
index 0374a747..80da0614 100644
--- a/klippy/extras/tmc2130.py
+++ b/klippy/extras/tmc2130.py
@@ -3,12 +3,10 @@
# Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
-import math, logging
+import math, logging, collections
import bus
TMC_FREQUENCY=13200000.
-GCONF_EN_PWM_MODE=1<<2
-GCONF_DIAG1_STALL=1<<8
Registers = {
"GCONF": 0x00, "GSTAT": 0x01, "IOIN": 0x04, "IHOLD_IRUN": 0x10,
@@ -25,6 +23,69 @@ ReadRegisters = [
]
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
+}
+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
+}
+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["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
+}
+Fields["COOLCONF"] = {
+ "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
+}
+Fields["PWMCONF"] = {
+ "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 }
+
+FieldFormatters = {
+ "I_scale_analog": (lambda v: "1(ExtVREF)" if v else ""),
+ "shaft": (lambda v: "1(Reverse)" 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),
+ "CUR_A": (lambda v: decode_signed_int(v, 9)),
+ "CUR_B": (lambda v: decode_signed_int(v, 9)),
+ "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 ""),
+ "sgt": (lambda v: decode_signed_int(v, 7)),
+}
######################################################################
@@ -155,37 +216,35 @@ class TMC2130:
gcode.register_mux_command(
"DUMP_TMC", "STEPPER", self.name,
self.cmd_DUMP_TMC, desc=self.cmd_DUMP_TMC_help)
- # Get config for initial driver settings
- self.fields = FieldHelper(Fields)
- interpolate = config.getboolean('interpolate', True)
- self.mres, en_pwm, sc_threshold = get_config_stealthchop(
- config, TMC_FREQUENCY)
- iholddelay = config.getint('driver_IHOLDDELAY', 8, minval=0, maxval=15)
- tpowerdown = config.getint('driver_TPOWERDOWN', 0, minval=0, maxval=255)
- blank_time_select = config.getint('driver_BLANK_TIME_SELECT', 1,
- minval=0, maxval=3)
- toff = config.getint('driver_TOFF', 4, minval=1, maxval=15)
- hend = config.getint('driver_HEND', 7, minval=0, maxval=15)
- hstrt = config.getint('driver_HSTRT', 0, minval=0, maxval=7)
- sgt = config.getint('driver_SGT', 0, minval=-64, maxval=63) & 0x7f
- pwm_scale = config.getboolean('driver_PWM_AUTOSCALE', True)
- pwm_freq = config.getint('driver_PWM_FREQ', 1, minval=0, maxval=3)
- pwm_grad = config.getint('driver_PWM_GRAD', 4, minval=0, maxval=255)
- pwm_ampl = config.getint('driver_PWM_AMPL', 128, minval=0, maxval=255)
+ # Setup basic register values
+ self.regs = collections.OrderedDict()
+ self.fields = FieldHelper(Fields, FieldFormatters, self.regs)
vsense, irun, ihold = get_config_current(config)
- # Configure registers
- self.reg_GCONF = en_pwm << 2
- self.set_register("GCONF", self.reg_GCONF)
- self.set_register("CHOPCONF", (
- toff | (hstrt << 4) | (hend << 7) | (blank_time_select << 15)
- | (vsense << 17) | (self.mres << 24) | (interpolate << 28)))
- self.set_register("IHOLD_IRUN",
- ihold | (irun << 8) | (iholddelay << 16))
- self.set_register("TPOWERDOWN", tpowerdown)
- self.set_register("TPWMTHRS", sc_threshold)
- self.set_register("COOLCONF", sgt << 16)
- self.set_register("PWMCONF", (
- pwm_ampl | (pwm_grad << 8) | (pwm_freq << 16) | (pwm_scale << 18)))
+ self.fields.set_field("vsense", vsense)
+ self.fields.set_field("IHOLD", ihold)
+ self.fields.set_field("IRUN", irun)
+ mres, en_pwm, thresh = get_config_stealthchop(config, TMC_FREQUENCY)
+ self.fields.set_field("MRES", mres)
+ self.fields.set_field("en_pwm_mode", en_pwm)
+ self.fields.set_field("TPWMTHRS", thresh)
+ # Allow other registers to be set from the config
+ set_config_field = self.fields.set_config_field
+ set_config_field(config, "toff", 4)
+ set_config_field(config, "hstrt", 0)
+ set_config_field(config, "hend", 7)
+ set_config_field(config, "TBL", 1, "driver_BLANK_TIME_SELECT")
+ set_config_field(config, "intpol", True, "interpolate")
+ set_config_field(config, "IHOLDDELAY", 8)
+ set_config_field(config, "TPOWERDOWN", 0)
+ set_config_field(config, "PWM_AMPL", 128)
+ set_config_field(config, "PWM_GRAD", 4)
+ set_config_field(config, "pwm_freq", 1)
+ set_config_field(config, "pwm_autoscale", True)
+ sgt = config.getint('driver_SGT', 0, minval=-64, maxval=63) & 0x7f
+ self.fields.set_field("sgt", sgt)
+ # Send registers
+ for reg_name, val in self.regs.items():
+ self.set_register(reg_name, val)
def setup_pin(self, pin_type, pin_params):
if pin_type != 'endstop' or pin_params['pin'] != 'virtual_endstop':
raise pins.error("tmc2130 virtual endstop only useful as endstop")
@@ -204,9 +263,10 @@ class TMC2130:
(val >> 8) & 0xff, val & 0xff]
self.spi.spi_send(data)
def get_microsteps(self):
- return 256 >> self.mres
+ return 256 >> self.fields.get_field("MRES")
def get_phase(self):
- return (self.get_register("MSCNT") & 0x3ff) >> self.mres
+ mscnt = self.fields.get_field("MSCNT", self.get_register("MSCNT"))
+ return mscnt >> self.fields.get_field("MRES")
cmd_DUMP_TMC_help = "Read and display TMC stepper driver registers"
def cmd_DUMP_TMC(self, params):
self.printer.lookup_object('toolhead').get_last_move_time()
@@ -228,6 +288,7 @@ class TMC2130VirtualEndstop:
self.mcu_endstop = ppins.setup_pin('endstop', tmc2130.diag1_pin)
if self.mcu_endstop.get_mcu() is not tmc2130.spi.get_mcu():
raise pins.error("tmc2130 virtual endstop must be on same mcu")
+ self.en_pwm = tmc2130.fields.get_field("en_pwm_mode")
# Wrappers
self.get_mcu = self.mcu_endstop.get_mcu
self.add_stepper = self.mcu_endstop.add_stepper
@@ -238,14 +299,15 @@ class TMC2130VirtualEndstop:
self.query_endstop_wait = self.mcu_endstop.query_endstop_wait
self.TimeoutError = self.mcu_endstop.TimeoutError
def home_prepare(self):
- gconf = self.tmc2130.reg_GCONF
- gconf &= ~GCONF_EN_PWM_MODE
- gconf |= GCONF_DIAG1_STALL
- self.tmc2130.set_register("GCONF", gconf)
+ self.tmc2130.fields.set_field("en_pwm_mode", 0)
+ self.tmc2130.fields.set_field("diag1_stall", 1)
+ self.tmc2130.set_register("GCONF", self.tmc2130.regs['GCONF'])
self.tmc2130.set_register("TCOOLTHRS", 0xfffff)
self.mcu_endstop.home_prepare()
def home_finalize(self):
- self.tmc2130.set_register("GCONF", self.tmc2130.reg_GCONF)
+ self.tmc2130.fields.set_field("en_pwm_mode", self.en_pwm)
+ self.tmc2130.fields.set_field("diag1_stall", 0)
+ self.tmc2130.set_register("GCONF", self.tmc2130.regs['GCONF'])
self.tmc2130.set_register("TCOOLTHRS", 0)
self.mcu_endstop.home_finalize()
diff --git a/klippy/extras/tmc2208.py b/klippy/extras/tmc2208.py
index ef476e3b..3057b163 100644
--- a/klippy/extras/tmc2208.py
+++ b/klippy/extras/tmc2208.py
@@ -168,26 +168,13 @@ Fields["PWM_AUTO"] = {
"PWM_GRAD_AUTO": 0xff << 16
}
-FieldFormatters = {
- "I_scale_analog": (lambda v: "1(ExtVREF)" if v else ""),
- "shaft": (lambda v: "1(Reverse)" if v else ""),
- "drv_err": (lambda v: "1(ErrorShutdown!)" if v else ""),
- "uv_cp": (lambda v: "1(Undervoltage!)" if v else ""),
+FieldFormatters = dict(tmc2130.FieldFormatters)
+FieldFormatters.update({
"SEL_A": (lambda v: "%d(%s)" % (v, ["TMC222x", "TMC220x"][v])),
- "VERSION": (lambda v: "%#x" % v),
- "CUR_A": (lambda v: str(tmc2130.decode_signed_int(v, 9))),
- "CUR_B": (lambda v: str(tmc2130.decode_signed_int(v, 9))),
- "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 ""),
"s2vsa": (lambda v: "1(LowSideShort_A!)" if v else ""),
"s2vsb": (lambda v: "1(LowSideShort_B!)" if v else ""),
- "ola": (lambda v: "1(OpenLoad_A!)" if v else ""),
- "olb": (lambda v: "1(OpenLoad_B!)" if v else ""),
- "PWM_SCALE_AUTO": (lambda v: str(tmc2130.decode_signed_int(v, 9)))
-}
+ "PWM_SCALE_AUTO": (lambda v: tmc2130.decode_signed_int(v, 9))
+})
######################################################################