Skip to content

Commit 19844b4

Browse files
mungewelldpgeorge
authored andcommitted
rp2/modmachine: Prevent lock-up when lightsleep() called within thread.
When `lightsleep()` is called from within a thread the interrupts may not be enabled on current core, and thus the call to `lightsleep()` never completes. Fixes issue #14092. Signed-off-by: Simon Wood <simon@mungewell.org>
1 parent f76cf29 commit 19844b4

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

ports/rp2/modmachine.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
127127

128128
const uint32_t xosc_hz = XOSC_MHZ * 1000000;
129129

130-
uint32_t my_interrupts = save_and_disable_interrupts();
130+
uint32_t my_interrupts = mp_thread_begin_atomic_section();
131131
#if MICROPY_PY_NETWORK_CYW43
132132
if (cyw43_has_pending && cyw43_poll != NULL) {
133-
restore_interrupts(my_interrupts);
133+
mp_thread_end_atomic_section(my_interrupts);
134134
return;
135135
}
136136
#endif
@@ -165,8 +165,15 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
165165
} else {
166166
uint32_t sleep_en0 = clocks_hw->sleep_en0;
167167
uint32_t sleep_en1 = clocks_hw->sleep_en1;
168+
bool timer3_enabled = irq_is_enabled(3);
169+
168170
clocks_hw->sleep_en0 = CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS;
169171
if (use_timer_alarm) {
172+
// Make sure ALARM3/IRQ3 is enabled on _this_ core
173+
timer_hw->inte |= 1 << 3;
174+
if (!timer3_enabled) {
175+
irq_set_enabled(3, true);
176+
}
170177
// Use timer alarm to wake.
171178
clocks_hw->sleep_en1 = CLOCKS_SLEEP_EN1_CLK_SYS_TIMER_BITS;
172179
timer_hw->alarm[3] = timer_hw->timerawl + delay_ms * 1000;
@@ -177,6 +184,9 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
177184
scb_hw->scr |= M0PLUS_SCR_SLEEPDEEP_BITS;
178185
__wfi();
179186
scb_hw->scr &= ~M0PLUS_SCR_SLEEPDEEP_BITS;
187+
if (!timer3_enabled) {
188+
irq_set_enabled(3, false);
189+
}
180190
clocks_hw->sleep_en0 = sleep_en0;
181191
clocks_hw->sleep_en1 = sleep_en1;
182192
}
@@ -186,7 +196,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
186196

187197
// Bring back all clocks.
188198
clocks_init();
189-
restore_interrupts(my_interrupts);
199+
mp_thread_end_atomic_section(my_interrupts);
190200
}
191201

192202
NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy