Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for D-Robotics RDK-X3 #914

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/adafruit_blinka/board/horizon/rdkx3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
#
# SPDX-License-Identifier: MIT
"""Pin definitions for RDK-X3."""

from adafruit_blinka.microcontroller.horizon.sunrise_x3 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
D20 = pin.D20
D21 = pin.D21
D22 = pin.D22
D23 = pin.D23
D24 = pin.D24
D25 = pin.D25
D26 = pin.D26
D27 = pin.D27
174 changes: 174 additions & 0 deletions src/adafruit_blinka/microcontroller/horizon/pwmio/PWMOut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
#
# SPDX-License-Identifier: MIT
"""Custom PWMOut Wrapper for Hobot.GPIO PWM Class"""
from Hobot import GPIO

GPIO.setmode(GPIO.BCM) # Use BCM pins D4 = GPIO #4
GPIO.setwarnings(False) # shh!
GPIO.cleanup()


# 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=48000, 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):
if pin == (0, 25):
gpio_pin = 12
elif pin == (0, 4):
gpio_pin = 13
else:
raise ValueError("PWM is only available on D12 or D13.")
self._pin = gpio_pin
GPIO.setmode(GPIO.BCM)
# GPIO.setup(self._pin, GPIO.OUT)
self._pwmpin = GPIO.PWM(self._pin, freq)

if variable_frequency:
print("Variable Frequency is not supported, continuing without it...")

# set frequency
self.frequency = freq
# set duty
duty = 656 if duty <= 656 else 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)
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,
)
55 changes: 55 additions & 0 deletions src/adafruit_blinka/microcontroller/horizon/sunrise_x3/pin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
#
# SPDX-License-Identifier: MIT
"""A Pin class for use with Horizon Sunrise X3."""

from adafruit_blinka.microcontroller.generic_linux.libgpiod_pin import Pin

D0 = Pin((0, 15))
D1 = Pin((0, 14))
D2 = Pin((0, 9))
D3 = Pin((0, 8))
D4 = Pin((0, 101))
D5 = Pin((0, 119))
D6 = Pin((0, 118))
D7 = Pin((0, 28))
D8 = Pin((0, 5))
D9 = Pin((0, 7))
D10 = Pin((0, 6))
D11 = Pin((0, 3))
D12 = Pin((0, 25))
D13 = Pin((0, 4))
D14 = Pin((0, 111))
D15 = Pin((0, 112))
D16 = Pin((0, 20))
D17 = Pin((0, 12))
D18 = Pin((0, 102))
D19 = Pin((0, 103))
D20 = Pin((0, 104))
D21 = Pin((0, 108))
D22 = Pin((0, 30))
D23 = Pin((0, 27))
D24 = Pin((0, 22))
D25 = Pin((0, 29))
D26 = Pin((0, 117))
D27 = Pin((0, 13))

SDA = D2
SCL = D3
MISO = D9
MOSI = D10
SCLK = D11
SCK = D11
TXD = D14
RXD = D15

spiPorts = ((1, SCLK, MOSI, MISO),)

uartPorts = ((0, TXD, RXD),)

i2cPorts = ((0, SCL, SDA),)

pwmOuts = (
((0, 0), D12),
((3, 0), D13),
)
3 changes: 3 additions & 0 deletions src/board.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,9 @@
elif board_id == ap_board.INDIEDROID_NOVA:
from adafruit_blinka.board.ameridroid.indiedroid_nova import *

elif board_id == ap_board.RDK_X3:
from adafruit_blinka.board.horizon.rdkx3 import *

elif "sphinx" in sys.modules:
pass

Expand Down
2 changes: 2 additions & 0 deletions src/digitalio.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@
from adafruit_blinka.microcontroller.thead.th1520.pin import Pin
elif detector.chip.K1:
from adafruit_blinka.microcontroller.spacemit.k1.pin import Pin
elif detector.chip.SUNRISE_X3:
from adafruit_blinka.microcontroller.horizon.sunrise_x3.pin import Pin
# Special Case Boards
elif detector.board.ftdi_ft232h:
from adafruit_blinka.microcontroller.ftdi_mpsse.ft232h.pin import Pin
Expand Down
2 changes: 2 additions & 0 deletions src/microcontroller/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ def delay_us(delay):
from adafruit_blinka.microcontroller.thead.th1520 import *
elif chip_id == ap_chip.K1:
from adafruit_blinka.microcontroller.spacemit.k1 import *
elif chip_id == ap_chip.SUNRISE_X3:
from adafruit_blinka.microcontroller.horizon.sunrise_x3 import *
elif chip_id == ap_chip.GENERIC_X86:
print("WARNING: GENERIC_X86 is not fully supported. Some features may not work.")
elif chip_id == ap_chip.OS_AGNOSTIC:
Expand Down
2 changes: 2 additions & 0 deletions src/microcontroller/pin.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@
from adafruit_blinka.microcontroller.rockchip.rv1103.pin import *
elif chip_id == ap_chip.RV1106:
from adafruit_blinka.microcontroller.rockchip.rv1106.pin import *
elif chip_id == ap_chip.SUNRISE_X3:
from adafruit_blinka.microcontroller.horizon.sunrise_x3.pin import *
elif "sphinx" in sys.modules:
# pylint: disable=unused-import
from adafruit_blinka.microcontroller.generic_micropython import Pin
Expand Down
2 changes: 2 additions & 0 deletions src/pwmio.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
elif detector.board.any_starfive_id:
from adafruit_blinka.microcontroller.starfive.JH7110.pwmio import PWMOut
elif detector.board.any_horizon_board:
from adafruit_blinka.microcontroller.horizon.pwmio.PWMOut import PWMOut
elif detector.board.OS_AGNOSTIC_BOARD:
from adafruit_blinka.microcontroller.generic_agnostic_board.PWMOut import PWMOut
elif (
Expand Down
Loading