summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/rp2/CMakeLists.txt3
-rw-r--r--ports/rp2/clocks_extra.c68
-rw-r--r--ports/rp2/clocks_extra.h2
-rw-r--r--ports/rp2/modmachine.c2
4 files changed, 58 insertions, 17 deletions
diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt
index 0d5b10f33..40672a8b3 100644
--- a/ports/rp2/CMakeLists.txt
+++ b/ports/rp2/CMakeLists.txt
@@ -181,6 +181,7 @@ set(PICO_SDK_COMPONENTS
cmsis_core
hardware_adc
hardware_base
+ hardware_boot_lock
hardware_clocks
hardware_dma
hardware_flash
@@ -487,7 +488,7 @@ target_compile_options(${MICROPY_TARGET} PRIVATE
target_link_options(${MICROPY_TARGET} PRIVATE
-Wl,--defsym=__micropy_c_heap_size__=${MICROPY_C_HEAP_SIZE}
-Wl,--wrap=dcd_event_handler
- -Wl,--wrap=clocks_init
+ -Wl,--wrap=runtime_init_clocks
)
# Apply optimisations to performance-critical source code.
diff --git a/ports/rp2/clocks_extra.c b/ports/rp2/clocks_extra.c
index e2c97962c..73def24b8 100644
--- a/ports/rp2/clocks_extra.c
+++ b/ports/rp2/clocks_extra.c
@@ -13,22 +13,36 @@
#include "hardware/xosc.h"
#include "hardware/irq.h"
#include "hardware/gpio.h"
+#include "hardware/ticks.h"
+#if PICO_RP2040
+// The RTC clock frequency is 48MHz divided by power of 2 (to ensure an integer
+// division ratio will be used in the clocks block). A divisor of 1024 generates
+// an RTC clock tick of 46875Hz. This frequency is relatively close to the
+// customary 32 or 32.768kHz 'slow clock' crystals and provides good timing resolution.
#define RTC_CLOCK_FREQ_HZ (USB_CLK_KHZ * KHZ / 1024)
+#endif
+
+static void start_all_ticks(void) {
+ uint32_t cycles = clock_get_hz(clk_ref) / MHZ;
+ // Note RP2040 has a single tick generator in the watchdog which serves
+ // watchdog, system timer and M0+ SysTick; The tick generator is clocked from clk_ref
+ // but is now adapted by the hardware_ticks library for compatibility with RP2350
+ // npte: hardware_ticks library now provides an adapter for RP2040
+
+ for (int i = 0; i < (int)TICK_COUNT; ++i) {
+ tick_start((tick_gen_num_t)i, cycles);
+ }
+}
// Wrap the SDK's clocks_init() function to save code size
-void __wrap_clocks_init(void) {
- clocks_init_optional_usb(true);
+void __wrap_runtime_init_clocks(void) {
+ runtime_init_clocks_optional_usb(true);
}
-// Copy of clocks_init() from pico-sdk, with USB
+// Copy of runtime_init_clocks() from pico-sdk, with USB
// PLL and clock init made optional (for light sleep wakeup).
-void clocks_init_optional_usb(bool init_usb) {
- // Start tick in watchdog, the argument is in 'cycles per microsecond' i.e. MHz
- watchdog_start_tick(XOSC_KHZ / KHZ);
-
- // Modification: removed FPGA check here
-
+void runtime_init_clocks_optional_usb(bool init_usb) {
// Disable resus that may be enabled from previous software
clocks_hw->resus.ctrl = 0;
@@ -46,14 +60,26 @@ void clocks_init_optional_usb(bool init_usb) {
}
/// \tag::pll_init[]
- pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_KHZ * KHZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
+ pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_HZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2);
if (init_usb) {
- pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_KHZ * KHZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2);
+ pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_HZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2);
}
/// \end::pll_init[]
// Configure clocks
- // CLK_REF = XOSC (usually) 12MHz / 1 = 12MHz
+
+ // todo amy, what is this N1,2,4 meant to mean?
+ // RP2040 CLK_REF = XOSC (usually) 12MHz / 1 = 12MHz
+ // RP2350 CLK_REF = XOSC (XOSC_MHZ) / N (1,2,4) = 12MHz
+
+ // clk_ref aux select is 0 because:
+ //
+ // - RP2040: no aux mux on clk_ref, so this field is don't-care.
+ //
+ // - RP2350: there is an aux mux, but we are selecting one of the
+ // non-aux inputs to the glitchless mux, so the aux select doesn't
+ // matter. The value of 0 here happens to be the sys PLL.
+
clock_configure(clk_ref,
CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC,
0, // No aux mux
@@ -85,18 +111,32 @@ void clocks_init_optional_usb(bool init_usb) {
USB_CLK_KHZ * KHZ,
USB_CLK_KHZ * KHZ);
+ #if HAS_RP2040_RTC
// CLK RTC = PLL USB 48MHz / 1024 = 46875Hz
clock_configure(clk_rtc,
0, // No GLMUX
CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
USB_CLK_KHZ * KHZ,
RTC_CLOCK_FREQ_HZ);
+ #endif
- // CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable
- // Normally choose clk_sys or clk_usb
+ // CLK PERI = clk_sys. Used as reference clock for UART and SPI serial.
clock_configure(clk_peri,
0,
CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS,
SYS_CLK_KHZ * KHZ,
SYS_CLK_KHZ * KHZ);
+
+ #if PICO_RP2350
+ // CLK_HSTX = clk_sys. Transmit bit clock for the HSTX peripheral.
+ clock_configure(clk_hstx,
+ 0,
+ CLOCKS_CLK_HSTX_CTRL_AUXSRC_VALUE_CLK_SYS,
+ SYS_CLK_KHZ * KHZ,
+ SYS_CLK_KHZ * KHZ);
+ #endif
+
+ // Finally, all clocks are configured so start the ticks
+ // The ticks use clk_ref so now that is configured we can start them
+ start_all_ticks();
}
diff --git a/ports/rp2/clocks_extra.h b/ports/rp2/clocks_extra.h
index 40f77f53b..7d630e508 100644
--- a/ports/rp2/clocks_extra.h
+++ b/ports/rp2/clocks_extra.h
@@ -28,6 +28,6 @@
#include "hardware/clocks.h"
-void clocks_init_optional_usb(bool init_usb);
+void runtime_init_clocks_optional_usb(bool init_usb);
#endif // MICROPY_INCLUDED_RP2_CLOCKS_EXTRA_H
diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c
index 798078faf..2faf0bc6f 100644
--- a/ports/rp2/modmachine.c
+++ b/ports/rp2/modmachine.c
@@ -259,7 +259,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
rosc_hw->ctrl = ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB;
// Bring back all clocks.
- clocks_init_optional_usb(disable_usb);
+ runtime_init_clocks_optional_usb(disable_usb);
MICROPY_END_ATOMIC_SECTION(my_interrupts);
}