Skip to content

Commit d0bc427

Browse files
peterharperukdpgeorge
authored andcommitted
rp2/clocks_extra: Update runtime_clocks_init based on new pico-sdk.
Signed-off-by: Damien George <damien@micropython.org>
1 parent 57f4cab commit d0bc427

4 files changed

Lines changed: 58 additions & 17 deletions

File tree

ports/rp2/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ set(PICO_SDK_COMPONENTS
181181
cmsis_core
182182
hardware_adc
183183
hardware_base
184+
hardware_boot_lock
184185
hardware_clocks
185186
hardware_dma
186187
hardware_flash
@@ -487,7 +488,7 @@ target_compile_options(${MICROPY_TARGET} PRIVATE
487488
target_link_options(${MICROPY_TARGET} PRIVATE
488489
-Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE}
489490
-Wl,--wrap=dcd_event_handler
490-
-Wl,--wrap=clocks_init
491+
-Wl,--wrap=runtime_init_clocks
491492
)
492493
493494
# Apply optimisations to performance-critical source code.

ports/rp2/clocks_extra.c

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,36 @@
1313
#include "hardware/xosc.h"
1414
#include "hardware/irq.h"
1515
#include "hardware/gpio.h"
16+
#include "hardware/ticks.h"
1617

18+
#if PICO_RP2040
19+
// The RTC clock frequency is 48MHz divided by power of 2 (to ensure an integer
20+
// division ratio will be used in the clocks block). A divisor of 1024 generates
21+
// an RTC clock tick of 46875Hz. This frequency is relatively close to the
22+
// customary 32 or 32.768kHz 'slow clock' crystals and provides good timing resolution.
1723
#define RTC_CLOCK_FREQ_HZ (USB_CLK_KHZ * KHZ / 1024)
24+
#endif
25+
26+
static void start_all_ticks(void) {
27+
uint32_t cycles = clock_get_hz(clk_ref) / MHZ;
28+
// Note RP2040 has a single tick generator in the watchdog which serves
29+
// watchdog, system timer and M0+ SysTick; The tick generator is clocked from clk_ref
30+
// but is now adapted by the hardware_ticks library for compatibility with RP2350
31+
// npte: hardware_ticks library now provides an adapter for RP2040
32+
33+
for (int i = 0; i < (int)TICK_COUNT; ++i) {
34+
tick_start((tick_gen_num_t)i, cycles);
35+
}
36+
}
1837

1938
// Wrap the SDK's clocks_init() function to save code size
20-
void __wrap_clocks_init(void) {
21-
clocks_init_optional_usb(true);
39+
void __wrap_runtime_init_clocks(void) {
40+
runtime_init_clocks_optional_usb(true);
2241
}
2342

24-
// Copy of clocks_init() from pico-sdk, with USB
43+
// Copy of runtime_init_clocks() from pico-sdk, with USB
2544
// PLL and clock init made optional (for light sleep wakeup).
26-
void clocks_init_optional_usb(bool init_usb) {
27-
// Start tick in watchdog, the argument is in 'cycles per microsecond' i.e. MHz
28-
watchdog_start_tick(XOSC_KHZ / KHZ);
29-
30-
// Modification: removed FPGA check here
31-
45+
void runtime_init_clocks_optional_usb(bool init_usb) {
3246
// Disable resus that may be enabled from previous software
3347
clocks_hw->resus.ctrl = 0;
3448

@@ -46,14 +60,26 @@ void clocks_init_optional_usb(bool init_usb) {
4660
}
4761

4862
/// \tag::pll_init[]
49-
pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_KHZ * KHZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
63+
pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
5064
if (init_usb) {
51-
pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_KHZ * KHZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2);
65+
pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_HZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2);
5266
}
5367
/// \end::pll_init[]
5468

5569
// Configure clocks
56-
// CLK_REF = XOSC (usually) 12MHz / 1 = 12MHz
70+
71+
// todo amy, what is this N1,2,4 meant to mean?
72+
// RP2040 CLK_REF = XOSC (usually) 12MHz / 1 = 12MHz
73+
// RP2350 CLK_REF = XOSC (XOSC_MHZ) / N (1,2,4) = 12MHz
74+
75+
// clk_ref aux select is 0 because:
76+
//
77+
// - RP2040: no aux mux on clk_ref, so this field is don't-care.
78+
//
79+
// - RP2350: there is an aux mux, but we are selecting one of the
80+
// non-aux inputs to the glitchless mux, so the aux select doesn't
81+
// matter. The value of 0 here happens to be the sys PLL.
82+
5783
clock_configure(clk_ref,
5884
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC,
5985
0, // No aux mux
@@ -85,18 +111,32 @@ void clocks_init_optional_usb(bool init_usb) {
85111
USB_CLK_KHZ * KHZ,
86112
USB_CLK_KHZ * KHZ);
87113

114+
#if HAS_RP2040_RTC
88115
// CLK RTC = PLL USB 48MHz / 1024 = 46875Hz
89116
clock_configure(clk_rtc,
90117
0, // No GLMUX
91118
CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
92119
USB_CLK_KHZ * KHZ,
93120
RTC_CLOCK_FREQ_HZ);
121+
#endif
94122

95-
// CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
96-
// Normally choose clk_sys or clk_usb
123+
// CLK PERI = clk_sys. Used as reference clock for UART and SPI serial.
97124
clock_configure(clk_peri,
98125
0,
99126
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
100127
SYS_CLK_KHZ * KHZ,
101128
SYS_CLK_KHZ * KHZ);
129+
130+
#if PICO_RP2350
131+
// CLK_HSTX = clk_sys. Transmit bit clock for the HSTX peripheral.
132+
clock_configure(clk_hstx,
133+
0,
134+
CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLK_SYS,
135+
SYS_CLK_KHZ * KHZ,
136+
SYS_CLK_KHZ * KHZ);
137+
#endif
138+
139+
// Finally, all clocks are configured so start the ticks
140+
// The ticks use clk_ref so now that is configured we can start them
141+
start_all_ticks();
102142
}

ports/rp2/clocks_extra.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@
2828

2929
#include "hardware/clocks.h"
3030

31-
void clocks_init_optional_usb(bool init_usb);
31+
void runtime_init_clocks_optional_usb(bool init_usb);
3232

3333
#endif // MICROPY_INCLUDED_RP2_CLOCKS_EXTRA_H

ports/rp2/modmachine.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
259259
rosc_hw->ctrl = ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB;
260260

261261
// Bring back all clocks.
262-
clocks_init_optional_usb(disable_usb);
262+
runtime_init_clocks_optional_usb(disable_usb);
263263
MICROPY_END_ATOMIC_SECTION(my_interrupts);
264264
}
265265

0 commit comments

Comments
 (0)