Skip to content

Commit

Permalink
Added support for D-Robotics RDK-X3
Browse files Browse the repository at this point in the history
  • Loading branch information
hajimef committed Dec 1, 2024
1 parent b91d3fc commit b1dc072
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 0 deletions.
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
175 changes: 175 additions & 0 deletions src/adafruit_blinka/microcontroller/horizon/pwmio/PWMOut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
#
# SPDX-License-Identifier: MIT
"""Custom PWMOut Wrapper for Hobot.GPIO PWM Class"""
import Hobot.GPIO as 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,
)
59 changes: 59 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,59 @@
# 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

0 comments on commit b1dc072

Please sign in to comment.