From: caternuson Date: Fri, 20 Sep 2019 01:35:41 +0000 (-0700) Subject: initial working ft232h i2c/spi/gpio X-Git-Tag: 2.5.0^2~4 X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/commitdiff_plain/ecba441c03a58ce97b3c1c769cb9c76675abbf7f initial working ft232h i2c/spi/gpio --- diff --git a/src/adafruit_blinka/board/ftdi_ft232h.py b/src/adafruit_blinka/board/ftdi_ft232h.py new file mode 100644 index 0000000..fc9aaf1 --- /dev/null +++ b/src/adafruit_blinka/board/ftdi_ft232h.py @@ -0,0 +1,21 @@ +from adafruit_blinka.microcontroller.ft232h import pin + +D4 = pin.D4 +D5 = pin.D5 +D6 = pin.D6 +D7 = pin.D7 +C0 = pin.C0 +C1 = pin.C1 +C2 = pin.C2 +C3 = pin.C3 +C4 = pin.C4 +C5 = pin.C5 +C6 = pin.C6 +C7 = pin.C7 + +SDA = pin.SDA +SCL = pin.SCL + +SCLK = pin.SCLK +MOSI = pin.MOSI +MISO = pin.MISO diff --git a/src/adafruit_blinka/microcontroller/ft232h/__init__.py b/src/adafruit_blinka/microcontroller/ft232h/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/adafruit_blinka/microcontroller/ft232h/i2c.py b/src/adafruit_blinka/microcontroller/ft232h/i2c.py new file mode 100644 index 0000000..45b8921 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/ft232h/i2c.py @@ -0,0 +1,34 @@ +from adafruit_blinka.microcontroller.ft232h.pin import Pin + +class I2C: + + def __init__(self): + # change GPIO controller to I2C + from pyftdi.i2c import I2cController + self._i2c = I2cController() + self._i2c.configure('ftdi:///1') + Pin.ft232h_gpio = self._i2c.get_gpio() + + def writeto(self, address, buffer, *, start=0, end=None, stop=True): + end = end if end else len(buffer) + port = self._i2c.get_port(address) + port.write(buffer[start:end], relax=stop) + + def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True): + end = end if end else len(buffer) + port = self._i2c.get_port(address) + result = port.read(len(buffer[start:end]), relax=stop) + for i, b in enumerate(result): + buffer[start+i] = b + + def writeto_then_readfrom(self, address, buffer_out, buffer_in, *, + out_start=0, out_end=None, + in_start=0, in_end=None, stop=False): + out_end = out_end if out_end else len(buffer_out) + in_end = in_end if in_end else len(buffer_in) + port = self._i2c.get_port(address) + result = port.exchange(buffer_out[out_start:out_end], + in_end-in_start, + relax=True).tobytes() + for i, b in enumerate(result): + buffer_in[in_start+i] = b diff --git a/src/adafruit_blinka/microcontroller/ft232h/pin.py b/src/adafruit_blinka/microcontroller/ft232h/pin.py new file mode 100644 index 0000000..d9763d2 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/ft232h/pin.py @@ -0,0 +1,79 @@ +class Pin: + """A basic Pin class for use with FT232H.""" + + IN = 0 + OUT = 1 + LOW = 0 + HIGH = 1 + + ft232h_gpio = None + + def __init__(self, pin_id=None): + # setup GPIO controller if not done yet + # use one provided by I2C as default + if not Pin.ft232h_gpio: + from pyftdi.i2c import I2cController + i2c = I2cController() + i2c.configure("ftdi:///1") + Pin.ft232h_gpio = i2c.get_gpio() + # check if pin is valid + if pin_id: + if Pin.ft232h_gpio.all_pins & 1 << pin_id == 0: + raise ValueError("Can not use pin {} as GPIO.".format(pin_id)) + # ID is just bit position + self.id = pin_id + + def init(self, mode=IN, pull=None): + if not self.id: + raise RuntimeError("Can not init a None type pin.") + # FT232H does't have configurable internal pulls? + if pull: + raise ValueError("Internal pull up/down not currently supported.") + pin_mask = Pin.ft232h_gpio.pins | 1 << self.id + current = Pin.ft232h_gpio.direction + if mode == self.OUT: + current |= 1 << self.id + else: + current &= ~(1 << self.id) + Pin.ft232h_gpio.set_direction(pin_mask, current) + + def value(self, val=None): + if not self.id: + raise RuntimeError("Can not access a None type pin.") + current = Pin.ft232h_gpio.read(with_output=True) + # read + if val is None: + return 1 if current & 1 << self.id != 0 else 0 + # write + elif val in (self.LOW, self.HIGH): + if val == self.HIGH: + current |= 1 << self.id + else: + current &= ~(1 << self.id) + Pin.ft232h_gpio.write(current & Pin.ft232h_gpio.direction) + # release the kraken + else: + raise RuntimeError("Invalid value for pin") + +# create pin instances for each pin +# D0 to D3 are used by I2C/SPI +D4 = Pin(4) +D5 = Pin(5) +D6 = Pin(6) +D7 = Pin(7) +C0 = Pin(8) +C1 = Pin(9) +C2 = Pin(10) +C3 = Pin(11) +C4 = Pin(12) +C5 = Pin(13) +C6 = Pin(14) +C7 = Pin(15) +# C8 and C9 are not GPIO + +# create None type pins for I2C and SPI since they are expected to be defined +SCL = Pin() +SDA = Pin() +SCK = SCLK = Pin() +MOSI = Pin() +MISO = Pin() \ No newline at end of file diff --git a/src/adafruit_blinka/microcontroller/ft232h/spi.py b/src/adafruit_blinka/microcontroller/ft232h/spi.py new file mode 100644 index 0000000..26e1bbb --- /dev/null +++ b/src/adafruit_blinka/microcontroller/ft232h/spi.py @@ -0,0 +1,50 @@ +from adafruit_blinka.microcontroller.ft232h.pin import Pin + +class SPI: + MSB = 0 + + baudrate = 100000 + mode = 0 + bits = 8 + + def __init__(self): + from pyftdi.spi import SpiController + self._spi = SpiController(cs_count=1) + self._spi.configure('ftdi:///1') + Pin.ft232h_gpio = self._spi.get_gpio() + + def init(self, baudrate=100000, polarity=0, phase=0, bits=8, + firstbit=MSB, sck=None, mosi=None, miso=None): + self.cs = 0 + self.freq = baudrate + if polarity == 0 and phase == 0: + self.mode = 0 + elif polarity == 0 and phase == 1: + self.mode = 1 + elif polarity == 1 and phase == 0: + raise ValueError("SPI mode 2 is not supported.") + elif polarity == 1 and phase == 1: + self.mode = 3 + else: + raise ValueError("Unknown SPI mode.") + + def write(self, buf, start=0, end=None): + end = end if end else len(buf) + port = self._spi.get_port(self.cs, self.freq, self.mode) + port.write(buf[start:end]) + + def readinto(self, buf, start=0, end=None, write_value=0): + end = end if end else len(buf) + port = self._spi.get_port(self.cs, self.freq, self.mode) + result = port.read(end-start) + for i, b in enumerate(result): + buf[start+i] = b + + def write_readinto(self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None): + out_end = out_end if out_end else len(buffer_out) + in_end = in_end if in_end else len(buffer_in) + port = self._spi.get_port(self.cs, self.freq, self.mode) + result = port.exchange(buffer_out[out_start:out_end], + in_end-in_start) + for i, b in enumerate(result): + buffer_in[in_start+i] = b \ No newline at end of file diff --git a/src/board.py b/src/board.py index 9b60001..f56af38 100755 --- a/src/board.py +++ b/src/board.py @@ -92,16 +92,19 @@ elif board_id == ap_board.ODROID_C2: from adafruit_blinka.board.odroidc2 import * elif board_id == ap_board.ODROID_N2: - from adafruit_blinka.board.odroidn2 import * + from adafruit_blinka.board.odroidn2 import * elif board_id == ap_board.DRAGONBOARD_410C: from adafruit_blinka.board.dragonboard_410c import * +elif board_id == ap_board.FTDI_FT232H: + from adafruit_blinka.board.ftdi_ft232h import * + elif "sphinx" in sys.modules: pass else: - raise NotImplementedError("Board not supported") + raise NotImplementedError("Board not supported {}".format(board_id)) def I2C(): """The singleton I2C interface""" diff --git a/src/busio.py b/src/busio.py index 0ddf7dc..9003bab 100755 --- a/src/busio.py +++ b/src/busio.py @@ -17,7 +17,11 @@ class I2C(Lockable): def init(self, scl, sda, frequency): self.deinit() - if detector.board.any_embedded_linux: + if detector.board.ftdi_ft232h: + from adafruit_blinka.microcontroller.ft232h.i2c import I2C + self._i2c = I2C() + return + elif detector.board.any_embedded_linux: from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C else: from machine import I2C as _I2C @@ -72,7 +76,13 @@ class I2C(Lockable): class SPI(Lockable): def __init__(self, clock, MOSI=None, MISO=None): self.deinit() - if detector.board.any_embedded_linux: + if detector.board.ftdi_ft232h: + from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI + from adafruit_blinka.microcontroller.ft232h.pin import SCK, MOSI, MISO + self._spi = _SPI() + self._pins = (SCK, MOSI, MISO) + return + elif detector.board.any_embedded_linux: from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI else: from machine import SPI as _SPI @@ -123,6 +133,9 @@ class SPI(Lockable): elif board_id == ap_board.JETSON_XAVIER: from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI from adafruit_blinka.microcontroller.tegra.t194.pin import Pin + elif detector.board.ftdi_ft232h: + from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI + from adafruit_blinka.microcontroller.ft232h.pin import Pin else: from machine import SPI as _SPI from machine import Pin diff --git a/src/digitalio.py b/src/digitalio.py index 6f6e9d1..c02c4d5 100755 --- a/src/digitalio.py +++ b/src/digitalio.py @@ -30,9 +30,11 @@ elif detector.chip.S905: elif detector.chip.S922X: from adafruit_blinka.microcontroller.amlogic.s922x.pin import Pin elif detector.chip.APQ8016: - from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin + from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import Pin elif detector.chip.IMX8MX: from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin +elif detector.board.ftdi_ft232h: + from adafruit_blinka.microcontroller.ft232h.pin import Pin elif detector.chip.STM32: from machine import Pin from adafruit_blinka import Enum, ContextManaged diff --git a/src/microcontroller/pin.py b/src/microcontroller/pin.py index 5dd250c..475156d 100755 --- a/src/microcontroller/pin.py +++ b/src/microcontroller/pin.py @@ -32,5 +32,7 @@ elif chip_id == ap_chip.APQ8016: from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import * elif chip_id == ap_chip.IMX8MX: from adafruit_blinka.microcontroller.nxp_imx8m.pin import * +elif chip_id == ap_chip.FT232H: + from adafruit_blinka.microcontroller.ft232h.pin import * else: raise NotImplementedError("Microcontroller not supported: ", chip_id)