diff --git a/src/rp2040/hardware_regs/include/hardware/regs/clocks.h b/src/rp2040/hardware_regs/include/hardware/regs/clocks.h index c0d2eab..9e7b7b8 100644 --- a/src/rp2040/hardware_regs/include/hardware/regs/clocks.h +++ b/src/rp2040/hardware_regs/include/hardware/regs/clocks.h @@ -1835,6 +1835,37 @@ #define CLOCKS_SLEEP_EN0_CLK_SYS_CLOCKS_MSB _u(0) #define CLOCKS_SLEEP_EN0_CLK_SYS_CLOCKS_LSB _u(0) #define CLOCKS_SLEEP_EN0_CLK_SYS_CLOCKS_ACCESS "RW" +// ----------------------------------------------------------------------------- +// Description : Clocks which are dependant on CLK_SYS +#define CLOCKS_SLEEP_EN0_CLK_SYS_DEPENDANTS_BITS ( \ + CLOCKS_SLEEP_EN0_CLK_SYS_SRAM3_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_SRAM2_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_SRAM1_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_SRAM0_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_SPI1_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_SPI0_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_SIO_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_RTC_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_ROSC_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_ROM_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_RESETS_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PWM_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PSM_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PLL_USB_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PLL_SYS_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PIO1_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PIO0_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_PADS_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_VREG_AND_CHIP_RESET_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_JTAG_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_IO_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_I2C1_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_I2C0_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_DMA_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_BUSFABRIC_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_BUSCTRL_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_ADC_BITS | \ + CLOCKS_SLEEP_EN0_CLK_SYS_CLOCKS_BITS ) // ============================================================================= // Register : CLOCKS_SLEEP_EN1 // Description : enable clock in sleep mode @@ -1961,6 +1992,21 @@ #define CLOCKS_SLEEP_EN1_CLK_SYS_SRAM4_MSB _u(0) #define CLOCKS_SLEEP_EN1_CLK_SYS_SRAM4_LSB _u(0) #define CLOCKS_SLEEP_EN1_CLK_SYS_SRAM4_ACCESS "RW" +// ----------------------------------------------------------------------------- +// Description : Clocks which are dependant on CLK_SYS +#define CLOCKS_SLEEP_EN1_CLK_SYS_DEPENDANTS_BITS ( \ + CLOCKS_SLEEP_EN1_CLK_SYS_XOSC_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_XIP_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_WATCHDOG_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_USBCTRL_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_UART1_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_UART0_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_TIMER_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_TBMAN_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_SYSINFO_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_SYSCFG_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_SRAM5_BITS | \ + CLOCKS_SLEEP_EN1_CLK_SYS_SRAM4_BITS ) // ============================================================================= // Register : CLOCKS_ENABLED0 // Description : indicates the state of the clock enable diff --git a/src/rp2_common/hardware_clocks/clocks.c b/src/rp2_common/hardware_clocks/clocks.c index ad1eaeb..f30b2d9 100644 --- a/src/rp2_common/hardware_clocks/clocks.c +++ b/src/rp2_common/hardware_clocks/clocks.c @@ -118,7 +118,7 @@ bool clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc, } /// \end::clock_configure[] -void clocks_init(void) { +void clocks_init(uint32_t sleep_en0, uint32_t sleep_en1) { // Start tick in watchdog, the argument is in 'cycles per microsecond' i.e. MHz watchdog_start_tick(XOSC_KHZ / KHZ); @@ -138,15 +138,20 @@ void clocks_init(void) { xosc_init(); // Before we touch PLLs, switch sys and ref cleanly away from their aux sources. - hw_clear_bits(&clocks_hw->clk[clk_sys].ctrl, CLOCKS_CLK_SYS_CTRL_SRC_BITS); - while (clocks_hw->clk[clk_sys].selected != 0x1) - tight_loop_contents(); + if (((sleep_en0 & CLOCKS_SLEEP_EN0_CLK_SYS_DEPENDANTS_BITS) == 0) & + ((sleep_en1 & CLOCKS_SLEEP_EN1_CLK_SYS_DEPENDANTS_BITS) == 0)) { + hw_clear_bits(&clocks_hw->clk[clk_sys].ctrl, CLOCKS_CLK_SYS_CTRL_SRC_BITS); + while (clocks_hw->clk[clk_sys].selected != 0x1) + tight_loop_contents(); + } hw_clear_bits(&clocks_hw->clk[clk_ref].ctrl, CLOCKS_CLK_REF_CTRL_SRC_BITS); while (clocks_hw->clk[clk_ref].selected != 0x1) tight_loop_contents(); /// \tag::pll_init[] - pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_KHZ * KHZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2); + if (((sleep_en0 & CLOCKS_SLEEP_EN0_CLK_SYS_DEPENDANTS_BITS) == 0) & + ((sleep_en1 & CLOCKS_SLEEP_EN1_CLK_SYS_DEPENDANTS_BITS) == 0)) + pll_init(pll_sys, PLL_COMMON_REFDIV, PLL_SYS_VCO_FREQ_KHZ * KHZ, PLL_SYS_POSTDIV1, PLL_SYS_POSTDIV2); pll_init(pll_usb, PLL_COMMON_REFDIV, PLL_USB_VCO_FREQ_KHZ * KHZ, PLL_USB_POSTDIV1, PLL_USB_POSTDIV2); /// \end::pll_init[] @@ -160,11 +165,14 @@ void clocks_init(void) { /// \tag::configure_clk_sys[] // CLK SYS = PLL SYS (usually) 125MHz / 1 = 125MHz - clock_configure(clk_sys, - CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, - CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, - SYS_CLK_KHZ * KHZ, - SYS_CLK_KHZ * KHZ); + if (((sleep_en0 & CLOCKS_SLEEP_EN0_CLK_SYS_DEPENDANTS_BITS) == 0) & + ((sleep_en1 & CLOCKS_SLEEP_EN1_CLK_SYS_DEPENDANTS_BITS) == 0)) { + clock_configure(clk_sys, + CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, + CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, + SYS_CLK_KHZ * KHZ, + SYS_CLK_KHZ * KHZ); + } /// \end::configure_clk_sys[] // CLK USB = PLL USB 48MHz / 1 = 48MHz diff --git a/src/rp2_common/hardware_clocks/include/hardware/clocks.h b/src/rp2_common/hardware_clocks/include/hardware/clocks.h index 66adefc..ddc4c45 100644 --- a/src/rp2_common/hardware_clocks/include/hardware/clocks.h +++ b/src/rp2_common/hardware_clocks/include/hardware/clocks.h @@ -163,7 +163,7 @@ extern "C" { * * Must be called before any other clock function. */ -void clocks_init(void); +void clocks_init(uint32_t sleep_en0, uint32_t sleep_en1); /*! \brief Configure the specified clock * \ingroup hardware_clocks diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index 144ace1..d32e5e2 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -107,7 +107,7 @@ void runtime_init(void) { // After calling preinit we have enough runtime to do the exciting maths // in clocks_init - clocks_init(); + clocks_init(0, 0); // Peripheral clocks should now all be running unreset_block_wait(RESETS_RESET_BITS);