aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Heilmann <Florian.Heilmann@gmx.net>2018-10-24 16:17:49 +0000
committerKevin O'Connor <kevin@koconnor.net>2018-10-28 18:45:49 -0400
commit4372d1812c93d159f53d52124aa18dfb520463dd (patch)
treeb2f6c6bacaac69c322e38d268bd68a08550605bb
parentd25e02144c3163f55419fbc247e51d4c0856187e (diff)
downloadkutter-4372d1812c93d159f53d52124aa18dfb520463dd.tar.gz
kutter-4372d1812c93d159f53d52124aa18dfb520463dd.tar.xz
kutter-4372d1812c93d159f53d52124aa18dfb520463dd.zip
Implement idle event support in the TMC2660 extra
Signed-off-by: Florian Heilmann <Florian.Heilmann@gmx.net>
-rw-r--r--config/example-extras.cfg29
-rw-r--r--klippy/extras/tmc2660.py73
2 files changed, 38 insertions, 64 deletions
diff --git a/config/example-extras.cfg b/config/example-extras.cfg
index c10d2732..29255c48 100644
--- a/config/example-extras.cfg
+++ b/config/example-extras.cfg
@@ -741,8 +741,8 @@
#[tmc2660 stepper_x]
#cs_pin:
# The pin corresponding to the TMC2660 chip select line. This pin
-# will be set to low at the start of SPI messages and raised to high
-# after the message completes. This parameter must be provided.
+# will be set to low at the start of SPI messages and set to high
+# after the message transfer completes. This parameter must be provided.
#bus:
# Select the SPI bus the TMC2660 stepper driver is connected to. This
# depends on the physical connections on your board, as well as the
@@ -760,20 +760,17 @@
# step at a rate of 256 micro-steps). This only works if microsteps
# is set to 16. The default is True.
#run_current:
-# The amount of current (in amps) to configure the driver to use
-# during stepper movement. This parameter must be provided.
-#idle_timeout: 0
-# The amount of time in seconds after which the run_current of the
-# stepper driver will be lowered to this percentage of run_current.
-# Set to 0 to disable the idle timeout. The default is 0.
-#idle_current_percent: 30
+# The amount of current (in ampere) used by the driver during stepper
+# movement. This parameter must be provided.
+#idle_current_percent: 100
# The percentage of the run_current the stepper driver will be
-# lowered to after the idle_timeout has expired. The current will
+# lowered to when the idle timeout expires (you need to set up the
+# timeout using a [idle_timeout] config section). The current will
# be raised again once the stepper has to move again. Make sure to
# set this to a high enough value such that the steppers do not lose
-# their position. There is also a delay of up to 100 ms until the
-# current is raised again, so take this into account commanding fast
-# moves when the stepper is idling. The default is 30.
+# their position. There is also small delay until the current is
+# raised again, so take this into account when commanding fast moves
+# while the stepper is idling. The default is 100 (no reduction).
#driver_DEDGE: False
#driver_TBL: 36
# Valid values are 16, 24, 36, 54.
@@ -804,10 +801,10 @@
#driver_VSENSE: high
# Valid values are 'high' and 'low'
#
-# Set the given register during the configuration of the TMC2660
-# chip. This may be used to set custom motor parameters. The
+# Set the given parameter during the configuration of the TMC2660
+# chip. This may be used to set custom driver parameters. The
# defaults for each parameter are next to the parameter name in the
-# above list. See the TMC2660 datasheet about what each parameter
+# list above. See the TMC2660 datasheet about what each parameter
# does and what the restrictions on parameter combinations are.
diff --git a/klippy/extras/tmc2660.py b/klippy/extras/tmc2660.py
index 6f14f7ac..373c3f07 100644
--- a/klippy/extras/tmc2660.py
+++ b/klippy/extras/tmc2660.py
@@ -82,7 +82,7 @@ class TMC2660:
self.name = config.get_name().split()[1]
self.toolhead = None
- # pin setup
+ # Generic setup
ppins = self.printer.lookup_object("pins")
cs_pin = config.get('cs_pin')
cs_pin_params = ppins.lookup_pin(cs_pin)
@@ -91,24 +91,19 @@ class TMC2660:
raise pins.error("tmc2660 can not invert pin")
pin = cs_pin_params['pin']
self.oid = self.mcu.create_oid()
- # Add SET_CURRENT command
- gcode = self.printer.lookup_object("gcode")
- gcode.register_mux_command(
- "SET_TMC_CURRENT", "STEPPER", self.name,
- self.cmd_SET_TMC_CURRENT, desc=self.cmd_SET_TMC_CURRENT_help)
- # Setup driver registers
self.bus = config.getint('bus', minval=0, maxval=3)
self.freq = config.getint('freq', default=2000000, minval=1000000, maxval=4000000)
self.mcu.add_config_cmd(
"config_spi oid=%d bus=%d pin=%s mode=%d rate=%d shutdown_msg=" % (
self.oid, self.bus, cs_pin_params['pin'], 0, self.freq))
-
self.spi_send_cmd = self.spi_transfer_cmd = None
self.mcu.register_config_callback(self.build_config)
-
- self.idle_current_percentage = config.getint('idle_current_percent', default=30, minval=0, maxval=100)
- self.idle_timeout = config.getfloat('idle_timeout', default=0., minval=0)
- self.is_idle = False
+ # Add SET_CURRENT command
+ gcode = self.printer.lookup_object("gcode")
+ gcode.register_mux_command(
+ "SET_TMC_CURRENT", "STEPPER", self.name,
+ self.cmd_SET_TMC_CURRENT, desc=self.cmd_SET_TMC_CURRENT_help)
+ # Setup driver registers
# DRVCTRL
steps = {'256': 0, '128': 1, '64': 2, '32': 3, '16': 4,
'8': 5, '4': 6, '2': 7, '1': 8}
@@ -164,7 +159,6 @@ class TMC2660:
self.driver_vsense = config.getchoice('driver_VSENSE', vsense, default='high')
self.driver_rdsel = 0 # Microsteps (used by endstop phase)
-
# Build and send registers
self.reg_drvconf = REG_DRVCONF | \
get_bits(DRVCONF, "TST", 0) | \
@@ -207,6 +201,14 @@ class TMC2660:
get_bits(SMARTEN, "SEMIN", self.driver_semin)
self.add_config_cmd(self.reg_smarten)
+ # Idle timeout
+ self.idle_current_percentage = config.getint('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)
+
def add_config_cmd(self, val):
self.mcu.add_config_cmd("spi_send oid=%d data=%06x" % (
self.oid, val & 0xffffff))
@@ -218,36 +220,6 @@ class TMC2660:
self.spi_transfer_cmd = self.mcu.lookup_command(
"spi_transfer oid=%c data=%*s", cq=cmd_queue)
- # register timeout handler which will lower the current to current * idle_current_percent / 100 after idle_timeout seconds
- # and raise it back to current if the printer needs to move the steppers
- def printer_state(self, state):
- if state == 'ready' and self.idle_timeout > 0:
- self.toolhead = self.printer.lookup_object('toolhead')
- reactor = self.printer.get_reactor()
- reactor.register_timer(self.idle_timeout_handler, reactor.NOW)
-
- # timeout handler to lower/raise current when entering/leaving the idle state
- def idle_timeout_handler(self, eventtime):
- info = self.toolhead.get_status(eventtime)
- status = info['status']
- print_time = info['print_time']
- if status == 'Printing':
- if self.is_idle:
- self.set_current(self.current)
- self.is_idle = False
- return eventtime + self.idle_timeout
- estimated_print_time = info['estimated_print_time']
- elapsed_time = estimated_print_time - print_time
- if elapsed_time < self.idle_timeout:
- if self.is_idle:
- self.set_current(self.current)
- self.is_idle = False
- return eventtime + self.idle_timeout - elapsed_time
- if not self.is_idle:
- self.set_current(float(self.idle_current_percentage) * self.current / 100)
- self.is_idle = True
- return eventtime + 0.1
-
def get_microsteps(self):
return 256 >> self.driver_mres
@@ -259,22 +231,27 @@ class TMC2660:
steps = (((pr[0] << 16) | (pr[1] << 8) | pr[2]) & READRSP['MSTEP'][1]) >> READRSP['MSTEP'][0]
return steps >> self.driver_mres
- def set_current(self, current):
+ def handle_printing(self, print_time):
+ self.set_current(print_time, self.current)
+
+ def handle_ready(self, print_time):
+ self.set_current(print_time, float(self.idle_current_percentage) * self.current / 100)
+
+ def set_current(self, print_time, current):
self.driver_cs = current_to_reg(current)
reg = self.reg_sgcsconf
reg &= ~(SGCSCONF["CS"][1])
reg |= get_bits(SGCSCONF, "CS", self.driver_cs)
reg_data = [(reg >> 16) & 0xff, (reg >> 8) & 0xff, reg & 0xff]
- params = self.spi_transfer_cmd.send_with_response([self.oid, reg_data], 'spi_transfer_response', self.oid)
+ clock = self.mcu.print_time_to_clock(print_time)
+ params = self.spi_send_cmd.send([self.oid, reg_data], minclock=clock, reqclock=clock)
cmd_SET_TMC_CURRENT_help = "Set the current of a TMC2660 driver (between %d and %d)" % (CURRENT_MIN, CURRENT_MAX)
def cmd_SET_TMC_CURRENT(self, params):
- self.printer.lookup_object('toolhead').get_last_move_time()
gcode = self.printer.lookup_object('gcode')
if 'CURRENT' in params:
self.current = gcode.get_float('CURRENT', params, minval=CURRENT_MIN, maxval=CURRENT_MAX)
- if not self.is_idle:
- self.set_current(self.current)
+ self.set_current(self.printer.lookup_object('toolhead').get_last_move_time(), self.current)
def load_config_prefix(config):
return TMC2660(config)