From: Francis Guevarra Date: Sun, 17 Nov 2019 05:38:12 +0000 (-0800) Subject: Initial Binho Nova plumbing X-Git-Tag: 3.1.0^2^2~1^2~13 X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/commitdiff_plain/7c00bb4d5237d7d46b65b33d62bbefe3381ded67 Initial Binho Nova plumbing --- diff --git a/src/adafruit_blinka/board/binho_nova.py b/src/adafruit_blinka/board/binho_nova.py new file mode 100644 index 0000000..12ffa9a --- /dev/null +++ b/src/adafruit_blinka/board/binho_nova.py @@ -0,0 +1,22 @@ +from adafruit_blinka.microcontroller.nova 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 + +SCK = pin.SCK +SCLK = pin.SCLK +MOSI = pin.MOSI +MISO = pin.MISO diff --git a/src/adafruit_blinka/microcontroller/nova/__init__.py b/src/adafruit_blinka/microcontroller/nova/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/adafruit_blinka/microcontroller/nova/i2c.py b/src/adafruit_blinka/microcontroller/nova/i2c.py new file mode 100644 index 0000000..4e34a7d --- /dev/null +++ b/src/adafruit_blinka/microcontroller/nova/i2c.py @@ -0,0 +1,37 @@ +from adafruit_blinka.microcontroller.nova.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 scan(self): + return [addr for addr in range(0x79) if self._i2c.poll(addr)] + + 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/nova/pin.py b/src/adafruit_blinka/microcontroller/nova/pin.py new file mode 100644 index 0000000..30dbc66 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/nova/pin.py @@ -0,0 +1,80 @@ +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) + # must mask out any input pins + 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() diff --git a/src/adafruit_blinka/microcontroller/nova/spi.py b/src/adafruit_blinka/microcontroller/nova/spi.py new file mode 100644 index 0000000..7882f23 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/nova/spi.py @@ -0,0 +1,49 @@ +from adafruit_blinka.microcontroller.nova.pin import Pin + +class SPI: + MSB = 0 + + def __init__(self): + from pyftdi.spi import SpiController + self._spi = SpiController(cs_count=1) + self._spi.configure('ftdi:///1') + self._port = self._spi.get_port(0) + self._port.set_frequency(100000) + self._port._cpol = 0 + self._port._cpha = 0 + # Change GPIO controller to SPI + 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._port.set_frequency(baudrate) + self._port._cpol = polarity + self._port._cpha = phase + + @property + def frequency(self): + return self._port.frequency + + def write(self, buf, start=0, end=None): + end = end if end else len(buf) + chunks, rest = divmod(end - start, self._spi.PAYLOAD_MAX_LENGTH) + for i in range(chunks): + chunk_start = start + i * self._spi.PAYLOAD_MAX_LENGTH + chunk_end = chunk_start + self._spi.PAYLOAD_MAX_LENGTH + self._port.write(buf[chunk_start:chunk_end]) + if rest: + self._port.write(buf[-1*rest:]) + + def readinto(self, buf, start=0, end=None, write_value=0): + end = end if end else len(buf) + result = self._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) + result = self._port.exchange(buffer_out[out_start:out_end], + in_end-in_start, duplex=True) + for i, b in enumerate(result): + buffer_in[in_start+i] = b diff --git a/src/board.py b/src/board.py index f56af38..e8b5dc4 100755 --- a/src/board.py +++ b/src/board.py @@ -100,6 +100,9 @@ elif board_id == ap_board.DRAGONBOARD_410C: elif board_id == ap_board.FTDI_FT232H: from adafruit_blinka.board.ftdi_ft232h import * +elif board_id == ap_board.BINHO_NOVA: + from adafruit_blinka.board.binho_nova import * + elif "sphinx" in sys.modules: pass diff --git a/src/microcontroller/pin.py b/src/microcontroller/pin.py index 475156d..b7298f3 100755 --- a/src/microcontroller/pin.py +++ b/src/microcontroller/pin.py @@ -34,5 +34,7 @@ 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 * +elif chip_id == ap_chip.NOVA: + from adafruit_blinka.microcontroller.nova.pin import * else: raise NotImplementedError("Microcontroller not supported: ", chip_id)