From 99ce0ad895659a2e1ba26003d4b5f78e6471f8e4 Mon Sep 17 00:00:00 2001 From: Martin Schnur Date: Wed, 21 Sep 2022 19:28:18 +0200 Subject: [PATCH 1/2] Added support for Siemens Simatic IOT2050 Basic/Advanced Added support for GPIO, AIO, I2C, SPI, UART, PWM, NeoPixels --- src/adafruit_blinka/board/siemens/__init__.py | 4 + .../board/siemens/siemens_iot2050.py | 60 ++++++ .../microcontroller/am65xx/__init__.py | 0 .../microcontroller/am65xx/analogio.py | 57 +++++ .../microcontroller/am65xx/i2c.py | 94 +++++++++ .../microcontroller/am65xx/pin.py | 199 ++++++++++++++++++ .../microcontroller/am65xx/pwmout.py | 177 ++++++++++++++++ .../microcontroller/am65xx/spi.py | 144 +++++++++++++ src/analogio.py | 3 + src/board.py | 3 + src/busio.py | 17 +- src/digitalio.py | 2 + src/microcontroller/__init__.py | 2 + src/microcontroller/pin.py | 2 + src/pwmio.py | 2 + 15 files changed, 765 insertions(+), 1 deletion(-) create mode 100644 src/adafruit_blinka/board/siemens/__init__.py create mode 100644 src/adafruit_blinka/board/siemens/siemens_iot2050.py create mode 100644 src/adafruit_blinka/microcontroller/am65xx/__init__.py create mode 100644 src/adafruit_blinka/microcontroller/am65xx/analogio.py create mode 100644 src/adafruit_blinka/microcontroller/am65xx/i2c.py create mode 100644 src/adafruit_blinka/microcontroller/am65xx/pin.py create mode 100644 src/adafruit_blinka/microcontroller/am65xx/pwmout.py create mode 100644 src/adafruit_blinka/microcontroller/am65xx/spi.py diff --git a/src/adafruit_blinka/board/siemens/__init__.py b/src/adafruit_blinka/board/siemens/__init__.py new file mode 100644 index 00000000..83d86e75 --- /dev/null +++ b/src/adafruit_blinka/board/siemens/__init__.py @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2022 Martin Schnur for Siemens AG +# +# SPDX-License-Identifier: MIT +"""Boards definition from Siemens AG""" diff --git a/src/adafruit_blinka/board/siemens/siemens_iot2050.py b/src/adafruit_blinka/board/siemens/siemens_iot2050.py new file mode 100644 index 00000000..80a288d2 --- /dev/null +++ b/src/adafruit_blinka/board/siemens/siemens_iot2050.py @@ -0,0 +1,60 @@ +# SPDX-FileCopyrightText: 2022 Martin Schnur for Siemens AG +# +# SPDX-License-Identifier: MIT +"""Pin definitions for the Siemens Simatic IOT2050 Basic/Advanced.""" +# Output Pins are the same as Arduino Uno R3,Overall 31 + 1 Pins ! + +from adafruit_blinka.microcontroller.am65xx import pin + +# Digital Pins +D0 = pin.D0 +D1 = pin.D1 +D2 = pin.D2 +D3 = pin.D3 +D4 = pin.D4 +D5 = pin.D5 +D6 = pin.D6 +D7 = pin.D7 +D8 = pin.D8 +D9 = pin.D9 +D10 = pin.D10 +D11 = pin.D11 +D12 = pin.D12 +D13 = pin.D13 +D14 = pin.D14 +D15 = pin.D15 +D16 = pin.D16 +D17 = pin.D17 +D18 = pin.D18 +D19 = pin.D19 + +# Analog Pins +A0 = pin.A0 +A1 = pin.A1 +A2 = pin.A2 +A3 = pin.A3 +A4 = pin.A4 +A5 = pin.A5 + +# I2C allocation +SCL = pin.I2C_SCL +SDA = pin.I2C_SDA + +# SPI allocation +SCLK = pin.SPIO_SCLK +MOSI = pin.SPIO_MOSI +MISO = pin.SPIO_MISO +SS = pin.SPIO_SS + +# UART allocation +UART_TX = pin.UART_TX +UART_RX = pin.UART_RX + + +# PWM allocation +PWM_4 = pin.PWM_4 +PWM_5 = pin.PWM_5 +PWM_6 = pin.PWM_6 +PWM_7 = pin.PWM_7 +PWM_8 = pin.PWM_8 +PWM_9 = pin.PWM_9 diff --git a/src/adafruit_blinka/microcontroller/am65xx/__init__.py b/src/adafruit_blinka/microcontroller/am65xx/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/adafruit_blinka/microcontroller/am65xx/analogio.py b/src/adafruit_blinka/microcontroller/am65xx/analogio.py new file mode 100644 index 00000000..aab050e1 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/am65xx/analogio.py @@ -0,0 +1,57 @@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT +""" +`analogio` - Analog input and output control +================================================= +See `CircuitPython:analogio` in CircuitPython for more details. +* Author(s): Martin Schnur +""" + +from adafruit_blinka.microcontroller.am65xx.pin import Pin +from adafruit_blinka import ContextManaged + + +class AnalogIn(ContextManaged): + """Analog Input Class""" + + def __init__(self, pin): + self._pin = Pin(pin.id) + self._pin.init(mode=Pin.ADC) + + @property + def value(self): + """Read the ADC and return the value""" + return self._pin.value() + + # pylint: disable=no-self-use + @value.setter + def value(self, value): + # emulate what CircuitPython does + raise AttributeError("'AnalogIn' object has no attribute 'value'") + + # pylint: enable=no-self-use + + def deinit(self): + del self._pin + + +class AnalogOut(ContextManaged): + """Analog Output Class""" + + def __init__(self, pin): + self._pin = Pin(pin.id) + self._pin.init(mode=Pin.DAC) + + @property + def value(self): + """Return an error. This is output only.""" + # emulate what CircuitPython does + raise AttributeError("AM65xx doesn't have an DAC! No Analog Output possible!") + + @value.setter + def value(self, value): + self._pin.value(value) + + def deinit(self): + del self._pin diff --git a/src/adafruit_blinka/microcontroller/am65xx/i2c.py b/src/adafruit_blinka/microcontroller/am65xx/i2c.py new file mode 100644 index 00000000..f4dbd25a --- /dev/null +++ b/src/adafruit_blinka/microcontroller/am65xx/i2c.py @@ -0,0 +1,94 @@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT +"""Generic Linux I2C class using PureIO's smbus class""" +from Adafruit_PureIO import smbus + + +class I2C: + """I2C class""" + + MASTER = 0 + SLAVE = 1 + _baudrate = None + _mode = None + _i2c_bus = None + + # pylint: disable=unused-argument + def __init__(self, bus_num, mode=MASTER, baudrate=None): + if mode != self.MASTER: + raise NotImplementedError("Only I2C Master supported!") + _mode = self.MASTER + + # if baudrate != None: + # print("I2C frequency is not settable in python, ignoring!") + + try: + self._i2c_bus = smbus.SMBus(bus_num) + except FileNotFoundError: + raise RuntimeError( + "I2C Bus #%d not found, check if enabled in config!" % bus_num + ) from RuntimeError + + # pylint: enable=unused-argument + + def scan(self): + """Try to read a byte from each address, if you get an OSError + it means the device isnt there""" + found = [] + for addr in range(0, 0x80): + try: + self._i2c_bus.read_byte(addr) + except OSError: + continue + found.append(addr) + return found + + # pylint: disable=unused-argument + def writeto(self, address, buffer, *, start=0, end=None, stop=True): + """Write data from the buffer to an address""" + if end is None: + end = len(buffer) + self._i2c_bus.write_bytes(address, buffer[start:end]) + + def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True): + """Read data from an address and into the buffer""" + if end is None: + end = len(buffer) + + readin = self._i2c_bus.read_bytes(address, end - start) + for i in range(end - start): + buffer[i + start] = readin[i] + + # pylint: enable=unused-argument + + def writeto_then_readfrom( + self, + address, + buffer_out, + buffer_in, + *, + out_start=0, + out_end=None, + in_start=0, + in_end=None, + stop=False + ): + """Write data from buffer_out to an address and then + read data from an address and into buffer_in + """ + if out_end is None: + out_end = len(buffer_out) + if in_end is None: + in_end = len(buffer_in) + if stop: + # To generate a stop in linux, do in two transactions + self.writeto(address, buffer_out, start=out_start, end=out_end, stop=True) + self.readfrom_into(address, buffer_in, start=in_start, end=in_end) + else: + # To generate without a stop, do in one block transaction + readin = self._i2c_bus.read_i2c_block_data( + address, buffer_out[out_start:out_end], in_end - in_start + ) + for i in range(in_end - in_start): + buffer_in[i + in_start] = readin[i] diff --git a/src/adafruit_blinka/microcontroller/am65xx/pin.py b/src/adafruit_blinka/microcontroller/am65xx/pin.py new file mode 100644 index 00000000..7040e251 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/am65xx/pin.py @@ -0,0 +1,199 @@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2022 Martin Schnur for Siemens AG +# +# SPDX-License-Identifier: MIT +"""TI AM65XX pin names""" + +import mraa + + +class Pin: + """Pins don't exist in CPython so...lets make our own!""" + + # pin modes + IN = 0 + OUT = 1 + ADC = 2 + DAC = 3 + PWM = 4 + # pin values + LOW = 0 + HIGH = 1 + # pin pulls + PULL_NONE = 0 + PULL_UP = 1 + PULL_DOWN = 2 + + id = None + _value = LOW + _mode = IN + + def __init__(self, pin_id=None): + self.id = pin_id + self._mode = None + self._pull = None + self._pin = None + + def __repr__(self): + return str(self.id) + + def __eq__(self, other): + return self.id == other + + def init(self, mode=IN, pull=None): + """Initialize the Pin""" + if self.id is None: + raise RuntimeError("Can not init a None type pin.") + if mode is not None: + if mode == self.IN: + self._mode = self.IN + mypin = mraa.Gpio(self.id) + mypin.dir(mraa.DIR_IN) + elif mode == self.OUT: + self._mode = self.OUT + mypin = mraa.Gpio(self.id) + mypin.dir(mraa.DIR_OUT) + elif mode in (self.ADC, self.DAC): + # ADC (DAC not available) only available on Pin 0-5 (X12 Pin 1-6) + if self.id not in (0, 1, 2, 3, 4, 5): + raise ValueError("Pin does not have ADC capabilities") + self._pin = mraa.Aio(self.id) + elif mode == self.PWM: + # PWM only available on Pin 4-9 (X10 Pin 1-2, X11 Pin 5-8) + if self.id not in (4, 5, 6, 7, 8, 9): + raise ValueError("Pin does not have PWM capabilities") + return + else: + raise RuntimeError("Invalid mode for pin: %s" % self.id) + self._mode = mode + if pull is not None: + if self._mode != self.IN: + raise RuntimeError("Cannot set pull resistor on output") + if pull == self.PULL_UP: + mypin = mraa.Gpio(self.id) + mypin.dir(mraa.DIR_IN) + elif pull == self.PULL_DOWN: + mypin = mraa.Gpio(self.id) + mypin.dir(mraa.DIR_IN) + else: + raise RuntimeError("Invalid pull for pin: %s" % self.id) + + def value(self, val=None): + """Set or return the Pin Value""" + # Digital In / Out + if self._mode in (Pin.IN, Pin.OUT): + if val is not None: + if val == self.LOW: + self._value = val + mypin = mraa.Gpio(self.id) + mypin.write(0) + elif val == self.HIGH: + self._value = val + mypin = mraa.Gpio(self.id) + mypin.write(1) + else: + raise RuntimeError("Invalid value for pin") + return None + return mraa.Gpio.read(mraa.Gpio(self.id)) + # Analog In + if self._mode == Pin.ADC: + if val is None: + # Read ADC here + mypin = mraa.Aio(self.id) + mypin.read() + return mypin.read() + # read only + raise AttributeError("'AnalogIn' object has no attribute 'value'") + # Analog Out + if self._mode == Pin.DAC: + """if val is None: + # write only + raise AttributeError("unreadable attribute") + # Set DAC here + mypin = mraa.Aio(self.id) + mypin.setBit(val)""" + raise AttributeError( + "AM65xx doesn't have an DAC! No Analog Output possible!" + ) + raise RuntimeError( + "No action for mode {} with value {}".format(self._mode, val) + ) + + +# Digital Pins (GPIO 0-19) +D0 = Pin(0) +D1 = Pin(1) +D2 = Pin(2) +D3 = Pin(3) +D4 = Pin(4) +D5 = Pin(5) +D6 = Pin(6) +D7 = Pin(7) +D8 = Pin(8) +D9 = Pin(9) +D10 = Pin(10) +D11 = Pin(11) +D12 = Pin(12) +D13 = Pin(13) +D14 = Pin(14) +D15 = Pin(15) +D16 = Pin(16) +D17 = Pin(17) +D18 = Pin(18) +D19 = Pin(19) + +# Analog Pins (AIO 0-5, only ADC!) +A0 = Pin(0) +A1 = Pin(1) +A2 = Pin(2) +A3 = Pin(3) +A4 = Pin(4) +A5 = Pin(5) + +# I2C allocation +I2C_SCL = "SCL" +I2C_SDA = "SDA" + +# SPI allocation +SPIO_SCLK = D13 +SPIO_MISO = D12 +SPIO_MOSI = D11 +SPIO_SS = D10 + +# UART allocation +UART_TX = "TX" +UART_RX = "RX" + +# pwmOuts (GPIO 4-9) +PWM_4 = D4 +PWM_5 = D5 +PWM_6 = D6 +PWM_7 = D7 +PWM_8 = D8 +PWM_9 = D9 + +# I2C +# ordered as sclID, sdaID +# i2c-4 (/dev/i2c-4) -> X10 Pin9, Pin10 (SDA, SCL) +i2cPorts = ((4, I2C_SCL, I2C_SDA),) + +# SPI +# ordered as spiId, sckId, mosiID, misoID +spiPorts = ((0, SPIO_SCLK, SPIO_MOSI, SPIO_MISO),) + +# UART +# use pySerial = dev/ttyS1 +# ordered as uartID, txID, rxID +uartPorts = ((0, UART_TX, UART_RX),) + +# PWM +pwmOuts = ( + ((0, 0), PWM_4), + ((0, 1), PWM_5), + ((2, 0), PWM_6), + ((2, 1), PWM_7), + ((4, 0), PWM_8), + ((4, 1), PWM_9), +) diff --git a/src/adafruit_blinka/microcontroller/am65xx/pwmout.py b/src/adafruit_blinka/microcontroller/am65xx/pwmout.py new file mode 100644 index 00000000..264f16da --- /dev/null +++ b/src/adafruit_blinka/microcontroller/am65xx/pwmout.py @@ -0,0 +1,177 @@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT +# SPDX-FileCopyrightText: 2022 Martin Schnur for Siemens AG +# +# SPDX-License-Identifier: MIT +"""Custom PWMOut Wrapper for am65xx""" +""" +Much code from https://github.com/vsergeev/python-periphery/blob/master/periphery/pwm.py +Copyright (c) 2015-2016 vsergeev / Ivan (Vanya) A. Sergeev +License: MIT +""" + +import mraa +from adafruit_blinka.microcontroller.am65xx.pin import Pin + + +# pylint: disable=unnecessary-pass +class PWMError(IOError): + """Base class for PWM errors.""" + + pass + + +# pylint: enable=unnecessary-pass + + +class PWMOut: + """Pulse Width Modulation Output Class""" + + def __init__(self, pin, *, frequency=500, duty_cycle=0, variable_frequency=False): + self._frequency = None + self._duty_cycle = None + self._pwmpin = None + self._period = 0 + self._enabled = False + self._varfreq = variable_frequency + # check pin for PWM support + self._pin = Pin(pin.id) + self._pin.init(mode=Pin.PWM) + # initialize pin + 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=500, variable_frequency=False): + self._pwmpin = mraa.Pwm(pin.id) + self.frequency = freq + self.enabled = True + self._varfreq = variable_frequency + self.duty_cycle = duty + + def deinit(self): + """Deinit the PWM.""" + if self._pwmpin is not None: + self._pwmpin.enable(False) + 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." + ) + + @property + def period(self): + """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 + """ + return 1.0 / self.frequency + + @period.setter + def period(self, period): + if not isinstance(period, (int, float)): + raise TypeError("Invalid period type, should be int or float.") + + self.frequency = 1.0 / period + + @property + def duty_cycle(self): + """Get or set the PWM's output duty cycle which is the fraction of + each pulse which is high. 16-bit + + 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 + """ + return int(self._duty_cycle * 65535) + + @duty_cycle.setter + def duty_cycle(self, duty_cycle): + if not isinstance(duty_cycle, (int, float)): + raise TypeError("Invalid duty cycle type, should be int or float.") + + if not 0 <= duty_cycle <= 65535: + raise ValueError("Invalid duty cycle value, should be between 0 and 65535") + + # convert from 16-bit + duty_cycle /= 65535.0 + + self._duty_cycle = duty_cycle + # self._pwmpin.ChangeDutyCycle(round(self._duty_cycle * 100)) + self._pwmpin.write(self._duty_cycle) # mraa duty_cycle 0.0f - 1.0f + + @property + def frequency(self): + """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 + """ + + return self._frequency + + @frequency.setter + def frequency(self, frequency): + if not isinstance(frequency, (int, float)): + raise TypeError("Invalid frequency type, should be int or float.") + + if self._enabled and not self._varfreq: + raise TypeError( + " Set variable_frequency = True to allow changing frequency " + ) + # mraa has different variants in seconds,milli(_ms),micro(_us) + self._pwmpin.period((1 / frequency)) + self._frequency = frequency + + @property + def enabled(self): + """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 + """ + return self._enabled + + @enabled.setter + def enabled(self, value): + if not isinstance(value, bool): + raise TypeError("Invalid enabled type, should be string.") + + if value: + self._pwmpin.enable(True) + self._enabled = value + else: + self._pwmpin.enable(False) + self._enabled(False) + + # String representation + def __str__(self): + return "pin %s (freq=%f Hz, duty_cycle=%f%%)" % ( + self._pin, + self.frequency, + self.duty_cycle, + ) diff --git a/src/adafruit_blinka/microcontroller/am65xx/spi.py b/src/adafruit_blinka/microcontroller/am65xx/spi.py new file mode 100644 index 00000000..d1fa0b1e --- /dev/null +++ b/src/adafruit_blinka/microcontroller/am65xx/spi.py @@ -0,0 +1,144 @@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT +"""am65xx SPI class using PureIO's SPI class""" + +from Adafruit_PureIO import spi + +# import Adafruit_PureIO.spi as spi +from adafruit_blinka.agnostic import detector + + +class SPI: + """SPI Class""" + + MSB = 0 + LSB = 1 + CPHA = 1 + CPOL = 2 + + baudrate = 100000 + mode = 0 + bits = 8 + + def __init__(self, portid): + if isinstance(portid, tuple): + self._spi = spi.SPI(device=portid) + else: + self._spi = spi.SPI(device=(portid, 0)) + self.clock_pin = None + self.mosi_pin = None + self.miso_pin = None + self.chip = None + + # pylint: disable=too-many-arguments,unused-argument + def init( + self, + baudrate=100000, + polarity=0, + phase=0, + bits=8, + firstbit=MSB, + sck=None, + mosi=None, + miso=None, + ): + """Initialize SPI""" + mode = 0 + if polarity: + mode |= self.CPOL + if phase: + mode |= self.CPHA + self.baudrate = baudrate + self.mode = mode + self.bits = bits + self.chip = detector.chip + + # Pins are not used + self.clock_pin = sck + self.mosi_pin = mosi + self.miso_pin = miso + + # pylint: enable=too-many-arguments,unused-argument + + # pylint: disable=unnecessary-pass + def set_no_cs(self): + """Setting so that SPI doesn't automatically set the CS pin""" + # No kernel seems to support this, so we're just going to pass + pass + + # pylint: enable=unnecessary-pass + + @property + def frequency(self): + """Return the current baudrate""" + return self.baudrate + + def write(self, buf, start=0, end=None): + """Write data from the buffer to SPI""" + if not buf: + return + if end is None: + end = len(buf) + try: + # self._spi.open(self._port, 0) + self.set_no_cs() + self._spi.max_speed_hz = self.baudrate + self._spi.mode = self.mode + self._spi.bits_per_word = self.bits + self._spi.writebytes(buf[start:end]) + # self._spi.close() + except FileNotFoundError: + print("Could not open SPI device - check if SPI is enabled in kernel!") + raise + + def readinto(self, buf, start=0, end=None, write_value=0): + """Read data from SPI and into the buffer""" + if not buf: + return + if end is None: + end = len(buf) + try: + # self._spi.open(self._port, 0) + # self.set_no_cs() + self._spi.max_speed_hz = self.baudrate + self._spi.mode = self.mode + self._spi.bits_per_word = self.bits + data = self._spi.transfer([write_value] * (end - start)) + for i in range(end - start): # 'readinto' the given buffer + buf[start + i] = data[i] + # self._spi.close() + except FileNotFoundError: + print("Could not open SPI device - check if SPI is enabled in kernel!") + raise + + # pylint: disable=too-many-arguments + def write_readinto( + self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None + ): + """Perform a half-duplex write from buffer_out and then + read data into buffer_in + """ + if not buffer_out or not buffer_in: + return + if out_end is None: + out_end = len(buffer_out) + if in_end is None: + in_end = len(buffer_in) + if out_end - out_start != in_end - in_start: + raise RuntimeError("Buffer slices must be of equal length.") + try: + # self._spi.open(self._port, 0) + # self.set_no_cs() + self._spi.max_speed_hz = self.baudrate + self._spi.mode = self.mode + self._spi.bits_per_word = self.bits + data = self._spi.transfer(list(buffer_out[out_start : out_end + 1])) + for i in range((in_end - in_start)): + buffer_in[i + in_start] = data[i] + # self._spi.close() + except FileNotFoundError: + print("Could not open SPI device - check if SPI is enabled in kernel!") + raise + + # pylint: enable=too-many-arguments diff --git a/src/analogio.py b/src/analogio.py index 23dfb0d5..4b7f9b06 100644 --- a/src/analogio.py +++ b/src/analogio.py @@ -22,6 +22,9 @@ elif detector.board.greatfet_one: from adafruit_blinka.microcontroller.nxp_lpc4330.analogio import AnalogIn from adafruit_blinka.microcontroller.nxp_lpc4330.analogio import AnalogOut +elif detector.board.any_siemens_simatic_iot2000: + from adafruit_blinka.microcontroller.am65xx.analogio import AnalogIn + from adafruit_blinka.microcontroller.am65xx.analogio import AnalogOut elif detector.chip.RK3308: from adafruit_blinka.microcontroller.generic_linux.sysfs_analogin import AnalogIn elif detector.chip.RK3399: diff --git a/src/board.py b/src/board.py index 36aca248..4b8ae56a 100644 --- a/src/board.py +++ b/src/board.py @@ -277,6 +277,9 @@ elif board_id == ap_board.LICHEE_RV: from adafruit_blinka.board.lichee_rv import * +elif board_id == ap_board.SIEMENS_SIMATIC_IOT2050_ADV: + from adafruit_blinka.board.siemens.siemens_iot2050 import * + elif "sphinx" in sys.modules: pass diff --git a/src/busio.py b/src/busio.py index dd748a59..75b08cba 100644 --- a/src/busio.py +++ b/src/busio.py @@ -100,6 +100,12 @@ def init(self, scl, sda, frequency): self._i2c = _I2C(scl, sda, frequency=frequency) return + if detector.board.any_siemens_iot2000: + from adafruit_blinka.microcontroller.am65xx.i2c import I2C as _I2C + + self._i2c = _I2C(frequency=frequency) + return + if detector.board.any_embedded_linux: from adafruit_blinka.microcontroller.generic_linux.i2c import I2C as _I2C elif detector.board.ftdi_ft2232h: @@ -270,6 +276,12 @@ def __init__(self, clock, MOSI=None, MISO=None): self._spi = _SPI(clock, MOSI, MISO) # Pins configured on instantiation self._pins = (clock, clock, clock) # These don't matter, they're discarded return + if detector.board.any_siemens_iot2000: + from adafruit_blinka.microcontroller.am65xx.spi import SPI as _SPI + + self._spi = _SPI(clock) # this is really all that's needed + self._pins = (clock, clock, clock) # will determine MOSI/MISO from clock + return if detector.board.any_embedded_linux: from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI elif detector.board.ftdi_ft2232h: @@ -332,6 +344,9 @@ def configure(self, baudrate=100000, polarity=0, phase=0, bits=8): from adafruit_blinka.microcontroller.rp2040_u2if.spi import SPI_QTPY as _SPI elif detector.chip.id == ap_chip.RP2040: from adafruit_blinka.microcontroller.rp2040.spi import SPI as _SPI + elif detector.board.any_siemens_iot2000: + from adafruit_blinka.microcontroller.am65xx.spi import SPI as _SPI + from adafruit_blinka.microcontroller.am65xx.pin import Pin elif detector.board.any_embedded_linux: from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI else: @@ -486,7 +501,7 @@ def readinto(self, buf, nbytes=None): return self._uart.readinto(buf, nbytes) def readline(self): - """Read a line of characters up to a newline charater from the UART""" + """Read a line of characters up to a newline character from the UART""" return self._uart.readline() def write(self, buf): diff --git a/src/digitalio.py b/src/digitalio.py index 0969f350..7f64fb10 100644 --- a/src/digitalio.py +++ b/src/digitalio.py @@ -18,6 +18,8 @@ from adafruit_blinka.microcontroller.bcm283x.pin import Pin elif detector.chip.AM33XX: from adafruit_blinka.microcontroller.am335x.pin import Pin +elif detector.chip.AM65XX: + from adafruit_blinka.microcontroller.am65xx.pin import Pin elif detector.chip.JH71x0: from adafruit_blinka.microcontroller.starfive.JH71x0.pin import Pin elif detector.chip.DRA74X: diff --git a/src/microcontroller/__init__.py b/src/microcontroller/__init__.py index 9bd7d09f..debf41c3 100644 --- a/src/microcontroller/__init__.py +++ b/src/microcontroller/__init__.py @@ -44,6 +44,8 @@ def delay_us(delay): from adafruit_blinka.microcontroller.dra74x import * elif chip_id == ap_chip.AM33XX: from adafruit_blinka.microcontroller.am335x import * +elif chip_id == ap_chip.AM65XX: + from adafruit_blinka.microcontroller.am65xx import * elif chip_id == ap_chip.JH71x0: from adafruit_blinka.microcontroller.starfive.JH71x0 import * elif chip_id == ap_chip.SUN8I: diff --git a/src/microcontroller/pin.py b/src/microcontroller/pin.py index 196aa038..a46c6cd2 100644 --- a/src/microcontroller/pin.py +++ b/src/microcontroller/pin.py @@ -29,6 +29,8 @@ from adafruit_blinka.microcontroller.dra74x.pin import * elif chip_id == ap_chip.AM33XX: from adafruit_blinka.microcontroller.am335x.pin import * +elif chip_id == ap_chip.AM65XX: + from adafruit_blinka.microcontroller.am65xx.pin import * elif chip_id == ap_chip.JH71x0: from adafruit_blinka.microcontroller.starfive.JH71x0.pin import * elif chip_id == ap_chip.SUN8I: diff --git a/src/pwmio.py b/src/pwmio.py index f4d6a8c9..ccf44209 100644 --- a/src/pwmio.py +++ b/src/pwmio.py @@ -24,6 +24,8 @@ from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut elif detector.board.any_beaglebone: from adafruit_blinka.microcontroller.am335x.sysfs_pwmout import PWMOut +elif detector.board.any_siemens_simatic_iot2000: + from adafruit_blinka.microcontroller.am65xx.pwmout import PWMOut elif detector.board.any_rock_pi_board: from adafruit_blinka.microcontroller.rockchip.PWMOut import PWMOut elif detector.board.binho_nova: From 9c00fbff4c844c043a7c5e959690880df5946055 Mon Sep 17 00:00:00 2001 From: Martin Schnur Date: Wed, 21 Sep 2022 20:11:44 +0200 Subject: [PATCH 2/2] Added pylint comments to pass pre-commit Added pylint comments to /am65xx/pin.py and pwmout.py. Which are minor "issues" which should be totaly ok to pass. --- src/adafruit_blinka/microcontroller/am65xx/pin.py | 3 +++ src/adafruit_blinka/microcontroller/am65xx/pwmout.py | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/adafruit_blinka/microcontroller/am65xx/pin.py b/src/adafruit_blinka/microcontroller/am65xx/pin.py index 7040e251..14b586a5 100644 --- a/src/adafruit_blinka/microcontroller/am65xx/pin.py +++ b/src/adafruit_blinka/microcontroller/am65xx/pin.py @@ -8,6 +8,9 @@ import mraa +# pylint: disable=too-many-branches,too-many-statements +# pylint: disable=pointless-string-statement + class Pin: """Pins don't exist in CPython so...lets make our own!""" diff --git a/src/adafruit_blinka/microcontroller/am65xx/pwmout.py b/src/adafruit_blinka/microcontroller/am65xx/pwmout.py index 264f16da..081b82d3 100644 --- a/src/adafruit_blinka/microcontroller/am65xx/pwmout.py +++ b/src/adafruit_blinka/microcontroller/am65xx/pwmout.py @@ -4,6 +4,11 @@ # SPDX-FileCopyrightText: 2022 Martin Schnur for Siemens AG # # SPDX-License-Identifier: MIT + +# pylint: disable=pointless-string-statement +# pylint: disable=ungrouped-imports,wrong-import-position,unused-import +# pylint: disable=import-outside-toplevel + """Custom PWMOut Wrapper for am65xx""" """ Much code from https://github.com/vsergeev/python-periphery/blob/master/periphery/pwm.py @@ -11,11 +16,13 @@ License: MIT """ + import mraa from adafruit_blinka.microcontroller.am65xx.pin import Pin - # pylint: disable=unnecessary-pass + + class PWMError(IOError): """Base class for PWM errors."""