]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/generic_linux/libgpiod/libgpiod_pin_2_x.py
aa1ee1861a25e86faf60aa68b505e91ffe8ee8d0
[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             line_config = gpiod.LineSettings()
52
53             if mode == self.IN:
54                 line_config.direction = gpiod.line.Direction.INPUT
55                 if pull is not None:
56                     if pull == self.PULL_UP:
57                         line_config.bias = gpiod.line.Bias.PULL_UP
58                     elif pull == self.PULL_DOWN:
59                         line_config.bias = gpiod.line.Bias.PULL_DOWN
60                     elif pull == self.PULL_NONE:
61                         line_config.bias = gpiod.line.Bias.DISABLED
62                     else:
63                         raise RuntimeError(f"Invalid pull for pin: {self.id}")
64
65             elif mode == self.OUT:
66                 if pull is not None:
67                     raise RuntimeError("Cannot set pull resistor on output")
68                 line_config.direction = gpiod.line.Direction.OUTPUT
69
70             else:
71                 raise RuntimeError(f"Invalid mode for pin: {self.id}")
72
73             self._line_request = self._chip.request_lines(
74                 {int(self._num): line_config},
75                 consumer=self._CONSUMER,
76             )
77
78     def value(self, val=None):
79         """Set or return the Pin Value"""
80         if val is None:
81             return bool(self._value_map.index(self._line_request.get_value(self._num)))
82
83         if val in (self.LOW, self.HIGH):
84             self._value = val
85             self._line_request.set_value(self._num, self._value_map[int(val)])
86             return None
87         raise RuntimeError("Invalid value for pin")