From 1c64ce1edc64f8a440a63da5acdd82de365392f8 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Fri, 26 Sep 2025 15:17:36 +0200 Subject: [PATCH 01/20] boards/rpi-pico-2-riscv: add riscv based rp2350 board --- boards/rpi-pico-2-riscv/Kconfig | 11 ++ boards/rpi-pico-2-riscv/Makefile | 3 + boards/rpi-pico-2-riscv/Makefile.features | 1 + boards/rpi-pico-2-riscv/Makefile.include | 7 ++ boards/rpi-pico-2-riscv/board.c | 18 +++ boards/rpi-pico-2-riscv/dist/openocd.cfg | 8 ++ boards/rpi-pico-2-riscv/doc.md | 116 ++++++++++++++++++ boards/rpi-pico-2-riscv/include/board.h | 45 +++++++ boards/rpi-pico-2-riscv/include/gpio_params.h | 18 +++ boards/rpi-pico-2-riscv/include/periph_conf.h | 61 +++++++++ cpu/riscv_common/ldscripts/riscv_base.ld | 7 ++ features.yaml | 2 + makefiles/arch/riscv.inc.mk | 1 + makefiles/features_existing.inc.mk | 1 + 14 files changed, 299 insertions(+) create mode 100644 boards/rpi-pico-2-riscv/Kconfig create mode 100644 boards/rpi-pico-2-riscv/Makefile create mode 100644 boards/rpi-pico-2-riscv/Makefile.features create mode 100644 boards/rpi-pico-2-riscv/Makefile.include create mode 100644 boards/rpi-pico-2-riscv/board.c create mode 100644 boards/rpi-pico-2-riscv/dist/openocd.cfg create mode 100644 boards/rpi-pico-2-riscv/doc.md create mode 100644 boards/rpi-pico-2-riscv/include/board.h create mode 100644 boards/rpi-pico-2-riscv/include/gpio_params.h create mode 100644 boards/rpi-pico-2-riscv/include/periph_conf.h diff --git a/boards/rpi-pico-2-riscv/Kconfig b/boards/rpi-pico-2-riscv/Kconfig new file mode 100644 index 000000000000..e9e2ff4413ab --- /dev/null +++ b/boards/rpi-pico-2-riscv/Kconfig @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2025 Tom Hert +# SPDX-FileCopyrightText: 2025 HAW Hamburg +# SPDX-License-Identifier: LGPL-2.1-only + +config BOARD + default "rpi-pico-2-riscv" if BOARD_RPI_PICO_2_RISCV + +config BOARD_RPI_PICO_2_RISV + bool + default y + select CPU_MODEL_RP2350_RISCV diff --git a/boards/rpi-pico-2-riscv/Makefile b/boards/rpi-pico-2-riscv/Makefile new file mode 100644 index 000000000000..f8fcbb53a065 --- /dev/null +++ b/boards/rpi-pico-2-riscv/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/rpi-pico-2-riscv/Makefile.features b/boards/rpi-pico-2-riscv/Makefile.features new file mode 100644 index 000000000000..1df8fa1b8571 --- /dev/null +++ b/boards/rpi-pico-2-riscv/Makefile.features @@ -0,0 +1 @@ +CPU := rp2350_riscv diff --git a/boards/rpi-pico-2-riscv/Makefile.include b/boards/rpi-pico-2-riscv/Makefile.include new file mode 100644 index 000000000000..b440109c92d5 --- /dev/null +++ b/boards/rpi-pico-2-riscv/Makefile.include @@ -0,0 +1,7 @@ +CPU_MODEL := RP2350_RISCV +PORT_LINUX ?= /dev/ttyACM0 + +# JLink isnt tested yet on RP2350 +# ifeq ($(PROGRAMMER),jlink) +# JLINK_DEVICE = RP2350_M33_0 +# endif diff --git a/boards/rpi-pico-2-riscv/board.c b/boards/rpi-pico-2-riscv/board.c new file mode 100644 index 000000000000..31c2557905e2 --- /dev/null +++ b/boards/rpi-pico-2-riscv/board.c @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#include "board.h" + +void board_init(void) { + /* Re-enable the LED0 pin + * Otherwise the LED will not work after a reset + * This is needed, esp. when the LED is used via + * the define macros */ + gpio_init(LED0_PIN_ID, GPIO_OUT); + + gpio_init(OSC_DEBUG_PIN_ID, GPIO_OUT); + gpio_init(OSC_DEBUG_PIN_ID_2, GPIO_OUT); +} diff --git a/boards/rpi-pico-2-riscv/dist/openocd.cfg b/boards/rpi-pico-2-riscv/dist/openocd.cfg new file mode 100644 index 000000000000..c90d870b123c --- /dev/null +++ b/boards/rpi-pico-2-riscv/dist/openocd.cfg @@ -0,0 +1,8 @@ +echo "Make sure to use the Raspberry Pi OpenOCD version!" +echo "For further details see Appendix A Building OpenOCD:" +echo "https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf" +source [find target/rp2350-riscv.cfg] +set USE_CORE SMP +set RESCUE 1 +$_TARGETNAME_0 configure -rtos auto +adapter speed 5000 diff --git a/boards/rpi-pico-2-riscv/doc.md b/boards/rpi-pico-2-riscv/doc.md new file mode 100644 index 000000000000..fc041d1f9d46 --- /dev/null +++ b/boards/rpi-pico-2-riscv/doc.md @@ -0,0 +1,116 @@ +@defgroup boards_rpi_pico_2 Raspberry Pi Pico 2 +@ingroup boards +@brief Support for the RP2350 based Raspberry Pi Pico board + +@warning The support for the Raspberry Pi Pico 2 is still in a very early stage! +See [Known Issues](#rpi_pico_2_known_issues). + +## Overview + +The Raspberry Pi Pico 2 is a microcontroller board based on the RP2350 chip, +featuring dual-core Arm Cortex-M0+ processors and RISC-V Hazard secondary +architecture. It is designed for a wide range of applications, +from hobbyist projects to professional embedded systems +for a fairly affordable price. + +![The Raspberry Pi Pico 2 Board](https://www.raspberrypi.com/documentation/microcontrollers/images/pico-2.png) + +## Hardware + +| MCU | RP2350 | +|:-----------|:------------------------------------------------------------| +| Family | Dual Cortex-M33 or Hazard3 (RISC-V) | +| Vendor | Raspberry Pi | +| RAM | 520 kB on-chip SRAM (10 independent banks) | +| Flash | Up to 16 MB external QSPI flash (Pico 2 has 4 MB by default)| +| Frequency | up to 150 MHz (Set to 125 MHz in RIOT) | +| Security | Boot signing, key storage, SHA-256 accelerator | +| PIOs | 12 state machines | +| UARTs | 2 | +| SPIs | 2 | +| I2Cs | 2 | +| PWM | 24 channels | +| USB | USB 1.1 controller with host and device support | +| Power | On-chip switched-mode power supply with LDO sleep mode | +| OTP | 8 kB of one-time-programmable storage | +| Datasheet | [RP2350 Datasheet](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf) | + +## User Interfaces + +| Interface | Description | +|:-----------|:-------------------------------------------------------------| +| LED0 | User LED (GPIO 0 at Pin 25) | +| SW0 | Button used in flash process, can be accessed using registers but difficult | + +## Pinout + +![Pinout Diagram](https://www.raspberrypi.com/documentation/microcontrollers/images/pico-2-r4-pinout.svg) + +## Flashing the Board + +The Raspberry Pi Pico 2 has a built-in bootloader that allows flashing via USB. +However, you can also use OpenOCD for flashing the board. +If you are using picotool, you need to hold the bootselect button +(the only button on the board) while connecting the board to +your computer via USB. This will put the board into bootloader mode, +allowing you to flash it. + +### Flashing using OpenOCD + +If you have two Raspberry Pi Pico boards, +you can utilize one as a programmer to program the other board. + +Please refer to the +[Debugprobe documentation](https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#getting-started) +for more details. + +Note that Raspberry Pi actually uses their own OpenOCD fork, which is available +in the [RP2040 OpenOCD repository](https://github.com/raspberrypi/openocd). +While technically you can use the standard OpenOCD, +it is recommended to use the Raspberry Pi fork for better compatibility with the +RP2350, as its still fairly "new" and under development, +which is why even their own Pico SDK Extension +uses the Raspberry Pi fork of OpenOCD, instead of the standard one. + +To do this, you need to connect the board to your computer +and use the following command: + +```bash +PROGRAMMER=openocd BOARD=rpi-pico-2-riscv make flash +``` + +You can then debug your application using GDB with the following command: + +```bash +PROGRAMMER=openocd BOARD=rpi-pico-2-riscv make debug +``` + +### Flashing using Picotool + +Simply connect the board to your computer via USB and use the following command: + +```bash +BOARD=rpi-pico-2-riscv make flash +``` + +This is the default method for flashing the Raspberry Pi Pico 2. +However, it does not allow for debugging using GDB. + +@note When programming the board with the Picotool for the first time, +RIOT will download and install the Picotool locally in the RIOT folder. +This process will take some minutes to complete. + +## Known Issues {#rpi_pico_2_known_issues} + +Currently RP2350 support is rather minimal, +as such peripheral support is extremely limited. +The following peripherals are supported: + +- GPIO +- Non-configurable write-only UART (UART0 using Pin 0 and 1) + - The UART Baudrate is set to 115200. + - UART does not work via USB, you need to connect it directly to the GPIO pins. + +More peripherals will be added in the future. +It should also be noted that we currently only support the Cortex M33 cores, +not the RISC-V Hazard cores. diff --git a/boards/rpi-pico-2-riscv/include/board.h b/boards/rpi-pico-2-riscv/include/board.h new file mode 100644 index 000000000000..2aaf6b1db423 --- /dev/null +++ b/boards/rpi-pico-2-riscv/include/board.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup boards_rpi_pico_2 + * @{ + * + * @file + * @brief Board specific definitions for the Raspberry Pi Pico 2 + * + * @author Tom Hert + */ + +#include "cpu.h" +#include "periph_conf.h" + +#include "periph/gpio.h" + +/** GPIO Pin ID for the onboard LED */ +#define LED0_PIN_ID 25u +#define LED0_ON gpio_set(LED0_PIN_ID) +#define LED0_OFF gpio_clear(LED0_PIN_ID) +#define LED0_TOGGLE gpio_toggle(LED0_PIN_ID) +#define LED0_NAME "LED(Green)" + +#define OSC_DEBUG_PIN_ID 15u +#define OSC_DEBUG_PIN_ID_2 14u + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialize the board, called from the cpu startup code */ +void board_init(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/boards/rpi-pico-2-riscv/include/gpio_params.h b/boards/rpi-pico-2-riscv/include/gpio_params.h new file mode 100644 index 000000000000..1998b8afaa24 --- /dev/null +++ b/boards/rpi-pico-2-riscv/include/gpio_params.h @@ -0,0 +1,18 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +#include "board.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif diff --git a/boards/rpi-pico-2-riscv/include/periph_conf.h b/boards/rpi-pico-2-riscv/include/periph_conf.h new file mode 100644 index 000000000000..fe5f5d4972ed --- /dev/null +++ b/boards/rpi-pico-2-riscv/include/periph_conf.h @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup boards_rpi_pico_2_riscv + * @{ + * + * @file + * @brief Board specific periph definitions + * for the Raspberry Pi Pico 2 + * + * @author Tom Hert + */ + +#include + +#include "kernel_defines.h" +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configuration details for an UART interface + */ +typedef struct { + UART0_Type *dev; /**< Base address of the I/O registers of the device */ + gpio_t rx_pin; /**< GPIO pin to use for RX */ + gpio_t tx_pin; /**< GPIO pin to use for TX */ + IRQn_Type irqn; /**< IRQ number of the UART interface */ +} uart_conf_t; + +static const uart_conf_t uart_config[] = { + { + .dev = UART0, + .rx_pin = GPIO_PIN(0, 1), + .tx_pin = GPIO_PIN(0, 0), + .irqn = UART0_IRQ_IRQn + }, + { + .dev = UART1, + .rx_pin = GPIO_PIN(0, 9), + .tx_pin = GPIO_PIN(0, 8), + .irqn = UART1_IRQ_IRQn + } +}; + +#define UART_0_ISR (isr_uart0) +#define UART_1_ISR (isr_uart1) + +#define UART_NUMOF ARRAY_SIZE(uart_config) + +#ifdef __cplusplus +} +#endif diff --git a/cpu/riscv_common/ldscripts/riscv_base.ld b/cpu/riscv_common/ldscripts/riscv_base.ld index c77f152a1963..2718816b318a 100644 --- a/cpu/riscv_common/ldscripts/riscv_base.ld +++ b/cpu/riscv_common/ldscripts/riscv_base.ld @@ -41,6 +41,13 @@ SECTIONS .text : { + /* + * Keep picobin block used by RP2350. + * This gives the Pico2 bootloader metadata about the + * exact configuration we are trying to run. + * E.g. secure mode, riscv, arm, etc. + */ + KEEP(*(SORT(.picobin_block*))) *(.text.unlikely .text.unlikely.*) *(.text.startup .text.startup.*) *(.text .text.*) diff --git a/features.yaml b/features.yaml index 7113af63e6c5..9777a18128ab 100644 --- a/features.yaml +++ b/features.yaml @@ -285,6 +285,8 @@ groups: help: The MCU is part of the Raspberry PI RPx0xx family. - name: cpu_rp2350 help: The MCU is a Raspberry Pi RP2350 + - name: cpu_rp2350_riscv + help: The MCU is a Raspberry Pi RP2350 RISCV - title: Silicon Laboratories EFM32 Grouping features: diff --git a/makefiles/arch/riscv.inc.mk b/makefiles/arch/riscv.inc.mk index 55ae154c581e..4d2736aa8743 100644 --- a/makefiles/arch/riscv.inc.mk +++ b/makefiles/arch/riscv.inc.mk @@ -52,6 +52,7 @@ endif GCC_DEFAULTS_TO_NEW_RISCV_ISA ?= 0 CFLAGS_CPU := -march=rv32imac -mabi=ilp32 +ASFLAGS := $(CFLAGS_CPU) # Since RISC-V ISA specifications 20191213 instructions previously included in # rv32imac have been moved to the ZICSR extension. See diff --git a/makefiles/features_existing.inc.mk b/makefiles/features_existing.inc.mk index 6420ccd089cd..dfeb27b1d693 100644 --- a/makefiles/features_existing.inc.mk +++ b/makefiles/features_existing.inc.mk @@ -87,6 +87,7 @@ FEATURES_EXISTING := \ cpu_nrf9160 \ cpu_qn908x \ cpu_rp2350 \ + cpu_rp2350_riscv \ cpu_rpx0xx \ cpu_sam3 \ cpu_sam4s \ From 5c953d99e5eab5473d1e611e9e20c00027568bf0 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Fri, 26 Sep 2025 15:18:59 +0200 Subject: [PATCH 02/20] cpu/rp2350_riscv: add initial support --- cpu/riscv_common/irq_arch.c | 4 + cpu/rp2350_riscv/Makefile | 8 ++ cpu/rp2350_riscv/Makefile.dep | 5 + cpu/rp2350_riscv/Makefile.features | 7 ++ cpu/rp2350_riscv/Makefile.include | 32 ++++++ cpu/rp2350_riscv/clock.c | 71 ++++++++++++ cpu/rp2350_riscv/cpu.c | 72 ++++++++++++ cpu/rp2350_riscv/doc.md | 7 ++ cpu/rp2350_riscv/include/clock_conf.h | 159 ++++++++++++++++++++++++++ cpu/rp2350_riscv/include/core_cm33.h | 13 +++ cpu/rp2350_riscv/include/cpu.h | 29 +++++ cpu/rp2350_riscv/include/cpu_conf.h | 34 ++++++ cpu/rp2350_riscv/include/gpio_conf.h | 66 +++++++++++ cpu/rp2350_riscv/include/helpers.h | 78 +++++++++++++ cpu/rp2350_riscv/include/periph_cpu.h | 117 +++++++++++++++++++ cpu/rp2350_riscv/include/uart_conf.h | 55 +++++++++ cpu/rp2350_riscv/periph/Makefile | 1 + cpu/rp2350_riscv/periph/gpio.c | 96 ++++++++++++++++ cpu/rp2350_riscv/periph/uart.c | 86 ++++++++++++++ cpu/rp2350_riscv/picobin_block.s | 37 ++++++ cpu/rp2350_riscv/xosc.c | 55 +++++++++ 21 files changed, 1032 insertions(+) create mode 100644 cpu/rp2350_riscv/Makefile create mode 100644 cpu/rp2350_riscv/Makefile.dep create mode 100644 cpu/rp2350_riscv/Makefile.features create mode 100644 cpu/rp2350_riscv/Makefile.include create mode 100644 cpu/rp2350_riscv/clock.c create mode 100644 cpu/rp2350_riscv/cpu.c create mode 100644 cpu/rp2350_riscv/doc.md create mode 100644 cpu/rp2350_riscv/include/clock_conf.h create mode 100644 cpu/rp2350_riscv/include/core_cm33.h create mode 100644 cpu/rp2350_riscv/include/cpu.h create mode 100644 cpu/rp2350_riscv/include/cpu_conf.h create mode 100644 cpu/rp2350_riscv/include/gpio_conf.h create mode 100644 cpu/rp2350_riscv/include/helpers.h create mode 100644 cpu/rp2350_riscv/include/periph_cpu.h create mode 100644 cpu/rp2350_riscv/include/uart_conf.h create mode 100644 cpu/rp2350_riscv/periph/Makefile create mode 100644 cpu/rp2350_riscv/periph/gpio.c create mode 100644 cpu/rp2350_riscv/periph/uart.c create mode 100644 cpu/rp2350_riscv/picobin_block.s create mode 100644 cpu/rp2350_riscv/xosc.c diff --git a/cpu/riscv_common/irq_arch.c b/cpu/riscv_common/irq_arch.c index f37b58e55050..2ec80fa7e93b 100644 --- a/cpu/riscv_common/irq_arch.c +++ b/cpu/riscv_common/irq_arch.c @@ -32,6 +32,10 @@ #include "clic.h" #include "architecture.h" +#if MODULE_PERIPH_XH3IRQ || DOXYGEN +# include "xh3irq.h" +#endif + #include "vendor/riscv_csr.h" /* Default state of mstatus register */ diff --git a/cpu/rp2350_riscv/Makefile b/cpu/rp2350_riscv/Makefile new file mode 100644 index 000000000000..ee03da8b7063 --- /dev/null +++ b/cpu/rp2350_riscv/Makefile @@ -0,0 +1,8 @@ +# define the module that is built +MODULE = cpu + +# add a list of subdirectories, that should also be built +DIRS += $(RIOTCPU)/rp2350_common +DIRS += $(RIOTCPU)/riscv_common + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/rp2350_riscv/Makefile.dep b/cpu/rp2350_riscv/Makefile.dep new file mode 100644 index 000000000000..9b356f1d4deb --- /dev/null +++ b/cpu/rp2350_riscv/Makefile.dep @@ -0,0 +1,5 @@ +USEMODULE += periph + +FEATURES_REQUIRED += periph_xh3irq + +include $(RIOTCPU)/riscv_common/Makefile.dep diff --git a/cpu/rp2350_riscv/Makefile.features b/cpu/rp2350_riscv/Makefile.features new file mode 100644 index 000000000000..8914a41a2f94 --- /dev/null +++ b/cpu/rp2350_riscv/Makefile.features @@ -0,0 +1,7 @@ +CPU_CORE := rv32imac + +FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_uart +FEATURES_PROVIDED += periph_xh3irq + +include $(RIOTCPU)/riscv_common/Makefile.features diff --git a/cpu/rp2350_riscv/Makefile.include b/cpu/rp2350_riscv/Makefile.include new file mode 100644 index 000000000000..a8d98087fe6e --- /dev/null +++ b/cpu/rp2350_riscv/Makefile.include @@ -0,0 +1,32 @@ +CFLAGS += -Wno-pedantic + +ROM_LEN ?= 2097152 # = 2 MiB used in the RPi Pico +ROM_OFFSET := 0 # bootloader size +RAM_LEN := 0x82000 # 520kB = 532479 used in the RPi Pico 2350 +ROM_START_ADDR := 0x10000000 # XIP Non-Secure address for rp2350 +RAM_START_ADDR := 0x20000000 # Non-Secure RAM address for rp2350 + +INCLUDES += -I$(RIOTCPU)/rp2350_riscv/include +INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include +INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include +INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2350/hardware_regs/include/hardware + +# CPU and architecture specific flags +CFLAGS += -D$(CPU_MODEL) +CFLAGS += -DROM_START_ADDR=$(ROM_START_ADDR) +CFLAGS += -DRAM_START_ADDR=$(RAM_START_ADDR) +CFLAGS += -march=rv32imac_zicsr_zifencei_zba_zbb_zbkb_zbs +CFLAGS += -mabi=lp64 + +# Linker flags +LINKFLAGS += -mcpu=$(CPU_ARCH) +LINKFLAGS += -Wl,--gc-sections +LINKFLAGS += -Wl,--start-group -lc -lm -Wl,--end-group +LINKFLAGS += -march=rv32imac_zicsr_zifencei_zba_zbb_zbkb_zbs + +# Supported programmers and debuggers +PROGRAMMERS_SUPPORTED := picotool openocd jlink +PROGRAMMER ?= picotool +OPENOCD_DEBUG_ADAPTER ?= dap + +include $(RIOTCPU)/riscv_common/Makefile.include diff --git a/cpu/rp2350_riscv/clock.c b/cpu/rp2350_riscv/clock.c new file mode 100644 index 000000000000..243b64451160 --- /dev/null +++ b/cpu/rp2350_riscv/clock.c @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Clock configuration implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "periph_cpu.h" + +void clock_reset(void) { + /* Reset the clock system */ + reset_component(RESET_PLL_SYS, RESET_PLL_SYS); +} + +/** + * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it + * @warning Make sure to call clock_reset() before this function to reset the + * clock system + * @see RP2350 Docs Chapter 8, mostly 8.2 for more details + */ +void cpu_clock_init(void) { + /* Enable the XOSC */ + xosc_start(); + + /* Setup the PLL using the XOSC as the reference clock. */ + PLL_SYS->FBDIV_INT = + PLL_FEEDBACK_DIVIDER_VALUE; /* Set the feedback divider */ + + /* Set the post-dividers for the PLL output.*/ + PLL_SYS->PRIM = PDIV; + /* Turn on PLL */ + atomic_clear(&PLL_SYS->PWR, + PLL_PWR_PD_BITS | PLL_PWR_VCOPD_BITS | PLL_PWR_POSTDIVPD_BITS); + + /* sleep 10ms to allow the PLL to stabilize */ + xosc_sleep(10); + + /* Based on the description in chapter 8 this is something that should be done + * However, it appears to cause issues and is not done by other examples on the + * internet. This needs to be investigated further. */ + + /* Wait for lock */ + /* while (!(PLL_SYS->CS & PLL_CS_LOCK_BITS)) { */ + /* Wait for the PLL to lock */ + /* } */ + + /* AUXSRC = 0x0 7:5 && SRC == 0x0 0 */ + CLOCKS->CLK_SYS_CTRL = CLK_SYS_PERI_CTRL_ENABLE_BIT; + + /* This register contains one decoded bit for each of the clock sources + * enumerated in the CTRL SRC field. The bit does not directly correlate with + * the value of the SRC field For example 0x0 is the first bit while 0x1 is + * the second bit. In some way this makes sense, in some way I lost too much + * time on this. */ + while (CLOCKS->CLK_SYS_SELECTED != CLK_SYS_SELECTED_PERI_FIELD_VALUE) { + } + + /* AUXSRC = 0x0 -> CLK_SYS Indirectly through lower line */ + CLOCKS->CLK_PERI_CTRL = CLK_PERI_CTRL_ENABLE_BIT; +} + +/** @} */ diff --git a/cpu/rp2350_riscv/cpu.c b/cpu/rp2350_riscv/cpu.c new file mode 100644 index 000000000000..6f1068732d88 --- /dev/null +++ b/cpu/rp2350_riscv/cpu.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017, 2019 Ken Rabold, JP Bonn + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_fe310 + * @{ + * + * @file cpu.c + * @brief Implementation of the CPU initialization for SiFive FE310 + * + * @author Ken Rabold + * @} + */ + +#include "board.h" +#include "cpu.h" +#include "clock_conf.h" +#include "kernel_init.h" +#include "periph/init.h" +#include "periph/uart.h" +#include "periph_conf.h" + +#include "stdio_uart.h" +#include +#include + +void gpio_reset(void) +{ + reset_component(RESET_PADS_BANK0, RESET_PADS_BANK0); + reset_component(RESET_IO_BANK0, RESET_IO_BANK0); +} + +/** + * @brief Initialize the CPU, set IRQ priorities, clocks, peripheral + */ +void cpu_init(void) +{ + riscv_init(); + + uint32_t ra_register = 0; + + __asm__ volatile ("mv %0, ra" : "=r"(ra_register)); + + /* Reset GPIO state */ + gpio_reset(); + + /* Reset clock to default state */ + clock_reset(); + + /* initialize the CPU clock */ + cpu_clock_init(); + + /* initialize the early peripherals */ + early_init(); + + /* trigger static peripheral initialization */ + periph_init(); + + board_init(); + + xosc_sleep(1000); + printf("Enabling IRQ 50\n"); + + printf("ra register at start of cpu_init: 0x%lx\n", ra_register); + + __asm__ volatile ("nop"); +} diff --git a/cpu/rp2350_riscv/doc.md b/cpu/rp2350_riscv/doc.md new file mode 100644 index 000000000000..8de5e9026d1c --- /dev/null +++ b/cpu/rp2350_riscv/doc.md @@ -0,0 +1,7 @@ +@defgroup cpu_fe310 SiFive fe310 +@ingroup cpu +@brief SiFive fe310 RISC-V MCU specific implementation. + +This module contains SiFive fe310 specific code and definition. + +@see cpu_riscv_common diff --git a/cpu/rp2350_riscv/include/clock_conf.h b/cpu/rp2350_riscv/include/clock_conf.h new file mode 100644 index 000000000000..f5137e4c57d0 --- /dev/null +++ b/cpu/rp2350_riscv/include/clock_conf.h @@ -0,0 +1,159 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Clock configuration for the RP2350 + * + * @author Tom Hert + */ + +#include "RP2350.h" +#include "macros/units.h" + +/** 1-15 MHz range + * @see hardware/regs/xosc.h and chapter 8.2.8 + */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ 0xaa0u +/** 10-30 MHz range */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_10_30MHZ 0xaa1u +/** 25-60 MHz range */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_25_60MHZ 0xaa2u +/** 40-100 MHz range */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_40_100MHZ 0xaa3u +/** Disable the XOSC */ +#define XOSC_CTRL_ENABLE_VALUE_DISABLE 0xd1eu +/** Enable the XOSC */ +#define XOSC_CTRL_ENABLE_VALUE_ENABLE 0xfabu +/** LSB of the enable bit */ +#define XOSC_CTRL_ENABLE_LSB 12u +/** Stable bit in the XOSC status register */ +#define XOSC_STATUS_STABLE_BITS 0x80000000u +/** Default crystal frequency is 12 MHz */ +#define XOSC_HZ MHZ(12u) +/** Reference divider for the PLL, set to 2 as per hardware manual */ +#define PLL_REF_DIV 2u +/** VCO frequency for the PLL, set to 750 MHz as per hardware manual */ +#define PLL_VCO_FREQ 750000000u +/** Post divider 1 for the PLL, set to 6 as per hardware manual */ +#define PLL_PD1 6u +/** Post divider 2 for the PLL, set to 2 as per hardware manual */ +#define PLL_PD2 2u +/** Power down bits for the PLL */ +#define PLL_PWR_PD_BITS 0x00000001u +/** VCO power down bits for the PLL */ +#define PLL_PWR_VCOPD_BITS 0x00000020u +/** Lock bit in the PLL control status register */ +#define PLL_CS_LOCK_BITS 0x80000000u +/** LSB of the post divider 1 in the PLL primary register */ +#define PLL_PRIM_POSTDIV1_LSB 16u +/** LSB of the post divider 2 in the PLL primary register */ +#define PLL_PRIM_POSTDIV2_LSB 12u +/** Post divider power down bits for the PLL */ +#define PLL_PWR_POSTDIVPD_BITS 0x00000008u +/** Enable bit for the peripheral clock control register */ +#define CLK_PERI_CTRL_ENABLE_BIT (1u << 11u) +/** Default CPU frequency in Hz, set to 125 MHz as per hardware manual */ +#define CPUFREQ 125000000u +/** Maximum crystal frequency */ +#define CLOCK_XOSC_MAX MHZ(15u) +/** Minimum crystal frequency */ +#define CLOCK_XOSC_MIN MHZ(5u) +/** Crystal frequency */ +#define CLOCK_XOSC (XOSC_HZ) +/** Minimum value of the post PLL clock divers */ +#define PLL_POSTDIV_MIN 1u +/** Maximum value of the post PLL clock divers */ +#define PLL_POSTDIV_MAX 7u +/** Minimum value of the PLL VCO feedback scaler */ +#define PLL_VCO_FEEDBACK_SCALE_MIN 16u +/** Maximum value of the PLL VCO feedback scaler */ +#define PLL_VCO_FEEDBACK_SCALE_MAX 320u +/** Minimum value of the clock divider applied before + * feeding in the reference clock into the PLL */ +#define PLL_REF_DIV_MIN 1u +/** Minimum value of the clock divider applied before feeding in + * the reference clock into the PLL */ +#define PLL_REF_DIV_MAX 1u +/** PLL feedback divider value, set to 125 as per hardware manual */ +#define PLL_FEEDBACK_DIVIDER_VALUE 125u +/** Enable bit for the system clock control register to select the peripheral + * clock */ +#define CLK_SYS_PERI_CTRL_ENABLE_BIT (1u << 0u) +/** Selected field value for the system clock control register +* to select the peripheral clock */ +#define CLK_SYS_SELECTED_PERI_FIELD_VALUE 2u +/** RIOT core clock frequency defined as the CPU frequency */ +#define CLOCK_CORECLOCK MHZ(12u) + +#if (PLL_VCO_FEEDBACK_SCALE_MIN < PLL_VCO_FEEDBACK_SCALE_MIN) || \ +(PLL_VCO_FEEDBACK_SCALE_MAX > PLL_VCO_FEEDBACK_SCALE_MAX) +# error "Value for PLL_VCO_FEEDBACK_SCALE out of range, check config" +#endif +#if (PLL_REF_DIV_MIN < PLL_REF_DIV_MIN) || (PLL_REF_DIV_MAX > PLL_REF_DIV_MAX) +# error "Value for PLLxosc_sleep_REF_DIV out of range, check config" +#endif +#if (PLL_POSTDIV_MIN < PLL_POSTDIV_MIN) || (PLL_POSTDIV_MAX > PLL_POSTDIV_MAX) +# error "Value for PLL_POSTDIV out of range, check config" +#endif +#if ((CLOCK_XOSC > CLOCK_XOSC_MAX) || (CLOCK_XOSC < CLOCK_XOSC_MIN)) +# error "Value for CLOCK_XOSC out of range, check config" +#endif + +/** Post divider for the PLL, calculated based on the post divider values */ +#define PDIV ((PLL_PD1 << PLL_PRIM_POSTDIV1_LSB) | (PLL_PD2 << PLL_PRIM_POSTDIV2_LSB)) +/** Feedback divider for the PLL, calculated based on the VCO frequency and +* reference clock frequency */ +#define FBDIV ((PLL_VCO_FREQ / XOSC_HZ) / PLL_REF_DIV) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configures the Crystal to run. + * @note The reference hardware manual suggests to use a 12 MHz crystal, which we + * use by default. + */ +void xosc_start(void); + +/** + * @brief Stop the crystal. + */ +void xosc_stop(void); + +/** + * @brief Sleep for a given time in milliseconds. + * @param milliseconds The time to sleep in milliseconds. + */ +void xosc_sleep(uint32_t milliseconds); + +/** + * @brief Reset the clock system. + * + * This function resets the clock system to a known state. + * It is recommended to call this function before configuring the clock system. + */ +void clock_reset(void); + +/** + * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it + * @pre Make sure to call clock_reset() before this function to reset the + * clock system + * @see RP2350 Docs Chapter 8, mostly 8.2 for more details + */ +void cpu_clock_init(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/include/core_cm33.h b/cpu/rp2350_riscv/include/core_cm33.h new file mode 100644 index 000000000000..95c4dbcc8c50 --- /dev/null +++ b/cpu/rp2350_riscv/include/core_cm33.h @@ -0,0 +1,13 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define __IM volatile const /**< Defines 'read only' structure member permissions */ +#define __OM volatile /**< Defines 'write only' structure member permissions */ +#define __IOM volatile /**< Defines 'read / write' structure member permissions */ + +#ifdef __cplusplus +} +#endif diff --git a/cpu/rp2350_riscv/include/cpu.h b/cpu/rp2350_riscv/include/cpu.h new file mode 100644 index 000000000000..2f677969fbb9 --- /dev/null +++ b/cpu/rp2350_riscv/include/cpu.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#pragma once + +/** + * @ingroup cpu_fe310 + * @{ + * + * @file + * @brief CPU specific definitions + */ + +#include "cpu_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h new file mode 100644 index 000000000000..6b272dee1ac1 --- /dev/null +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 Ken Rabold + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +#pragma once + +/** + * @ingroup cpu_fe310 + * @{ + * + * @file + * @brief CPU specific configuration options + * + * @author Ken Rabold + */ + +#include "cpu_conf_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CPU_DEFAULT_IRQ_PRIO 1u +#define CPU_IRQ_NUMOF 52u + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/include/gpio_conf.h b/cpu/rp2350_riscv/include/gpio_conf.h new file mode 100644 index 000000000000..3991542d434c --- /dev/null +++ b/cpu/rp2350_riscv/include/gpio_conf.h @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert git@annsann.eu> + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief GPIO configuration for the RP2350 + * + * @author Tom Hert + */ + +/** The number of GPIO pins available on the RP2350 */ +#define GPIO_PIN_NUMOF 30u + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Possible function values for @ref gpio_io_ctrl_t::function_select + */ +typedef enum { + /** connect pin to the SPI peripheral (MISO/MOSI/SCK depends on pin) */ + FUNCTION_SELECT_SPI = 1, + + /** connect pin to the UART peripheral (TXD/RXD depends on pin) */ + FUNCTION_SELECT_UART = 2, + + /** connect pin to the I2C peripheral (SCL/SDA depends on pin) */ + FUNCTION_SELECT_I2C = 3, + + /** connect pin to the timer for PWM (channel depends on pin) */ + FUNCTION_SELECT_PWM = 4, + + /** use pin as vanilla GPIO */ + FUNCTION_SELECT_SIO = 5, + + /** connect pin to the first PIO peripheral */ + FUNCTION_SELECT_PIO0 = 6, + + /** connect pin to the second PIO peripheral */ + FUNCTION_SELECT_PIO1 = 7, + + /** connect pin to the timer (depending on pin: external clock, + * clock output, or not supported) */ + FUNCTION_SELECT_CLOCK = 8, + + /** connect pin to the USB peripheral (function depends on pin) */ + FUNCTION_SELECT_USB = 9, + + /** Reset value, pin unconnected */ + FUNCTION_SELECT_NONE = 31, +} gpio_function_select_t; + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/include/helpers.h b/cpu/rp2350_riscv/include/helpers.h new file mode 100644 index 000000000000..6ab9b4dd9c03 --- /dev/null +++ b/cpu/rp2350_riscv/include/helpers.h @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Helper functions for atomic register operations + * + * @author Tom Hert + */ + +/** Bit to be set for an atomic XOR operation */ +#define ATOMIC_XOR_WRITE 0x1000u +/** Bit to be set for an atomic set operation */ +#define ATOMIC_BITMASK_SET_WRITE 0x2000u +/** Bits to be set for an atomic clear operation */ +#define ATOMIC_BITMASK_CLEAR_WRITE 0x3000u + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Perform an atomic XOR write to a register + * + * @param[in,out] reg Pointer to the target register + * @param[in] val Value to be XORed with the register + */ +static inline void atomic_xor(volatile uint32_t *reg, uint32_t val) { + *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_XOR_WRITE) = val; +} + +/** + * @brief Set bits in a register atomically + * + * @param[in,out] reg Pointer to the target register + * @param[in] val Bit mask of bits to set + */ +static inline void atomic_set(volatile uint32_t *reg, uint32_t val) { + *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_SET_WRITE) = val; +} + +/** + * @brief Clear bits in a register atomically + * + * @param[in,out] reg Pointer to the target register + * @param[in] val Bit mask of bits to clear + */ +static inline void atomic_clear(volatile uint32_t *reg, uint32_t val) { + *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_CLEAR_WRITE) = val; +} + +/** + * @brief Reset a component by clearing its reset bits and waiting for the reset to complete + * + * @param reset_value Bit mask of the reset bits to clear + * @param reset_done_value Bit mask of the reset done bits to wait for + */ +static inline void reset_component(uint32_t reset_value, + uint32_t reset_done_value) { + atomic_clear(&RESETS->RESET, reset_value); + while (~RESETS->RESET_DONE & reset_done_value) { + /* Wait for the reset to complete */ + } +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/include/periph_cpu.h b/cpu/rp2350_riscv/include/periph_cpu.h new file mode 100644 index 000000000000..2122d895d9eb --- /dev/null +++ b/cpu/rp2350_riscv/include/periph_cpu.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2017 Ken Rabold + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +#pragma once + +/** + * @ingroup cpu_fe310 + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author Ken Rabold + */ + +#include + +/** Overwrite the default GPIO type to use uint32_t */ +#define HAVE_GPIO_T +typedef uint32_t gpio_t; + +/* Im currently copying the original rp2040 def but this causes the other port to not be addressable (I think)*/ +#define GPIO_PIN(port, pin) (((port) & 0) | (pin)) + +/* This is a define used throughout the pico sdk */ +#define _u(x) ((uint32_t)(x)) + +#include "periph_cpu_common.h" +#include "cpu.h" +#include "core_cm33.h" /* Trick RP2350 into believing the file exists on RISCV */ +#include "RP2350.h" +#include "helpers.h" +#include "gpio_conf.h" +#include "clock_conf.h" +#include "uart_conf.h" +#include "xh3irq.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** GPIO Pin ID for oscillator debugging */ +#define OSC_DEBUG_PIN_ID 15u + +/** Reset bit for the system PLL */ +#define RESET_PLL_SYS (1u << 14u) + +/** Reset bit for the pads bank 0 */ +#define RESET_PADS_BANK0 (1u << 9u) + +/** Reset bit for UART0 peripheral */ +#define RESET_UART0 (1u << 26u) + +/** Reset bit for UART1 peripheral */ +#define RESET_UART1 (1u << 27u) + +/** Reset bit for the IO bank 0 */ +#define RESET_IO_BANK0 (1u << 6u) + +/** Input enable bit for GPIO0 in PADS_BANK0 */ +#define PADS_BANK0_GPIO0_IE_BITS (1u << 6u) + +/** Isolation bits for PADS_BANK0 */ +#define PADS_BANK0_ISO_BITS (1u << 8u) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Calculate the address of the GPIO pad register for a given pin + * @param pin The GPIO pin number + * @return The address of the GPIO pad register for the given pin + */ +static inline uint32_t calculate_gpio_pad_register_addr(gpio_t pin) { + /* Each pin has a 4 byte register, so we can calculate the address + * by adding 4 bytes for each pin, starting at the base address of PADS_BANK0 + * and adding 4 bytes to skip VOLTAGE_SELECT */ + return PADS_BANK0_BASE + 4 * (pin + 1); +} + +/** + * @brief Calculate the address of the GPIO IO status register for a given pin + * @param pin The GPIO pin number + * @return The address of the GPIO IO status register for the given pin + */ +static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { + /* Each status register is followed by a ctrl register, */ + return IO_BANK0_BASE + 8 * pin; +} + +/** + * @brief Calculate the address of the GPIO IO control register for a given + * pin + * @param pin The GPIO pin number + * @return The address of the GPIO IO control register for the given pin + */ +static inline uint32_t calculate_gpio_io_ctrl_register_addr(gpio_t pin) { + /* Each pin has a 8 byte register (4 Bytes of Status, 4 Bytes of CTRL), + * so we can calculate the address by adding 8 bytes for each pin, + * starting at the base address of IO_BANK0 */ + return calculate_gpio_io_status_register_addr(pin) + 4; +} + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/include/uart_conf.h b/cpu/rp2350_riscv/include/uart_conf.h new file mode 100644 index 000000000000..ed25e9f6eae3 --- /dev/null +++ b/cpu/rp2350_riscv/include/uart_conf.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief UART configuration for the RP2350 + * + * @author Tom Hert + */ + +#include "RP2350.h" +#include "macros/units.h" +#include "periph_cpu.h" + +/** UART baud rate in bits per second */ +#define BAUDRATE 115200u + +/** Integer baud rate divisor */ +#define IBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) / 64u) + +/** Fractional baud rate divisor */ +#define FBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) % 64u) + +/** UART enable bit in control register */ +#define UART_UARTCR_UARTEN_BITS (1u << 0u) + +/** UART receive enable bit in control register */ +#define UART_UARTCR_RXE_BITS (1u << 9u) + +/** UART transmit enable bit in control register */ +#define UART_UARTCR_TXE_BITS (1u << 8u) + +/** UART receive FIFO full flag bit in flag register */ +#define UART_UARTFR_RXFF_BITS (1u << 6u) + +/** UART transmit FIFO empty flag bit in flag register */ +#define UART_UARTFR_TXFE_BITS (1u << 7u) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_riscv/periph/Makefile b/cpu/rp2350_riscv/periph/Makefile new file mode 100644 index 000000000000..a36df249ac1d --- /dev/null +++ b/cpu/rp2350_riscv/periph/Makefile @@ -0,0 +1 @@ +include $(RIOTMAKE)/periph.mk diff --git a/cpu/rp2350_riscv/periph/gpio.c b/cpu/rp2350_riscv/periph/gpio.c new file mode 100644 index 000000000000..e949b344451d --- /dev/null +++ b/cpu/rp2350_riscv/periph/gpio.c @@ -0,0 +1,96 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief GPIO implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "periph/gpio.h" + +#include + +#include "board.h" +#include "irq.h" +#include "periph_conf.h" +#include "periph_cpu.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +int gpio_init(gpio_t pin, gpio_mode_t mode) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + + /* Clear the pin's output enable and output state */ + SIO->GPIO_OE_CLR = 1LU << pin; + SIO->GPIO_OUT_CLR = 1LU << pin; + + switch (mode) { + case GPIO_OUT: + *(uint32_t*)calculate_gpio_io_ctrl_register_addr(pin) = + FUNCTION_SELECT_SIO; + + volatile uint32_t* pad_reg = + (uint32_t*)calculate_gpio_pad_register_addr(pin); + + /* We clear all bits except the drive strength bit + * We set that to the highest one possible (12mA) + * to mimic the behavior of the pico1 GPIO driver + * (Not too sure why we do this, but it seems to be the standard) */ + *pad_reg = 0x3 << 4; + + SIO->GPIO_OE_SET = 1 << pin; /* Set the pin as output */ + + break; + default: + /* Unsupported mode */ + return -ENOTSUP; + } + return 0; +} + +bool gpio_read(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + /* Read the pin state */ + return (SIO->GPIO_IN & (1 << pin)) != 0; /* Return true if the pin is HIGH */ +} + +void gpio_set(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + SIO->GPIO_OUT_SET = 1 << pin; /* Set the pin to HIGH */ +} + +void gpio_clear(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + SIO->GPIO_OUT_CLR = 1 << pin; /* Set the pin to LOW */ +} + +void gpio_toggle(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + SIO->GPIO_OUT_XOR = 1 << pin; /* Toggle the pin state (XOR) */ +} + +void gpio_write(gpio_t pin, bool value) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + if (value) { + gpio_set(pin); /* Set the pin to HIGH */ + } else { + gpio_clear(pin); /* Set the pin to LOW */ + } +} + +/** @} */ diff --git a/cpu/rp2350_riscv/periph/uart.c b/cpu/rp2350_riscv/periph/uart.c new file mode 100644 index 000000000000..4b6c21677e72 --- /dev/null +++ b/cpu/rp2350_riscv/periph/uart.c @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief UART implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "periph/uart.h" + +#include "periph_cpu.h" + +int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) { + (void)uart; + (void)baud; + (void)rx_cb; + (void)arg; + /* Set the UART pins to the correct function */ + IO_BANK0->GPIO0_CTRL = FUNCTION_SELECT_UART; + IO_BANK0->GPIO1_CTRL = FUNCTION_SELECT_UART; + /* Clear the ISO bits */ + atomic_clear(&PADS_BANK0->GPIO0, PADS_BANK0_ISO_BITS); + atomic_clear(&PADS_BANK0->GPIO1, PADS_BANK0_ISO_BITS); + /* Set IE bit for gpio1 */ + PADS_BANK0->GPIO1 = PADS_BANK0->GPIO1 | PADS_BANK0_GPIO0_IE_BITS; + + /* We reset UART0 here, so we can be sure it is in a known state */ + reset_component(RESET_UART0, RESET_UART0); + + UART0->UARTIBRD = IBRD; + UART0->UARTFBRD = FBRD; + uart_mode(0, 8, UART_PARITY_NONE, 1); + return 0; +} + +int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, + uart_stop_bits_t stop_bits) { + (void)uart; + (void)data_bits; + (void)stop_bits; + atomic_clear(&UART0->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS | + UART_UARTCR_TXE_BITS); + + /* Set the data bits, parity, and stop bits + * Set to 8 bits (0b11) based on Table 1035 page 976 + */ + UART0->UARTLCR_H = 0b11 << 5; + + switch (parity) { + case UART_PARITY_NONE: + break; + default: + return UART_NOMODE; + } + + UART0->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS; + + return UART_OK; +} + +void uart_write(uart_t uart, const uint8_t *data, size_t len) { + (void)uart; + for (size_t i = 0; i < len; i++) { + UART0->UARTDR = data[i]; + /* Wait until the TX FIFO is empty before sending the next byte */ + while (!(UART0->UARTFR & UART_UARTFR_TXFE_BITS)) { + } + } +} + +void uart_poweron(uart_t uart) { + (void)uart; +} +void uart_poweroff(uart_t uart) { + (void)uart; +} + +/** @} */ diff --git a/cpu/rp2350_riscv/picobin_block.s b/cpu/rp2350_riscv/picobin_block.s new file mode 100644 index 000000000000..1f1747347bf5 --- /dev/null +++ b/cpu/rp2350_riscv/picobin_block.s @@ -0,0 +1,37 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/* Picobin block required for the binary. + * This defines the minimum viable image metadata to be recognized by the RP2350 bootloader + * based on RP2350 Chapter 5.9.1 */ + +.section .picobin_block, "a" /* "a" means "allocatable" (can be moved by the linker) */ + +/* PICOBIN_BLOCK_MARKER_START */ +.word 0xffffded3 + /* ITEM 0 START based on 5.9.3.1 */ + .byte 0x42 /* (size_flag == 0, item_type == PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE) */ + .byte 0x1 /* Block Size in words */ + /* image_type_flags (2 bytes) [See 5.9.3.1 / p419] */ + /* 15 -> 0 (1 for "Try before you buy" image [Wacky] */ + /* 12-14 -> 001 (RP2350 = 1) */ + /* 11 -> 0 (Reserved) */ + /* 8-10 -> 001 (EXE_CPU_ARM == 000) || (EXE_CPU_RISCV == 001^) */ + /* 6-7 -> 00 (Reserved) */ + /* 4-5 -> 10 (2) EXE Security + * (As far as I understand we cant run in EXE_SECURITY_NS on the RP2350) + * thus EXE_SECURITY_S = 2 + */ + /* 0-3 // 0001 IMAGE_TYPE_EXE */ + .hword 0b0001000100100001 + /* ITEM 0 END see 5.1.5.1 for explanation and 5.9.5.1 for the value / structure */ + .byte 0xff /* PICOBIN_BLOCK_ITEM_2BS_LAST */ + .hword 0x0001 /* Size of the item in words (predefined value) */ + .byte 0x00 /* Padding */ + /* Next Block Pointer */ + .word 0x00000000 /* Next block pointer (0 means no more blocks) */ +/* PICOBIN_BLOCK_MARKER_END */ +.word 0xab123579 /* Marker for the end of the picobin block */ diff --git a/cpu/rp2350_riscv/xosc.c b/cpu/rp2350_riscv/xosc.c new file mode 100644 index 000000000000..c398e28ec9ee --- /dev/null +++ b/cpu/rp2350_riscv/xosc.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief XOSC implementation for the RP2350 + * + * @author Tom Hert + */ + +#include + +#include "RP2350.h" +#include "board.h" +#include "macros/units.h" +#include "periph_cpu.h" + +/* Based on datasheet 8.2.4 (1ms wait time) */ +#define STARTUP_DELAY 47 +#define MAX_XOSC_COUNTER_SIZE 0xFFFF +#define SLEEP_100HZ_SPEED 12000000UL +#define CYCLES_PER_MS (SLEEP_100HZ_SPEED / 1000) + +void xosc_start(void) { + /* Set the FREQ_RANGE */ + XOSC->CTRL = XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ; + /* Set the startup delay (default 1ms) */ + XOSC->STARTUP = STARTUP_DELAY; + /* set enable bit */ + atomic_set(&XOSC->CTRL, + XOSC_CTRL_ENABLE_VALUE_ENABLE << XOSC_CTRL_ENABLE_LSB); + + while (!(XOSC->STATUS & XOSC_STATUS_STABLE_BITS)) { + /* Wait for the crystal to stabilize */ + } +} + +void xosc_sleep(uint32_t milliseconds) { + for (uint32_t i = milliseconds; i > 0; i--) { + XOSC->COUNT = CYCLES_PER_MS; + while (XOSC->COUNT != 0) {}; + } +} + +void xosc_stop(void) { + /* @TODO */ +} + +/** @} */ From 4e3fc7e873f7e7b6eee053dfa928474775bb85a8 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Fri, 26 Sep 2025 15:19:36 +0200 Subject: [PATCH 03/20] cpu/riscv_common: Add periph xh3irq support --- cpu/riscv_common/include/xh3irq.h | 72 +++++++++++++++++++++++++ cpu/riscv_common/irq_arch.c | 55 +++++++++++++++++-- cpu/riscv_common/periph/xh3irq.c | 85 ++++++++++++++++++++++++++++++ features.yaml | 3 ++ makefiles/features_existing.inc.mk | 1 + makefiles/features_modules.inc.mk | 1 + 6 files changed, 213 insertions(+), 4 deletions(-) create mode 100644 cpu/riscv_common/include/xh3irq.h create mode 100644 cpu/riscv_common/periph/xh3irq.c diff --git a/cpu/riscv_common/include/xh3irq.h b/cpu/riscv_common/include/xh3irq.h new file mode 100644 index 000000000000..caac8e2673f1 --- /dev/null +++ b/cpu/riscv_common/include/xh3irq.h @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +#include + +#include "panic.h" +#include "cpu_conf.h" + +/** + * @ingroup cpu_riscv_common + * @{ + * + * @file + * @brief xh3irq.h interrupt controller support + * + * @author Tom Hert + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** CPU specific interrupt vector table + * @see 3.2 Interrupts and IRQn_Type in RP2350.h + */ +extern const void *vector_cpu[CPU_IRQ_NUMOF]; + +/** + * Hazard3 has internal registers to individually filter which + * external IRQs appear in meip. When meip is 1, + * this indicates there is at least one external interrupt + * which is asserted (hence pending in mieipa), enabled in meiea, + * and of priority greater than or equal to the current + * preemption level in meicontext.preempt. + */ +#define MEIP_OFFSET 11 +/** Mask to extract the MEIP bit from MIP/MISE */ +#define MEIP_MASK 0x1 +/** + * Index of the highest-priority active external interrupt. + * Zero when no external interrupts with sufficient priority + * are both pending and enabled + */ +#define MEINEXT_IRQ_OFFSET 2 +/** Mask to extract the IRQ number from MEINEXT */ +#define MEINEXT_MASK 0x1FF +/** XH3IRQ Interrupt arrays have a window to access the IRQ bits */ +#define INTERRUPT_ARRAY_MASK_OFFSET 16 + +/** + * @brief Check if there are any pending interrupts + * @return 1 if there are pending interrupts, 0 otherwise + */ +uint32_t xh3irq_has_pending(void); +void xh3irq_handler(void); + +void xh3irq_enable_irq(uint32_t irq_no); + +void xh3irq_disable_irq(uint32_t irq_no); + +void xh3irq_force_irq(uint32_t irq_no); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/riscv_common/irq_arch.c b/cpu/riscv_common/irq_arch.c index 2ec80fa7e93b..3a58e0e9af56 100644 --- a/cpu/riscv_common/irq_arch.c +++ b/cpu/riscv_common/irq_arch.c @@ -30,6 +30,7 @@ #include "sched.h" #include "plic.h" #include "clic.h" +#include "xh3irq.h" #include "architecture.h" #if MODULE_PERIPH_XH3IRQ || DOXYGEN @@ -39,7 +40,7 @@ #include "vendor/riscv_csr.h" /* Default state of mstatus register */ -#define MSTATUS_DEFAULT (MSTATUS_MPP | MSTATUS_MPIE) +#define MSTATUS_DEFAULT (MSTATUS_MPP | MSTATUS_MPIE) volatile int riscv_in_isr = 0; @@ -87,8 +88,7 @@ void riscv_irq_init(void) /** * @brief Global trap and interrupt handler */ -__attribute((used)) -static void handle_trap(uword_t mcause) +__attribute((used)) static void handle_trap(uword_t mcause) { /* Tell RIOT to set sched_context_switch_request instead of * calling thread_yield(). */ @@ -96,11 +96,55 @@ static void handle_trap(uword_t mcause) uword_t trap = mcause & CPU_CSR_MCAUSE_CAUSE_MSK; +#ifdef DEVELHELP + printf("Trap: mcause=0x%" PRIx32 " mepc=0x%lx mtval=0x%lx\n", + (uint32_t)mcause, read_csr(mepc), read_csr(mtval)); + + /* See https://riscv.github.io/riscv-isa-manual/snapshot/privileged/#mcause */ + if ((mcause & ~MCAUSE_INT) <= 0xb) { + const char *error_messages[] = { + "Instruction address misaligned", + "Instruction access fault", + "Illegal instruction", + "Breakpoint", + "Load address misaligned", + "Load access fault", + "Store/AMO address misaligned", + "Store/AMO access fault", + "Environment call from U-mode", + "Environment call from S-mode", + NULL, + "Environment call from M-mode", + "Instruction page fault", + "Load page fault", + NULL, + "Store/AMO page fault", + "Double trap", + NULL, + "Software check", + "Hardware error" + }; + + uword_t cause_code = mcause & ~MCAUSE_INT; + if (cause_code <= (ARRAY_SIZE(error_messages) - 1)) { + if (error_messages[cause_code] != NULL) { + printf("Machine Cause Error 0x%lx: %s\n", + cause_code, error_messages[cause_code] + ); + } else { + printf("Machine Cause indicates that 0x%lx" + " is a reserved or custom cause code\n", + cause_code + ); + } + } + } +#endif + /* Check for INT or TRAP */ if ((mcause & MCAUSE_INT) == MCAUSE_INT) { /* Cause is an interrupt - determine type */ switch (mcause & MCAUSE_CAUSE) { - #ifdef MODULE_PERIPH_CORETIMER case IRQ_M_TIMER: /* Handle timer interrupt */ @@ -112,6 +156,9 @@ static void handle_trap(uword_t mcause) if (IS_ACTIVE(MODULE_PERIPH_PLIC)) { plic_isr_handler(); } + if (IS_ACTIVE(MODULE_PERIPH_XH3IRQ)) { + xh3irq_handler(); + } break; default: diff --git a/cpu/riscv_common/periph/xh3irq.c b/cpu/riscv_common/periph/xh3irq.c new file mode 100644 index 000000000000..9d3fc90c9b34 --- /dev/null +++ b/cpu/riscv_common/periph/xh3irq.c @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#include + +#include "bit.h" +#include "xh3irq.h" + +uint32_t xh3irq_has_pending(void) +{ + /* + * Get MEIP which is the external interrupt pending bit + * from the Machine Interrupt Pending Register address + */ + uint32_t mip_reg = read_csr(0x344); + uint32_t meip = bit_check32(&mip_reg, MEIP_OFFSET); + + return (meip != 0); +} + +void xh3irq_handler(void) +{ + /* + * Get MEINEXT at 0xbe4 which is the next highest interrupt to handle (Bit 2-10). + * This will also automagically clear the interrupt (See 3.8.6.1.2.) + * + * Contains the index of the highest-priority external interrupt + * which is both asserted in meipa and enabled in meiea, left- + * shifted by 2 so that it can be used to index an array of 32-bit + * function pointers. If there is no such interrupt, the MSB is set. + */ + uint32_t meinext = (read_csr(0xBE4) >> MEINEXT_IRQ_OFFSET) & MEINEXT_MASK; + + void (*isr)(void) = (void (*)(void)) vector_cpu[meinext]; +#ifdef DEVELHELP + printf("Calling isr %p for irq %ld\n", isr, meinext); +#endif + isr(); +} + +void _meiea_set_req_bit(uint32_t irq_no, uint32_t bit_val) +{ + uint32_t index = irq_no / INTERRUPT_ARRAY_MASK_OFFSET; + uint32_t mask = bit_val << (irq_no % INTERRUPT_ARRAY_MASK_OFFSET); + + /* + * 0xbe0 is the external interrupt enable array. + * The array contains a read-write bit for each external interrupt request: + * a 1 bit indicates that interrupt is currently enabled. + * There are up to 512 external interrupts. + * The upper half of this register contains a 16-bit window into the full + * 512-bit vector. The window is indexed by the 5 LSBs of the write data. + */ + __asm__ volatile( + "csrs 0xbe0, %0\n" + : : "r"(index | (mask << INTERRUPT_ARRAY_MASK_OFFSET)) + ); +} + +void xh3irq_enable_irq(uint32_t irq_no) +{ + _meiea_set_req_bit(irq_no, 1); +} + +void xh3irq_disable_irq(uint32_t irq_no) +{ + _meiea_set_req_bit(irq_no, 0); +} + +void xh3irq_force_irq(uint32_t irq_no) +{ + uint32_t index = irq_no / INTERRUPT_ARRAY_MASK_OFFSET; + uint32_t mask = 1u << (irq_no % INTERRUPT_ARRAY_MASK_OFFSET); + + /** + * 0xbe2 is the external interrupt force array. + * See _meiea_set_req_bit / 0xbe0 for more details. + */ + __asm__ volatile( + "csrs 0xbe2, %0\n" + : : "r"(index | (mask << INTERRUPT_ARRAY_MASK_OFFSET))); +} diff --git a/features.yaml b/features.yaml index 9777a18128ab..d528ebaddd31 100644 --- a/features.yaml +++ b/features.yaml @@ -829,6 +829,9 @@ groups: help: A RISC-V Core-local Interrupt Controller (CLIC) peripheral is present. - name: periph_plic help: A RISC-V Platform-local Interrupt Controller (PLIC) peripheral is present. + - name: periph_xh3irq + help: An XH3IRQ peripheral is present. This is a special interrupt controller + for the Hazard3 used by the RP2350 - title: Cryptographic Features help: Hardware acceleration for cryptographic primitives, hardware random diff --git a/makefiles/features_existing.inc.mk b/makefiles/features_existing.inc.mk index dfeb27b1d693..3f73608ce82c 100644 --- a/makefiles/features_existing.inc.mk +++ b/makefiles/features_existing.inc.mk @@ -258,6 +258,7 @@ FEATURES_EXISTING := \ periph_wdt \ periph_wdt_cb \ periph_wdt_warning_period \ + periph_xh3irq \ picolibc \ pio_i2c \ puf_sram \ diff --git a/makefiles/features_modules.inc.mk b/makefiles/features_modules.inc.mk index 975cf003c0c2..38dc3faff6f8 100644 --- a/makefiles/features_modules.inc.mk +++ b/makefiles/features_modules.inc.mk @@ -57,6 +57,7 @@ PERIPH_IGNORE_MODULES := \ periph_uart_rxstart_irq \ periph_wdog \ periph_wdt_auto_start \ + periph_xh3irq \ # PERIPH_MODULES := $(filter-out $(PERIPH_IGNORE_MODULES),\ $(filter periph_%,$(USEMODULE))) From 9a1fce24c36d7ceadcf080c069c9bea0fa89adbf Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 13:57:00 +0200 Subject: [PATCH 04/20] cpu/rp2350_riscv: add xh3irq support --- boards/rpi-pico-2-riscv/board.c | 3 - boards/rpi-pico-2-riscv/doc.md | 8 +- boards/rpi-pico-2-riscv/include/board.h | 5 +- boards/rpi-pico-2-riscv/include/periph_conf.h | 3 + cpu/riscv_common/include/xh3irq.h | 18 +++ cpu/rp2350_riscv/clock.c | 2 +- cpu/rp2350_riscv/cpu.c | 14 +- cpu/rp2350_riscv/doc.md | 10 +- cpu/rp2350_riscv/include/clock_conf.h | 4 +- cpu/rp2350_riscv/include/core_cm33.h | 6 + cpu/rp2350_riscv/include/cpu.h | 10 +- cpu/rp2350_riscv/include/cpu_conf.h | 73 +++++++-- cpu/rp2350_riscv/include/gpio_conf.h | 2 +- cpu/rp2350_riscv/include/helpers.h | 2 +- cpu/rp2350_riscv/include/periph_cpu.h | 28 ++-- cpu/rp2350_riscv/include/uart_conf.h | 2 +- cpu/rp2350_riscv/periph/gpio.c | 4 +- cpu/rp2350_riscv/periph/uart.c | 2 +- cpu/rp2350_riscv/vectors.c | 141 ++++++++++++++++++ features.yaml | 2 +- 20 files changed, 274 insertions(+), 65 deletions(-) create mode 100644 cpu/rp2350_riscv/vectors.c diff --git a/boards/rpi-pico-2-riscv/board.c b/boards/rpi-pico-2-riscv/board.c index 31c2557905e2..49f7740789db 100644 --- a/boards/rpi-pico-2-riscv/board.c +++ b/boards/rpi-pico-2-riscv/board.c @@ -12,7 +12,4 @@ void board_init(void) { * This is needed, esp. when the LED is used via * the define macros */ gpio_init(LED0_PIN_ID, GPIO_OUT); - - gpio_init(OSC_DEBUG_PIN_ID, GPIO_OUT); - gpio_init(OSC_DEBUG_PIN_ID_2, GPIO_OUT); } diff --git a/boards/rpi-pico-2-riscv/doc.md b/boards/rpi-pico-2-riscv/doc.md index fc041d1f9d46..73277fe212a5 100644 --- a/boards/rpi-pico-2-riscv/doc.md +++ b/boards/rpi-pico-2-riscv/doc.md @@ -1,9 +1,9 @@ -@defgroup boards_rpi_pico_2 Raspberry Pi Pico 2 +@defgroup boards_rpi_pico_2_riscv Raspberry Pi Pico 2 @ingroup boards -@brief Support for the RP2350 based Raspberry Pi Pico board +@brief Support for the RP2350 RISCV based Raspberry Pi Pico board @warning The support for the Raspberry Pi Pico 2 is still in a very early stage! -See [Known Issues](#rpi_pico_2_known_issues). +See [Known Issues](#rpi_pico_2_riscv_known_issues). ## Overview @@ -100,7 +100,7 @@ However, it does not allow for debugging using GDB. RIOT will download and install the Picotool locally in the RIOT folder. This process will take some minutes to complete. -## Known Issues {#rpi_pico_2_known_issues} +## Known Issues {#rpi_pico_2_riscv_known_issues} Currently RP2350 support is rather minimal, as such peripheral support is extremely limited. diff --git a/boards/rpi-pico-2-riscv/include/board.h b/boards/rpi-pico-2-riscv/include/board.h index 2aaf6b1db423..fafbc14a88c9 100644 --- a/boards/rpi-pico-2-riscv/include/board.h +++ b/boards/rpi-pico-2-riscv/include/board.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup boards_rpi_pico_2 + * @ingroup boards_rpi_pico_2_riscv * @{ * * @file @@ -28,9 +28,6 @@ #define LED0_TOGGLE gpio_toggle(LED0_PIN_ID) #define LED0_NAME "LED(Green)" -#define OSC_DEBUG_PIN_ID 15u -#define OSC_DEBUG_PIN_ID_2 14u - #ifdef __cplusplus extern "C" { #endif diff --git a/boards/rpi-pico-2-riscv/include/periph_conf.h b/boards/rpi-pico-2-riscv/include/periph_conf.h index fe5f5d4972ed..4f6f16422484 100644 --- a/boards/rpi-pico-2-riscv/include/periph_conf.h +++ b/boards/rpi-pico-2-riscv/include/periph_conf.h @@ -17,6 +17,7 @@ * @author Tom Hert */ +#include "kernel_defines.h" #include #include "kernel_defines.h" @@ -59,3 +60,5 @@ static const uart_conf_t uart_config[] = { #ifdef __cplusplus } #endif + +/** @} */ diff --git a/cpu/riscv_common/include/xh3irq.h b/cpu/riscv_common/include/xh3irq.h index caac8e2673f1..89c6489345e1 100644 --- a/cpu/riscv_common/include/xh3irq.h +++ b/cpu/riscv_common/include/xh3irq.h @@ -57,12 +57,30 @@ extern const void *vector_cpu[CPU_IRQ_NUMOF]; * @return 1 if there are pending interrupts, 0 otherwise */ uint32_t xh3irq_has_pending(void); + +/** + * @brief The main IRQ handler, called from the assembly IRQ handler + * @note This function must clear the pending interrupt in the interrupt controller + */ void xh3irq_handler(void); +/** + * @brief Enable the given IRQ number + * @param irq_no The IRQ number to enable + */ void xh3irq_enable_irq(uint32_t irq_no); +/** + * @brief Disable the given IRQ number + * @param irq_no The IRQ number to disable + */ void xh3irq_disable_irq(uint32_t irq_no); +/** + * @brief Force the given IRQ number to be pending + * @param irq_no The IRQ number to force + * @note The IRQ still must be enabled to be handled + */ void xh3irq_force_irq(uint32_t irq_no); #ifdef __cplusplus diff --git a/cpu/rp2350_riscv/clock.c b/cpu/rp2350_riscv/clock.c index 243b64451160..af6047f88f02 100644 --- a/cpu/rp2350_riscv/clock.c +++ b/cpu/rp2350_riscv/clock.c @@ -5,7 +5,7 @@ */ /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file diff --git a/cpu/rp2350_riscv/cpu.c b/cpu/rp2350_riscv/cpu.c index 6f1068732d88..7f92758fdde1 100644 --- a/cpu/rp2350_riscv/cpu.c +++ b/cpu/rp2350_riscv/cpu.c @@ -1,19 +1,17 @@ /* - * Copyright (C) 2017, 2019 Ken Rabold, JP Bonn - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only */ /** - * @ingroup cpu_fe310 + * @ingroup cpu_rp2350_riscv * @{ * * @file cpu.c - * @brief Implementation of the CPU initialization for SiFive FE310 + * @brief Implementation of the CPU initialization for RP2350 * - * @author Ken Rabold + * @author Tom Hert * @} */ diff --git a/cpu/rp2350_riscv/doc.md b/cpu/rp2350_riscv/doc.md index 8de5e9026d1c..f9d0b1664f2d 100644 --- a/cpu/rp2350_riscv/doc.md +++ b/cpu/rp2350_riscv/doc.md @@ -1,7 +1,5 @@ -@defgroup cpu_fe310 SiFive fe310 -@ingroup cpu -@brief SiFive fe310 RISC-V MCU specific implementation. +@defgroup cpu_rp2350_riscv RP2350 RISCV MCUs +@ingroup cpu +@brief RP2350 RISCV MCU code and definitions -This module contains SiFive fe310 specific code and definition. - -@see cpu_riscv_common +This module contains the code and definitions for MCUs of the RP2350 RISCV family used by the Pi Pico 2. diff --git a/cpu/rp2350_riscv/include/clock_conf.h b/cpu/rp2350_riscv/include/clock_conf.h index f5137e4c57d0..e2609ff0c704 100644 --- a/cpu/rp2350_riscv/include/clock_conf.h +++ b/cpu/rp2350_riscv/include/clock_conf.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file @@ -89,7 +89,7 @@ * clock */ #define CLK_SYS_PERI_CTRL_ENABLE_BIT (1u << 0u) /** Selected field value for the system clock control register -* to select the peripheral clock */ + * to select the peripheral clock */ #define CLK_SYS_SELECTED_PERI_FIELD_VALUE 2u /** RIOT core clock frequency defined as the CPU frequency */ #define CLOCK_CORECLOCK MHZ(12u) diff --git a/cpu/rp2350_riscv/include/core_cm33.h b/cpu/rp2350_riscv/include/core_cm33.h index 95c4dbcc8c50..f5e13719a4d3 100644 --- a/cpu/rp2350_riscv/include/core_cm33.h +++ b/cpu/rp2350_riscv/include/core_cm33.h @@ -1,3 +1,9 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + #pragma once #ifdef __cplusplus diff --git a/cpu/rp2350_riscv/include/cpu.h b/cpu/rp2350_riscv/include/cpu.h index 2f677969fbb9..d995f19efcc7 100644 --- a/cpu/rp2350_riscv/include/cpu.h +++ b/cpu/rp2350_riscv/include/cpu.h @@ -1,15 +1,13 @@ /* - * Copyright (C) 2023 Gunar Schorcht - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License v2.1. See the file LICENSE in the top level - * directory for more details. + * SPDX-FileCopyrightText: 2025 Tom Hert git@annsann.eu> + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only */ #pragma once /** - * @ingroup cpu_fe310 + * @ingroup cpu_rp2350_riscv * @{ * * @file diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h index 6b272dee1ac1..aa122483fb6d 100644 --- a/cpu/rp2350_riscv/include/cpu_conf.h +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -1,21 +1,18 @@ /* - * Copyright (C) 2017 Ken Rabold - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for more - * details. + * SPDX-FileCopyrightText: 2025 Tom Hert git@annsann.eu> + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only */ #pragma once /** - * @ingroup cpu_fe310 + * @ingroup cpu_rp2350_riscv * @{ - * * @file - * @brief CPU specific configuration options + * @brief CPU configuration for the RP2350 * - * @author Ken Rabold + * @author Tom Hert */ #include "cpu_conf_common.h" @@ -27,6 +24,64 @@ extern "C" { #define CPU_DEFAULT_IRQ_PRIO 1u #define CPU_IRQ_NUMOF 52u +/** + * @brief Interrupt numbers for RP2350 RISC-V + */ +typedef enum { + TIMER0_IRQ_0_IRQn = 0, /**< Timer 0 interrupt 0 */ + TIMER0_IRQ_1_IRQn = 1, /**< Timer 0 interrupt 1 */ + TIMER0_IRQ_2_IRQn = 2, /**< Timer 0 interrupt 2 */ + TIMER0_IRQ_3_IRQn = 3, /**< Timer 0 interrupt 3 */ + TIMER1_IRQ_0_IRQn = 4, /**< Timer 1 interrupt 0 */ + TIMER1_IRQ_1_IRQn = 5, /**< Timer 1 interrupt 1 */ + TIMER1_IRQ_2_IRQn = 6, /**< Timer 1 interrupt 2 */ + TIMER1_IRQ_3_IRQn = 7, /**< Timer 1 interrupt 3 */ + PWM_IRQ_WRAP_0_IRQn = 8, /**< PWM wrap interrupt 0 */ + PWM_IRQ_WRAP_1_IRQn = 9, /**< PWM wrap interrupt 1 */ + DMA_IRQ_0_IRQn = 10, /**< DMA interrupt 0 */ + DMA_IRQ_1_IRQn = 11, /**< DMA interrupt 1 */ + DMA_IRQ_2_IRQn = 12, /**< DMA interrupt 2 */ + DMA_IRQ_3_IRQn = 13, /**< DMA interrupt 3 */ + USBCTRL_IRQ_IRQn = 14, /**< USB controller interrupt */ + PIO0_IRQ_0_IRQn = 15, /**< PIO 0 interrupt 0 */ + PIO0_IRQ_1_IRQn = 16, /**< PIO 0 interrupt 1 */ + PIO1_IRQ_0_IRQn = 17, /**< PIO 1 interrupt 0 */ + PIO1_IRQ_1_IRQn = 18, /**< PIO 1 interrupt 1 */ + PIO2_IRQ_0_IRQn = 19, /**< PIO 2 interrupt 0 */ + PIO2_IRQ_1_IRQn = 20, /**< PIO 2 interrupt 1 */ + IO_IRQ_BANK0_IRQn = 21, /**< IO bank 0 interrupt */ + IO_IRQ_BANK0_NS_IRQn = 22, /**< IO bank 0 non-secure interrupt */ + IO_IRQ_QSPI_IRQn = 23, /**< IO QSPI interrupt */ + IO_IRQ_QSPI_NS_IRQn = 24, /**< IO QSPI non-secure interrupt */ + SIO_IRQ_FIFO_IRQn = 25, /**< SIO FIFO interrupt */ + SIO_IRQ_BELL_IRQn = 26, /**< SIO bell interrupt */ + SIO_IRQ_FIFO_NS_IRQn = 27, /**< SIO FIFO non-secure interrupt */ + SIO_IRQ_BELL_NS_IRQn = 28, /**< SIO bell non-secure interrupt */ + SIO_IRQ_MTIMECMP_IRQn = 29, /**< SIO MTIMECMP interrupt */ + CLOCKS_IRQ_IRQn = 30, /**< Clocks interrupt */ + SPI0_IRQ_IRQn = 31, /**< SPI 0 interrupt */ + SPI1_IRQ_IRQn = 32, /**< SPI 1 interrupt */ + UART0_IRQ_IRQn = 33, /**< UART 0 interrupt */ + UART1_IRQ_IRQn = 34, /**< UART 1 interrupt */ + ADC_IRQ_FIFO_IRQn = 35, /**< ADC FIFO interrupt */ + I2C0_IRQ_IRQn = 36, /**< I2C 0 interrupt */ + I2C1_IRQ_IRQn = 37, /**< I2C 1 interrupt */ + OTP_IRQ_IRQn = 38, /**< OTP interrupt */ + TRNG_IRQ_IRQn = 39, /**< TRNG interrupt */ + PROC0_IRQ_CTI_IRQn = 40, /**< Processor 0 CTI interrupt */ + PROC1_IRQ_CTI_IRQn = 41, /**< Processor 1 CTI interrupt */ + PLL_SYS_IRQ_IRQn = 42, /**< PLL SYS interrupt */ + PLL_USB_IRQ_IRQn = 43, /**< PLL USB interrupt */ + POWMAN_IRQ_POW_IRQn = 44, /**< Power manager power interrupt */ + POWMAN_IRQ_TIMER_IRQn = 45, /**< Power manager timer interrupt */ + SPAREIRQ_IRQ_0_IRQn = 46, /**< Spare interrupt 0 */ + SPAREIRQ_IRQ_1_IRQn = 47, /**< Spare interrupt 1 */ + SPAREIRQ_IRQ_2_IRQn = 48, /**< Spare interrupt 2 */ + SPAREIRQ_IRQ_3_IRQn = 49, /**< Spare interrupt 3 */ + SPAREIRQ_IRQ_4_IRQn = 50, /**< Spare interrupt 4 */ + SPAREIRQ_IRQ_5_IRQn = 51 /**< Spare interrupt 5 */ +} IRQn_Type; + #ifdef __cplusplus } #endif diff --git a/cpu/rp2350_riscv/include/gpio_conf.h b/cpu/rp2350_riscv/include/gpio_conf.h index 3991542d434c..4408392c00ad 100644 --- a/cpu/rp2350_riscv/include/gpio_conf.h +++ b/cpu/rp2350_riscv/include/gpio_conf.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file diff --git a/cpu/rp2350_riscv/include/helpers.h b/cpu/rp2350_riscv/include/helpers.h index 6ab9b4dd9c03..f88b7d0950a3 100644 --- a/cpu/rp2350_riscv/include/helpers.h +++ b/cpu/rp2350_riscv/include/helpers.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file diff --git a/cpu/rp2350_riscv/include/periph_cpu.h b/cpu/rp2350_riscv/include/periph_cpu.h index 2122d895d9eb..4a0f3a3bf2df 100644 --- a/cpu/rp2350_riscv/include/periph_cpu.h +++ b/cpu/rp2350_riscv/include/periph_cpu.h @@ -1,21 +1,19 @@ /* - * Copyright (C) 2017 Ken Rabold - * - * This file is subject to the terms and conditions of the GNU Lesser General - * Public License v2.1. See the file LICENSE in the top level directory for more - * details. + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only */ #pragma once /** - * @ingroup cpu_fe310 + * @ingroup cpu_rp2350_riscv * @{ * * @file - * @brief CPU specific definitions for internal peripheral handling + * @brief Peripheral CPU definitions for the RP2350 * - * @author Ken Rabold + * @author Tom Hert */ #include @@ -24,10 +22,14 @@ #define HAVE_GPIO_T typedef uint32_t gpio_t; -/* Im currently copying the original rp2040 def but this causes the other port to not be addressable (I think)*/ +/** + * @brief Macro to create a GPIO pin identifier + * @param port The GPIO port (Currently only GPIO0) + * @param pin The GPIO pin number + */ #define GPIO_PIN(port, pin) (((port) & 0) | (pin)) -/* This is a define used throughout the pico sdk */ +/** This is a define used throughout the pico sdk */ #define _u(x) ((uint32_t)(x)) #include "periph_cpu_common.h" @@ -68,9 +70,6 @@ extern "C" { /** Isolation bits for PADS_BANK0 */ #define PADS_BANK0_ISO_BITS (1u << 8u) -#ifdef __cplusplus -extern "C" { -#endif /** * @brief Calculate the address of the GPIO pad register for a given pin @@ -90,7 +89,7 @@ static inline uint32_t calculate_gpio_pad_register_addr(gpio_t pin) { * @return The address of the GPIO IO status register for the given pin */ static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { - /* Each status register is followed by a ctrl register, */ + /* Each status register is followed by a ctrl register */ return IO_BANK0_BASE + 8 * pin; } @@ -108,7 +107,6 @@ static inline uint32_t calculate_gpio_io_ctrl_register_addr(gpio_t pin) { } -/** @} */ #ifdef __cplusplus } diff --git a/cpu/rp2350_riscv/include/uart_conf.h b/cpu/rp2350_riscv/include/uart_conf.h index ed25e9f6eae3..f886e974bc3c 100644 --- a/cpu/rp2350_riscv/include/uart_conf.h +++ b/cpu/rp2350_riscv/include/uart_conf.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file diff --git a/cpu/rp2350_riscv/periph/gpio.c b/cpu/rp2350_riscv/periph/gpio.c index e949b344451d..4ba74bbfa513 100644 --- a/cpu/rp2350_riscv/periph/gpio.c +++ b/cpu/rp2350_riscv/periph/gpio.c @@ -5,7 +5,7 @@ */ /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file @@ -42,7 +42,7 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) { volatile uint32_t* pad_reg = (uint32_t*)calculate_gpio_pad_register_addr(pin); - /* We clear all bits except the drive strength bit + /* We clear all bits except the drive strength bit. * We set that to the highest one possible (12mA) * to mimic the behavior of the pico1 GPIO driver * (Not too sure why we do this, but it seems to be the standard) */ diff --git a/cpu/rp2350_riscv/periph/uart.c b/cpu/rp2350_riscv/periph/uart.c index 4b6c21677e72..3ea1f97d3319 100644 --- a/cpu/rp2350_riscv/periph/uart.c +++ b/cpu/rp2350_riscv/periph/uart.c @@ -5,7 +5,7 @@ */ /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_riscv * @{ * * @file diff --git a/cpu/rp2350_riscv/vectors.c b/cpu/rp2350_riscv/vectors.c new file mode 100644 index 000000000000..0f3df6495478 --- /dev/null +++ b/cpu/rp2350_riscv/vectors.c @@ -0,0 +1,141 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Interrupt vector table for the RP2350 + * + * @author Tom Hert + */ + +#include "cpu_conf.h" +#include "xh3irq.h" +#include "panic.h" +#include + +#define WEAK_DEFAULT __attribute__((weak, alias("dummy_handler"))) + +/* define a local dummy handler as it needs to be in the same compilation unit + * as the alias definition */ +void dummy_handler(void) +{ + core_panic(PANIC_GENERAL_ERROR, "DUMMY HANDLER"); +} + +/* rp2350 specific interrupt vector */ +WEAK_DEFAULT void isr_timer0_0(void); +WEAK_DEFAULT void isr_timer0_1(void); +WEAK_DEFAULT void isr_timer0_2(void); +WEAK_DEFAULT void isr_timer0_3(void); +WEAK_DEFAULT void isr_timer1_0(void); +WEAK_DEFAULT void isr_timer1_1(void); +WEAK_DEFAULT void isr_timer1_2(void); +WEAK_DEFAULT void isr_timer1_3(void); +WEAK_DEFAULT void isr_pwm_wrap_0(void); +WEAK_DEFAULT void isr_pwm_wrap_1(void); +WEAK_DEFAULT void isr_dma_0(void); +WEAK_DEFAULT void isr_dma_1(void); +WEAK_DEFAULT void isr_dma_2(void); +WEAK_DEFAULT void isr_dma_3(void); +WEAK_DEFAULT void isr_usbctrl(void); +WEAK_DEFAULT void isr_pio0_0(void); +WEAK_DEFAULT void isr_pio0_1(void); +WEAK_DEFAULT void isr_pio1_0(void); +WEAK_DEFAULT void isr_pio1_1(void); +WEAK_DEFAULT void isr_pio2_0(void); +WEAK_DEFAULT void isr_pio2_1(void); +WEAK_DEFAULT void isr_io_bank0(void); +WEAK_DEFAULT void isr_io_bank0_ns(void); +WEAK_DEFAULT void isr_io_qspi(void); +WEAK_DEFAULT void isr_io_qspi_ns(void); +WEAK_DEFAULT void isr_sio_fifo(void); +WEAK_DEFAULT void isr_sio_bell(void); +WEAK_DEFAULT void isr_sio_fifo_ns(void); +WEAK_DEFAULT void isr_sio_bell_ns(void); +WEAK_DEFAULT void isr_sio_mtimecmp(void); +WEAK_DEFAULT void isr_clocks(void); +WEAK_DEFAULT void isr_spi0(void); +WEAK_DEFAULT void isr_spi1(void); +WEAK_DEFAULT void isr_uart0(void); +WEAK_DEFAULT void isr_uart1(void); +WEAK_DEFAULT void isr_adc_fifo(void); +WEAK_DEFAULT void isr_i2c0(void); +WEAK_DEFAULT void isr_i2c1(void); +WEAK_DEFAULT void isr_otp(void); +WEAK_DEFAULT void isr_trng(void); +WEAK_DEFAULT void isr_proc0_cti(void); +WEAK_DEFAULT void isr_proc1_cti(void); +WEAK_DEFAULT void isr_pll_sys(void); +WEAK_DEFAULT void isr_pll_usb(void); +WEAK_DEFAULT void isr_powman_pow(void); +WEAK_DEFAULT void isr_powman_timer(void); +WEAK_DEFAULT void isr_spareirq_0(void); +WEAK_DEFAULT void isr_spareirq_1(void); +WEAK_DEFAULT void isr_spareirq_2(void); +WEAK_DEFAULT void isr_spareirq_3(void); +WEAK_DEFAULT void isr_spareirq_4(void); +WEAK_DEFAULT void isr_spareirq_5(void); + +/** CPU specific interrupt vector table + * @see 3.2 Interrupts and IRQn_Type in RP2350.h + */ +const void* vector_cpu[CPU_IRQ_NUMOF] = { + (void*)isr_timer0_0, /* 0 TIMER0_IRQ_0 */ + (void*)isr_timer0_1, /* 1 TIMER0_IRQ_1 */ + (void*)isr_timer0_2, /* 2 TIMER0_IRQ_2 */ + (void*)isr_timer0_3, /* 3 TIMER0_IRQ_3 */ + (void*)isr_timer1_0, /* 4 TIMER1_IRQ_0 */ + (void*)isr_timer1_1, /* 5 TIMER1_IRQ_1 */ + (void*)isr_timer1_2, /* 6 TIMER1_IRQ_2 */ + (void*)isr_timer1_3, /* 7 TIMER1_IRQ_3 */ + (void*)isr_pwm_wrap_0, /* 8 PWM_IRQ_WRAP_0 */ + (void*)isr_pwm_wrap_1, /* 9 PWM_IRQ_WRAP_1 */ + (void*)isr_dma_0, /* 10 DMA_IRQ_0 */ + (void*)isr_dma_1, /* 11 DMA_IRQ_1 */ + (void*)isr_dma_2, /* 12 DMA_IRQ_2 */ + (void*)isr_dma_3, /* 13 DMA_IRQ_3 */ + (void*)isr_usbctrl, /* 14 USBCTRL_IRQ */ + (void*)isr_pio0_0, /* 15 PIO0_IRQ_0 */ + (void*)isr_pio0_1, /* 16 PIO0_IRQ_1 */ + (void*)isr_pio1_0, /* 17 PIO1_IRQ_0 */ + (void*)isr_pio1_1, /* 18 PIO1_IRQ_1 */ + (void*)isr_pio2_0, /* 19 PIO2_IRQ_0 */ + (void*)isr_pio2_1, /* 20 PIO2_IRQ_1 */ + (void*)isr_io_bank0, /* 21 IO_IRQ_BANK0 */ + (void*)isr_io_bank0_ns, /* 22 IO_IRQ_BANK0_NS */ + (void*)isr_io_qspi, /* 23 IO_IRQ_QSPI */ + (void*)isr_io_qspi_ns, /* 24 IO_IRQ_QSPI_NS */ + (void*)isr_sio_fifo, /* 25 SIO_IRQ_FIFO */ + (void*)isr_sio_bell, /* 26 SIO_IRQ_BELL */ + (void*)isr_sio_fifo_ns, /* 27 SIO_IRQ_FIFO_NS */ + (void*)isr_sio_bell_ns, /* 28 SIO_IRQ_BELL_NS */ + (void*)isr_sio_mtimecmp, /* 29 SIO_IRQ_MTIMECMP */ + (void*)isr_clocks, /* 30 CLOCKS_IRQ */ + (void*)isr_spi0, /* 31 SPI0_IRQ */ + (void*)isr_spi1, /* 32 SPI1_IRQ */ + (void*)isr_uart0, /* 33 UART0_IRQ */ + (void*)isr_uart1, /* 34 UART1_IRQ */ + (void*)isr_adc_fifo, /* 35 ADC_IRQ_FIFO */ + (void*)isr_i2c0, /* 36 I2C0_IRQ */ + (void*)isr_i2c1, /* 37 I2C1_IRQ */ + (void*)isr_otp, /* 38 OTP_IRQ */ + (void*)isr_trng, /* 39 TRNG_IRQ */ + (void*)isr_proc0_cti, /* 40 PROC0_IRQ_CTI */ + (void*)isr_proc1_cti, /* 41 PROC1_IRQ_CTI */ + (void*)isr_pll_sys, /* 42 PLL_SYS_IRQ */ + (void*)isr_pll_usb, /* 43 PLL_USB_IRQ */ + (void*)isr_powman_pow, /* 44 POWMAN_IRQ_POW */ + (void*)isr_powman_timer, /* 45 POWMAN_IRQ_TIMER */ + (void*)isr_spareirq_0, /* 46 SPAREIRQ_IRQ_0 */ + (void*)isr_spareirq_1, /* 47 SPAREIRQ_IRQ_1 */ + (void*)isr_spareirq_2, /* 48 SPAREIRQ_IRQ_2 */ + (void*)isr_spareirq_3, /* 49 SPAREIRQ_IRQ_3 */ + (void*)isr_spareirq_4, /* 50 SPAREIRQ_IRQ_4 */ + (void*)isr_spareirq_5, /* 51 SPAREIRQ_IRQ_5 */ +}; diff --git a/features.yaml b/features.yaml index d528ebaddd31..5c98b23e43c6 100644 --- a/features.yaml +++ b/features.yaml @@ -831,7 +831,7 @@ groups: help: A RISC-V Platform-local Interrupt Controller (PLIC) peripheral is present. - name: periph_xh3irq help: An XH3IRQ peripheral is present. This is a special interrupt controller - for the Hazard3 used by the RP2350 + for the Hazard3 used by the RP2350. - title: Cryptographic Features help: Hardware acceleration for cryptographic primitives, hardware random From c5dd279d5589da809d9ede2f9a5d8cff10c72188 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Tue, 30 Sep 2025 15:58:19 +0200 Subject: [PATCH 05/20] cpu/rp2350: move to new uart --- cpu/riscv_common/irq_arch.c | 1 - cpu/rp2350_riscv/cpu.c | 19 +-- cpu/rp2350_riscv/include/cpu_conf.h | 58 -------- cpu/rp2350_riscv/periph/uart.c | 211 +++++++++++++++++++++++----- 4 files changed, 182 insertions(+), 107 deletions(-) diff --git a/cpu/riscv_common/irq_arch.c b/cpu/riscv_common/irq_arch.c index 3a58e0e9af56..6bff5a9eef60 100644 --- a/cpu/riscv_common/irq_arch.c +++ b/cpu/riscv_common/irq_arch.c @@ -30,7 +30,6 @@ #include "sched.h" #include "plic.h" #include "clic.h" -#include "xh3irq.h" #include "architecture.h" #if MODULE_PERIPH_XH3IRQ || DOXYGEN diff --git a/cpu/rp2350_riscv/cpu.c b/cpu/rp2350_riscv/cpu.c index 7f92758fdde1..5419f3463277 100644 --- a/cpu/rp2350_riscv/cpu.c +++ b/cpu/rp2350_riscv/cpu.c @@ -23,8 +23,6 @@ #include "periph/uart.h" #include "periph_conf.h" -#include "stdio_uart.h" -#include #include void gpio_reset(void) @@ -38,12 +36,6 @@ void gpio_reset(void) */ void cpu_init(void) { - riscv_init(); - - uint32_t ra_register = 0; - - __asm__ volatile ("mv %0, ra" : "=r"(ra_register)); - /* Reset GPIO state */ gpio_reset(); @@ -53,18 +45,15 @@ void cpu_init(void) /* initialize the CPU clock */ cpu_clock_init(); + /* initialize the RISC-V core */ + riscv_init(); + /* initialize the early peripherals */ early_init(); /* trigger static peripheral initialization */ periph_init(); + /* initialize the board */ board_init(); - - xosc_sleep(1000); - printf("Enabling IRQ 50\n"); - - printf("ra register at start of cpu_init: 0x%lx\n", ra_register); - - __asm__ volatile ("nop"); } diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h index aa122483fb6d..28f799c0976e 100644 --- a/cpu/rp2350_riscv/include/cpu_conf.h +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -24,64 +24,6 @@ extern "C" { #define CPU_DEFAULT_IRQ_PRIO 1u #define CPU_IRQ_NUMOF 52u -/** - * @brief Interrupt numbers for RP2350 RISC-V - */ -typedef enum { - TIMER0_IRQ_0_IRQn = 0, /**< Timer 0 interrupt 0 */ - TIMER0_IRQ_1_IRQn = 1, /**< Timer 0 interrupt 1 */ - TIMER0_IRQ_2_IRQn = 2, /**< Timer 0 interrupt 2 */ - TIMER0_IRQ_3_IRQn = 3, /**< Timer 0 interrupt 3 */ - TIMER1_IRQ_0_IRQn = 4, /**< Timer 1 interrupt 0 */ - TIMER1_IRQ_1_IRQn = 5, /**< Timer 1 interrupt 1 */ - TIMER1_IRQ_2_IRQn = 6, /**< Timer 1 interrupt 2 */ - TIMER1_IRQ_3_IRQn = 7, /**< Timer 1 interrupt 3 */ - PWM_IRQ_WRAP_0_IRQn = 8, /**< PWM wrap interrupt 0 */ - PWM_IRQ_WRAP_1_IRQn = 9, /**< PWM wrap interrupt 1 */ - DMA_IRQ_0_IRQn = 10, /**< DMA interrupt 0 */ - DMA_IRQ_1_IRQn = 11, /**< DMA interrupt 1 */ - DMA_IRQ_2_IRQn = 12, /**< DMA interrupt 2 */ - DMA_IRQ_3_IRQn = 13, /**< DMA interrupt 3 */ - USBCTRL_IRQ_IRQn = 14, /**< USB controller interrupt */ - PIO0_IRQ_0_IRQn = 15, /**< PIO 0 interrupt 0 */ - PIO0_IRQ_1_IRQn = 16, /**< PIO 0 interrupt 1 */ - PIO1_IRQ_0_IRQn = 17, /**< PIO 1 interrupt 0 */ - PIO1_IRQ_1_IRQn = 18, /**< PIO 1 interrupt 1 */ - PIO2_IRQ_0_IRQn = 19, /**< PIO 2 interrupt 0 */ - PIO2_IRQ_1_IRQn = 20, /**< PIO 2 interrupt 1 */ - IO_IRQ_BANK0_IRQn = 21, /**< IO bank 0 interrupt */ - IO_IRQ_BANK0_NS_IRQn = 22, /**< IO bank 0 non-secure interrupt */ - IO_IRQ_QSPI_IRQn = 23, /**< IO QSPI interrupt */ - IO_IRQ_QSPI_NS_IRQn = 24, /**< IO QSPI non-secure interrupt */ - SIO_IRQ_FIFO_IRQn = 25, /**< SIO FIFO interrupt */ - SIO_IRQ_BELL_IRQn = 26, /**< SIO bell interrupt */ - SIO_IRQ_FIFO_NS_IRQn = 27, /**< SIO FIFO non-secure interrupt */ - SIO_IRQ_BELL_NS_IRQn = 28, /**< SIO bell non-secure interrupt */ - SIO_IRQ_MTIMECMP_IRQn = 29, /**< SIO MTIMECMP interrupt */ - CLOCKS_IRQ_IRQn = 30, /**< Clocks interrupt */ - SPI0_IRQ_IRQn = 31, /**< SPI 0 interrupt */ - SPI1_IRQ_IRQn = 32, /**< SPI 1 interrupt */ - UART0_IRQ_IRQn = 33, /**< UART 0 interrupt */ - UART1_IRQ_IRQn = 34, /**< UART 1 interrupt */ - ADC_IRQ_FIFO_IRQn = 35, /**< ADC FIFO interrupt */ - I2C0_IRQ_IRQn = 36, /**< I2C 0 interrupt */ - I2C1_IRQ_IRQn = 37, /**< I2C 1 interrupt */ - OTP_IRQ_IRQn = 38, /**< OTP interrupt */ - TRNG_IRQ_IRQn = 39, /**< TRNG interrupt */ - PROC0_IRQ_CTI_IRQn = 40, /**< Processor 0 CTI interrupt */ - PROC1_IRQ_CTI_IRQn = 41, /**< Processor 1 CTI interrupt */ - PLL_SYS_IRQ_IRQn = 42, /**< PLL SYS interrupt */ - PLL_USB_IRQ_IRQn = 43, /**< PLL USB interrupt */ - POWMAN_IRQ_POW_IRQn = 44, /**< Power manager power interrupt */ - POWMAN_IRQ_TIMER_IRQn = 45, /**< Power manager timer interrupt */ - SPAREIRQ_IRQ_0_IRQn = 46, /**< Spare interrupt 0 */ - SPAREIRQ_IRQ_1_IRQn = 47, /**< Spare interrupt 1 */ - SPAREIRQ_IRQ_2_IRQn = 48, /**< Spare interrupt 2 */ - SPAREIRQ_IRQ_3_IRQn = 49, /**< Spare interrupt 3 */ - SPAREIRQ_IRQ_4_IRQn = 50, /**< Spare interrupt 4 */ - SPAREIRQ_IRQ_5_IRQn = 51 /**< Spare interrupt 5 */ -} IRQn_Type; - #ifdef __cplusplus } #endif diff --git a/cpu/rp2350_riscv/periph/uart.c b/cpu/rp2350_riscv/periph/uart.c index 3ea1f97d3319..ca79a626e59c 100644 --- a/cpu/rp2350_riscv/periph/uart.c +++ b/cpu/rp2350_riscv/periph/uart.c @@ -5,7 +5,7 @@ */ /** - * @ingroup cpu_rp2350_riscv + * @ingroup cpu_rp2350 * @{ * * @file @@ -18,69 +18,214 @@ #include "periph_cpu.h" -int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) { - (void)uart; - (void)baud; - (void)rx_cb; - (void)arg; - /* Set the UART pins to the correct function */ - IO_BANK0->GPIO0_CTRL = FUNCTION_SELECT_UART; - IO_BANK0->GPIO1_CTRL = FUNCTION_SELECT_UART; - /* Clear the ISO bits */ - atomic_clear(&PADS_BANK0->GPIO0, PADS_BANK0_ISO_BITS); - atomic_clear(&PADS_BANK0->GPIO1, PADS_BANK0_ISO_BITS); - /* Set IE bit for gpio1 */ - PADS_BANK0->GPIO1 = PADS_BANK0->GPIO1 | PADS_BANK0_GPIO0_IE_BITS; +#include "regs/uart.h" +#include - /* We reset UART0 here, so we can be sure it is in a known state */ - reset_component(RESET_UART0, RESET_UART0); +#define ENABLE_DEBUG 0 +#include "debug.h" + +#include "xh3irq.h" + +#include "board.h" + +static uart_isr_ctx_t ctx[UART_NUMOF]; - UART0->UARTIBRD = IBRD; - UART0->UARTFBRD = FBRD; - uart_mode(0, 8, UART_PARITY_NONE, 1); - return 0; +/* back up values of registers used during uart_poweroff() / uart_poweron() */ +static uint32_t uartibrd; +static uint32_t uartfbrd; +static uint32_t uartlcr_h; +static uint32_t uartcr; + +/** Pico1 uart uses non-sdk conform defines + * @todo Change Pico1 defines if I ever get around to it + */ +#define UART0_UARTIMSC_RXIM_Msk (UART_UARTIMSC_RXIM_BITS) + +void _irq_enable(uart_t uart) { + UART0_Type *dev = uart_config[uart].dev; + /* We set the UART Receive Interrupt Mask (Bit 4) [See p979 UART 12.1]*/ + dev->UARTIMSC = UART0_UARTIMSC_RXIM_Msk; + /* Enable the IRQ in the NVIC */ + xh3irq_enable_irq(uart_config[uart].irqn); } int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, - uart_stop_bits_t stop_bits) { - (void)uart; + uart_stop_bits_t stop_bits) { + assert((unsigned)uart < UART_NUMOF); + UART0_Type *dev = uart_config[uart].dev; + (void)data_bits; (void)stop_bits; - atomic_clear(&UART0->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS | - UART_UARTCR_TXE_BITS); + + /* Disable the UART before changing the mode */ + atomic_clear(&dev->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS | + UART_UARTCR_TXE_BITS); /* Set the data bits, parity, and stop bits * Set to 8 bits (0b11) based on Table 1035 page 976 + * @todo allow different data bits */ - UART0->UARTLCR_H = 0b11 << 5; + dev->UARTLCR_H = 0b11 << 5; switch (parity) { - case UART_PARITY_NONE: + case UART_PARITY_NONE: break; - default: + // case UART_PARITY_EVEN: + // io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk); + // break; + // case UART_PARITY_ODD: + // io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk); + // break; + default: return UART_NOMODE; } - UART0->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS; + dev->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS; + + return UART_OK; +} + +static void _reset_uart(uart_t uart) { + switch (uart) { + case 0: + /* We reset UART0 here, so we can be sure it is in a known state */ + reset_component(RESET_UART0, RESET_UART0); + break; + case 1: + /* We reset UART1 here, so we can be sure it is in a known state */ + reset_component(RESET_UART1, RESET_UART1); + break; + default: + break; + } +} + +void uart_init_pins(uart_t uart) { + assert((unsigned)uart < UART_NUMOF); + UART0_Type *dev = uart_config[uart].dev; + + /* Set the UART pins to the correct function */ + *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART; + *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART; + /* Clear the ISO bits */ + atomic_clear((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].tx_pin), PADS_BANK0_ISO_BITS); + atomic_clear((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_ISO_BITS); + + /* Set Input Enable Flag */ + atomic_set((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_GPIO0_IE_BITS); + + /* We reset UART0 here, so we can be sure it is in a known state */ + _reset_uart(uart); + + dev->UARTIBRD = IBRD; + dev->UARTFBRD = FBRD; +} + +int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) { + (void)baud; + + if (uart >= UART_NUMOF) { + return UART_NODEV; + } + + UART0_Type *dev = uart_config[uart].dev; + ctx[uart].rx_cb = rx_cb; + ctx[uart].arg = arg; + + uart_init_pins(uart); + + if (uart_mode(uart, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1) != UART_OK) { + return UART_NOMODE; + } + + /* enable RX and IRQs, if needed */ + if (rx_cb != NULL) { + _irq_enable(uart); + /* clear any pending data and IRQ to avoid receiving a garbage char */ + uint32_t status = dev->UARTRIS; + dev->UARTICR = status; + (void)dev->UARTDR; + atomic_set(&dev->UARTCR, UART_UARTCR_RXE_BITS); + } return UART_OK; } void uart_write(uart_t uart, const uint8_t *data, size_t len) { - (void)uart; + UART0_Type *dev = uart_config[uart].dev; for (size_t i = 0; i < len; i++) { - UART0->UARTDR = data[i]; + dev->UARTDR = data[i]; /* Wait until the TX FIFO is empty before sending the next byte */ - while (!(UART0->UARTFR & UART_UARTFR_TXFE_BITS)) { + while (!(dev->UARTFR & UART_UARTFR_TXFE_BITS)) { } } } void uart_poweron(uart_t uart) { - (void)uart; + assert((unsigned)uart < UART_NUMOF); + /* Get into a save state where we know whats up */ + _reset_uart(uart); + UART0_Type *dev = uart_config[uart].dev; + /* Restore config from registers */ + dev->UARTIBRD = uartibrd; + dev->UARTFBRD = uartfbrd; + dev->UARTLCR_H = uartlcr_h; + dev->UARTCR = uartcr; + /* restore IRQs, if needed */ + if (ctx[uart].rx_cb != NULL) { + _irq_enable(uart); + } + uart_init_pins(uart); +} + +void uart_deinit_pins(uart_t uart) { + assert((unsigned)uart < UART_NUMOF); + /* @TODO */ + /* gpio_reset_all_config(uart_config[uart].tx_pin); */ + SIO->GPIO_OE_CLR = 1LU << uart_config[uart].tx_pin; + if (ctx[uart].rx_cb) { + /* gpio_reset_all_config(uart_config[uart].rx_pin); */ + } } + void uart_poweroff(uart_t uart) { - (void)uart; + assert((unsigned)uart < UART_NUMOF); + UART0_Type *dev = uart_config[uart].dev; + /* backup configuration registers */ + uartibrd = dev->UARTIBRD; + uartfbrd = dev->UARTFBRD; + uartlcr_h = dev->UARTLCR_H; + uartcr = dev->UARTCR; + /* disconnect GPIOs and power off peripheral */ + uart_deinit_pins(uart); + _reset_uart(uart); +} + +void isr_handler(uint8_t num) { + UART0_Type *dev = uart_config[num].dev; + + uint32_t status = dev->UARTMIS; + dev->UARTICR = status; + + if (status & UART_UARTMIS_RXMIS_BITS) { + uint32_t data = dev->UARTDR; + // if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) { + // DEBUG_PUTS("[rpx0xx] uart RX error (parity, break, or framing error"); + // } + // else { + printf("UART%d received: %c\n", num, (char)(data & 0xFF)); + ctx[num].rx_cb(ctx[num].arg, (uint8_t)data); + // } + } +} + +/** Overwrites the WEAK_DEFAULT isr_uart0 */ +void isr_uart0(void) { + isr_handler(0); +} + +void isr_uart1(void) { + isr_handler(1); } /** @} */ From 58a46cbcc5beefa313c119dc9cd1844a902ba78e Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Tue, 30 Sep 2025 16:02:48 +0200 Subject: [PATCH 06/20] cpu/rp2350_common: create shared folder for RISCV & ARM --- cpu/riscv_common/Makefile | 2 +- cpu/rp2350/doc.md | 2 +- cpu/rp2350_arm/Makefile.include | 18 ++ cpu/rp2350_common/Makefile | 3 + cpu/rp2350_common/Makefile.dep | 4 + cpu/rp2350_common/Makefile.features | 2 + cpu/rp2350_common/Makefile.include | 15 ++ cpu/rp2350_common/clock.c | 71 ++++++ cpu/rp2350_common/cpu.c | 56 +++++ cpu/rp2350_common/doc.md | 5 + cpu/rp2350_common/include/clock_conf.h | 159 +++++++++++++ cpu/rp2350_common/include/compat_layer.h | 56 +++++ cpu/rp2350_common/include/gpio_conf.h | 66 ++++++ cpu/rp2350_common/include/helpers.h | 78 +++++++ cpu/rp2350_common/include/periph_cpu.h | 129 +++++++++++ cpu/rp2350_common/include/uart_conf.h | 76 +++++++ cpu/rp2350_common/periph/Makefile | 1 + cpu/rp2350_common/periph/gpio.c | 96 ++++++++ cpu/rp2350_common/periph/uart.c | 275 +++++++++++++++++++++++ cpu/rp2350_common/vectors.c | 155 +++++++++++++ cpu/rp2350_common/xosc.c | 55 +++++ 21 files changed, 1322 insertions(+), 2 deletions(-) create mode 100644 cpu/rp2350_arm/Makefile.include create mode 100644 cpu/rp2350_common/Makefile create mode 100644 cpu/rp2350_common/Makefile.dep create mode 100644 cpu/rp2350_common/Makefile.features create mode 100644 cpu/rp2350_common/Makefile.include create mode 100644 cpu/rp2350_common/clock.c create mode 100644 cpu/rp2350_common/cpu.c create mode 100644 cpu/rp2350_common/doc.md create mode 100644 cpu/rp2350_common/include/clock_conf.h create mode 100644 cpu/rp2350_common/include/compat_layer.h create mode 100644 cpu/rp2350_common/include/gpio_conf.h create mode 100644 cpu/rp2350_common/include/helpers.h create mode 100644 cpu/rp2350_common/include/periph_cpu.h create mode 100644 cpu/rp2350_common/include/uart_conf.h create mode 100644 cpu/rp2350_common/periph/Makefile create mode 100644 cpu/rp2350_common/periph/gpio.c create mode 100644 cpu/rp2350_common/periph/uart.c create mode 100644 cpu/rp2350_common/vectors.c create mode 100644 cpu/rp2350_common/xosc.c diff --git a/cpu/riscv_common/Makefile b/cpu/riscv_common/Makefile index e09377cd1e39..880129078d0d 100644 --- a/cpu/riscv_common/Makefile +++ b/cpu/riscv_common/Makefile @@ -1,3 +1,3 @@ -DIRS = periph +DIRS += periph include $(RIOTBASE)/Makefile.base diff --git a/cpu/rp2350/doc.md b/cpu/rp2350/doc.md index cc2f01362ef9..aefe5eef356e 100644 --- a/cpu/rp2350/doc.md +++ b/cpu/rp2350/doc.md @@ -1,4 +1,4 @@ -@defgroup cpu_rp2350 RP2350 MCUs +@defgroup cpu_rp2350_arm RP2350 MCUs @ingroup cpu @brief RP2350 MCU code and definitions diff --git a/cpu/rp2350_arm/Makefile.include b/cpu/rp2350_arm/Makefile.include new file mode 100644 index 000000000000..eb5931c3cc04 --- /dev/null +++ b/cpu/rp2350_arm/Makefile.include @@ -0,0 +1,18 @@ +# CPU and architecture specific flags +CFLAGS += -D$(CPU_MODEL) +CFLAGS += -DROM_START_ADDR=$(ROM_START_ADDR) +CFLAGS += -DRAM_START_ADDR=$(RAM_START_ADDR) + +# Linker flags +LINKFLAGS += -mcpu=$(CPU_ARCH) -mthumb +LINKFLAGS += -Wl,--gc-sections +LINKFLAGS += -Wl,--start-group -lc -lm -Wl,--end-group + +# Vector table configuration +VECTORS_O ?= $(BINDIR)/cpu/vectors.o +VECTORS_FILE := $(RIOTCPU)/rp2350_common/vectors.c + +include $(RIOTCPU)/rp2350_common/Makefile.include + +# Include the base Cortex-M makefile +include $(RIOTMAKE)/arch/cortexm.inc.mk diff --git a/cpu/rp2350_common/Makefile b/cpu/rp2350_common/Makefile new file mode 100644 index 000000000000..880129078d0d --- /dev/null +++ b/cpu/rp2350_common/Makefile @@ -0,0 +1,3 @@ +DIRS += periph + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/rp2350_common/Makefile.dep b/cpu/rp2350_common/Makefile.dep new file mode 100644 index 000000000000..51983f6a1cf8 --- /dev/null +++ b/cpu/rp2350_common/Makefile.dep @@ -0,0 +1,4 @@ +USEMODULE += periph +USEPKG += picosdk +# We tell the build system that common needs to be built +USEMODULE += rp2350_common diff --git a/cpu/rp2350_common/Makefile.features b/cpu/rp2350_common/Makefile.features new file mode 100644 index 000000000000..783de0af307d --- /dev/null +++ b/cpu/rp2350_common/Makefile.features @@ -0,0 +1,2 @@ +FEATURES_PROVIDED += periph_gpio +FEATURES_PROVIDED += periph_uart diff --git a/cpu/rp2350_common/Makefile.include b/cpu/rp2350_common/Makefile.include new file mode 100644 index 000000000000..de8bf749b0b0 --- /dev/null +++ b/cpu/rp2350_common/Makefile.include @@ -0,0 +1,15 @@ +ROM_LEN ?= 2097152 # = 2 MiB used in the RPi Pico +ROM_OFFSET := 0 # bootloader size +RAM_LEN := 0x82000 # 520kB = 532479 used in the RPi Pico 2350 +ROM_START_ADDR := 0x10000000 # XIP Non-Secure address for rp2350 +RAM_START_ADDR := 0x20000000 # Non-Secure RAM address for rp2350 + +INCLUDES += -I$(RIOTCPU)/rp2350_common/include +INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include +INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include +INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2350/hardware_regs/include/hardware + +# Supported programmers and debuggers +PROGRAMMERS_SUPPORTED := picotool openocd jlink +PROGRAMMER ?= picotool +OPENOCD_DEBUG_ADAPTER ?= dap diff --git a/cpu/rp2350_common/clock.c b/cpu/rp2350_common/clock.c new file mode 100644 index 000000000000..243b64451160 --- /dev/null +++ b/cpu/rp2350_common/clock.c @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Clock configuration implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "periph_cpu.h" + +void clock_reset(void) { + /* Reset the clock system */ + reset_component(RESET_PLL_SYS, RESET_PLL_SYS); +} + +/** + * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it + * @warning Make sure to call clock_reset() before this function to reset the + * clock system + * @see RP2350 Docs Chapter 8, mostly 8.2 for more details + */ +void cpu_clock_init(void) { + /* Enable the XOSC */ + xosc_start(); + + /* Setup the PLL using the XOSC as the reference clock. */ + PLL_SYS->FBDIV_INT = + PLL_FEEDBACK_DIVIDER_VALUE; /* Set the feedback divider */ + + /* Set the post-dividers for the PLL output.*/ + PLL_SYS->PRIM = PDIV; + /* Turn on PLL */ + atomic_clear(&PLL_SYS->PWR, + PLL_PWR_PD_BITS | PLL_PWR_VCOPD_BITS | PLL_PWR_POSTDIVPD_BITS); + + /* sleep 10ms to allow the PLL to stabilize */ + xosc_sleep(10); + + /* Based on the description in chapter 8 this is something that should be done + * However, it appears to cause issues and is not done by other examples on the + * internet. This needs to be investigated further. */ + + /* Wait for lock */ + /* while (!(PLL_SYS->CS & PLL_CS_LOCK_BITS)) { */ + /* Wait for the PLL to lock */ + /* } */ + + /* AUXSRC = 0x0 7:5 && SRC == 0x0 0 */ + CLOCKS->CLK_SYS_CTRL = CLK_SYS_PERI_CTRL_ENABLE_BIT; + + /* This register contains one decoded bit for each of the clock sources + * enumerated in the CTRL SRC field. The bit does not directly correlate with + * the value of the SRC field For example 0x0 is the first bit while 0x1 is + * the second bit. In some way this makes sense, in some way I lost too much + * time on this. */ + while (CLOCKS->CLK_SYS_SELECTED != CLK_SYS_SELECTED_PERI_FIELD_VALUE) { + } + + /* AUXSRC = 0x0 -> CLK_SYS Indirectly through lower line */ + CLOCKS->CLK_PERI_CTRL = CLK_PERI_CTRL_ENABLE_BIT; +} + +/** @} */ diff --git a/cpu/rp2350_common/cpu.c b/cpu/rp2350_common/cpu.c new file mode 100644 index 000000000000..91e44a910b9e --- /dev/null +++ b/cpu/rp2350_common/cpu.c @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Implementation of the CPU initialization for RP2350 + * + * @author Tom Hert + * @} + */ + +#include + +#include "board.h" +#include "cpu.h" +#include "clock_conf.h" +#include "kernel_init.h" +#include "periph/init.h" +#include "periph/uart.h" +#include "periph_conf.h" + +void gpio_reset(void) +{ + reset_component(RESET_PADS_BANK0, RESET_PADS_BANK0); + reset_component(RESET_IO_BANK0, RESET_IO_BANK0); +} + +/** + * @brief Initialize the CPU, set IRQ priorities, clocks, peripheral + */ +void rp2350_init(void) +{ + /* Reset GPIO state */ + gpio_reset(); + + /* Reset clock to default state */ + clock_reset(); + + /* initialize the CPU clock */ + cpu_clock_init(); + + /* initialize the early peripherals */ + early_init(); + + /* trigger static peripheral initialization */ + periph_init(); + + /* initialize the board */ + board_init(); +} diff --git a/cpu/rp2350_common/doc.md b/cpu/rp2350_common/doc.md new file mode 100644 index 000000000000..c080f9fe1b89 --- /dev/null +++ b/cpu/rp2350_common/doc.md @@ -0,0 +1,5 @@ +@defgroup cpu_rp2350 RP2350 MCUs +@ingroup cpu +@brief RP2350 MCU code and definitions + +This module contains the code and definitions for MCUs of the RP2350 used by the Pi Pico 2. diff --git a/cpu/rp2350_common/include/clock_conf.h b/cpu/rp2350_common/include/clock_conf.h new file mode 100644 index 000000000000..c6451d225afc --- /dev/null +++ b/cpu/rp2350_common/include/clock_conf.h @@ -0,0 +1,159 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Clock configuration for the RP2350 + * + * @author Tom Hert + */ + +#include "RP2350.h" +#include "macros/units.h" + +/** 1-15 MHz range + * @see hardware/regs/xosc.h and chapter 8.2.8 + */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ 0xaa0u +/** 10-30 MHz range */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_10_30MHZ 0xaa1u +/** 25-60 MHz range */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_25_60MHZ 0xaa2u +/** 40-100 MHz range */ +#define XOSC_CTRL_FREQ_RANGE_VALUE_40_100MHZ 0xaa3u +/** Disable the XOSC */ +#define XOSC_CTRL_ENABLE_VALUE_DISABLE 0xd1eu +/** Enable the XOSC */ +#define XOSC_CTRL_ENABLE_VALUE_ENABLE 0xfabu +/** LSB of the enable bit */ +#define XOSC_CTRL_ENABLE_LSB 12u +/** Stable bit in the XOSC status register */ +#define XOSC_STATUS_STABLE_BITS 0x80000000u +/** Default crystal frequency is 12 MHz */ +#define XOSC_HZ MHZ(12u) +/** Reference divider for the PLL, set to 2 as per hardware manual */ +#define PLL_REF_DIV 2u +/** VCO frequency for the PLL, set to 750 MHz as per hardware manual */ +#define PLL_VCO_FREQ 750000000u +/** Post divider 1 for the PLL, set to 6 as per hardware manual */ +#define PLL_PD1 6u +/** Post divider 2 for the PLL, set to 2 as per hardware manual */ +#define PLL_PD2 2u +/** Power down bits for the PLL */ +#define PLL_PWR_PD_BITS 0x00000001u +/** VCO power down bits for the PLL */ +#define PLL_PWR_VCOPD_BITS 0x00000020u +/** Lock bit in the PLL control status register */ +#define PLL_CS_LOCK_BITS 0x80000000u +/** LSB of the post divider 1 in the PLL primary register */ +#define PLL_PRIM_POSTDIV1_LSB 16u +/** LSB of the post divider 2 in the PLL primary register */ +#define PLL_PRIM_POSTDIV2_LSB 12u +/** Post divider power down bits for the PLL */ +#define PLL_PWR_POSTDIVPD_BITS 0x00000008u +/** Enable bit for the peripheral clock control register */ +#define CLK_PERI_CTRL_ENABLE_BIT (1u << 11u) +/** Default CPU frequency in Hz, set to 125 MHz as per hardware manual */ +#define CPUFREQ 125000000u +/** Maximum crystal frequency */ +#define CLOCK_XOSC_MAX MHZ(15u) +/** Minimum crystal frequency */ +#define CLOCK_XOSC_MIN MHZ(5u) +/** Crystal frequency */ +#define CLOCK_XOSC (XOSC_HZ) +/** Minimum value of the post PLL clock divers */ +#define PLL_POSTDIV_MIN 1u +/** Maximum value of the post PLL clock divers */ +#define PLL_POSTDIV_MAX 7u +/** Minimum value of the PLL VCO feedback scaler */ +#define PLL_VCO_FEEDBACK_SCALE_MIN 16u +/** Maximum value of the PLL VCO feedback scaler */ +#define PLL_VCO_FEEDBACK_SCALE_MAX 320u +/** Minimum value of the clock divider applied before + * feeding in the reference clock into the PLL */ +#define PLL_REF_DIV_MIN 1u +/** Minimum value of the clock divider applied before feeding in + * the reference clock into the PLL */ +#define PLL_REF_DIV_MAX 1u +/** PLL feedback divider value, set to 125 as per hardware manual */ +#define PLL_FEEDBACK_DIVIDER_VALUE 125u +/** Enable bit for the system clock control register to select the peripheral + * clock */ +#define CLK_SYS_PERI_CTRL_ENABLE_BIT (1u << 0u) +/** Selected field value for the system clock control register + * to select the peripheral clock */ +#define CLK_SYS_SELECTED_PERI_FIELD_VALUE 2u +/** RIOT core clock frequency defined as the CPU frequency */ +#define CLOCK_CORECLOCK MHZ(12u) + +#if (PLL_VCO_FEEDBACK_SCALE_MIN < PLL_VCO_FEEDBACK_SCALE_MIN) || \ +(PLL_VCO_FEEDBACK_SCALE_MAX > PLL_VCO_FEEDBACK_SCALE_MAX) +# error "Value for PLL_VCO_FEEDBACK_SCALE out of range, check config" +#endif +#if (PLL_REF_DIV_MIN < PLL_REF_DIV_MIN) || (PLL_REF_DIV_MAX > PLL_REF_DIV_MAX) +# error "Value for PLLxosc_sleep_REF_DIV out of range, check config" +#endif +#if (PLL_POSTDIV_MIN < PLL_POSTDIV_MIN) || (PLL_POSTDIV_MAX > PLL_POSTDIV_MAX) +# error "Value for PLL_POSTDIV out of range, check config" +#endif +#if ((CLOCK_XOSC > CLOCK_XOSC_MAX) || (CLOCK_XOSC < CLOCK_XOSC_MIN)) +# error "Value for CLOCK_XOSC out of range, check config" +#endif + +/** Post divider for the PLL, calculated based on the post divider values */ +#define PDIV ((PLL_PD1 << PLL_PRIM_POSTDIV1_LSB) | (PLL_PD2 << PLL_PRIM_POSTDIV2_LSB)) +/** Feedback divider for the PLL, calculated based on the VCO frequency and +* reference clock frequency */ +#define FBDIV ((PLL_VCO_FREQ / XOSC_HZ) / PLL_REF_DIV) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Configures the Crystal to run. + * @note The reference hardware manual suggests to use a 12 MHz crystal, which we + * use by default. + */ +void xosc_start(void); + +/** + * @brief Stop the crystal. + */ +void xosc_stop(void); + +/** + * @brief Sleep for a given time in milliseconds. + * @param milliseconds The time to sleep in milliseconds. + */ +void xosc_sleep(uint32_t milliseconds); + +/** + * @brief Reset the clock system. + * + * This function resets the clock system to a known state. + * It is recommended to call this function before configuring the clock system. + */ +void clock_reset(void); + +/** + * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it + * @pre Make sure to call clock_reset() before this function to reset the + * clock system + * @see RP2350 Docs Chapter 8, mostly 8.2 for more details + */ +void cpu_clock_init(void); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_common/include/compat_layer.h b/cpu/rp2350_common/include/compat_layer.h new file mode 100644 index 000000000000..134c0809bdc6 --- /dev/null +++ b/cpu/rp2350_common/include/compat_layer.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Compatibility layer for different CPU architectures + * + * @author Tom Hert + */ + +#include "periph_cpu.h" + +#ifdef RP2350_USE_RISCV +# include "xh3irq.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Enable the given IRQ + * @param[in] irq_no IRQ number to enable + */ +static inline void rp_irq_enable(uint32_t irq_no) +{ +#ifdef RP2350_USE_RISCV + xh3irq_enable_irq(irq_no); +#else + NVIC_EnableIRQ(irq_no); +#endif +} + +/** + * @brief Called upon the end of an ISR + */ +static inline void rp_end_isr(void) +{ +#ifdef RP2350_USE_ARM + cortexm_isr_end(); +#endif +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_common/include/gpio_conf.h b/cpu/rp2350_common/include/gpio_conf.h new file mode 100644 index 000000000000..3991542d434c --- /dev/null +++ b/cpu/rp2350_common/include/gpio_conf.h @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert git@annsann.eu> + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief GPIO configuration for the RP2350 + * + * @author Tom Hert + */ + +/** The number of GPIO pins available on the RP2350 */ +#define GPIO_PIN_NUMOF 30u + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Possible function values for @ref gpio_io_ctrl_t::function_select + */ +typedef enum { + /** connect pin to the SPI peripheral (MISO/MOSI/SCK depends on pin) */ + FUNCTION_SELECT_SPI = 1, + + /** connect pin to the UART peripheral (TXD/RXD depends on pin) */ + FUNCTION_SELECT_UART = 2, + + /** connect pin to the I2C peripheral (SCL/SDA depends on pin) */ + FUNCTION_SELECT_I2C = 3, + + /** connect pin to the timer for PWM (channel depends on pin) */ + FUNCTION_SELECT_PWM = 4, + + /** use pin as vanilla GPIO */ + FUNCTION_SELECT_SIO = 5, + + /** connect pin to the first PIO peripheral */ + FUNCTION_SELECT_PIO0 = 6, + + /** connect pin to the second PIO peripheral */ + FUNCTION_SELECT_PIO1 = 7, + + /** connect pin to the timer (depending on pin: external clock, + * clock output, or not supported) */ + FUNCTION_SELECT_CLOCK = 8, + + /** connect pin to the USB peripheral (function depends on pin) */ + FUNCTION_SELECT_USB = 9, + + /** Reset value, pin unconnected */ + FUNCTION_SELECT_NONE = 31, +} gpio_function_select_t; + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_common/include/helpers.h b/cpu/rp2350_common/include/helpers.h new file mode 100644 index 000000000000..6ab9b4dd9c03 --- /dev/null +++ b/cpu/rp2350_common/include/helpers.h @@ -0,0 +1,78 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Helper functions for atomic register operations + * + * @author Tom Hert + */ + +/** Bit to be set for an atomic XOR operation */ +#define ATOMIC_XOR_WRITE 0x1000u +/** Bit to be set for an atomic set operation */ +#define ATOMIC_BITMASK_SET_WRITE 0x2000u +/** Bits to be set for an atomic clear operation */ +#define ATOMIC_BITMASK_CLEAR_WRITE 0x3000u + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Perform an atomic XOR write to a register + * + * @param[in,out] reg Pointer to the target register + * @param[in] val Value to be XORed with the register + */ +static inline void atomic_xor(volatile uint32_t *reg, uint32_t val) { + *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_XOR_WRITE) = val; +} + +/** + * @brief Set bits in a register atomically + * + * @param[in,out] reg Pointer to the target register + * @param[in] val Bit mask of bits to set + */ +static inline void atomic_set(volatile uint32_t *reg, uint32_t val) { + *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_SET_WRITE) = val; +} + +/** + * @brief Clear bits in a register atomically + * + * @param[in,out] reg Pointer to the target register + * @param[in] val Bit mask of bits to clear + */ +static inline void atomic_clear(volatile uint32_t *reg, uint32_t val) { + *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_CLEAR_WRITE) = val; +} + +/** + * @brief Reset a component by clearing its reset bits and waiting for the reset to complete + * + * @param reset_value Bit mask of the reset bits to clear + * @param reset_done_value Bit mask of the reset done bits to wait for + */ +static inline void reset_component(uint32_t reset_value, + uint32_t reset_done_value) { + atomic_clear(&RESETS->RESET, reset_value); + while (~RESETS->RESET_DONE & reset_done_value) { + /* Wait for the reset to complete */ + } +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_common/include/periph_cpu.h b/cpu/rp2350_common/include/periph_cpu.h new file mode 100644 index 000000000000..81d3c149f430 --- /dev/null +++ b/cpu/rp2350_common/include/periph_cpu.h @@ -0,0 +1,129 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Peripheral CPU definitions for the RP2350 + * + * @author Tom Hert + */ + +#include + +/** Overwrite the default GPIO type to use uint32_t */ +#define HAVE_GPIO_T +typedef uint32_t gpio_t; + +/** + * @brief Macro to create a GPIO pin identifier + * @param port The GPIO port (Currently only GPIO0) + * @param pin The GPIO pin number + */ +#define GPIO_PIN(port, pin) (((port) & 0) | (pin)) + +/** This is a define used throughout the pico sdk */ +#define _u(x) ((uint32_t)(x)) + +#ifdef RP2350_USE_RISCV +# include "periph_cpu_common.h" +# include "xh3irq.h" +#endif +#include "cpu.h" +#include "core_cm33.h" /* Trick RP2350 into believing the file exists on RISCV */ +#include "RP2350.h" +#include "helpers.h" +#include "gpio_conf.h" +#include "clock_conf.h" +#include "uart_conf.h" + +#if !(defined(RP2350_USE_ARM) || defined(RP2350_USE_RISCV)) +# error "Either RP2350_USE_ARM or RP2350_USE_RISCV must be defined" +#endif + +#if (defined(RP2350_USE_ARM) && defined(RP2350_USE_RISCV)) +# error "Only one of RP2350_USE_ARM or RP2350_USE_RISCV can be defined" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** GPIO Pin ID for oscillator debugging */ +#define OSC_DEBUG_PIN_ID 15u + +/** Reset bit for the system PLL */ +#define RESET_PLL_SYS (1u << 14u) + +/** Reset bit for the pads bank 0 */ +#define RESET_PADS_BANK0 (1u << 9u) + +/** Reset bit for UART0 peripheral */ +#define RESET_UART0 (1u << 26u) + +/** Reset bit for UART1 peripheral */ +#define RESET_UART1 (1u << 27u) + +/** Reset bit for the IO bank 0 */ +#define RESET_IO_BANK0 (1u << 6u) + +/** Input enable bit for GPIO0 in PADS_BANK0 */ +#define PADS_BANK0_GPIO0_IE_BITS (1u << 6u) + +/** Isolation bits for PADS_BANK0 */ +#define PADS_BANK0_ISO_BITS (1u << 8u) + +/** + * @brief Initialize RP2350 specific CPU peripherals that are not + * architecture specific + */ +void rp2350_init(void); + +/** + * @brief Calculate the address of the GPIO pad register for a given pin + * @param[in] pin The GPIO pin number + * @return The address of the GPIO pad register for the given pin + */ +static inline uint32_t* calculate_gpio_pad_register_addr(gpio_t pin) +{ + /* Each pin has a 4 byte register, so we can calculate the address + * by adding 4 bytes for each pin, starting at the base address of PADS_BANK0 + * and adding 4 bytes to skip VOLTAGE_SELECT */ + return (uint32_t*) (PADS_BANK0_BASE + (4 * (pin + 1))); +} + +/** + * @brief Calculate the address of the GPIO IO status register for a given pin + * @param pin The GPIO pin number + * @return The address of the GPIO IO status register for the given pin + */ +static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { + /* Each status register is followed by a ctrl register */ + return IO_BANK0_BASE + 8 * pin; +} + +/** + * @brief Calculate the address of the GPIO IO control register for a given + * pin + * @param pin The GPIO pin number + * @return The address of the GPIO IO control register for the given pin + */ +static inline uint32_t calculate_gpio_io_ctrl_register_addr(gpio_t pin) { + /* Each pin has a 8 byte register (4 Bytes of Status, 4 Bytes of CTRL), + * so we can calculate the address by adding 8 bytes for each pin, + * starting at the base address of IO_BANK0 */ + return calculate_gpio_io_status_register_addr(pin) + 4; +} + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_common/include/uart_conf.h b/cpu/rp2350_common/include/uart_conf.h new file mode 100644 index 000000000000..829da0dcf3c1 --- /dev/null +++ b/cpu/rp2350_common/include/uart_conf.h @@ -0,0 +1,76 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +#pragma once + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief UART configuration for the RP2350 + * + * @author Tom Hert + */ + +#include "RP2350.h" +#include "macros/units.h" +#include "periph_cpu.h" + +/** UART baud rate in bits per second */ +#define BAUDRATE 115200u + +/** Integer baud rate divisor */ +#define IBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) / 64u) + +/** Fractional baud rate divisor */ +#define FBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) % 64u) + +/** UART enable bit in control register */ +#define UART_UARTCR_UARTEN_BITS (1u << 0u) + +/** UART receive enable bit in control register */ +#define UART_UARTCR_RXE_BITS (1u << 9u) + +/** UART transmit enable bit in control register */ +#define UART_UARTCR_TXE_BITS (1u << 8u) + +/** UART receive FIFO full flag bit in flag register */ +#define UART_UARTFR_RXFF_BITS (1u << 6u) + +/** UART transmit FIFO empty flag bit in flag register */ +#define UART_UARTFR_TXFE_BITS (1u << 7u) + +/** UART data register break error mask */ +#define UART0_UARTDR_BE_Msk (0x400UL) + +/** UART data register parity error mask */ +#define UART0_UARTDR_PE_Msk (0x200UL) + +/** UART data register framing error mask */ +#define UART0_UARTDR_FE_Msk (0x100UL) + +/** UART raw interrupt status transmit interrupt mask */ +#define UART0_UARTRIS_TXRIS_Msk (0x20UL) + +/** UART line control register two stop bits mask */ +#define UART0_UARTLCR_H_STP2_Msk (0x8UL) + +/** UART line control register even parity select mask */ +#define UART0_UARTLCR_H_EPS_Msk (0x4UL) + +/** UART line control register parity enable mask */ +#define UART0_UARTLCR_H_PEN_Msk (0x2UL) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/cpu/rp2350_common/periph/Makefile b/cpu/rp2350_common/periph/Makefile new file mode 100644 index 000000000000..a36df249ac1d --- /dev/null +++ b/cpu/rp2350_common/periph/Makefile @@ -0,0 +1 @@ +include $(RIOTMAKE)/periph.mk diff --git a/cpu/rp2350_common/periph/gpio.c b/cpu/rp2350_common/periph/gpio.c new file mode 100644 index 000000000000..2827d43ac282 --- /dev/null +++ b/cpu/rp2350_common/periph/gpio.c @@ -0,0 +1,96 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief GPIO implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "periph/gpio.h" + +#include + +#include "board.h" +#include "irq.h" +#include "periph_conf.h" +#include "periph_cpu.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +int gpio_init(gpio_t pin, gpio_mode_t mode) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + + /* Clear the pin's output enable and output state */ + SIO->GPIO_OE_CLR = 1LU << pin; + SIO->GPIO_OUT_CLR = 1LU << pin; + + switch (mode) { + case GPIO_OUT: + *(uint32_t*)calculate_gpio_io_ctrl_register_addr(pin) = + FUNCTION_SELECT_SIO; + + volatile uint32_t* pad_reg = + (uint32_t*)calculate_gpio_pad_register_addr(pin); + + /* We clear all bits except the drive strength bit. + * We set that to the highest one possible (12mA) + * to mimic the behavior of the pico1 GPIO driver + * (Not too sure why we do this, but it seems to be the standard) */ + *pad_reg = 0x3 << 4; + + SIO->GPIO_OE_SET = 1 << pin; /* Set the pin as output */ + + break; + default: + /* Unsupported mode */ + return -ENOTSUP; + } + return 0; +} + +bool gpio_read(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + /* Read the pin state */ + return (SIO->GPIO_IN & (1 << pin)) != 0; /* Return true if the pin is HIGH */ +} + +void gpio_set(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + SIO->GPIO_OUT_SET = 1 << pin; /* Set the pin to HIGH */ +} + +void gpio_clear(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + SIO->GPIO_OUT_CLR = 1 << pin; /* Set the pin to LOW */ +} + +void gpio_toggle(gpio_t pin) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + SIO->GPIO_OUT_XOR = 1 << pin; /* Toggle the pin state (XOR) */ +} + +void gpio_write(gpio_t pin, bool value) { + /* Check if we exceed the maximum number of GPIO pins */ + assert(pin < GPIO_PIN_NUMOF); + if (value) { + gpio_set(pin); /* Set the pin to HIGH */ + } else { + gpio_clear(pin); /* Set the pin to LOW */ + } +} + +/** @} */ diff --git a/cpu/rp2350_common/periph/uart.c b/cpu/rp2350_common/periph/uart.c new file mode 100644 index 000000000000..fdf2da558bd3 --- /dev/null +++ b/cpu/rp2350_common/periph/uart.c @@ -0,0 +1,275 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief UART implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "board.h" +#include "compat_layer.h" +#include "periph_cpu.h" + +#include "regs/uart.h" +#include "periph/uart.h" + +#define ENABLE_DEBUG 0 +#include "debug.h" + +static uart_isr_ctx_t ctx[UART_NUMOF]; + +/* back up values of registers used during uart_poweroff() / uart_poweron() */ +static uint32_t uartibrd; +static uint32_t uartfbrd; +static uint32_t uartlcr_h; +static uint32_t uartcr; + +void _irq_enable(uart_t uart) +{ + UART0_Type *dev = uart_config[uart].dev; + /* We set the UART Receive Interrupt Mask (Bit 4) [See p979 UART 12.1]*/ + dev->UARTIMSC = UART_UARTIMSC_RXIM_BITS; + /* Enable the IRQ */ + rp_irq_enable(uart_config[uart].irqn); +} + +void _set_symbolrate(uart_t uart, uint32_t baud) +{ + assert(baud != 0); + UART0_Type *dev = uart_config[uart].dev; + uint32_t baud_rate_div = (8 * CPUFREQ / baud); + uint32_t baud_ibrd = baud_rate_div >> 7; + uint32_t baud_fbrd; + + if (baud_ibrd == 0) { + baud_ibrd = 1; + baud_fbrd = 0; + } + else if (baud_ibrd >= 65535) { + baud_ibrd = 65535; + baud_fbrd = 0; + } + else { + baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2; + } + + dev->UARTIBRD = baud_ibrd; + dev->UARTFBRD = baud_fbrd; +} + +int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, + uart_stop_bits_t stop_bits) +{ + assert((unsigned)uart < UART_NUMOF); + UART0_Type *dev = uart_config[uart].dev; + + /* Disable the UART before changing the mode */ + atomic_clear(&dev->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS | + UART_UARTCR_TXE_BITS | 1 << 7); + + /* Beware of strange hardware bug: If the configuration bitmask is prepared in register and + * transferred with a single 32 bit write (updating both parity and number of data bits at the + * same time), the configuration change of the parity bits will not take place until after the + * next char send out. If the configuration is updated in multiple bus accesses, it will apply + * directly to the next char. So: Double check e.g. with tests/periph/uart_mode after touching + * the initialization code here + * based on Table 1035 page 976 */ + dev->UARTLCR_H = (uint32_t)data_bits << 5; + + if (stop_bits == UART_STOP_BITS_2) { + atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_STP2_Msk); + } + + switch (parity) { + case UART_PARITY_NONE: + break; + case UART_PARITY_EVEN: + atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk); + break; + case UART_PARITY_ODD: + atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk); + break; + default: + return UART_NOMODE; + } + + atomic_set(&dev->UARTCR, UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS); + + return UART_OK; +} + +static void _reset_uart(uart_t uart) +{ + switch (uart) { + case 0: + /* We reset UART0 here, so we can be sure it is in a known state */ + reset_component(RESET_UART0, RESET_UART0); + break; + case 1: + /* We reset UART1 here, so we can be sure it is in a known state */ + reset_component(RESET_UART1, RESET_UART1); + break; + default: + break; + } +} + +void uart_init_pins(uart_t uart) +{ + assert((unsigned)uart < UART_NUMOF); + + /* We reset UART0 here, so we can be sure it is in a known state */ + _reset_uart(uart); + + UART0_Type *dev = uart_config[uart].dev; + + /* Set the UART pins to the correct function */ + *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART; + *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART; + /* Clear the ISO bits */ + atomic_clear( + calculate_gpio_pad_register_addr(uart_config[uart].tx_pin), + PADS_BANK0_ISO_BITS); + atomic_clear( + calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), + PADS_BANK0_ISO_BITS); + + /* Set Input Enable Flag */ + atomic_set( + calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), + PADS_BANK0_GPIO0_IE_BITS); + + dev->UARTIBRD = IBRD; + dev->UARTFBRD = FBRD; +} + +int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) +{ + if (uart >= UART_NUMOF) { + return UART_NODEV; + } + + UART0_Type *dev = uart_config[uart].dev; + ctx[uart].rx_cb = rx_cb; + ctx[uart].arg = arg; + + uart_init_pins(uart); + + _set_symbolrate(uart, baud); + + if (uart_mode( + uart, + UART_DATA_BITS_8, + UART_PARITY_NONE, + UART_STOP_BITS_1) != UART_OK) { + return UART_NOMODE; + } + + /* enable RX and IRQs, if needed */ + if (rx_cb != NULL) { + _irq_enable(uart); + /* clear any pending data and IRQ to avoid receiving a garbage char */ + uint32_t status = dev->UARTRIS; + dev->UARTICR = status; + (void)dev->UARTDR; + atomic_set(&dev->UARTCR, UART_UARTCR_RXE_BITS); + } + + return UART_OK; +} + +void uart_write(uart_t uart, const uint8_t *data, size_t len) +{ + assert((unsigned)uart < UART_NUMOF); + UART0_Type *dev = uart_config[uart].dev; + + for (size_t i = 0; i < len; i++) { + dev->UARTDR = data[i]; + /* Wait until the TX FIFO is empty before sending the next byte */ + while (!(dev->UARTRIS & UART0_UARTRIS_TXRIS_Msk)) { } + } +} + +void uart_poweron(uart_t uart) +{ + assert((unsigned)uart < UART_NUMOF); + /* Get into a safe state where we know what's up */ + _reset_uart(uart); + UART0_Type *dev = uart_config[uart].dev; + /* Restore config from registers */ + dev->UARTIBRD = uartibrd; + dev->UARTFBRD = uartfbrd; + dev->UARTLCR_H = uartlcr_h; + dev->UARTCR = uartcr; + /* restore IRQs, if needed */ + if (ctx[uart].rx_cb != NULL) { + _irq_enable(uart); + } + uart_init_pins(uart); +} + +void uart_deinit_pins(uart_t uart) +{ + assert((unsigned)uart < UART_NUMOF); + /* @TODO */ + /* gpio_reset_all_config(uart_config[uart].tx_pin); */ + SIO->GPIO_OE_CLR = 1LU << uart_config[uart].tx_pin; + if (ctx[uart].rx_cb) { + /* gpio_reset_all_config(uart_config[uart].rx_pin); */ + } +} + +void uart_poweroff(uart_t uart) +{ + assert((unsigned)uart < UART_NUMOF); + UART0_Type *dev = uart_config[uart].dev; + /* backup configuration registers */ + uartibrd = dev->UARTIBRD; + uartfbrd = dev->UARTFBRD; + uartlcr_h = dev->UARTLCR_H; + uartcr = dev->UARTCR; + /* disconnect GPIOs and power off peripheral */ + uart_deinit_pins(uart); + _reset_uart(uart); +} + +void isr_handler(uint8_t num) +{ + UART0_Type *dev = uart_config[num].dev; + + uint32_t status = dev->UARTMIS; + atomic_set(&dev->UARTICR, status); + + if (status & UART_UARTMIS_RXMIS_BITS) { + uint32_t data = dev->UARTDR; + if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) { + puts("[rpx0xx] uart RX error (parity, break, or framing error"); + } + else { + ctx[num].rx_cb(ctx[num].arg, (uint8_t)data); + } + } +} + +/** Overwrites the WEAK_DEFAULT isr_uart0 */ +void isr_uart0(void) +{ + isr_handler(0); + rp_end_isr(); +} + +void isr_uart1(void) +{ + isr_handler(1); + rp_end_isr(); +} + +/** @} */ diff --git a/cpu/rp2350_common/vectors.c b/cpu/rp2350_common/vectors.c new file mode 100644 index 000000000000..5c5ed1eae4dd --- /dev/null +++ b/cpu/rp2350_common/vectors.c @@ -0,0 +1,155 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief Interrupt vector table for the RP2350 + * + * @author Tom Hert + */ + +#include + +#include "cpu_conf.h" +#include "panic.h" + +#ifdef RP2350_USE_RISCV +# include "xh3irq.h" +#else +# include "vectors_cortexm.h" +#endif + +#ifndef WEAK_DEFAULT +# define WEAK_DEFAULT __attribute__((weak, alias("dummy_handler"))) +#endif + +/* define a local dummy handler as it needs to be in the same compilation unit + * as the alias definition */ +void dummy_handler(void) +{ + core_panic(PANIC_GENERAL_ERROR, "DUMMY HANDLER"); +} + +/* rp2350 specific interrupt vector */ +WEAK_DEFAULT void isr_timer0_0(void); +WEAK_DEFAULT void isr_timer0_1(void); +WEAK_DEFAULT void isr_timer0_2(void); +WEAK_DEFAULT void isr_timer0_3(void); +WEAK_DEFAULT void isr_timer1_0(void); +WEAK_DEFAULT void isr_timer1_1(void); +WEAK_DEFAULT void isr_timer1_2(void); +WEAK_DEFAULT void isr_timer1_3(void); +WEAK_DEFAULT void isr_pwm_wrap_0(void); +WEAK_DEFAULT void isr_pwm_wrap_1(void); +WEAK_DEFAULT void isr_dma_0(void); +WEAK_DEFAULT void isr_dma_1(void); +WEAK_DEFAULT void isr_dma_2(void); +WEAK_DEFAULT void isr_dma_3(void); +WEAK_DEFAULT void isr_usbctrl(void); +WEAK_DEFAULT void isr_pio0_0(void); +WEAK_DEFAULT void isr_pio0_1(void); +WEAK_DEFAULT void isr_pio1_0(void); +WEAK_DEFAULT void isr_pio1_1(void); +WEAK_DEFAULT void isr_pio2_0(void); +WEAK_DEFAULT void isr_pio2_1(void); +WEAK_DEFAULT void isr_io_bank0(void); +WEAK_DEFAULT void isr_io_bank0_ns(void); +WEAK_DEFAULT void isr_io_qspi(void); +WEAK_DEFAULT void isr_io_qspi_ns(void); +WEAK_DEFAULT void isr_sio_fifo(void); +WEAK_DEFAULT void isr_sio_bell(void); +WEAK_DEFAULT void isr_sio_fifo_ns(void); +WEAK_DEFAULT void isr_sio_bell_ns(void); +WEAK_DEFAULT void isr_sio_mtimecmp(void); +WEAK_DEFAULT void isr_clocks(void); +WEAK_DEFAULT void isr_spi0(void); +WEAK_DEFAULT void isr_spi1(void); +WEAK_DEFAULT void isr_uart0(void); +WEAK_DEFAULT void isr_uart1(void); +WEAK_DEFAULT void isr_adc_fifo(void); +WEAK_DEFAULT void isr_i2c0(void); +WEAK_DEFAULT void isr_i2c1(void); +WEAK_DEFAULT void isr_otp(void); +WEAK_DEFAULT void isr_trng(void); +WEAK_DEFAULT void isr_proc0_cti(void); +WEAK_DEFAULT void isr_proc1_cti(void); +WEAK_DEFAULT void isr_pll_sys(void); +WEAK_DEFAULT void isr_pll_usb(void); +WEAK_DEFAULT void isr_powman_pow(void); +WEAK_DEFAULT void isr_powman_timer(void); +WEAK_DEFAULT void isr_spareirq_0(void); +WEAK_DEFAULT void isr_spareirq_1(void); +WEAK_DEFAULT void isr_spareirq_2(void); +WEAK_DEFAULT void isr_spareirq_3(void); +WEAK_DEFAULT void isr_spareirq_4(void); +WEAK_DEFAULT void isr_spareirq_5(void); + +/** CPU specific interrupt vector table + * @see 3.2 Interrupts and IRQn_Type in RP2350.h + */ +#ifdef RP2350_USE_ARM +/* Cortex-M does some macro magic, RISC-V does not */ +ISR_VECTOR(1) +#endif +const void* vector_cpu[CPU_IRQ_NUMOF] = { + (void*)isr_timer0_0, /* 0 TIMER0_IRQ_0 */ + (void*)isr_timer0_1, /* 1 TIMER0_IRQ_1 */ + (void*)isr_timer0_2, /* 2 TIMER0_IRQ_2 */ + (void*)isr_timer0_3, /* 3 TIMER0_IRQ_3 */ + (void*)isr_timer1_0, /* 4 TIMER1_IRQ_0 */ + (void*)isr_timer1_1, /* 5 TIMER1_IRQ_1 */ + (void*)isr_timer1_2, /* 6 TIMER1_IRQ_2 */ + (void*)isr_timer1_3, /* 7 TIMER1_IRQ_3 */ + (void*)isr_pwm_wrap_0, /* 8 PWM_IRQ_WRAP_0 */ + (void*)isr_pwm_wrap_1, /* 9 PWM_IRQ_WRAP_1 */ + (void*)isr_dma_0, /* 10 DMA_IRQ_0 */ + (void*)isr_dma_1, /* 11 DMA_IRQ_1 */ + (void*)isr_dma_2, /* 12 DMA_IRQ_2 */ + (void*)isr_dma_3, /* 13 DMA_IRQ_3 */ + (void*)isr_usbctrl, /* 14 USBCTRL_IRQ */ + (void*)isr_pio0_0, /* 15 PIO0_IRQ_0 */ + (void*)isr_pio0_1, /* 16 PIO0_IRQ_1 */ + (void*)isr_pio1_0, /* 17 PIO1_IRQ_0 */ + (void*)isr_pio1_1, /* 18 PIO1_IRQ_1 */ + (void*)isr_pio2_0, /* 19 PIO2_IRQ_0 */ + (void*)isr_pio2_1, /* 20 PIO2_IRQ_1 */ + (void*)isr_io_bank0, /* 21 IO_IRQ_BANK0 */ + (void*)isr_io_bank0_ns, /* 22 IO_IRQ_BANK0_NS */ + (void*)isr_io_qspi, /* 23 IO_IRQ_QSPI */ + (void*)isr_io_qspi_ns, /* 24 IO_IRQ_QSPI_NS */ + (void*)isr_sio_fifo, /* 25 SIO_IRQ_FIFO */ + (void*)isr_sio_bell, /* 26 SIO_IRQ_BELL */ + (void*)isr_sio_fifo_ns, /* 27 SIO_IRQ_FIFO_NS */ + (void*)isr_sio_bell_ns, /* 28 SIO_IRQ_BELL_NS */ + (void*)isr_sio_mtimecmp, /* 29 SIO_IRQ_MTIMECMP */ + (void*)isr_clocks, /* 30 CLOCKS_IRQ */ + (void*)isr_spi0, /* 31 SPI0_IRQ */ + (void*)isr_spi1, /* 32 SPI1_IRQ */ + (void*)isr_uart0, /* 33 UART0_IRQ */ + (void*)isr_uart1, /* 34 UART1_IRQ */ + (void*)isr_adc_fifo, /* 35 ADC_IRQ_FIFO */ + (void*)isr_i2c0, /* 36 I2C0_IRQ */ + (void*)isr_i2c1, /* 37 I2C1_IRQ */ + (void*)isr_otp, /* 38 OTP_IRQ */ + (void*)isr_trng, /* 39 TRNG_IRQ */ + (void*)isr_proc0_cti, /* 40 PROC0_IRQ_CTI */ + (void*)isr_proc1_cti, /* 41 PROC1_IRQ_CTI */ + (void*)isr_pll_sys, /* 42 PLL_SYS_IRQ */ + (void*)isr_pll_usb, /* 43 PLL_USB_IRQ */ + (void*)isr_powman_pow, /* 44 POWMAN_IRQ_POW */ + (void*)isr_powman_timer, /* 45 POWMAN_IRQ_TIMER */ + (void*)isr_spareirq_0, /* 46 SPAREIRQ_IRQ_0 */ + (void*)isr_spareirq_1, /* 47 SPAREIRQ_IRQ_1 */ + (void*)isr_spareirq_2, /* 48 SPAREIRQ_IRQ_2 */ + (void*)isr_spareirq_3, /* 49 SPAREIRQ_IRQ_3 */ + (void*)isr_spareirq_4, /* 50 SPAREIRQ_IRQ_4 */ + (void*)isr_spareirq_5, /* 51 SPAREIRQ_IRQ_5 */ +}; + +/** @} */ diff --git a/cpu/rp2350_common/xosc.c b/cpu/rp2350_common/xosc.c new file mode 100644 index 000000000000..c398e28ec9ee --- /dev/null +++ b/cpu/rp2350_common/xosc.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350 + * @{ + * + * @file + * @brief XOSC implementation for the RP2350 + * + * @author Tom Hert + */ + +#include + +#include "RP2350.h" +#include "board.h" +#include "macros/units.h" +#include "periph_cpu.h" + +/* Based on datasheet 8.2.4 (1ms wait time) */ +#define STARTUP_DELAY 47 +#define MAX_XOSC_COUNTER_SIZE 0xFFFF +#define SLEEP_100HZ_SPEED 12000000UL +#define CYCLES_PER_MS (SLEEP_100HZ_SPEED / 1000) + +void xosc_start(void) { + /* Set the FREQ_RANGE */ + XOSC->CTRL = XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ; + /* Set the startup delay (default 1ms) */ + XOSC->STARTUP = STARTUP_DELAY; + /* set enable bit */ + atomic_set(&XOSC->CTRL, + XOSC_CTRL_ENABLE_VALUE_ENABLE << XOSC_CTRL_ENABLE_LSB); + + while (!(XOSC->STATUS & XOSC_STATUS_STABLE_BITS)) { + /* Wait for the crystal to stabilize */ + } +} + +void xosc_sleep(uint32_t milliseconds) { + for (uint32_t i = milliseconds; i > 0; i--) { + XOSC->COUNT = CYCLES_PER_MS; + while (XOSC->COUNT != 0) {}; + } +} + +void xosc_stop(void) { + /* @TODO */ +} + +/** @} */ From e475534771f4d80a150584b5d63de1ccd075003e Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 13:57:56 +0200 Subject: [PATCH 07/20] cpu/rp2350_riscv: move to shared rp2350_common --- cpu/rp2350/Makefile | 6 - cpu/rp2350/Makefile.dep | 3 - cpu/rp2350/Makefile.include | 33 --- cpu/rp2350/clock.c | 71 ------ cpu/rp2350/cpu.c | 59 ----- cpu/rp2350/include/clock_conf.h | 159 ------------ cpu/rp2350/include/gpio_conf.h | 66 ----- cpu/rp2350/include/helpers.h | 80 ------ cpu/rp2350/include/periph_cpu.h | 102 -------- cpu/rp2350/include/uart_conf.h | 55 ----- cpu/rp2350/periph/Makefile | 1 - cpu/rp2350/periph/gpio.c | 96 -------- cpu/rp2350/periph/uart.c | 86 ------- cpu/rp2350/vectors.c | 136 ----------- cpu/rp2350/xosc.c | 55 ----- cpu/{rp2350 => rp2350_arm}/Kconfig | 12 +- cpu/rp2350_arm/Makefile | 8 + cpu/rp2350_arm/Makefile.dep | 4 + cpu/{rp2350 => rp2350_arm}/Makefile.features | 6 +- cpu/rp2350_arm/cpu.c | 26 ++ cpu/{rp2350 => rp2350_arm}/doc.md | 0 cpu/{rp2350 => rp2350_arm}/include/cpu_conf.h | 4 +- .../ldscripts/RP2350_ARM.ld} | 0 cpu/{rp2350 => rp2350_arm}/picobin_block.s | 0 cpu/rp2350_riscv/Makefile.dep | 4 +- cpu/rp2350_riscv/Makefile.features | 6 +- cpu/rp2350_riscv/Makefile.include | 21 +- cpu/rp2350_riscv/clock.c | 71 ------ cpu/rp2350_riscv/cpu.c | 28 +-- cpu/rp2350_riscv/include/clock_conf.h | 159 ------------ cpu/rp2350_riscv/include/cpu_conf.h | 2 + cpu/rp2350_riscv/include/gpio_conf.h | 66 ----- cpu/rp2350_riscv/include/helpers.h | 78 ------ cpu/rp2350_riscv/include/periph_cpu.h | 115 --------- cpu/rp2350_riscv/include/uart_conf.h | 55 ----- cpu/rp2350_riscv/periph/Makefile | 1 - cpu/rp2350_riscv/periph/gpio.c | 96 -------- cpu/rp2350_riscv/periph/uart.c | 231 ------------------ cpu/rp2350_riscv/vectors.c | 141 ----------- cpu/rp2350_riscv/xosc.c | 55 ----- 40 files changed, 62 insertions(+), 2135 deletions(-) delete mode 100644 cpu/rp2350/Makefile delete mode 100644 cpu/rp2350/Makefile.dep delete mode 100644 cpu/rp2350/Makefile.include delete mode 100644 cpu/rp2350/clock.c delete mode 100644 cpu/rp2350/cpu.c delete mode 100644 cpu/rp2350/include/clock_conf.h delete mode 100644 cpu/rp2350/include/gpio_conf.h delete mode 100644 cpu/rp2350/include/helpers.h delete mode 100644 cpu/rp2350/include/periph_cpu.h delete mode 100644 cpu/rp2350/include/uart_conf.h delete mode 100644 cpu/rp2350/periph/Makefile delete mode 100644 cpu/rp2350/periph/gpio.c delete mode 100644 cpu/rp2350/periph/uart.c delete mode 100644 cpu/rp2350/vectors.c delete mode 100644 cpu/rp2350/xosc.c rename cpu/{rp2350 => rp2350_arm}/Kconfig (55%) create mode 100644 cpu/rp2350_arm/Makefile create mode 100644 cpu/rp2350_arm/Makefile.dep rename cpu/{rp2350 => rp2350_arm}/Makefile.features (58%) create mode 100644 cpu/rp2350_arm/cpu.c rename cpu/{rp2350 => rp2350_arm}/doc.md (100%) rename cpu/{rp2350 => rp2350_arm}/include/cpu_conf.h (80%) rename cpu/{rp2350/ldscripts/RP2350.ld => rp2350_arm/ldscripts/RP2350_ARM.ld} (100%) rename cpu/{rp2350 => rp2350_arm}/picobin_block.s (100%) delete mode 100644 cpu/rp2350_riscv/clock.c delete mode 100644 cpu/rp2350_riscv/include/clock_conf.h delete mode 100644 cpu/rp2350_riscv/include/gpio_conf.h delete mode 100644 cpu/rp2350_riscv/include/helpers.h delete mode 100644 cpu/rp2350_riscv/include/periph_cpu.h delete mode 100644 cpu/rp2350_riscv/include/uart_conf.h delete mode 100644 cpu/rp2350_riscv/periph/Makefile delete mode 100644 cpu/rp2350_riscv/periph/gpio.c delete mode 100644 cpu/rp2350_riscv/periph/uart.c delete mode 100644 cpu/rp2350_riscv/vectors.c delete mode 100644 cpu/rp2350_riscv/xosc.c diff --git a/cpu/rp2350/Makefile b/cpu/rp2350/Makefile deleted file mode 100644 index 33d57306d1a7..000000000000 --- a/cpu/rp2350/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -MODULE = cpu - -DIRS += $(RIOTCPU)/cortexm_common -DIRS += periph - -include $(RIOTBASE)/Makefile.base diff --git a/cpu/rp2350/Makefile.dep b/cpu/rp2350/Makefile.dep deleted file mode 100644 index 75b95e8112ed..000000000000 --- a/cpu/rp2350/Makefile.dep +++ /dev/null @@ -1,3 +0,0 @@ -USEPKG += picosdk - -include $(RIOTCPU)/cortexm_common/Makefile.dep diff --git a/cpu/rp2350/Makefile.include b/cpu/rp2350/Makefile.include deleted file mode 100644 index 67a10640106d..000000000000 --- a/cpu/rp2350/Makefile.include +++ /dev/null @@ -1,33 +0,0 @@ -ROM_LEN ?= 2097152 # = 2 MiB used in the RPi Pico -ROM_OFFSET := 0 # bootloader size -RAM_LEN := 0x82000 # 520kB = 532479 used in the RPi Pico 2350 -ROM_START_ADDR := 0x10000000 # XIP Non-Secure address for rp2350 -RAM_START_ADDR := 0x20000000 # Non-Secure RAM address for rp2350 - -# CPU and architecture specific flags -CFLAGS += -D$(CPU_MODEL) -CFLAGS += -DROM_START_ADDR=$(ROM_START_ADDR) -CFLAGS += -DRAM_START_ADDR=$(RAM_START_ADDR) -CFLAGS += -Wno-error - -# Include paths -INCLUDES += -I$(RIOTCPU)/rp2350/include -INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include -INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include - -# Linker flags -LINKFLAGS += -mcpu=$(CPU_ARCH) -mthumb -LINKFLAGS += -Wl,--gc-sections -LINKFLAGS += -Wl,--start-group -lc -lm -Wl,--end-group - -# Vector table configuration -VECTORS_O ?= $(BINDIR)/cpu/vectors.o -VECTORS_FILE := $(RIOTCPU)/rp2350/vectors.c - -# Supported programmers and debuggers -PROGRAMMERS_SUPPORTED := picotool openocd jlink -PROGRAMMER ?= picotool -OPENOCD_DEBUG_ADAPTER ?= dap - -# Include the base Cortex-M makefile -include $(RIOTMAKE)/arch/cortexm.inc.mk diff --git a/cpu/rp2350/clock.c b/cpu/rp2350/clock.c deleted file mode 100644 index 243b64451160..000000000000 --- a/cpu/rp2350/clock.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief Clock configuration implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "periph_cpu.h" - -void clock_reset(void) { - /* Reset the clock system */ - reset_component(RESET_PLL_SYS, RESET_PLL_SYS); -} - -/** - * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it - * @warning Make sure to call clock_reset() before this function to reset the - * clock system - * @see RP2350 Docs Chapter 8, mostly 8.2 for more details - */ -void cpu_clock_init(void) { - /* Enable the XOSC */ - xosc_start(); - - /* Setup the PLL using the XOSC as the reference clock. */ - PLL_SYS->FBDIV_INT = - PLL_FEEDBACK_DIVIDER_VALUE; /* Set the feedback divider */ - - /* Set the post-dividers for the PLL output.*/ - PLL_SYS->PRIM = PDIV; - /* Turn on PLL */ - atomic_clear(&PLL_SYS->PWR, - PLL_PWR_PD_BITS | PLL_PWR_VCOPD_BITS | PLL_PWR_POSTDIVPD_BITS); - - /* sleep 10ms to allow the PLL to stabilize */ - xosc_sleep(10); - - /* Based on the description in chapter 8 this is something that should be done - * However, it appears to cause issues and is not done by other examples on the - * internet. This needs to be investigated further. */ - - /* Wait for lock */ - /* while (!(PLL_SYS->CS & PLL_CS_LOCK_BITS)) { */ - /* Wait for the PLL to lock */ - /* } */ - - /* AUXSRC = 0x0 7:5 && SRC == 0x0 0 */ - CLOCKS->CLK_SYS_CTRL = CLK_SYS_PERI_CTRL_ENABLE_BIT; - - /* This register contains one decoded bit for each of the clock sources - * enumerated in the CTRL SRC field. The bit does not directly correlate with - * the value of the SRC field For example 0x0 is the first bit while 0x1 is - * the second bit. In some way this makes sense, in some way I lost too much - * time on this. */ - while (CLOCKS->CLK_SYS_SELECTED != CLK_SYS_SELECTED_PERI_FIELD_VALUE) { - } - - /* AUXSRC = 0x0 -> CLK_SYS Indirectly through lower line */ - CLOCKS->CLK_PERI_CTRL = CLK_PERI_CTRL_ENABLE_BIT; -} - -/** @} */ diff --git a/cpu/rp2350/cpu.c b/cpu/rp2350/cpu.c deleted file mode 100644 index f4ff0006d8c8..000000000000 --- a/cpu/rp2350/cpu.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief CPU initialization implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "cpu.h" - -#include "RP2350.h" -#include "board.h" -#include "kernel_init.h" -#include "macros/units.h" -#include "periph/gpio.h" -#include "periph/init.h" -#include "periph_cpu.h" -#include "stdio_base.h" - -#define DEBUG_WITH_OSC - -void gpio_reset(void) { - reset_component(RESET_PADS_BANK0, RESET_PADS_BANK0); - reset_component(RESET_IO_BANK0, RESET_IO_BANK0); -} - -void cpu_init(void) { - /* initialize the Cortex-M core, once UART support is moved - * to shared driver as currently this will cause unhandled interrupts */ - /* cortexm_init(); */ - - /* Reset GPIO state */ - gpio_reset(); - - /* Reset clock to default state */ - clock_reset(); - - /* initialize the CPU clock */ - cpu_clock_init(); - - /* initialize the early peripherals */ - early_init(); - - /* trigger static peripheral initialization */ - periph_init(); - - /* initialize the board */ - board_init(); -} - -/** @} */ diff --git a/cpu/rp2350/include/clock_conf.h b/cpu/rp2350/include/clock_conf.h deleted file mode 100644 index f5137e4c57d0..000000000000 --- a/cpu/rp2350/include/clock_conf.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief Clock configuration for the RP2350 - * - * @author Tom Hert - */ - -#include "RP2350.h" -#include "macros/units.h" - -/** 1-15 MHz range - * @see hardware/regs/xosc.h and chapter 8.2.8 - */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ 0xaa0u -/** 10-30 MHz range */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_10_30MHZ 0xaa1u -/** 25-60 MHz range */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_25_60MHZ 0xaa2u -/** 40-100 MHz range */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_40_100MHZ 0xaa3u -/** Disable the XOSC */ -#define XOSC_CTRL_ENABLE_VALUE_DISABLE 0xd1eu -/** Enable the XOSC */ -#define XOSC_CTRL_ENABLE_VALUE_ENABLE 0xfabu -/** LSB of the enable bit */ -#define XOSC_CTRL_ENABLE_LSB 12u -/** Stable bit in the XOSC status register */ -#define XOSC_STATUS_STABLE_BITS 0x80000000u -/** Default crystal frequency is 12 MHz */ -#define XOSC_HZ MHZ(12u) -/** Reference divider for the PLL, set to 2 as per hardware manual */ -#define PLL_REF_DIV 2u -/** VCO frequency for the PLL, set to 750 MHz as per hardware manual */ -#define PLL_VCO_FREQ 750000000u -/** Post divider 1 for the PLL, set to 6 as per hardware manual */ -#define PLL_PD1 6u -/** Post divider 2 for the PLL, set to 2 as per hardware manual */ -#define PLL_PD2 2u -/** Power down bits for the PLL */ -#define PLL_PWR_PD_BITS 0x00000001u -/** VCO power down bits for the PLL */ -#define PLL_PWR_VCOPD_BITS 0x00000020u -/** Lock bit in the PLL control status register */ -#define PLL_CS_LOCK_BITS 0x80000000u -/** LSB of the post divider 1 in the PLL primary register */ -#define PLL_PRIM_POSTDIV1_LSB 16u -/** LSB of the post divider 2 in the PLL primary register */ -#define PLL_PRIM_POSTDIV2_LSB 12u -/** Post divider power down bits for the PLL */ -#define PLL_PWR_POSTDIVPD_BITS 0x00000008u -/** Enable bit for the peripheral clock control register */ -#define CLK_PERI_CTRL_ENABLE_BIT (1u << 11u) -/** Default CPU frequency in Hz, set to 125 MHz as per hardware manual */ -#define CPUFREQ 125000000u -/** Maximum crystal frequency */ -#define CLOCK_XOSC_MAX MHZ(15u) -/** Minimum crystal frequency */ -#define CLOCK_XOSC_MIN MHZ(5u) -/** Crystal frequency */ -#define CLOCK_XOSC (XOSC_HZ) -/** Minimum value of the post PLL clock divers */ -#define PLL_POSTDIV_MIN 1u -/** Maximum value of the post PLL clock divers */ -#define PLL_POSTDIV_MAX 7u -/** Minimum value of the PLL VCO feedback scaler */ -#define PLL_VCO_FEEDBACK_SCALE_MIN 16u -/** Maximum value of the PLL VCO feedback scaler */ -#define PLL_VCO_FEEDBACK_SCALE_MAX 320u -/** Minimum value of the clock divider applied before - * feeding in the reference clock into the PLL */ -#define PLL_REF_DIV_MIN 1u -/** Minimum value of the clock divider applied before feeding in - * the reference clock into the PLL */ -#define PLL_REF_DIV_MAX 1u -/** PLL feedback divider value, set to 125 as per hardware manual */ -#define PLL_FEEDBACK_DIVIDER_VALUE 125u -/** Enable bit for the system clock control register to select the peripheral - * clock */ -#define CLK_SYS_PERI_CTRL_ENABLE_BIT (1u << 0u) -/** Selected field value for the system clock control register -* to select the peripheral clock */ -#define CLK_SYS_SELECTED_PERI_FIELD_VALUE 2u -/** RIOT core clock frequency defined as the CPU frequency */ -#define CLOCK_CORECLOCK MHZ(12u) - -#if (PLL_VCO_FEEDBACK_SCALE_MIN < PLL_VCO_FEEDBACK_SCALE_MIN) || \ -(PLL_VCO_FEEDBACK_SCALE_MAX > PLL_VCO_FEEDBACK_SCALE_MAX) -# error "Value for PLL_VCO_FEEDBACK_SCALE out of range, check config" -#endif -#if (PLL_REF_DIV_MIN < PLL_REF_DIV_MIN) || (PLL_REF_DIV_MAX > PLL_REF_DIV_MAX) -# error "Value for PLLxosc_sleep_REF_DIV out of range, check config" -#endif -#if (PLL_POSTDIV_MIN < PLL_POSTDIV_MIN) || (PLL_POSTDIV_MAX > PLL_POSTDIV_MAX) -# error "Value for PLL_POSTDIV out of range, check config" -#endif -#if ((CLOCK_XOSC > CLOCK_XOSC_MAX) || (CLOCK_XOSC < CLOCK_XOSC_MIN)) -# error "Value for CLOCK_XOSC out of range, check config" -#endif - -/** Post divider for the PLL, calculated based on the post divider values */ -#define PDIV ((PLL_PD1 << PLL_PRIM_POSTDIV1_LSB) | (PLL_PD2 << PLL_PRIM_POSTDIV2_LSB)) -/** Feedback divider for the PLL, calculated based on the VCO frequency and -* reference clock frequency */ -#define FBDIV ((PLL_VCO_FREQ / XOSC_HZ) / PLL_REF_DIV) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the Crystal to run. - * @note The reference hardware manual suggests to use a 12 MHz crystal, which we - * use by default. - */ -void xosc_start(void); - -/** - * @brief Stop the crystal. - */ -void xosc_stop(void); - -/** - * @brief Sleep for a given time in milliseconds. - * @param milliseconds The time to sleep in milliseconds. - */ -void xosc_sleep(uint32_t milliseconds); - -/** - * @brief Reset the clock system. - * - * This function resets the clock system to a known state. - * It is recommended to call this function before configuring the clock system. - */ -void clock_reset(void); - -/** - * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it - * @pre Make sure to call clock_reset() before this function to reset the - * clock system - * @see RP2350 Docs Chapter 8, mostly 8.2 for more details - */ -void cpu_clock_init(void); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350/include/gpio_conf.h b/cpu/rp2350/include/gpio_conf.h deleted file mode 100644 index 3991542d434c..000000000000 --- a/cpu/rp2350/include/gpio_conf.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert git@annsann.eu> - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief GPIO configuration for the RP2350 - * - * @author Tom Hert - */ - -/** The number of GPIO pins available on the RP2350 */ -#define GPIO_PIN_NUMOF 30u - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Possible function values for @ref gpio_io_ctrl_t::function_select - */ -typedef enum { - /** connect pin to the SPI peripheral (MISO/MOSI/SCK depends on pin) */ - FUNCTION_SELECT_SPI = 1, - - /** connect pin to the UART peripheral (TXD/RXD depends on pin) */ - FUNCTION_SELECT_UART = 2, - - /** connect pin to the I2C peripheral (SCL/SDA depends on pin) */ - FUNCTION_SELECT_I2C = 3, - - /** connect pin to the timer for PWM (channel depends on pin) */ - FUNCTION_SELECT_PWM = 4, - - /** use pin as vanilla GPIO */ - FUNCTION_SELECT_SIO = 5, - - /** connect pin to the first PIO peripheral */ - FUNCTION_SELECT_PIO0 = 6, - - /** connect pin to the second PIO peripheral */ - FUNCTION_SELECT_PIO1 = 7, - - /** connect pin to the timer (depending on pin: external clock, - * clock output, or not supported) */ - FUNCTION_SELECT_CLOCK = 8, - - /** connect pin to the USB peripheral (function depends on pin) */ - FUNCTION_SELECT_USB = 9, - - /** Reset value, pin unconnected */ - FUNCTION_SELECT_NONE = 31, -} gpio_function_select_t; - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350/include/helpers.h b/cpu/rp2350/include/helpers.h deleted file mode 100644 index 556088201772..000000000000 --- a/cpu/rp2350/include/helpers.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -#include "RP2350.h" - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief Helper functions for atomic register operations - * - * @author Tom Hert - */ - -/** Bit to be set for an atomic XOR operation */ -#define ATOMIC_XOR_WRITE 0x1000u -/** Bit to be set for an atomic set operation */ -#define ATOMIC_BITMASK_SET_WRITE 0x2000u -/** Bits to be set for an atomic clear operation */ -#define ATOMIC_BITMASK_CLEAR_WRITE 0x3000u - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Perform an atomic XOR write to a register - * - * @param[in,out] reg Pointer to the target register - * @param[in] val Value to be XORed with the register - */ -static inline void atomic_xor(volatile uint32_t *reg, uint32_t val) { - *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_XOR_WRITE) = val; -} - -/** - * @brief Set bits in a register atomically - * - * @param[in,out] reg Pointer to the target register - * @param[in] val Bit mask of bits to set - */ -static inline void atomic_set(volatile uint32_t *reg, uint32_t val) { - *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_SET_WRITE) = val; -} - -/** - * @brief Clear bits in a register atomically - * - * @param[in,out] reg Pointer to the target register - * @param[in] val Bit mask of bits to clear - */ -static inline void atomic_clear(volatile uint32_t *reg, uint32_t val) { - *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_CLEAR_WRITE) = val; -} - -/** - * @brief Reset a component by clearing its reset bits and waiting for the reset to complete - * - * @param reset_value Bit mask of the reset bits to clear - * @param reset_done_value Bit mask of the reset done bits to wait for - */ -static inline void reset_component(uint32_t reset_value, - uint32_t reset_done_value) { - atomic_clear(&RESETS->RESET, reset_value); - while (~RESETS->RESET_DONE & reset_done_value) { - /* Wait for the reset to complete */ - } -} - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350/include/periph_cpu.h b/cpu/rp2350/include/periph_cpu.h deleted file mode 100644 index 0eb149a4a009..000000000000 --- a/cpu/rp2350/include/periph_cpu.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief Peripheral CPU definitions for the RP2350 - * - * @author Tom Hert - */ - -#include -#include - -#include "RP2350.h" -#include "clock_conf.h" -#include "cpu.h" -#include "gpio_conf.h" -#include "helpers.h" -#include "uart_conf.h" - -/** Overwrite the default GPIO type to use uint32_t */ -#define HAVE_GPIO_T -typedef uint32_t gpio_t; - -#include "periph/gpio.h" - -/** GPIO Pin ID for oscillator debugging */ -#define OSC_DEBUG_PIN_ID 15u - -/** Reset bit for the system PLL */ -#define RESET_PLL_SYS (1u << 14u) - -/** Reset bit for the pads bank 0 */ -#define RESET_PADS_BANK0 (1u << 9u) - -/** Reset bit for UART0 peripheral */ -#define RESET_UART0 (1u << 26u) - -/** Reset bit for UART1 peripheral */ -#define RESET_UART1 (1u << 27u) - -/** Reset bit for the IO bank 0 */ -#define RESET_IO_BANK0 (1u << 6u) - -/** Input enable bit for GPIO0 in PADS_BANK0 */ -#define PADS_BANK0_GPIO0_IE_BITS (1u << 6u) - -/** Isolation bits for PADS_BANK0 */ -#define PADS_BANK0_ISO_BITS (1u << 8u) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Calculate the address of the GPIO pad register for a given pin - * @param pin The GPIO pin number - * @return The address of the GPIO pad register for the given pin - */ -static inline uint32_t calculate_gpio_pad_register_addr(gpio_t pin) { - /* Each pin has a 4 byte register, so we can calculate the address - * by adding 4 bytes for each pin, starting at the base address of PADS_BANK0 - * and adding 4 bytes to skip VOLTAGE_SELECT */ - return PADS_BANK0_BASE + 4 * (pin + 1); -} - -/** - * @brief Calculate the address of the GPIO IO status register for a given pin - * @param pin The GPIO pin number - * @return The address of the GPIO IO status register for the given pin - */ -static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { - /* Each status register is followed by a ctrl register, */ - return IO_BANK0_BASE + 8 * pin; -} - -/** - * @brief Calculate the address of the GPIO IO control register for a given - * pin - * @param pin The GPIO pin number - * @return The address of the GPIO IO control register for the given pin - */ -static inline uint32_t calculate_gpio_io_ctrl_register_addr(gpio_t pin) { - /* Each pin has a 8 byte register (4 Bytes of Status, 4 Bytes of CTRL), - * so we can calculate the address by adding 8 bytes for each pin, - * starting at the base address of IO_BANK0 */ - return calculate_gpio_io_status_register_addr(pin) + 4; -} - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350/include/uart_conf.h b/cpu/rp2350/include/uart_conf.h deleted file mode 100644 index ed25e9f6eae3..000000000000 --- a/cpu/rp2350/include/uart_conf.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief UART configuration for the RP2350 - * - * @author Tom Hert - */ - -#include "RP2350.h" -#include "macros/units.h" -#include "periph_cpu.h" - -/** UART baud rate in bits per second */ -#define BAUDRATE 115200u - -/** Integer baud rate divisor */ -#define IBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) / 64u) - -/** Fractional baud rate divisor */ -#define FBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) % 64u) - -/** UART enable bit in control register */ -#define UART_UARTCR_UARTEN_BITS (1u << 0u) - -/** UART receive enable bit in control register */ -#define UART_UARTCR_RXE_BITS (1u << 9u) - -/** UART transmit enable bit in control register */ -#define UART_UARTCR_TXE_BITS (1u << 8u) - -/** UART receive FIFO full flag bit in flag register */ -#define UART_UARTFR_RXFF_BITS (1u << 6u) - -/** UART transmit FIFO empty flag bit in flag register */ -#define UART_UARTFR_TXFE_BITS (1u << 7u) - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350/periph/Makefile b/cpu/rp2350/periph/Makefile deleted file mode 100644 index a36df249ac1d..000000000000 --- a/cpu/rp2350/periph/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(RIOTMAKE)/periph.mk diff --git a/cpu/rp2350/periph/gpio.c b/cpu/rp2350/periph/gpio.c deleted file mode 100644 index e949b344451d..000000000000 --- a/cpu/rp2350/periph/gpio.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief GPIO implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "periph/gpio.h" - -#include - -#include "board.h" -#include "irq.h" -#include "periph_conf.h" -#include "periph_cpu.h" - -#define ENABLE_DEBUG 0 -#include "debug.h" - -int gpio_init(gpio_t pin, gpio_mode_t mode) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - - /* Clear the pin's output enable and output state */ - SIO->GPIO_OE_CLR = 1LU << pin; - SIO->GPIO_OUT_CLR = 1LU << pin; - - switch (mode) { - case GPIO_OUT: - *(uint32_t*)calculate_gpio_io_ctrl_register_addr(pin) = - FUNCTION_SELECT_SIO; - - volatile uint32_t* pad_reg = - (uint32_t*)calculate_gpio_pad_register_addr(pin); - - /* We clear all bits except the drive strength bit - * We set that to the highest one possible (12mA) - * to mimic the behavior of the pico1 GPIO driver - * (Not too sure why we do this, but it seems to be the standard) */ - *pad_reg = 0x3 << 4; - - SIO->GPIO_OE_SET = 1 << pin; /* Set the pin as output */ - - break; - default: - /* Unsupported mode */ - return -ENOTSUP; - } - return 0; -} - -bool gpio_read(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - /* Read the pin state */ - return (SIO->GPIO_IN & (1 << pin)) != 0; /* Return true if the pin is HIGH */ -} - -void gpio_set(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - SIO->GPIO_OUT_SET = 1 << pin; /* Set the pin to HIGH */ -} - -void gpio_clear(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - SIO->GPIO_OUT_CLR = 1 << pin; /* Set the pin to LOW */ -} - -void gpio_toggle(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - SIO->GPIO_OUT_XOR = 1 << pin; /* Toggle the pin state (XOR) */ -} - -void gpio_write(gpio_t pin, bool value) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - if (value) { - gpio_set(pin); /* Set the pin to HIGH */ - } else { - gpio_clear(pin); /* Set the pin to LOW */ - } -} - -/** @} */ diff --git a/cpu/rp2350/periph/uart.c b/cpu/rp2350/periph/uart.c deleted file mode 100644 index 4b6c21677e72..000000000000 --- a/cpu/rp2350/periph/uart.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief UART implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "periph/uart.h" - -#include "periph_cpu.h" - -int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) { - (void)uart; - (void)baud; - (void)rx_cb; - (void)arg; - /* Set the UART pins to the correct function */ - IO_BANK0->GPIO0_CTRL = FUNCTION_SELECT_UART; - IO_BANK0->GPIO1_CTRL = FUNCTION_SELECT_UART; - /* Clear the ISO bits */ - atomic_clear(&PADS_BANK0->GPIO0, PADS_BANK0_ISO_BITS); - atomic_clear(&PADS_BANK0->GPIO1, PADS_BANK0_ISO_BITS); - /* Set IE bit for gpio1 */ - PADS_BANK0->GPIO1 = PADS_BANK0->GPIO1 | PADS_BANK0_GPIO0_IE_BITS; - - /* We reset UART0 here, so we can be sure it is in a known state */ - reset_component(RESET_UART0, RESET_UART0); - - UART0->UARTIBRD = IBRD; - UART0->UARTFBRD = FBRD; - uart_mode(0, 8, UART_PARITY_NONE, 1); - return 0; -} - -int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, - uart_stop_bits_t stop_bits) { - (void)uart; - (void)data_bits; - (void)stop_bits; - atomic_clear(&UART0->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS | - UART_UARTCR_TXE_BITS); - - /* Set the data bits, parity, and stop bits - * Set to 8 bits (0b11) based on Table 1035 page 976 - */ - UART0->UARTLCR_H = 0b11 << 5; - - switch (parity) { - case UART_PARITY_NONE: - break; - default: - return UART_NOMODE; - } - - UART0->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS; - - return UART_OK; -} - -void uart_write(uart_t uart, const uint8_t *data, size_t len) { - (void)uart; - for (size_t i = 0; i < len; i++) { - UART0->UARTDR = data[i]; - /* Wait until the TX FIFO is empty before sending the next byte */ - while (!(UART0->UARTFR & UART_UARTFR_TXFE_BITS)) { - } - } -} - -void uart_poweron(uart_t uart) { - (void)uart; -} -void uart_poweroff(uart_t uart) { - (void)uart; -} - -/** @} */ diff --git a/cpu/rp2350/vectors.c b/cpu/rp2350/vectors.c deleted file mode 100644 index 36d0079f4c59..000000000000 --- a/cpu/rp2350/vectors.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief Interrupt vector table for the RP2350 - * - * @author Tom Hert - */ - -#include "RP2350.h" -#include "cpu_conf.h" -#include "vectors_cortexm.h" - -/* define a local dummy handler as it needs to be in the same compilation unit - * as the alias definition */ -void dummy_handler(void) { dummy_handler_default(); } - -/* rp2350 specific interrupt vector */ -WEAK_DEFAULT void isr_timer0_0(void); -WEAK_DEFAULT void isr_timer0_1(void); -WEAK_DEFAULT void isr_timer0_2(void); -WEAK_DEFAULT void isr_timer0_3(void); -WEAK_DEFAULT void isr_timer1_0(void); -WEAK_DEFAULT void isr_timer1_1(void); -WEAK_DEFAULT void isr_timer1_2(void); -WEAK_DEFAULT void isr_timer1_3(void); -WEAK_DEFAULT void isr_pwm_wrap_0(void); -WEAK_DEFAULT void isr_pwm_wrap_1(void); -WEAK_DEFAULT void isr_dma_0(void); -WEAK_DEFAULT void isr_dma_1(void); -WEAK_DEFAULT void isr_dma_2(void); -WEAK_DEFAULT void isr_dma_3(void); -WEAK_DEFAULT void isr_usbctrl(void); -WEAK_DEFAULT void isr_pio0_0(void); -WEAK_DEFAULT void isr_pio0_1(void); -WEAK_DEFAULT void isr_pio1_0(void); -WEAK_DEFAULT void isr_pio1_1(void); -WEAK_DEFAULT void isr_pio2_0(void); -WEAK_DEFAULT void isr_pio2_1(void); -WEAK_DEFAULT void isr_io_bank0(void); -WEAK_DEFAULT void isr_io_bank0_ns(void); -WEAK_DEFAULT void isr_io_qspi(void); -WEAK_DEFAULT void isr_io_qspi_ns(void); -WEAK_DEFAULT void isr_sio_fifo(void); -WEAK_DEFAULT void isr_sio_bell(void); -WEAK_DEFAULT void isr_sio_fifo_ns(void); -WEAK_DEFAULT void isr_sio_bell_ns(void); -WEAK_DEFAULT void isr_sio_mtimecmp(void); -WEAK_DEFAULT void isr_clocks(void); -WEAK_DEFAULT void isr_spi0(void); -WEAK_DEFAULT void isr_spi1(void); -WEAK_DEFAULT void isr_uart0(void); -WEAK_DEFAULT void isr_uart1(void); -WEAK_DEFAULT void isr_adc_fifo(void); -WEAK_DEFAULT void isr_i2c0(void); -WEAK_DEFAULT void isr_i2c1(void); -WEAK_DEFAULT void isr_otp(void); -WEAK_DEFAULT void isr_trng(void); -WEAK_DEFAULT void isr_proc0_cti(void); -WEAK_DEFAULT void isr_proc1_cti(void); -WEAK_DEFAULT void isr_pll_sys(void); -WEAK_DEFAULT void isr_pll_usb(void); -WEAK_DEFAULT void isr_powman_pow(void); -WEAK_DEFAULT void isr_powman_timer(void); -WEAK_DEFAULT void isr_spareirq_0(void); -WEAK_DEFAULT void isr_spareirq_1(void); -WEAK_DEFAULT void isr_spareirq_2(void); -WEAK_DEFAULT void isr_spareirq_3(void); -WEAK_DEFAULT void isr_spareirq_4(void); -WEAK_DEFAULT void isr_spareirq_5(void); - -/* CPU specific interrupt vector table */ -ISR_VECTOR(1) -const isr_t vector_cpu[CPU_IRQ_NUMOF] = { - (void*)isr_timer0_0, /* 0 TIMER0_IRQ_0 */ - (void*)isr_timer0_1, /* 1 TIMER0_IRQ_1 */ - (void*)isr_timer0_2, /* 2 TIMER0_IRQ_2 */ - (void*)isr_timer0_3, /* 3 TIMER0_IRQ_3 */ - (void*)isr_timer1_0, /* 4 TIMER1_IRQ_0 */ - (void*)isr_timer1_1, /* 5 TIMER1_IRQ_1 */ - (void*)isr_timer1_2, /* 6 TIMER1_IRQ_2 */ - (void*)isr_timer1_3, /* 7 TIMER1_IRQ_3 */ - (void*)isr_pwm_wrap_0, /* 8 PWM_IRQ_WRAP_0 */ - (void*)isr_pwm_wrap_1, /* 9 PWM_IRQ_WRAP_1 */ - (void*)isr_dma_0, /* 10 DMA_IRQ_0 */ - (void*)isr_dma_1, /* 11 DMA_IRQ_1 */ - (void*)isr_dma_2, /* 12 DMA_IRQ_2 */ - (void*)isr_dma_3, /* 13 DMA_IRQ_3 */ - (void*)isr_usbctrl, /* 14 USBCTRL_IRQ */ - (void*)isr_pio0_0, /* 15 PIO0_IRQ_0 */ - (void*)isr_pio0_1, /* 16 PIO0_IRQ_1 */ - (void*)isr_pio1_0, /* 17 PIO1_IRQ_0 */ - (void*)isr_pio1_1, /* 18 PIO1_IRQ_1 */ - (void*)isr_pio2_0, /* 19 PIO2_IRQ_0 */ - (void*)isr_pio2_1, /* 20 PIO2_IRQ_1 */ - (void*)isr_io_bank0, /* 21 IO_IRQ_BANK0 */ - (void*)isr_io_bank0_ns, /* 22 IO_IRQ_BANK0_NS */ - (void*)isr_io_qspi, /* 23 IO_IRQ_QSPI */ - (void*)isr_io_qspi_ns, /* 24 IO_IRQ_QSPI_NS */ - (void*)isr_sio_fifo, /* 25 SIO_IRQ_FIFO */ - (void*)isr_sio_bell, /* 26 SIO_IRQ_BELL */ - (void*)isr_sio_fifo_ns, /* 27 SIO_IRQ_FIFO_NS */ - (void*)isr_sio_bell_ns, /* 28 SIO_IRQ_BELL_NS */ - (void*)isr_sio_mtimecmp, /* 29 SIO_IRQ_MTIMECMP */ - (void*)isr_clocks, /* 30 CLOCKS_IRQ */ - (void*)isr_spi0, /* 31 SPI0_IRQ */ - (void*)isr_spi1, /* 32 SPI1_IRQ */ - (void*)isr_uart0, /* 33 UART0_IRQ */ - (void*)isr_uart1, /* 34 UART1_IRQ */ - (void*)isr_adc_fifo, /* 35 ADC_IRQ_FIFO */ - (void*)isr_i2c0, /* 36 I2C0_IRQ */ - (void*)isr_i2c1, /* 37 I2C1_IRQ */ - (void*)isr_otp, /* 38 OTP_IRQ */ - (void*)isr_trng, /* 39 TRNG_IRQ */ - (void*)isr_proc0_cti, /* 40 PROC0_IRQ_CTI */ - (void*)isr_proc1_cti, /* 41 PROC1_IRQ_CTI */ - (void*)isr_pll_sys, /* 42 PLL_SYS_IRQ */ - (void*)isr_pll_usb, /* 43 PLL_USB_IRQ */ - (void*)isr_powman_pow, /* 44 POWMAN_IRQ_POW */ - (void*)isr_powman_timer, /* 45 POWMAN_IRQ_TIMER */ - (void*)isr_spareirq_0, /* 46 SPAREIRQ_IRQ_0 */ - (void*)isr_spareirq_1, /* 47 SPAREIRQ_IRQ_1 */ - (void*)isr_spareirq_2, /* 48 SPAREIRQ_IRQ_2 */ - (void*)isr_spareirq_3, /* 49 SPAREIRQ_IRQ_3 */ - (void*)isr_spareirq_4, /* 50 SPAREIRQ_IRQ_4 */ - (void*)isr_spareirq_5, /* 51 SPAREIRQ_IRQ_5 */ -}; - -/** @} */ diff --git a/cpu/rp2350/xosc.c b/cpu/rp2350/xosc.c deleted file mode 100644 index c398e28ec9ee..000000000000 --- a/cpu/rp2350/xosc.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief XOSC implementation for the RP2350 - * - * @author Tom Hert - */ - -#include - -#include "RP2350.h" -#include "board.h" -#include "macros/units.h" -#include "periph_cpu.h" - -/* Based on datasheet 8.2.4 (1ms wait time) */ -#define STARTUP_DELAY 47 -#define MAX_XOSC_COUNTER_SIZE 0xFFFF -#define SLEEP_100HZ_SPEED 12000000UL -#define CYCLES_PER_MS (SLEEP_100HZ_SPEED / 1000) - -void xosc_start(void) { - /* Set the FREQ_RANGE */ - XOSC->CTRL = XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ; - /* Set the startup delay (default 1ms) */ - XOSC->STARTUP = STARTUP_DELAY; - /* set enable bit */ - atomic_set(&XOSC->CTRL, - XOSC_CTRL_ENABLE_VALUE_ENABLE << XOSC_CTRL_ENABLE_LSB); - - while (!(XOSC->STATUS & XOSC_STATUS_STABLE_BITS)) { - /* Wait for the crystal to stabilize */ - } -} - -void xosc_sleep(uint32_t milliseconds) { - for (uint32_t i = milliseconds; i > 0; i--) { - XOSC->COUNT = CYCLES_PER_MS; - while (XOSC->COUNT != 0) {}; - } -} - -void xosc_stop(void) { - /* @TODO */ -} - -/** @} */ diff --git a/cpu/rp2350/Kconfig b/cpu/rp2350_arm/Kconfig similarity index 55% rename from cpu/rp2350/Kconfig rename to cpu/rp2350_arm/Kconfig index 867bcf84f90b..a53b79b69122 100644 --- a/cpu/rp2350/Kconfig +++ b/cpu/rp2350_arm/Kconfig @@ -2,22 +2,22 @@ # SPDX-FileCopyrightText: 2025 HAW Hamburg # SPDX-License-Identifier: LGPL-2.1-only -config CPU_FAM_RP2350 +config CPU_FAM_RP2350_ARM bool select CPU_CORE_CORTEX_M33 config CPU_FAM - default "RP2350" if CPU_FAM_RP2350 + default "RP2350_ARM" if CPU_FAM_RP2350_ARM -config CPU_MODEL_RP2350 +config CPU_MODEL_RP2350_ARM bool - select CPU_FAM_RP2350 + select CPU_FAM_RP2350_ARM config CPU_MODEL - default "RP2350" if CPU_MODEL_RP2350 + default "RP2350_ARM" if CPU_MODEL_RP2350_ARM config CPU - default "rp2350" if CPU_FAM_RP2350 + default "rp2350_arm" if CPU_FAM_RP2350_ARM source "$(RIOTCPU)/cortexm_common/Kconfig" diff --git a/cpu/rp2350_arm/Makefile b/cpu/rp2350_arm/Makefile new file mode 100644 index 000000000000..d097b987ce69 --- /dev/null +++ b/cpu/rp2350_arm/Makefile @@ -0,0 +1,8 @@ +# define the module that is built +MODULE = cpu + +# add a list of subdirectories, that should also be built +DIRS += $(RIOTCPU)/rp2350_common +DIRS += $(RIOTCPU)/cortexm_common + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/rp2350_arm/Makefile.dep b/cpu/rp2350_arm/Makefile.dep new file mode 100644 index 000000000000..0c4c8e18303e --- /dev/null +++ b/cpu/rp2350_arm/Makefile.dep @@ -0,0 +1,4 @@ +USEMODULE += cortexm_common + +include $(RIOTCPU)/rp2350_common/Makefile.dep +include $(RIOTCPU)/cortexm_common/Makefile.dep diff --git a/cpu/rp2350/Makefile.features b/cpu/rp2350_arm/Makefile.features similarity index 58% rename from cpu/rp2350/Makefile.features rename to cpu/rp2350_arm/Makefile.features index 5fc956bd1ba3..049467c49595 100644 --- a/cpu/rp2350/Makefile.features +++ b/cpu/rp2350_arm/Makefile.features @@ -1,9 +1,7 @@ CPU_CORE := cortex-m33 CPU_FAM := RP2350 CPU_ARCH = armv8m -CPU_MODEL = rp2350 +CPU_MODEL = rp2350_cortexm +include $(RIOTCPU)/rp2350_common/Makefile.features include $(RIOTCPU)/cortexm_common/Makefile.features - -FEATURES_PROVIDED += periph_gpio -FEATURES_PROVIDED += periph_uart diff --git a/cpu/rp2350_arm/cpu.c b/cpu/rp2350_arm/cpu.c new file mode 100644 index 000000000000..d89d5ab270c9 --- /dev/null +++ b/cpu/rp2350_arm/cpu.c @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2025 Tom Hert + * SPDX-FileCopyrightText: 2025 HAW Hamburg + * SPDX-License-Identifier: LGPL-2.1-only + */ + +/** + * @ingroup cpu_rp2350_arm + * @{ + * + * @file + * @brief CPU initialization implementation for the RP2350 + * + * @author Tom Hert + */ + +#include "cpu.h" +#include "periph_cpu.h" + +void cpu_init(void) +{ + cortexm_init(); + rp2350_init(); +} + +/** @} */ diff --git a/cpu/rp2350/doc.md b/cpu/rp2350_arm/doc.md similarity index 100% rename from cpu/rp2350/doc.md rename to cpu/rp2350_arm/doc.md diff --git a/cpu/rp2350/include/cpu_conf.h b/cpu/rp2350_arm/include/cpu_conf.h similarity index 80% rename from cpu/rp2350/include/cpu_conf.h rename to cpu/rp2350_arm/include/cpu_conf.h index 652be6fe27e5..b6d38c449e7c 100644 --- a/cpu/rp2350/include/cpu_conf.h +++ b/cpu/rp2350_arm/include/cpu_conf.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup cpu_rp2350 + * @ingroup cpu_rp2350_arm * @{ * @file * @brief CPU configuration for the RP2350 @@ -21,6 +21,8 @@ #define CPU_DEFAULT_IRQ_PRIO 1u #define CPU_IRQ_NUMOF 52u +/** This tells rp2350_common that we are using the ARM core */ +#define RP2350_USE_ARM 1 #ifdef __cplusplus extern "C" { diff --git a/cpu/rp2350/ldscripts/RP2350.ld b/cpu/rp2350_arm/ldscripts/RP2350_ARM.ld similarity index 100% rename from cpu/rp2350/ldscripts/RP2350.ld rename to cpu/rp2350_arm/ldscripts/RP2350_ARM.ld diff --git a/cpu/rp2350/picobin_block.s b/cpu/rp2350_arm/picobin_block.s similarity index 100% rename from cpu/rp2350/picobin_block.s rename to cpu/rp2350_arm/picobin_block.s diff --git a/cpu/rp2350_riscv/Makefile.dep b/cpu/rp2350_riscv/Makefile.dep index 9b356f1d4deb..d648a1452e80 100644 --- a/cpu/rp2350_riscv/Makefile.dep +++ b/cpu/rp2350_riscv/Makefile.dep @@ -1,5 +1,3 @@ -USEMODULE += periph - FEATURES_REQUIRED += periph_xh3irq - +include $(RIOTCPU)/rp2350_common/Makefile.dep include $(RIOTCPU)/riscv_common/Makefile.dep diff --git a/cpu/rp2350_riscv/Makefile.features b/cpu/rp2350_riscv/Makefile.features index 8914a41a2f94..964245e3d11a 100644 --- a/cpu/rp2350_riscv/Makefile.features +++ b/cpu/rp2350_riscv/Makefile.features @@ -1,7 +1,9 @@ CPU_CORE := rv32imac +CPU_FAM := RP2350 +CPU_MODEL = rp2350_hazard3 -FEATURES_PROVIDED += periph_gpio -FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_xh3irq +include $(RIOTCPU)/rp2350_common/Makefile.features + include $(RIOTCPU)/riscv_common/Makefile.features diff --git a/cpu/rp2350_riscv/Makefile.include b/cpu/rp2350_riscv/Makefile.include index a8d98087fe6e..f579f2204560 100644 --- a/cpu/rp2350_riscv/Makefile.include +++ b/cpu/rp2350_riscv/Makefile.include @@ -1,16 +1,3 @@ -CFLAGS += -Wno-pedantic - -ROM_LEN ?= 2097152 # = 2 MiB used in the RPi Pico -ROM_OFFSET := 0 # bootloader size -RAM_LEN := 0x82000 # 520kB = 532479 used in the RPi Pico 2350 -ROM_START_ADDR := 0x10000000 # XIP Non-Secure address for rp2350 -RAM_START_ADDR := 0x20000000 # Non-Secure RAM address for rp2350 - -INCLUDES += -I$(RIOTCPU)/rp2350_riscv/include -INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include -INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include -INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2350/hardware_regs/include/hardware - # CPU and architecture specific flags CFLAGS += -D$(CPU_MODEL) CFLAGS += -DROM_START_ADDR=$(ROM_START_ADDR) @@ -24,9 +11,7 @@ LINKFLAGS += -Wl,--gc-sections LINKFLAGS += -Wl,--start-group -lc -lm -Wl,--end-group LINKFLAGS += -march=rv32imac_zicsr_zifencei_zba_zbb_zbkb_zbs -# Supported programmers and debuggers -PROGRAMMERS_SUPPORTED := picotool openocd jlink -PROGRAMMER ?= picotool -OPENOCD_DEBUG_ADAPTER ?= dap - +include $(RIOTCPU)/rp2350_common/Makefile.include include $(RIOTCPU)/riscv_common/Makefile.include + +INCLUDES += -I$(RIOTCPU)/rp2350_riscv/include diff --git a/cpu/rp2350_riscv/clock.c b/cpu/rp2350_riscv/clock.c deleted file mode 100644 index af6047f88f02..000000000000 --- a/cpu/rp2350_riscv/clock.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief Clock configuration implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "periph_cpu.h" - -void clock_reset(void) { - /* Reset the clock system */ - reset_component(RESET_PLL_SYS, RESET_PLL_SYS); -} - -/** - * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it - * @warning Make sure to call clock_reset() before this function to reset the - * clock system - * @see RP2350 Docs Chapter 8, mostly 8.2 for more details - */ -void cpu_clock_init(void) { - /* Enable the XOSC */ - xosc_start(); - - /* Setup the PLL using the XOSC as the reference clock. */ - PLL_SYS->FBDIV_INT = - PLL_FEEDBACK_DIVIDER_VALUE; /* Set the feedback divider */ - - /* Set the post-dividers for the PLL output.*/ - PLL_SYS->PRIM = PDIV; - /* Turn on PLL */ - atomic_clear(&PLL_SYS->PWR, - PLL_PWR_PD_BITS | PLL_PWR_VCOPD_BITS | PLL_PWR_POSTDIVPD_BITS); - - /* sleep 10ms to allow the PLL to stabilize */ - xosc_sleep(10); - - /* Based on the description in chapter 8 this is something that should be done - * However, it appears to cause issues and is not done by other examples on the - * internet. This needs to be investigated further. */ - - /* Wait for lock */ - /* while (!(PLL_SYS->CS & PLL_CS_LOCK_BITS)) { */ - /* Wait for the PLL to lock */ - /* } */ - - /* AUXSRC = 0x0 7:5 && SRC == 0x0 0 */ - CLOCKS->CLK_SYS_CTRL = CLK_SYS_PERI_CTRL_ENABLE_BIT; - - /* This register contains one decoded bit for each of the clock sources - * enumerated in the CTRL SRC field. The bit does not directly correlate with - * the value of the SRC field For example 0x0 is the first bit while 0x1 is - * the second bit. In some way this makes sense, in some way I lost too much - * time on this. */ - while (CLOCKS->CLK_SYS_SELECTED != CLK_SYS_SELECTED_PERI_FIELD_VALUE) { - } - - /* AUXSRC = 0x0 -> CLK_SYS Indirectly through lower line */ - CLOCKS->CLK_PERI_CTRL = CLK_PERI_CTRL_ENABLE_BIT; -} - -/** @} */ diff --git a/cpu/rp2350_riscv/cpu.c b/cpu/rp2350_riscv/cpu.c index 5419f3463277..932425aa9396 100644 --- a/cpu/rp2350_riscv/cpu.c +++ b/cpu/rp2350_riscv/cpu.c @@ -25,35 +25,13 @@ #include -void gpio_reset(void) -{ - reset_component(RESET_PADS_BANK0, RESET_PADS_BANK0); - reset_component(RESET_IO_BANK0, RESET_IO_BANK0); -} - /** * @brief Initialize the CPU, set IRQ priorities, clocks, peripheral */ void cpu_init(void) { - /* Reset GPIO state */ - gpio_reset(); - - /* Reset clock to default state */ - clock_reset(); - - /* initialize the CPU clock */ - cpu_clock_init(); - - /* initialize the RISC-V core */ + /* rp2350 common startup routine */ + rp2350_init(); + /* initialize the RISC-V core (Interrupts, FPU, etc) */ riscv_init(); - - /* initialize the early peripherals */ - early_init(); - - /* trigger static peripheral initialization */ - periph_init(); - - /* initialize the board */ - board_init(); } diff --git a/cpu/rp2350_riscv/include/clock_conf.h b/cpu/rp2350_riscv/include/clock_conf.h deleted file mode 100644 index e2609ff0c704..000000000000 --- a/cpu/rp2350_riscv/include/clock_conf.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief Clock configuration for the RP2350 - * - * @author Tom Hert - */ - -#include "RP2350.h" -#include "macros/units.h" - -/** 1-15 MHz range - * @see hardware/regs/xosc.h and chapter 8.2.8 - */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ 0xaa0u -/** 10-30 MHz range */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_10_30MHZ 0xaa1u -/** 25-60 MHz range */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_25_60MHZ 0xaa2u -/** 40-100 MHz range */ -#define XOSC_CTRL_FREQ_RANGE_VALUE_40_100MHZ 0xaa3u -/** Disable the XOSC */ -#define XOSC_CTRL_ENABLE_VALUE_DISABLE 0xd1eu -/** Enable the XOSC */ -#define XOSC_CTRL_ENABLE_VALUE_ENABLE 0xfabu -/** LSB of the enable bit */ -#define XOSC_CTRL_ENABLE_LSB 12u -/** Stable bit in the XOSC status register */ -#define XOSC_STATUS_STABLE_BITS 0x80000000u -/** Default crystal frequency is 12 MHz */ -#define XOSC_HZ MHZ(12u) -/** Reference divider for the PLL, set to 2 as per hardware manual */ -#define PLL_REF_DIV 2u -/** VCO frequency for the PLL, set to 750 MHz as per hardware manual */ -#define PLL_VCO_FREQ 750000000u -/** Post divider 1 for the PLL, set to 6 as per hardware manual */ -#define PLL_PD1 6u -/** Post divider 2 for the PLL, set to 2 as per hardware manual */ -#define PLL_PD2 2u -/** Power down bits for the PLL */ -#define PLL_PWR_PD_BITS 0x00000001u -/** VCO power down bits for the PLL */ -#define PLL_PWR_VCOPD_BITS 0x00000020u -/** Lock bit in the PLL control status register */ -#define PLL_CS_LOCK_BITS 0x80000000u -/** LSB of the post divider 1 in the PLL primary register */ -#define PLL_PRIM_POSTDIV1_LSB 16u -/** LSB of the post divider 2 in the PLL primary register */ -#define PLL_PRIM_POSTDIV2_LSB 12u -/** Post divider power down bits for the PLL */ -#define PLL_PWR_POSTDIVPD_BITS 0x00000008u -/** Enable bit for the peripheral clock control register */ -#define CLK_PERI_CTRL_ENABLE_BIT (1u << 11u) -/** Default CPU frequency in Hz, set to 125 MHz as per hardware manual */ -#define CPUFREQ 125000000u -/** Maximum crystal frequency */ -#define CLOCK_XOSC_MAX MHZ(15u) -/** Minimum crystal frequency */ -#define CLOCK_XOSC_MIN MHZ(5u) -/** Crystal frequency */ -#define CLOCK_XOSC (XOSC_HZ) -/** Minimum value of the post PLL clock divers */ -#define PLL_POSTDIV_MIN 1u -/** Maximum value of the post PLL clock divers */ -#define PLL_POSTDIV_MAX 7u -/** Minimum value of the PLL VCO feedback scaler */ -#define PLL_VCO_FEEDBACK_SCALE_MIN 16u -/** Maximum value of the PLL VCO feedback scaler */ -#define PLL_VCO_FEEDBACK_SCALE_MAX 320u -/** Minimum value of the clock divider applied before - * feeding in the reference clock into the PLL */ -#define PLL_REF_DIV_MIN 1u -/** Minimum value of the clock divider applied before feeding in - * the reference clock into the PLL */ -#define PLL_REF_DIV_MAX 1u -/** PLL feedback divider value, set to 125 as per hardware manual */ -#define PLL_FEEDBACK_DIVIDER_VALUE 125u -/** Enable bit for the system clock control register to select the peripheral - * clock */ -#define CLK_SYS_PERI_CTRL_ENABLE_BIT (1u << 0u) -/** Selected field value for the system clock control register - * to select the peripheral clock */ -#define CLK_SYS_SELECTED_PERI_FIELD_VALUE 2u -/** RIOT core clock frequency defined as the CPU frequency */ -#define CLOCK_CORECLOCK MHZ(12u) - -#if (PLL_VCO_FEEDBACK_SCALE_MIN < PLL_VCO_FEEDBACK_SCALE_MIN) || \ -(PLL_VCO_FEEDBACK_SCALE_MAX > PLL_VCO_FEEDBACK_SCALE_MAX) -# error "Value for PLL_VCO_FEEDBACK_SCALE out of range, check config" -#endif -#if (PLL_REF_DIV_MIN < PLL_REF_DIV_MIN) || (PLL_REF_DIV_MAX > PLL_REF_DIV_MAX) -# error "Value for PLLxosc_sleep_REF_DIV out of range, check config" -#endif -#if (PLL_POSTDIV_MIN < PLL_POSTDIV_MIN) || (PLL_POSTDIV_MAX > PLL_POSTDIV_MAX) -# error "Value for PLL_POSTDIV out of range, check config" -#endif -#if ((CLOCK_XOSC > CLOCK_XOSC_MAX) || (CLOCK_XOSC < CLOCK_XOSC_MIN)) -# error "Value for CLOCK_XOSC out of range, check config" -#endif - -/** Post divider for the PLL, calculated based on the post divider values */ -#define PDIV ((PLL_PD1 << PLL_PRIM_POSTDIV1_LSB) | (PLL_PD2 << PLL_PRIM_POSTDIV2_LSB)) -/** Feedback divider for the PLL, calculated based on the VCO frequency and -* reference clock frequency */ -#define FBDIV ((PLL_VCO_FREQ / XOSC_HZ) / PLL_REF_DIV) - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configures the Crystal to run. - * @note The reference hardware manual suggests to use a 12 MHz crystal, which we - * use by default. - */ -void xosc_start(void); - -/** - * @brief Stop the crystal. - */ -void xosc_stop(void); - -/** - * @brief Sleep for a given time in milliseconds. - * @param milliseconds The time to sleep in milliseconds. - */ -void xosc_sleep(uint32_t milliseconds); - -/** - * @brief Reset the clock system. - * - * This function resets the clock system to a known state. - * It is recommended to call this function before configuring the clock system. - */ -void clock_reset(void); - -/** - * @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it - * @pre Make sure to call clock_reset() before this function to reset the - * clock system - * @see RP2350 Docs Chapter 8, mostly 8.2 for more details - */ -void cpu_clock_init(void); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h index 28f799c0976e..0bc775f5f816 100644 --- a/cpu/rp2350_riscv/include/cpu_conf.h +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -23,6 +23,8 @@ extern "C" { #define CPU_DEFAULT_IRQ_PRIO 1u #define CPU_IRQ_NUMOF 52u +/* This tells rp2350_common that we are using the RISC-V core */ +#define RP2350_USE_RISCV 1 #ifdef __cplusplus } diff --git a/cpu/rp2350_riscv/include/gpio_conf.h b/cpu/rp2350_riscv/include/gpio_conf.h deleted file mode 100644 index 4408392c00ad..000000000000 --- a/cpu/rp2350_riscv/include/gpio_conf.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert git@annsann.eu> - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief GPIO configuration for the RP2350 - * - * @author Tom Hert - */ - -/** The number of GPIO pins available on the RP2350 */ -#define GPIO_PIN_NUMOF 30u - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Possible function values for @ref gpio_io_ctrl_t::function_select - */ -typedef enum { - /** connect pin to the SPI peripheral (MISO/MOSI/SCK depends on pin) */ - FUNCTION_SELECT_SPI = 1, - - /** connect pin to the UART peripheral (TXD/RXD depends on pin) */ - FUNCTION_SELECT_UART = 2, - - /** connect pin to the I2C peripheral (SCL/SDA depends on pin) */ - FUNCTION_SELECT_I2C = 3, - - /** connect pin to the timer for PWM (channel depends on pin) */ - FUNCTION_SELECT_PWM = 4, - - /** use pin as vanilla GPIO */ - FUNCTION_SELECT_SIO = 5, - - /** connect pin to the first PIO peripheral */ - FUNCTION_SELECT_PIO0 = 6, - - /** connect pin to the second PIO peripheral */ - FUNCTION_SELECT_PIO1 = 7, - - /** connect pin to the timer (depending on pin: external clock, - * clock output, or not supported) */ - FUNCTION_SELECT_CLOCK = 8, - - /** connect pin to the USB peripheral (function depends on pin) */ - FUNCTION_SELECT_USB = 9, - - /** Reset value, pin unconnected */ - FUNCTION_SELECT_NONE = 31, -} gpio_function_select_t; - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350_riscv/include/helpers.h b/cpu/rp2350_riscv/include/helpers.h deleted file mode 100644 index f88b7d0950a3..000000000000 --- a/cpu/rp2350_riscv/include/helpers.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief Helper functions for atomic register operations - * - * @author Tom Hert - */ - -/** Bit to be set for an atomic XOR operation */ -#define ATOMIC_XOR_WRITE 0x1000u -/** Bit to be set for an atomic set operation */ -#define ATOMIC_BITMASK_SET_WRITE 0x2000u -/** Bits to be set for an atomic clear operation */ -#define ATOMIC_BITMASK_CLEAR_WRITE 0x3000u - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Perform an atomic XOR write to a register - * - * @param[in,out] reg Pointer to the target register - * @param[in] val Value to be XORed with the register - */ -static inline void atomic_xor(volatile uint32_t *reg, uint32_t val) { - *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_XOR_WRITE) = val; -} - -/** - * @brief Set bits in a register atomically - * - * @param[in,out] reg Pointer to the target register - * @param[in] val Bit mask of bits to set - */ -static inline void atomic_set(volatile uint32_t *reg, uint32_t val) { - *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_SET_WRITE) = val; -} - -/** - * @brief Clear bits in a register atomically - * - * @param[in,out] reg Pointer to the target register - * @param[in] val Bit mask of bits to clear - */ -static inline void atomic_clear(volatile uint32_t *reg, uint32_t val) { - *(volatile uint32_t *)((uintptr_t)reg | ATOMIC_BITMASK_CLEAR_WRITE) = val; -} - -/** - * @brief Reset a component by clearing its reset bits and waiting for the reset to complete - * - * @param reset_value Bit mask of the reset bits to clear - * @param reset_done_value Bit mask of the reset done bits to wait for - */ -static inline void reset_component(uint32_t reset_value, - uint32_t reset_done_value) { - atomic_clear(&RESETS->RESET, reset_value); - while (~RESETS->RESET_DONE & reset_done_value) { - /* Wait for the reset to complete */ - } -} - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350_riscv/include/periph_cpu.h b/cpu/rp2350_riscv/include/periph_cpu.h deleted file mode 100644 index 4a0f3a3bf2df..000000000000 --- a/cpu/rp2350_riscv/include/periph_cpu.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief Peripheral CPU definitions for the RP2350 - * - * @author Tom Hert - */ - -#include - -/** Overwrite the default GPIO type to use uint32_t */ -#define HAVE_GPIO_T -typedef uint32_t gpio_t; - -/** - * @brief Macro to create a GPIO pin identifier - * @param port The GPIO port (Currently only GPIO0) - * @param pin The GPIO pin number - */ -#define GPIO_PIN(port, pin) (((port) & 0) | (pin)) - -/** This is a define used throughout the pico sdk */ -#define _u(x) ((uint32_t)(x)) - -#include "periph_cpu_common.h" -#include "cpu.h" -#include "core_cm33.h" /* Trick RP2350 into believing the file exists on RISCV */ -#include "RP2350.h" -#include "helpers.h" -#include "gpio_conf.h" -#include "clock_conf.h" -#include "uart_conf.h" -#include "xh3irq.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** GPIO Pin ID for oscillator debugging */ -#define OSC_DEBUG_PIN_ID 15u - -/** Reset bit for the system PLL */ -#define RESET_PLL_SYS (1u << 14u) - -/** Reset bit for the pads bank 0 */ -#define RESET_PADS_BANK0 (1u << 9u) - -/** Reset bit for UART0 peripheral */ -#define RESET_UART0 (1u << 26u) - -/** Reset bit for UART1 peripheral */ -#define RESET_UART1 (1u << 27u) - -/** Reset bit for the IO bank 0 */ -#define RESET_IO_BANK0 (1u << 6u) - -/** Input enable bit for GPIO0 in PADS_BANK0 */ -#define PADS_BANK0_GPIO0_IE_BITS (1u << 6u) - -/** Isolation bits for PADS_BANK0 */ -#define PADS_BANK0_ISO_BITS (1u << 8u) - - -/** - * @brief Calculate the address of the GPIO pad register for a given pin - * @param pin The GPIO pin number - * @return The address of the GPIO pad register for the given pin - */ -static inline uint32_t calculate_gpio_pad_register_addr(gpio_t pin) { - /* Each pin has a 4 byte register, so we can calculate the address - * by adding 4 bytes for each pin, starting at the base address of PADS_BANK0 - * and adding 4 bytes to skip VOLTAGE_SELECT */ - return PADS_BANK0_BASE + 4 * (pin + 1); -} - -/** - * @brief Calculate the address of the GPIO IO status register for a given pin - * @param pin The GPIO pin number - * @return The address of the GPIO IO status register for the given pin - */ -static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { - /* Each status register is followed by a ctrl register */ - return IO_BANK0_BASE + 8 * pin; -} - -/** - * @brief Calculate the address of the GPIO IO control register for a given - * pin - * @param pin The GPIO pin number - * @return The address of the GPIO IO control register for the given pin - */ -static inline uint32_t calculate_gpio_io_ctrl_register_addr(gpio_t pin) { - /* Each pin has a 8 byte register (4 Bytes of Status, 4 Bytes of CTRL), - * so we can calculate the address by adding 8 bytes for each pin, - * starting at the base address of IO_BANK0 */ - return calculate_gpio_io_status_register_addr(pin) + 4; -} - - - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350_riscv/include/uart_conf.h b/cpu/rp2350_riscv/include/uart_conf.h deleted file mode 100644 index f886e974bc3c..000000000000 --- a/cpu/rp2350_riscv/include/uart_conf.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief UART configuration for the RP2350 - * - * @author Tom Hert - */ - -#include "RP2350.h" -#include "macros/units.h" -#include "periph_cpu.h" - -/** UART baud rate in bits per second */ -#define BAUDRATE 115200u - -/** Integer baud rate divisor */ -#define IBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) / 64u) - -/** Fractional baud rate divisor */ -#define FBRD ((((8u * CPUFREQ) + BAUDRATE) / (2u * BAUDRATE)) % 64u) - -/** UART enable bit in control register */ -#define UART_UARTCR_UARTEN_BITS (1u << 0u) - -/** UART receive enable bit in control register */ -#define UART_UARTCR_RXE_BITS (1u << 9u) - -/** UART transmit enable bit in control register */ -#define UART_UARTCR_TXE_BITS (1u << 8u) - -/** UART receive FIFO full flag bit in flag register */ -#define UART_UARTFR_RXFF_BITS (1u << 6u) - -/** UART transmit FIFO empty flag bit in flag register */ -#define UART_UARTFR_TXFE_BITS (1u << 7u) - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/cpu/rp2350_riscv/periph/Makefile b/cpu/rp2350_riscv/periph/Makefile deleted file mode 100644 index a36df249ac1d..000000000000 --- a/cpu/rp2350_riscv/periph/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(RIOTMAKE)/periph.mk diff --git a/cpu/rp2350_riscv/periph/gpio.c b/cpu/rp2350_riscv/periph/gpio.c deleted file mode 100644 index 4ba74bbfa513..000000000000 --- a/cpu/rp2350_riscv/periph/gpio.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350_riscv - * @{ - * - * @file - * @brief GPIO implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "periph/gpio.h" - -#include - -#include "board.h" -#include "irq.h" -#include "periph_conf.h" -#include "periph_cpu.h" - -#define ENABLE_DEBUG 0 -#include "debug.h" - -int gpio_init(gpio_t pin, gpio_mode_t mode) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - - /* Clear the pin's output enable and output state */ - SIO->GPIO_OE_CLR = 1LU << pin; - SIO->GPIO_OUT_CLR = 1LU << pin; - - switch (mode) { - case GPIO_OUT: - *(uint32_t*)calculate_gpio_io_ctrl_register_addr(pin) = - FUNCTION_SELECT_SIO; - - volatile uint32_t* pad_reg = - (uint32_t*)calculate_gpio_pad_register_addr(pin); - - /* We clear all bits except the drive strength bit. - * We set that to the highest one possible (12mA) - * to mimic the behavior of the pico1 GPIO driver - * (Not too sure why we do this, but it seems to be the standard) */ - *pad_reg = 0x3 << 4; - - SIO->GPIO_OE_SET = 1 << pin; /* Set the pin as output */ - - break; - default: - /* Unsupported mode */ - return -ENOTSUP; - } - return 0; -} - -bool gpio_read(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - /* Read the pin state */ - return (SIO->GPIO_IN & (1 << pin)) != 0; /* Return true if the pin is HIGH */ -} - -void gpio_set(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - SIO->GPIO_OUT_SET = 1 << pin; /* Set the pin to HIGH */ -} - -void gpio_clear(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - SIO->GPIO_OUT_CLR = 1 << pin; /* Set the pin to LOW */ -} - -void gpio_toggle(gpio_t pin) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - SIO->GPIO_OUT_XOR = 1 << pin; /* Toggle the pin state (XOR) */ -} - -void gpio_write(gpio_t pin, bool value) { - /* Check if we exceed the maximum number of GPIO pins */ - assert(pin < GPIO_PIN_NUMOF); - if (value) { - gpio_set(pin); /* Set the pin to HIGH */ - } else { - gpio_clear(pin); /* Set the pin to LOW */ - } -} - -/** @} */ diff --git a/cpu/rp2350_riscv/periph/uart.c b/cpu/rp2350_riscv/periph/uart.c deleted file mode 100644 index ca79a626e59c..000000000000 --- a/cpu/rp2350_riscv/periph/uart.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief UART implementation for the RP2350 - * - * @author Tom Hert - */ - -#include "periph/uart.h" - -#include "periph_cpu.h" - -#include "regs/uart.h" -#include - -#define ENABLE_DEBUG 0 -#include "debug.h" - -#include "xh3irq.h" - -#include "board.h" - -static uart_isr_ctx_t ctx[UART_NUMOF]; - -/* back up values of registers used during uart_poweroff() / uart_poweron() */ -static uint32_t uartibrd; -static uint32_t uartfbrd; -static uint32_t uartlcr_h; -static uint32_t uartcr; - -/** Pico1 uart uses non-sdk conform defines - * @todo Change Pico1 defines if I ever get around to it - */ -#define UART0_UARTIMSC_RXIM_Msk (UART_UARTIMSC_RXIM_BITS) - -void _irq_enable(uart_t uart) { - UART0_Type *dev = uart_config[uart].dev; - /* We set the UART Receive Interrupt Mask (Bit 4) [See p979 UART 12.1]*/ - dev->UARTIMSC = UART0_UARTIMSC_RXIM_Msk; - /* Enable the IRQ in the NVIC */ - xh3irq_enable_irq(uart_config[uart].irqn); -} - -int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t parity, - uart_stop_bits_t stop_bits) { - assert((unsigned)uart < UART_NUMOF); - UART0_Type *dev = uart_config[uart].dev; - - (void)data_bits; - (void)stop_bits; - - /* Disable the UART before changing the mode */ - atomic_clear(&dev->UARTCR, UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS | - UART_UARTCR_TXE_BITS); - - /* Set the data bits, parity, and stop bits - * Set to 8 bits (0b11) based on Table 1035 page 976 - * @todo allow different data bits - */ - dev->UARTLCR_H = 0b11 << 5; - - switch (parity) { - case UART_PARITY_NONE: - break; - // case UART_PARITY_EVEN: - // io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk); - // break; - // case UART_PARITY_ODD: - // io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk); - // break; - default: - return UART_NOMODE; - } - - dev->UARTCR = UART_UARTCR_TXE_BITS | UART_UARTCR_UARTEN_BITS | UART_UARTCR_RXE_BITS; - - return UART_OK; -} - -static void _reset_uart(uart_t uart) { - switch (uart) { - case 0: - /* We reset UART0 here, so we can be sure it is in a known state */ - reset_component(RESET_UART0, RESET_UART0); - break; - case 1: - /* We reset UART1 here, so we can be sure it is in a known state */ - reset_component(RESET_UART1, RESET_UART1); - break; - default: - break; - } -} - -void uart_init_pins(uart_t uart) { - assert((unsigned)uart < UART_NUMOF); - UART0_Type *dev = uart_config[uart].dev; - - /* Set the UART pins to the correct function */ - *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART; - *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART; - /* Clear the ISO bits */ - atomic_clear((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].tx_pin), PADS_BANK0_ISO_BITS); - atomic_clear((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_ISO_BITS); - - /* Set Input Enable Flag */ - atomic_set((uint32_t *)calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_GPIO0_IE_BITS); - - /* We reset UART0 here, so we can be sure it is in a known state */ - _reset_uart(uart); - - dev->UARTIBRD = IBRD; - dev->UARTFBRD = FBRD; -} - -int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) { - (void)baud; - - if (uart >= UART_NUMOF) { - return UART_NODEV; - } - - UART0_Type *dev = uart_config[uart].dev; - ctx[uart].rx_cb = rx_cb; - ctx[uart].arg = arg; - - uart_init_pins(uart); - - if (uart_mode(uart, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1) != UART_OK) { - return UART_NOMODE; - } - - /* enable RX and IRQs, if needed */ - if (rx_cb != NULL) { - _irq_enable(uart); - /* clear any pending data and IRQ to avoid receiving a garbage char */ - uint32_t status = dev->UARTRIS; - dev->UARTICR = status; - (void)dev->UARTDR; - atomic_set(&dev->UARTCR, UART_UARTCR_RXE_BITS); - } - - return UART_OK; -} - -void uart_write(uart_t uart, const uint8_t *data, size_t len) { - UART0_Type *dev = uart_config[uart].dev; - for (size_t i = 0; i < len; i++) { - dev->UARTDR = data[i]; - /* Wait until the TX FIFO is empty before sending the next byte */ - while (!(dev->UARTFR & UART_UARTFR_TXFE_BITS)) { - } - } -} - -void uart_poweron(uart_t uart) { - assert((unsigned)uart < UART_NUMOF); - /* Get into a save state where we know whats up */ - _reset_uart(uart); - UART0_Type *dev = uart_config[uart].dev; - /* Restore config from registers */ - dev->UARTIBRD = uartibrd; - dev->UARTFBRD = uartfbrd; - dev->UARTLCR_H = uartlcr_h; - dev->UARTCR = uartcr; - /* restore IRQs, if needed */ - if (ctx[uart].rx_cb != NULL) { - _irq_enable(uart); - } - uart_init_pins(uart); -} - -void uart_deinit_pins(uart_t uart) { - assert((unsigned)uart < UART_NUMOF); - /* @TODO */ - /* gpio_reset_all_config(uart_config[uart].tx_pin); */ - SIO->GPIO_OE_CLR = 1LU << uart_config[uart].tx_pin; - if (ctx[uart].rx_cb) { - /* gpio_reset_all_config(uart_config[uart].rx_pin); */ - } -} - -void uart_poweroff(uart_t uart) { - assert((unsigned)uart < UART_NUMOF); - UART0_Type *dev = uart_config[uart].dev; - /* backup configuration registers */ - uartibrd = dev->UARTIBRD; - uartfbrd = dev->UARTFBRD; - uartlcr_h = dev->UARTLCR_H; - uartcr = dev->UARTCR; - /* disconnect GPIOs and power off peripheral */ - uart_deinit_pins(uart); - _reset_uart(uart); -} - -void isr_handler(uint8_t num) { - UART0_Type *dev = uart_config[num].dev; - - uint32_t status = dev->UARTMIS; - dev->UARTICR = status; - - if (status & UART_UARTMIS_RXMIS_BITS) { - uint32_t data = dev->UARTDR; - // if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) { - // DEBUG_PUTS("[rpx0xx] uart RX error (parity, break, or framing error"); - // } - // else { - printf("UART%d received: %c\n", num, (char)(data & 0xFF)); - ctx[num].rx_cb(ctx[num].arg, (uint8_t)data); - // } - } -} - -/** Overwrites the WEAK_DEFAULT isr_uart0 */ -void isr_uart0(void) { - isr_handler(0); -} - -void isr_uart1(void) { - isr_handler(1); -} - -/** @} */ diff --git a/cpu/rp2350_riscv/vectors.c b/cpu/rp2350_riscv/vectors.c deleted file mode 100644 index 0f3df6495478..000000000000 --- a/cpu/rp2350_riscv/vectors.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief Interrupt vector table for the RP2350 - * - * @author Tom Hert - */ - -#include "cpu_conf.h" -#include "xh3irq.h" -#include "panic.h" -#include - -#define WEAK_DEFAULT __attribute__((weak, alias("dummy_handler"))) - -/* define a local dummy handler as it needs to be in the same compilation unit - * as the alias definition */ -void dummy_handler(void) -{ - core_panic(PANIC_GENERAL_ERROR, "DUMMY HANDLER"); -} - -/* rp2350 specific interrupt vector */ -WEAK_DEFAULT void isr_timer0_0(void); -WEAK_DEFAULT void isr_timer0_1(void); -WEAK_DEFAULT void isr_timer0_2(void); -WEAK_DEFAULT void isr_timer0_3(void); -WEAK_DEFAULT void isr_timer1_0(void); -WEAK_DEFAULT void isr_timer1_1(void); -WEAK_DEFAULT void isr_timer1_2(void); -WEAK_DEFAULT void isr_timer1_3(void); -WEAK_DEFAULT void isr_pwm_wrap_0(void); -WEAK_DEFAULT void isr_pwm_wrap_1(void); -WEAK_DEFAULT void isr_dma_0(void); -WEAK_DEFAULT void isr_dma_1(void); -WEAK_DEFAULT void isr_dma_2(void); -WEAK_DEFAULT void isr_dma_3(void); -WEAK_DEFAULT void isr_usbctrl(void); -WEAK_DEFAULT void isr_pio0_0(void); -WEAK_DEFAULT void isr_pio0_1(void); -WEAK_DEFAULT void isr_pio1_0(void); -WEAK_DEFAULT void isr_pio1_1(void); -WEAK_DEFAULT void isr_pio2_0(void); -WEAK_DEFAULT void isr_pio2_1(void); -WEAK_DEFAULT void isr_io_bank0(void); -WEAK_DEFAULT void isr_io_bank0_ns(void); -WEAK_DEFAULT void isr_io_qspi(void); -WEAK_DEFAULT void isr_io_qspi_ns(void); -WEAK_DEFAULT void isr_sio_fifo(void); -WEAK_DEFAULT void isr_sio_bell(void); -WEAK_DEFAULT void isr_sio_fifo_ns(void); -WEAK_DEFAULT void isr_sio_bell_ns(void); -WEAK_DEFAULT void isr_sio_mtimecmp(void); -WEAK_DEFAULT void isr_clocks(void); -WEAK_DEFAULT void isr_spi0(void); -WEAK_DEFAULT void isr_spi1(void); -WEAK_DEFAULT void isr_uart0(void); -WEAK_DEFAULT void isr_uart1(void); -WEAK_DEFAULT void isr_adc_fifo(void); -WEAK_DEFAULT void isr_i2c0(void); -WEAK_DEFAULT void isr_i2c1(void); -WEAK_DEFAULT void isr_otp(void); -WEAK_DEFAULT void isr_trng(void); -WEAK_DEFAULT void isr_proc0_cti(void); -WEAK_DEFAULT void isr_proc1_cti(void); -WEAK_DEFAULT void isr_pll_sys(void); -WEAK_DEFAULT void isr_pll_usb(void); -WEAK_DEFAULT void isr_powman_pow(void); -WEAK_DEFAULT void isr_powman_timer(void); -WEAK_DEFAULT void isr_spareirq_0(void); -WEAK_DEFAULT void isr_spareirq_1(void); -WEAK_DEFAULT void isr_spareirq_2(void); -WEAK_DEFAULT void isr_spareirq_3(void); -WEAK_DEFAULT void isr_spareirq_4(void); -WEAK_DEFAULT void isr_spareirq_5(void); - -/** CPU specific interrupt vector table - * @see 3.2 Interrupts and IRQn_Type in RP2350.h - */ -const void* vector_cpu[CPU_IRQ_NUMOF] = { - (void*)isr_timer0_0, /* 0 TIMER0_IRQ_0 */ - (void*)isr_timer0_1, /* 1 TIMER0_IRQ_1 */ - (void*)isr_timer0_2, /* 2 TIMER0_IRQ_2 */ - (void*)isr_timer0_3, /* 3 TIMER0_IRQ_3 */ - (void*)isr_timer1_0, /* 4 TIMER1_IRQ_0 */ - (void*)isr_timer1_1, /* 5 TIMER1_IRQ_1 */ - (void*)isr_timer1_2, /* 6 TIMER1_IRQ_2 */ - (void*)isr_timer1_3, /* 7 TIMER1_IRQ_3 */ - (void*)isr_pwm_wrap_0, /* 8 PWM_IRQ_WRAP_0 */ - (void*)isr_pwm_wrap_1, /* 9 PWM_IRQ_WRAP_1 */ - (void*)isr_dma_0, /* 10 DMA_IRQ_0 */ - (void*)isr_dma_1, /* 11 DMA_IRQ_1 */ - (void*)isr_dma_2, /* 12 DMA_IRQ_2 */ - (void*)isr_dma_3, /* 13 DMA_IRQ_3 */ - (void*)isr_usbctrl, /* 14 USBCTRL_IRQ */ - (void*)isr_pio0_0, /* 15 PIO0_IRQ_0 */ - (void*)isr_pio0_1, /* 16 PIO0_IRQ_1 */ - (void*)isr_pio1_0, /* 17 PIO1_IRQ_0 */ - (void*)isr_pio1_1, /* 18 PIO1_IRQ_1 */ - (void*)isr_pio2_0, /* 19 PIO2_IRQ_0 */ - (void*)isr_pio2_1, /* 20 PIO2_IRQ_1 */ - (void*)isr_io_bank0, /* 21 IO_IRQ_BANK0 */ - (void*)isr_io_bank0_ns, /* 22 IO_IRQ_BANK0_NS */ - (void*)isr_io_qspi, /* 23 IO_IRQ_QSPI */ - (void*)isr_io_qspi_ns, /* 24 IO_IRQ_QSPI_NS */ - (void*)isr_sio_fifo, /* 25 SIO_IRQ_FIFO */ - (void*)isr_sio_bell, /* 26 SIO_IRQ_BELL */ - (void*)isr_sio_fifo_ns, /* 27 SIO_IRQ_FIFO_NS */ - (void*)isr_sio_bell_ns, /* 28 SIO_IRQ_BELL_NS */ - (void*)isr_sio_mtimecmp, /* 29 SIO_IRQ_MTIMECMP */ - (void*)isr_clocks, /* 30 CLOCKS_IRQ */ - (void*)isr_spi0, /* 31 SPI0_IRQ */ - (void*)isr_spi1, /* 32 SPI1_IRQ */ - (void*)isr_uart0, /* 33 UART0_IRQ */ - (void*)isr_uart1, /* 34 UART1_IRQ */ - (void*)isr_adc_fifo, /* 35 ADC_IRQ_FIFO */ - (void*)isr_i2c0, /* 36 I2C0_IRQ */ - (void*)isr_i2c1, /* 37 I2C1_IRQ */ - (void*)isr_otp, /* 38 OTP_IRQ */ - (void*)isr_trng, /* 39 TRNG_IRQ */ - (void*)isr_proc0_cti, /* 40 PROC0_IRQ_CTI */ - (void*)isr_proc1_cti, /* 41 PROC1_IRQ_CTI */ - (void*)isr_pll_sys, /* 42 PLL_SYS_IRQ */ - (void*)isr_pll_usb, /* 43 PLL_USB_IRQ */ - (void*)isr_powman_pow, /* 44 POWMAN_IRQ_POW */ - (void*)isr_powman_timer, /* 45 POWMAN_IRQ_TIMER */ - (void*)isr_spareirq_0, /* 46 SPAREIRQ_IRQ_0 */ - (void*)isr_spareirq_1, /* 47 SPAREIRQ_IRQ_1 */ - (void*)isr_spareirq_2, /* 48 SPAREIRQ_IRQ_2 */ - (void*)isr_spareirq_3, /* 49 SPAREIRQ_IRQ_3 */ - (void*)isr_spareirq_4, /* 50 SPAREIRQ_IRQ_4 */ - (void*)isr_spareirq_5, /* 51 SPAREIRQ_IRQ_5 */ -}; diff --git a/cpu/rp2350_riscv/xosc.c b/cpu/rp2350_riscv/xosc.c deleted file mode 100644 index c398e28ec9ee..000000000000 --- a/cpu/rp2350_riscv/xosc.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -/** - * @ingroup cpu_rp2350 - * @{ - * - * @file - * @brief XOSC implementation for the RP2350 - * - * @author Tom Hert - */ - -#include - -#include "RP2350.h" -#include "board.h" -#include "macros/units.h" -#include "periph_cpu.h" - -/* Based on datasheet 8.2.4 (1ms wait time) */ -#define STARTUP_DELAY 47 -#define MAX_XOSC_COUNTER_SIZE 0xFFFF -#define SLEEP_100HZ_SPEED 12000000UL -#define CYCLES_PER_MS (SLEEP_100HZ_SPEED / 1000) - -void xosc_start(void) { - /* Set the FREQ_RANGE */ - XOSC->CTRL = XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ; - /* Set the startup delay (default 1ms) */ - XOSC->STARTUP = STARTUP_DELAY; - /* set enable bit */ - atomic_set(&XOSC->CTRL, - XOSC_CTRL_ENABLE_VALUE_ENABLE << XOSC_CTRL_ENABLE_LSB); - - while (!(XOSC->STATUS & XOSC_STATUS_STABLE_BITS)) { - /* Wait for the crystal to stabilize */ - } -} - -void xosc_sleep(uint32_t milliseconds) { - for (uint32_t i = milliseconds; i > 0; i--) { - XOSC->COUNT = CYCLES_PER_MS; - while (XOSC->COUNT != 0) {}; - } -} - -void xosc_stop(void) { - /* @TODO */ -} - -/** @} */ From b048fd793c50b2c5a990ee65ccc199992ebc3f3d Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Tue, 30 Sep 2025 16:05:24 +0200 Subject: [PATCH 08/20] boards/rpi-pico-2: adjust to new rp2350_arm name --- boards/rpi-pico-2/Kconfig | 2 +- boards/rpi-pico-2/Makefile.features | 2 +- boards/rpi-pico-2/Makefile.include | 2 +- boards/rpi-pico-2/include/board.h | 7 ++--- boards/rpi-pico-2/include/periph_conf.h | 42 +++++++++++++++++++++++++ features.yaml | 6 ++-- makefiles/features_existing.inc.mk | 2 +- 7 files changed, 52 insertions(+), 11 deletions(-) diff --git a/boards/rpi-pico-2/Kconfig b/boards/rpi-pico-2/Kconfig index d0ac0bb5744c..923eb20a8d43 100644 --- a/boards/rpi-pico-2/Kconfig +++ b/boards/rpi-pico-2/Kconfig @@ -8,4 +8,4 @@ config BOARD config BOARD_RPI_PICO_2 bool default y - select CPU_MODEL_RP2350 + select CPU_MODEL_RP2350_RISCV diff --git a/boards/rpi-pico-2/Makefile.features b/boards/rpi-pico-2/Makefile.features index b19f996d1407..f6baa706cf83 100644 --- a/boards/rpi-pico-2/Makefile.features +++ b/boards/rpi-pico-2/Makefile.features @@ -1 +1 @@ -CPU := rp2350 +CPU := rp2350_arm diff --git a/boards/rpi-pico-2/Makefile.include b/boards/rpi-pico-2/Makefile.include index b80aa5b4da25..94a0f6a0aec4 100644 --- a/boards/rpi-pico-2/Makefile.include +++ b/boards/rpi-pico-2/Makefile.include @@ -1,4 +1,4 @@ -CPU_MODEL := RP2350 +CPU_MODEL := RP2350_ARM PORT_LINUX ?= /dev/ttyACM0 # JLink isnt tested yet on RP2350 diff --git a/boards/rpi-pico-2/include/board.h b/boards/rpi-pico-2/include/board.h index 0cdbc0d51ff6..563cb74cafb1 100644 --- a/boards/rpi-pico-2/include/board.h +++ b/boards/rpi-pico-2/include/board.h @@ -7,7 +7,7 @@ #pragma once /** - * @ingroup boards_rpi_pico_2 + * @ingroup boards_rpi_pico_2_arm * @{ * * @file @@ -16,11 +16,10 @@ * @author Tom Hert */ -#include "RP2350.h" #include "cpu.h" -#include "cpu_conf.h" #include "periph_conf.h" -#include "periph_cpu.h" + +#include "periph/gpio.h" /** GPIO Pin ID for the onboard LED */ #define LED0_PIN_ID 25u diff --git a/boards/rpi-pico-2/include/periph_conf.h b/boards/rpi-pico-2/include/periph_conf.h index ed237d2c3b58..aa7d31c0a922 100644 --- a/boards/rpi-pico-2/include/periph_conf.h +++ b/boards/rpi-pico-2/include/periph_conf.h @@ -6,6 +6,16 @@ #pragma once +/** + * @ingroup boards_rpi_pico_2_arm + * @{ + * + * @file + * @brief Board periph definitions for the Raspberry Pi Pico 2 + * + * @author Tom Hert + */ + #include #include "RP2350.h" @@ -15,6 +25,38 @@ extern "C" { #endif +/** + * @brief Configuration details for an UART interface + */ +typedef struct { + UART0_Type *dev; /**< Base address of the I/O registers of the device */ + gpio_t rx_pin; /**< GPIO pin to use for RX */ + gpio_t tx_pin; /**< GPIO pin to use for TX */ + IRQn_Type irqn; /**< IRQ number of the UART interface */ +} uart_conf_t; + +static const uart_conf_t uart_config[] = { + { + .dev = UART0, + .rx_pin = GPIO_PIN(0, 1), + .tx_pin = GPIO_PIN(0, 0), + .irqn = UART0_IRQ_IRQn + }, + { + .dev = UART1, + .rx_pin = GPIO_PIN(0, 9), + .tx_pin = GPIO_PIN(0, 8), + .irqn = UART1_IRQ_IRQn + } +}; + +#define UART_0_ISR (isr_uart0) +#define UART_1_ISR (isr_uart1) + +#define UART_NUMOF ARRAY_SIZE(uart_config) + #ifdef __cplusplus } #endif + +/** @} */ diff --git a/features.yaml b/features.yaml index 5c98b23e43c6..3f1ea71e2021 100644 --- a/features.yaml +++ b/features.yaml @@ -283,10 +283,10 @@ groups: features: - name: cpu_rpx0xx help: The MCU is part of the Raspberry PI RPx0xx family. - - name: cpu_rp2350 - help: The MCU is a Raspberry Pi RP2350 + - name: cpu_rp2350_arm + help: The MCU is a Raspberry Pi RP2350 Cortex-M33 ARM, - name: cpu_rp2350_riscv - help: The MCU is a Raspberry Pi RP2350 RISCV + help: The MCU is a Raspberry Pi RP2350 Hazard3 RISC-V. - title: Silicon Laboratories EFM32 Grouping features: diff --git a/makefiles/features_existing.inc.mk b/makefiles/features_existing.inc.mk index 3f73608ce82c..8889dc5f5b1e 100644 --- a/makefiles/features_existing.inc.mk +++ b/makefiles/features_existing.inc.mk @@ -86,7 +86,7 @@ FEATURES_EXISTING := \ cpu_nrf53 \ cpu_nrf9160 \ cpu_qn908x \ - cpu_rp2350 \ + cpu_rp2350_arm \ cpu_rp2350_riscv \ cpu_rpx0xx \ cpu_sam3 \ From b6da093a95ae3e49cc469b810ba8950f11bc3ebb Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Tue, 30 Sep 2025 16:17:48 +0200 Subject: [PATCH 09/20] boards/rpi-pico-2: rename arm pico 2 version to rpi-pico-2-arm --- boards/{rpi-pico-2 => rpi-pico-2-arm}/Kconfig | 6 +++--- boards/{rpi-pico-2 => rpi-pico-2-arm}/Makefile | 0 boards/{rpi-pico-2 => rpi-pico-2-arm}/Makefile.features | 0 boards/{rpi-pico-2 => rpi-pico-2-arm}/Makefile.include | 0 boards/{rpi-pico-2 => rpi-pico-2-arm}/board.c | 0 boards/{rpi-pico-2 => rpi-pico-2-arm}/dist/openocd.cfg | 5 ++++- boards/{rpi-pico-2 => rpi-pico-2-arm}/doc.md | 6 +++--- boards/{rpi-pico-2 => rpi-pico-2-arm}/include/board.h | 0 boards/{rpi-pico-2 => rpi-pico-2-arm}/include/gpio_params.h | 0 boards/{rpi-pico-2 => rpi-pico-2-arm}/include/periph_conf.h | 0 10 files changed, 10 insertions(+), 7 deletions(-) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/Kconfig (61%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/Makefile (100%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/Makefile.features (100%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/Makefile.include (100%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/board.c (100%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/dist/openocd.cfg (50%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/doc.md (97%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/include/board.h (100%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/include/gpio_params.h (100%) rename boards/{rpi-pico-2 => rpi-pico-2-arm}/include/periph_conf.h (100%) diff --git a/boards/rpi-pico-2/Kconfig b/boards/rpi-pico-2-arm/Kconfig similarity index 61% rename from boards/rpi-pico-2/Kconfig rename to boards/rpi-pico-2-arm/Kconfig index 923eb20a8d43..0733e813ef55 100644 --- a/boards/rpi-pico-2/Kconfig +++ b/boards/rpi-pico-2-arm/Kconfig @@ -3,9 +3,9 @@ # SPDX-License-Identifier: LGPL-2.1-only config BOARD - default "rpi-pico-2" if BOARD_RPI_PICO_2 + default "rpi-pico-2-arm" if BOARD_RPI_PICO_2_ARM -config BOARD_RPI_PICO_2 +config BOARD_RPI_PICO_2_ARM bool default y - select CPU_MODEL_RP2350_RISCV + select CPU_MODEL_RP2350_ARM diff --git a/boards/rpi-pico-2/Makefile b/boards/rpi-pico-2-arm/Makefile similarity index 100% rename from boards/rpi-pico-2/Makefile rename to boards/rpi-pico-2-arm/Makefile diff --git a/boards/rpi-pico-2/Makefile.features b/boards/rpi-pico-2-arm/Makefile.features similarity index 100% rename from boards/rpi-pico-2/Makefile.features rename to boards/rpi-pico-2-arm/Makefile.features diff --git a/boards/rpi-pico-2/Makefile.include b/boards/rpi-pico-2-arm/Makefile.include similarity index 100% rename from boards/rpi-pico-2/Makefile.include rename to boards/rpi-pico-2-arm/Makefile.include diff --git a/boards/rpi-pico-2/board.c b/boards/rpi-pico-2-arm/board.c similarity index 100% rename from boards/rpi-pico-2/board.c rename to boards/rpi-pico-2-arm/board.c diff --git a/boards/rpi-pico-2/dist/openocd.cfg b/boards/rpi-pico-2-arm/dist/openocd.cfg similarity index 50% rename from boards/rpi-pico-2/dist/openocd.cfg rename to boards/rpi-pico-2-arm/dist/openocd.cfg index 69faf2c879bd..85a621c1e613 100644 --- a/boards/rpi-pico-2/dist/openocd.cfg +++ b/boards/rpi-pico-2-arm/dist/openocd.cfg @@ -1,7 +1,10 @@ echo "Make sure to use the Raspberry Pi OpenOCD version!" +echo "For further details see Appendix A Building OpenOCD:" +echo "https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf" source [find target/rp2350.cfg] -set USE_CORE 0 +set USE_CORE SMP set RESCUE 1 $_TARGETNAME_0 configure -rtos auto adapter speed 5000 rp2350.dap.core1 cortex_m reset_config sysresetreq +rp2350.dap.core0 cortex_m reset_config sysresetreq diff --git a/boards/rpi-pico-2/doc.md b/boards/rpi-pico-2-arm/doc.md similarity index 97% rename from boards/rpi-pico-2/doc.md rename to boards/rpi-pico-2-arm/doc.md index f441304714cd..79493086bb1e 100644 --- a/boards/rpi-pico-2/doc.md +++ b/boards/rpi-pico-2-arm/doc.md @@ -76,13 +76,13 @@ To do this, you need to connect the board to your computer and use the following command: ```bash -PROGRAMMER=openocd BOARD=rpi-pico-2 make flash +PROGRAMMER=openocd BOARD=rpi-pico-2-arm make flash ``` You can then debug your application using GDB with the following command: ```bash -PROGRAMMER=openocd BOARD=rpi-pico-2 make debug +PROGRAMMER=openocd BOARD=rpi-pico-2-arm make debug ``` ### Flashing using Picotool @@ -90,7 +90,7 @@ PROGRAMMER=openocd BOARD=rpi-pico-2 make debug Simply connect the board to your computer via USB and use the following command: ```bash -BOARD=rpi-pico-2 make flash +BOARD=rpi-pico-2-arm make flash ``` This is the default method for flashing the Raspberry Pi Pico 2. diff --git a/boards/rpi-pico-2/include/board.h b/boards/rpi-pico-2-arm/include/board.h similarity index 100% rename from boards/rpi-pico-2/include/board.h rename to boards/rpi-pico-2-arm/include/board.h diff --git a/boards/rpi-pico-2/include/gpio_params.h b/boards/rpi-pico-2-arm/include/gpio_params.h similarity index 100% rename from boards/rpi-pico-2/include/gpio_params.h rename to boards/rpi-pico-2-arm/include/gpio_params.h diff --git a/boards/rpi-pico-2/include/periph_conf.h b/boards/rpi-pico-2-arm/include/periph_conf.h similarity index 100% rename from boards/rpi-pico-2/include/periph_conf.h rename to boards/rpi-pico-2-arm/include/periph_conf.h From ad79ea52dd8b5c95b4bc753bd2f9a7e9e60cb3b0 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 13:58:22 +0200 Subject: [PATCH 10/20] cpu/rp2350_common: change register calculation functions to pointers --- cpu/rp2350_common/include/periph_cpu.h | 6 +++--- cpu/rp2350_common/periph/gpio.c | 4 ++-- cpu/rp2350_common/periph/uart.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cpu/rp2350_common/include/periph_cpu.h b/cpu/rp2350_common/include/periph_cpu.h index 81d3c149f430..74af385437ff 100644 --- a/cpu/rp2350_common/include/periph_cpu.h +++ b/cpu/rp2350_common/include/periph_cpu.h @@ -106,7 +106,7 @@ static inline uint32_t* calculate_gpio_pad_register_addr(gpio_t pin) */ static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { /* Each status register is followed by a ctrl register */ - return IO_BANK0_BASE + 8 * pin; + return IO_BANK0_BASE + (8 * pin); } /** @@ -115,11 +115,11 @@ static uint32_t calculate_gpio_io_status_register_addr(gpio_t pin) { * @param pin The GPIO pin number * @return The address of the GPIO IO control register for the given pin */ -static inline uint32_t calculate_gpio_io_ctrl_register_addr(gpio_t pin) { +static inline uint32_t* calculate_gpio_io_ctrl_register_addr(gpio_t pin) { /* Each pin has a 8 byte register (4 Bytes of Status, 4 Bytes of CTRL), * so we can calculate the address by adding 8 bytes for each pin, * starting at the base address of IO_BANK0 */ - return calculate_gpio_io_status_register_addr(pin) + 4; + return (uint32_t*) (calculate_gpio_io_status_register_addr(pin) + 4); } #ifdef __cplusplus diff --git a/cpu/rp2350_common/periph/gpio.c b/cpu/rp2350_common/periph/gpio.c index 2827d43ac282..c910230d06e7 100644 --- a/cpu/rp2350_common/periph/gpio.c +++ b/cpu/rp2350_common/periph/gpio.c @@ -36,11 +36,11 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) { switch (mode) { case GPIO_OUT: - *(uint32_t*)calculate_gpio_io_ctrl_register_addr(pin) = + *calculate_gpio_io_ctrl_register_addr(pin) = FUNCTION_SELECT_SIO; volatile uint32_t* pad_reg = - (uint32_t*)calculate_gpio_pad_register_addr(pin); + calculate_gpio_pad_register_addr(pin); /* We clear all bits except the drive strength bit. * We set that to the highest one possible (12mA) diff --git a/cpu/rp2350_common/periph/uart.c b/cpu/rp2350_common/periph/uart.c index fdf2da558bd3..dc78e8b423ac 100644 --- a/cpu/rp2350_common/periph/uart.c +++ b/cpu/rp2350_common/periph/uart.c @@ -132,8 +132,8 @@ void uart_init_pins(uart_t uart) UART0_Type *dev = uart_config[uart].dev; /* Set the UART pins to the correct function */ - *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART; - *(uint32_t *)calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART; + *calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART; + *calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART; /* Clear the ISO bits */ atomic_clear( calculate_gpio_pad_register_addr(uart_config[uart].tx_pin), From 9830fc7cde6e77be146ede7abc26a15c698b4d29 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 1 Oct 2025 16:21:15 +0200 Subject: [PATCH 11/20] boards/rpi-pico-2: unify doc.md into one singular doc.md --- boards/rpi-pico-2-arm/doc.md | 115 +-------------------------------- boards/rpi-pico-2-riscv/doc.md | 29 ++++++++- 2 files changed, 28 insertions(+), 116 deletions(-) diff --git a/boards/rpi-pico-2-arm/doc.md b/boards/rpi-pico-2-arm/doc.md index 79493086bb1e..12b28d7b9929 100644 --- a/boards/rpi-pico-2-arm/doc.md +++ b/boards/rpi-pico-2-arm/doc.md @@ -1,116 +1,5 @@ -@defgroup boards_rpi_pico_2 Raspberry Pi Pico 2 +@defgroup boards_rpi_pico_2_arm Raspberry Pi Pico 2 @ingroup boards @brief Support for the RP2350 based Raspberry Pi Pico board -@warning The support for the Raspberry Pi Pico 2 is still in a very early stage! -See [Known Issues](#rpi_pico_2_known_issues). - -## Overview - -The Raspberry Pi Pico 2 is a microcontroller board based on the RP2350 chip, -featuring dual-core Arm Cortex-M0+ processors and RISC-V Hazard secondary -architecture. It is designed for a wide range of applications, -from hobbyist projects to professional embedded systems -for a fairly affordable price. - -![The Raspberry Pi Pico 2 Board](https://www.raspberrypi.com/documentation/microcontrollers/images/pico-2.png) - -## Hardware - -| MCU | RP2350 | -|:-----------|:------------------------------------------------------------| -| Family | Dual Cortex-M33 or Hazard3 (RISC-V) | -| Vendor | Raspberry Pi | -| RAM | 520 kB on-chip SRAM (10 independent banks) | -| Flash | Up to 16 MB external QSPI flash (Pico 2 has 4 MB by default)| -| Frequency | up to 150 MHz (Set to 125 MHz in RIOT) | -| Security | Boot signing, key storage, SHA-256 accelerator | -| PIOs | 12 state machines | -| UARTs | 2 | -| SPIs | 2 | -| I2Cs | 2 | -| PWM | 24 channels | -| USB | USB 1.1 controller with host and device support | -| Power | On-chip switched-mode power supply with LDO sleep mode | -| OTP | 8 kB of one-time-programmable storage | -| Datasheet | [RP2350 Datasheet](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf) | - -## User Interfaces - -| Interface | Description | -|:-----------|:-------------------------------------------------------------| -| LED0 | User LED (GPIO 0 at Pin 25) | -| SW0 | Button used in flash process, can be accessed using registers but difficult | - -## Pinout - -![Pinout Diagram](https://www.raspberrypi.com/documentation/microcontrollers/images/pico-2-r4-pinout.svg) - -## Flashing the Board - -The Raspberry Pi Pico 2 has a built-in bootloader that allows flashing via USB. -However, you can also use OpenOCD for flashing the board. -If you are using picotool, you need to hold the bootselect button -(the only button on the board) while connecting the board to -your computer via USB. This will put the board into bootloader mode, -allowing you to flash it. - -### Flashing using OpenOCD - -If you have two Raspberry Pi Pico boards, -you can utilize one as a programmer to program the other board. - -Please refer to the -[Debugprobe documentation](https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#getting-started) -for more details. - -Note that Raspberry Pi actually uses their own OpenOCD fork, which is available -in the [RP2040 OpenOCD repository](https://github.com/raspberrypi/openocd). -While technically you can use the standard OpenOCD, -it is recommended to use the Raspberry Pi fork for better compatibility with the -RP2350, as its still fairly "new" and under development, -which is why even their own Pico SDK Extension -uses the Raspberry Pi fork of OpenOCD, instead of the standard one. - -To do this, you need to connect the board to your computer -and use the following command: - -```bash -PROGRAMMER=openocd BOARD=rpi-pico-2-arm make flash -``` - -You can then debug your application using GDB with the following command: - -```bash -PROGRAMMER=openocd BOARD=rpi-pico-2-arm make debug -``` - -### Flashing using Picotool - -Simply connect the board to your computer via USB and use the following command: - -```bash -BOARD=rpi-pico-2-arm make flash -``` - -This is the default method for flashing the Raspberry Pi Pico 2. -However, it does not allow for debugging using GDB. - -@note When programming the board with the Picotool for the first time, -RIOT will download and install the Picotool locally in the RIOT folder. -This process will take some minutes to complete. - -## Known Issues {#rpi_pico_2_known_issues} - -Currently RP2350 support is rather minimal, -as such peripheral support is extremely limited. -The following peripherals are supported: - -- GPIO -- Non-configurable write-only UART (UART0 using Pin 0 and 1) - - The UART Baudrate is set to 115200. - - UART does not work via USB, you need to connect it directly to the GPIO pins. - -More peripherals will be added in the future. -It should also be noted that we currently only support the Cortex M33 cores, -not the RISC-V Hazard cores. +See @ref boards_rpi_pico_2_riscv for further information. diff --git a/boards/rpi-pico-2-riscv/doc.md b/boards/rpi-pico-2-riscv/doc.md index 73277fe212a5..8cdec6378cd2 100644 --- a/boards/rpi-pico-2-riscv/doc.md +++ b/boards/rpi-pico-2-riscv/doc.md @@ -55,6 +55,12 @@ If you are using picotool, you need to hold the bootselect button your computer via USB. This will put the board into bootloader mode, allowing you to flash it. +Generally while Picotool is the easiest way to flash the board, +it does not allow for debugging using GDB. + +It does tend to be more reliable than OpenOCD though, +especially when switching between RISC-V and ARM cores. + ### Flashing using OpenOCD If you have two Raspberry Pi Pico boards, @@ -79,12 +85,24 @@ and use the following command: PROGRAMMER=openocd BOARD=rpi-pico-2-riscv make flash ``` +or, if you want to use the CortexM: + +```bash +PROGRAMMER=openocd BOARD=rpi-pico-2-arm make flash +``` + You can then debug your application using GDB with the following command: ```bash PROGRAMMER=openocd BOARD=rpi-pico-2-riscv make debug ``` +or, if you want to use the CortexM: + +```bash +PROGRAMMER=openocd BOARD=rpi-pico-2-arm make debug +``` + ### Flashing using Picotool Simply connect the board to your computer via USB and use the following command: @@ -93,6 +111,12 @@ Simply connect the board to your computer via USB and use the following command: BOARD=rpi-pico-2-riscv make flash ``` +or, if you want to use the CortexM: + +```bash +BOARD=rpi-pico-2-arm make flash +``` + This is the default method for flashing the Raspberry Pi Pico 2. However, it does not allow for debugging using GDB. @@ -106,11 +130,10 @@ Currently RP2350 support is rather minimal, as such peripheral support is extremely limited. The following peripherals are supported: +- XH3IRQ RISC-V Interrupt Controller (CortexM Interrupts also work) - GPIO -- Non-configurable write-only UART (UART0 using Pin 0 and 1) +- UART - The UART Baudrate is set to 115200. - UART does not work via USB, you need to connect it directly to the GPIO pins. More peripherals will be added in the future. -It should also be noted that we currently only support the Cortex M33 cores, -not the RISC-V Hazard cores. From b00cf0a6ae327c52d458d2bc39b408fbed8cb1ff Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Thu, 2 Oct 2025 15:32:50 +0200 Subject: [PATCH 12/20] pkg/picosdk: Add patch for bit overlap --- pkg/picosdk/patches/bit.patch | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 pkg/picosdk/patches/bit.patch diff --git a/pkg/picosdk/patches/bit.patch b/pkg/picosdk/patches/bit.patch new file mode 100644 index 000000000000..dd5ee4742f83 --- /dev/null +++ b/pkg/picosdk/patches/bit.patch @@ -0,0 +1,48 @@ +From ac99966860b9101739361412e1374cdd3e4fadf0 Mon Sep 17 00:00:00 2001 +From: AnnsAnn +Date: Thu, 2 Oct 2025 15:31:10 +0200 +Subject: [PATCH] Remove the evil lines + +--- + .../stub/CMSIS/Device/RP2350/Include/RP2350.h | 25 ------------------- + 1 file changed, 25 deletions(-) + +diff --git a/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h b/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h +index ba5d206..154e7c4 100644 +--- a/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h ++++ b/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h +@@ -671,31 +671,6 @@ typedef struct { /*!< HSTX_FIFO Structure + + + +-/* =========================================================================================================================== */ +-/* ================ HSTX_CTRL ================ */ +-/* =========================================================================================================================== */ +- +- +-/** +- * @brief Control interface to HSTX. For FIFO write access and status, see the HSTX_FIFO register block. (HSTX_CTRL) +- */ +- +-typedef struct { /*!< HSTX_CTRL Structure */ +- __IOM uint32_t CSR; /*!< CSR */ +- __IOM uint32_t BIT0; /*!< Data control register for output bit 0 */ +- __IOM uint32_t BIT1; /*!< Data control register for output bit 1 */ +- __IOM uint32_t BIT2; /*!< Data control register for output bit 2 */ +- __IOM uint32_t BIT3; /*!< Data control register for output bit 3 */ +- __IOM uint32_t BIT4; /*!< Data control register for output bit 4 */ +- __IOM uint32_t BIT5; /*!< Data control register for output bit 5 */ +- __IOM uint32_t BIT6; /*!< Data control register for output bit 6 */ +- __IOM uint32_t BIT7; /*!< Data control register for output bit 7 */ +- __IOM uint32_t EXPAND_SHIFT; /*!< Configure the optional shifter inside the command expander */ +- __IOM uint32_t EXPAND_TMDS; /*!< Configure the optional TMDS encoder inside the command expander */ +-} HSTX_CTRL_Type; /*!< Size = 44 (0x2c) */ +- +- +- + /* =========================================================================================================================== */ + /* ================ EPPB ================ */ + /* =========================================================================================================================== */ +-- +2.51.0 + From f63178f97dfe49a679e15b1801022b5b022be6e3 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 13:23:04 +0200 Subject: [PATCH 13/20] boards/rpi-pico-2-*: create common board folder --- boards/Makefile | 3 + boards/Makefile.features | 3 + boards/Makefile.include | 3 + boards/common/rpi-pico-2/Makefile | 3 + boards/common/rpi-pico-2/Makefile.features | 0 boards/common/rpi-pico-2/Makefile.include | 2 + .../rpi-pico-2}/board.c | 0 .../rpi-pico-2}/include/board.h | 0 .../rpi-pico-2}/include/gpio_params.h | 0 .../rpi-pico-2}/include/periph_conf.h | 0 boards/rpi-pico-2-arm/Makefile.dep | 1 + boards/rpi-pico-2-riscv/Makefile.dep | 1 + boards/rpi-pico-2-riscv/board.c | 15 ----- boards/rpi-pico-2-riscv/include/board.h | 42 ------------ boards/rpi-pico-2-riscv/include/gpio_params.h | 18 ------ boards/rpi-pico-2-riscv/include/periph_conf.h | 64 ------------------- 16 files changed, 16 insertions(+), 139 deletions(-) create mode 100644 boards/common/rpi-pico-2/Makefile create mode 100644 boards/common/rpi-pico-2/Makefile.features create mode 100644 boards/common/rpi-pico-2/Makefile.include rename boards/{rpi-pico-2-arm => common/rpi-pico-2}/board.c (100%) rename boards/{rpi-pico-2-arm => common/rpi-pico-2}/include/board.h (100%) rename boards/{rpi-pico-2-arm => common/rpi-pico-2}/include/gpio_params.h (100%) rename boards/{rpi-pico-2-arm => common/rpi-pico-2}/include/periph_conf.h (100%) create mode 100644 boards/rpi-pico-2-arm/Makefile.dep create mode 100644 boards/rpi-pico-2-riscv/Makefile.dep delete mode 100644 boards/rpi-pico-2-riscv/board.c delete mode 100644 boards/rpi-pico-2-riscv/include/board.h delete mode 100644 boards/rpi-pico-2-riscv/include/gpio_params.h delete mode 100644 boards/rpi-pico-2-riscv/include/periph_conf.h diff --git a/boards/Makefile b/boards/Makefile index ae92f259427e..a0d19ba7ac5b 100644 --- a/boards/Makefile +++ b/boards/Makefile @@ -6,6 +6,9 @@ DIRS += $(RIOTBOARD)/common/init ifneq (,$(filter boards_common_adafruit-nrf52-bootloader,$(USEMODULE))) DIRS += $(RIOTBOARD)/common/adafruit-nrf52-bootloader endif +ifneq (,$(filter boards_common_rpi_pico_2,$(USEMODULE))) + DIRS += $(RIOTBOARD)/common/rpi-pico-2 +endif ifneq (,$(filter boards_common_seeedstudio-xiao-nrf52840,$(USEMODULE))) DIRS += $(RIOTBOARD)/common/seeedstudio-xiao-nrf52840 endif diff --git a/boards/Makefile.features b/boards/Makefile.features index 895bb1116850..42c2bf3852fd 100644 --- a/boards/Makefile.features +++ b/boards/Makefile.features @@ -1,4 +1,7 @@ # SORT THIS ALPHABETICALLY BY COMMON BOARD NAME! +ifneq (,$(filter boards_common_rpi_pico_2,$(USEMODULE))) + include $(RIOTBOARD)/common/rpi-pico-2/Makefile.features +endif ifneq (,$(filter boards_common_seeedstudio-xiao-nrf52840,$(USEMODULE))) include $(RIOTBOARD)/common/seeedstudio-xiao-nrf52840/Makefile.features endif diff --git a/boards/Makefile.include b/boards/Makefile.include index 4fb738b7adb0..6168b3f21ada 100644 --- a/boards/Makefile.include +++ b/boards/Makefile.include @@ -2,6 +2,9 @@ ifneq (,$(filter boards_common_adafruit-nrf52-bootloader,$(USEMODULE))) include $(RIOTBOARD)/common/adafruit-nrf52-bootloader/Makefile.include endif +ifneq (,$(filter boards_common_rpi_pico_2,$(USEMODULE))) + include $(RIOTBOARD)/common/rpi-pico-2/Makefile.include +endif ifneq (,$(filter boards_common_seeedstudio-xiao-nrf52840,$(USEMODULE))) include $(RIOTBOARD)/common/seeedstudio-xiao-nrf52840/Makefile.include endif diff --git a/boards/common/rpi-pico-2/Makefile b/boards/common/rpi-pico-2/Makefile new file mode 100644 index 000000000000..67b301c3b4fa --- /dev/null +++ b/boards/common/rpi-pico-2/Makefile @@ -0,0 +1,3 @@ +MODULE = boards_common_rpi_pico_2 + +include $(RIOTBASE)/Makefile.base diff --git a/boards/common/rpi-pico-2/Makefile.features b/boards/common/rpi-pico-2/Makefile.features new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/boards/common/rpi-pico-2/Makefile.include b/boards/common/rpi-pico-2/Makefile.include new file mode 100644 index 000000000000..b98f525a7a27 --- /dev/null +++ b/boards/common/rpi-pico-2/Makefile.include @@ -0,0 +1,2 @@ +# add the common header files to the include path +INCLUDES += -I$(RIOTBOARD)/common/rpi-pico-2/include diff --git a/boards/rpi-pico-2-arm/board.c b/boards/common/rpi-pico-2/board.c similarity index 100% rename from boards/rpi-pico-2-arm/board.c rename to boards/common/rpi-pico-2/board.c diff --git a/boards/rpi-pico-2-arm/include/board.h b/boards/common/rpi-pico-2/include/board.h similarity index 100% rename from boards/rpi-pico-2-arm/include/board.h rename to boards/common/rpi-pico-2/include/board.h diff --git a/boards/rpi-pico-2-arm/include/gpio_params.h b/boards/common/rpi-pico-2/include/gpio_params.h similarity index 100% rename from boards/rpi-pico-2-arm/include/gpio_params.h rename to boards/common/rpi-pico-2/include/gpio_params.h diff --git a/boards/rpi-pico-2-arm/include/periph_conf.h b/boards/common/rpi-pico-2/include/periph_conf.h similarity index 100% rename from boards/rpi-pico-2-arm/include/periph_conf.h rename to boards/common/rpi-pico-2/include/periph_conf.h diff --git a/boards/rpi-pico-2-arm/Makefile.dep b/boards/rpi-pico-2-arm/Makefile.dep new file mode 100644 index 000000000000..73d807ad5db4 --- /dev/null +++ b/boards/rpi-pico-2-arm/Makefile.dep @@ -0,0 +1 @@ +USEMODULE += boards_common_rpi_pico_2 diff --git a/boards/rpi-pico-2-riscv/Makefile.dep b/boards/rpi-pico-2-riscv/Makefile.dep new file mode 100644 index 000000000000..73d807ad5db4 --- /dev/null +++ b/boards/rpi-pico-2-riscv/Makefile.dep @@ -0,0 +1 @@ +USEMODULE += boards_common_rpi_pico_2 diff --git a/boards/rpi-pico-2-riscv/board.c b/boards/rpi-pico-2-riscv/board.c deleted file mode 100644 index 49f7740789db..000000000000 --- a/boards/rpi-pico-2-riscv/board.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#include "board.h" - -void board_init(void) { - /* Re-enable the LED0 pin - * Otherwise the LED will not work after a reset - * This is needed, esp. when the LED is used via - * the define macros */ - gpio_init(LED0_PIN_ID, GPIO_OUT); -} diff --git a/boards/rpi-pico-2-riscv/include/board.h b/boards/rpi-pico-2-riscv/include/board.h deleted file mode 100644 index fafbc14a88c9..000000000000 --- a/boards/rpi-pico-2-riscv/include/board.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup boards_rpi_pico_2_riscv - * @{ - * - * @file - * @brief Board specific definitions for the Raspberry Pi Pico 2 - * - * @author Tom Hert - */ - -#include "cpu.h" -#include "periph_conf.h" - -#include "periph/gpio.h" - -/** GPIO Pin ID for the onboard LED */ -#define LED0_PIN_ID 25u -#define LED0_ON gpio_set(LED0_PIN_ID) -#define LED0_OFF gpio_clear(LED0_PIN_ID) -#define LED0_TOGGLE gpio_toggle(LED0_PIN_ID) -#define LED0_NAME "LED(Green)" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Initialize the board, called from the cpu startup code */ -void board_init(void); - -#ifdef __cplusplus -} -#endif - -/** @} */ diff --git a/boards/rpi-pico-2-riscv/include/gpio_params.h b/boards/rpi-pico-2-riscv/include/gpio_params.h deleted file mode 100644 index 1998b8afaa24..000000000000 --- a/boards/rpi-pico-2-riscv/include/gpio_params.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -#include "board.h" -#include "saul/periph.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif diff --git a/boards/rpi-pico-2-riscv/include/periph_conf.h b/boards/rpi-pico-2-riscv/include/periph_conf.h deleted file mode 100644 index 4f6f16422484..000000000000 --- a/boards/rpi-pico-2-riscv/include/periph_conf.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Tom Hert - * SPDX-FileCopyrightText: 2025 HAW Hamburg - * SPDX-License-Identifier: LGPL-2.1-only - */ - -#pragma once - -/** - * @ingroup boards_rpi_pico_2_riscv - * @{ - * - * @file - * @brief Board specific periph definitions - * for the Raspberry Pi Pico 2 - * - * @author Tom Hert - */ - -#include "kernel_defines.h" -#include - -#include "kernel_defines.h" -#include "periph_cpu.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Configuration details for an UART interface - */ -typedef struct { - UART0_Type *dev; /**< Base address of the I/O registers of the device */ - gpio_t rx_pin; /**< GPIO pin to use for RX */ - gpio_t tx_pin; /**< GPIO pin to use for TX */ - IRQn_Type irqn; /**< IRQ number of the UART interface */ -} uart_conf_t; - -static const uart_conf_t uart_config[] = { - { - .dev = UART0, - .rx_pin = GPIO_PIN(0, 1), - .tx_pin = GPIO_PIN(0, 0), - .irqn = UART0_IRQ_IRQn - }, - { - .dev = UART1, - .rx_pin = GPIO_PIN(0, 9), - .tx_pin = GPIO_PIN(0, 8), - .irqn = UART1_IRQ_IRQn - } -}; - -#define UART_0_ISR (isr_uart0) -#define UART_1_ISR (isr_uart1) - -#define UART_NUMOF ARRAY_SIZE(uart_config) - -#ifdef __cplusplus -} -#endif - -/** @} */ From 944729341dfd3fe5620f51c96af71de301c21e26 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 13:10:47 +0200 Subject: [PATCH 14/20] cpu/rp2350: increase stack size --- cpu/rp2350_common/Makefile.include | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu/rp2350_common/Makefile.include b/cpu/rp2350_common/Makefile.include index de8bf749b0b0..d25da2943b04 100644 --- a/cpu/rp2350_common/Makefile.include +++ b/cpu/rp2350_common/Makefile.include @@ -4,6 +4,8 @@ RAM_LEN := 0x82000 # 520kB = 532479 used in the RPi Pico 2350 ROM_START_ADDR := 0x10000000 # XIP Non-Secure address for rp2350 RAM_START_ADDR := 0x20000000 # Non-Secure RAM address for rp2350 +CFLAGS += -DISR_STACKSIZE=8192 + INCLUDES += -I$(RIOTCPU)/rp2350_common/include INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include From 5286de10eb0efb369b48333d612561f61302dfdc Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 13:49:10 +0200 Subject: [PATCH 15/20] cpu/rp2350: provide pmp --- cpu/rp2350_riscv/Makefile.features | 1 + cpu/rp2350_riscv/include/cpu_conf.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cpu/rp2350_riscv/Makefile.features b/cpu/rp2350_riscv/Makefile.features index 964245e3d11a..587c6d29fcab 100644 --- a/cpu/rp2350_riscv/Makefile.features +++ b/cpu/rp2350_riscv/Makefile.features @@ -2,6 +2,7 @@ CPU_CORE := rv32imac CPU_FAM := RP2350 CPU_MODEL = rp2350_hazard3 +FEATURES_PROVIDED += periph_pmp FEATURES_PROVIDED += periph_xh3irq include $(RIOTCPU)/rp2350_common/Makefile.features diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h index 0bc775f5f816..32e753147662 100644 --- a/cpu/rp2350_riscv/include/cpu_conf.h +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -23,7 +23,8 @@ extern "C" { #define CPU_DEFAULT_IRQ_PRIO 1u #define CPU_IRQ_NUMOF 52u -/* This tells rp2350_common that we are using the RISC-V core */ +#define NUM_PMP_ENTRIES 16u +/** This tells rp2350_common that we are using the RISC-V core */ #define RP2350_USE_RISCV 1 #ifdef __cplusplus From 7faffd3ef04455c94d49c52c8720475467a6669a Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Tue, 30 Sep 2025 16:30:35 +0200 Subject: [PATCH 16/20] DELETEME --- .murdock | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/.murdock b/.murdock index 416a7cffbfbf..39955956fcbf 100755 --- a/.murdock +++ b/.murdock @@ -6,21 +6,8 @@ #export APPS="examples/basic/hello-world tests/unittests" QUICKBUILD_BOARDS=" -adafruit-itsybitsy-m4 -atmega256rfr2-xpro -esp32-wroom-32 -esp32s3-devkit -frdm-k64f -hifive1b -msb-430 -msba2 -native32 -native64 -nrf52840dk -qn9080dk -samr21-xpro -stk3200 -stm32f429i-disc1" +rpi-pico-2-riscv +rpi-pico-2-arm" # this configures boards that are available via pifleet case "${CI_MURDOCK_PROJECT}" in From 19da0650f2b941917f7b3fc77d17227e17521619 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 8 Oct 2025 15:53:16 +0200 Subject: [PATCH 17/20] fixup! cpu/rp2350_common: create shared folder for RISCV & ARM --- cpu/rp2350_common/periph/uart.c | 3 --- cpu/rp2350_common/vectors.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cpu/rp2350_common/periph/uart.c b/cpu/rp2350_common/periph/uart.c index dc78e8b423ac..a2be7e83e035 100644 --- a/cpu/rp2350_common/periph/uart.c +++ b/cpu/rp2350_common/periph/uart.c @@ -146,9 +146,6 @@ void uart_init_pins(uart_t uart) atomic_set( calculate_gpio_pad_register_addr(uart_config[uart].rx_pin), PADS_BANK0_GPIO0_IE_BITS); - - dev->UARTIBRD = IBRD; - dev->UARTFBRD = FBRD; } int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg) diff --git a/cpu/rp2350_common/vectors.c b/cpu/rp2350_common/vectors.c index 5c5ed1eae4dd..4a4cf43d1c7d 100644 --- a/cpu/rp2350_common/vectors.c +++ b/cpu/rp2350_common/vectors.c @@ -26,7 +26,7 @@ #endif #ifndef WEAK_DEFAULT -# define WEAK_DEFAULT __attribute__((weak, alias("dummy_handler"))) +# define WEAK_DEFAULT __attribute__((weak, alias("dummy_handler"))) #endif /* define a local dummy handler as it needs to be in the same compilation unit From 09946582e03882e413f519a3a5923cfd65af13e1 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Fri, 10 Oct 2025 10:40:10 +0200 Subject: [PATCH 18/20] fixup! cpu/rp2350_riscv: add initial support --- cpu/rp2350_riscv/cpu.c | 16 ++++++++-------- cpu/rp2350_riscv/include/cpu_conf.h | 4 ++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cpu/rp2350_riscv/cpu.c b/cpu/rp2350_riscv/cpu.c index 932425aa9396..a46e2b3548ce 100644 --- a/cpu/rp2350_riscv/cpu.c +++ b/cpu/rp2350_riscv/cpu.c @@ -15,15 +15,15 @@ * @} */ -#include "board.h" -#include "cpu.h" -#include "clock_conf.h" -#include "kernel_init.h" -#include "periph/init.h" -#include "periph/uart.h" -#include "periph_conf.h" + #include -#include + #include "board.h" + #include "cpu.h" + #include "clock_conf.h" + #include "kernel_init.h" + #include "periph/init.h" + #include "periph/uart.h" + #include "periph_conf.h" /** * @brief Initialize the CPU, set IRQ priorities, clocks, peripheral diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h index 32e753147662..c47a6e0c81a5 100644 --- a/cpu/rp2350_riscv/include/cpu_conf.h +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -21,8 +21,12 @@ extern "C" { #endif +/** Default IRQ priority for the CPU, + * we don't have different levels at the moment */ #define CPU_DEFAULT_IRQ_PRIO 1u +/** The RP2350 has 52 IRQs, see vectors.c for more details */ #define CPU_IRQ_NUMOF 52u +/** The Hazard3 core supports 16 PMP entries */ #define NUM_PMP_ENTRIES 16u /** This tells rp2350_common that we are using the RISC-V core */ #define RP2350_USE_RISCV 1 From 1ce2f8ea57f6dbe306a7fa74ae8e794abe59cdc8 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Wed, 15 Oct 2025 15:52:45 +0200 Subject: [PATCH 19/20] Update uart.c --- cpu/rp2350_common/periph/uart.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/cpu/rp2350_common/periph/uart.c b/cpu/rp2350_common/periph/uart.c index a2be7e83e035..2b057d1bc394 100644 --- a/cpu/rp2350_common/periph/uart.c +++ b/cpu/rp2350_common/periph/uart.c @@ -129,8 +129,6 @@ void uart_init_pins(uart_t uart) /* We reset UART0 here, so we can be sure it is in a known state */ _reset_uart(uart); - UART0_Type *dev = uart_config[uart].dev; - /* Set the UART pins to the correct function */ *calculate_gpio_io_ctrl_register_addr(uart_config[uart].tx_pin) = FUNCTION_SELECT_UART; *calculate_gpio_io_ctrl_register_addr(uart_config[uart].rx_pin) = FUNCTION_SELECT_UART; From 70e27db3730a1585f3dcb9431a252284899cae45 Mon Sep 17 00:00:00 2001 From: AnnsAnn Date: Thu, 16 Oct 2025 13:33:15 +0200 Subject: [PATCH 20/20] fix: pmp is actually just 8, the other 8 are a lie --- cpu/rp2350_riscv/include/cpu_conf.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cpu/rp2350_riscv/include/cpu_conf.h b/cpu/rp2350_riscv/include/cpu_conf.h index c47a6e0c81a5..17780774e319 100644 --- a/cpu/rp2350_riscv/include/cpu_conf.h +++ b/cpu/rp2350_riscv/include/cpu_conf.h @@ -26,8 +26,13 @@ extern "C" { #define CPU_DEFAULT_IRQ_PRIO 1u /** The RP2350 has 52 IRQs, see vectors.c for more details */ #define CPU_IRQ_NUMOF 52u -/** The Hazard3 core supports 16 PMP entries */ -#define NUM_PMP_ENTRIES 16u +/** + * The Hazard3 core supports 16 PMP entries + * Only the first 8 are dynamic + * the next 3 hard-wired + * the remaining ones OFF + */ +#define NUM_PMP_ENTRIES 8u /** This tells rp2350_common that we are using the RISC-V core */ #define RP2350_USE_RISCV 1