diff --git a/docs/Config_Reference.md b/docs/Config_Reference.md index 7b9a9768..94b8d88f 100644 --- a/docs/Config_Reference.md +++ b/docs/Config_Reference.md @@ -1574,6 +1574,22 @@ main printer config file. Wildcards may also be used (eg, [include my_other_config.cfg] ``` +## [duplicate_pin_override] + +This tool allows a single micro-controller pin to be defined multiple +times in a config file without normal error checking. This is intended +for diagnostic and debugging purposes. This section is not needed +where Klipper supports using the same pin multiple times, and using +this override may cause confusing and unexpected results. + +``` +[duplicate_pin_override] +pins: +# A comma separated list of pins that may be used multiple times in +# a config file without normal error checks. This parameter must be +# provided. +``` + # Bed probing hardware ## [probe] diff --git a/klippy/extras/duplicate_pin_override.py b/klippy/extras/duplicate_pin_override.py new file mode 100644 index 00000000..a769a65f --- /dev/null +++ b/klippy/extras/duplicate_pin_override.py @@ -0,0 +1,15 @@ +# Tool to disable config checks for duplicate pins +# +# Copyright (C) 2021 Kevin O'Connor +# +# This file may be distributed under the terms of the GNU GPLv3 license. + +class PrinterDupPinOverride: + def __init__(self, config): + printer = config.get_printer() + ppins = printer.lookup_object('pins') + for pin_desc in config.get('pins').split(','): + ppins.allow_multi_use_pin(pin_desc) + +def load_config(config): + return PrinterDupPinOverride(config) diff --git a/klippy/pins.py b/klippy/pins.py index 4f2c1db2..a160c78b 100644 --- a/klippy/pins.py +++ b/klippy/pins.py @@ -205,6 +205,7 @@ class PrinterPins: self.chips = {} self.active_pins = {} self.pin_resolvers = {} + self.allow_multi_use_pins = {} def parse_pin(self, pin_desc, can_invert=False, can_pullup=False): desc = pin_desc.strip() pullup = invert = 0 @@ -241,10 +242,12 @@ class PrinterPins: share_name = "%s:%s" % (pin_params['chip_name'], pin) if share_name in self.active_pins: share_params = self.active_pins[share_name] - if share_type is None or share_type != share_params['share_type']: + if share_name in self.allow_multi_use_pins: + pass + elif share_type is None or share_type != share_params['share_type']: raise error("pin %s used multiple times in config" % (pin,)) - if (pin_params['invert'] != share_params['invert'] - or pin_params['pullup'] != share_params['pullup']): + elif (pin_params['invert'] != share_params['invert'] + or pin_params['pullup'] != share_params['pullup']): raise error("Shared pin %s must have same polarity" % (pin,)) return share_params pin_params['share_type'] = share_type @@ -268,6 +271,10 @@ class PrinterPins: raise error("Duplicate chip name '%s'" % (chip_name,)) self.chips[chip_name] = chip self.pin_resolvers[chip_name] = PinResolver() + def allow_multi_use_pin(self, pin_desc): + pin_params = self.parse_pin(pin_desc) + share_name = "%s:%s" % (pin_params['chip_name'], pin_params['pin']) + self.allow_multi_use_pins[share_name] = True def add_printer_objects(config): config.get_printer().add_object('pins', PrinterPins())