From: Jens Oberender <1905126+burberius@users.noreply.github.com> Date: Tue, 28 May 2024 11:58:26 +0000 (+0200) Subject: Merge branch 'adafruit:main' into raxda-zero3 X-Git-Tag: 8.40.0~1^2 X-Git-Url: https://git.ayoreis.com/Adafruit_Blinka-hackapet.git/commitdiff_plain/89028b7fe874bf72ea080b017fd63acfa8dbd1ed?hp=dabf9683569452fa4c40b811a33b5c9a3a845f86 Merge branch 'adafruit:main' into raxda-zero3 --- diff --git a/src/adafruit_blinka/board/fake_microchip_mcp2221.py b/src/adafruit_blinka/board/fake_microchip_mcp2221.py deleted file mode 100644 index 6aae9d5..0000000 --- a/src/adafruit_blinka/board/fake_microchip_mcp2221.py +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries -# -# SPDX-License-Identifier: MIT -"""Pin definitions for the MicroChip MCP2221""" -from adafruit_blinka.microcontroller.fake_mcp2221 import pin - -G0 = pin.G0 -G1 = pin.G1 -G2 = pin.G2 -G3 = pin.G3 - -SCL = pin.SCL -SDA = pin.SDA diff --git a/src/adafruit_blinka/board/generic_agnostic_board.py b/src/adafruit_blinka/board/generic_agnostic_board.py new file mode 100644 index 0000000..925e7ba --- /dev/null +++ b/src/adafruit_blinka/board/generic_agnostic_board.py @@ -0,0 +1,38 @@ +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +"""Pin definitions for a generic, os-agnostic, board.""" +from adafruit_blinka.microcontroller.generic_agnostic_board import pin + +# Digital pins +Dx_INPUT_TRUE = pin.D0 +Dx_INPUT_FALSE = pin.D1 +Dx_INPUT_TRUE_PULL_UP = pin.D2 +Dx_INPUT_TRUE_PULL_DOWN = pin.D3 +Dx_OUTPUT = pin.D4 +Dx_INPUT_TOGGLE = pin.D7 +# Special "digital" pins +NEOPIXEL = pin.D6 + + +# Analog pins +Ax_INPUT_RAND_INT = pin.A0 +Ax_INPUT_FIXED_INT_PI = pin.A1 +Ax_INPUT_WAVE_SINE = pin.A2 +Ax_INPUT_WAVE_SAW = pin.A3 +Ax_OUTPUT = pin.A4 + +# I2C pins +SDA = pin.SDA +SCL = pin.SCL + +# SPI pins +SCLK = pin.SCLK +SCK = pin.SCK +MOSI = pin.MOSI +MISO = pin.MISO +CS = pin.D6 + +# UART pins +UART_TX = pin.UART_TX +UART_RX = pin.UART_RX diff --git a/src/adafruit_blinka/microcontroller/fake_mcp2221/fake_mcp2221.py b/src/adafruit_blinka/microcontroller/fake_mcp2221/fake_mcp2221.py deleted file mode 100644 index 74a0713..0000000 --- a/src/adafruit_blinka/microcontroller/fake_mcp2221/fake_mcp2221.py +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries -# -# SPDX-License-Identifier: MIT -"""Chip Definition for MCP2221""" - - -class MCP2221: - """MCP2221 Device Class Definition""" - - def __init__(self): - pass # This is a "fake" implementation - - def __del__(self): - # try to close the device before destroying the instance - return - - # pylint: enable=unused-argument - - -mcp2221 = MCP2221() diff --git a/src/adafruit_blinka/microcontroller/fake_mcp2221/i2c.py b/src/adafruit_blinka/microcontroller/fake_mcp2221/i2c.py deleted file mode 100644 index d4b2c6f..0000000 --- a/src/adafruit_blinka/microcontroller/fake_mcp2221/i2c.py +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries -# -# SPDX-License-Identifier: MIT -"""I2C Class for MCP2221""" -import random -from .fake_mcp2221 import mcp2221 - - -class I2C: - """Custom I2C Class for MCP2221""" - - def __init__(self, *, frequency=100000): - self._mcp2221 = mcp2221 - self._freq = frequency - - @staticmethod - def scan(address_list=None): - """Mocks an I2C scan. - If address_list is not provided, this function returns a - list of 3 randomly generated I2C addresses from 0x0 to 0x79. - For a stimulus-driven test: If address_list is provided, - this function returns the provided address_list. - """ - if address_list is None: - # Generate a list of 3 randomly generated addresses from 0x0 to 0x79 - address_list = [] - for _ in range(3): - address_list.append(random.randint(0x0, 0x79)) - return address_list - return address_list diff --git a/src/adafruit_blinka/microcontroller/fake_mcp2221/pin.py b/src/adafruit_blinka/microcontroller/fake_mcp2221/pin.py deleted file mode 100644 index f522a39..0000000 --- a/src/adafruit_blinka/microcontroller/fake_mcp2221/pin.py +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries -# -# SPDX-License-Identifier: MIT -"""fake_mcp2221 pin names""" -import random - - -class Pin: - """A basic Pin class for use with a "fake" MCP2221.""" - - # pin modes - OUT = 0 - IN = 1 - ADC = 2 - DAC = 3 - # pin values - LOW = 0 - HIGH = 1 - - def __init__(self, pin_id=None): - self.id = pin_id - self._mode = None - self._prv_val = False - - 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 pull is not None: - raise NotImplementedError("Internal pullups and pulldowns not supported") - if mode in (Pin.IN, Pin.OUT): - # All pins can do GPIO - # mcp2221.gp_set_mode(self.id, mcp2221.GP_GPIO) - # mcp2221.gpio_set_direction(self.id, mode) - self._mode = mode - elif mode == Pin.ADC: - # ADC only available on these pins - if self.id not in (1, 2, 3): - raise ValueError("Pin does not have ADC capabilities") - # mcp2221.gp_set_mode(self.id, mcp2221.GP_ALT0) - # mcp2221.adc_configure() - elif mode == Pin.DAC: - # DAC only available on these pins - if self.id not in (2, 3): - raise ValueError("Pin does not have DAC capabilities") - # mcp2221.gp_set_mode(self.id, mcp2221.GP_ALT1) - # mcp2221.dac_configure() - else: - raise ValueError("Incorrect pin mode: {}".format(mode)) - self._mode = mode - - def value(self, val=None): - """Set or return the Pin Value""" - # Digital In / Out - if self._mode in (Pin.IN, Pin.OUT): - # digital read - if val is None: - # The returned value toggles between True and false - self._prv_val = not self._prv_val - return self._prv_val - # digital write - if val in (Pin.LOW, Pin.HIGH): - # We don't need to do anything here - no data is produced - return None - # nope - raise ValueError("Invalid value for pin.") - # Analog In - if self._mode == Pin.ADC: - if val is None: - # Returned value is between 0 and 65535 inclusive - # https://docs.circuitpython.org/en/latest/shared-bindings/analogio/index.html#analogio.AnalogIn.value - self._prv_val = random.randint(0, 65535) - return self._prv_val - # 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") - # We don't write to the DAC as this is a "fake" implementation - return None - raise RuntimeError( - "No action for mode {} with value {}".format(self._mode, val) - ) - - -# create pin instances for each pin -G0 = Pin(0) -G1 = Pin(1) -G2 = Pin(2) -G3 = Pin(3) - -SCL = Pin() -SDA = Pin() diff --git a/src/adafruit_blinka/microcontroller/fake_mcp2221/__init__.py b/src/adafruit_blinka/microcontroller/generic_agnostic_board/__init__.py similarity index 100% rename from src/adafruit_blinka/microcontroller/fake_mcp2221/__init__.py rename to src/adafruit_blinka/microcontroller/generic_agnostic_board/__init__.py diff --git a/src/adafruit_blinka/microcontroller/fake_mcp2221/analogio.py b/src/adafruit_blinka/microcontroller/generic_agnostic_board/analogio.py similarity index 79% rename from src/adafruit_blinka/microcontroller/fake_mcp2221/analogio.py rename to src/adafruit_blinka/microcontroller/generic_agnostic_board/analogio.py index a70d7fc..cdaa188 100644 --- a/src/adafruit_blinka/microcontroller/fake_mcp2221/analogio.py +++ b/src/adafruit_blinka/microcontroller/generic_agnostic_board/analogio.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries # # SPDX-License-Identifier: MIT """ @@ -8,7 +8,7 @@ See `CircuitPython:analogio` in CircuitPython for more details. * Author(s): Carter Nelson """ -from adafruit_blinka.microcontroller.fake_mcp2221.pin import Pin +from adafruit_blinka.microcontroller.generic_agnostic_board.pin import Pin from adafruit_blinka import ContextManaged @@ -45,9 +45,8 @@ class AnalogOut(ContextManaged): @property def value(self): - """Return an error. This is output only.""" - # emulate what CircuitPython does - raise AttributeError("unreadable attribute") + """Fake the output.""" + return self._pin.value() @value.setter def value(self, value): diff --git a/src/adafruit_blinka/microcontroller/generic_agnostic_board/generic_agnostic_board.py b/src/adafruit_blinka/microcontroller/generic_agnostic_board/generic_agnostic_board.py new file mode 100644 index 0000000..40f204c --- /dev/null +++ b/src/adafruit_blinka/microcontroller/generic_agnostic_board/generic_agnostic_board.py @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +"""Chip Definition for a generic, os-agnostic, board.""" + + +class GENERIC_AGNOSTIC_BOARD: + """Generic Agnostic Board Device Class Definition""" + + def __init__(self): + pass # This implementation is for a generic board, no initialization is required + + def __del__(self): + # try to close the device before destroying the instance + return + + # pylint: enable=unused-argument + + +generic_agnostic_board = GENERIC_AGNOSTIC_BOARD() diff --git a/src/adafruit_blinka/microcontroller/generic_agnostic_board/i2c.py b/src/adafruit_blinka/microcontroller/generic_agnostic_board/i2c.py new file mode 100644 index 0000000..475f414 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/generic_agnostic_board/i2c.py @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +"""I2C Class for Generic Agnostic Board""" +from random import randint + +# from .generic_agnostic_board.pin import generic_agnostic_board + + +class I2C: + """Custom I2C Class for a Generic Agnostic Board""" + + def __init__(self, *, frequency=100000): + # self._generic_agnostic_board = generic_agnostic_board + self.freq = frequency + + @staticmethod + def scan(): + """Mocks an I2C scan and returns a list of 3 randomly generated + I2C addresses from 0x0 to 0x79. + """ + # Generate a list of 3 randomly generated addresses from 0x0 to 0x79 + address_list = [] + for _ in range(3): + address_list.append(randint(0x0, 0x79)) + return address_list diff --git a/src/adafruit_blinka/microcontroller/generic_agnostic_board/pin.py b/src/adafruit_blinka/microcontroller/generic_agnostic_board/pin.py new file mode 100644 index 0000000..47d9754 --- /dev/null +++ b/src/adafruit_blinka/microcontroller/generic_agnostic_board/pin.py @@ -0,0 +1,222 @@ +# SPDX-FileCopyrightText: 2024 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT +"""generic_agnostic_board pin interface""" +import random + +# Values for sine wave +# (data points = 20, amplitude=100, frequency=1) +sine_wave = [ + 0, + 31, + 59, + 81, + 95, + 100, + 95, + 81, + 59, + 31, + 0, + -31, + -59, + -81, + -95, + -100, + -95, + -81, + -59, + -31, +] + +# Values for a sawtooth wave +# (data points = 20, amplitude=100) +sawtooth_wave = [ + -100, + -80, + -60, + -40, + -20, + 0, + 20, + 40, + 60, + 80, + -100, + -80, + -60, + -40, + -20, + 0, + 20, + 40, + 60, + 80, +] + + +class Pin: + """A basic Pin class for use with generic_agnostic_board""" + + # pin modes + OUT = 0 + IN = 1 + ADC = 2 + DAC = 3 + # pin values + LOW = 0 + HIGH = 1 + # pin pulls + PULL_NONE = 0 + PULL_UP = 1 + PULL_DOWN = 2 + + # pylint: disable=no-self-use + + def return_toggle(self): + """Returns the pin's expected value, toggling between True and False""" + toggle_state = not self.previous_value + return toggle_state + + def return_false(self): + """Returns the pin's expected value, False""" + return False + + def return_true(self): + """Returns the pin's expected value, True""" + return True + + def return_random_int(self): + """Returns a random integer""" + return random.randint(0, 65535) + + def return_fixed_int_pi(self): + """Returns the first five digits of Pi, 31415""" + return 31415 + + def return_sine_wave(self): + """Returns the next value in the sine wave""" + if self._wave_idx is None: + self._wave_idx = 0 + else: + self._wave_idx = (self._wave_idx + 1) % len(sine_wave) + return sine_wave[self._wave_idx] + + def return_sawtooth_wave(self): + """Returns the next value in the sawtooth wave""" + if self._wave_idx is None: + self._wave_idx = 0 + else: + self._wave_idx = (self._wave_idx + 1) % len(sawtooth_wave) + return sawtooth_wave[self._wave_idx] + + def __init__(self, pin_id=None): + self.id = pin_id + self._mode = None + self._pull = None + self.previous_value = False + self.current_value = None + self._wave_idx = None + + # mapping of pin definition names to expected behavior + self.pin_behavior = { + 0: self.return_true, # Dx_INPUT_TRUE + 1: self.return_false, # Dx_INPUT_FALSE + 2: self.return_true, # Dx_INPUT_TRUE_PULL_UP + 3: self.return_true, # Dx_INPUT_TRUE_PULL_DOWN + 4: self.return_true, # Dx_OUTPUT + 7: self.return_random_int, # Ax_INPUT_RAND_INT + 8: self.return_fixed_int_pi, # Ax_INPUT_FIXED_INT_PI + 9: self.return_sine_wave, # Ax_INPUT_WAVE_SINE + 10: self.return_sawtooth_wave, # Ax_INPUT_WAVE_SAW + 11: self.return_toggle, # Dx_INPUT_TOGGLE + } + + def init(self, mode=IN, pull=None): + """Initialize the Pin""" + if self.id is None: + raise RuntimeError("Can not init a None type pin.") + pull = Pin.PULL_NONE if pull is None else pull + self._pull = pull + self._mode = mode + + def write(self, new_value): + """Saves the new_value to the pin for subsequent calls to .value""" + self.previous_value = self.current_value + self.current_value = new_value + + def read(self): + """Returns the pin's expected value.""" + self.previous_value = self.current_value + # perform a lookup on the pin_behavior dict to get the value + self.current_value = self.pin_behavior.get(self.id)() + + # is pin a pull up and pin is LOW? + if self._pull == Pin.PULL_UP and self.current_value is False: + self.current_value = False + # is pin a pull down and pin is HIGH? + if self._pull == Pin.PULL_DOWN and self.current_value is True: + self.current_value = False + return self.current_value + + def value(self, val=None): + """Set or return the Pin Value""" + # Digital In / Out + if self._mode in (Pin.IN, Pin.OUT): + # digital read + if val is None: + return self.read() + # digital write + if val in (Pin.LOW, Pin.HIGH): + return self.write(val) + # nope + raise ValueError("Invalid value for pin.") + # Analog In + if self._mode == Pin.ADC: + if val is None: + return self.read() + # read only + raise AttributeError("'AnalogIn' object has no attribute 'value'") + # Analog Out + if self._mode == Pin.DAC: + if val is None: + self.previous_value = self.current_value + return self.current_value + self.write(val) + return None + raise RuntimeError( + "No action for mode {} with value {}".format(self._mode, val) + ) + + +# create pin instances for each pin +D0 = Pin(0) +D1 = Pin(1) +D2 = Pin(2) +D3 = Pin(3) +D4 = Pin(4) +# Special "digital" pins +D6 = Pin(6) +# Analog pins +A0 = Pin(7) +A1 = Pin(8) +A2 = Pin(9) +A3 = Pin(10) +A4 = Pin(12) + +D7 = Pin(11) + +# I2C pins +SDA = Pin() +SCL = Pin() + +# SPI pins +SCLK = Pin() +SCK = Pin() +MOSI = Pin() +MISO = Pin() +CS = Pin() + +# UART pins +UART_TX = Pin() +UART_RX = Pin() diff --git a/src/analogio.py b/src/analogio.py index c132ba3..f1b9a55 100644 --- a/src/analogio.py +++ b/src/analogio.py @@ -17,15 +17,8 @@ from adafruit_blinka.agnostic import detector # pylint: disable=ungrouped-imports,wrong-import-position,unused-import if detector.board.microchip_mcp2221: - if ( - "BLINKA_FORCECHIP" in os.environ - and os.environ["BLINKA_FORCEBOARD"] == "MICROCHIP_MCP2221" - ): - from adafruit_blinka.microcontroller.fake_mcp2221.analogio import AnalogIn - from adafruit_blinka.microcontroller.fake_mcp2221.analogio import AnalogOut - else: - from adafruit_blinka.microcontroller.mcp2221.analogio import AnalogIn - from adafruit_blinka.microcontroller.mcp2221.analogio import AnalogOut + from adafruit_blinka.microcontroller.mcp2221.analogio import AnalogIn + from adafruit_blinka.microcontroller.mcp2221.analogio import AnalogOut elif detector.board.greatfet_one: from adafruit_blinka.microcontroller.nxp_lpc4330.analogio import AnalogIn from adafruit_blinka.microcontroller.nxp_lpc4330.analogio import AnalogOut @@ -70,5 +63,13 @@ elif detector.board.itsybitsy_u2if: from adafruit_blinka.microcontroller.rp2040_u2if.analogio import ( AnalogIn_ItsyBitsy as AnalogIn, ) +elif ( + "BLINKA_FORCECHIP" in os.environ + and os.environ["BLINKA_FORCEBOARD"] == "GENERIC_AGNOSTIC_BOARD" +): + from adafruit_blinka.microcontroller.generic_agnostic_board.analogio import AnalogIn + from adafruit_blinka.microcontroller.generic_agnostic_board.analogio import ( + AnalogOut, + ) else: raise NotImplementedError("analogio not supported for this board.") diff --git a/src/board.py b/src/board.py index 46e9c10..085743a 100644 --- a/src/board.py +++ b/src/board.py @@ -224,13 +224,7 @@ elif board_id == ap_board.BINHO_NOVA: from adafruit_blinka.board.binho_nova import * elif board_id == ap_board.MICROCHIP_MCP2221: - if ( - "BLINKA_FORCECHIP" in os.environ - and os.environ["BLINKA_FORCEBOARD"] == "MICROCHIP_MCP2221" - ): - from adafruit_blinka.board.fake_microchip_mcp2221 import * - else: - from adafruit_blinka.board.microchip_mcp2221 import * + from adafruit_blinka.board.microchip_mcp2221 import * elif board_id == ap_board.GREATFET_ONE: from adafruit_blinka.board.greatfet_one import * @@ -397,6 +391,12 @@ elif board_id == ap_board.LICHEEPI_4A: elif board_id == ap_board.MILKV_DUO: from adafruit_blinka.board.milkv_duo import * +elif ( + "BLINKA_FORCECHIP" in os.environ + and os.environ["BLINKA_FORCEBOARD"] == "GENERIC_AGNOSTIC_BOARD" +): + from adafruit_blinka.board.generic_agnostic_board import * + elif "sphinx" in sys.modules: pass diff --git a/src/busio.py b/src/busio.py index 0a3f529..70ead88 100644 --- a/src/busio.py +++ b/src/busio.py @@ -51,15 +51,22 @@ class I2C(Lockable): self._i2c = _I2C(frequency=frequency) return if detector.board.microchip_mcp2221: - if ( - "BLINKA_FORCECHIP" in os.environ - and os.environ["BLINKA_FORCEBOARD"] == "MICROCHIP_MCP2221" - ): - from adafruit_blinka.microcontroller.fake_mcp2221.i2c import I2C as _I2C - else: - from adafruit_blinka.microcontroller.mcp2221.i2c import I2C as _I2C + from adafruit_blinka.microcontroller.mcp2221.i2c import I2C as _I2C + + self._i2c = _I2C(frequency=frequency) + return + + if ( + "BLINKA_FORCECHIP" in os.environ + and os.environ["BLINKA_FORCEBOARD"] == "GENERIC_AGNOSTIC_BOARD" + ): + from adafruit_blinka.microcontroller.generic_agnostic_board.i2c import ( + I2C as _I2C, + ) + self._i2c = _I2C(frequency=frequency) return + if detector.board.greatfet_one: from adafruit_blinka.microcontroller.nxp_lpc4330.i2c import I2C as _I2C diff --git a/src/digitalio.py b/src/digitalio.py index 7f57e31..ecdc98e 100644 --- a/src/digitalio.py +++ b/src/digitalio.py @@ -127,13 +127,7 @@ elif detector.board.binho_nova: elif detector.board.greatfet_one: from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin elif detector.board.microchip_mcp2221: - if ( - "BLINKA_FORCECHIP" in os.environ - and os.environ["BLINKA_FORCEBOARD"] == "MICROCHIP_MCP2221" - ): - from adafruit_blinka.microcontroller.fake_mcp2221.pin import Pin - else: - from adafruit_blinka.microcontroller.mcp2221.pin import Pin + from adafruit_blinka.microcontroller.mcp2221.pin import Pin elif detector.chip.RP2040_U2IF: from adafruit_blinka.microcontroller.rp2040_u2if.pin import Pin # MicroPython Chips @@ -143,6 +137,11 @@ elif detector.chip.RP2040: from machine import Pin elif detector.chip.CV1800B: from adafruit_blinka.microcontroller.cv1800b.pin import Pin +elif ( + "BLINKA_FORCECHIP" in os.environ + and os.environ["BLINKA_FORCEBOARD"] == "GENERIC_AGNOSTIC_BOARD" +): + from adafruit_blinka.microcontroller.generic_agnostic_board.pin import Pin from adafruit_blinka import Enum, ContextManaged diff --git a/src/microcontroller/__init__.py b/src/microcontroller/__init__.py index 5ab316c..394d274 100644 --- a/src/microcontroller/__init__.py +++ b/src/microcontroller/__init__.py @@ -123,13 +123,7 @@ elif chip_id == ap_chip.BINHO: elif chip_id == ap_chip.LPC4330: from adafruit_blinka.microcontroller.nxp_lpc4330 import * elif chip_id == ap_chip.MCP2221: - if ( - "BLINKA_FORCECHIP" in os.environ - and os.environ["BLINKA_FORCEBOARD"] == "MICROCHIP_MCP2221" - ): - from adafruit_blinka.microcontroller.fake_mcp2221 import * - else: - from adafruit_blinka.microcontroller.mcp2221 import * + from adafruit_blinka.microcontroller.mcp2221 import * elif chip_id == ap_chip.MIPS24KC: from adafruit_blinka.microcontroller.atheros.ar9331 import * elif chip_id == ap_chip.MIPS24KEC: @@ -156,6 +150,11 @@ elif chip_id == ap_chip.TH1520: from adafruit_blinka.microcontroller.thead.th1520 import * elif chip_id == ap_chip.GENERIC_X86: print("WARNING: GENERIC_X86 is not fully supported. Some features may not work.") +elif ( + "BLINKA_FORCECHIP" in os.environ + and os.environ["BLINKA_FORCEBOARD"] == "GENERIC_AGNOSTIC_BOARD" +): + from adafruit_blinka.microcontroller.generic_agnostic_board import * elif chip_id is None: print( "WARNING: chip_id == None is not fully supported. Some features may not work." diff --git a/src/microcontroller/pin.py b/src/microcontroller/pin.py index 8d30cbb..0d083a0 100644 --- a/src/microcontroller/pin.py +++ b/src/microcontroller/pin.py @@ -97,13 +97,7 @@ elif chip_id == ap_chip.BINHO: elif chip_id == ap_chip.LPC4330: from adafruit_blinka.microcontroller.nxp_lpc4330.pin import * elif chip_id == ap_chip.MCP2221: - if ( - "BLINKA_FORCECHIP" in os.environ - and os.environ["BLINKA_FORCEBOARD"] == "MICROCHIP_MCP2221" - ): - from adafruit_blinka.microcontroller.fake_mcp2221.pin import * - else: - from adafruit_blinka.microcontroller.mcp2221.pin import * + from adafruit_blinka.microcontroller.mcp2221.pin import * elif chip_id == ap_chip.A10: from adafruit_blinka.microcontroller.allwinner.a20.pin import * elif chip_id == ap_chip.A20: @@ -155,6 +149,11 @@ elif "sphinx" in sys.modules: elif chip_id == ap_chip.GENERIC_X86: print("WARNING: GENERIC_X86 is not fully supported. Some features may not work.") from adafruit_blinka.microcontroller.generic_micropython import Pin +elif ( + "BLINKA_FORCECHIP" in os.environ + and os.environ["BLINKA_FORCEBOARD"] == "GENERIC_AGNOSTIC_BOARD" +): + from adafruit_blinka.microcontroller.generic_agnostic_board.pin import * elif chip_id is None: print( "WARNING: chip_id == None is not fully supported. Some features may not work." diff --git a/tests/test_generic_agnostic_board_analogio.py b/tests/test_generic_agnostic_board_analogio.py new file mode 100644 index 0000000..3658380 --- /dev/null +++ b/tests/test_generic_agnostic_board_analogio.py @@ -0,0 +1,126 @@ +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import pytest # pylint: disable=unused-import +import board +import analogio + + +# Analog Outputs +def test_Ax_OUTPUT(): + """Test analog output pin functionality.""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_out = analogio.AnalogOut(board.Ax_OUTPUT) + + # Test boundaries of setting the value and reading it back + pin_out.value = 0 + assert pin_out.value == 0 + pin_out.value = 65535 + assert pin_out.value == 65535 + + pin_out.deinit() + + +# Analog Inputs + +# Values for sine wave +# (data points = 20, amplitude=100, frequency=1) +sine_wave = [ + 0, + 31, + 59, + 81, + 95, + 100, + 95, + 81, + 59, + 31, + 0, + -31, + -59, + -81, + -95, + -100, + -95, + -81, + -59, + -31, +] + +# Values for a sawtooth wave +# (data points = 20, amplitude=100) +sawtooth_wave = [ + -100, + -80, + -60, + -40, + -20, + 0, + 20, + 40, + 60, + 80, + -100, + -80, + -60, + -40, + -20, + 0, + 20, + 40, + 60, + 80, +] + + +def test_Ax_INPUT_RAND_INT(): + """Test random integer from pin Ax_INPUT_RAND_INT""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_random = analogio.AnalogIn(board.Ax_INPUT_RAND_INT) + + assert isinstance(pin_random.value, int) + + pin_random.deinit() + + +def test_Ax_INPUT_FIXED_INT_PI(): + """Test fixed integer from pin Ax_INPUT_FIXED_INT_PI""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_pi = analogio.AnalogIn(board.Ax_INPUT_FIXED_INT_PI) + + assert pin_pi.value == 31415 + + pin_pi.deinit() + + +def test_Ax_INPUT_WAVE_SINE(): + """Test sine wave from pin Ax_INPUT_WAVE_SINE""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_sine_wave = analogio.AnalogIn(board.Ax_INPUT_WAVE_SINE) + + # Run through the sine wave once + for expected_value in sine_wave: + assert pin_sine_wave.value == expected_value + + # Run through the sine wave again to ensure it loops back correctly + for expected_value in sine_wave: + assert pin_sine_wave.value == expected_value + + pin_sine_wave.deinit() + + +def test_Ax_INPUT_WAVE_SAW(): + """Test sawtooth wave from pin Ax_INPUT_WAVE_SAW""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_saw_wave = analogio.AnalogIn(board.Ax_INPUT_WAVE_SAW) + + # Run through the sine wave once + for expected_value in sawtooth_wave: + assert pin_saw_wave.value == expected_value + + # Run through the sine wave again to ensure it loops back correctly + for expected_value in sawtooth_wave: + assert pin_saw_wave.value == expected_value + + pin_saw_wave.deinit() diff --git a/tests/test_generic_agnostic_board_digitalio.py b/tests/test_generic_agnostic_board_digitalio.py new file mode 100644 index 0000000..a9ebb32 --- /dev/null +++ b/tests/test_generic_agnostic_board_digitalio.py @@ -0,0 +1,80 @@ +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import pytest # pylint: disable=unused-import +import board +import digitalio + +# Digital output pins + + +def test_Dx_OUTPUT_TRUE(): + """Test digital output pin functionality.""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_out = digitalio.DigitalInOut(board.Dx_OUTPUT) + pin_out.direction = digitalio.Direction.OUTPUT + # Test setting the value and reading it back + pin_out.value = True + assert pin_out.value is True + pin_out.value = False + assert pin_out.value is True + pin_out.deinit() + + +# Digital Input Pins + + +def test_Dx_INPUT_TRUE(): + """Test digital input pin Dx_INPUT_TRUE.""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_true = digitalio.DigitalInOut(board.Dx_INPUT_TRUE) + pin_true.direction = digitalio.Direction.INPUT + assert pin_true.value is True + assert pin_true.value is True # Test subsequent call does not change value + pin_true.deinit() + + +def test_Dx_INPUT_TRUE_PULL_DOWN(): + """Test digital input pin Dx_INPUT_TRUE w/pull down.""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_true = digitalio.DigitalInOut(board.Dx_INPUT_TRUE) + pin_true.direction = digitalio.Direction.INPUT + assert pin_true.value is True + assert pin_true.value is True # Test subsequent call does not change value + pin_true.pull = digitalio.Pull.DOWN + assert pin_true.value is False + pin_true.deinit() + + +def test_Dx_INPUT_FALSE_PULL_UP(): + """Test digital input pin Dx_INPUT_FALSE w/pull up.""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_false = digitalio.DigitalInOut(board.Dx_INPUT_FALSE) + pin_false.direction = digitalio.Direction.INPUT + assert pin_false.value is False + assert pin_false.value is False # Test subsequent call does not change value + pin_false.pull = digitalio.Pull.UP + assert pin_false.value is False + pin_false.deinit() + + +def test_Dx_INPUT_FALSE(): + """Test digital input pin Dx_INPUT_FALSE""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_false = digitalio.DigitalInOut(board.Dx_INPUT_FALSE) + pin_false.direction = digitalio.Direction.INPUT + assert pin_false.value is False + assert pin_false.value is False # Test subsequent call does not change value + pin_false.deinit() + + +def test_Dx_INPUT_TOGGLE(): + """Test digital input pin Dx_INPUT_TOGGLE""" + assert board.board_id == "GENERIC_AGNOSTIC_BOARD" + pin_toggle = digitalio.DigitalInOut(board.Dx_INPUT_TOGGLE) + pin_toggle.direction = digitalio.Direction.INPUT + assert pin_toggle.value is True + assert ( + pin_toggle.value is False + ) # Test subsequent call does change value for this pin + pin_toggle.deinit() diff --git a/tests/test_generic_agnostic_board_i2c.py b/tests/test_generic_agnostic_board_i2c.py new file mode 100644 index 0000000..12136bd --- /dev/null +++ b/tests/test_generic_agnostic_board_i2c.py @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: 2024 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT +import pytest # pylint: disable=unused-import +import busio +from board import SCL, SDA + + +def test_i2c_scan_random(): + i2c = busio.I2C(SCL, SDA) + i2c.try_lock() + addr_list = i2c.scan() + assert len(addr_list) == 3 + for addr in addr_list: + assert addr >= 0x0 + assert addr <= 0x79 + i2c.unlock() + i2c.deinit()