tmc_uart: Add support for configuring the uart address on tmc2209 chips

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-07-31 12:08:11 -04:00
parent 79cec9ba5c
commit a730aec8bc
3 changed files with 19 additions and 13 deletions

View File

@ -1106,6 +1106,10 @@
#stealthchop_threshold: 0 #stealthchop_threshold: 0
# See the tmc2208 section above for the definition of these # See the tmc2208 section above for the definition of these
# parameters. # 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_IHOLDDELAY: 8
#driver_TPOWERDOWN: 20 #driver_TPOWERDOWN: 20
#driver_TBL: 2 #driver_TBL: 2

View File

@ -58,7 +58,7 @@ class TMC2209:
# Setup mcu communication # Setup mcu communication
self.fields = tmc.FieldHelper(Fields, tmc2208.SignedFields, self.fields = tmc.FieldHelper(Fields, tmc2208.SignedFields,
FieldFormatters) 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 # Allow virtual pins to be created
tmc.TMCVirtualPinHelper(config, self.mcu_tmc) tmc.TMCVirtualPinHelper(config, self.mcu_tmc)
# Register commands # Register commands

View File

@ -77,19 +77,20 @@ class MCU_TMC_uart_bitbang:
% (self.oid, self.rx_pin, self.pullup, self.tx_pin, bit_ticks)) % (self.oid, self.rx_pin, self.pullup, self.tx_pin, bit_ticks))
self.tmcuart_send_cmd = self.mcu.lookup_command( self.tmcuart_send_cmd = self.mcu.lookup_command(
"tmcuart_send oid=%c write=%*s read=%c", cq=self.cmd_queue) "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 if (rx_pin_params['pin'] != self.rx_pin
or tx_pin_params['pin'] != self.tx_pin or tx_pin_params['pin'] != self.tx_pin
or (select_pins_desc is None) != (self.analog_mux is None)): or (select_pins_desc is None) != (self.analog_mux is None)):
raise self.mcu.get_printer().config_error( 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 instance_id = None
if self.analog_mux is not None: if self.analog_mux is not None:
instance_id = self.analog_mux.get_instance_id(select_pins_desc) 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( raise self.mcu.get_printer().config_error(
"Each TMC uart must have unique select pins polarity") "Shared TMC uarts need unique address or select_pins polarity")
self.instances[instance_id] = True self.instances[(instance_id, addr)] = True
return instance_id return instance_id
def _calc_crc8(self, data): def _calc_crc8(self, data):
# Generate a CRC8-ATM value for a bytearray # 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) minclock = self.mcu.print_time_to_clock(print_time)
if self.analog_mux is not None: if self.analog_mux is not None:
self.analog_mux.activate(instance_id) 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.tmcuart_send_cmd.send_with_response(
[self.oid, msg, 0], 'tmcuart_response', self.oid, [self.oid, msg, 0], 'tmcuart_response', self.oid,
minclock=minclock) minclock=minclock)
# Lookup a (possibly shared) tmc uart # 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") ppins = config.get_printer().lookup_object("pins")
rx_pin_params = ppins.lookup_pin( rx_pin_params = ppins.lookup_pin(
config.get('uart_pin'), can_pullup=True, share_type="tmc_uart_rx") 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']: 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") raise ppins.error("TMC uart rx and tx pins must be on the same mcu")
select_pins_desc = config.get('select_pins', None) select_pins_desc = config.get('select_pins', None)
addr = config.getint('uart_address', 0, maxval=max_addr)
mcu_uart = rx_pin_params.get('class') mcu_uart = rx_pin_params.get('class')
if mcu_uart is None: if mcu_uart is None:
mcu_uart = MCU_TMC_uart_bitbang(rx_pin_params, tx_pin_params, mcu_uart = MCU_TMC_uart_bitbang(rx_pin_params, tx_pin_params,
select_pins_desc) select_pins_desc)
rx_pin_params['class'] = mcu_uart rx_pin_params['class'] = mcu_uart
instance_id = mcu_uart.register_instance(rx_pin_params, tx_pin_params, instance_id = mcu_uart.register_instance(rx_pin_params, tx_pin_params,
select_pins_desc) select_pins_desc, addr)
return instance_id, mcu_uart return instance_id, addr, mcu_uart
# Helper code for communicating via TMC uart # Helper code for communicating via TMC uart
class MCU_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.printer = config.get_printer()
self.name = config.get_name().split()[-1] self.name = config.get_name().split()[-1]
self.name_to_reg = name_to_reg self.name_to_reg = name_to_reg
self.fields = fields self.fields = fields
self.ifcnt = None self.ifcnt = None
self.addr = 0 self.instance_id, self.addr, self.mcu_uart = lookup_tmc_uart_bitbang(
self.instance_id, self.mcu_uart = lookup_tmc_uart_bitbang(config) config, max_addr)
self.mutex = self.mcu_uart.mutex self.mutex = self.mcu_uart.mutex
def get_fields(self): def get_fields(self):
return self.fields return self.fields