aboutsummaryrefslogtreecommitdiffstats
path: root/klippy/pins.py
diff options
context:
space:
mode:
Diffstat (limited to 'klippy/pins.py')
-rw-r--r--klippy/pins.py109
1 files changed, 69 insertions, 40 deletions
diff --git a/klippy/pins.py b/klippy/pins.py
index 35fc58a2..ff2cfb96 100644
--- a/klippy/pins.py
+++ b/klippy/pins.py
@@ -5,6 +5,7 @@
# This file may be distributed under the terms of the GNU GPLv3 license.
import re
+
class error(Exception):
pass
@@ -13,7 +14,8 @@ class error(Exception):
# Command translation
######################################################################
-re_pin = re.compile(r'(?P<prefix>[ _]pin=)(?P<name>[^ ]*)')
+re_pin = re.compile(r"(?P<prefix>[ _]pin=)(?P<name>[^ ]*)")
+
class PinResolver:
def __init__(self, validate_aliases=True):
@@ -21,16 +23,22 @@ class PinResolver:
self.reserved = {}
self.aliases = {}
self.active_pins = {}
+
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))
+ raise error(
+ "Pin %s reserved for %s - can't reserve for %s"
+ % (pin, self.reserved[pin], reserve_name)
+ )
self.reserved[pin] = reserve_name
+
def alias_pin(self, alias, pin):
if alias in self.aliases and self.aliases[alias] != pin:
- raise error("Alias %s mapped to %s - can't alias to %s" % (
- alias, self.aliases[alias], pin))
- if [c for c in '^~!:' if c in pin] or ''.join(pin.split()) != pin:
+ raise error(
+ "Alias %s mapped to %s - can't alias to %s"
+ % (alias, self.aliases[alias], pin)
+ )
+ if [c for c in "^~!:" if c in pin] or "".join(pin.split()) != pin:
raise error("Invalid pin alias '%s'\n" % (pin,))
if pin in self.aliases:
pin = self.aliases[pin]
@@ -38,18 +46,22 @@ class PinResolver:
for existing_alias, existing_pin in self.aliases.items():
if existing_pin == alias:
self.aliases[existing_alias] = pin
+
def update_command(self, cmd):
def pin_fixup(m):
- name = m.group('name')
+ name = m.group("name")
pin_id = self.aliases.get(name, 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]))
+ 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])
+ )
if pin_id in self.reserved:
- raise error("pin %s is reserved for %s" % (
- name, self.reserved[pin_id]))
- return m.group('prefix') + str(pin_id)
+ raise error("pin %s is reserved for %s" % (name, self.reserved[pin_id]))
+ return m.group("prefix") + str(pin_id)
+
return re_pin.sub(pin_fixup, cmd)
@@ -57,82 +69,99 @@ class PinResolver:
# Pin to chip mapping
######################################################################
+
class PrinterPins:
error = error
+
def __init__(self):
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
- if can_pullup and (desc.startswith('^') or desc.startswith('~')):
+ if can_pullup and (desc.startswith("^") or desc.startswith("~")):
pullup = 1
- if desc.startswith('~'):
+ if desc.startswith("~"):
pullup = -1
desc = desc[1:].strip()
- if can_invert and desc.startswith('!'):
+ if can_invert and desc.startswith("!"):
invert = 1
desc = desc[1:].strip()
- if ':' not in desc:
- chip_name, pin = 'mcu', desc
+ if ":" not in desc:
+ chip_name, pin = "mcu", desc
else:
- chip_name, pin = [s.strip() for s in desc.split(':', 1)]
+ chip_name, pin = [s.strip() for s in desc.split(":", 1)]
if chip_name not in self.chips:
raise error("Unknown pin chip name '%s'" % (chip_name,))
- if [c for c in '^~!:' if c in pin] or ''.join(pin.split()) != pin:
+ if [c for c in "^~!:" if c in pin] or "".join(pin.split()) != pin:
format = ""
if can_pullup:
format += "[^~] "
if can_invert:
format += "[!] "
- raise error("Invalid pin description '%s'\n"
- "Format is: %s[chip_name:] pin_name" % (
- pin_desc, format))
- pin_params = {'chip': self.chips[chip_name], 'chip_name': chip_name,
- 'pin': pin, 'invert': invert, 'pullup': pullup}
+ raise error(
+ "Invalid pin description '%s'\n"
+ "Format is: %s[chip_name:] pin_name" % (pin_desc, format)
+ )
+ pin_params = {
+ "chip": self.chips[chip_name],
+ "chip_name": chip_name,
+ "pin": pin,
+ "invert": invert,
+ "pullup": pullup,
+ }
return pin_params
- def lookup_pin(self, pin_desc, can_invert=False, can_pullup=False,
- share_type=None):
+
+ def lookup_pin(self, pin_desc, can_invert=False, can_pullup=False, share_type=None):
pin_params = self.parse_pin(pin_desc, can_invert, can_pullup)
- pin = pin_params['pin']
- share_name = "%s:%s" % (pin_params['chip_name'], pin)
+ pin = pin_params["pin"]
+ 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_name in self.allow_multi_use_pins:
pass
- elif share_type is None or share_type != share_params['share_type']:
+ elif share_type is None or share_type != share_params["share_type"]:
raise error("pin %s used multiple times in config" % (pin,))
- elif (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
+ pin_params["share_type"] = share_type
self.active_pins[share_name] = pin_params
return pin_params
+
def setup_pin(self, pin_type, pin_desc):
- can_invert = pin_type in ['endstop', 'digital_out', 'pwm']
- can_pullup = pin_type in ['endstop']
+ can_invert = pin_type in ["endstop", "digital_out", "pwm"]
+ can_pullup = pin_type in ["endstop"]
pin_params = self.lookup_pin(pin_desc, can_invert, can_pullup)
- return pin_params['chip'].setup_pin(pin_type, pin_params)
+ return pin_params["chip"].setup_pin(pin_type, pin_params)
+
def reset_pin_sharing(self, pin_params):
- share_name = "%s:%s" % (pin_params['chip_name'], pin_params['pin'])
+ share_name = "%s:%s" % (pin_params["chip_name"], pin_params["pin"])
del self.active_pins[share_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 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'])
+ 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())
+ config.get_printer().add_object("pins", PrinterPins())