rp2/modmachine: Implement lightsleep for RP2350.
This isn't fully working, the CPU often wakes up early. That will be fixed when a newer version of pico-sdk is released. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
c90d996c9d
commit
d1423ef7a2
@ -162,6 +162,9 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
|
||||
}
|
||||
|
||||
clock_stop(clk_adc);
|
||||
#if PICO_RP2350
|
||||
clock_stop(clk_hstx);
|
||||
#endif
|
||||
|
||||
// CLK_REF = XOSC
|
||||
clock_configure(clk_ref, CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC, 0, xosc_hz, xosc_hz);
|
||||
@ -170,7 +173,9 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
|
||||
clock_configure(clk_sys, CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLK_REF, 0, xosc_hz, xosc_hz);
|
||||
|
||||
// CLK_RTC = XOSC / 256
|
||||
#if PICO_RP2040
|
||||
clock_configure(clk_rtc, 0, CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_XOSC_CLKSRC, xosc_hz, xosc_hz / 256);
|
||||
#endif
|
||||
|
||||
// CLK_PERI = CLK_SYS
|
||||
clock_configure(clk_peri, 0, CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, xosc_hz, xosc_hz);
|
||||
@ -190,38 +195,63 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
|
||||
#endif
|
||||
xosc_dormant();
|
||||
} else {
|
||||
uint32_t sleep_en0 = clocks_hw->sleep_en0;
|
||||
uint32_t sleep_en1 = clocks_hw->sleep_en1;
|
||||
bool timer3_enabled = irq_is_enabled(3);
|
||||
|
||||
clocks_hw->sleep_en0 = CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS;
|
||||
const uint32_t alarm_num = 3;
|
||||
const uint32_t irq_num = TIMER_ALARM_IRQ_NUM(timer_hw, alarm_num);
|
||||
if (use_timer_alarm) {
|
||||
// Make sure ALARM3/IRQ3 is enabled on _this_ core
|
||||
timer_hw->inte |= 1 << 3;
|
||||
if (!timer3_enabled) {
|
||||
irq_set_enabled(3, true);
|
||||
irq_set_enabled(irq_num, true);
|
||||
}
|
||||
hw_set_bits(&timer_hw->inte, 1u << alarm_num);
|
||||
// Use timer alarm to wake.
|
||||
clocks_hw->sleep_en0 = 0x0;
|
||||
#if PICO_RP2040
|
||||
clocks_hw->sleep_en1 = CLOCKS_SLEEP_EN1_CLK_SYS_TIMER_BITS;
|
||||
timer_hw->alarm[3] = timer_hw->timerawl + delay_ms * 1000;
|
||||
#elif PICO_RP2350
|
||||
clocks_hw->sleep_en1 = CLOCKS_SLEEP_EN1_CLK_REF_TICKS_BITS | CLOCKS_SLEEP_EN1_CLK_SYS_TIMER0_BITS;
|
||||
#else
|
||||
#error Unknown processor
|
||||
#endif
|
||||
timer_hw->intr = 1u << alarm_num; // clear any IRQ
|
||||
timer_hw->alarm[alarm_num] = timer_hw->timerawl + delay_ms * 1000;
|
||||
} else {
|
||||
// TODO: Use RTC alarm to wake.
|
||||
clocks_hw->sleep_en1 = 0;
|
||||
clocks_hw->sleep_en0 = 0x0;
|
||||
clocks_hw->sleep_en1 = 0x0;
|
||||
}
|
||||
|
||||
if (!disable_usb) {
|
||||
clocks_hw->sleep_en0 |= CLOCKS_SLEEP_EN0_CLK_SYS_PLL_USB_BITS;
|
||||
#if PICO_RP2040
|
||||
clocks_hw->sleep_en1 |= CLOCKS_SLEEP_EN1_CLK_USB_USBCTRL_BITS;
|
||||
#elif PICO_RP2350
|
||||
clocks_hw->sleep_en1 |= CLOCKS_SLEEP_EN1_CLK_SYS_USBCTRL_BITS;
|
||||
#else
|
||||
#error Unknown processor
|
||||
#endif
|
||||
}
|
||||
|
||||
#if PICO_ARM
|
||||
// Configure SLEEPDEEP bits on Cortex-M CPUs.
|
||||
#if PICO_RP2040
|
||||
scb_hw->scr |= M0PLUS_SCR_SLEEPDEEP_BITS;
|
||||
#elif PICO_RP2350
|
||||
scb_hw->scr |= M33_SCR_SLEEPDEEP_BITS;
|
||||
#else
|
||||
#error Unknown processor
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Go into low-power mode.
|
||||
__wfi();
|
||||
scb_hw->scr &= ~M0PLUS_SCR_SLEEPDEEP_BITS;
|
||||
|
||||
if (!timer3_enabled) {
|
||||
irq_set_enabled(3, false);
|
||||
irq_set_enabled(irq_num, false);
|
||||
}
|
||||
clocks_hw->sleep_en0 = sleep_en0;
|
||||
clocks_hw->sleep_en1 = sleep_en1;
|
||||
clocks_hw->sleep_en0 |= ~(0u);
|
||||
clocks_hw->sleep_en1 |= ~(0u);
|
||||
}
|
||||
|
||||
// Enable ROSC.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user