]> Repositories - Adafruit_Blinka-hackapet.git/commitdiff
Restructure and move pins to generic linux
authorMelissa LeBlanc-Williams <melissa@adafruit.com>
Fri, 14 Mar 2025 21:36:06 +0000 (14:36 -0700)
committerMelissa LeBlanc-Williams <melissa@adafruit.com>
Fri, 14 Mar 2025 21:36:06 +0000 (14:36 -0700)
13 files changed:
src/adafruit_blinka/board/raspberrypi/raspi_5.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/bcm2711/pin.py
src/adafruit_blinka/microcontroller/bcm2712/__init__.py [moved from src/adafruit_blinka/microcontroller/bcm283x/pwmio/__init__.py with 100% similarity]
src/adafruit_blinka/microcontroller/bcm2712/pin.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/bcm283x/pin.py
src/adafruit_blinka/microcontroller/generic_linux/lgpio_pin.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/generic_linux/lgpio_pwmout.py [moved from src/adafruit_blinka/microcontroller/bcm283x/pwmio/PWMOut.py with 98% similarity]
src/adafruit_blinka/microcontroller/generic_linux/rpi_gpio_pin.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/generic_linux/rpi_gpio_pwmout.py [new file with mode: 0644]
src/board.py
src/digitalio.py
src/microcontroller/pin.py
src/pwmio.py

diff --git a/src/adafruit_blinka/board/raspberrypi/raspi_5.py b/src/adafruit_blinka/board/raspberrypi/raspi_5.py
new file mode 100644 (file)
index 0000000..ef09c3a
--- /dev/null
@@ -0,0 +1,58 @@
+# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+"""Pin definitions for Raspberry Pi 5 models using the BCM2712."""
+
+from adafruit_blinka.microcontroller.bcm2712 import pin
+
+D0 = pin.D0
+D1 = pin.D1
+
+D2 = pin.D2
+SDA = pin.SDA
+D3 = pin.D3
+SCL = pin.SCL
+
+D4 = pin.D4
+D5 = pin.D5
+D6 = pin.D6
+
+D7 = pin.D7
+CE1 = pin.D7
+D8 = pin.D8
+CE0 = pin.D8
+D9 = pin.D9
+MISO = pin.D9
+D10 = pin.D10
+MOSI = pin.D10
+D11 = pin.D11
+SCLK = pin.D11
+SCK = pin.D11
+
+D12 = pin.D12
+D13 = pin.D13
+
+D14 = pin.D14
+TXD = pin.D14
+D15 = pin.D15
+RXD = pin.D15
+# create alias for most of the examples
+TX = pin.D14
+RX = pin.D15
+
+D16 = pin.D16
+D17 = pin.D17
+D18 = pin.D18
+D19 = pin.D19
+MISO_1 = pin.D19
+D20 = pin.D20
+MOSI_1 = pin.D20
+D21 = pin.D21
+SCLK_1 = pin.D21
+SCK_1 = pin.D21
+D22 = pin.D22
+D23 = pin.D23
+D24 = pin.D24
+D25 = pin.D25
+D26 = pin.D26
+D27 = pin.D27
index c0aedde86d7c6166a4ccd36bfd40cf72c7f7bbf9..69e0a5315717d5bbf6311027927f1f32bdc418b2 100644 (file)
@@ -3,7 +3,8 @@
 # SPDX-License-Identifier: MIT
 """Broadcom BCM2711 pin names"""
 
-from adafruit_blinka.microcontroller.bcm283x.pin import Pin
+# Use RPi.GPIO pins for Raspberry Pi 4
+from adafruit_blinka.microcontroller.generic_linux.rpi_gpio_pin import Pin
 
 D0 = Pin(0)
 D1 = Pin(1)
diff --git a/src/adafruit_blinka/microcontroller/bcm2712/pin.py b/src/adafruit_blinka/microcontroller/bcm2712/pin.py
new file mode 100644 (file)
index 0000000..736114f
--- /dev/null
@@ -0,0 +1,100 @@
+# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+"""Broadcom BCM2712 pin names"""
+
+# Use lgpio pins for Raspberry Pi 5
+from adafruit_blinka.microcontroller.generic_linux.lgpio_pin import Pin
+
+D0 = Pin(0)
+D1 = Pin(1)
+
+D2 = Pin(2)
+SDA = Pin(2)
+D3 = Pin(3)
+SCL = Pin(3)
+
+D4 = Pin(4)
+D5 = Pin(5)
+D6 = Pin(6)
+
+D7 = Pin(7)
+CE1 = Pin(7)
+D8 = Pin(8)
+CE0 = Pin(8)
+D9 = Pin(9)
+MISO = Pin(9)
+D10 = Pin(10)
+MOSI = Pin(10)
+D11 = Pin(11)
+SCLK = Pin(11)  # Raspberry Pi naming
+SCK = Pin(11)  # CircuitPython naming
+
+D12 = Pin(12)
+D13 = Pin(13)
+
+D14 = Pin(14)
+TXD = Pin(14)
+D15 = Pin(15)
+RXD = Pin(15)
+
+D16 = Pin(16)
+D17 = Pin(17)
+D18 = Pin(18)
+D19 = Pin(19)
+MISO_1 = Pin(19)
+D20 = Pin(20)
+MOSI_1 = Pin(20)
+D21 = Pin(21)
+SCLK_1 = Pin(21)
+SCK_1 = Pin(21)
+D22 = Pin(22)
+D23 = Pin(23)
+D24 = Pin(24)
+D25 = Pin(25)
+D26 = Pin(26)
+D27 = Pin(27)
+D28 = Pin(28)
+D29 = Pin(29)
+D30 = Pin(30)
+D31 = Pin(31)
+D32 = Pin(32)
+D33 = Pin(33)
+D34 = Pin(34)
+D35 = Pin(35)
+D36 = Pin(36)
+D37 = Pin(37)
+D38 = Pin(38)
+D39 = Pin(39)
+D40 = Pin(40)
+MISO_2 = Pin(40)
+D41 = Pin(41)
+MOSI_2 = Pin(41)
+D42 = Pin(42)
+SCLK_2 = Pin(42)
+SCK_2 = Pin(43)
+D43 = Pin(43)
+D44 = Pin(44)
+D45 = Pin(45)
+
+# ordered as spiId, sckId, mosiId, misoId
+spiPorts = (
+    (0, SCLK, MOSI, MISO),
+    (1, SCLK_1, MOSI_1, MISO_1),
+    (2, SCLK_2, MOSI_2, MISO_2),
+    (3, D3, D2, D1),
+    (4, D7, D6, D5),
+    (5, D15, D14, D13),
+)
+
+# ordered as uartId, txId, rxId
+uartPorts = ((1, TXD, RXD),)
+
+# These are the known hardware I2C ports / pins.
+# For software I2C ports created with the i2c-gpio overlay, see:
+#     https://github.com/adafruit/Adafruit_Python_Extended_Bus
+i2cPorts = (
+    (1, SCL, SDA),
+    (0, D1, D0),  # both pi 1 and pi 2 i2c ports!
+    (10, D45, D44),  # internal i2c bus for the CM4
+)
index e31d401249d68f12fac8a63460b1046af3ba163a..d741ada1854b07db851e5e8bab8799a8de08edad 100644 (file)
@@ -2,131 +2,9 @@
 #
 # SPDX-License-Identifier: MIT
 """Broadcom BCM283x pin names"""
-from pathlib import Path
-import lgpio
-
-
-def _get_gpiochip():
-    """
-    Determines the handle of the GPIO chip device to access.
-
-    iterate through sysfs  to find a GPIO chip device with a driver known to be
-    used for userspace GPIO access.
-    """
-    for dev in Path("/sys/bus/gpio/devices").glob("gpiochip*"):
-        drivers = set((dev / "of_node/compatible").read_text().split("\0"))
-        #   check if driver names are intended for userspace control
-        if drivers & {
-            "raspberrypi,rp1-gpio",
-            "raspberrypi,bcm2835-gpio",
-            "raspberrypi,bcm2711-gpio",
-        }:
-            return lgpio.gpiochip_open(int(dev.name[-1]))
-    # return chip0 as a fallback
-    return lgpio.gpiochip_open(0)
-
-
-CHIP = _get_gpiochip()
-
-
-class Pin:
-    """Pins dont exist in CPython so...lets make our own!"""
-
-    LOW = 0
-    HIGH = 1
-    OFF = LOW
-    ON = HIGH
-
-    # values of lg mode constants
-    PULL_NONE = 0x80
-    PULL_UP = 0x20
-    PULL_DOWN = 0x40
-    ACTIVE_LOW = 0x02
-
-    # drive mode lg constants
-    OPEN_DRAIN = 0x04
-    IN = 0x0100
-    OUT = 0x0200
-
-    # LG mode constants
-    _LG_ALERT = 0x400
-    _LG_GROUP = 0x800
-    _LG_MODES = IN | OUT | _LG_ALERT | _LG_GROUP
-    _LG_PULLS = PULL_NONE | PULL_UP | PULL_NONE | ACTIVE_LOW
-    _LG_DRIVES = OPEN_DRAIN
-
-    id = None
-    _value = LOW
-    _mode = IN
-
-    # we want exceptions
-    lgpio.exceptions = True
-
-    def __init__(self, bcm_number):
-        self.id = bcm_number
-
-    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 mode is not None:
-            if mode == Pin.IN:
-                self._mode = Pin.IN
-                self._set_gpio_mode_in()
-            elif mode == self.OUT:
-                self._mode = Pin.OUT
-                Pin._check_result(lgpio.gpio_claim_output(CHIP, self.id, Pin.LOW))
-            else:
-                raise RuntimeError(f"Invalid mode for pin: {self.id}")
-        if pull is not None:
-            if self._mode != Pin.IN:
-                raise RuntimeError("Can only set pull resistor on input")
-            if pull in {Pin.PULL_UP, Pin.PULL_DOWN, Pin.PULL_NONE}:
-                self._set_gpio_mode_in(lflags=pull)
-            else:
-                raise RuntimeError(f"Invalid pull for pin: {self.id}")
-
-    def value(self, val=None):
-        """Set or return the Pin Value"""
-        if val is not None:
-            if val == Pin.LOW:
-                self._value = val
-                Pin._check_result(lgpio.gpio_write(CHIP, self.id, val))
-            elif val == Pin.HIGH:
-                self._value = val
-                Pin._check_result(lgpio.gpio_write(CHIP, self.id, val))
-            else:
-                raise RuntimeError("Invalid value for pin")
-            return None
-        return Pin._check_result(lgpio.gpio_read(CHIP, self.id))
-
-    @staticmethod
-    def _check_result(result):
-        """
-        convert any result other than zero to a text message and pass it back
-        as a runtime exception.  Typical usage:  use the lgpio call as the
-        argument.
-        """
-        if result < 0:
-            raise RuntimeError(lgpio.error_text(result))
-        return result
-
-    def _set_gpio_mode_in(self, lflags=0):
-        """
-        claim a gpio as input, or modify the flags (PULL_UP, PULL_DOWN, ... )
-        """
-        # This gpio_free may seem redundant, but is required when
-        #  changing the line-flags of an already acquired input line
-        try:
-            lgpio.gpio_free(CHIP, self.id)
-        except lgpio.error:
-            pass
-        Pin._check_result(lgpio.gpio_claim_input(CHIP, self.id, lFlags=lflags))
 
+# Use RPi.GPIO pins for Raspberry Pi 1-3B+
+from adafruit_blinka.microcontroller.generic_linux.rpi_gpio_pin import Pin
 
 D0 = Pin(0)
 D1 = Pin(1)
diff --git a/src/adafruit_blinka/microcontroller/generic_linux/lgpio_pin.py b/src/adafruit_blinka/microcontroller/generic_linux/lgpio_pin.py
new file mode 100644 (file)
index 0000000..25a8268
--- /dev/null
@@ -0,0 +1,129 @@
+# SPDX-FileCopyrightText: 2025 Melissa LeBlanc-Williams for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+"""A Pin class for use with lgpio."""
+
+from pathlib import Path
+import lgpio
+
+
+def _get_gpiochip():
+    """
+    Determines the handle of the GPIO chip device to access.
+
+    iterate through sysfs  to find a GPIO chip device with a driver known to be
+    used for userspace GPIO access.
+    """
+    for dev in Path("/sys/bus/gpio/devices").glob("gpiochip*"):
+        drivers = set((dev / "of_node/compatible").read_text().split("\0"))
+        #   check if driver names are intended for userspace control
+        if drivers & {
+            "raspberrypi,rp1-gpio",
+            "raspberrypi,bcm2835-gpio",
+            "raspberrypi,bcm2711-gpio",
+        }:
+            return lgpio.gpiochip_open(int(dev.name[-1]))
+    # return chip0 as a fallback
+    return lgpio.gpiochip_open(0)
+
+
+CHIP = _get_gpiochip()
+
+
+class Pin:
+    """Pins dont exist in CPython so...lets make our own!"""
+
+    LOW = 0
+    HIGH = 1
+    OFF = LOW
+    ON = HIGH
+
+    # values of lg mode constants
+    PULL_NONE = 0x80
+    PULL_UP = 0x20
+    PULL_DOWN = 0x40
+    ACTIVE_LOW = 0x02
+
+    # drive mode lg constants
+    OPEN_DRAIN = 0x04
+    IN = 0x0100
+    OUT = 0x0200
+
+    # LG mode constants
+    _LG_ALERT = 0x400
+    _LG_GROUP = 0x800
+    _LG_MODES = IN | OUT | _LG_ALERT | _LG_GROUP
+    _LG_PULLS = PULL_NONE | PULL_UP | PULL_NONE | ACTIVE_LOW
+    _LG_DRIVES = OPEN_DRAIN
+
+    id = None
+    _value = LOW
+    _mode = IN
+
+    # we want exceptions
+    lgpio.exceptions = True
+
+    def __init__(self, bcm_number):
+        self.id = bcm_number
+
+    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 mode is not None:
+            if mode == Pin.IN:
+                self._mode = Pin.IN
+                self._set_gpio_mode_in()
+            elif mode == self.OUT:
+                self._mode = Pin.OUT
+                Pin._check_result(lgpio.gpio_claim_output(CHIP, self.id, Pin.LOW))
+            else:
+                raise RuntimeError(f"Invalid mode for pin: {self.id}")
+        if pull is not None:
+            if self._mode != Pin.IN:
+                raise RuntimeError("Can only set pull resistor on input")
+            if pull in {Pin.PULL_UP, Pin.PULL_DOWN, Pin.PULL_NONE}:
+                self._set_gpio_mode_in(lflags=pull)
+            else:
+                raise RuntimeError(f"Invalid pull for pin: {self.id}")
+
+    def value(self, val=None):
+        """Set or return the Pin Value"""
+        if val is not None:
+            if val == Pin.LOW:
+                self._value = val
+                Pin._check_result(lgpio.gpio_write(CHIP, self.id, val))
+            elif val == Pin.HIGH:
+                self._value = val
+                Pin._check_result(lgpio.gpio_write(CHIP, self.id, val))
+            else:
+                raise RuntimeError("Invalid value for pin")
+            return None
+        return Pin._check_result(lgpio.gpio_read(CHIP, self.id))
+
+    @staticmethod
+    def _check_result(result):
+        """
+        convert any result other than zero to a text message and pass it back
+        as a runtime exception.  Typical usage:  use the lgpio call as the
+        argument.
+        """
+        if result < 0:
+            raise RuntimeError(lgpio.error_text(result))
+        return result
+
+    def _set_gpio_mode_in(self, lflags=0):
+        """
+        claim a gpio as input, or modify the flags (PULL_UP, PULL_DOWN, ... )
+        """
+        # This gpio_free may seem redundant, but is required when
+        #  changing the line-flags of an already acquired input line
+        try:
+            lgpio.gpio_free(CHIP, self.id)
+        except lgpio.error:
+            pass
+        Pin._check_result(lgpio.gpio_claim_input(CHIP, self.id, lFlags=lflags))
similarity index 98%
rename from src/adafruit_blinka/microcontroller/bcm283x/pwmio/PWMOut.py
rename to src/adafruit_blinka/microcontroller/generic_linux/lgpio_pwmout.py
index 3633cebd62d3cd87f4e0b774771459a32373ec7a..e4cf5a74fe2a07b6f2f848ef4be6f02c306df412 100644 (file)
@@ -5,7 +5,7 @@
 """ PWMOut Class for lgpio lg library tx_pwm library """
 
 import lgpio
-from adafruit_blinka.microcontroller.bcm283x.pin import CHIP
+from adafruit_blinka.microcontroller.generic_linux.lgpio_pin import CHIP
 
 
 class PWMError(IOError):
diff --git a/src/adafruit_blinka/microcontroller/generic_linux/rpi_gpio_pin.py b/src/adafruit_blinka/microcontroller/generic_linux/rpi_gpio_pin.py
new file mode 100644 (file)
index 0000000..cf3acbd
--- /dev/null
@@ -0,0 +1,69 @@
+# SPDX-FileCopyrightText: 2025 Melissa LeBlanc-Williams for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+"""A Pin class for use with Rpi.GPIO."""
+
+from RPi import GPIO
+
+GPIO.setmode(GPIO.BCM)  # Use BCM pins D4 = GPIO #4
+GPIO.setwarnings(False)  # shh!
+
+
+class Pin:
+    """Pins dont exist in CPython so...lets make our own!"""
+
+    IN = 0
+    OUT = 1
+    LOW = 0
+    HIGH = 1
+    PULL_NONE = 0
+    PULL_UP = 1
+    PULL_DOWN = 2
+
+    id = None
+    _value = LOW
+    _mode = IN
+
+    def __init__(self, bcm_number):
+        self.id = bcm_number
+
+    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 mode is not None:
+            if mode == self.IN:
+                self._mode = self.IN
+                GPIO.setup(self.id, GPIO.IN)
+            elif mode == self.OUT:
+                self._mode = self.OUT
+                GPIO.setup(self.id, GPIO.OUT)
+            else:
+                raise RuntimeError("Invalid mode for pin: %s" % self.id)
+        if pull is not None:
+            if self._mode != self.IN:
+                raise RuntimeError("Cannot set pull resistor on output")
+            if pull == self.PULL_UP:
+                GPIO.setup(self.id, GPIO.IN, pull_up_down=GPIO.PUD_UP)
+            elif pull == self.PULL_DOWN:
+                GPIO.setup(self.id, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
+            else:
+                raise RuntimeError("Invalid pull for pin: %s" % self.id)
+
+    def value(self, val=None):
+        """Set or return the Pin Value"""
+        if val is not None:
+            if val == self.LOW:
+                self._value = val
+                GPIO.output(self.id, val)
+            elif val == self.HIGH:
+                self._value = val
+                GPIO.output(self.id, val)
+            else:
+                raise RuntimeError("Invalid value for pin")
+            return None
+        return GPIO.input(self.id)
diff --git a/src/adafruit_blinka/microcontroller/generic_linux/rpi_gpio_pwmout.py b/src/adafruit_blinka/microcontroller/generic_linux/rpi_gpio_pwmout.py
new file mode 100644 (file)
index 0000000..3b7b57f
--- /dev/null
@@ -0,0 +1,165 @@
+# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
+#
+# SPDX-License-Identifier: MIT
+"""Custom PWMOut Wrapper for Rpi.GPIO PWM Class"""
+from RPi import GPIO
+
+GPIO.setmode(GPIO.BCM)  # Use BCM pins D4 = GPIO #4
+GPIO.setwarnings(False)  # shh!
+
+
+# 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._pwmpin = None
+        self._period = 0
+        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._pin = pin
+        GPIO.setup(pin.id, GPIO.OUT)
+        self._pwmpin = GPIO.PWM(pin.id, freq)
+
+        if variable_frequency:
+            print("Variable Frequency is not supported, continuing without it...")
+
+        # set frequency
+        self.frequency = freq
+        # set duty
+        self.duty_cycle = duty
+
+        self.enabled = True
+
+    def deinit(self):
+        """Deinit the PWM."""
+        if self._pwmpin is not None:
+            self._pwmpin.stop()
+            GPIO.cleanup(self._pin.id)
+            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))
+
+    @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.")
+
+        self._pwmpin.ChangeFrequency(round(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.start(round(self._duty_cycle * 100))
+        else:
+            self._pwmpin.stop()
+
+        self._enabled = value
+
+    # String representation
+    def __str__(self):
+        return "pin %s (freq=%f Hz, duty_cycle=%f%%)" % (
+            self._pin,
+            self.frequency,
+            self.duty_cycle,
+        )
index 5a85cc75268885143ede3423a19633c665b6e34d..c9fa46d530a2bcea00cd639e7fdb1d32fb838859 100644 (file)
@@ -41,7 +41,10 @@ elif board_id == ap_board.PYBOARD:
 elif board_id == ap_board.RASPBERRY_PI_PICO:
     from adafruit_blinka.board.raspberrypi.pico import *
 
-elif detector.board.any_raspberry_pi_4_board or detector.board.any_raspberry_pi_5_board:
+elif detector.board.any_raspberry_pi_5_board:
+    from adafruit_blinka.board.raspberrypi.raspi_5 import *
+
+elif detector.board.any_raspberry_pi_4_board:
     from adafruit_blinka.board.raspberrypi.raspi_4b import *
 
 elif detector.board.any_raspberry_pi_40_pin:
index 6f04984c0f7861b79f70bf4ea308efc3bbbea58a..c56f3497670b348d71d382aef162074e8cc54f70 100644 (file)
@@ -15,14 +15,10 @@ from adafruit_blinka.agnostic import board_id, detector
 
 # By Chip Class
 if detector.chip.BCM2XXX:
-    if board_id in (
-        "RASPBERRY_PI_4B",
-        "RASPBERRY_PI_400",
-        "RASPBERRY_PI_CM4",
-        "RASPBERRY_PI_CM4S",
-        "RASPBERRY_PI_5",
-    ):
-        from adafruit_blinka.microcontroller.bcm2711.pin import *
+    if detector.board.any_raspberry_pi_5_board:
+        from adafruit_blinka.microcontroller.bcm2712.pin import Pin
+    elif detector.board.any_raspberry_pi_4_board:
+        from adafruit_blinka.microcontroller.bcm2711.pin import Pin
     else:
         from adafruit_blinka.microcontroller.bcm283x.pin import Pin
 elif detector.chip.AM33XX:
index 3d4a560d56bd13570d4cb961c7d1fd227313b5ce..c461538d1497ea670412235c768cdc648715c3e4 100644 (file)
@@ -4,7 +4,7 @@
 """Pins named after their chip name."""
 import sys
 from adafruit_platformdetect.constants import chips as ap_chip, boards as ap_boards
-from adafruit_blinka.agnostic import board_id, chip_id
+from adafruit_blinka.agnostic import board_id, chip_id, detector
 
 # We intentionally are patching into this namespace so skip the wildcard check.
 # pylint: disable=unused-wildcard-import,wildcard-import,ungrouped-imports
@@ -16,13 +16,9 @@ elif chip_id == ap_chip.STM32F405:
 elif chip_id == ap_chip.RP2040:
     from adafruit_blinka.microcontroller.rp2040.pin import *
 elif chip_id == ap_chip.BCM2XXX:
-    if board_id in (
-        "RASPBERRY_PI_4B",
-        "RASPBERRY_PI_400",
-        "RASPBERRY_PI_CM4",
-        "RASPBERRY_PI_CM4S",
-        "RASPBERRY_PI_5",
-    ):
+    if detector.board.any_raspberry_pi_5_board:
+        from adafruit_blinka.microcontroller.bcm2712.pin import *
+    elif detector.board.any_raspberry_pi_4_board:
         from adafruit_blinka.microcontroller.bcm2711.pin import *
     else:
         from adafruit_blinka.microcontroller.bcm283x.pin import *
index 72ce0d896395fa2905678701538923ff822e7d8a..f6452f80529d3275272191053d2a39a729f13d5d 100644 (file)
@@ -16,8 +16,11 @@ from adafruit_blinka.agnostic import detector
 
 # pylint: disable=unused-import
 
-if detector.board.any_raspberry_pi:
-    from adafruit_blinka.microcontroller.bcm283x.pwmio.PWMOut import PWMOut
+if detector.board.any_raspberry_pi_5_board:
+    from adafruit_blinka.microcontroller.generic_linux.lgpio_pwmout import PWMOut
+elif detector.board.any_raspberry_pi:
+    # Pi 4 or lower
+    from adafruit_blinka.microcontroller.generic_linux.rpi_gpio_pwmout import PWMOut
 elif detector.board.any_bananapi:
     from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
 elif detector.board.any_coral_board: