1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
4 """A Pin class for use with libgpiod."""
9 "libgpiod Python bindings not found, please install and try again! See "
10 "https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/blob/master/libgpiod.sh"
14 """Pins dont exist in CPython so...lets make our own!"""
23 _CONSUMER = "adafruit_blinka"
29 def __init__(self, pin_id):
31 if isinstance(pin_id, tuple):
32 self._num = int(pin_id[1])
33 if hasattr(gpiod, 'Chip'):
34 self._chip = gpiod.Chip(str(pin_id[0]), gpiod.Chip.OPEN_BY_NUMBER)
36 self._chip = gpiod.chip(str(pin_id[0]), gpiod.chip.OPEN_BY_NUMBER)
38 self._num = int(pin_id)
39 if hasattr(gpiod, 'Chip'):
40 self._chip = gpiod.Chip("gpiochip0", gpiod.Chip.OPEN_BY_NAME)
42 self._chip = gpiod.chip("gpiochip0", gpiod.chip.OPEN_BY_NAME)
48 def __eq__(self, other):
49 return self.id == other
51 def init(self, mode=IN, pull=None):
52 """Initialize the Pin"""
54 self._line = self._chip.get_line(int(self._num))
55 # print("init line: ", self.id, self._line)
62 if pull == self.PULL_UP:
63 if hasattr(gpiod, 'line') and hasattr(gpiod.line, 'BIAS_PULL_UP') :
64 config = gpiod.line_request()
65 config.consumer = self._CONSUMER
66 config.request_type = gpiod.line.BIAS_PULL_UP
67 self._line.request(config)
70 consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_IN, flags=flags
72 raise NotImplementedError(
73 "Internal pullups not supported in this version of libgpiod, "
74 "use physical resistor instead!"
76 elif pull == self.PULL_DOWN:
77 if hasattr(gpiod, 'line') and hasattr(gpiod.line, 'BIAS_PULL_DOWN') :
78 config = gpiod.line_request()
79 config.consumer = self._CONSUMER
80 config.request_type = gpiod.line.BIAS_PULL_DOWN
81 self._line.request(config)
83 raise NotImplementedError(
84 "Internal pulldowns not supported in this version of libgpiod, "
85 "use physical resistor instead!"
87 elif pull == self.PULL_NONE:
88 if hasattr(gpiod, 'line') and hasattr(gpiod.line, 'BIAS_DISABLE') :
89 config = gpiod.line_request()
90 config.consumer = self._CONSUMER
91 config.request_type = gpiod.line.BIAS_DISABLE
92 self._line.request(config)
94 raise RuntimeError(f"Invalid pull for pin: {self.id}")
98 if hasattr(gpiod, 'LINE_REQ_DIR_IN'):
100 consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_IN, flags=flags
103 config = gpiod.line_request()
104 config.consumer = self._CONSUMER
105 config.request_type = gpiod.line_request.DIRECTION_INPUT
106 self._line.request(config)
108 elif mode == self.OUT:
110 raise RuntimeError("Cannot set pull resistor on output")
111 self._mode = self.OUT
113 if hasattr(gpiod, 'LINE_REQ_DIR_OUT'):
114 self._line.request(consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_OUT)
116 config = gpiod.line_request()
117 config.consumer = self._CONSUMER
118 config.request_type = gpiod.line_request.DIRECTION_OUTPUT
119 self._line.request(config)
121 raise RuntimeError("Invalid mode for pin: %s" % self.id)
123 def value(self, val=None):
124 """Set or return the Pin Value"""
126 return self._line.get_value()
128 if val in (self.LOW, self.HIGH):
130 self._line.set_value(val)
132 raise RuntimeError("Invalid value for pin")