diff --git a/klippy/console.py b/klippy/console.py index 1610c4d0..2d5d05aa 100755 --- a/klippy/console.py +++ b/klippy/console.py @@ -38,7 +38,7 @@ class KeyboardReader: self.fd = sys.stdin.fileno() util.set_nonblock(self.fd) self.mcu_freq = 0 - self.pins = None + self.pins = pins.PinResolver({}, validate_aliases=False) self.data = "" reactor.register_fd(self.fd, self.process_kbd) reactor.register_callback(self.connect) @@ -63,8 +63,6 @@ class KeyboardReader: self.ser.handle_default = self.handle_default self.ser.register_response(self.handle_output, '#output') self.mcu_freq = msgparser.get_constant_float('CLOCK_FREQ') - mcu_type = msgparser.get_constant('MCU') - self.pins = pins.PinResolver(mcu_type, {}, validate_aliases=False) self.output("="*20 + " connected " + "="*20) return self.reactor.NEVER def output(self, msg): @@ -83,7 +81,8 @@ class KeyboardReader: self.eval_globals['freq'] = self.mcu_freq self.eval_globals['clock'] = self.clocksync.get_clock(eventtime) def command_PINS(self, parts): - self.pins.update_aliases(parts[1]) + mcu_type = self.ser.get_msgparser().get_constant('MCU') + self.pins.add_pin_mapping(mcu_type, parts[1]) def command_SET(self, parts): val = parts[2] try: @@ -164,12 +163,11 @@ class KeyboardReader: return None line = ''.join(evalparts) self.output("Eval: %s" % (line,)) - if self.pins is not None: - try: - line = self.pins.update_command(line).strip() - except: - self.output("Unable to map pin: %s" % (line,)) - return None + try: + line = self.pins.update_command(line).strip() + except: + self.output("Unable to map pin: %s" % (line,)) + return None if line: parts = line.split() if parts[0] in self.local_commands: diff --git a/klippy/extras/bus.py b/klippy/extras/bus.py index 04795a88..0b50efc7 100644 --- a/klippy/extras/bus.py +++ b/klippy/extras/bus.py @@ -26,9 +26,10 @@ def resolve_bus_name(mcu, param, bus): # Check for reserved bus pins constants = mcu.get_constants() reserve_pins = constants.get('BUS_PINS_%s' % (bus,), None) + pin_resolver = ppins.get_pin_resolver(mcu_name) if reserve_pins is not None: for pin in reserve_pins.split(','): - ppins.reserve_pin(mcu_name, pin, bus) + pin_resolver.reserve_pin(pin, bus) return bus diff --git a/klippy/extras/replicape.py b/klippy/extras/replicape.py index 75687277..6817a051 100644 --- a/klippy/extras/replicape.py +++ b/klippy/extras/replicape.py @@ -128,8 +128,9 @@ class servo_pwm: pru_mcu = replicape.mcu_pwm_enable.get_mcu() printer = pru_mcu.get_printer() ppins = printer.lookup_object('pins') - ppins.reserve_pin(pru_mcu.get_name(), resv1, config_name) - ppins.reserve_pin(pru_mcu.get_name(), resv2, config_name) + pin_resolver = ppins.get_pin_resolver(pru_mcu.get_name()) + pin_resolver.reserve_pin(resv1, config_name) + pin_resolver.reserve_pin(resv2, config_name) def setup_cycle_time(self, cycle_time, hardware_pwm=False): self.mcu_pwm.setup_cycle_time(cycle_time, True); diff --git a/klippy/mcu.py b/klippy/mcu.py index c99214ef..2aa91691 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -568,10 +568,9 @@ class MCU: # Resolve pin names mcu_type = self._serial.get_msgparser().get_constant('MCU') ppins = self._printer.lookup_object('pins') - reserved_pins = ppins.get_reserved_pins(self._name) - pin_resolver = pins.PinResolver(mcu_type, reserved_pins) + pin_resolver = ppins.get_pin_resolver(self._name) if self._pin_map is not None: - pin_resolver.update_aliases(self._pin_map) + pin_resolver.add_pin_mapping(mcu_type, 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): @@ -651,10 +650,11 @@ class MCU: ["%s=%s" % (k, v) for k, v in self.get_constants().items()]))] logging.info("\n".join(log_info)) ppins = self._printer.lookup_object('pins') + pin_resolver = ppins.get_pin_resolver(name) for cname, value in self.get_constants().items(): if cname.startswith("RESERVE_PINS_"): for pin in value.split(','): - ppins.reserve_pin(name, pin, cname[13:]) + pin_resolver.reserve_pin(pin, cname[13:]) self._mcu_freq = self.get_constant_float('CLOCK_FREQ') self._stats_sumsq_base = self.get_constant_float('STATS_SUMSQ_BASE') self._emergency_stop_cmd = self.lookup_command("emergency_stop") diff --git a/klippy/pins.py b/klippy/pins.py index 46a3ecbd..c1b4588f 100644 --- a/klippy/pins.py +++ b/klippy/pins.py @@ -151,17 +151,21 @@ def get_aliases_beaglebone(mcu): re_pin = re.compile(r'(?P[ _]pin=)(?P[^ ]*)') class PinResolver: - def __init__(self, mcu_type, reserved_pins, validate_aliases=True): - self.mcu_type = mcu_type - self.reserved_pins = reserved_pins + def __init__(self, validate_aliases=True): self.validate_aliases = validate_aliases + self.reserved = {} self.aliases = {} self.active_pins = {} - def update_aliases(self, mapping_name): + def reserve_pin(self, pin, reserve_name): + if pin in self.reserved and self.reserved[pin] != reserve_name: + raise error("Pin %s reserved for %s - can't reserve for %s" % ( + pin, self.reserved[pin], reserve_name)) + self.reserved[pin] = reserve_name + def add_pin_mapping(self, mcu_type, mapping_name): if mapping_name == 'arduino': - self.aliases = get_aliases_arduino(self.mcu_type) + self.aliases = get_aliases_arduino(mcu_type) elif mapping_name == 'beaglebone': - self.aliases = get_aliases_beaglebone(self.mcu_type) + self.aliases = get_aliases_beaglebone(mcu_type) else: raise error("Unknown pin alias mapping '%s'" % (mapping_name,)) def update_command(self, cmd): @@ -172,9 +176,9 @@ class PinResolver: and self.validate_aliases): raise error("pin %s is an alias for %s" % ( name, self.active_pins[pin_id])) - if pin_id in self.reserved_pins: + if pin_id in self.reserved: raise error("pin %s is reserved for %s" % ( - name, self.reserved_pins[pin_id])) + name, self.reserved[pin_id])) return m.group('prefix') + str(pin_id) return re_pin.sub(pin_fixup, cmd) @@ -188,7 +192,7 @@ class PrinterPins: def __init__(self): self.chips = {} self.active_pins = {} - self.reserved_pins = {} + self.pin_resolvers = {} def parse_pin(self, pin_desc, can_invert=False, can_pullup=False): desc = pin_desc.strip() pullup = invert = 0 @@ -242,19 +246,16 @@ class PrinterPins: def reset_pin_sharing(self, pin_params): share_name = "%s:%s" % (pin_params['chip_name'], pin_params['pin']) del self.active_pins[share_name] - def reserve_pin(self, chip_name, pin, reserve_name): - chip_reserve = self.reserved_pins.setdefault(chip_name, {}) - if pin in chip_reserve and chip_reserve[pin] != reserve_name: - raise error("Pin %s:%s reserved for %s - can't reserve for %s" % ( - chip_name, pin, chip_reserve[pin], reserve_name)) - chip_reserve[pin] = reserve_name - def get_reserved_pins(self, chip_name): - return self.reserved_pins.get(chip_name, {}) + def get_pin_resolver(self, chip_name): + if chip_name not in self.pin_resolvers: + raise error("Unknown chip name '%s'" % (chip_name,)) + return self.pin_resolvers[chip_name] def register_chip(self, chip_name, chip): chip_name = chip_name.strip() if chip_name in self.chips: raise error("Duplicate chip name '%s'" % (chip_name,)) self.chips[chip_name] = chip + self.pin_resolvers[chip_name] = PinResolver() def add_printer_objects(config): config.get_printer().add_object('pins', PrinterPins())