]> Repositories - Adafruit_Blinka-hackapet.git/commitdiff
Merge remote-tracking branch 'adafruit/main'
authorRyan L <ryestar101@gmail.com>
Tue, 6 Jun 2023 22:17:35 +0000 (23:17 +0100)
committerRyan L <ryestar101@gmail.com>
Tue, 6 Jun 2023 22:17:35 +0000 (23:17 +0100)
.gitignore
setup.py
src/adafruit_blinka/board/hardkernel/odroidc4.py
src/adafruit_blinka/board/radxa/rockpi4.py
src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pin.py
src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/PulseIn.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/__init__.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein [new file with mode: 0755]
src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein.license [new file with mode: 0644]
src/adafruit_blinka/microcontroller/rockchip/rk3399/pin.py
src/pulseio.py

index 5fb597bd075ede07a303f531c92cb2cd8396acb7..4c18ddf4b1948a9e1e82811d9263891af332f837 100644 (file)
@@ -14,3 +14,4 @@ bundles
 dist
 **/*.egg-info
 .vscode
+build
index 51df79116680efa093914aed56b6012cecd2620b..c94ab3cbe92278699d5b8c386da66444e16f503a 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -75,6 +75,9 @@ setup(
             "libgpiod_pulsein",
             "libgpiod_pulsein64",
         ],
+        "adafruit_blinka.microcontroller.amlogic.meson_g12_common.pulseio": [
+            "libgpiod_pulsein",
+        ],
         "micropython-stubs": ["*.pyi"],
     },
     include_package_data=True,
index 2191013eb24a4a0d3c2718b069bb8fb7734dacf2..814f374ce99cebb537e8596e67bb9da54b480834 100644 (file)
@@ -9,8 +9,9 @@ for it in pin.i2cPorts:
     globals()["SCL" + str(it[0])] = it[1]
     globals()["SDA" + str(it[0])] = it[2]
 
-SCL = pin.i2cPorts[0][1]
-SDA = pin.i2cPorts[0][2]
+if pin.i2cPorts:
+    SCL = pin.i2cPorts[0][1]
+    SDA = pin.i2cPorts[0][2]
 
 SCLK = pin.SPI0_SCLK
 MOSI = pin.SPI0_MOSI
index 9fdccbc1b241a1b553c0261e609d8d12abc86e2a..c8070edf9c8f5e8e1605957661010ea62f8aea54 100644 (file)
@@ -46,9 +46,9 @@ SCL7 = D5
 SDA = SDA2
 SCL = SCL2
 
-SCLK = D19
-MOSI = D21
-MISO = D23
+SCLK = D23
+MOSI = D19
+MISO = D21
 CS = D24
 SCK = SCLK
 
index 41cf8f2e5918b3f560fc1c054d3ac41ca9545ca8..87f45719ac1918e5e98c40bc23cff1b71e97c931 100644 (file)
@@ -14,23 +14,34 @@ Linux kernel 5.4.y (mainline)
 from typing import Optional
 import os
 import re
-import gpiod
+
+try:
+    import gpiod
+except ImportError:
+    raise ImportError(
+        "libgpiod Python bindings not found, please install and try again!"
+    ) from ImportError
 from adafruit_blinka.microcontroller.generic_linux.libgpiod_pin import Pin
 
-chip0 = gpiod.Chip("0")
-chip1 = gpiod.Chip("1")
+if hasattr(gpiod, "Chip"):
+    chip0 = gpiod.Chip("0")
+    chip1 = gpiod.Chip("1")
+else:
+    chip0 = gpiod.chip("0")
+    chip1 = gpiod.chip("1")
+
 
-if chip0.num_lines() < 20:
+if chip0.num_lines < 20:
     aobus = 0
     periphs = 1
-    periphs_offset = chip1.num_lines() - 85
+    periphs_offset = chip1.num_lines - 85
 else:
     aobus = 1
     periphs = 0
-    periphs_offset = chip0.num_lines() - 85
+    periphs_offset = chip0.num_lines - 85
 
-chip0.close()
-chip1.close()
+del chip0
+del chip1
 
 GPIOAO_0 = GPIO496 = Pin((aobus, 0))
 GPIOAO_1 = GPIO497 = Pin((aobus, 1))
diff --git a/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/PulseIn.py b/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/PulseIn.py
new file mode 100644 (file)
index 0000000..ae82f1c
--- /dev/null
@@ -0,0 +1,183 @@
+# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+"""Custom PulseIn Class to read PWM signals"""
+import time
+import subprocess
+import os
+import atexit
+import random
+import sysv_ipc
+
+DEBUG = False
+queues = []
+procs = []
+
+# The message queues live outside of python space, and must be formally cleaned!
+def final():
+    """In case the program is cancelled or quit, we need to clean up the PulseIn
+    helper process and also the message queue, this is called at exit to do so"""
+    if DEBUG:
+        print("Cleaning up message queues", queues)
+        print("Cleaning up processes", procs)
+    for q in queues:
+        q.remove()
+    for proc in procs:
+        proc.terminate()
+
+
+atexit.register(final)
+
+# pylint: disable=c-extension-no-member
+class PulseIn:
+    """PulseIn Class to read PWM signals"""
+
+    def __init__(self, pin, maxlen=2, idle_state=False):
+        """Create a PulseIn object associated with the given pin.
+        The object acts as a read-only sequence of pulse lengths with
+        a given max length. When it is active, new pulse lengths are
+        added to the end of the list. When there is no more room
+        (len() == maxlen) the oldest pulse length is removed to make room."""
+
+        if isinstance(pin.id, tuple):
+            self._pin = str(pin.id[1])
+            self._chip = "gpiochip{}".format(pin.id[0])
+        else:
+            self._pin = str(pin.id)
+            self._chip = "gpiochip0"
+
+        self._maxlen = maxlen
+        self._idle_state = idle_state
+        self._queue_key = random.randint(1, 9999)
+        try:
+            self._mq = sysv_ipc.MessageQueue(None, flags=sysv_ipc.IPC_CREX)
+            if DEBUG:
+                print("Message Queue Key: ", self._mq.key)
+            queues.append(self._mq)
+        except sysv_ipc.ExistentialError:
+            raise RuntimeError(
+                "Message queue creation failed"
+            ) from sysv_ipc.ExistentialError
+
+        # Check if OS is 64-bit
+        libgpiod_filename = "libgpiod_pulsein"
+        dir_path = os.path.dirname(os.path.realpath(__file__))
+        cmd = [
+            dir_path + "/" + libgpiod_filename,
+            "--pulses",
+            str(maxlen),
+            "--queue",
+            str(self._mq.key),
+        ]
+        if idle_state:
+            cmd.append("-i")
+        cmd.append(self._chip)
+        cmd.append(self._pin)
+        if DEBUG:
+            print(cmd)
+
+        self._process = subprocess.Popen(cmd)  # pylint: disable=consider-using-with
+        procs.append(self._process)
+
+        # wait for it to start up
+        if DEBUG:
+            print("Waiting for startup success message from subprocess")
+        message = self._wait_receive_msg(timeout=0.25)
+        if message[0] != b"!":
+            raise RuntimeError("Could not establish message queue with subprocess")
+        self._paused = False
+
+    # pylint: disable=redefined-builtin
+    def _wait_receive_msg(self, timeout=0, type=2):
+        """Internal helper that will wait for new messages of a given type,
+        and throw an exception on timeout"""
+        if timeout > 0:
+            stamp = time.monotonic()
+            while (time.monotonic() - stamp) < timeout:
+                try:
+                    message = self._mq.receive(block=False, type=type)
+                    return message
+                except sysv_ipc.BusyError:
+                    time.sleep(0.001)  # wait a bit then retry!
+            # uh-oh timed out
+            raise RuntimeError(
+                "Timed out waiting for PulseIn message. Make sure libgpiod is installed."
+            )
+        message = self._mq.receive(block=True, type=type)
+        return message
+
+    # pylint: enable=redefined-builtin
+
+    def deinit(self):
+        """Deinitialises the PulseIn and releases any hardware and software
+        resources for reuse."""
+        # Clean up after ourselves
+        self._process.terminate()
+        procs.remove(self._process)
+        self._mq.remove()
+        queues.remove(self._mq)
+
+    def __enter__(self):
+        """No-op used by Context Managers."""
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        """Automatically deinitializes the hardware when exiting a context."""
+        self.deinit()
+
+    def resume(self, trigger_duration=0):
+        """Resumes pulse capture after an optional trigger pulse."""
+        if trigger_duration != 0:
+            self._mq.send("t%d" % trigger_duration, True, type=1)
+        else:
+            self._mq.send("r", True, type=1)
+        self._paused = False
+
+    def pause(self):
+        """Pause pulse capture"""
+        self._mq.send("p", True, type=1)
+        self._paused = True
+
+    @property
+    def paused(self):
+        """True when pulse capture is paused as a result of pause() or
+        an error during capture such as a signal that is too fast."""
+        return self._paused
+
+    @property
+    def maxlen(self):
+        """The maximum length of the PulseIn. When len() is equal to maxlen,
+        it is unclear which pulses are active and which are idle."""
+        return self._maxlen
+
+    def clear(self):
+        """Clears all captured pulses"""
+        self._mq.send("c", True, type=1)
+
+    def popleft(self):
+        """Removes and returns the oldest read pulse."""
+        self._mq.send("^", True, type=1)
+        message = self._wait_receive_msg()
+        reply = int(message[0].decode("utf-8"))
+        # print(reply)
+        if reply == -1:
+            raise IndexError("pop from empty list")
+        return reply
+
+    def __len__(self):
+        """Returns the current pulse length"""
+        self._mq.send("l", True, type=1)
+        message = self._wait_receive_msg()
+        return int(message[0].decode("utf-8"))
+
+    # pylint: disable=redefined-builtin
+    def __getitem__(self, index, type=None):
+        """Returns the value at the given index or values in slice."""
+        self._mq.send("i%d" % index, True, type=1)
+        message = self._wait_receive_msg()
+        ret = int(message[0].decode("utf-8"))
+        if ret == -1:
+            raise IndexError("list index out of range")
+        return ret
+
+    # pylint: enable=redefined-builtin
diff --git a/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/__init__.py b/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein b/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein
new file mode 100755 (executable)
index 0000000..51bcb9a
Binary files /dev/null and b/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein differ
diff --git a/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein.license b/src/adafruit_blinka/microcontroller/amlogic/meson_g12_common/pulseio/libgpiod_pulsein.license
new file mode 100644 (file)
index 0000000..3165372
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-FileCopyrightText: 2023 Jan Volckaert for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
index f9912ae2dc6a632f17b9a841266507676da1c5e0..792cff93099a776dcf3432cf5079225fe3ad443e 100644 (file)
 # SPDX-License-Identifier: MIT
 """A Pin class for use with Rockchip RK3399 and RK3399_T."""
 
-from adafruit_blinka.microcontroller.generic_linux.sysfs_pin import Pin
-
-GPIO1_A1 = Pin(33)
-GPIO1_A3 = Pin(35)
-GPIO1_A7 = Pin(39)
-GPIO1_B0 = Pin(40)
-GPIO1_B1 = Pin(41)
-GPIO1_B2 = Pin(42)
-GPIO1_C2 = Pin(50)
-GPIO1_C4 = Pin(52)
-GPIO1_C5 = Pin(53)
-GPIO1_C6 = Pin(54)
-GPIO1_C7 = Pin(55)
-GPIO1_D0 = Pin(56)
-GPIO2_A0 = Pin(64)
-GPIO2_A1 = Pin(65)
-GPIO2_A7 = Pin(71)
-GPIO2_B0 = Pin(72)
-GPIO2_B1 = Pin(73)
-GPIO2_B2 = Pin(74)
-GPIO2_B3 = Pin(75)
-GPIO2_B4 = Pin(76)
-GPIO2_D4 = Pin(92)
-GPIO3_C0 = Pin(112)
-GPIO4_A3 = Pin(131)
-GPIO4_A4 = Pin(132)
-GPIO4_A5 = Pin(133)
-GPIO4_A6 = Pin(134)
-GPIO4_A7 = Pin(135)
-GPIO4_C0 = Pin(144)
-GPIO4_C1 = Pin(145)
-GPIO4_C2 = Pin(146)
-GPIO4_C3 = Pin(147)
-GPIO4_C4 = Pin(148)
-GPIO4_C5 = Pin(149)
-GPIO4_C6 = Pin(150)
-GPIO4_D2 = Pin(154)
-GPIO4_D4 = Pin(156)
-GPIO4_D5 = Pin(157)
-GPIO4_D6 = Pin(158)
+from adafruit_blinka.microcontroller.generic_linux.libgpiod_pin import Pin
+
+# GPIOx_yz = x * 32 + y * 8 + z
+# y: A -> 0, B -> 1, C -> 2, D -> 3
+
+GPIO0_A0 = Pin((0, 0))
+GPIO0_A1 = Pin((0, 1))
+GPIO0_A2 = Pin((0, 2))
+GPIO0_A3 = Pin((0, 3))
+GPIO0_A4 = Pin((0, 4))
+GPIO0_A5 = Pin((0, 5))
+GPIO0_A6 = Pin((0, 6))
+GPIO0_A7 = Pin((0, 7))
+GPIO0_B0 = Pin((0, 8))
+GPIO0_B1 = Pin((0, 9))
+GPIO0_B2 = Pin((0, 10))
+GPIO0_B3 = Pin((0, 11))
+GPIO0_B4 = Pin((0, 12))
+GPIO0_B5 = Pin((0, 13))
+GPIO0_B6 = Pin((0, 14))
+GPIO0_B7 = Pin((0, 15))
+GPIO0_C0 = Pin((0, 16))
+GPIO0_C1 = Pin((0, 17))
+GPIO0_C2 = Pin((0, 18))
+GPIO0_C3 = Pin((0, 19))
+GPIO0_C4 = Pin((0, 20))
+GPIO0_C5 = Pin((0, 21))
+GPIO0_C6 = Pin((0, 22))
+GPIO0_C7 = Pin((0, 23))
+GPIO0_D0 = Pin((0, 24))
+GPIO0_D1 = Pin((0, 25))
+GPIO0_D2 = Pin((0, 26))
+GPIO0_D3 = Pin((0, 27))
+GPIO0_D4 = Pin((0, 28))
+GPIO0_D5 = Pin((0, 29))
+GPIO0_D6 = Pin((0, 30))
+GPIO0_D7 = Pin((0, 31))
+
+GPIO1_A0 = Pin((1, 0))
+GPIO1_A1 = Pin((1, 1))
+GPIO1_A2 = Pin((1, 2))
+GPIO1_A3 = Pin((1, 3))
+GPIO1_A4 = Pin((1, 4))
+GPIO1_A5 = Pin((1, 5))
+GPIO1_A6 = Pin((1, 6))
+GPIO1_A7 = Pin((1, 7))
+GPIO1_B0 = Pin((1, 8))
+GPIO1_B1 = Pin((1, 9))
+GPIO1_B2 = Pin((1, 10))
+GPIO1_B3 = Pin((1, 11))
+GPIO1_B4 = Pin((1, 12))
+GPIO1_B5 = Pin((1, 13))
+GPIO1_B6 = Pin((1, 14))
+GPIO1_B7 = Pin((1, 15))
+GPIO1_C0 = Pin((1, 16))
+GPIO1_C1 = Pin((1, 17))
+GPIO1_C2 = Pin((1, 18))
+GPIO1_C3 = Pin((1, 19))
+GPIO1_C4 = Pin((1, 20))
+GPIO1_C5 = Pin((1, 21))
+GPIO1_C6 = Pin((1, 22))
+GPIO1_C7 = Pin((1, 23))
+GPIO1_D0 = Pin((1, 24))
+GPIO1_D1 = Pin((1, 25))
+GPIO1_D2 = Pin((1, 26))
+GPIO1_D3 = Pin((1, 27))
+GPIO1_D4 = Pin((1, 28))
+GPIO1_D5 = Pin((1, 29))
+GPIO1_D6 = Pin((1, 30))
+GPIO1_D7 = Pin((1, 31))
+
+GPIO2_A0 = Pin((2, 0))
+GPIO2_A1 = Pin((2, 1))
+GPIO2_A2 = Pin((2, 2))
+GPIO2_A3 = Pin((2, 3))
+GPIO2_A4 = Pin((2, 4))
+GPIO2_A5 = Pin((2, 5))
+GPIO2_A6 = Pin((2, 6))
+GPIO2_A7 = Pin((2, 7))
+GPIO2_B0 = Pin((2, 8))
+GPIO2_B1 = Pin((2, 9))
+GPIO2_B2 = Pin((2, 10))
+GPIO2_B3 = Pin((2, 11))
+GPIO2_B4 = Pin((2, 12))
+GPIO2_B5 = Pin((2, 13))
+GPIO2_B6 = Pin((2, 14))
+GPIO2_B7 = Pin((2, 15))
+GPIO2_C0 = Pin((2, 16))
+GPIO2_C1 = Pin((2, 17))
+GPIO2_C2 = Pin((2, 18))
+GPIO2_C3 = Pin((2, 19))
+GPIO2_C4 = Pin((2, 20))
+GPIO2_C5 = Pin((2, 21))
+GPIO2_C6 = Pin((2, 22))
+GPIO2_C7 = Pin((2, 23))
+GPIO2_D0 = Pin((2, 24))
+GPIO2_D1 = Pin((2, 25))
+GPIO2_D2 = Pin((2, 26))
+GPIO2_D3 = Pin((2, 27))
+GPIO2_D4 = Pin((2, 28))
+GPIO2_D5 = Pin((2, 29))
+GPIO2_D6 = Pin((2, 30))
+GPIO2_D7 = Pin((2, 31))
+
+GPIO3_A0 = Pin((3, 0))
+GPIO3_A1 = Pin((3, 1))
+GPIO3_A2 = Pin((3, 2))
+GPIO3_A3 = Pin((3, 3))
+GPIO3_A4 = Pin((3, 4))
+GPIO3_A5 = Pin((3, 5))
+GPIO3_A6 = Pin((3, 6))
+GPIO3_A7 = Pin((3, 7))
+GPIO3_B0 = Pin((3, 8))
+GPIO3_B1 = Pin((3, 9))
+GPIO3_B2 = Pin((3, 10))
+GPIO3_B3 = Pin((3, 11))
+GPIO3_B4 = Pin((3, 12))
+GPIO3_B5 = Pin((3, 13))
+GPIO3_B6 = Pin((3, 14))
+GPIO3_B7 = Pin((3, 15))
+GPIO3_C0 = Pin((3, 16))
+GPIO3_C1 = Pin((3, 17))
+GPIO3_C2 = Pin((3, 18))
+GPIO3_C3 = Pin((3, 19))
+GPIO3_C4 = Pin((3, 20))
+GPIO3_C5 = Pin((3, 21))
+GPIO3_C6 = Pin((3, 22))
+GPIO3_C7 = Pin((3, 23))
+GPIO3_D0 = Pin((3, 24))
+GPIO3_D1 = Pin((3, 25))
+GPIO3_D2 = Pin((3, 26))
+GPIO3_D3 = Pin((3, 27))
+GPIO3_D4 = Pin((3, 28))
+GPIO3_D5 = Pin((3, 29))
+GPIO3_D6 = Pin((3, 30))
+GPIO3_D7 = Pin((3, 31))
+
+GPIO4_A0 = Pin((4, 0))
+GPIO4_A1 = Pin((4, 1))
+GPIO4_A2 = Pin((4, 2))
+GPIO4_A3 = Pin((4, 3))
+GPIO4_A4 = Pin((4, 4))
+GPIO4_A5 = Pin((4, 5))
+GPIO4_A6 = Pin((4, 6))
+GPIO4_A7 = Pin((4, 7))
+GPIO4_B0 = Pin((4, 8))
+GPIO4_B1 = Pin((4, 9))
+GPIO4_B2 = Pin((4, 10))
+GPIO4_B3 = Pin((4, 11))
+GPIO4_B4 = Pin((4, 12))
+GPIO4_B5 = Pin((4, 13))
+GPIO4_B6 = Pin((4, 14))
+GPIO4_B7 = Pin((4, 15))
+GPIO4_C0 = Pin((4, 16))
+GPIO4_C1 = Pin((4, 17))
+GPIO4_C2 = Pin((4, 18))
+GPIO4_C3 = Pin((4, 19))
+GPIO4_C4 = Pin((4, 20))
+GPIO4_C5 = Pin((4, 21))
+GPIO4_C6 = Pin((4, 22))
+GPIO4_C7 = Pin((4, 23))
+GPIO4_D0 = Pin((4, 24))
+GPIO4_D1 = Pin((4, 25))
+GPIO4_D2 = Pin((4, 26))
+GPIO4_D3 = Pin((4, 27))
+GPIO4_D4 = Pin((4, 28))
+GPIO4_D5 = Pin((4, 29))
+GPIO4_D6 = Pin((4, 30))
+GPIO4_D7 = Pin((4, 31))
+
 ADC_IN0 = 1
 
 # I2C
index f80459e6eb113323e39e016c48adcc45c1081646..c6aa49e78e1023aee19185b89cff83f5758026ef 100644 (file)
@@ -20,5 +20,9 @@ if detector.board.any_raspberry_pi:
     from adafruit_blinka.microcontroller.bcm283x.pulseio.PulseIn import PulseIn
 elif "sphinx" in sys.modules:
     pass
+elif detector.board.any_odroid_40_pin:
+    from adafruit_blinka.microcontroller.amlogic.meson_g12_common.pulseio.PulseIn import (
+        PulseIn,
+    )
 else:
     raise NotImplementedError("pulseio not supported for this board.")