Skip to content
Merged
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
5 changes: 5 additions & 0 deletions boards/adafruit/metro_rp2350/Kconfig.adafruit_metro_rp2350
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) 2025 Pete Johanson
# SPDX-License-Identifier: Apache-2.0

config BOARD_ADAFRUIT_METRO_RP2350
select SOC_RP2350B_M33 if BOARD_ADAFRUIT_METRO_RP2350_RP2350B_M33
9 changes: 9 additions & 0 deletions boards/adafruit/metro_rp2350/Kconfig.defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025 Pete Johanson
# SPDX-License-Identifier: Apache-2.0

if BOARD_ADAFRUIT_METRO_RP2350

config USB_SELF_POWERED
default n

endif # BOARD_ADAFRUIT_METRO_RP2350
58 changes: 58 additions & 0 deletions boards/adafruit/metro_rp2350/adafruit_metro_rp2350-pinctrl.dtsi
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2025 Pete Johanson
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/dt-bindings/pinctrl/rpi-pico-rp2350b-pinctrl.h>

&pinctrl {
uart0_default: uart0_default {
group1 {
pinmux = <UART0_TX_P0>;
};

group2 {
pinmux = <UART0_RX_P1>;
input-enable;
};
};

i2c0_default: i2c0_default {
group1 {
pinmux = <I2C0_SDA_P20>;
input-enable;
};

group2 {
pinmux = <I2C0_SCL_P21>;
};
};

adc_default: adc_default {
group1 {
pinmux = <ADC_CH1_P41>, <ADC_CH2_P42>, <ADC_CH3_P43>,
<ADC_CH4_P44>, <ADC_CH5_P45>, <ADC_CH6_P46>;
input-enable;
};
};

pwm_default: pwm_default {
group1 {
pinmux = <PWM_1B_P3>, <PWM_2B_P5>, <PWM_3A_P6>, <PWM_4B_P9>, <PWM_5A_P10>,
<PWM_5B_P11>;
};
};

pio0_spi0_default: pio0_spi0_default {
/* gpio 10 is used for chip select, not assigned to the PIO */
group1 {
pinmux = <PIO0_P11>, <PIO0_P12>;
};
};

pio1_ws2812_default: pio1_ws2812_default {
group1 {
pinmux = <PIO1_P25>;
};
};
};
205 changes: 205 additions & 0 deletions boards/adafruit/metro_rp2350/adafruit_metro_rp2350_rp2350b_m33.dts
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/*
* Copyright (c) 2025 Pete Johanson
*
* SPDX-License-Identifier: Apache-2.0
*/

/dts-v1/;

/* The build system assumes that there's a cpucluster-specific file.
*
* This file provides composition of the device tree:
* 1. The common features of the SoC
* 2. Core-specific configuration.
* 3. Board-specific configuration.
*/
#include <raspberrypi/rpi_pico/rp2350b.dtsi>
#include <raspberrypi/rpi_pico/m33.dtsi>

#include <freq.h>

#include <zephyr/dt-bindings/gpio/arduino-header-r3.h>
#include <zephyr/dt-bindings/i2c/i2c.h>
#include <zephyr/dt-bindings/led/led.h>
#include <zephyr/dt-bindings/pwm/pwm.h>

#include "adafruit_metro_rp2350-pinctrl.dtsi"

/ {
chosen {
zephyr,sram = &sram0;
zephyr,flash = &flash0;
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
zephyr,code-partition = &code_partition;
};

aliases {
watchdog0 = &wdt0;
led-strip = &ws2812;
led0 = &user_led;
};

leds {
compatible = "gpio-leds";

user_led: user_led {
gpios = <&gpio0 23 GPIO_ACTIVE_LOW>;
label = "USER_LED";
};
};

arduino_header: connector {
compatible = "arduino-header-r3";
#gpio-cells = <2>;
gpio-map-mask = <0xffffffff 0xffffffc0>;
gpio-map-pass-thru = <0 0x3f>;
gpio-map =
<ARDUINO_HEADER_R3_A0 0 &gpio0_hi 9 0>,
<ARDUINO_HEADER_R3_A1 0 &gpio0_hi 10 0>,
<ARDUINO_HEADER_R3_A2 0 &gpio0_hi 11 0>,
<ARDUINO_HEADER_R3_A3 0 &gpio0_hi 12 0>,
<ARDUINO_HEADER_R3_A4 0 &gpio0_hi 13 0>,
<ARDUINO_HEADER_R3_A5 0 &gpio0_hi 14 0>,
<ARDUINO_HEADER_R3_D0 0 &gpio0 1 0>,
<ARDUINO_HEADER_R3_D1 0 &gpio0 0 0>,
<ARDUINO_HEADER_R3_D2 0 &gpio0 2 0>,
<ARDUINO_HEADER_R3_D3 0 &gpio0 3 0>,
<ARDUINO_HEADER_R3_D4 0 &gpio0 4 0>,
<ARDUINO_HEADER_R3_D5 0 &gpio0 5 0>,
<ARDUINO_HEADER_R3_D6 0 &gpio0 6 0>,
<ARDUINO_HEADER_R3_D7 0 &gpio0 7 0>,
<ARDUINO_HEADER_R3_D8 0 &gpio0 8 0>,
<ARDUINO_HEADER_R3_D9 0 &gpio0 9 0>,
<ARDUINO_HEADER_R3_D10 0 &gpio0 10 0>,
<ARDUINO_HEADER_R3_D11 0 &gpio0 11 0>,
<ARDUINO_HEADER_R3_D12 0 &gpio0 22 0>,
<ARDUINO_HEADER_R3_D13 0 &gpio0 23 0>,
<ARDUINO_HEADER_R3_D14 0 &gpio0 16 0>,
<ARDUINO_HEADER_R3_D15 0 &gpio0 17 0>;
};

arduino_adc: analog-connector {
compatible = "arduino,uno-adc";
#io-channel-cells = <1>;
io-channel-map = <0 &adc 1>, /* A0 = GPIO41 = ADC1 */
<1 &adc 2>, /* A1 = GPIO42 = ADC2 */
<2 &adc 3>, /* A2 = GPIO43 = ADC3 */
<3 &adc 4>, /* A3 = GPIO44 = ADC4 */
<4 &adc 5>, /* A4 = GPIO45 = ADC5 */
<5 &adc 6>; /* A5 = GPIO46 = ADC6 */
};
};

&flash0 {
reg = <0x10000000 DT_SIZE_M(16)>;

partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

/* Reserved memory for an image definition block. The block is much
* smaller than 256 bytes, but in practice the linker places the vector
* table at a much larger alignment offset.
*/
image_def: partition@0 {
label = "image_def";
reg = <0x00000000 0x100>;
read-only;
};

/*
* Usable flash. Starts at 0x100, after the image definition block.
* The partition size is 4MB minus the 0x100 bytes taken by the
* image definition.
*/
code_partition: partition@100 {
label = "code-partition";
reg = <0x100 (DT_SIZE_M(16) - 0x100)>;
read-only;
};
};
};

&uart0 {
current-speed = <115200>;
status = "okay";
pinctrl-0 = <&uart0_default>;
pinctrl-names = "default";
};

&gpio0 {
status = "okay";
};

&i2c0 {
clock-frequency = <I2C_BITRATE_STANDARD>;
pinctrl-0 = <&i2c0_default>;
pinctrl-names = "default";
status = "okay";
};

&adc {
pinctrl-0 = <&adc_default>;
pinctrl-names = "default";
status = "okay";
};

&pwm {
pinctrl-0 = <&pwm_default>;
pinctrl-names = "default";
divider-int-0 = <255>;
};

&timer0 {
status = "okay";
};

zephyr_udc0: &usbd {
status = "okay";
};

&pio0 {
status = "okay";

arduion_spi: pio0_spi0 {
compatible = "raspberrypi,pico-spi-pio";
clocks = < &clocks RPI_PICO_CLKID_CLK_SYS >;
#address-cells = <1>;
#size-cells = <0>;
cs-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
clk-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;
mosi-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
miso-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
pinctrl-0 = <&pio0_spi0_default>;
pinctrl-names = "default";
};
};

&pio1 {
status = "okay";

pio-ws2812 {
compatible = "worldsemi,ws2812-rpi_pico-pio";
status = "okay";
pinctrl-0 = <&pio1_ws2812_default>;
pinctrl-names = "default";
bit-waveform = <3>, <3>, <4>;

ws2812: ws2812 {
status = "okay";
gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
chain-length = <1>;
color-mapping = <LED_COLOR_ID_GREEN
LED_COLOR_ID_RED
LED_COLOR_ID_BLUE>;
reset-delay = <280>;
frequency = <800000>;
};
};
};


arduino_serial: &uart0 {};
arduino_i2c: &i2c0 {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
identifier: adafruit_metro_rp2350/rp2350b/m33
name: Adafruit Metro RP2350 (Cortex-M33)
type: mcu
arch: arm
flash: 16384
ram: 520
toolchain:
- zephyr
- gnuarmemb
supported:
- adc
- clock
- counter
- dma
- gpio
- hwinfo
- i2c
- pwm
- spi
- uart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This configuration is orthogonal to whether the Cortex-M33 or Hazard3 cores
# are in use, but Zephyr does not support providing a qualifier-agnostic
# _defconfig file.
CONFIG_BUILD_OUTPUT_HEX=y
CONFIG_BUILD_OUTPUT_UF2=y
CONFIG_CLOCK_CONTROL=y
CONFIG_CONSOLE=y
CONFIG_GPIO=y
CONFIG_RESET=y
CONFIG_SERIAL=y
CONFIG_UART_CONSOLE=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_USE_DT_CODE_PARTITION=y
18 changes: 18 additions & 0 deletions boards/adafruit/metro_rp2350/board.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: Apache-2.0

if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "")
set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap")
endif()

board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]")
board_runner_args(openocd --cmd-pre-init "source [find target/rp2350.cfg]")

# The adapter speed is expected to be set by interface configuration.
# The Raspberry Pi's OpenOCD fork doesn't, so match their documentation at
# https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#debugging-with-swd
board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 5000")

board_runner_args(uf2 "--board-id=RP2350")

include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake)
include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake)
6 changes: 6 additions & 0 deletions boards/adafruit/metro_rp2350/board.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
board:
name: adafruit_metro_rp2350
full_name: Adafruit Metro RP2350
vendor: adafruit
socs:
- name: rp2350b
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 57 additions & 0 deletions boards/adafruit/metro_rp2350/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
.. zephyr:board:: adafruit_metro_rp2350

Overview
********

Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain",
"528K RAM round-about" and "16 Megabytes of Flash town". This train is piled high with hardware that
complements the Raspberry Pi RP2350 chip to make it an excellent development board for projects that
want Arduino-shape-compatibility or just need the extra space and debugging ports.
Comment on lines +5 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For future reference, I don't think we want to use the vendor's marketing blurb (esp. when the tone is clearly geared towards "promotion") verbatim in our own Zephyr docs. Maybe this can be adjusted in a follow-up PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair. I'll work to correct in a follow up


The Adafruit Metro RP2350 is the second Metro board to use the Rasperry Pi Pico family.

There are many limitations of the board currently. Including but not limited to:
- The Zephyr build only supports configuring the RP2350B with the Cortex-M33 cores.
- As with other RP2040/RP2350 devices, there's no support for running any code on the second core.

Hardware
********

- RP2350 main chip, 150MHz clock, 3.3V logic
- 16 MB of QSPI flash for program storage
- 37 Available GPIO: 23 on the socket/SPI headers, 12 on HSTX port, and another 2 for USB host. 6 of which are also analog inputs
- Micro SD card socket wired up for SPI interfacing, also has extra pins connected for advanced-user SDIO interfacing (note that there's no code for SDIO in Arduino/Python, so this is a super-cutting-edge setup)
- 5V Buck Converter featuring TPS563201 6~17V DC input and up to 2A output
- Onboard RGB NeoPixel
- Onboard #23 LED
- Stemma QT port for I2C peripherals and sensors
- 22-pin 3-lane differential HSTX FPC port with 'Pi 5' compatible pinout, makes for quick DVI video output. Or, this also provides 12 extra GPIO that can be used for more pins.
- Reset and Boot buttons on PCB edge
- Pico Probe debug port - 3 pin JST SH compatible
- USB Type C power and data
- 5.5mm / 2.1mm DC jack for 6-17VDC power
- On/off switch for DC jack
- RX / TX switch for swapping D0 and D1 locations
- USB Host breakout pads - with controllable 5V power and D+/D- for bitbang USB Host.
- GPIO pin numbers match classic Arduino pins, other than GPIO 12 and 13 as those are needed for HSTX connectivity

Supported Features
==================

.. zephyr:board-supported-hw::

Connections and IOs
===================

The default pin mapping is unchanged from the Pico 1 (see :ref:`rpi_pico_pin_mapping`).

Programming and Debugging
*************************

As with other RP3250 devices, the SWD interface can be used to program and debug the
device, e.g. using OpenOCD with the `Raspberry Pi Debug Probe <https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html>`_ .

References
**********

.. target-notes::
Loading