spidev>=3.4; sys_platform == 'linux'
sysv_ipc; sys_platform == 'linux'
pyftdi>=0.30.0
+binho-host-adapter>=0.1.4
\ No newline at end of file
--- /dev/null
+from adafruit_blinka.microcontroller.nova import pin
+
+IO0 = pin.IO0
+IO1 = pin.IO1
+IO2 = pin.IO2
+IO3 = pin.IO3
+IO4 = pin.IO4
+
+TX = IO4
+RX = IO3
+
+SDA = pin.SDA
+SCL = pin.SCL
+
+SCK = pin.SCK
+SCLK = pin.SCLK
+MOSI = pin.MOSI
+MISO = pin.MISO
+SS0 = pin.SS0
+SS1 = pin.SS1
TXD = pin.D14
D15 = pin.D15
RXD = pin.D15
+# create alias for most of the examples
+TX = pin.D14
+RX = pin.D15
D17 = pin.D17
D18 = pin.D18
TXD = pin.D14
D15 = pin.D15
RXD = pin.D15
+# create alias for most of the examples
+TX = pin.D14
+RX = pin.D15
D17 = pin.D17
D18 = pin.D18
from adafruit_blinka.microcontroller.bcm283x import pin
+D0 = pin.D0
+D1 = pin.D1
+
D2 = pin.D2
SDA = pin.SDA
D3 = pin.D3
TXD = pin.D14
D15 = pin.D15
RXD = pin.D15
+# create alias for most of the examples
+TX = pin.D14
+RX = pin.D15
D16 = pin.D16
D17 = pin.D17
TXD = pin.D14
D15 = pin.D15
RXD = pin.D15
+# create alias for most of the examples
+TX = pin.D14
+RX = pin.D15
D16 = pin.D16
D17 = pin.D17
)
i2cPorts = (
- (1, SCL, SDA), (0, D1, D0), # both pi 1 and pi 2 i2c ports!
+ (3, SCL, SDA), (1, SCL, SDA), (0, D1, D0), # both pi 1 and pi 2 i2c ports!
)
-
--- /dev/null
+class Connection:
+ __instance = None
+ @staticmethod
+ def getInstance():
+ """ Static access method. """
+ if Connection.__instance is None:
+ Connection()
+ return Connection.__instance
+
+ def __init__(self):
+ """ Virtually private constructor. """
+ if Connection.__instance is not None:
+ raise Exception("This class is a singleton!")
+
+ from binhoHostAdapter import binhoHostAdapter
+ from binhoHostAdapter import binhoUtilities
+
+ utilities = binhoUtilities.binhoUtilities()
+ devices = utilities.listAvailableDevices()
+
+ if len(devices) > 0:
+ Connection.__instance = binhoHostAdapter.binhoHostAdapter(devices[0])
+ else:
+ raise RuntimeError('No Binho Nova found!')
--- /dev/null
+class I2C:
+
+ def __init__(self):
+ from adafruit_blinka.microcontroller.nova import Connection
+ self._nova = Connection.getInstance()
+ self._nova.setNumericalBase(10)
+ self._nova.setOperationMode(0, "I2C")
+ self._nova.setPullUpStateI2C(0, "EN")
+ self._nova.setClockI2C(0, 400000)
+
+ def scan(self):
+
+ scanResults = []
+
+ for i in range(8, 121):
+ result = self._nova.scanAddrI2C(0, i<<1)
+
+ resp = result.split(" ")
+
+ if resp[3] == 'OK':
+ scanResults.append(i)
+
+ return scanResults
+
+ def writeto(self, address, buffer, *, start=0, end=None, stop=True):
+
+ end = end if end else len(buffer)
+
+ self._nova.startI2C(0, address<<1)
+
+ for i in range(start, end):
+ self._nova.writeByteI2C(0, buffer[i])
+
+ if stop:
+ self._nova.endI2C(0)
+ else:
+ self._nova.endI2C(0, True)
+
+ def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
+
+ end = end if end else len(buffer)
+
+ result = self._nova.readBytesI2C(0, address<<1, len(buffer[start:end]))
+
+ if result != "-NG":
+ resp = result.split(" ")
+
+ for i in range(len(buffer[start:end])):
+ buffer[start+i] = int(resp[2+i])
+ else:
+ raise RuntimeError("Received error response from Binho Nova, result = " + result)
+
+ 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)
+
+ self._nova.startI2C(0, address<<1)
+
+ for i in range(out_start, out_end):
+ self._nova.writeByteI2C(0, buffer_out[i])
+
+ self._nova.endI2C(0, True)
+
+ result = self._nova.readBytesI2C(0, address<<1, len(buffer_in[in_start:in_end]))
+
+ if result != "-NG":
+ resp = result.split(" ")
+
+ for i in range(len(buffer_in[in_start:in_end])):
+ buffer_in[in_start+i] = int(resp[2+i])
+ else:
+ raise RuntimeError("Received error response from Binho Nova, result = " + result)
--- /dev/null
+class Pin:
+ """A basic Pin class for use with Binho Nova."""
+
+ IN = 'DIN'
+ OUT = 'DOUT'
+ AIN = 'AIN'
+ AOUT = 'AOUT'
+ PWM = 'PWM'
+ LOW = 0
+ HIGH = 1
+
+ _nova = None
+
+ def __init__(self, pin_id=None):
+ if not Pin._nova:
+ from adafruit_blinka.microcontroller.nova import Connection
+ Pin._nova = Connection.getInstance()
+ # check if pin is valid
+ if pin_id > 4:
+ raise ValueError("Invalid pin {}.".format(pin_id))
+
+ self.id = pin_id
+
+ def init(self, mode=IN, pull=None):
+ if self.id is None:
+ raise RuntimeError("Can not init a None type pin.")
+ # Nova does't have configurable internal pulls for
+ if pull:
+ raise ValueError("Internal pull up/down not currently supported.")
+ Pin._nova.setIOpinMode(self.id, mode)
+
+ def value(self, val=None):
+ if self.id is None:
+ raise RuntimeError("Can not access a None type pin.")
+ # read
+ if val is None:
+ return int(Pin._nova.getIOpinValue(self.id).split('VALUE ')[1])
+ # write
+ if val in (self.LOW, self.HIGH):
+ Pin._nova.setIOpinValue(self.id, val)
+ else:
+ raise RuntimeError("Invalid value for pin")
+
+# create pin instances for each pin
+IO0 = Pin(0)
+IO1 = Pin(1)
+IO2 = Pin(2)
+IO3 = Pin(3)
+IO4 = Pin(4)
+
+SCL = IO2
+SDA = IO0
+SCK = SCLK = IO3
+MOSI = IO4
+MISO = IO2
+SS0 = IO0
+SS1 = IO1
+
+PWM0 = IO0
+# No PWM support on IO1
+PWM2 = IO2
+PWM3 = IO3
+PWM4 = IO4
+
+# orderd as (channel, pin), id
+pwmOuts = (((1, 0), PWM0), ((1, 2), PWM2), ((1, 3), PWM3), ((1, 4), PWM4))
+
+UART1_TX = IO4
+UART1_RX = IO3
+
+# ordered as uartId, txId, rxId
+uartPorts = ((0, UART1_TX, UART1_RX), )
--- /dev/null
+
+try:
+ from microcontroller.pin import pwmOuts
+except ImportError:
+ raise RuntimeError("No PWM outputs defined for this board")
+
+from microcontroller.pin import Pin
+
+class PWMError(IOError):
+ """Base class for PWM errors."""
+ pass
+
+
+class PWMOut(object):
+ # Nova instance
+ _nova = None
+ MAX_CYCLE_LEVEL = 1024
+
+ def __init__(self, pin, *, frequency=750, duty_cycle=0, variable_frequency=False):
+ """Instantiate a PWM object and open the sysfs PWM corresponding to the
+ specified channel and pin.
+
+ Args:
+ pin (Pin): CircuitPython Pin object to output to
+ duty_cycle (int) : The fraction of each pulse which is high. 16-bit
+ frequency (int) : target frequency in Hertz (32-bit)
+ variable_frequency (bool) : True if the frequency will change over time
+
+ Returns:
+ PWMOut: PWMOut object.
+
+ Raises:
+ PWMError: if an I/O or OS error occurs.
+ TypeError: if `channel` or `pin` types are invalid.
+ ValueError: if PWM channel does not exist.
+
+ """
+ if PWMOut._nova is None:
+ from adafruit_blinka.microcontroller.nova import Connection
+ PWMOut._nova = Connection.getInstance()
+
+ PWMOut._nova.setOperationMode(0, 'IO')
+ self._pwmpin = None
+ self._open(pin, duty_cycle, frequency, variable_frequency)
+
+ def __del__(self):
+ self.deinit()
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, t, value, traceback):
+ self.deinit()
+
+ def _open(self, pin, duty=0, freq=750, variable_frequency=False):
+ self._channel = None
+ for pwmpair in pwmOuts:
+ if pwmpair[1] == pin:
+ self._channel = pwmpair[0][0]
+ self._pwmpin = pwmpair[0][1]
+
+ self._pin = pin
+ if self._channel is None:
+ raise RuntimeError("No PWM channel found for this Pin")
+
+ PWMOut._nova.setIOpinMode(self._pwmpin, Pin.PWM)
+
+ # set frequency
+ self.frequency = freq
+ # set period
+ self._period = self._get_period()
+
+ # set duty
+ self.duty_cycle = duty
+
+ self._set_enabled(True)
+
+ def deinit(self):
+ try:
+ """Deinit the Nova PWM."""
+ if self._channel is not None:
+ #self.duty_cycle = 0
+ self._set_enabled(False) # make to disable before unexport
+
+ except Exception as e:
+ # due to a race condition for which I have not yet been
+ # able to find the root cause, deinit() often fails
+ # but it does not effect future usage of the pwm pin
+ print("warning: failed to deinitialize pwm pin {0}:{1} due to: {2}\n".format(self._channel, self._pwmpin, type(e).__name__))
+ finally:
+ self._channel = None
+ self._pwmpin = None
+
+ def _is_deinited(self):
+ if self._pwmpin is None:
+ raise ValueError("Object has been deinitialize and can no longer "
+ "be used. Create a new object.")
+
+ # Mutable properties
+
+ def _get_period(self):
+ return 1.0 / self._get_frequency()
+
+ def _set_period(self, period):
+ if not isinstance(period, (int, float)):
+ raise TypeError("Invalid period type, should be int or float.")
+
+ self._set_frequency(1.0 / period)
+
+ period = property(_get_period, _set_period)
+
+ """Get or set the PWM's output period in seconds.
+
+ Raises:
+ PWMError: if an I/O or OS error occurs.
+ TypeError: if value type is not int or float.
+
+ :type: int, float
+ """
+
+ def _get_duty_cycle(self):
+ duty_cycle = Pin._nova.getIOpinValue(self._pwmpin)
+
+ # Convert duty cycle to ratio from 0.0 to 1.0
+ duty_cycle = duty_cycle / PWMOut.MAX_CYCLE_LEVEL
+
+ # convert to 16-bit
+ duty_cycle = int(duty_cycle * 65535)
+ return duty_cycle
+
+ def _set_duty_cycle(self, duty_cycle):
+ if not isinstance(duty_cycle, (int, float)):
+ raise TypeError("Invalid duty cycle type, should be int or float.")
+
+ # convert from 16-bit
+ duty_cycle /= 65535.0
+ if not 0.0 <= duty_cycle <= 1.0:
+ raise ValueError("Invalid duty cycle value, should be between 0.0 and 1.0.")
+
+ # Convert duty cycle from ratio to 1024 levels
+ duty_cycle = duty_cycle * PWMOut.MAX_CYCLE_LEVEL
+
+ # Set duty cycle
+ Pin._nova.setIOpinValue(self._pwmpin, duty_cycle)
+
+ duty_cycle = property(_get_duty_cycle, _set_duty_cycle)
+ """Get or set the PWM's output duty cycle as a ratio from 0.0 to 1.0.
+
+ Raises:
+ PWMError: if an I/O or OS error occurs.
+ TypeError: if value type is not int or float.
+ ValueError: if value is out of bounds of 0.0 to 1.0.
+
+ :type: int, float
+ """
+
+ def _get_frequency(self):
+ return int(PWMOut._nova.getIOpinPWMFreq(self._pwmpin).split('PWMFREQ ')[1])
+
+ def _set_frequency(self, frequency):
+ if not isinstance(frequency, (int, float)):
+ raise TypeError("Invalid frequency type, should be int or float.")
+
+ PWMOut._nova.setIOpinPWMFreq(self._pwmpin, frequency)
+
+ frequency = property(_get_frequency, _set_frequency)
+ """Get or set the PWM's output frequency in Hertz.
+
+ Raises:
+ PWMError: if an I/O or OS error occurs.
+ TypeError: if value type is not int or float.
+
+ :type: int, float
+ """
+
+ def _get_enabled(self):
+ enabled = self._enable
+
+ if enabled == "1":
+ return True
+ elif enabled == "0":
+ return False
+
+ raise PWMError(None, "Unknown enabled value: \"%s\"" % enabled)
+
+ def _set_enabled(self, value):
+ if not isinstance(value, bool):
+ raise TypeError("Invalid enabled type, should be string.")
+ self._enable = value
+ if not self._enable:
+ self._set_duty_cycle(0.0)
+ """Get or set the PWM's output enabled state.
+
+ Raises:
+ PWMError: if an I/O or OS error occurs.
+ TypeError: if value type is not bool.
+
+ :type: bool
+ """
+
+ # String representation
+
+ def __str__(self):
+ return "PWM%d, pin %s (freq=%f Hz, duty_cycle=%f%%)" % \
+ (self._pin, self._pin, self.frequency, self.duty_cycle * 100,)
--- /dev/null
+class SPI:
+ MSB = 0
+ PAYLOAD_MAX_LENGTH = 64
+
+ def __init__(self, clock):
+ from adafruit_blinka.microcontroller.nova import Connection
+ self._nova = Connection.getInstance()
+ self._nova.setNumericalBase(10)
+ self._nova.setOperationMode(0, 'SPI')
+ self._nova.setClockSPI(0, clock)
+ self._nova.setModeSPI(0, 0)
+ self._nova.setIOpinMode(0, 'DOUT')
+ self._nova.setIOpinMode(1, 'DOUT')
+ self._nova.beginSPI(0)
+
+ # Cpol and Cpha set by mode
+ # Mode Cpol Cpha
+ # 0 0 0
+ # 1 0 1
+ # 2 1 0
+ # 3 1 1
+
+ def init(self, baudrate=100000, polarity=0, phase=0, bits=8,
+ firstbit=MSB, sck=None, mosi=None, miso=None):
+ #print("baudrate: " + str(baudrate))
+ #print("mode: " + str((polarity<<1) | (phase)))
+ self._nova.setClockSPI(0, baudrate)
+ self._nova.setModeSPI(0, (polarity<<1) | (phase))
+
+ @staticmethod
+ def get_received_data(lineOutput):
+ return (lineOutput.split('RXD ')[1])
+
+ @property
+ def frequency(self):
+ return self._nova.getClockSPI(0).split('CLK ')[1]
+
+ def write(self, buf, start=0, end=None):
+ end = end if end else len(buf)
+ chunks, rest = divmod(end - start, self.PAYLOAD_MAX_LENGTH)
+ for i in range(chunks):
+ chunk_start = start + i * self.PAYLOAD_MAX_LENGTH
+ chunk_end = chunk_start + self.PAYLOAD_MAX_LENGTH
+ buffer_data = buf[chunk_start:chunk_end]
+ self._nova.clearBuffer(0)
+ self._nova.writeToBuffer(0, 0, buffer_data)
+ self._nova.transferBufferSPI(0, chunk_end - chunk_start + 1)
+ if rest:
+ buffer_data = buf[-1*rest:]
+ self._nova.clearBuffer(0)
+ self._nova.writeToBuffer(0, 0, buffer_data)
+ self._nova.transferBufferSPI(0, rest)
+
+ def readinto(self, buf, start=0, end=None, write_value=0):
+ end = end if end else len(buf)
+ for i in range(start, end):
+ buf[start+i] = int(self.get_received_data(self._nova.transferSPI(0, write_value)))
+
+ 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)
+ readlen = in_end-in_start
+ writelen = out_end-out_start
+ if readlen > writelen:
+ # resize out and pad with 0's
+ tmp = bytearray(buffer_out)
+ tmp.extend([0] * (readlen - len(buffer_out)))
+ buffer_out = tmp
+ i = 0
+ for data_out in buffer_out:
+ data_in = int(self.get_received_data(self._nova.transferSPI(0, data_out)))
+ if i < readlen:
+ buffer_in[in_start+i] = data_in
+ i += 1
--- /dev/null
+import time
+
+class UART():
+ ESCAPE_SEQUENCE = "+++UART0"
+ def __init__(self,
+ portid,
+ baudrate=9600,
+ bits=8,
+ parity=None,
+ stop=1,
+ timeout=1000,
+ read_buf_len=None,
+ flow=None):
+ from adafruit_blinka.microcontroller.nova import Connection
+ self._nova = Connection.getInstance()
+
+ self._id = portid
+ self._baudrate = baudrate
+ self._parity = parity
+ self._bits = bits
+ self._stop = stop
+ self._timeout = timeout
+
+ if flow is not None: # default 0
+ raise NotImplementedError(
+ "Parameter '{}' unsupported on Binho Nova".format(
+ "flow"))
+
+ self._nova.setOperationMode(self._id, 'UART')
+ self._nova.setBaudRateUART(self._id, baudrate)
+ self._nova.setDataBitsUART(self._id, bits)
+ self._nova.setParityUART(self._id, parity)
+ self._nova.setStopBitsUART(self._id, stop)
+ self._nova.setEscapeSequenceUART(self._id, UART.ESCAPE_SEQUENCE)
+ self._nova.beginBridgeUART(self._id)
+
+ def deinit(self):
+ self._nova.writeBridgeUART(UART.ESCAPE_SEQUENCE)
+ self._nova.stopBridgeUART(UART.ESCAPE_SEQUENCE)
+
+ def read(self, nbytes=None):
+ if nbytes is None:
+ return None
+ data = bytearray()
+ for i in range(nbytes):
+ data.append(ord(self._nova.readBridgeUART()))
+ return data
+
+ def readinto(self, buf, nbytes=None):
+ if nbytes is None:
+ return None
+ for i in range(nbytes):
+ buf.append(ord(self._nova.readBridgeUART()))
+ return buf
+
+ def readline(self):
+ out = self._nova.readBridgeUART()
+ line = out
+ while out != '\r':
+ out = self._nova.readBridgeUART()
+ line += out
+ return line
+
+ def write(self, buf):
+ return self._nova.writeBridgeUART(buf)
elif board_id == ap_board.BEAGLEBONE_BLACK:
from adafruit_blinka.board.beaglebone_black import *
+
+elif board_id == ap_board.BEAGLEBONE_BLACK_INDUSTRIAL:
+ from adafruit_blinka.board.beaglebone_black import *
+
+elif board_id == ap_board.BEAGLEBONE_GREEN_WIRELESS:
+ from adafruit_blinka.board.beaglebone_black import *
elif board_id == ap_board.BEAGLEBONE_POCKETBEAGLE:
from adafruit_blinka.board.beaglebone_pocketbeagle import *
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
from adafruit_blinka.microcontroller.ft232h.i2c import I2C
self._i2c = I2C()
return
+ elif detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.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
from microcontroller.pin import i2cPorts
for portId, portScl, portSda in i2cPorts:
- if scl == portScl and sda == portSda:
- self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
- break
+ try:
+ if scl == portScl and sda == portSda:
+ self._i2c = _I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
+ break
+ except RuntimeError:
+ pass
else:
raise ValueError(
"No Hardware I2C on (scl,sda)={}\nValid I2C ports: {}".format((scl, sda), i2cPorts)
self._spi = _SPI()
self._pins = (SCK, MOSI, MISO)
return
+ elif detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
+ from adafruit_blinka.microcontroller.nova.pin import SCK, MOSI, MISO
+ self._spi = _SPI(clock)
+ self._pins = (SCK, MOSI, MISO)
+ return
elif detector.board.any_embedded_linux:
from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
else:
elif detector.board.ftdi_ft232h:
from adafruit_blinka.microcontroller.ft232h.spi import SPI as _SPI
from adafruit_blinka.microcontroller.ft232h.pin import Pin
+ elif detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.spi import SPI as _SPI
+ from adafruit_blinka.microcontroller.nova.pin import Pin
else:
from machine import SPI as _SPI
from machine import Pin
flow=None):
if detector.board.any_embedded_linux:
raise RuntimeError('busio.UART not supported on this platform. Please use pyserial instead.')
+ elif detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.uart import UART as _UART
else:
from machine import UART as _UART
- from microcontroller.pin import uartPorts
+
+ if detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.pin import uartPorts
+ else:
+ from microcontroller.pin import uartPorts
self.baudrate = baudrate
)
def deinit(self):
+ if detector.board.binho_nova:
+ self._uart.deinit()
self._uart = None
def read(self, nbytes=None):
from adafruit_blinka.microcontroller.nxp_imx8m.pin import Pin
elif detector.board.ftdi_ft232h:
from adafruit_blinka.microcontroller.ft232h.pin import Pin
+elif detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.pin import Pin
elif detector.chip.STM32:
from machine import Pin
from adafruit_blinka import Enum, ContextManaged
from adafruit_blinka.microcontroller.snapdragon.apq8016.pin import *
elif chip_id == ap_chip.IMX8MX:
from adafruit_blinka.microcontroller.nxp_imx8m import *
+elif chip_id == ap_chip.BINHO:
+ from adafruit_blinka.microcontroller.nova import *
else:
raise NotImplementedError("Microcontroller not supported:", chip_id)
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.BINHO:
+ from adafruit_blinka.microcontroller.nova.pin import *
else:
raise NotImplementedError("Microcontroller not supported: ", chip_id)
from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
if detector.board.any_beaglebone:
from adafruit_blinka.microcontroller.am335x.sysfs_pwmout import PWMOut
+if detector.board.binho_nova:
+ from adafruit_blinka.microcontroller.nova.pwmout import PWMOut