]> Repositories - Adafruit_Blinka-hackapet.git/commitdiff
Merge pull request #476 from caternuson/feather_u2if
authorLimor "Ladyada" Fried <limor@ladyada.net>
Sat, 22 May 2021 14:00:43 +0000 (10:00 -0400)
committerGitHub <noreply@github.com>
Sat, 22 May 2021 14:00:43 +0000 (10:00 -0400)
Adding more u2if firmware boards

23 files changed:
src/adafruit_blinka/board/feather_u2if.py [new file with mode: 0644]
src/adafruit_blinka/board/itsybitsy_u2if.py [new file with mode: 0644]
src/adafruit_blinka/board/pico_u2if.py
src/adafruit_blinka/board/qt2040_trinkey_u2if.py [new file with mode: 0644]
src/adafruit_blinka/board/qtpy_u2if.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/pico_u2if/analogio.py [deleted file]
src/adafruit_blinka/microcontroller/pico_u2if/i2c.py [deleted file]
src/adafruit_blinka/microcontroller/pico_u2if/spi.py [deleted file]
src/adafruit_blinka/microcontroller/rp2040_u2if/__init__.py [moved from src/adafruit_blinka/microcontroller/pico_u2if/__init__.py with 100% similarity]
src/adafruit_blinka/microcontroller/rp2040_u2if/analogio.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/rp2040_u2if/i2c.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/rp2040_u2if/neopixel.py [moved from src/adafruit_blinka/microcontroller/pico_u2if/neopixel.py with 79% similarity]
src/adafruit_blinka/microcontroller/rp2040_u2if/pin.py [moved from src/adafruit_blinka/microcontroller/pico_u2if/pin.py with 77% similarity]
src/adafruit_blinka/microcontroller/rp2040_u2if/pwmio.py [moved from src/adafruit_blinka/microcontroller/pico_u2if/pwmio.py with 64% similarity]
src/adafruit_blinka/microcontroller/rp2040_u2if/rp2040_u2if.py [moved from src/adafruit_blinka/microcontroller/pico_u2if/pico_u2if.py with 93% similarity]
src/adafruit_blinka/microcontroller/rp2040_u2if/spi.py [new file with mode: 0644]
src/analogio.py
src/board.py
src/busio.py
src/digitalio.py
src/microcontroller/pin.py
src/neopixel_write.py
src/pwmio.py

diff --git a/src/adafruit_blinka/board/feather_u2if.py b/src/adafruit_blinka/board/feather_u2if.py
new file mode 100644 (file)
index 0000000..a6ba759
--- /dev/null
@@ -0,0 +1,45 @@
+"""
+Pin definitions for the Feather RP2040 with u2if firmware.
+
+Adafruit CircuitPython 6.2.0 on 2021-04-05; Adafruit Feather RP2040 with rp2040
+>>> import board
+>>> board.
+A0              A1              A2              A3
+D0              D1              D10             D11
+D12             D13             D24             D25
+D4              D5              D6              D9
+I2C             LED             MISO            MOSI
+NEOPIXEL        RX              SCK             SCL
+SDA             SPI             TX              UART
+"""
+
+from adafruit_blinka.microcontroller.rp2040_u2if import pin
+
+D0 = pin.GP0
+D1 = pin.GP1
+D4 = pin.GP6
+D5 = pin.GP7
+D6 = pin.GP8
+D9 = pin.GP9
+D10 = pin.GP10
+D11 = pin.GP11
+D12 = pin.GP12
+D13 = pin.GP13
+D24 = pin.GP24
+D25 = pin.GP25
+
+A0 = pin.GP26
+A1 = pin.GP27
+A2 = pin.GP28
+# A3 = pin.GP29 # not currently supported in firmware
+
+SCL = pin.GP3
+SDA = pin.GP2
+
+SCLK = SCK = pin.GP18
+MOSI = pin.GP19
+MISO = pin.GP20
+
+# access u2if via pin instance to open for specifc VID/PID
+# pylint:disable = protected-access
+pin.GP0._u2if_open_hid(0x239A, 0x00F1)
diff --git a/src/adafruit_blinka/board/itsybitsy_u2if.py b/src/adafruit_blinka/board/itsybitsy_u2if.py
new file mode 100644 (file)
index 0000000..c13d24c
--- /dev/null
@@ -0,0 +1,54 @@
+"""
+Pin definitions for the ItsyBitsy RP2040 with u2if firmware.
+
+Adafruit CircuitPython 6.2.0 on 2021-04-05; Adafruit ItsyBitsy RP2040 with rp2040
+>>> import board
+>>> board.
+A0              A1              A2              A3
+BUTTON          D0              D1              D10
+D11             D12             D13             D2
+D24             D25             D3              D4
+D5              D7              D9              I2C
+LED             MISO            MOSI            NEOPIXEL
+NEOPIXEL_POWER  RX              SCK             SCL
+SDA             SPI             TX              UART
+"""
+
+
+from adafruit_blinka.microcontroller.rp2040_u2if import pin
+
+D0 = pin.GP1
+D1 = pin.GP0
+D2 = pin.GP12
+D3 = pin.GP5
+D4 = pin.GP4
+D5 = pin.GP14
+D7 = pin.GP6
+D9 = pin.GP7
+D10 = pin.GP8
+D11 = pin.GP9
+D12 = pin.GP10
+D13 = pin.GP11
+D24 = pin.GP24
+D25 = pin.GP25
+
+A0 = pin.GP26
+A1 = pin.GP27
+A2 = pin.GP28
+# A3 = pin.GP29 # not currently supported in firmware
+
+SCL = pin.GP3
+SDA = pin.GP2
+
+SCLK = SCK = pin.GP18
+MOSI = pin.GP19
+MISO = pin.GP20
+
+NEOPIXEL = pin.GP17
+NEOPIXEL_POWER = pin.GP16
+
+BUTTON = pin.GP13
+
+# access u2if via pin instance to open for specifc VID/PID
+# pylint:disable = protected-access
+pin.GP0._u2if_open_hid(0x239A, 0x00FD)
index bcdfe47c34557e25bc97559b0d98d62c084cf0ea..6564ed38b5f00a45306b05ceb52cbc46afa52591 100644 (file)
@@ -1,5 +1,5 @@
-"""Pin definitions for the MicroChip MCP2221"""
-from adafruit_blinka.microcontroller.pico_u2if import pin
+"""Pin definitions for the Raspberry Pi Pico running u2if firmware"""
+from adafruit_blinka.microcontroller.rp2040_u2if import pin
 
 GP0 = pin.GP0
 GP1 = pin.GP1
@@ -44,3 +44,7 @@ MISO = MISO0 = GP12
 SCLK1 = SCK1 = GP10
 MOSI1 = GP11
 MISO1 = GP12
+
+# access u2if via pin instance to open for specifc VID/PID
+# pylint:disable = protected-access
+pin.GP0._u2if_open_hid(0xCAFE, 0x4005)
diff --git a/src/adafruit_blinka/board/qt2040_trinkey_u2if.py b/src/adafruit_blinka/board/qt2040_trinkey_u2if.py
new file mode 100644 (file)
index 0000000..d71bea8
--- /dev/null
@@ -0,0 +1,14 @@
+"""Pin definitions for the QT2040 Trinkey with u2if firmware."""
+
+from adafruit_blinka.microcontroller.rp2040_u2if import pin
+
+BUTTON = pin.GP12
+
+SCL = pin.GP17
+SDA = pin.GP16
+
+NEOPIXEL = pin.GP27
+
+# access u2if via pin instance to open for specifc VID/PID
+# pylint:disable = protected-access
+pin.GP0._u2if_open_hid(0x239A, 0x0109)
diff --git a/src/adafruit_blinka/board/qtpy_u2if.py b/src/adafruit_blinka/board/qtpy_u2if.py
new file mode 100644 (file)
index 0000000..569ace2
--- /dev/null
@@ -0,0 +1,54 @@
+"""
+Pin definitions for the QT Py RP2040 with u2if firmware.
+
+Adafruit CircuitPython 6.2.0 on 2021-04-05; Adafruit QTPy RP2040 with rp2040
+>>> import board
+>>> board.
+A0              A1              A2              A3
+BUTTON          D0              D1              D10
+D2              D3              D4              D5
+D6              D7              D8              D9
+I2C             MISO            MOSI            NEOPIXEL
+NEOPIXEL_POWER  RX              SCK             SCL
+SCL1            SDA             SDA1            SPI
+TX              UART
+"""
+
+
+from adafruit_blinka.microcontroller.rp2040_u2if import pin
+
+D0 = pin.GP29
+D1 = pin.GP28
+D2 = pin.GP27
+D3 = pin.GP26
+D4 = pin.GP24
+D5 = pin.GP25
+D6 = pin.GP20
+D7 = pin.GP5
+D8 = pin.GP6
+D9 = pin.GP4
+D10 = pin.GP3
+
+# A0 = pin.GP29 # not currently supported in firmware
+A1 = pin.GP28
+A2 = pin.GP27
+A3 = pin.GP26
+
+SCL = pin.GP25
+SDA = pin.GP24
+
+SCL1 = pin.GP23
+SDA1 = pin.GP22
+
+SCLK = SCK = pin.GP6
+MOSI = pin.GP3
+MISO = pin.GP4
+
+NEOPIXEL = pin.GP12
+NEOPIXEL_POWER = pin.GP11
+
+BUTTON = pin.GP21
+
+# access u2if via pin instance to open for specifc VID/PID
+# pylint:disable = protected-access
+pin.GP0._u2if_open_hid(0x239A, 0x00F7)
diff --git a/src/adafruit_blinka/microcontroller/pico_u2if/analogio.py b/src/adafruit_blinka/microcontroller/pico_u2if/analogio.py
deleted file mode 100644 (file)
index 2ae480f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-"""
-`analogio` - Analog input and output control
-=================================================
-See `CircuitPython:analogio` in CircuitPython for more details.
-* Author(s): Carter Nelson
-"""
-from adafruit_blinka import ContextManaged
-from .pico_u2if import pico_u2if
-
-
-class AnalogIn(ContextManaged):
-    """Analog Input Class"""
-
-    def __init__(self, pin):
-        # per their pinout, why only two?
-        if pin.id not in (26, 27):
-            raise ValueError("Pin does not support ADC.")
-        self.pin_id = pin.id
-        pico_u2if.adc_init_pin(self.pin_id)
-
-    @property
-    def value(self):
-        """Read the ADC and return the value"""
-        return pico_u2if.adc_get_value(self.pin_id) << 4
-
-    # 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):
-        pass
diff --git a/src/adafruit_blinka/microcontroller/pico_u2if/i2c.py b/src/adafruit_blinka/microcontroller/pico_u2if/i2c.py
deleted file mode 100644 (file)
index ee393bb..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-"""I2C Class for Pico u2if"""
-from .pico_u2if import pico_u2if
-
-
-class I2C:
-    """Custom I2C Class for Pico u2if"""
-
-    def __init__(self, scl, sda, *, frequency=100000):
-        index = None
-        if scl.id == 5 and sda.id == 4:
-            index = 0
-        if scl.id == 15 and sda.id == 14:
-            index = 1
-        if index is None:
-            raise ValueError("I2C not found on specified pins.")
-        self._index = index
-        pico_u2if.i2c_set_port(self._index)
-        pico_u2if.i2c_configure(frequency)
-
-    def scan(self):
-        """Perform an I2C Device Scan"""
-        pico_u2if.i2c_set_port(self._index)
-        return pico_u2if.i2c_scan()
-
-    # pylint: disable=unused-argument
-    def writeto(self, address, buffer, *, start=0, end=None, stop=True):
-        """Write data from the buffer to an address"""
-        pico_u2if.i2c_set_port(self._index)
-        pico_u2if.i2c_writeto(address, buffer, start=start, end=end)
-
-    def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
-        """Read data from an address and into the buffer"""
-        pico_u2if.i2c_set_port(self._index)
-        pico_u2if.i2c_readfrom_into(address, buffer, start=start, end=end)
-
-    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
-        """
-        pico_u2if.i2c_set_port(self._index)
-        pico_u2if.i2c_writeto_then_readfrom(
-            address,
-            buffer_out,
-            buffer_in,
-            out_start=out_start,
-            out_end=out_end,
-            in_start=in_start,
-            in_end=in_end,
-        )
-
-    # pylint: enable=unused-argument
diff --git a/src/adafruit_blinka/microcontroller/pico_u2if/spi.py b/src/adafruit_blinka/microcontroller/pico_u2if/spi.py
deleted file mode 100644 (file)
index e4d7202..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-"""SPI Class for Pico u2if"""
-from .pico_u2if import pico_u2if
-
-# pylint: disable=protected-access, no-self-use
-class SPI:
-    """Custom SPI Class for Pico u2if"""
-
-    MSB = 0
-
-    def __init__(self, clock, *, baudrate=100000):
-        index = None
-        if clock.id == 18:
-            index = 0
-        if clock.id == 10:
-            index = 1
-        if index is None:
-            raise ValueError("No SPI port on specified pin.")
-        self._index = index
-        self._frequency = baudrate
-        pico_u2if.spi_set_port(self._index)
-        pico_u2if.spi_configure(self._frequency)
-
-    # pylint: disable=too-many-arguments,unused-argument
-    def init(
-        self,
-        baudrate=1000000,
-        polarity=0,
-        phase=0,
-        bits=8,
-        firstbit=MSB,
-        sck=None,
-        mosi=None,
-        miso=None,
-    ):
-        """Initialize the Port"""
-        self._frequency = baudrate
-        pico_u2if.spi_set_port(self._index)
-        pico_u2if.spi_configure(self._frequency)
-
-    # pylint: enable=too-many-arguments
-
-    @property
-    def frequency(self):
-        """Return the current frequency"""
-        return self._frequency
-
-    def write(self, buf, start=0, end=None):
-        """Write data from the buffer to SPI"""
-        pico_u2if.spi_write(buf, start=start, end=end)
-
-    def readinto(self, buf, start=0, end=None, write_value=0):
-        """Read data from SPI and into the buffer"""
-        pico_u2if.spi_readinto(buf, start=start, end=end, write_value=write_value)
-
-    # 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
-        """
-        pico_u2if.spi_write_readinto(
-            buffer_out,
-            buffer_in,
-            out_start=out_start,
-            out_end=out_end,
-            in_start=in_start,
-            in_end=in_end,
-        )
-
-    # pylint: enable=too-many-arguments
diff --git a/src/adafruit_blinka/microcontroller/rp2040_u2if/analogio.py b/src/adafruit_blinka/microcontroller/rp2040_u2if/analogio.py
new file mode 100644 (file)
index 0000000..e4db746
--- /dev/null
@@ -0,0 +1,69 @@
+"""
+`analogio` - Analog input and output control
+=================================================
+See `CircuitPython:analogio` in CircuitPython for more details.
+* Author(s): Carter Nelson
+"""
+from adafruit_blinka import ContextManaged
+from .rp2040_u2if import rp2040_u2if
+
+
+class AnalogIn(ContextManaged):
+    """AnalogIn Base Class for RP2040 u2if"""
+
+    def __init__(self, pin):
+        self.pin_id = pin.id
+        rp2040_u2if.adc_init_pin(self.pin_id)
+
+    @property
+    def value(self):
+        """Read the ADC and return the value"""
+        return rp2040_u2if.adc_get_value(self.pin_id) << 4
+
+    # 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):
+        pass
+
+
+class AnalogIn_Pico(AnalogIn):
+    """AnalogIn Base Class for Pico u2if"""
+
+    def __init__(self, pin):
+        # per their pinout, why only two?
+        if pin.id not in (26, 27):
+            raise ValueError("Pin does not support ADC.")
+        super().__init__(pin)
+
+
+class AnalogIn_Feather(AnalogIn):
+    """AnalogIn Base Class for Feather u2if"""
+
+    def __init__(self, pin):
+        if pin.id not in (26, 27, 28):
+            raise ValueError("Pin does not support ADC.")
+        super().__init__(pin)
+
+
+class AnalogIn_QTPY(AnalogIn):
+    """AnalogIn Base Class for QT Py 2040 u2if"""
+
+    def __init__(self, pin):
+        if pin.id not in (26, 27, 28):
+            raise ValueError("Pin does not support ADC.")
+        super().__init__(pin)
+
+
+class AnalogIn_ItsyBitsy(AnalogIn):
+    """AnalogIn Base Class for ItsyBitsy 2040 u2if"""
+
+    def __init__(self, pin):
+        if pin.id not in (26, 27, 28):
+            raise ValueError("Pin does not support ADC.")
+        super().__init__(pin)
diff --git a/src/adafruit_blinka/microcontroller/rp2040_u2if/i2c.py b/src/adafruit_blinka/microcontroller/rp2040_u2if/i2c.py
new file mode 100644 (file)
index 0000000..f12764a
--- /dev/null
@@ -0,0 +1,129 @@
+"""I2C Classes for RP2040s with u2if firmware"""
+from .rp2040_u2if import rp2040_u2if
+
+
+class I2C:
+    """I2C Base Class for RP2040 u2if"""
+
+    def __init__(self, index, *, frequency=100000):
+        self._index = index
+        rp2040_u2if.i2c_set_port(self._index)
+        rp2040_u2if.i2c_configure(frequency)
+
+    def scan(self):
+        """Perform an I2C Device Scan"""
+        rp2040_u2if.i2c_set_port(self._index)
+        return rp2040_u2if.i2c_scan()
+
+    # pylint: disable=unused-argument
+    def writeto(self, address, buffer, *, start=0, end=None, stop=True):
+        """Write data from the buffer to an address"""
+        rp2040_u2if.i2c_set_port(self._index)
+        rp2040_u2if.i2c_writeto(address, buffer, start=start, end=end)
+
+    def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
+        """Read data from an address and into the buffer"""
+        rp2040_u2if.i2c_set_port(self._index)
+        rp2040_u2if.i2c_readfrom_into(address, buffer, start=start, end=end)
+
+    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
+        """
+        rp2040_u2if.i2c_set_port(self._index)
+        rp2040_u2if.i2c_writeto_then_readfrom(
+            address,
+            buffer_out,
+            buffer_in,
+            out_start=out_start,
+            out_end=out_end,
+            in_start=in_start,
+            in_end=in_end,
+        )
+
+    # pylint: enable=unused-argument
+
+
+class I2C_Pico(I2C):
+    """I2C Class for Pico u2if"""
+
+    def __init__(self, scl, sda, *, frequency=100000):
+        index = None
+        if scl.id == 5 and sda.id == 4:
+            index = 0
+        if scl.id == 15 and sda.id == 14:
+            index = 1
+        if index is None:
+            raise ValueError("I2C not found on specified pins.")
+        self._index = index
+
+        super().__init__(index, frequency=frequency)
+
+
+class I2C_Feather(I2C):
+    """I2C Class for Feather u2if"""
+
+    def __init__(self, scl, sda, *, frequency=100000):
+        index = None
+        if scl.id == 3 and sda.id == 2:
+            index = 1
+        if index is None:
+            raise ValueError("I2C not found on specified pins.")
+        self._index = index
+
+        super().__init__(index, frequency=frequency)
+
+
+class I2C_QTPY(I2C):
+    """I2C Class for QT Py 2if"""
+
+    def __init__(self, scl, sda, *, frequency=100000):
+        index = None
+        if scl.id == 25 and sda.id == 24:
+            index = 0
+        if scl.id == 23 and sda.id == 22:
+            index = 1
+        if index is None:
+            raise ValueError("I2C not found on specified pins.")
+        self._index = index
+
+        super().__init__(index, frequency=frequency)
+
+
+class I2C_ItsyBitsy(I2C):
+    """I2C Class for ItsyBitsy u2if"""
+
+    def __init__(self, scl, sda, *, frequency=100000):
+        index = None
+        if scl.id == 3 and sda.id == 2:
+            index = 1
+        if index is None:
+            raise ValueError("I2C not found on specified pins.")
+        self._index = index
+
+        super().__init__(index, frequency=frequency)
+
+
+class I2C_QT2040_Trinkey(I2C):
+    """I2C Class for QT2040 Trinkey u2if"""
+
+    def __init__(self, scl, sda, *, frequency=100000):
+        index = None
+        if scl.id == 17 and sda.id == 16:
+            index = 0
+        if index is None:
+            raise ValueError("I2C not found on specified pins.")
+        self._index = index
+
+        super().__init__(index, frequency=frequency)
similarity index 79%
rename from src/adafruit_blinka/microcontroller/pico_u2if/neopixel.py
rename to src/adafruit_blinka/microcontroller/rp2040_u2if/neopixel.py
index 4953c2d5ea2bda15d2cb72a296b37dcfe7744630..f0177aeaa7692218f9b92281f923b550a221efc9 100644 (file)
@@ -1,6 +1,6 @@
 """NeoPixel write for Pico u2if."""
 
-from .pico_u2if import pico_u2if
+from .rp2040_u2if import rp2040_u2if
 
 
 def neopixel_write(gpio, buf):
@@ -14,4 +14,4 @@ def neopixel_write(gpio, buf):
         buffer.append(buf[i + 1])
         buffer.append(buf[i])
 
-    pico_u2if.neopixel_write(gpio, buffer)
+    rp2040_u2if.neopixel_write(gpio, buffer)
similarity index 77%
rename from src/adafruit_blinka/microcontroller/pico_u2if/pin.py
rename to src/adafruit_blinka/microcontroller/rp2040_u2if/pin.py
index ef225872b9df7ef0c93edf51f57c0184a9685d2b..37a5ed50a8ff6df1af885899486165fdf746251d 100644 (file)
@@ -1,9 +1,9 @@
-"""PICO pin names"""
-from .pico_u2if import pico_u2if
+"""Generic RP2040 pin names"""
+from .rp2040_u2if import rp2040_u2if
 
 
 class Pin:
-    """A basic Pin class for use with MCP2221."""
+    """A basic Pin class for use with RP2040 with u2if firmware."""
 
     # pin modes
     IN = 0
@@ -21,6 +21,10 @@ class Pin:
         self._mode = None
         self._pull = None
 
+    # pylint:disable = no-self-use
+    def _u2if_open_hid(self, vid, pid):
+        rp2040_u2if.open(vid, pid)
+
     def init(self, mode=IN, pull=PULL_NONE):
         """Initialize the Pin"""
         pull = Pin.PULL_NONE if pull is None else pull
@@ -31,7 +35,7 @@ class Pin:
         if pull not in (Pin.PULL_NONE, Pin.PULL_UP, Pin.PULL_DOWN):
             raise ValueError("Incorrect pull value.")
 
-        pico_u2if.gpio_init_pin(self.id, mode, pull)
+        rp2040_u2if.gpio_init_pin(self.id, mode, pull)
 
         self._mode = mode
         self._pull = pull
@@ -42,10 +46,10 @@ class Pin:
         if self._mode in (Pin.IN, Pin.OUT):
             # digital read
             if val is None:
-                return pico_u2if.gpio_get_pin(self.id)
+                return rp2040_u2if.gpio_get_pin(self.id)
             # digital write
             if val in (Pin.LOW, Pin.HIGH):
-                pico_u2if.gpio_set_pin(self.id, val)
+                rp2040_u2if.gpio_set_pin(self.id, val)
                 return None
             # nope
             raise ValueError("Invalid value for pin.")
@@ -79,6 +83,10 @@ GP19 = Pin(19)
 GP20 = Pin(20)
 GP21 = Pin(21)
 GP22 = Pin(22)
+GP23 = Pin(23)
+GP24 = Pin(24)
+GP25 = Pin(25)
 GP26 = Pin(26)
 GP27 = Pin(27)
 GP28 = Pin(28)
+GP29 = Pin(29)
similarity index 64%
rename from src/adafruit_blinka/microcontroller/pico_u2if/pwmio.py
rename to src/adafruit_blinka/microcontroller/rp2040_u2if/pwmio.py
index f69d28eaa7f60e06261dd1c38ffa922c8a8ba47f..3cbf5e476003dae806095b8749483ee18c80516f 100644 (file)
@@ -1,12 +1,12 @@
-"""PWMOut Class for Pico u2if"""
-from .pico_u2if import pico_u2if
+"""PWMOut Class for RP2040s with u2if"""
+from .rp2040_u2if import rp2040_u2if
 
 
 class PWMOut:
-    """Pulse Width Modulation Output Class"""
+    """Base Pulse Width Modulation Output Class"""
 
     def __init__(self, pin, *, frequency=500, duty_cycle=0, variable_frequency=False):
-        pico_u2if.pwm_configure(
+        rp2040_u2if.pwm_configure(
             pin,
             frequency=frequency,
             duty_cycle=duty_cycle,
@@ -26,22 +26,22 @@ class PWMOut:
 
     def deinit(self):
         """Deinit PWM."""
-        pico_u2if.pwm_deinit(self._pin)
+        rp2040_u2if.pwm_deinit(self._pin)
 
     @property
     def duty_cycle(self):
         """The PWM's output duty cycle, 16-bit."""
-        return pico_u2if.pwm_get_duty_cycle(self._pin)
+        return rp2040_u2if.pwm_get_duty_cycle(self._pin)
 
     @duty_cycle.setter
     def duty_cycle(self, duty_cycle):
-        pico_u2if.pwm_set_duty_cycle(self._pin, duty_cycle)
+        rp2040_u2if.pwm_set_duty_cycle(self._pin, duty_cycle)
 
     @property
     def frequency(self):
         """The PWM's output frequency in Hertz."""
-        return pico_u2if.pwm_get_frequency(self._pin)
+        return rp2040_u2if.pwm_get_frequency(self._pin)
 
     @frequency.setter
     def frequency(self, frequency):
-        pico_u2if.pwm_set_frequency(self._pin, frequency)
+        rp2040_u2if.pwm_set_frequency(self._pin, frequency)
similarity index 93%
rename from src/adafruit_blinka/microcontroller/pico_u2if/pico_u2if.py
rename to src/adafruit_blinka/microcontroller/rp2040_u2if/rp2040_u2if.py
index 687bfc033585b4212b5bd44945fee65c4140461f..6431f94482f0906b5aabf24856af74e8df9ed16a 100644 (file)
@@ -1,4 +1,4 @@
-"""Chip Definition for Pico with u2if firmware"""
+"""Helper class for use with RP2040 running u2if firmware"""
 # https://github.com/execuc/u2if
 
 import os
@@ -6,17 +6,14 @@ import time
 import hid
 
 # Use to set delay between reset and device reopen. if negative, don't reset at all
-PICO_U2IF_RESET_DELAY = float(os.environ.get("PICO_U2IF_RESET_DELAY", 1))
+RP2040_U2IF_RESET_DELAY = float(os.environ.get("RP2040_U2IF_RESET_DELAY", 1))
 
 # pylint: disable=import-outside-toplevel,too-many-branches,too-many-statements
 # pylint: disable=too-many-arguments,too-many-function-args, too-many-public-methods
 
 
-class Pico_u2if:
-    """MCP2221 Device Class Definition"""
-
-    VID = 0xCAFE
-    PID = 0x4005
+class RP2040_u2if:
+    """Helper class for use with RP2040 running u2if firmware"""
 
     # MISC
     RESP_OK = 0x01
@@ -71,10 +68,10 @@ class Pico_u2if:
     PWM_GET_DUTY_NS = 0x37
 
     def __init__(self):
-        self._hid = hid.device()
-        self._hid.open(Pico_u2if.VID, Pico_u2if.PID)
-        if PICO_U2IF_RESET_DELAY >= 0:
-            self._reset()
+        self._vid = None
+        self._pid = None
+        self._hid = None
+        self._opened = False
         self._i2c_index = None
         self._spi_index = None
         self._serial = None
@@ -94,16 +91,32 @@ class Pico_u2if:
 
     def _reset(self):
         self._hid_xfer(bytes([self.SYS_RESET]), False)
-        time.sleep(PICO_U2IF_RESET_DELAY)
+        time.sleep(RP2040_U2IF_RESET_DELAY)
         start = time.monotonic()
         while time.monotonic() - start < 5:
             try:
-                self._hid.open(Pico_u2if.VID, Pico_u2if.PID)
+                self._hid.open(self._vid, self._pid)
             except OSError:
                 time.sleep(0.1)
                 continue
             return
-        raise OSError("Pico open error.")
+        raise OSError("RP2040 u2if open error.")
+
+    # ----------------------------------------------------------------
+    # MISC
+    # ----------------------------------------------------------------
+    def open(self, vid, pid):
+        """Open HID interface for given USB VID and PID."""
+
+        if self._opened:
+            return
+        self._vid = vid
+        self._pid = pid
+        self._hid = hid.device()
+        self._hid.open(self._vid, self._pid)
+        if RP2040_U2IF_RESET_DELAY >= 0:
+            self._reset()
+        self._opened = True
 
     # ----------------------------------------------------------------
     # GPIO
@@ -369,7 +382,7 @@ class Pico_u2if:
 
             ports = serial.tools.list_ports.comports()
             for port in ports:
-                if port.vid == self.VID and port.pid == self.PID:
+                if port.vid == self._vid and port.pid == self._pid:
                     self._serial = serial.Serial(port.device)
                     break
         if self._serial is None:
@@ -409,7 +422,6 @@ class Pico_u2if:
                     "Neopixel write error : too many pixel for the firmware."
                 )
             elif resp[2] == 0x02:
-                print(resp[0:10])
                 raise RuntimeError(
                     "Neopixel write error : transfer already in progress."
                 )
@@ -422,6 +434,7 @@ class Pico_u2if:
             self._serial.write([0])
         self._serial.flush()
         # polling loop to wait for write complete?
+        time.sleep(0.1)
         resp = self._hid.read(64)
         while resp[0] != self.WS2812B_WRITE:
             resp = self._hid.read(64)
@@ -489,4 +502,4 @@ class Pico_u2if:
             raise RuntimeError("PWM set duty cycle error.")
 
 
-pico_u2if = Pico_u2if()
+rp2040_u2if = RP2040_u2if()
diff --git a/src/adafruit_blinka/microcontroller/rp2040_u2if/spi.py b/src/adafruit_blinka/microcontroller/rp2040_u2if/spi.py
new file mode 100644 (file)
index 0000000..9e025f9
--- /dev/null
@@ -0,0 +1,114 @@
+"""SPI Classes for RP2040s with u2if firmware"""
+from .rp2040_u2if import rp2040_u2if
+
+# pylint: disable=protected-access, no-self-use
+class SPI:
+    """SPI Base Class for RP2040 u2if"""
+
+    MSB = 0
+
+    def __init__(self, index, *, baudrate=100000):
+        self._index = index
+        self._frequency = baudrate
+        rp2040_u2if.spi_set_port(self._index)
+        rp2040_u2if.spi_configure(self._frequency)
+
+    # pylint: disable=too-many-arguments,unused-argument
+    def init(
+        self,
+        baudrate=1000000,
+        polarity=0,
+        phase=0,
+        bits=8,
+        firstbit=MSB,
+        sck=None,
+        mosi=None,
+        miso=None,
+    ):
+        """Initialize the Port"""
+        self._frequency = baudrate
+        rp2040_u2if.spi_set_port(self._index)
+        rp2040_u2if.spi_configure(self._frequency)
+
+    # pylint: enable=too-many-arguments
+
+    @property
+    def frequency(self):
+        """Return the current frequency"""
+        return self._frequency
+
+    def write(self, buf, start=0, end=None):
+        """Write data from the buffer to SPI"""
+        rp2040_u2if.spi_write(buf, start=start, end=end)
+
+    def readinto(self, buf, start=0, end=None, write_value=0):
+        """Read data from SPI and into the buffer"""
+        rp2040_u2if.spi_readinto(buf, start=start, end=end, write_value=write_value)
+
+    # 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
+        """
+        rp2040_u2if.spi_write_readinto(
+            buffer_out,
+            buffer_in,
+            out_start=out_start,
+            out_end=out_end,
+            in_start=in_start,
+            in_end=in_end,
+        )
+
+    # pylint: enable=too-many-arguments
+
+
+class SPI_Pico(SPI):
+    """SPI Class for Pico u2if"""
+
+    def __init__(self, clock, *, baudrate=100000):
+        index = None
+        if clock.id == 18:
+            index = 0
+        if clock.id == 10:
+            index = 1
+        if index is None:
+            raise ValueError("No SPI port on specified pin.")
+        super().__init__(index, baudrate=baudrate)
+
+
+class SPI_Feather(SPI):
+    """SPI Class for Feather u2if"""
+
+    def __init__(self, clock, *, baudrate=100000):
+        index = None
+        if clock.id == 18:
+            index = 0
+        if index is None:
+            raise ValueError("No SPI port on specified pin.")
+        super().__init__(index, baudrate=baudrate)
+
+
+class SPI_QTPY(SPI):
+    """SPI Class for QT Py u2if"""
+
+    def __init__(self, clock, *, baudrate=100000):
+        index = None
+        if clock.id == 6:
+            index = 0
+        if index is None:
+            raise ValueError("No SPI port on specified pin.")
+        super().__init__(index, baudrate=baudrate)
+
+
+class SPI_ItsyBitsy(SPI):
+    """SPI Class for ItsyBitsy u2if"""
+
+    def __init__(self, clock, *, baudrate=100000):
+        index = None
+        if clock.id == 18:
+            index = 0
+        if index is None:
+            raise ValueError("No SPI port on specified pin.")
+        super().__init__(index, baudrate=baudrate)
index 04d3afce8494afb0b38f47a45a54cfc964acb8d1..0016505a21d54030f35e68ffa980dbbbd7446b51 100644 (file)
@@ -30,6 +30,20 @@ elif detector.chip.STM32MP157:
 elif "sphinx" in sys.modules:
     pass
 elif detector.board.pico_u2if:
-    from adafruit_blinka.microcontroller.pico_u2if.analogio import AnalogIn
+    from adafruit_blinka.microcontroller.rp2040_u2if.analogio import (
+        AnalogIn_Pico as AnalogIn,
+    )
+elif detector.board.feather_u2if:
+    from adafruit_blinka.microcontroller.rp2040_u2if.analogio import (
+        AnalogIn_Feather as AnalogIn,
+    )
+elif detector.board.qtpy_u2if:
+    from adafruit_blinka.microcontroller.rp2040_u2if.analogio import (
+        AnalogIn_QTPY as AnalogIn,
+    )
+elif detector.board.itsybitsy_u2if:
+    from adafruit_blinka.microcontroller.rp2040_u2if.analogio import (
+        AnalogIn_ItsyBitsy as AnalogIn,
+    )
 else:
     raise NotImplementedError("analogio not supported for this board.")
index 0c8a6455ff962d4badde8034420e90698fa72b6e..eb5e7d97a13ea13884fc324e83d07da5cd2ff0e0 100755 (executable)
@@ -227,6 +227,18 @@ elif board_id == ap_board.NANOPI_DUO2:
 elif board_id == ap_board.PICO_U2IF:
     from adafruit_blinka.board.pico_u2if import *
 
+elif board_id == ap_board.FEATHER_U2IF:
+    from adafruit_blinka.board.feather_u2if import *
+
+elif board_id == ap_board.QTPY_U2IF:
+    from adafruit_blinka.board.qtpy_u2if import *
+
+elif board_id == ap_board.ITSYBITSY_U2IF:
+    from adafruit_blinka.board.itsybitsy_u2if import *
+
+elif board_id == ap_board.QT2040_TRINKEY_U2IF:
+    from adafruit_blinka.board.qt2040_trinkey_u2if import *
+
 elif "sphinx" in sys.modules:
     pass
 
index 11c6341421ad002fe01ef4b29493590d2988c1d5..3057e525acf6fe525fc16d7970fc8345f73698ad 100755 (executable)
@@ -18,7 +18,7 @@ from adafruit_blinka import Enum, Lockable, agnostic
 from adafruit_blinka.agnostic import board_id, detector
 
 # pylint: disable=import-outside-toplevel,too-many-branches,too-many-statements
-# pylint: disable=too-many-arguments,too-many-function-args,consider-using-with
+# pylint: disable=too-many-arguments,too-many-function-args,consider-using-with,too-many-return-statements
 
 
 class I2C(Lockable):
@@ -54,7 +54,33 @@ class I2C(Lockable):
             self._i2c = _I2C(frequency=frequency)
             return
         if detector.board.pico_u2if:
-            from adafruit_blinka.microcontroller.pico_u2if.i2c import I2C as _I2C
+            from adafruit_blinka.microcontroller.rp2040_u2if.i2c import I2C_Pico as _I2C
+
+            self._i2c = _I2C(scl, sda, frequency=frequency)
+            return
+        if detector.board.feather_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.i2c import (
+                I2C_Feather as _I2C,
+            )
+
+            self._i2c = _I2C(scl, sda, frequency=frequency)
+            return
+        if detector.board.qtpy_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.i2c import I2C_QTPY as _I2C
+
+            self._i2c = _I2C(scl, sda, frequency=frequency)
+            return
+        if detector.board.itsybitsy_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.i2c import (
+                I2C_ItsyBitsy as _I2C,
+            )
+
+            self._i2c = _I2C(scl, sda, frequency=frequency)
+            return
+        if detector.board.qt2040_trinkey_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.i2c import (
+                I2C_QT2040_Trinkey as _I2C,
+            )
 
             self._i2c = _I2C(scl, sda, frequency=frequency)
             return
@@ -192,7 +218,29 @@ class SPI(Lockable):
             self._pins = (SCK, MOSI, MISO)
             return
         if detector.board.pico_u2if:
-            from adafruit_blinka.microcontroller.pico_u2if.spi import SPI as _SPI
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import SPI_Pico 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.feather_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import (
+                SPI_Feather 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.itsybitsy_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import (
+                SPI_ItsyBitsy 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.qtpy_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import SPI_QTPY as _SPI
 
             self._spi = _SPI(clock)  # this is really all that's needed
             self._pins = (clock, clock, clock)  # will determine MOSI/MISO from clock
@@ -301,7 +349,17 @@ class SPI(Lockable):
         elif detector.board.any_lubancat and detector.chip.id == ap_chip.IMX6ULL:
             from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
         elif detector.board.pico_u2if:
-            from adafruit_blinka.microcontroller.pico_u2if.spi import SPI as _SPI
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import SPI_Pico as _SPI
+        elif detector.board.feather_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import (
+                SPI_Feather as _SPI,
+            )
+        elif detector.board.itsybitsy_u2if:
+            from adafruit_blinka.microcontroller.rp2040_u2if.spi import (
+                SPI_ItsyBitsy as _SPI,
+            )
+        elif detector.board.qtpy_u2if:
+            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
         else:
index eef0015f076bdaa420fa659f446fb344b4532b00..4237bac7be4f597ccd90f734f5ca1c2334f91f71 100755 (executable)
@@ -82,7 +82,14 @@ elif detector.chip.H6:
 elif detector.chip.H616:
     from adafruit_blinka.microcontroller.allwinner.h616.pin import Pin
 elif detector.board.pico_u2if:
-    from adafruit_blinka.microcontroller.pico_u2if.pin import Pin
+    from adafruit_blinka.microcontroller.rp2040_u2if.pin import Pin
+elif (
+    detector.board.feather_u2if
+    or detector.board.qtpy_u2if
+    or detector.board.itsybitsy_u2if
+    or detector.board.qt2040_trinkey_u2if
+):
+    from adafruit_blinka.microcontroller.rp2040_u2if.pin import Pin
 
 from adafruit_blinka import Enum, ContextManaged
 
index 34f7b4a7641a1d51ce1b97f413184a7eaa192824..7b945a0e010d4fdec27887c744b39408843051cf 100755 (executable)
@@ -81,6 +81,6 @@ elif chip_id == ap_chip.STM32MP157:
 elif chip_id == ap_chip.MT8167:
     from adafruit_blinka.microcontroller.mt8167.pin import *
 elif chip_id == ap_chip.PICO_U2IF:
-    from adafruit_blinka.microcontroller.pico_u2if.pin import *
+    from adafruit_blinka.microcontroller.rp2040_u2if.pin import *
 else:
     raise NotImplementedError("Microcontroller not supported: ", chip_id)
index 00ffa0b8df09026c32605ddf4f78d2a089832ba1..2097c84915b5fad24edb02884e816a9286388bbc 100644 (file)
@@ -15,7 +15,14 @@ from adafruit_blinka.agnostic import detector
 if detector.board.any_raspberry_pi:
     from adafruit_blinka.microcontroller.bcm283x import neopixel as _neopixel
 elif detector.board.pico_u2if:
-    from adafruit_blinka.microcontroller.pico_u2if import neopixel as _neopixel
+    from adafruit_blinka.microcontroller.rp2040_u2if import neopixel as _neopixel
+elif (
+    detector.board.feather_u2if
+    or detector.board.qtpy_u2if
+    or detector.board.itsybitsy_u2if
+    or detector.board.qt2040_trinkey_u2if
+):
+    from adafruit_blinka.microcontroller.rp2040_u2if import neopixel as _neopixel
 elif "sphinx" in sys.modules:
     pass
 else:
index dbb8bb79777c6ff3a4602c2fd2bd0bb1fffb2037..f59805852b52d95d3f67033a36ac9764dba6c33c 100644 (file)
@@ -30,7 +30,14 @@ elif detector.board.greatfet_one:
 elif detector.board.any_lubancat:
     from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
 elif detector.board.pico_u2if:
-    from adafruit_blinka.microcontroller.pico_u2if.pwmio import PWMOut
+    from adafruit_blinka.microcontroller.rp2040_u2if.pwmio import PWMOut
+elif (
+    detector.board.feather_u2if
+    or detector.board.qtpy_u2if
+    or detector.board.itsybitsy_u2if
+    or detector.board.qt2040_trinkey_u2if
+):
+    from adafruit_blinka.microcontroller.rp2040_u2if.pwmio import PWMOut
 elif "sphinx" in sys.modules:
     pass
 else: