aboutsummaryrefslogtreecommitdiffstats
path: root/klippy
diff options
context:
space:
mode:
authorMarco D'Alessio <marco@wrecklab.com>2020-10-18 10:50:32 +0200
committerKevin O'Connor <kevin@koconnor.net>2021-02-26 10:54:47 -0500
commitc7688c6bcadeba0e6131f57a3d7f09a475f14e48 (patch)
tree18254a458f9ee4ca42621d21e9ad1c0eeb1a3534 /klippy
parenta8742e982d899e75f9ffcd3992878b401223ed9e (diff)
downloadkutter-c7688c6bcadeba0e6131f57a3d7f09a475f14e48.tar.gz
kutter-c7688c6bcadeba0e6131f57a3d7f09a475f14e48.tar.xz
kutter-c7688c6bcadeba0e6131f57a3d7f09a475f14e48.zip
tmc2130: Add spi daisy chain support
This patch adds the ability to daisy-chain multiple tmc2130 and tmc5160 drivers. Signed-off-by: Marco D'Alessio <marco@wrecklab.com> Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy')
-rw-r--r--klippy/extras/bus.py4
-rw-r--r--klippy/extras/tmc2130.py73
2 files changed, 61 insertions, 16 deletions
diff --git a/klippy/extras/bus.py b/klippy/extras/bus.py
index 7c6ae440..09259b9f 100644
--- a/klippy/extras/bus.py
+++ b/klippy/extras/bus.py
@@ -97,11 +97,11 @@ class MCU_SPI:
# Helper to setup an spi bus from settings in a config section
def MCU_SPI_from_config(config, mode, pin_option="cs_pin",
- default_speed=100000):
+ default_speed=100000, share_type=None):
# Determine pin from config
ppins = config.get_printer().lookup_object("pins")
cs_pin = config.get(pin_option)
- cs_pin_params = ppins.lookup_pin(cs_pin)
+ cs_pin_params = ppins.lookup_pin(cs_pin, share_type=share_type)
pin = cs_pin_params['pin']
if pin == 'None':
ppins.reset_pin_sharing(cs_pin_params)
diff --git a/klippy/extras/tmc2130.py b/klippy/extras/tmc2130.py
index 891de858..f300afbc 100644
--- a/klippy/extras/tmc2130.py
+++ b/klippy/extras/tmc2130.py
@@ -170,12 +170,66 @@ class TMCCurrentHelper:
# TMC2130 SPI
######################################################################
+class MCU_TMC_SPI_chain:
+ def __init__(self, config, chain_len=1):
+ self.printer = config.get_printer()
+ self.chain_len = chain_len
+ self.mutex = self.printer.get_reactor().mutex()
+ share = None
+ if chain_len > 1:
+ share = "tmc_spi_cs"
+ self.spi = bus.MCU_SPI_from_config(config, 3, default_speed=4000000,
+ share_type=share)
+ self.taken_chain_positions = []
+ def _build_cmd(self, data, chain_pos):
+ return ([0x00] * ((self.chain_len - chain_pos) * 5) +
+ data + [0x00] * ((chain_pos - 1) * 5))
+ def reg_read(self, reg, chain_pos):
+ cmd = self._build_cmd([reg, 0x00, 0x00, 0x00, 0x00], chain_pos)
+ self.spi.spi_send(cmd)
+ if self.printer.get_start_args().get('debugoutput') is not None:
+ return 0
+ params = self.spi.spi_transfer(cmd)
+ pr = bytearray(params['response'])
+ pr = pr[(self.chain_len - chain_pos) * 5 :
+ (self.chain_len - chain_pos + 1) * 5]
+ return (pr[1] << 24) | (pr[2] << 16) | (pr[3] << 8) | pr[4]
+ def reg_write(self, reg, val, chain_pos, print_time=None):
+ minclock = 0
+ if print_time is not None:
+ minclock = self.spi.get_mcu().print_time_to_clock(print_time)
+ data = [(reg | 0x80) & 0xff, (val >> 24) & 0xff, (val >> 16) & 0xff,
+ (val >> 8) & 0xff, val & 0xff]
+ self.spi.spi_send(self._build_cmd(data, chain_pos), minclock)
+
+# Helper to setup an spi daisy chain bus from settings in a config section
+def lookup_tmc_spi_chain(config):
+ chain_len = config.getint('chain_length', None, minval=2)
+ if chain_len is None:
+ # Simple, non daisy chained SPI connection
+ return MCU_TMC_SPI_chain(config, 1), 1
+
+ # Shared SPI bus - lookup existing MCU_TMC_SPI_chain
+ ppins = config.get_printer().lookup_object("pins")
+ cs_pin_params = ppins.lookup_pin(config.get('cs_pin'),
+ share_type="tmc_spi_cs")
+ tmc_spi = cs_pin_params.get('class')
+ if tmc_spi is None:
+ tmc_spi = cs_pin_params['class'] = MCU_TMC_SPI_chain(config, chain_len)
+ if chain_len != tmc_spi.chain_len:
+ raise config.error("TMC SPI chain must have same length")
+ chain_pos = config.getint('chain_position', minval=1, maxval=chain_len)
+ if chain_pos in tmc_spi.taken_chain_positions:
+ raise config.error("TMC SPI chain can not have duplicate position")
+ tmc_spi.taken_chain_positions.append(chain_pos)
+ return tmc_spi, chain_pos
+
# Helper code for working with TMC devices via SPI
class MCU_TMC_SPI:
def __init__(self, config, name_to_reg, fields):
self.printer = config.get_printer()
- self.mutex = self.printer.get_reactor().mutex()
- self.spi = bus.MCU_SPI_from_config(config, 3, default_speed=4000000)
+ self.tmc_spi, self.chain_pos = lookup_tmc_spi_chain(config)
+ self.mutex = self.tmc_spi.mutex
self.name_to_reg = name_to_reg
self.fields = fields
def get_fields(self):
@@ -183,21 +237,12 @@ class MCU_TMC_SPI:
def get_register(self, reg_name):
reg = self.name_to_reg[reg_name]
with self.mutex:
- self.spi.spi_send([reg, 0x00, 0x00, 0x00, 0x00])
- if self.printer.get_start_args().get('debugoutput') is not None:
- return 0
- params = self.spi.spi_transfer([reg, 0x00, 0x00, 0x00, 0x00])
- pr = bytearray(params['response'])
- return (pr[1] << 24) | (pr[2] << 16) | (pr[3] << 8) | pr[4]
+ read = self.tmc_spi.reg_read(reg, self.chain_pos)
+ return read
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]
- data = [(reg | 0x80) & 0xff, (val >> 24) & 0xff, (val >> 16) & 0xff,
- (val >> 8) & 0xff, val & 0xff]
with self.mutex:
- self.spi.spi_send(data, minclock)
+ self.tmc_spi.reg_write(reg, val, self.chain_pos, print_time)
######################################################################