]> Repositories - Adafruit_Blinka-hackapet.git/commitdiff
Merge pull request #429 from thomoray/add-rockpi4c-support 6.4.0
authorMelissa LeBlanc-Williams <melissa@adafruit.com>
Tue, 9 Mar 2021 18:19:34 +0000 (10:19 -0800)
committerGitHub <noreply@github.com>
Tue, 9 Mar 2021 18:19:34 +0000 (10:19 -0800)
Add rockpi4c support

src/adafruit_blinka/board/radxa/rockpi4.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/rockchip/PWMOut.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/rockchip/rk3399/__init__.py [new file with mode: 0644]
src/adafruit_blinka/microcontroller/rockchip/rk3399/pin.py [new file with mode: 0644]
src/analogio.py
src/board.py
src/busio.py
src/digitalio.py
src/microcontroller/__init__.py
src/microcontroller/pin.py
src/pwmio.py

diff --git a/src/adafruit_blinka/board/radxa/rockpi4.py b/src/adafruit_blinka/board/radxa/rockpi4.py
new file mode 100644 (file)
index 0000000..e327ff3
--- /dev/null
@@ -0,0 +1,62 @@
+"""Pin definitions for the Rock Pi 4."""
+
+from adafruit_blinka.microcontroller.rockchip.rk3399 import pin
+
+D3 = pin.GPIO2_A7  # /I2C7_SDA/PIN 71/
+D5 = pin.GPIO2_B0  # /I2C7_SCL/PIN 72/
+D7 = pin.GPIO2_B3  # /SPI2_CLK/PIN 75/
+D8 = pin.GPIO4_C4  # /UART2_TXD/PIN 148/
+D10 = pin.GPIO4_C3  # /UART2_RXD/PIN 147/
+D11 = pin.GPIO4_C2  # /PWM0/PIN 146/
+D13 = pin.GPIO4_C6  # /PWM1/PIN 150/
+D15 = pin.GPIO4_C5  # /SPDIF_TX/PIN 149/
+D16 = pin.GPIO4_D2  # /PIN 154/
+D17 = pin.GPIO4_D4  # /PIN 156/
+D19 = pin.GPIO1_B0  # /UART4_TXD/SPI1_TXD/PIN 40/
+D21 = pin.GPIO1_A7  # /UART4_RXD/SPI1_RXD/PIN 39/
+D22 = pin.GPIO4_D5  # /PIN 157/
+D23 = pin.GPIO1_B1  # /SPI1_CLK/PIN 41/
+D24 = pin.GPIO1_B2  # /SPI1_CS/PIN 42/
+D27 = pin.GPIO2_A0  # /I2C2_SDA/PIN 64/
+D28 = pin.GPIO2_A1  # /I2C2_SCL/PIN 65/
+D29 = pin.GPIO2_B2  # /I2C6_SCL/SPI2_TXD/PIN 74/
+D31 = pin.GPIO2_B1  # /I2C6_SDA/SPI2_RXD/PIN 73/
+D32 = pin.GPIO3_C0  # /SPDIF_TX/UART3_CTS/PIN 112/
+D33 = pin.GPIO2_B4  # /SPI2_CS/PIN 76/
+D35 = pin.GPIO4_A5  # /I2S1_LRCK_TX/PIN 133/
+D36 = pin.GPIO4_A4  # /I2S1_LRCK_RX/PIN 132/
+D37 = pin.GPIO4_D6  # /PIN 158/
+D38 = pin.GPIO4_A6  # /I2S1_SDI/PIN 134/
+D40 = pin.GPIO4_A7  # /I2S1_SDO/PIN 135/
+
+SDA2 = D27
+SCL2 = D28
+
+SDA6 = D31
+SCL6 = D29
+
+SDA7 = D3
+SCL7 = D5
+
+SDA = SDA2
+SCL = SCL2
+
+SCLK = D7
+MOSI = D29
+MISO = D31
+CS = D33
+SCK = SCLK
+
+UART2_TX = D8
+UART2_RX = D10
+
+UART4_TX = D19
+UART4_RX = D21
+
+UART_TX = UART2_TX
+UART_RX = UART2_RX
+
+PWM0 = pin.PWM0
+PWM1 = pin.PWM1
+
+ADC_IN0 = pin.ADC_IN0
diff --git a/src/adafruit_blinka/microcontroller/rockchip/PWMOut.py b/src/adafruit_blinka/microcontroller/rockchip/PWMOut.py
new file mode 100644 (file)
index 0000000..09c4a8e
--- /dev/null
@@ -0,0 +1,392 @@
+"""
+Much code from https://github.com/vsergeev/python-periphery/blob/master/periphery/pwm.py
+Copyright (c) 2015-2016 vsergeev / Ivan (Vanya) A. Sergeev
+License: MIT
+"""
+
+import os
+from time import sleep
+from errno import EACCES
+
+try:
+    from microcontroller.pin import pwmOuts
+except ImportError:
+    raise RuntimeError("No PWM outputs defined for this board.") from ImportError
+
+
+# pylint: disable=unnecessary-pass, too-many-instance-attributes
+
+
+class PWMError(IOError):
+    """Base class for PWM errors."""
+
+    pass
+
+
+# pylint: enable=unnecessary-pass
+
+
+class PWMOut:
+    """Pulse Width Modulation Output Class"""
+
+    # Number of retries to check for successful PWM export on open
+    PWM_STAT_RETRIES = 10
+    # Delay between check for successful PWM export on open (100ms)
+    PWM_STAT_DELAY = 0.1
+
+    # Sysfs paths
+    _chip_path = "pwmchip{}"
+    _channel_path = "pwm{}"
+
+    def __init__(self, pwm, *, frequency=500, duty_cycle=0, variable_frequency=False):
+        """Instantiate a PWM object and open the sysfs PWM corresponding to the
+        specified chip and channel.
+        Args:
+            pwm (str): PWM pin.
+            frequency (int, float): target frequency in Hertz (32-bit).
+            duty_cycle (int, float): The fraction of each pulse which is high (16-bit).
+            variable_frequency (bool): True if the frequency will change over time.
+        Returns:
+            PWM: PWM object.
+        Raises:
+            PWMError: if an I/O or OS error occurs.
+            TypeError: if `chip` or `channel` types are invalid.
+            LookupError: if PWM chip does not exist.
+            TimeoutError: if waiting for PWM export times out.
+        """
+
+        self._chip = None
+        self._channel = None
+        self._period_ns = 0
+        self._open(pwm, frequency, duty_cycle, variable_frequency)
+
+    def __del__(self):
+        self.close()
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        self.close()
+
+    def _open(self, pwm, frequency, duty_cycle, variable_frequency):
+        for pwmout in pwmOuts:
+            if pwmout[1] == pwm:
+                self._chip = pwmout[0][0]
+                self._channel = pwmout[0][1]
+
+        self._chip_path = os.path.join(
+            "/sys/class/pwm", self._chip_path.format(self._chip)
+        )
+        self._channel_path = os.path.join(
+            self._chip_path, self._channel_path.format(self._channel)
+        )
+
+        if variable_frequency:
+            print("Variable Frequency is not supported, continuing without it...")
+
+        if not os.path.isdir(self._chip_path):
+            raise LookupError("Opening PWM: PWM chip {} not found.".format(self._chip))
+
+        if not os.path.isdir(self._channel_path):
+            # Exporting the PWM.
+            try:
+                with open(os.path.join(self._chip_path, "export"), "w") as f_export:
+                    f_export.write("{:d}\n".format(self._channel))
+            except IOError as e:
+                raise PWMError(
+                    e.errno, "Exporting PWM channel: " + e.strerror
+                ) from IOError
+
+            # Loop until PWM is exported
+            exported = False
+            for i in range(PWMOut.PWM_STAT_RETRIES):
+                if os.path.isdir(self._channel_path):
+                    exported = True
+                    break
+
+                sleep(PWMOut.PWM_STAT_DELAY)
+
+            if not exported:
+                raise TimeoutError(
+                    'Exporting PWM: waiting for "{:s}" timed out.'.format(
+                        self._channel_path
+                    )
+                )
+
+            # Loop until 'period' is writable, This could take some time after
+            # export as application of the udev rules after export is asynchronous.
+            # Without this loop, the following properties may not be writable yet.
+            for i in range(PWMOut.PWM_STAT_RETRIES):
+                try:
+                    with open(
+                        os.path.join(self._channel_path, "period"),
+                        "w",
+                    ):
+                        break
+                except IOError as e:
+                    if e.errno != EACCES or (
+                        e.errno == EACCES and i == PWMOut.PWM_STAT_RETRIES - 1
+                    ):
+                        raise PWMError(
+                            e.errno, "Opening PWM period: " + e.strerror
+                        ) from IOError
+
+                sleep(PWMOut.PWM_STAT_DELAY)
+
+            self.frequency = frequency
+            self.duty_cycle = duty_cycle
+
+            # Cache the period for fast duty cycle updates
+            self._period_ns = self._get_period_ns()
+
+    def close(self):
+        """Close the PWM."""
+        if self._channel is not None:
+            # Unexporting the PWM channel
+            try:
+                unexport_fd = os.open(
+                    os.path.join(self._chip_path, "unexport"), os.O_WRONLY
+                )
+                os.write(unexport_fd, "{:d}\n".format(self._channel).encode())
+                os.close(unexport_fd)
+            except OSError as e:
+                raise PWMError(e.errno, "Unexporting PWM: " + e.strerror) from OSError
+
+        self._chip = None
+        self._channel = None
+
+    def _write_channel_attr(self, attr, value):
+        with open(os.path.join(self._channel_path, attr), "w") as f_attr:
+            f_attr.write(value + "\n")
+
+    def _read_channel_attr(self, attr):
+        with open(os.path.join(self._channel_path, attr), "r") as f_attr:
+            return f_attr.read().strip()
+
+    # Methods
+
+    def enable(self):
+        """Enable the PWM output."""
+        self.enabled = True
+
+    def disable(self):
+        """Disable the PWM output."""
+        self.enabled = False
+
+    # Mutable properties
+
+    def _get_period(self):
+        return float(self.period_ms) / 1000
+
+    def _set_period(self, period):
+        if not isinstance(period, (int, float)):
+            raise TypeError("Invalid period type, should be int.")
+
+        self.period_ms = int(period * 1000)
+
+    period = property(_get_period, _set_period)
+    """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.
+
+    :type: int, float
+    """
+
+    def _get_period_ms(self):
+        return self.period_us / 1000
+
+    def _set_period_ms(self, period_ms):
+        if not isinstance(period_ms, (int, float)):
+            raise TypeError("Invalid period type, should be int or float.")
+        self.period_us = int(period_ms * 1000)
+
+    period_ms = property(_get_period_ms, _set_period_ms)
+    """Get or set the PWM's output period in milliseconds.
+
+    Raises:
+        PWMError: if an I/O or OS error occurs.
+        TypeError: if value type is not int.
+
+    :type: int, float
+    """
+
+    def _get_period_us(self):
+        return self.period_ns / 1000
+
+    def _set_period_us(self, period_us):
+        if not isinstance(period_us, int):
+            raise TypeError("Invalid period type, should be int.")
+
+        self.period_ns = int(period_us * 1000)
+
+    period_us = property(_get_period_us, _set_period_us)
+    """Get or set the PWM's output period in microseconds.
+
+    Raises:
+        PWMError: if an I/O or OS error occurs.
+        TypeError: if value type is not int.
+
+    :type: int
+    """
+
+    def _get_period_ns(self):
+        period_ns = self._read_channel_attr("period")
+        try:
+            period_ns = int(period_ns)
+        except ValueError:
+            raise PWMError(
+                None, 'Unknown period value: "%s".' % period_ns
+            ) from ValueError
+
+        self._period_ns = period_ns
+
+        return period_ns
+
+    def _set_period_ns(self, period_ns):
+        if not isinstance(period_ns, int):
+            raise TypeError("Invalid period type, should be int.")
+
+        self._write_channel_attr("period", str(period_ns))
+
+        # Update our cached period
+        self._period_ns = period_ns
+
+    period_ns = property(_get_period_ns, _set_period_ns)
+    """Get or set the PWM's output period in nanoseconds.
+
+    Raises:
+        PWMError: if an I/O or OS error occurs.
+        TypeError: if value type is not int.
+
+    :type: int
+    """
+
+    def _get_duty_cycle_ns(self):
+        duty_cycle_ns_str = self._read_channel_attr("duty_cycle")
+
+        try:
+            duty_cycle_ns = int(duty_cycle_ns_str)
+        except ValueError:
+            raise PWMError(
+                None, 'Unknown duty cycle value: "{:s}"'.format(duty_cycle_ns_str)
+            ) from ValueError
+
+        return duty_cycle_ns
+
+    def _set_duty_cycle_ns(self, duty_cycle_ns):
+        if not isinstance(duty_cycle_ns, int):
+            raise TypeError("Invalid duty cycle type, should be int.")
+
+        self._write_channel_attr("duty_cycle", str(duty_cycle_ns))
+
+    duty_cycle_ns = property(_get_duty_cycle_ns, _set_duty_cycle_ns)
+    """Get or set the PWM's output duty cycle in nanoseconds.
+
+    Raises:
+        PWMError: if an I/O or OS error occurs.
+        TypeError: if value type is not int.
+
+    :type: int
+    """
+
+    def _get_duty_cycle(self):
+        return float(self.duty_cycle_ns) / self._period_ns
+
+    def _set_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.0 <= duty_cycle <= 1.0:
+            raise ValueError("Invalid duty cycle value, should be between 0.0 and 1.0.")
+
+        # Convert duty cycle from ratio to nanoseconds
+        self.duty_cycle_ns = int(duty_cycle * self._period_ns)
+
+    duty_cycle = property(_get_duty_cycle, _set_duty_cycle)
+    """Get or set the PWM's output duty cycle as a ratio from 0.0 to 1.0.
+    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
+    """
+
+    def _get_frequency(self):
+        return 1.0 / self.period
+
+    def _set_frequency(self, frequency):
+        if not isinstance(frequency, (int, float)):
+            raise TypeError("Invalid frequency type, should be int or float.")
+
+        self.period = 1.0 / frequency
+
+    frequency = property(_get_frequency, _set_frequency)
+    """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
+    """
+
+    def _get_polarity(self):
+        return self._read_channel_attr("polarity")
+
+    def _set_polarity(self, polarity):
+        if not isinstance(polarity, str):
+            raise TypeError("Invalid polarity type, should be str.")
+
+        if polarity.lower() not in ["normal", "inversed"]:
+            raise ValueError('Invalid polarity, can be: "normal" or "inversed".')
+
+        self._write_channel_attr("polarity", polarity.lower())
+
+    polarity = property(_get_polarity, _set_polarity)
+    """Get or set the PWM's output polarity. Can be "normal" or "inversed".
+    Raises:
+        PWMError: if an I/O or OS error occurs.
+        TypeError: if value type is not str.
+        ValueError: if value is invalid.
+    :type: str
+    """
+
+    def _get_enabled(self):
+        enabled = self._read_channel_attr("enable")
+
+        if enabled == "1":
+            return True
+        if enabled == "0":
+            return False
+
+        raise PWMError(None, 'Unknown enabled value: "{:s}"'.format(enabled))
+
+    def _set_enabled(self, value):
+        if not isinstance(value, bool):
+            raise TypeError("Invalid enabled type, should be bool.")
+
+        self._write_channel_attr("enable", "1" if value else "0")
+
+    enabled = property(_get_enabled, _set_enabled)
+    """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
+    """
+
+    # String representation
+
+    def __str__(self):
+        return (
+            "PWM {:d}, chip {:d} (period={:f} sec, duty_cycle={:f}%,"
+            " polarity={:s}, enabled={:s})".format(
+                self._channel,
+                self._chip,
+                self.period,
+                self.duty_cycle * 100,
+                self.polarity,
+                str(self.enabled),
+            )
+        )
diff --git a/src/adafruit_blinka/microcontroller/rockchip/rk3399/__init__.py b/src/adafruit_blinka/microcontroller/rockchip/rk3399/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/adafruit_blinka/microcontroller/rockchip/rk3399/pin.py b/src/adafruit_blinka/microcontroller/rockchip/rk3399/pin.py
new file mode 100644 (file)
index 0000000..4419861
--- /dev/null
@@ -0,0 +1,77 @@
+"""A Pin class for use with Rockchip RK3399."""
+
+from adafruit_blinka.microcontroller.generic_linux.sysfs_pin import Pin
+
+GPIO1_A7 = Pin(39)
+GPIO1_B0 = Pin(40)
+GPIO1_B1 = Pin(41)
+GPIO1_B2 = Pin(42)
+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)
+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_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)
+ADC_IN0 = 1
+
+# I2C
+I2C2_SDA = GPIO2_A0
+I2C2_SCL = GPIO2_A1
+I2C6_SDA = GPIO2_B1
+I2C6_SCL = GPIO2_B2
+I2C7_SDA = GPIO2_A7
+I2C7_SCL = GPIO2_B0
+
+# SPI
+SPI1_CS = GPIO1_B2
+SPI1_SCLK = GPIO1_B1
+SPI1_MISO = GPIO1_B0
+SPI1_MOSI = GPIO1_A7
+SPI2_CS = GPIO2_B4
+SPI2_SCLK = GPIO2_A1
+SPI2_MISO = GPIO2_B1
+SPI2_MOSI = GPIO2_B2
+
+# UART
+UART0_TX = GPIO4_C4
+UART0_RX = GPIO4_C3
+
+# PWM
+PWM0 = GPIO4_C2
+PWM1 = GPIO4_C6
+
+# ordered as i2cId, SCL, SDA
+i2cPorts = (
+    (0, I2C2_SCL, I2C2_SDA),
+    (1, I2C6_SCL, I2C6_SDA),
+    (7, I2C7_SCL, I2C7_SDA),
+)
+
+# ordered as spiId, sckId, mosiId, misoId
+spiPorts = ((1, SPI1_SCLK, SPI1_MOSI, SPI1_MISO),)
+
+# SysFS pwm outputs, pwm channel and pin in first tuple
+pwmOuts = (
+    ((0, 0), PWM0),
+    ((1, 0), PWM1),
+)
+
+# SysFS analog inputs, Ordered as analog analogInId, device, and channel
+analogIns = ((ADC_IN0, 0, 0),)
index 8ca58c1c71c0c323aa1c4d6913f6487e5c15be0a..1db939a3fd93465d4f88cb75bf5ae1c4bc190ef2 100644 (file)
@@ -21,6 +21,8 @@ elif detector.board.greatfet_one:
     from adafruit_blinka.microcontroller.nxp_lpc4330.analogio import AnalogOut
 elif detector.chip.RK3308:
     from adafruit_blinka.microcontroller.generic_linux.sysfs_analogin import AnalogIn
+elif detector.chip.RK3399:
+    from adafruit_blinka.microcontroller.generic_linux.sysfs_analogin import AnalogIn
 elif detector.chip.IMX6ULL:
     from adafruit_blinka.microcontroller.generic_linux.sysfs_analogin import AnalogIn
 elif "sphinx" in sys.modules:
index cf2076a307e42feaf05af241cf244ec7b907158b..e4909f243c3304754d9c19b84c346e29113aa8d9 100755 (executable)
@@ -191,6 +191,9 @@ elif board_id == ap_board.ONION_OMEGA2:
 elif board_id == ap_board.ROCK_PI_S:
     from adafruit_blinka.board.radxa.rockpis import *
 
+elif board_id == ap_board.ROCK_PI_4:
+    from adafruit_blinka.board.radxa.rockpi4 import *
+
 elif board_id == ap_board.UDOO_X86:
     from adafruit_blinka.board.udoo_x86ultra import *
 
index d4613a3620d5a77ee83a886e61502c42b85eb20d..67494592e6592ea7928289fe94f93e726e47f02c 100755 (executable)
@@ -254,6 +254,9 @@ class SPI(Lockable):
         elif detector.board.ROCK_PI_S:
             from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
             from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
+        elif detector.board.ROCK_PI_4:
+            from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
+            from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
         elif detector.board.SIFIVE_UNLEASHED:
             from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI
             from adafruit_blinka.microcontroller.hfu540.pin import Pin
index 08d154967f2a456accfdb622c7cc9b08015f71d0..a59866b9a74eb10270f775983156f22da5ae9a73 100755 (executable)
@@ -51,6 +51,8 @@ elif detector.chip.MIPS24KEC:
     from adafruit_blinka.microcontroller.mips24kec.pin import Pin
 elif detector.chip.RK3308:
     from adafruit_blinka.microcontroller.rockchip.rk3308.pin import Pin
+elif detector.chip.RK3399:
+    from adafruit_blinka.microcontroller.rockchip.rk3399.pin import Pin
 elif detector.board.ftdi_ft232h:
     from adafruit_blinka.microcontroller.ft232h.pin import Pin
 elif detector.board.binho_nova:
index a5b3b75c4dea47f24eaab3397d96738662ae4f9d..abd5a10a5db7bb5ea57c0856bf47a153a11e77d4 100755 (executable)
@@ -75,6 +75,8 @@ elif chip_id == ap_chip.A33:
     from adafruit_blinka.microcontroller.allwinner.a33.pin import *
 elif chip_id == ap_chip.RK3308:
     from adafruit_blinka.microcontroller.rockchip.rk3308.pin import *
+elif chip_id == ap_chip.RK3399:
+    from adafruit_blinka.microcontroller.rockchip.rk3399.pin import *
 elif chip_id == ap_chip.H5:
     from adafruit_blinka.microcontroller.allwinner.h5.pin import *
 elif chip_id == ap_chip.IMX8MX:
index 4ac63dd15b9deb192ab1dcf01680c19920969805..f83162f8ac05f8913c22fad6aadbee2f5ea187a6 100755 (executable)
@@ -56,6 +56,8 @@ elif chip_id == ap_chip.A33:
     from adafruit_blinka.microcontroller.allwinner.a33.pin import *
 elif chip_id == ap_chip.RK3308:
     from adafruit_blinka.microcontroller.rockchip.rk3308.pin import *
+elif chip_id == ap_chip.RK3399:
+    from adafruit_blinka.microcontroller.rockchip.rk3399.pin import *
 elif chip_id == ap_chip.MIPS24KC:
     from adafruit_blinka.microcontroller.atheros.ar9331.pin import *
 elif chip_id == ap_chip.MIPS24KEC:
index 05263c2a3e9a04cc5ae143c0be8b1d80f8a30266..3a6b5bdc01e7a7d4291f9d55fe8a405302b82b35 100644 (file)
@@ -22,7 +22,7 @@ elif detector.board.any_giant_board:
 elif detector.board.any_beaglebone:
     from adafruit_blinka.microcontroller.am335x.sysfs_pwmout import PWMOut
 elif detector.board.any_rock_pi_board:
-    from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
+    from adafruit_blinka.microcontroller.rockchip.PWMOut import PWMOut
 elif detector.board.binho_nova:
     from adafruit_blinka.microcontroller.nova.pwmout import PWMOut
 elif detector.board.greatfet_one: