Skip to content

Commit 160378c

Browse files
authored
Merge pull request #914 from hajimef/develop
Added support for D-Robotics RDK-X3
2 parents 4b39004 + 4af3f22 commit 160378c

File tree

8 files changed

+294
-0
lines changed

8 files changed

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

src/board.py

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

449+
elif board_id == ap_board.RDK_X3:
450+
from adafruit_blinka.board.horizon.rdkx3 import *
451+
449452
elif "sphinx" in sys.modules:
450453
pass
451454

src/digitalio.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@
117117
from adafruit_blinka.microcontroller.thead.th1520.pin import Pin
118118
elif detector.chip.K1:
119119
from adafruit_blinka.microcontroller.spacemit.k1.pin import Pin
120+
elif detector.chip.SUNRISE_X3:
121+
from adafruit_blinka.microcontroller.horizon.sunrise_x3.pin import Pin
120122
# Special Case Boards
121123
elif detector.board.ftdi_ft232h:
122124
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
@@ -149,6 +149,8 @@
149149
from adafruit_blinka.microcontroller.rockchip.rv1103.pin import *
150150
elif chip_id == ap_chip.RV1106:
151151
from adafruit_blinka.microcontroller.rockchip.rv1106.pin import *
152+
elif chip_id == ap_chip.SUNRISE_X3:
153+
from adafruit_blinka.microcontroller.horizon.sunrise_x3.pin import *
152154
elif "sphinx" in sys.modules:
153155
# pylint: disable=unused-import
154156
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
@@ -53,6 +53,8 @@
5353
from adafruit_blinka.microcontroller.generic_linux.sysfs_pwmout import PWMOut
5454
elif detector.board.any_starfive_id:
5555
from adafruit_blinka.microcontroller.starfive.JH7110.pwmio import PWMOut
56+
elif detector.board.any_horizon_board:
57+
from adafruit_blinka.microcontroller.horizon.pwmio.PWMOut import PWMOut
5658
elif detector.board.OS_AGNOSTIC_BOARD:
5759
from adafruit_blinka.microcontroller.generic_agnostic_board.PWMOut import PWMOut
5860
elif (

0 commit comments

Comments
 (0)