]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_linux/libgpiod_pin.py
Merge pull request #1 from dnssoftware/dnssoftware-patch-1
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / generic_linux / libgpiod_pin.py
1 """A Pin class for use with libgpiod."""
2 try:
3     import gpiod
4 except ImportError:
5     raise ImportError(
6         "libgpiod Python bindings not found, please install and try again! See "
7         "https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/blob/master/libgpiod.sh"
8     )
9
10
11 class Pin:
12     """Pins dont exist in CPython so...lets make our own!"""
13
14     IN = 0
15     OUT = 1
16     LOW = 0
17     HIGH = 1
18     PULL_NONE = 0
19     PULL_UP = 1
20     PULL_DOWN = 2
21     _CONSUMER = "adafruit_blinka"
22
23     id = None
24     _value = LOW
25     _mode = IN
26
27     def __init__(self, pin_id):
28         self.id = pin_id
29         if isinstance(pin_id, tuple):
30             self._num = int(pin_id[1])
31             self._chip = gpiod.Chip(str(pin_id[0]), gpiod.Chip.OPEN_BY_NUMBER)
32         else:
33             self._num = int(pin_id)
34             self._chip = gpiod.Chip("gpiochip0", gpiod.Chip.OPEN_BY_NAME)
35         self._line = None
36
37     def __repr__(self):
38         return str(self.id)
39
40     def __eq__(self, other):
41         return self.id == other
42
43     def init(self, mode=IN, pull=None):
44         """Initialize the Pin"""
45         if not self._line:
46             self._line = self._chip.get_line(int(self._num))
47             # print("init line: ", self.id, self._line)
48
49         if mode is not None:
50             if mode == self.IN:
51                 flags = 0
52                 if pull is not None:
53                     if pull == self.PULL_UP:
54                         raise NotImplementedError(
55                             "Internal pullups not supported in libgpiod, "
56                             "use physical resistor instead!"
57                         )
58                     if pull == self.PULL_DOWN:
59                         raise NotImplementedError(
60                             "Internal pulldowns not supported in libgpiod, "
61                             "use physical resistor instead!"
62                         )
63                     raise RuntimeError("Invalid pull for pin: %s" % self.id)
64
65                 self._mode = self.IN
66                 self._line.release()
67                 self._line.request(
68                     consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_IN, flags=flags
69                 )
70
71             elif mode == self.OUT:
72                 if pull is not None:
73                     raise RuntimeError("Cannot set pull resistor on output")
74                 self._mode = self.OUT
75                 self._line.release()
76                 self._line.request(consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_OUT)
77
78             else:
79                 raise RuntimeError("Invalid mode for pin: %s" % self.id)
80
81     def value(self, val=None):
82         """Set or return the Pin Value"""
83         if val is None:
84             return self._line.get_value()
85
86         if val in (self.LOW, self.HIGH):
87             self._value = val
88             self._line.set_value(val)
89             return None
90         raise RuntimeError("Invalid value for pin")