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