]> Repositories - Adafruit_Blinka-hackapet.git/blob - src/adafruit_blinka/microcontroller/ftdi_mpsse/mpsse/pin.py
Add support for FT2232H "microcontroller"
[Adafruit_Blinka-hackapet.git] / src / adafruit_blinka / microcontroller / ftdi_mpsse / mpsse / pin.py
1 """MPSSE pin names"""
2
3
4 class Pin:
5     """A basic Pin class for use with FTDI MPSSEs."""
6
7     IN = 0
8     OUT = 1
9     LOW = 0
10     HIGH = 1
11
12     mpsse_gpio = None
13
14     def __init__(self, pin_id=None, url="ftdi://ftdi:ft232h/1"):
15         # setup GPIO controller if not done yet
16         # use one provided by I2C as default
17         if not Pin.mpsse_gpio:
18             # pylint: disable=import-outside-toplevel
19             from pyftdi.i2c import I2cController
20
21             # pylint: enable=import-outside-toplevel
22
23             i2c = I2cController()
24             i2c.configure(url)
25             Pin.mpsse_gpio = i2c.get_gpio()
26         # check if pin is valid
27         if pin_id:
28             if Pin.mpsse_gpio.all_pins & 1 << pin_id == 0:
29                 raise ValueError("Can not use pin {} as GPIO.".format(pin_id))
30         # ID is just bit position
31         self.id = pin_id
32
33     def init(self, mode=IN, pull=None):
34         """Initialize the Pin"""
35         if not self.id:
36             raise RuntimeError("Can not init a None type pin.")
37         # MPSSE does't have configurable internal pulls?
38         if pull:
39             raise ValueError("Internal pull up/down not currently supported.")
40         pin_mask = Pin.mpsse_gpio.pins | 1 << self.id
41         current = Pin.mpsse_gpio.direction
42         if mode == self.OUT:
43             current |= 1 << self.id
44         else:
45             current &= ~(1 << self.id)
46         Pin.mpsse_gpio.set_direction(pin_mask, current)
47
48     def value(self, val=None):
49         """Set or return the Pin Value"""
50         if not self.id:
51             raise RuntimeError("Can not access a None type pin.")
52         current = Pin.mpsse_gpio.read(with_output=True)
53         # read
54         if val is None:
55             return 1 if current & 1 << self.id != 0 else 0
56         # write
57         if val in (self.LOW, self.HIGH):
58             if val == self.HIGH:
59                 current |= 1 << self.id
60             else:
61                 current &= ~(1 << self.id)
62             # must mask out any input pins
63             Pin.mpsse_gpio.write(current & Pin.mpsse_gpio.direction)
64             return None
65         # release the kraken
66         raise RuntimeError("Invalid value for pin")