From 3833669c3a41a26e944ffe891cc259ceaf2b9de0 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Wed, 10 Jan 2018 18:34:42 -0500 Subject: [PATCH] pins: Check if the same pin is referenced via different aliases Change the update_command() call to use a new PinResolver class. In that new class, verify that the same pin isn't referenced in two different parts of the config using different aliases for the pin. Signed-off-by: Kevin O'Connor --- klippy/console.py | 9 ++++----- klippy/mcu.py | 17 ++++++++--------- klippy/pins.py | 39 +++++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/klippy/console.py b/klippy/console.py index c862ba9e..cd7facfd 100755 --- a/klippy/console.py +++ b/klippy/console.py @@ -55,8 +55,8 @@ class KeyboardReader: self.clocksync.connect(self.ser) self.ser.handle_default = self.handle_default self.mcu_freq = self.ser.msgparser.get_constant_float('CLOCK_FREQ') - mcu = self.ser.msgparser.get_constant('MCU') - self.pins = pins.get_pin_map(mcu) + mcu_type = self.ser.msgparser.get_constant('MCU') + self.pins = pins.PinResolver(mcu_type, validate_aliases=False) self.reactor.unregister_timer(self.connect_timer) self.output("="*20 + " connected " + "="*20) return self.reactor.NEVER @@ -71,8 +71,7 @@ class KeyboardReader: self.eval_globals['freq'] = self.mcu_freq self.eval_globals['clock'] = self.clocksync.get_clock(eventtime) def command_PINS(self, parts): - mcu = self.ser.msgparser.get_constant('MCU') - self.pins = pins.get_pin_map(mcu, parts[1]) + self.pins.update_aliases(parts[1]) def command_SET(self, parts): val = parts[2] try: @@ -156,7 +155,7 @@ class KeyboardReader: self.output("Eval: %s" % (line,)) if self.pins is not None: try: - line = pins.update_command(line, self.pins).strip() + line = self.pins.update_command(line).strip() except: self.output("Unable to map pin: %s" % (line,)) return None diff --git a/klippy/mcu.py b/klippy/mcu.py index b5631f4e..a415ba25 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -522,15 +522,14 @@ class MCU: self._oid_count,)) # Resolve pin names - mcu = self._serial.msgparser.get_constant('MCU') - pnames = pins.get_pin_map(mcu, self._pin_map) - updated_cmds = [] - for cmd in self._config_cmds: - try: - updated_cmds.append(pins.update_command(cmd, pnames)) - except: - raise pins.error("Unable to translate pin name: %s" % (cmd,)) - self._config_cmds = updated_cmds + mcu_type = self._serial.msgparser.get_constant('MCU') + pin_resolver = pins.PinResolver(mcu_type) + if self._pin_map is not None: + pin_resolver.update_aliases(self._pin_map) + for i, cmd in enumerate(self._config_cmds): + self._config_cmds[i] = pin_resolver.update_command(cmd) + for i, cmd in enumerate(self._init_cmds): + self._init_cmds[i] = pin_resolver.update_command(cmd) # Calculate config CRC self._config_crc = zlib.crc32('\n'.join(self._config_cmds)) & 0xffffffff diff --git a/klippy/pins.py b/klippy/pins.py index c612432c..c7983280 100644 --- a/klippy/pins.py +++ b/klippy/pins.py @@ -152,21 +152,32 @@ def update_map_beaglebone(pins, mcu): # Command translation ###################################################################### -# Obtains the pin mappings -def get_pin_map(mcu, mapping_name=None): - pins = dict(MCU_PINS.get(mcu, {})) - if mapping_name == 'arduino': - update_map_arduino(pins, mcu) - elif mapping_name == 'beaglebone': - update_map_beaglebone(pins, mcu) - return pins - -# Translate pin names in a firmware command re_pin = re.compile(r'(?P[ _]pin=)(?P[^ ]*)') -def update_command(cmd, pmap): - def pin_fixup(m): - return m.group('prefix') + str(pmap[m.group('name')]) - return re_pin.sub(pin_fixup, cmd) + +class PinResolver: + def __init__(self, mcu_type, validate_aliases=True): + self.mcu_type = mcu_type + self.validate_aliases = validate_aliases + self.pins = dict(MCU_PINS.get(mcu_type, {})) + self.active_pins = {} + def update_aliases(self, mapping_name): + self.pins = dict(MCU_PINS.get(self.mcu_type, {})) + if mapping_name == 'arduino': + update_map_arduino(self.pins, self.mcu_type) + elif mapping_name == 'beaglebone': + update_map_beaglebone(self.pins, self.mcu_type) + def update_command(self, cmd): + def pin_fixup(m): + name = m.group('name') + if name not in self.pins: + raise error("Unable to translate pin name: %s" % (cmd,)) + pin_id = self.pins[name] + if (name != self.active_pins.setdefault(pin_id, name) + and self.validate_aliases): + raise error("pin %s is an alias for %s" % ( + name, self.active_pins[pin_id])) + return m.group('prefix') + str(pin_id) + return re_pin.sub(pin_fixup, cmd) ######################################################################