diff --git a/config/example-extras.cfg b/config/example-extras.cfg index 4dbf7254..01105b0f 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1206,10 +1206,7 @@ # Configure a TMC2130 stepper motor driver via SPI bus. To use this # feature, define a config section with a "tmc2130" prefix followed by # the name of the corresponding stepper config section (for example, -# "[tmc2130 stepper_x]"). This also creates a -# "tmc2130_stepper_x:virtual_enable" virtual pin which may be used as -# the stepper's enable_pin (for enabling the driver via an SPI -# message). +# "[tmc2130 stepper_x]"). #[tmc2130 stepper_x] #cs_pin: # The pin corresponding to the TMC2130 chip select line. This pin @@ -1271,10 +1268,7 @@ # Configure a TMC2208 (or TMC2224) stepper motor driver via single # wire UART. To use this feature, define a config section with a # "tmc2208" prefix followed by the name of the corresponding stepper -# config section (for example, "[tmc2208 stepper_x]"). This also -# creates a "tmc2208_stepper_x:virtual_enable" virtual pin which may -# be used as the stepper's enable_pin (for enabling the driver via a -# UART message). +# config section (for example, "[tmc2208 stepper_x]"). #[tmc2208 stepper_x] #uart_pin: # The pin connected to the TMC2208 PDN_UART line. This parameter @@ -1331,10 +1325,7 @@ # Configure a TMC2209 stepper motor driver via single wire UART. To # use this feature, define a config section with a "tmc2209" prefix # followed by the name of the corresponding stepper config section -# (for example, "[tmc2209 stepper_x]"). This also creates a -# "tmc2209_stepper_x:virtual_enable" virtual pin which may be used as -# the stepper's enable_pin (for enabling the driver via a UART -# message). +# (for example, "[tmc2209 stepper_x]"). #[tmc2209 stepper_x] #uart_pin: #tx_pin: @@ -1380,10 +1371,7 @@ # Configure a TMC2660 stepper motor driver via SPI bus. To use this # feature, define a config section with a tmc2660 prefix followed by # the name of the corresponding stepper config section (for example, -# "[tmc2660 stepper_x]"). This also creates a -# "tmc2660_stepper_x:virtual_enable" virtual pin which may be used as -# the stepper's enable_pin (for enabling the driver via an SPI -# message). +# "[tmc2660 stepper_x]"). #[tmc2660 stepper_x] #cs_pin: # The pin corresponding to the TMC2660 chip select line. This pin @@ -1455,10 +1443,7 @@ # Configure a TMC5160 stepper motor driver via SPI bus. To use this # feature, define a config section with a "tmc5160" prefix followed by # the name of the corresponding stepper config section (for example, -# "[tmc5160 stepper_x]"). This also creates a -# "tmc5160_stepper_x:virtual_enable" virtual pin which may be used as -# the stepper's enable_pin (for enabling the driver via an SPI -# message). +# "[tmc5160 stepper_x]"). #[tmc5160 stepper_x] #cs_pin: # The pin corresponding to the TMC5160 chip select line. This pin diff --git a/config/generic-duet2-duex.cfg b/config/generic-duet2-duex.cfg index dfdce853..0960b952 100644 --- a/config/generic-duet2-duex.cfg +++ b/config/generic-duet2-duex.cfg @@ -86,7 +86,7 @@ [stepper_x] step_pin: PD6 dir_pin: PD11 -enable_pin: !PC6, tmc2660_stepper_x:virtual_enable +enable_pin: !PC6 step_distance: .0125 endstop_pin: ^PC14 position_endstop: 0 @@ -104,7 +104,7 @@ idle_current_percent: 20 [stepper_y] step_pin: PD7 dir_pin: !PD12 -enable_pin: !PC6, tmc2660_stepper_y:virtual_enable +enable_pin: !PC6 step_distance: .0125 endstop_pin: ^PA2 position_endstop: 0 @@ -122,7 +122,7 @@ idle_current_percent: 20 [stepper_z] step_pin: PD8 dir_pin: PD13 -enable_pin: !PC6, tmc2660_stepper_z:virtual_enable +enable_pin: !PC6 step_distance: .0025 endstop_pin: ^PD29 position_endstop: 0.5 @@ -140,7 +140,7 @@ sense_resistor: 0.051 [stepper_z1] step_pin: PD0 dir_pin: PD16 -enable_pin: !PC6, tmc2660_stepper_z1:virtual_enable +enable_pin: !PC6 step_distance: .0025 [tmc2660 stepper_z1] @@ -155,7 +155,7 @@ sense_resistor: 0.051 [stepper_z2] step_pin: PD3 dir_pin: !PD17 -enable_pin: !PC6, tmc2660_stepper_z2:virtual_enable +enable_pin: !PC6 step_distance: .0025 [tmc2660 stepper_z2] @@ -170,7 +170,7 @@ sense_resistor: 0.051 [stepper_z3] step_pin: PD27 dir_pin: !PC0 -enable_pin: !PC6, tmc2660_stepper_z3:virtual_enable +enable_pin: !PC6 step_distance: .0025 [tmc2660 stepper_z3] @@ -185,7 +185,7 @@ sense_resistor: 0.051 [extruder] step_pin: PD5 dir_pin: PA1 -enable_pin: !PC6, tmc2660_extruder:virtual_enable +enable_pin: !PC6 step_distance: .002 nozzle_diameter: 0.400 filament_diameter: 1.750 @@ -211,7 +211,7 @@ sense_resistor: 0.051 [extruder1] step_pin: PD4 dir_pin: PD9 -enable_pin: !PC6, tmc2660_extruder1:virtual_enable +enable_pin: !PC6 step_distance: .002 nozzle_diameter: 0.400 filament_diameter: 1.750 @@ -237,7 +237,7 @@ sense_resistor: 0.051 [extruder2] step_pin: PD2 dir_pin: !PD28 -enable_pin: !PC6, tmc2660_extruder2:virtual_enable +enable_pin: !PC6 step_distance: .002 nozzle_diameter: 0.400 filament_diameter: 1.750 @@ -263,7 +263,7 @@ sense_resistor: 0.051 [extruder3] step_pin: PD1 dir_pin: !PD22 -enable_pin: !PC6, tmc2660_extruder3:virtual_enable +enable_pin: !PC6 step_distance: .002 nozzle_diameter: 0.400 filament_diameter: 1.750 diff --git a/config/generic-duet2-maestro.cfg b/config/generic-duet2-maestro.cfg index 34426bff..d4877d67 100644 --- a/config/generic-duet2-maestro.cfg +++ b/config/generic-duet2-maestro.cfg @@ -6,7 +6,7 @@ [stepper_x] step_pin: PC20 dir_pin: PC18 -enable_pin: !PA1, tmc2208_stepper_x:virtual_enable +enable_pin: !PA1 step_distance: .0125 endstop_pin: ^PA24 position_endstop: 0 @@ -25,7 +25,7 @@ stealthchop_threshold: 250 [stepper_y] step_pin: PC2 dir_pin: PA8 -enable_pin: !PA1, tmc2208_stepper_y:virtual_enable +enable_pin: !PA1 step_distance: .0125 endstop_pin: ^PB6 position_endstop: 0 @@ -44,7 +44,7 @@ stealthchop_threshold: 250 [stepper_z] step_pin: PC28 dir_pin: PB4 -enable_pin: !PA1, tmc2208_stepper_z:virtual_enable +enable_pin: !PA1 step_distance: .0025 endstop_pin: ^PC10 position_endstop: 0.5 @@ -62,7 +62,7 @@ stealthchop_threshold: 30 [extruder] step_pin: PC4 dir_pin: PB7 -enable_pin: !PA1, tmc2208_extruder:virtual_enable +enable_pin: !PA1 step_distance: .002 nozzle_diameter: 0.400 filament_diameter: 1.750 diff --git a/config/generic-duet2.cfg b/config/generic-duet2.cfg index a0555f7a..615288d7 100644 --- a/config/generic-duet2.cfg +++ b/config/generic-duet2.cfg @@ -6,7 +6,7 @@ [stepper_x] step_pin: PD6 dir_pin: PD11 -enable_pin: !PC6, tmc2660_stepper_x:virtual_enable +enable_pin: !PC6 step_distance: .0125 endstop_pin: ^PC14 position_endstop: 0 @@ -22,7 +22,7 @@ sense_resistor: 0.051 [stepper_y] step_pin: PD7 dir_pin: !PD12 -enable_pin: !PC6, tmc2660_stepper_y:virtual_enable +enable_pin: !PC6 step_distance: .0125 endstop_pin: ^PA2 position_endstop: 0 @@ -38,7 +38,7 @@ sense_resistor: 0.051 [stepper_z] step_pin: PD8 dir_pin: PD13 -enable_pin: !PC6, tmc2660_stepper_z:virtual_enable +enable_pin: !PC6 step_distance: .0025 endstop_pin: ^PD29 #endstop_pin: PD10 # E0 endstop @@ -56,7 +56,7 @@ sense_resistor: 0.051 [extruder] step_pin: PD5 dir_pin: PA1 -enable_pin: !PC6, tmc2660_extruder:virtual_enable +enable_pin: !PC6 step_distance: .002 nozzle_diameter: 0.400 filament_diameter: 1.750 @@ -80,7 +80,7 @@ sense_resistor: 0.051 #[extruder1] #step_pin: PD4 #dir_pin: PD9 -#enable_pin: !PC6, tmc2660_extruder1:virtual_enable +#enable_pin: !PC6 #heater_pin: !PA16 #sensor_pin: PC12 #... diff --git a/docs/Config_Changes.md b/docs/Config_Changes.md index ff8f601e..059641e3 100644 --- a/docs/Config_Changes.md +++ b/docs/Config_Changes.md @@ -6,6 +6,11 @@ All dates in this document are approximate. # Changes +20191112: The tmc stepper driver virtual enable capability is now +automatically enabled if the stepper does not have a dedicated stepper +enable pin. Remove references to tmcXXXX:virtual_enable from the +config. + 20191107: The primary extruder config section must be specified as "extruder" and may no longer be specified as "extruder0". Gcode command templates that query the extruder status are now accessed via diff --git a/klippy/extras/stepper_enable.py b/klippy/extras/stepper_enable.py index 52910387..99f075ff 100644 --- a/klippy/extras/stepper_enable.py +++ b/klippy/extras/stepper_enable.py @@ -12,6 +12,7 @@ class StepperEnablePin: def __init__(self, mcu_enable, enable_count=0): self.mcu_enable = mcu_enable self.enable_count = enable_count + self.is_dedicated = enable_count == 0 def set_enable(self, print_time): if not self.enable_count: self.mcu_enable.set_digital(print_time, 1) @@ -25,6 +26,7 @@ class StepperEnablePin: class StepperMultiEnablePin: def __init__(self, enable_list): self.enable_list = enable_list + self.is_dedicated = False def set_enable(self, print_time): for en in self.enable_list: en.set_enable(print_time) @@ -45,6 +47,8 @@ def lookup_enable_pin(ppins, pin_list): mcu_enable = pin_params['chip'].setup_pin('digital_out', pin_params) mcu_enable.setup_max_duration(0.) pin_params['class'] = enable = StepperEnablePin(mcu_enable) + else: + enable.is_dedicated = False enable_list.append(enable) if len(enable_list) == 1: return enable_list[0] @@ -54,21 +58,30 @@ def lookup_enable_pin(ppins, pin_list): class EnableTracking: def __init__(self, printer, stepper, pin): self.stepper = stepper + self.callbacks = [] self.is_enabled = False self.stepper.add_active_callback(self.motor_enable) self.enable = lookup_enable_pin(printer.lookup_object('pins'), pin) + def register_state_callback(self, callback): + self.callbacks.append(callback) def motor_enable(self, print_time): if not self.is_enabled: + for cb in self.callbacks: + cb(print_time, True) self.enable.set_enable(print_time) self.is_enabled = True def motor_disable(self, print_time): if self.is_enabled: # Enable stepper on future stepper movement + for cb in self.callbacks: + cb(print_time, False) self.enable.set_disable(print_time) self.is_enabled = False self.stepper.add_active_callback(self.motor_enable) def is_motor_enabled(self): return self.is_enabled + def has_dedicated_enable(self): + return self.enable.is_dedicated class PrinterStepperEnable: def __init__(self, config): diff --git a/klippy/extras/tmc.py b/klippy/extras/tmc.py index 8d0bf9f9..a9d99cc0 100644 --- a/klippy/extras/tmc.py +++ b/klippy/extras/tmc.py @@ -82,10 +82,15 @@ class FieldHelper: class TMCCommandHelper: def __init__(self, config, mcu_tmc): self.printer = config.get_printer() + self.stepper_name = ' '.join(config.get_name().split()[1:]) self.name = config.get_name().split()[-1] self.mcu_tmc = mcu_tmc self.fields = mcu_tmc.get_fields() self.read_registers = self.read_translate = None + self.toff = None + self.printer.register_event_handler("klippy:connect", + self._handle_connect) + # Register commands self.gcode = self.printer.lookup_object("gcode") self.gcode.register_mux_command( "SET_TMC_FIELD", "STEPPER", self.name, @@ -93,13 +98,21 @@ class TMCCommandHelper: self.gcode.register_mux_command( "INIT_TMC", "STEPPER", self.name, self.cmd_INIT_TMC, desc=self.cmd_INIT_TMC_help) - self.printer.register_event_handler("klippy:connect", - self._handle_connect) def _init_registers(self, print_time=None): # Send registers for reg_name, val in self.fields.registers.items(): self.mcu_tmc.set_register(reg_name, val, print_time) def _handle_connect(self): + # Check for soft stepper enable/disable + stepper_enable = self.printer.lookup_object('stepper_enable') + enable_line = stepper_enable.lookup_enable(self.stepper_name) + if not enable_line.has_dedicated_enable(): + self.toff = self.fields.get_field("toff") + self.fields.set_field("toff", 0) + enable_line.register_state_callback(self.handle_stepper_enable) + logging.info("Enabling TMC virtual enable for '%s'", + self.stepper_name) + # Send init retry_count = 0 while 1: try: @@ -129,6 +142,18 @@ class TMCCommandHelper: reg_val = self.fields.set_field(field_name, value) print_time = self.printer.lookup_object('toolhead').get_last_move_time() self.mcu_tmc.set_register(reg_name, reg_val, print_time) + # Stepper enable/disable via comms + def _do_enable(self, print_time, is_enable): + toff_val = 0 + if is_enable: + toff_val = self.toff + print_time -= 0.100 # Schedule slightly before deadline + val = self.fields.set_field("toff", toff_val) + reg_name = self.fields.lookup_register("toff") + self.mcu_tmc.set_register(reg_name, val, print_time) + def handle_stepper_enable(self, print_time, is_enable): + cb = (lambda ev: self._do_enable(print_time, is_enable)) + self.printer.get_reactor().register_callback(cb) # DUMP_TMC support def setup_register_dump(self, read_registers, read_translate=None): self.read_registers = read_registers @@ -203,30 +228,8 @@ class TMCVirtualEndstop: self.mcu_tmc.set_register("TCOOLTHRS", 0) self.mcu_endstop.home_finalize() -# Digital output wrapper for virtual enable -class TMCVirtualEnable: - def __init__(self, printer, mcu_tmc): - self.reactor = printer.get_reactor() - self.mcu_tmc = mcu_tmc - self.fields = mcu_tmc.get_fields() - self.toff = self.fields.get_field("toff") - self.fields.set_field("toff", 0) - def setup_max_duration(self, max_duration): - pass - def _do_set_digital(self, print_time, value): - toff_val = 0 - if value: - toff_val = self.toff - print_time -= 0.100 # Schedule slightly before deadline - val = self.fields.set_field("toff", toff_val) - reg_name = self.fields.lookup_register("toff") - self.mcu_tmc.set_register(reg_name, val, print_time) - def set_digital(self, print_time, value): - self.reactor.register_callback( - (lambda ev: self._do_set_digital(print_time, value))) - class TMCVirtualPinHelper: - def __init__(self, config, mcu_tmc, diag_pin=None): + def __init__(self, config, mcu_tmc, diag_pin): self.printer = config.get_printer() self.mcu_tmc = mcu_tmc self.diag_pin = diag_pin @@ -235,18 +238,12 @@ class TMCVirtualPinHelper: ppins.register_chip("%s_%s" % (name_parts[0], name_parts[-1]), self) def setup_pin(self, pin_type, pin_params): ppins = self.printer.lookup_object('pins') - if pin_params['pin'] not in ('virtual_endstop', 'virtual_enable'): - raise ppins.error("Unknown tmc virtual pin") + if pin_type != 'endstop' or pin_params['pin'] != 'virtual_endstop': + raise ppins.error("tmc virtual endstop only useful as endstop") if pin_params['invert'] or pin_params['pullup']: raise ppins.error("Can not pullup/invert tmc virtual pin") - if pin_params['pin'] == 'virtual_enable': - if pin_type != 'digital_out': - raise ppins.error("tmc virtual enable only useful for enable") - return TMCVirtualEnable(self.printer, self.mcu_tmc) if self.diag_pin is None: raise ppins.error("tmc virtual endstop requires diag pin config") - if pin_type != 'endstop': - raise ppins.error("tmc virtual endstop only useful as endstop") mcu_endstop = ppins.setup_pin('endstop', self.diag_pin) return TMCVirtualEndstop(self.mcu_tmc, mcu_endstop) diff --git a/klippy/extras/tmc2208.py b/klippy/extras/tmc2208.py index 93a4aee9..fa55fd70 100644 --- a/klippy/extras/tmc2208.py +++ b/klippy/extras/tmc2208.py @@ -187,8 +187,6 @@ class TMC2208: # Setup mcu communication self.fields = tmc.FieldHelper(Fields, SignedFields, FieldFormatters) self.mcu_tmc = tmc_uart.MCU_TMC_uart(config, Registers, self.fields) - # Allow virtual pins to be created - tmc.TMCVirtualPinHelper(config, self.mcu_tmc) # Register commands cmdhelper = tmc.TMCCommandHelper(config, self.mcu_tmc) cmdhelper.setup_register_dump(ReadRegisters, self.read_translate) diff --git a/klippy/extras/tmc2660.py b/klippy/extras/tmc2660.py index 056ccfe1..95321056 100644 --- a/klippy/extras/tmc2660.py +++ b/klippy/extras/tmc2660.py @@ -242,8 +242,6 @@ class TMC2660: self.fields = tmc.FieldHelper(Fields, SignedFields, FieldFormatters) self.fields.set_field("SDOFF", 0) # Access DRVCTRL in step/dir mode self.mcu_tmc = MCU_TMC2660_SPI(config, Registers, self.fields) - # Allow virtual pins to be created - tmc.TMCVirtualPinHelper(config, self.mcu_tmc) # Register commands cmdhelper = tmc.TMCCommandHelper(config, self.mcu_tmc) cmdhelper.setup_register_dump(ReadRegisters)