]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_linux/libgpiod/libgpiod_pin_2_x.py
9f12d9d427cd07baf730e2dfa2f770766b3a1852
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / generic_linux / libgpiod / libgpiod_pin_2_x.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """A Pin class for use with libgpiod 2.x."""
5 import gpiod
6
7
8 # pylint: disable=too-many-branches,too-many-statements
9 class Pin:
10     """Pins dont exist in CPython so...lets make our own!"""
11
12     IN = 0
13     OUT = 1
14     LOW = 0
15     HIGH = 1
16     PULL_NONE = 0
17     PULL_UP = 1
18     PULL_DOWN = 2
19     _CONSUMER = "adafruit_blinka"
20
21     id = None
22     _value = LOW
23     _mode = IN
24
25     _value_map = (gpiod.line.Value.INACTIVE, gpiod.line.Value.ACTIVE)
26
27     def __init__(self, pin_id):
28         self.id = pin_id
29         chip_id = 0
30         if isinstance(pin_id, tuple):
31             chip_id, self._num = pin_id
32         if isinstance(chip_id, int):
33             chip_id = f"/dev/gpiochip{chip_id}"
34         self._chip = gpiod.Chip(chip_id)
35         self._line_request = None
36
37     def __del__(self):
38         if self._line_request:
39             self._line_request.release()
40
41     def __repr__(self):
42         return str(self.id)
43
44     def __eq__(self, other):
45         return self.id == other
46
47     def init(self, mode=IN, pull=None):
48         """Initialize the Pin"""
49         # Input,
50         if not self._line_request:
51             self._line_request = self._chip.request_lines(
52                 config={int(self._num): None},
53                 consumer=self._CONSUMER,
54             )
55             # print("init line: ", self.id, self._line)
56
57         if mode is not None:
58             line_config = gpiod.LineSettings()
59             if mode == self.IN:
60                 line_config.direction = gpiod.line.Direction.INPUT
61                 if pull is not None:
62                     if pull == self.PULL_UP:
63                         line_config.bias = gpiod.line.Bias.PULL_UP
64                     elif pull == self.PULL_DOWN:
65                         line_config.bias = gpiod.line.Bias.PULL_DOWN
66                     elif pull == self.PULL_NONE:
67                         line_config.bias = gpiod.line.Bias.DISABLED
68                     else:
69                         raise RuntimeError(f"Invalid pull for pin: {self.id}")
70
71                 self._mode = self.IN
72                 self._line_request.reconfigure_lines(
73                     {
74                         int(self._num): line_config,
75                     }
76                 )
77             elif mode == self.OUT:
78                 if pull is not None:
79                     raise RuntimeError("Cannot set pull resistor on output")
80                 self._mode = self.OUT
81                 line_config.direction = gpiod.line.Direction.OUTPUT
82                 self._line_request.reconfigure_lines(
83                     {
84                         int(self._num): line_config,
85                     }
86                 )
87             else:
88                 raise RuntimeError("Invalid mode for pin: %s" % self.id)
89
90     def value(self, val=None):
91         """Set or return the Pin Value"""
92         if val is None:
93             return bool(self._value_map.index(self._line_request.get_value(self._num)))
94
95         if val in (self.LOW, self.HIGH):
96             self._value = val
97             self._line_request.set_value(self._num, self._value_map[int(val)])
98             return None
99         raise RuntimeError("Invalid value for pin")