Skip to content

Commit 677b63f

Browse files
committed
# This is a combination of 4 commits.
# This is the 1st commit message: cpu/rp2350_common: create shared folder for RISCV & ARM # The commit message #2 will be skipped: # fixup! cpu/rp2350_common: create shared folder for RISCV & ARM # The commit message #3 will be skipped: # fixup! cpu/rp2350_common: create shared folder for RISCV & ARM # The commit message #4 will be skipped: # fixup! cpu/rp2350_common: create shared folder for RISCV & ARM
1 parent 4c421e4 commit 677b63f

File tree

18 files changed

+1188
-1
lines changed

18 files changed

+1188
-1
lines changed

cpu/riscv_common/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
DIRS = periph
1+
DIRS += periph
22

33
include $(RIOTBASE)/Makefile.base

cpu/rp2350_common/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
DIRS += periph
2+
3+
include $(RIOTBASE)/Makefile.base

cpu/rp2350_common/Makefile.dep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
USEMODULE += periph
2+
USEPKG += picosdk
3+
# We tell the build system that common needs to be built
4+
USEMODULE += rp2350_common
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FEATURES_PROVIDED += periph_gpio
2+
FEATURES_PROVIDED += periph_uart

cpu/rp2350_common/Makefile.include

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CFLAGS += -Wno-pedantic
2+
3+
ROM_LEN ?= 2097152 # = 2 MiB used in the RPi Pico
4+
ROM_OFFSET := 0 # bootloader size
5+
RAM_LEN := 0x82000 # 520kB = 532479 used in the RPi Pico 2350
6+
ROM_START_ADDR := 0x10000000 # XIP Non-Secure address for rp2350
7+
RAM_START_ADDR := 0x20000000 # Non-Secure RAM address for rp2350
8+
9+
INCLUDES += -I$(RIOTCPU)/rp2350_common/include
10+
INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include
11+
INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include
12+
INCLUDES += -isystem$(RIOTBASE)/build/pkg/picosdk/src/rp2350/hardware_regs/include/hardware
13+
14+
# Supported programmers and debuggers
15+
PROGRAMMERS_SUPPORTED := picotool openocd jlink
16+
PROGRAMMER ?= picotool
17+
OPENOCD_DEBUG_ADAPTER ?= dap

cpu/rp2350_common/clock.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Tom Hert <[email protected]>
3+
* SPDX-FileCopyrightText: 2025 HAW Hamburg
4+
* SPDX-License-Identifier: LGPL-2.1-only
5+
*/
6+
7+
/**
8+
* @ingroup cpu_rp2350
9+
* @{
10+
*
11+
* @file
12+
* @brief Clock configuration implementation for the RP2350
13+
*
14+
* @author Tom Hert <[email protected]>
15+
*/
16+
17+
#include "periph_cpu.h"
18+
19+
void clock_reset(void) {
20+
/* Reset the clock system */
21+
reset_component(RESET_PLL_SYS, RESET_PLL_SYS);
22+
}
23+
24+
/**
25+
* @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it
26+
* @warning Make sure to call clock_reset() before this function to reset the
27+
* clock system
28+
* @see RP2350 Docs Chapter 8, mostly 8.2 for more details
29+
*/
30+
void cpu_clock_init(void) {
31+
/* Enable the XOSC */
32+
xosc_start();
33+
34+
/* Setup the PLL using the XOSC as the reference clock. */
35+
PLL_SYS->FBDIV_INT =
36+
PLL_FEEDBACK_DIVIDER_VALUE; /* Set the feedback divider */
37+
38+
/* Set the post-dividers for the PLL output.*/
39+
PLL_SYS->PRIM = PDIV;
40+
/* Turn on PLL */
41+
atomic_clear(&PLL_SYS->PWR,
42+
PLL_PWR_PD_BITS | PLL_PWR_VCOPD_BITS | PLL_PWR_POSTDIVPD_BITS);
43+
44+
/* sleep 10ms to allow the PLL to stabilize */
45+
xosc_sleep(10);
46+
47+
/* Based on the description in chapter 8 this is something that should be done
48+
* However, it appears to cause issues and is not done by other examples on the
49+
* internet. This needs to be investigated further. */
50+
51+
/* Wait for lock */
52+
/* while (!(PLL_SYS->CS & PLL_CS_LOCK_BITS)) { */
53+
/* Wait for the PLL to lock */
54+
/* } */
55+
56+
/* AUXSRC = 0x0 7:5 && SRC == 0x0 0 */
57+
CLOCKS->CLK_SYS_CTRL = CLK_SYS_PERI_CTRL_ENABLE_BIT;
58+
59+
/* This register contains one decoded bit for each of the clock sources
60+
* enumerated in the CTRL SRC field. The bit does not directly correlate with
61+
* the value of the SRC field For example 0x0 is the first bit while 0x1 is
62+
* the second bit. In some way this makes sense, in some way I lost too much
63+
* time on this. */
64+
while (CLOCKS->CLK_SYS_SELECTED != CLK_SYS_SELECTED_PERI_FIELD_VALUE) {
65+
}
66+
67+
/* AUXSRC = 0x0 -> CLK_SYS Indirectly through lower line */
68+
CLOCKS->CLK_PERI_CTRL = CLK_PERI_CTRL_ENABLE_BIT;
69+
}
70+
71+
/** @} */

cpu/rp2350_common/cpu.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Tom Hert <[email protected]>
3+
* SPDX-FileCopyrightText: 2025 HAW Hamburg
4+
* SPDX-License-Identifier: LGPL-2.1-only
5+
*/
6+
7+
/**
8+
* @ingroup cpu_rp2350
9+
* @{
10+
*
11+
* @file cpu.c
12+
* @brief Implementation of the CPU initialization for RP2350
13+
*
14+
* @author Tom Hert <[email protected]>
15+
* @}
16+
*/
17+
18+
#include <sys/unistd.h>
19+
20+
#include "board.h"
21+
#include "cpu.h"
22+
#include "clock_conf.h"
23+
#include "kernel_init.h"
24+
#include "periph/init.h"
25+
#include "periph/uart.h"
26+
#include "periph_conf.h"
27+
28+
void gpio_reset(void)
29+
{
30+
reset_component(RESET_PADS_BANK0, RESET_PADS_BANK0);
31+
reset_component(RESET_IO_BANK0, RESET_IO_BANK0);
32+
}
33+
34+
/**
35+
* @brief Initialize the CPU, set IRQ priorities, clocks, peripheral
36+
*/
37+
void rp2350_init(void)
38+
{
39+
/* Reset GPIO state */
40+
gpio_reset();
41+
42+
/* Reset clock to default state */
43+
clock_reset();
44+
45+
/* initialize the CPU clock */
46+
cpu_clock_init();
47+
48+
/* initialize the early peripherals */
49+
early_init();
50+
51+
/* trigger static peripheral initialization */
52+
periph_init();
53+
54+
/* initialize the board */
55+
board_init();
56+
}

cpu/rp2350_common/doc.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@defgroup cpu_rp2350 RP2350 MCUs
2+
@ingroup cpu
3+
@brief RP2350 MCU code and definitions
4+
5+
This module contains the code and definitions for MCUs of the RP2350 used by the Pi Pico 2.
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Tom Hert <[email protected]>
3+
* SPDX-FileCopyrightText: 2025 HAW Hamburg
4+
* SPDX-License-Identifier: LGPL-2.1-only
5+
*/
6+
7+
#pragma once
8+
9+
/**
10+
* @ingroup cpu_rp2350
11+
* @{
12+
*
13+
* @file
14+
* @brief Clock configuration for the RP2350
15+
*
16+
* @author Tom Hert <[email protected]>
17+
*/
18+
19+
#include "RP2350.h"
20+
#include "macros/units.h"
21+
22+
/** 1-15 MHz range
23+
* @see hardware/regs/xosc.h and chapter 8.2.8
24+
*/
25+
#define XOSC_CTRL_FREQ_RANGE_VALUE_1_15MHZ 0xaa0u
26+
/** 10-30 MHz range */
27+
#define XOSC_CTRL_FREQ_RANGE_VALUE_10_30MHZ 0xaa1u
28+
/** 25-60 MHz range */
29+
#define XOSC_CTRL_FREQ_RANGE_VALUE_25_60MHZ 0xaa2u
30+
/** 40-100 MHz range */
31+
#define XOSC_CTRL_FREQ_RANGE_VALUE_40_100MHZ 0xaa3u
32+
/** Disable the XOSC */
33+
#define XOSC_CTRL_ENABLE_VALUE_DISABLE 0xd1eu
34+
/** Enable the XOSC */
35+
#define XOSC_CTRL_ENABLE_VALUE_ENABLE 0xfabu
36+
/** LSB of the enable bit */
37+
#define XOSC_CTRL_ENABLE_LSB 12u
38+
/** Stable bit in the XOSC status register */
39+
#define XOSC_STATUS_STABLE_BITS 0x80000000u
40+
/** Default crystal frequency is 12 MHz */
41+
#define XOSC_HZ MHZ(12u)
42+
/** Reference divider for the PLL, set to 2 as per hardware manual */
43+
#define PLL_REF_DIV 2u
44+
/** VCO frequency for the PLL, set to 750 MHz as per hardware manual */
45+
#define PLL_VCO_FREQ 750000000u
46+
/** Post divider 1 for the PLL, set to 6 as per hardware manual */
47+
#define PLL_PD1 6u
48+
/** Post divider 2 for the PLL, set to 2 as per hardware manual */
49+
#define PLL_PD2 2u
50+
/** Power down bits for the PLL */
51+
#define PLL_PWR_PD_BITS 0x00000001u
52+
/** VCO power down bits for the PLL */
53+
#define PLL_PWR_VCOPD_BITS 0x00000020u
54+
/** Lock bit in the PLL control status register */
55+
#define PLL_CS_LOCK_BITS 0x80000000u
56+
/** LSB of the post divider 1 in the PLL primary register */
57+
#define PLL_PRIM_POSTDIV1_LSB 16u
58+
/** LSB of the post divider 2 in the PLL primary register */
59+
#define PLL_PRIM_POSTDIV2_LSB 12u
60+
/** Post divider power down bits for the PLL */
61+
#define PLL_PWR_POSTDIVPD_BITS 0x00000008u
62+
/** Enable bit for the peripheral clock control register */
63+
#define CLK_PERI_CTRL_ENABLE_BIT (1u << 11u)
64+
/** Default CPU frequency in Hz, set to 125 MHz as per hardware manual */
65+
#define CPUFREQ 125000000u
66+
/** Maximum crystal frequency */
67+
#define CLOCK_XOSC_MAX MHZ(15u)
68+
/** Minimum crystal frequency */
69+
#define CLOCK_XOSC_MIN MHZ(5u)
70+
/** Crystal frequency */
71+
#define CLOCK_XOSC (XOSC_HZ)
72+
/** Minimum value of the post PLL clock divers */
73+
#define PLL_POSTDIV_MIN 1u
74+
/** Maximum value of the post PLL clock divers */
75+
#define PLL_POSTDIV_MAX 7u
76+
/** Minimum value of the PLL VCO feedback scaler */
77+
#define PLL_VCO_FEEDBACK_SCALE_MIN 16u
78+
/** Maximum value of the PLL VCO feedback scaler */
79+
#define PLL_VCO_FEEDBACK_SCALE_MAX 320u
80+
/** Minimum value of the clock divider applied before
81+
* feeding in the reference clock into the PLL */
82+
#define PLL_REF_DIV_MIN 1u
83+
/** Minimum value of the clock divider applied before feeding in
84+
* the reference clock into the PLL */
85+
#define PLL_REF_DIV_MAX 1u
86+
/** PLL feedback divider value, set to 125 as per hardware manual */
87+
#define PLL_FEEDBACK_DIVIDER_VALUE 125u
88+
/** Enable bit for the system clock control register to select the peripheral
89+
* clock */
90+
#define CLK_SYS_PERI_CTRL_ENABLE_BIT (1u << 0u)
91+
/** Selected field value for the system clock control register
92+
* to select the peripheral clock */
93+
#define CLK_SYS_SELECTED_PERI_FIELD_VALUE 2u
94+
/** RIOT core clock frequency defined as the CPU frequency */
95+
#define CLOCK_CORECLOCK MHZ(12u)
96+
97+
#if (PLL_VCO_FEEDBACK_SCALE_MIN < PLL_VCO_FEEDBACK_SCALE_MIN) || \
98+
(PLL_VCO_FEEDBACK_SCALE_MAX > PLL_VCO_FEEDBACK_SCALE_MAX)
99+
# error "Value for PLL_VCO_FEEDBACK_SCALE out of range, check config"
100+
#endif
101+
#if (PLL_REF_DIV_MIN < PLL_REF_DIV_MIN) || (PLL_REF_DIV_MAX > PLL_REF_DIV_MAX)
102+
# error "Value for PLLxosc_sleep_REF_DIV out of range, check config"
103+
#endif
104+
#if (PLL_POSTDIV_MIN < PLL_POSTDIV_MIN) || (PLL_POSTDIV_MAX > PLL_POSTDIV_MAX)
105+
# error "Value for PLL_POSTDIV out of range, check config"
106+
#endif
107+
#if ((CLOCK_XOSC > CLOCK_XOSC_MAX) || (CLOCK_XOSC < CLOCK_XOSC_MIN))
108+
# error "Value for CLOCK_XOSC out of range, check config"
109+
#endif
110+
111+
/** Post divider for the PLL, calculated based on the post divider values */
112+
#define PDIV ((PLL_PD1 << PLL_PRIM_POSTDIV1_LSB) | (PLL_PD2 << PLL_PRIM_POSTDIV2_LSB))
113+
/** Feedback divider for the PLL, calculated based on the VCO frequency and
114+
* reference clock frequency */
115+
#define FBDIV ((PLL_VCO_FREQ / XOSC_HZ) / PLL_REF_DIV)
116+
117+
#ifdef __cplusplus
118+
extern "C" {
119+
#endif
120+
121+
/**
122+
* @brief Configures the Crystal to run.
123+
* @note The reference hardware manual suggests to use a 12 MHz crystal, which we
124+
* use by default.
125+
*/
126+
void xosc_start(void);
127+
128+
/**
129+
* @brief Stop the crystal.
130+
*/
131+
void xosc_stop(void);
132+
133+
/**
134+
* @brief Sleep for a given time in milliseconds.
135+
* @param milliseconds The time to sleep in milliseconds.
136+
*/
137+
void xosc_sleep(uint32_t milliseconds);
138+
139+
/**
140+
* @brief Reset the clock system.
141+
*
142+
* This function resets the clock system to a known state.
143+
* It is recommended to call this function before configuring the clock system.
144+
*/
145+
void clock_reset(void);
146+
147+
/**
148+
* @brief Configures the XOSC and then sets CLK_SYS, PLL_SYS and CLK_PERI to it
149+
* @pre Make sure to call clock_reset() before this function to reset the
150+
* clock system
151+
* @see RP2350 Docs Chapter 8, mostly 8.2 for more details
152+
*/
153+
void cpu_clock_init(void);
154+
155+
#ifdef __cplusplus
156+
}
157+
#endif
158+
159+
/** @} */
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Tom Hert [email protected]>
3+
* SPDX-FileCopyrightText: 2025 HAW Hamburg
4+
* SPDX-License-Identifier: LGPL-2.1-only
5+
*/
6+
7+
#pragma once
8+
9+
/**
10+
* @ingroup cpu_rp2350
11+
* @{
12+
*
13+
* @file
14+
* @brief GPIO configuration for the RP2350
15+
*
16+
* @author Tom Hert <[email protected]>
17+
*/
18+
19+
/** The number of GPIO pins available on the RP2350 */
20+
#define GPIO_PIN_NUMOF 30u
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
/**
27+
* @brief Possible function values for @ref gpio_io_ctrl_t::function_select
28+
*/
29+
typedef enum {
30+
/** connect pin to the SPI peripheral (MISO/MOSI/SCK depends on pin) */
31+
FUNCTION_SELECT_SPI = 1,
32+
33+
/** connect pin to the UART peripheral (TXD/RXD depends on pin) */
34+
FUNCTION_SELECT_UART = 2,
35+
36+
/** connect pin to the I2C peripheral (SCL/SDA depends on pin) */
37+
FUNCTION_SELECT_I2C = 3,
38+
39+
/** connect pin to the timer for PWM (channel depends on pin) */
40+
FUNCTION_SELECT_PWM = 4,
41+
42+
/** use pin as vanilla GPIO */
43+
FUNCTION_SELECT_SIO = 5,
44+
45+
/** connect pin to the first PIO peripheral */
46+
FUNCTION_SELECT_PIO0 = 6,
47+
48+
/** connect pin to the second PIO peripheral */
49+
FUNCTION_SELECT_PIO1 = 7,
50+
51+
/** connect pin to the timer (depending on pin: external clock,
52+
* clock output, or not supported) */
53+
FUNCTION_SELECT_CLOCK = 8,
54+
55+
/** connect pin to the USB peripheral (function depends on pin) */
56+
FUNCTION_SELECT_USB = 9,
57+
58+
/** Reset value, pin unconnected */
59+
FUNCTION_SELECT_NONE = 31,
60+
} gpio_function_select_t;
61+
62+
#ifdef __cplusplus
63+
}
64+
#endif
65+
66+
/** @} */

0 commit comments

Comments
 (0)