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 # pylint: disable=too-many-branches,too-many-statements
 
  16     """Pins dont exist in CPython so...lets make our own!"""
 
  25     _CONSUMER = "adafruit_blinka"
 
  31     def __init__(self, pin_id):
 
  33         if isinstance(pin_id, tuple):
 
  34             self._num = int(pin_id[1])
 
  35             if hasattr(gpiod, "Chip"):
 
  36                 self._chip = gpiod.Chip(str(pin_id[0]), gpiod.Chip.OPEN_BY_NUMBER)
 
  38                 self._chip = gpiod.chip(str(pin_id[0]), gpiod.chip.OPEN_BY_NUMBER)
 
  40             self._num = int(pin_id)
 
  41             if hasattr(gpiod, "Chip"):
 
  42                 self._chip = gpiod.Chip("gpiochip0", gpiod.Chip.OPEN_BY_NAME)
 
  44                 self._chip = gpiod.chip("gpiochip0", gpiod.chip.OPEN_BY_NAME)
 
  50     def __eq__(self, other):
 
  51         return self.id == other
 
  53     def init(self, mode=IN, pull=None):
 
  54         """Initialize the Pin"""
 
  56             self._line = self._chip.get_line(int(self._num))
 
  57             # print("init line: ", self.id, self._line)
 
  64                     if pull == self.PULL_UP:
 
  65                         if hasattr(gpiod, "LINE_REQ_FLAG_BIAS_PULL_UP"):
 
  66                             flags |= gpiod.LINE_REQ_FLAG_BIAS_PULL_UP
 
  68                             raise NotImplementedError(
 
  69                                 "Internal pullups not supported in this version of libgpiod, "
 
  70                                 "use physical resistor instead!"
 
  72                     elif pull == self.PULL_DOWN:
 
  73                         if hasattr(gpiod, "line") and hasattr(
 
  74                             gpiod, "LINE_REQ_FLAG_BIAS_PULL_DOWN"
 
  76                             flags |= gpiod.LINE_REQ_FLAG_BIAS_PULL_DOWN
 
  78                             raise NotImplementedError(
 
  79                                 "Internal pulldowns not supported in this version of libgpiod, "
 
  80                                 "use physical resistor instead!"
 
  82                     elif pull == self.PULL_NONE:
 
  83                         if hasattr(gpiod, "line") and hasattr(
 
  84                             gpiod, "LINE_REQ_FLAG_BIAS_DISABLE"
 
  86                             flags |= gpiod.LINE_REQ_FLAG_BIAS_DISABLE
 
  88                             raise NotImplementedError(
 
  89                                 "Internal pulldowns not supported in this version of libgpiod, "
 
  90                                 "use physical resistor instead!"
 
  93                         raise RuntimeError(f"Invalid pull for pin: {self.id}")
 
  97                 if hasattr(gpiod, "LINE_REQ_DIR_IN"):
 
  99                         consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_IN, flags=flags
 
 102                     config = gpiod.line_request()
 
 103                     config.consumer = self._CONSUMER
 
 104                     config.request_type = gpiod.line_request.DIRECTION_INPUT
 
 105                     self._line.request(config)
 
 107             elif mode == self.OUT:
 
 109                     raise RuntimeError("Cannot set pull resistor on output")
 
 110                 self._mode = self.OUT
 
 112                 if hasattr(gpiod, "LINE_REQ_DIR_OUT"):
 
 114                         consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_OUT
 
 117                     config = gpiod.line_request()
 
 118                     config.consumer = self._CONSUMER
 
 119                     config.request_type = gpiod.line_request.DIRECTION_OUTPUT
 
 120                     self._line.request(config)
 
 122                 raise RuntimeError("Invalid mode for pin: %s" % self.id)
 
 124     def value(self, val=None):
 
 125         """Set or return the Pin Value"""
 
 127             return self._line.get_value()
 
 129         if val in (self.LOW, self.HIGH):
 
 131             self._line.set_value(val)
 
 133         raise RuntimeError("Invalid value for pin")