Skip to content

Commit 5ca7fdd

Browse files
authored
Merge pull request #970 from bablokb/radxa_x4
add support for Radxa-X4 via U2IF
2 parents 8f45d6c + e6c2e68 commit 5ca7fdd

File tree

7 files changed

+182
-0
lines changed

7 files changed

+182
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# SPDX-FileCopyrightText: 2025 Bernhard Bablok
2+
#
3+
# Copied and adapted from pico_u2if.py
4+
# Copyright: 2021 Melissa LeBlanc-Williams for Adafruit Industries
5+
#
6+
# SPDX-License-Identifier: MIT
7+
"""Pin definitions for the Raspberry Pi Pico running u2if firmware"""
8+
from adafruit_blinka.microcontroller.rp2040_u2if import pin
9+
10+
# Pico names
11+
GP0 = pin.GP0
12+
GP1 = pin.GP1
13+
GP2 = pin.GP2
14+
GP3 = pin.GP3
15+
GP4 = pin.GP4
16+
GP5 = pin.GP5
17+
GP6 = pin.GP6
18+
GP7 = pin.GP7
19+
GP8 = pin.GP8
20+
GP9 = pin.GP9
21+
GP10 = pin.GP10
22+
GP11 = pin.GP11
23+
GP12 = pin.GP12
24+
GP13 = pin.GP13
25+
GP14 = pin.GP14
26+
GP15 = pin.GP15
27+
GP16 = pin.GP16
28+
GP17 = pin.GP17
29+
GP18 = pin.GP18
30+
GP19 = pin.GP19
31+
GP20 = pin.GP20
32+
GP21 = pin.GP21
33+
GP22 = pin.GP22
34+
GP23 = pin.GP23
35+
GP24 = pin.GP24
36+
GP25 = pin.GP25
37+
GP26 = pin.GP26
38+
GP27 = pin.GP27
39+
GP28 = pin.GP28
40+
GP29 = pin.GP29
41+
42+
# Pi names left side (top down)
43+
GPIO2 = GP28
44+
GPIO3 = GP29
45+
46+
GPIO4 = GP4
47+
GPIO17 = GP5
48+
GPIO27 = GP6
49+
GPIO22 = GP3
50+
51+
GPIO10 = GP11
52+
GPIO9 = GP8
53+
GPIO11 = GP10
54+
55+
GPIO0 = GP16
56+
GPIO5 = GP7
57+
GPIO6 = GP12
58+
GPIO13 = GP13
59+
GPIO19 = GP15
60+
GPIO26 = GP14
61+
62+
# right side (top down)
63+
GPIO14 = GP20
64+
GPIO15 = GP21
65+
GPIO18 = GP23
66+
67+
GPIO23 = GP22
68+
GPIO24 = GP27
69+
70+
GPIO25 = GP24
71+
GPIO8 = GP9
72+
GPIO7 = GP18
73+
GPIO1 = GP17
74+
75+
GPIO12 = GP19
76+
77+
GPIO16 = GP26
78+
GPIO20 = GP2
79+
GPIO21 = GP25
80+
81+
# specials (INT: internal connection to N100-chip, EXT: on GPIO-pins)
82+
UART_TX_INT = GP0
83+
UART_RX_INT = GP1
84+
UART_RX_EXT = GP20 # GPIO14
85+
UART_RX_EXT = GP21 # GPIO15
86+
87+
ADC0 = GP26
88+
ADC1 = GP27
89+
ADC2 = GP28
90+
ADC3 = GP29
91+
92+
PWM0 = GPIO12
93+
PWM1 = GPIO13
94+
95+
# Pi defaults (I2C0 is also mapped to the ID-pins GPIO0/GPIO1 aka GP16/GP17)
96+
SDA = SDA0 = GP28 # GPIO2
97+
SCL = SCL0 = GP29 # GPIO3
98+
99+
# other choices have more conflicts
100+
SDA1 = GP18
101+
SCL1 = GP19
102+
103+
# Pico-SPI0 (Radxa-X4 does not map Pi-SPI1)
104+
SCLK0 = SCK0 = GP6
105+
MOSI0 = GP3
106+
MISO0 = GP4
107+
CE0 = GPIO8
108+
CE1 = GPIO7
109+
110+
# Pi (SPI0) defaults (Radxa-X4 maps Pi-SPI0 to Pico-SPI1)
111+
SCLK = SCK = SCLK1 = SCK1 = GP10
112+
MOSI = MOSI1 = GP11
113+
MISO = MISO1 = GP8
114+
115+
# access u2if via pin instance to open for specifc VID/PID
116+
# pylint:disable = protected-access
117+
pin.GP0._u2if_open_hid(0xCAFF, 0x4005)

src/adafruit_blinka/microcontroller/rp2040_u2if/analogio.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,12 @@ def __init__(self, pin):
7070
if pin.id not in (26, 27, 28):
7171
raise ValueError("Pin does not support ADC.")
7272
super().__init__(pin)
73+
74+
75+
class AnalogIn_Radxa_X4(AnalogIn):
76+
"""AnalogIn Base Class for Radxa X4 u2if"""
77+
78+
def __init__(self, pin):
79+
if pin.id not in (26, 27, 28, 29):
80+
raise ValueError("Pin does not support ADC.")
81+
super().__init__(pin)

src/adafruit_blinka/microcontroller/rp2040_u2if/i2c.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,19 @@ def __init__(self, scl, sda, *, frequency=100000):
199199
self._index = index
200200

201201
super().__init__(index, frequency=frequency)
202+
203+
204+
class I2C_Radxa_X4(I2C):
205+
"""I2C Class for Radxa X4 u2if"""
206+
207+
def __init__(self, scl, sda, *, frequency=100000):
208+
index = None
209+
if scl.id == 29 and sda.id == 28:
210+
index = 0
211+
if scl.id == 19 and sda.id == 18:
212+
index = 1
213+
if index is None:
214+
raise ValueError("I2C not found on specified pins.")
215+
self._index = index
216+
217+
super().__init__(index, frequency=frequency)

src/adafruit_blinka/microcontroller/rp2040_u2if/spi.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,17 @@ def __init__(self, clock, *, baudrate=100000):
178178
if index is None:
179179
raise ValueError("No SPI port on specified pin.")
180180
super().__init__(index, baudrate=baudrate)
181+
182+
183+
class SPI_Radxa_X4(SPI):
184+
"""SPI Class for Radxa X4 u2if"""
185+
186+
def __init__(self, clock, *, baudrate=100000):
187+
index = None
188+
if clock.id == 6:
189+
index = 0
190+
if clock.id == 10:
191+
index = 1
192+
if index is None:
193+
raise ValueError("No SPI port on specified pin.")
194+
super().__init__(index, baudrate=baudrate)

src/analogio.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@
6666
from adafruit_blinka.microcontroller.rp2040_u2if.analogio import (
6767
AnalogIn_ItsyBitsy as AnalogIn,
6868
)
69+
elif detector.board.radxa_x4_u2if:
70+
from adafruit_blinka.microcontroller.rp2040_u2if.analogio import (
71+
AnalogIn_Radxa_X4 as AnalogIn,
72+
)
6973
elif detector.board.OS_AGNOSTIC_BOARD:
7074
from adafruit_blinka.microcontroller.generic_agnostic_board.analogio import AnalogIn
7175
from adafruit_blinka.microcontroller.generic_agnostic_board.analogio import (

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.RP2040_ONE_U2IF:
441441
from adafruit_blinka.board.rp2040_one_u2if import *
442442

443+
elif board_id == ap_board.RADXA_X4_U2IF:
444+
from adafruit_blinka.board.radxa_x4_u2if import *
445+
443446
elif board_id == ap_board.OS_AGNOSTIC_BOARD:
444447
from adafruit_blinka.board.generic_agnostic_board import *
445448

src/busio.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ def init(self, scl, sda, frequency):
131131
I2C_KB2040 as _I2C,
132132
)
133133

134+
self._i2c = _I2C(scl, sda, frequency=frequency)
135+
return
136+
if detector.board.radxa_x4_u2if:
137+
from adafruit_blinka.microcontroller.rp2040_u2if.i2c import (
138+
I2C_Radxa_X4 as _I2C,
139+
)
140+
134141
self._i2c = _I2C(scl, sda, frequency=frequency)
135142
return
136143
if detector.chip.id == ap_chip.RP2040:
@@ -341,6 +348,14 @@ def __init__(self, clock, MOSI=None, MISO=None):
341348
SPI_KB2040 as _SPI,
342349
)
343350

351+
self._spi = _SPI(clock) # this is really all that's needed
352+
self._pins = (clock, clock, clock) # will determine MOSI/MISO from clock
353+
return
354+
if detector.board.radxa_x4_u2if:
355+
from adafruit_blinka.microcontroller.rp2040_u2if.spi import (
356+
SPI_Radxa_X4 as _SPI,
357+
)
358+
344359
self._spi = _SPI(clock) # this is really all that's needed
345360
self._pins = (clock, clock, clock) # will determine MOSI/MISO from clock
346361
return
@@ -442,6 +457,10 @@ def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
442457
)
443458
elif detector.board.qtpy_u2if:
444459
from adafruit_blinka.microcontroller.rp2040_u2if.spi import SPI_QTPY as _SPI
460+
elif detector.board.radxa_x4_u2if:
461+
from adafruit_blinka.microcontroller.rp2040_u2if.spi import (
462+
SPI_Radxa_X4 as _SPI,
463+
)
445464
elif detector.chip.id == ap_chip.RP2040:
446465
from adafruit_blinka.microcontroller.rp2040.spi import SPI as _SPI
447466
elif detector.board.any_siemens_iot2000:

0 commit comments

Comments
 (0)