diff options
Diffstat (limited to 'klippy/extras/tmc2660.py')
-rw-r--r-- | klippy/extras/tmc2660.py | 120 |
1 files changed, 67 insertions, 53 deletions
diff --git a/klippy/extras/tmc2660.py b/klippy/extras/tmc2660.py index c97f1eff..03b8c12c 100644 --- a/klippy/extras/tmc2660.py +++ b/klippy/extras/tmc2660.py @@ -8,43 +8,42 @@ import math, logging from . import bus, tmc, tmc2130 Registers = { - "DRVCONF": 0xE, "SGCSCONF": 0xC, "SMARTEN": 0xA, - "CHOPCONF": 0x8, "DRVCTRL": 0x0 + "DRVCONF": 0xE, + "SGCSCONF": 0xC, + "SMARTEN": 0xA, + "CHOPCONF": 0x8, + "DRVCTRL": 0x0, } -ReadRegisters = [ "READRSP@RDSEL0", "READRSP@RDSEL1", "READRSP@RDSEL2" ] +ReadRegisters = ["READRSP@RDSEL0", "READRSP@RDSEL1", "READRSP@RDSEL2"] Fields = {} Fields["DRVCTRL"] = { - "mres": 0x0f, + "mres": 0x0F, "dedge": 0x01 << 8, "intpol": 0x01 << 9, } Fields["CHOPCONF"] = { - "toff": 0x0f, + "toff": 0x0F, "hstrt": 0x7 << 4, - "hend": 0x0f << 7, + "hend": 0x0F << 7, "hdec": 0x03 << 11, "rndtf": 0x01 << 13, "chm": 0x01 << 14, - "tbl": 0x03 << 15 + "tbl": 0x03 << 15, } Fields["SMARTEN"] = { - "semin" : 0x0f, + "semin": 0x0F, "seup": 0x03 << 5, - "semax": 0x0f << 8, + "semax": 0x0F << 8, "sedn": 0x03 << 13, - "seimin": 0x01 << 15 + "seimin": 0x01 << 15, } -Fields["SGCSCONF"] = { - "cs": 0x1f, - "sgt": 0x7F << 8, - "sfilt": 0x01 << 16 -} +Fields["SGCSCONF"] = {"cs": 0x1F, "sgt": 0x7F << 8, "sfilt": 0x01 << 16} Fields["DRVCONF"] = { "rdsel": 0x03 << 4, @@ -54,7 +53,7 @@ Fields["DRVCONF"] = { "diss2g": 0x01 << 10, "slpl": 0x03 << 12, "slph": 0x03 << 14, - "tst": 0x01 << 16 + "tst": 0x01 << 16, } Fields["READRSP@RDSEL0"] = { @@ -66,7 +65,7 @@ Fields["READRSP@RDSEL0"] = { "ola": 0x01 << 9, "olb": 0x01 << 10, "stst": 0x01 << 11, - "mstep": 0x3ff << 14 + "mstep": 0x3FF << 14, } Fields["READRSP@RDSEL1"] = { @@ -78,7 +77,7 @@ Fields["READRSP@RDSEL1"] = { "ola": 0x01 << 9, "olb": 0x01 << 10, "stst": 0x01 << 11, - "sg_result": 0x3ff << 14 + "sg_result": 0x3FF << 14, } Fields["READRSP@RDSEL2"] = { @@ -90,20 +89,22 @@ Fields["READRSP@RDSEL2"] = { "ola": 0x01 << 9, "olb": 0x01 << 10, "stst": 0x01 << 11, - "se": 0x1f << 14, - "sg_result@rdsel2": 0x1f << 19 + "se": 0x1F << 14, + "sg_result@rdsel2": 0x1F << 19, } SignedFields = ["sgt"] FieldFormatters = dict(tmc2130.FieldFormatters) -FieldFormatters.update({ - "chm": (lambda v: "1(constant toff)" if v else "0(spreadCycle)"), - "vsense": (lambda v: "1(165mV)" if v else "0(305mV)"), - "sdoff": (lambda v: "1(Step/Dir disabled!)" if v else ""), - "diss2g": (lambda v: "1(Short to GND disabled!)" if v else ""), - "se": (lambda v: ("%d" % v) if v else "0(Reset?)"), -}) +FieldFormatters.update( + { + "chm": (lambda v: "1(constant toff)" if v else "0(spreadCycle)"), + "vsense": (lambda v: "1(165mV)" if v else "0(305mV)"), + "sdoff": (lambda v: "1(Step/Dir disabled!)" if v else ""), + "diss2g": (lambda v: "1(Short to GND disabled!)" if v else ""), + "se": (lambda v: ("%d" % v) if v else "0(Reset?)"), + } +) ###################################################################### @@ -112,37 +113,40 @@ FieldFormatters.update({ MAX_CURRENT = 2.400 + class TMC2660CurrentHelper: 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.current = config.getfloat('run_current', minval=0.1, - maxval=MAX_CURRENT) - self.sense_resistor = config.getfloat('sense_resistor') + self.current = config.getfloat("run_current", minval=0.1, maxval=MAX_CURRENT) + self.sense_resistor = config.getfloat("sense_resistor") vsense, cs = self._calc_current(self.current) self.fields.set_field("cs", cs) self.fields.set_field("vsense", vsense) # Register ready/printing handlers self.idle_current_percentage = config.getint( - 'idle_current_percent', default=100, minval=0, maxval=100) + "idle_current_percent", default=100, minval=0, maxval=100 + ) if self.idle_current_percentage < 100: - self.printer.register_event_handler("idle_timeout:printing", - self._handle_printing) - self.printer.register_event_handler("idle_timeout:ready", - self._handle_ready) + self.printer.register_event_handler( + "idle_timeout:printing", self._handle_printing + ) + self.printer.register_event_handler( + "idle_timeout:ready", self._handle_ready + ) def _calc_current_bits(self, current, vsense): vref = 0.165 if vsense else 0.310 sr = self.sense_resistor - cs = int(32. * sr * current * math.sqrt(2.) / vref + .5) - 1 + cs = int(32.0 * sr * current * math.sqrt(2.0) / vref + 0.5) - 1 return max(0, min(31, cs)) def _calc_current_from_bits(self, cs, vsense): vref = 0.165 if vsense else 0.310 - return (cs + 1) * vref / (32. * self.sense_resistor * math.sqrt(2.)) + return (cs + 1) * vref / (32.0 * self.sense_resistor * math.sqrt(2.0)) def _calc_current(self, run_current): vsense = True @@ -158,14 +162,16 @@ class TMC2660CurrentHelper: return vsense, irun def _handle_printing(self, print_time): - print_time -= 0.100 # Schedule slightly before deadline + print_time -= 0.100 # Schedule slightly before deadline self.printer.get_reactor().register_callback( - (lambda ev: self._update_current(self.current, print_time))) + (lambda ev: self._update_current(self.current, print_time)) + ) def _handle_ready(self, print_time): - current = self.current * float(self.idle_current_percentage) / 100. + current = self.current * float(self.idle_current_percentage) / 100.0 self.printer.get_reactor().register_callback( - (lambda ev: self._update_current(current, print_time))) + (lambda ev: self._update_current(current, print_time)) + ) def _update_current(self, current, print_time): vsense, cs = self._calc_current(current) @@ -188,6 +194,7 @@ class TMC2660CurrentHelper: # TMC2660 SPI ###################################################################### + # Helper code for working with TMC2660 devices via SPI class MCU_TMC2660_SPI: def __init__(self, config, name_to_reg, fields): @@ -196,41 +203,47 @@ class MCU_TMC2660_SPI: self.spi = bus.MCU_SPI_from_config(config, 0, default_speed=4000000) self.name_to_reg = name_to_reg self.fields = fields + def get_fields(self): return self.fields + def get_register_raw(self, reg_name): new_rdsel = ReadRegisters.index(reg_name) reg = self.name_to_reg["DRVCONF"] - if self.printer.get_start_args().get('debugoutput') is not None: + if self.printer.get_start_args().get("debugoutput") is not None: return { - 'data': 0, - '#receive_time': .0, + "data": 0, + "#receive_time": 0.0, } with self.mutex: old_rdsel = self.fields.get_field("rdsel") val = self.fields.set_field("rdsel", new_rdsel) - msg = [((val >> 16) | reg) & 0xff, (val >> 8) & 0xff, val & 0xff] + msg = [((val >> 16) | reg) & 0xFF, (val >> 8) & 0xFF, val & 0xFF] if new_rdsel != old_rdsel: # Must set RDSEL value first self.spi.spi_send(msg) params = self.spi.spi_transfer(msg) - pr = bytearray(params['response']) + pr = bytearray(params["response"]) return { - 'data': (pr[0] << 16) | (pr[1] << 8) | pr[2], - '#receive_time': params['#receive_time'], + "data": (pr[0] << 16) | (pr[1] << 8) | pr[2], + "#receive_time": params["#receive_time"], } + def get_register(self, reg_name): - return self.get_register_raw(reg_name)['data'] + return self.get_register_raw(reg_name)["data"] + def set_register(self, reg_name, val, print_time=None): minclock = 0 if print_time is not None: minclock = self.spi.get_mcu().print_time_to_clock(print_time) reg = self.name_to_reg[reg_name] - msg = [((val >> 16) | reg) & 0xff, (val >> 8) & 0xff, val & 0xff] + msg = [((val >> 16) | reg) & 0xFF, (val >> 8) & 0xFF, val & 0xFF] with self.mutex: self.spi.spi_send(msg, minclock) + def get_tmc_frequency(self): return None + def get_mcu(self): return self.spi.get_mcu() @@ -239,11 +252,12 @@ class MCU_TMC2660_SPI: # TMC2660 printer object ###################################################################### + class TMC2660: def __init__(self, config): # Setup mcu communication self.fields = tmc.FieldHelper(Fields, SignedFields, FieldFormatters) - self.fields.set_field("sdoff", 0) # Access DRVCTRL in step/dir mode + self.fields.set_field("sdoff", 0) # Access DRVCTRL in step/dir mode self.mcu_tmc = MCU_TMC2660_SPI(config, Registers, self.fields) # Register commands current_helper = TMC2660CurrentHelper(config, self.mcu_tmc) @@ -262,8 +276,7 @@ class TMC2660: set_config_field(config, "hstrt", 3) set_config_field(config, "toff", 4) if not self.fields.get_field("chm"): - if (self.fields.get_field("hstrt") + - self.fields.get_field("hend")) > 15: + if (self.fields.get_field("hstrt") + self.fields.get_field("hend")) > 15: raise config.error("driver_HEND + driver_HSTRT must be <= 15") # SMARTEN set_config_field(config, "seimin", 0) @@ -282,5 +295,6 @@ class TMC2660: set_config_field(config, "diss2g", 0) set_config_field(config, "ts2g", 3) + def load_config_prefix(config): return TMC2660(config) |