diff --git a/config/example-extras.cfg b/config/example-extras.cfg index f7deeb61..fc28000e 100644 --- a/config/example-extras.cfg +++ b/config/example-extras.cfg @@ -1106,6 +1106,10 @@ #stealthchop_threshold: 0 # See the tmc2208 section above for the definition of these # parameters. +#uart_address: +# The address of the TMC2209 chip for UART messages (an integer +# between 0 and 3). This is typically used when multiple TMC2209 +# chips are connected to the same UART pin. The default is zero. #driver_IHOLDDELAY: 8 #driver_TPOWERDOWN: 20 #driver_TBL: 2 diff --git a/klippy/extras/tmc2209.py b/klippy/extras/tmc2209.py index 45072446..5f487122 100644 --- a/klippy/extras/tmc2209.py +++ b/klippy/extras/tmc2209.py @@ -58,7 +58,7 @@ class TMC2209: # Setup mcu communication self.fields = tmc.FieldHelper(Fields, tmc2208.SignedFields, FieldFormatters) - self.mcu_tmc = tmc_uart.MCU_TMC_uart(config, Registers, self.fields) + self.mcu_tmc = tmc_uart.MCU_TMC_uart(config, Registers, self.fields, 3) # Allow virtual pins to be created tmc.TMCVirtualPinHelper(config, self.mcu_tmc) # Register commands diff --git a/klippy/extras/tmc_uart.py b/klippy/extras/tmc_uart.py index bf6a29cf..8af0be07 100644 --- a/klippy/extras/tmc_uart.py +++ b/klippy/extras/tmc_uart.py @@ -77,19 +77,20 @@ class MCU_TMC_uart_bitbang: % (self.oid, self.rx_pin, self.pullup, self.tx_pin, bit_ticks)) self.tmcuart_send_cmd = self.mcu.lookup_command( "tmcuart_send oid=%c write=%*s read=%c", cq=self.cmd_queue) - def register_instance(self, rx_pin_params, tx_pin_params, select_pins_desc): + def register_instance(self, rx_pin_params, tx_pin_params, + select_pins_desc, addr): if (rx_pin_params['pin'] != self.rx_pin or tx_pin_params['pin'] != self.tx_pin or (select_pins_desc is None) != (self.analog_mux is None)): raise self.mcu.get_printer().config_error( - "Shared TMC uart must use identical pins") + "Shared TMC uarts must use the same pins") instance_id = None if self.analog_mux is not None: instance_id = self.analog_mux.get_instance_id(select_pins_desc) - if instance_id in self.instances: + if (instance_id, addr) in self.instances: raise self.mcu.get_printer().config_error( - "Each TMC uart must have unique select pins polarity") - self.instances[instance_id] = True + "Shared TMC uarts need unique address or select_pins polarity") + self.instances[(instance_id, addr)] = True return instance_id def _calc_crc8(self, data): # Generate a CRC8-ATM value for a bytearray @@ -156,13 +157,13 @@ class MCU_TMC_uart_bitbang: minclock = self.mcu.print_time_to_clock(print_time) if self.analog_mux is not None: self.analog_mux.activate(instance_id) - msg = self._encode_write(0xf5, 0x00, reg | 0x80, val) + msg = self._encode_write(0xf5, addr, reg | 0x80, val) self.tmcuart_send_cmd.send_with_response( [self.oid, msg, 0], 'tmcuart_response', self.oid, minclock=minclock) # Lookup a (possibly shared) tmc uart -def lookup_tmc_uart_bitbang(config): +def lookup_tmc_uart_bitbang(config, max_addr): ppins = config.get_printer().lookup_object("pins") rx_pin_params = ppins.lookup_pin( config.get('uart_pin'), can_pullup=True, share_type="tmc_uart_rx") @@ -174,25 +175,26 @@ def lookup_tmc_uart_bitbang(config): if rx_pin_params['chip'] is not tx_pin_params['chip']: raise ppins.error("TMC uart rx and tx pins must be on the same mcu") select_pins_desc = config.get('select_pins', None) + addr = config.getint('uart_address', 0, maxval=max_addr) mcu_uart = rx_pin_params.get('class') if mcu_uart is None: mcu_uart = MCU_TMC_uart_bitbang(rx_pin_params, tx_pin_params, select_pins_desc) rx_pin_params['class'] = mcu_uart instance_id = mcu_uart.register_instance(rx_pin_params, tx_pin_params, - select_pins_desc) - return instance_id, mcu_uart + select_pins_desc, addr) + return instance_id, addr, mcu_uart # Helper code for communicating via TMC uart class MCU_TMC_uart: - def __init__(self, config, name_to_reg, fields): + def __init__(self, config, name_to_reg, fields, max_addr=0): self.printer = config.get_printer() self.name = config.get_name().split()[-1] self.name_to_reg = name_to_reg self.fields = fields self.ifcnt = None - self.addr = 0 - self.instance_id, self.mcu_uart = lookup_tmc_uart_bitbang(config) + self.instance_id, self.addr, self.mcu_uart = lookup_tmc_uart_bitbang( + config, max_addr) self.mutex = self.mcu_uart.mutex def get_fields(self): return self.fields