]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/ftdi_mpsse/mpsse/pin.py
Add board & microcontroller.
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / ftdi_mpsse / mpsse / pin.py
1 # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
2 #
3 # SPDX-License-Identifier: MIT
4 """MPSSE pin names"""
5
6 from adafruit_blinka.microcontroller.ftdi_mpsse.mpsse.url import (
7     get_ft232h_url,
8     get_ft2232h_url,
9 )
10
11
12 class Pin:
13     """A basic Pin class for use with FTDI MPSSEs."""
14
15     IN = 0
16     OUT = 1
17     LOW = 0
18     HIGH = 1
19     PULL_NONE = 0
20     PULL_UP = 1
21     PULL_DOWN = 2
22
23     mpsse_gpio = None
24
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
31
32             # pylint: enable=import-outside-toplevel
33
34             i2c = I2cController()
35             if interface_id is None:
36                 i2c.configure(get_ft232h_url())
37             else:
38                 i2c.configure(get_ft2232h_url(interface_id))
39             Pin.mpsse_gpio = i2c.get_gpio()
40         # check if pin is valid
41         if pin_id:
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
45         self.id = pin_id
46
47     def init(self, mode=IN, pull=None):
48         """Initialize the Pin"""
49         if not self.id:
50             raise RuntimeError("Can not init a None type pin.")
51         # MPSSE does't have configurable internal pulls?
52         if pull:
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
56         if mode == self.OUT:
57             current |= 1 << self.id
58         else:
59             current &= ~(1 << self.id)
60         Pin.mpsse_gpio.set_direction(pin_mask, current)
61
62     def value(self, val=None):
63         """Set or return the Pin Value"""
64         if not self.id:
65             raise RuntimeError("Can not access a None type pin.")
66         current = Pin.mpsse_gpio.read(with_output=True)
67         # read
68         if val is None:
69             return 1 if current & 1 << self.id != 0 else 0
70         # write
71         if val in (self.LOW, self.HIGH):
72             if val == self.HIGH:
73                 current |= 1 << self.id
74             else:
75                 current &= ~(1 << self.id)
76             # must mask out any input pins
77             Pin.mpsse_gpio.write(current & Pin.mpsse_gpio.direction)
78             return None
79         # release the kraken
80         raise RuntimeError("Invalid value for pin")