1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
3 # SPDX-License-Identifier: MIT
6 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.url import (
13 """A basic Pin class for use with FTDI MPSSEs."""
25 def __init__(self, pin_id=None, interface_id=None):
26 # setup GPIO controller if not done yet
27 # use one provided by I2C as default
28 if not Pin.mpsse_gpio:
29 # pylint: disable=import-outside-toplevel
30 from pyftdi.i2c import I2cController
32 # pylint: enable=import-outside-toplevel
35 if interface_id is None:
36 i2c.configure(get_ft232h_url())
38 i2c.configure(get_ftx232h_url(interface_id))
39 Pin.mpsse_gpio = i2c.get_gpio()
40 # check if pin is valid
42 if Pin.mpsse_gpio.all_pins & 1 << pin_id == 0:
43 raise ValueError("Can not use pin {} as GPIO.".format(pin_id))
44 # ID is just bit position
47 def init(self, mode=IN, pull=None):
48 """Initialize the Pin"""
50 raise RuntimeError("Can not init a None type pin.")
51 # MPSSE does't have configurable internal pulls?
53 raise NotImplementedError("Internal pull up/down not currently supported.")
54 pin_mask = Pin.mpsse_gpio.pins | 1 << self.id
55 current = Pin.mpsse_gpio.direction
57 current |= 1 << self.id
59 current &= ~(1 << self.id)
60 Pin.mpsse_gpio.set_direction(pin_mask, current)
62 def value(self, val=None):
63 """Set or return the Pin Value"""
65 raise RuntimeError("Can not access a None type pin.")
66 current = Pin.mpsse_gpio.read(with_output=True)
69 return 1 if current & 1 << self.id != 0 else 0
71 if val in (self.LOW, self.HIGH):
73 current |= 1 << self.id
75 current &= ~(1 << self.id)
76 # must mask out any input pins
77 Pin.mpsse_gpio.write(current & Pin.mpsse_gpio.direction)
80 raise RuntimeError("Invalid value for pin")