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"
 
  13 # pylint: disable=too-many-branches,too-many-statements
 
  15     """Pins dont exist in CPython so...lets make our own!"""
 
  24     _CONSUMER = "adafruit_blinka"
 
  30     def __init__(self, pin_id):
 
  32         if isinstance(pin_id, tuple):
 
  33             self._num = int(pin_id[1])
 
  34             if hasattr(gpiod, "Chip"):
 
  35                 self._chip = gpiod.Chip(str(pin_id[0]), gpiod.Chip.OPEN_BY_NUMBER)
 
  37                 self._chip = gpiod.chip(str(pin_id[0]), gpiod.chip.OPEN_BY_NUMBER)
 
  39             self._num = int(pin_id)
 
  40             if hasattr(gpiod, "Chip"):
 
  41                 self._chip = gpiod.Chip("gpiochip0", gpiod.Chip.OPEN_BY_NAME)
 
  43                 self._chip = gpiod.chip("gpiochip0", gpiod.chip.OPEN_BY_NAME)
 
  49     def __eq__(self, other):
 
  50         return self.id == other
 
  52     def init(self, mode=IN, pull=None):
 
  53         """Initialize the Pin"""
 
  55             self._line = self._chip.get_line(int(self._num))
 
  56             # print("init line: ", self.id, self._line)
 
  63                     if pull == self.PULL_UP:
 
  64                         if hasattr(gpiod, "line") and hasattr(
 
  65                             gpiod.line, "BIAS_PULL_UP"
 
  67                             config = gpiod.line_request()
 
  68                             config.consumer = self._CONSUMER
 
  69                             config.request_type = gpiod.line.BIAS_PULL_UP
 
  70                             self._line.request(config)
 
  73                                 consumer=self._CONSUMER,
 
  74                                 type=gpiod.LINE_REQ_DIR_IN,
 
  77                             raise NotImplementedError(
 
  78                                 "Internal pullups not supported in this version of libgpiod, "
 
  79                                 "use physical resistor instead!"
 
  81                     elif pull == self.PULL_DOWN:
 
  82                         if hasattr(gpiod, "line") and hasattr(
 
  83                             gpiod.line, "BIAS_PULL_DOWN"
 
  85                             config = gpiod.line_request()
 
  86                             config.consumer = self._CONSUMER
 
  87                             config.request_type = gpiod.line.BIAS_PULL_DOWN
 
  88                             self._line.request(config)
 
  90                             raise NotImplementedError(
 
  91                                 "Internal pulldowns not supported in this version of libgpiod, "
 
  92                                 "use physical resistor instead!"
 
  94                     elif pull == self.PULL_NONE:
 
  95                         if hasattr(gpiod, "line") and hasattr(
 
  96                             gpiod.line, "BIAS_DISABLE"
 
  98                             config = gpiod.line_request()
 
  99                             config.consumer = self._CONSUMER
 
 100                             config.request_type = gpiod.line.BIAS_DISABLE
 
 101                             self._line.request(config)
 
 103                         raise RuntimeError(f"Invalid pull for pin: {self.id}")
 
 107                 if hasattr(gpiod, "LINE_REQ_DIR_IN"):
 
 109                         consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_IN, flags=flags
 
 112                     config = gpiod.line_request()
 
 113                     config.consumer = self._CONSUMER
 
 114                     config.request_type = gpiod.line_request.DIRECTION_INPUT
 
 115                     self._line.request(config)
 
 117             elif mode == self.OUT:
 
 119                     raise RuntimeError("Cannot set pull resistor on output")
 
 120                 self._mode = self.OUT
 
 122                 if hasattr(gpiod, "LINE_REQ_DIR_OUT"):
 
 124                         consumer=self._CONSUMER, type=gpiod.LINE_REQ_DIR_OUT
 
 127                     config = gpiod.line_request()
 
 128                     config.consumer = self._CONSUMER
 
 129                     config.request_type = gpiod.line_request.DIRECTION_OUTPUT
 
 130                     self._line.request(config)
 
 132                 raise RuntimeError("Invalid mode for pin: %s" % self.id)
 
 134     def value(self, val=None):
 
 135         """Set or return the Pin Value"""
 
 137             return self._line.get_value()
 
 139         if val in (self.LOW, self.HIGH):
 
 141             self._line.set_value(val)
 
 143         raise RuntimeError("Invalid value for pin")