Implement idle event support in the TMC2660 extra
Signed-off-by: Florian Heilmann <Florian.Heilmann@gmx.net>
This commit is contained in:
parent
d25e02144c
commit
4372d1812c
|
@ -741,8 +741,8 @@
|
||||||
#[tmc2660 stepper_x]
|
#[tmc2660 stepper_x]
|
||||||
#cs_pin:
|
#cs_pin:
|
||||||
# The pin corresponding to the TMC2660 chip select line. This 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
|
# will be set to low at the start of SPI messages and set to high
|
||||||
# after the message completes. This parameter must be provided.
|
# after the message transfer completes. This parameter must be provided.
|
||||||
#bus:
|
#bus:
|
||||||
# Select the SPI bus the TMC2660 stepper driver is connected to. This
|
# Select the SPI bus the TMC2660 stepper driver is connected to. This
|
||||||
# depends on the physical connections on your board, as well as the
|
# 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
|
# step at a rate of 256 micro-steps). This only works if microsteps
|
||||||
# is set to 16. The default is True.
|
# is set to 16. The default is True.
|
||||||
#run_current:
|
#run_current:
|
||||||
# The amount of current (in amps) to configure the driver to use
|
# The amount of current (in ampere) used by the driver during stepper
|
||||||
# during stepper movement. This parameter must be provided.
|
# movement. This parameter must be provided.
|
||||||
#idle_timeout: 0
|
#idle_current_percent: 100
|
||||||
# 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 percentage of the run_current the stepper driver will be
|
# 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
|
# 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
|
# 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
|
# their position. There is also small delay until the current is
|
||||||
# current is raised again, so take this into account commanding fast
|
# raised again, so take this into account when commanding fast moves
|
||||||
# moves when the stepper is idling. The default is 30.
|
# while the stepper is idling. The default is 100 (no reduction).
|
||||||
#driver_DEDGE: False
|
#driver_DEDGE: False
|
||||||
#driver_TBL: 36
|
#driver_TBL: 36
|
||||||
# Valid values are 16, 24, 36, 54.
|
# Valid values are 16, 24, 36, 54.
|
||||||
|
@ -804,10 +801,10 @@
|
||||||
#driver_VSENSE: high
|
#driver_VSENSE: high
|
||||||
# Valid values are 'high' and 'low'
|
# Valid values are 'high' and 'low'
|
||||||
#
|
#
|
||||||
# Set the given register during the configuration of the TMC2660
|
# Set the given parameter during the configuration of the TMC2660
|
||||||
# chip. This may be used to set custom motor parameters. The
|
# chip. This may be used to set custom driver parameters. The
|
||||||
# defaults for each parameter are next to the parameter name in 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.
|
# does and what the restrictions on parameter combinations are.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ class TMC2660:
|
||||||
self.name = config.get_name().split()[1]
|
self.name = config.get_name().split()[1]
|
||||||
self.toolhead = None
|
self.toolhead = None
|
||||||
|
|
||||||
# pin setup
|
# Generic setup
|
||||||
ppins = self.printer.lookup_object("pins")
|
ppins = self.printer.lookup_object("pins")
|
||||||
cs_pin = config.get('cs_pin')
|
cs_pin = config.get('cs_pin')
|
||||||
cs_pin_params = ppins.lookup_pin(cs_pin)
|
cs_pin_params = ppins.lookup_pin(cs_pin)
|
||||||
|
@ -91,24 +91,19 @@ class TMC2660:
|
||||||
raise pins.error("tmc2660 can not invert pin")
|
raise pins.error("tmc2660 can not invert pin")
|
||||||
pin = cs_pin_params['pin']
|
pin = cs_pin_params['pin']
|
||||||
self.oid = self.mcu.create_oid()
|
self.oid = self.mcu.create_oid()
|
||||||
|
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)
|
||||||
# Add SET_CURRENT command
|
# Add SET_CURRENT command
|
||||||
gcode = self.printer.lookup_object("gcode")
|
gcode = self.printer.lookup_object("gcode")
|
||||||
gcode.register_mux_command(
|
gcode.register_mux_command(
|
||||||
"SET_TMC_CURRENT", "STEPPER", self.name,
|
"SET_TMC_CURRENT", "STEPPER", self.name,
|
||||||
self.cmd_SET_TMC_CURRENT, desc=self.cmd_SET_TMC_CURRENT_help)
|
self.cmd_SET_TMC_CURRENT, desc=self.cmd_SET_TMC_CURRENT_help)
|
||||||
# Setup driver registers
|
# 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
|
|
||||||
# DRVCTRL
|
# DRVCTRL
|
||||||
steps = {'256': 0, '128': 1, '64': 2, '32': 3, '16': 4,
|
steps = {'256': 0, '128': 1, '64': 2, '32': 3, '16': 4,
|
||||||
'8': 5, '4': 6, '2': 7, '1': 8}
|
'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_vsense = config.getchoice('driver_VSENSE', vsense, default='high')
|
||||||
self.driver_rdsel = 0 # Microsteps (used by endstop phase)
|
self.driver_rdsel = 0 # Microsteps (used by endstop phase)
|
||||||
|
|
||||||
|
|
||||||
# Build and send registers
|
# Build and send registers
|
||||||
self.reg_drvconf = REG_DRVCONF | \
|
self.reg_drvconf = REG_DRVCONF | \
|
||||||
get_bits(DRVCONF, "TST", 0) | \
|
get_bits(DRVCONF, "TST", 0) | \
|
||||||
|
@ -207,6 +201,14 @@ class TMC2660:
|
||||||
get_bits(SMARTEN, "SEMIN", self.driver_semin)
|
get_bits(SMARTEN, "SEMIN", self.driver_semin)
|
||||||
self.add_config_cmd(self.reg_smarten)
|
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):
|
def add_config_cmd(self, val):
|
||||||
self.mcu.add_config_cmd("spi_send oid=%d data=%06x" % (
|
self.mcu.add_config_cmd("spi_send oid=%d data=%06x" % (
|
||||||
self.oid, val & 0xffffff))
|
self.oid, val & 0xffffff))
|
||||||
|
@ -218,36 +220,6 @@ class TMC2660:
|
||||||
self.spi_transfer_cmd = self.mcu.lookup_command(
|
self.spi_transfer_cmd = self.mcu.lookup_command(
|
||||||
"spi_transfer oid=%c data=%*s", cq=cmd_queue)
|
"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):
|
def get_microsteps(self):
|
||||||
return 256 >> self.driver_mres
|
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]
|
steps = (((pr[0] << 16) | (pr[1] << 8) | pr[2]) & READRSP['MSTEP'][1]) >> READRSP['MSTEP'][0]
|
||||||
return steps >> self.driver_mres
|
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)
|
self.driver_cs = current_to_reg(current)
|
||||||
reg = self.reg_sgcsconf
|
reg = self.reg_sgcsconf
|
||||||
reg &= ~(SGCSCONF["CS"][1])
|
reg &= ~(SGCSCONF["CS"][1])
|
||||||
reg |= get_bits(SGCSCONF, "CS", self.driver_cs)
|
reg |= get_bits(SGCSCONF, "CS", self.driver_cs)
|
||||||
reg_data = [(reg >> 16) & 0xff, (reg >> 8) & 0xff, reg & 0xff]
|
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)
|
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):
|
def cmd_SET_TMC_CURRENT(self, params):
|
||||||
self.printer.lookup_object('toolhead').get_last_move_time()
|
|
||||||
gcode = self.printer.lookup_object('gcode')
|
gcode = self.printer.lookup_object('gcode')
|
||||||
if 'CURRENT' in params:
|
if 'CURRENT' in params:
|
||||||
self.current = gcode.get_float('CURRENT', params, minval=CURRENT_MIN, maxval=CURRENT_MAX)
|
self.current = gcode.get_float('CURRENT', params, minval=CURRENT_MIN, maxval=CURRENT_MAX)
|
||||||
if not self.is_idle:
|
self.set_current(self.printer.lookup_object('toolhead').get_last_move_time(), self.current)
|
||||||
self.set_current(self.current)
|
|
||||||
|
|
||||||
def load_config_prefix(config):
|
def load_config_prefix(config):
|
||||||
return TMC2660(config)
|
return TMC2660(config)
|
||||||
|
|
Loading…
Reference in New Issue