Skip to content

Commit b1dc072

Browse files
committed
Added support for D-Robotics RDK-X3
1 parent b91d3fc commit b1dc072

File tree

8 files changed

+299
-0
lines changed

8 files changed

+299
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""Pin definitions for RDK-X3."""
5+
6+
from adafruit_blinka.microcontroller.horizon.sunrise_x3 import pin
7+
8+
D0 = pin.D0
9+
D1 = pin.D1
10+
11+
D2 = pin.D2
12+
SDA = pin.SDA
13+
D3 = pin.D3
14+
SCL = pin.SCL
15+
16+
D4 = pin.D4
17+
D5 = pin.D5
18+
D6 = pin.D6
19+
20+
D7 = pin.D7
21+
CE1 = pin.D7
22+
D8 = pin.D8
23+
CE0 = pin.D8
24+
D9 = pin.D9
25+
MISO = pin.D9
26+
D10 = pin.D10
27+
MOSI = pin.D10
28+
D11 = pin.D11
29+
SCLK = pin.D11
30+
SCK = pin.D11
31+
32+
D12 = pin.D12
33+
D13 = pin.D13
34+
35+
D14 = pin.D14
36+
TXD = pin.D14
37+
D15 = pin.D15
38+
RXD = pin.D15
39+
# create alias for most of the examples
40+
TX = pin.D14
41+
RX = pin.D15
42+
43+
D16 = pin.D16
44+
D17 = pin.D17
45+
D18 = pin.D18
46+
D19 = pin.D19
47+
D20 = pin.D20
48+
D21 = pin.D21
49+
D22 = pin.D22
50+
D23 = pin.D23
51+
D24 = pin.D24
52+
D25 = pin.D25
53+
D26 = pin.D26
54+
D27 = pin.D27
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""Custom PWMOut Wrapper for Hobot.GPIO PWM Class"""
5+
import Hobot.GPIO as GPIO
6+
7+
GPIO.setmode(GPIO.BCM) # Use BCM pins D4 = GPIO #4
8+
GPIO.setwarnings(False) # shh!
9+
GPIO.cleanup()
10+
11+
# pylint: disable=unnecessary-pass
12+
class PWMError(IOError):
13+
"""Base class for PWM errors."""
14+
15+
pass
16+
17+
18+
# pylint: enable=unnecessary-pass
19+
20+
21+
class PWMOut:
22+
"""Pulse Width Modulation Output Class"""
23+
24+
def __init__(self, pin, *, frequency=48000, duty_cycle=0, variable_frequency=False):
25+
self._pwmpin = None
26+
self._period = 0
27+
self._open(pin, duty_cycle, frequency, variable_frequency)
28+
29+
def __del__(self):
30+
self.deinit()
31+
32+
def __enter__(self):
33+
return self
34+
35+
def __exit__(self, t, value, traceback):
36+
self.deinit()
37+
38+
def _open(self, pin, duty=0, freq=500, variable_frequency=False):
39+
if (pin == (0, 25)):
40+
gpio_pin = 12
41+
elif (pin == (0, 4)):
42+
gpio_pin = 13
43+
else:
44+
raise ValueError(
45+
"PWM is only available on D12 or D13."
46+
)
47+
self._pin = gpio_pin
48+
GPIO.setmode(GPIO.BCM)
49+
# GPIO.setup(self._pin, GPIO.OUT)
50+
self._pwmpin = GPIO.PWM(self._pin, freq)
51+
52+
if variable_frequency:
53+
print("Variable Frequency is not supported, continuing without it...")
54+
55+
# set frequency
56+
self.frequency = freq
57+
# set duty
58+
duty = 656 if duty <= 656 else duty
59+
self.duty_cycle = duty
60+
61+
self.enabled = True
62+
63+
def deinit(self):
64+
"""Deinit the PWM."""
65+
if self._pwmpin is not None:
66+
self._pwmpin.stop()
67+
GPIO.cleanup(self._pin)
68+
self._pwmpin = None
69+
70+
def _is_deinited(self):
71+
if self._pwmpin is None:
72+
raise ValueError(
73+
"Object has been deinitialize and can no longer "
74+
"be used. Create a new object."
75+
)
76+
77+
@property
78+
def period(self):
79+
"""Get or set the PWM's output period in seconds.
80+
81+
Raises:
82+
PWMError: if an I/O or OS error occurs.
83+
TypeError: if value type is not int or float.
84+
85+
:type: int, float
86+
"""
87+
return 1.0 / self.frequency
88+
89+
@period.setter
90+
def period(self, period):
91+
if not isinstance(period, (int, float)):
92+
raise TypeError("Invalid period type, should be int or float.")
93+
94+
self.frequency = 1.0 / period
95+
96+
@property
97+
def duty_cycle(self):
98+
"""Get or set the PWM's output duty cycle which is the fraction of
99+
each pulse which is high. 16-bit
100+
101+
Raises:
102+
PWMError: if an I/O or OS error occurs.
103+
TypeError: if value type is not int or float.
104+
ValueError: if value is out of bounds of 0.0 to 1.0.
105+
106+
:type: int, float
107+
"""
108+
return int(self._duty_cycle * 65535)
109+
110+
@duty_cycle.setter
111+
def duty_cycle(self, duty_cycle):
112+
if not isinstance(duty_cycle, (int, float)):
113+
raise TypeError("Invalid duty cycle type, should be int or float.")
114+
115+
if not 0 <= duty_cycle <= 65535:
116+
raise ValueError("Invalid duty cycle value, should be between 0 and 65535")
117+
118+
# convert from 16-bit
119+
duty_cycle /= 65535.0
120+
121+
self._duty_cycle = duty_cycle
122+
self._pwmpin.ChangeDutyCycle(round(self._duty_cycle * 100))
123+
124+
@property
125+
def frequency(self):
126+
"""Get or set the PWM's output frequency in Hertz.
127+
128+
Raises:
129+
PWMError: if an I/O or OS error occurs.
130+
TypeError: if value type is not int or float.
131+
132+
:type: int, float
133+
"""
134+
135+
return self._frequency
136+
137+
@frequency.setter
138+
def frequency(self, frequency):
139+
if not isinstance(frequency, (int, float)):
140+
raise TypeError("Invalid frequency type, should be int or float.")
141+
142+
self._pwmpin.ChangeFrequency(round(frequency))
143+
self._frequency = frequency
144+
145+
@property
146+
def enabled(self):
147+
"""Get or set the PWM's output enabled state.
148+
149+
Raises:
150+
PWMError: if an I/O or OS error occurs.
151+
TypeError: if value type is not bool.
152+
153+
:type: bool
154+
"""
155+
return self._enabled
156+
157+
@enabled.setter
158+
def enabled(self, value):
159+
if not isinstance(value, bool):
160+
raise TypeError("Invalid enabled type, should be string.")
161+
162+
if value:
163+
self._pwmpin.start(round(self._duty_cycle * 100))
164+
else:
165+
self._pwmpin.stop()
166+
167+
self._enabled = value
168+
169+
# String representation
170+
def __str__(self):
171+
return "pin %s (freq=%f Hz, duty_cycle=%f%%)" % (
172+
self._pin,
173+
self.frequency,
174+
self.duty_cycle,
175+
)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# SPDX-FileCopyrightText: 2024 Hajime Fujimoto
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""A Pin class for use with Horizon Sunrise X3."""
5+
6+
from adafruit_blinka.microcontroller.generic_linux.libgpiod_pin import Pin
7+
8+
D0 = Pin((0, 15))
9+
D1 = Pin((0, 14))
10+
D2 = Pin((0, 9))
11+
D3 = Pin((0, 8))
12+
D4 = Pin((0, 101))
13+
D5 = Pin((0, 119))
14+
D6 = Pin((0, 118))
15+
D7 = Pin((0, 28))
16+
D8 = Pin((0, 5))
17+
D9 = Pin((0, 7))
18+
D10 = Pin((0, 6))
19+
D11 = Pin((0, 3))
20+
D12 = Pin((0, 25))
21+
D13 = Pin((0, 4))
22+
D14 = Pin((0, 111))
23+
D15 = Pin((0, 112))
24+
D16 = Pin((0, 20))
25+
D17 = Pin((0, 12))
26+
D18 = Pin((0, 102))
27+
D19 = Pin((0, 103))
28+
D20 = Pin((0, 104))
29+
D21 = Pin((0, 108))
30+
D22 = Pin((0, 30))
31+
D23 = Pin((0, 27))
32+
D24 = Pin((0, 22))
33+
D25 = Pin((0, 29))
34+
D26 = Pin((0, 117))
35+
D27 = Pin((0, 13))
36+
37+
SDA = D2
38+
SCL = D3
39+
MISO = D9
40+
MOSI = D10
41+
SCLK = D11
42+
SCK = D11
43+
TXD = D14
44+
RXD = D15
45+
46+
spiPorts = (
47+
(1, SCLK, MOSI, MISO),
48+
)
49+
50+
uartPorts = ((0, TXD, RXD),)
51+
52+
i2cPorts = (
53+
(0, SCL, SDA),
54+
)
55+
56+
pwmOuts = (
57+
((0, 0), D12),
58+
((3, 0), D13),
59+
)

src/board.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,9 @@
440440
elif board_id == ap_board.INDIEDROID_NOVA:
441441
from adafruit_blinka.board.ameridroid.indiedroid_nova import *
442442

443+
elif board_id == ap_board.RDK_X3:
444+
from adafruit_blinka.board.horizon.rdkx3 import *
445+
443446
elif "sphinx" in sys.modules:
444447
pass
445448

src/digitalio.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@
121121
from adafruit_blinka.microcontroller.thead.th1520.pin import Pin
122122
elif detector.chip.K1:
123123
from adafruit_blinka.microcontroller.spacemit.k1.pin import Pin
124+
elif detector.chip.SUNRISE_X3:
125+
from adafruit_blinka.microcontroller.horizon.sunrise_x3.pin import Pin
124126
# Special Case Boards
125127
elif detector.board.ftdi_ft232h:
126128
from adafruit_blinka.microcontroller.ftdi_mpsse.ft232h.pin import Pin

src/microcontroller/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ def delay_us(delay):
159159
from adafruit_blinka.microcontroller.thead.th1520 import *
160160
elif chip_id == ap_chip.K1:
161161
from adafruit_blinka.microcontroller.spacemit.k1 import *
162+
elif chip_id == ap_chip.SUNRISE_X3:
163+
from adafruit_blinka.microcontroller.horizon.sunrise_x3 import *
162164
elif chip_id == ap_chip.GENERIC_X86:
163165
print("WARNING: GENERIC_X86 is not fully supported. Some features may not work.")
164166
elif chip_id == ap_chip.OS_AGNOSTIC:

src/microcontroller/pin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@
153153
from adafruit_blinka.microcontroller.rockchip.rv1103.pin import *
154154
elif chip_id == ap_chip.RV1106:
155155
from adafruit_blinka.microcontroller.rockchip.rv1106.pin import *
156+
elif chip_id == ap_chip.SUNRISE_X3:
157+
from adafruit_blinka.microcontroller.horizon.sunrise_x3.pin import *
156158
elif "sphinx" in sys.modules:
157159
# pylint: disable=unused-import
158160
from adafruit_blinka.microcontroller.generic_micropython import Pin

src/pwmio.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
5151
elif detector.board.any_starfive_id:
5252
from adafruit_blinka.microcontroller.starfive.JH7110.pwmio import PWMOut
53+
elif detector.board.any_horizon_board:
54+
from adafruit_blinka.microcontroller.horizon.pwmio.PWMOut import PWMOut
5355
elif detector.board.OS_AGNOSTIC_BOARD:
5456
from adafruit_blinka.microcontroller.generic_agnostic_board.PWMOut import PWMOut
5557
elif (

0 commit comments

Comments
 (0)