Skip to content

Commit 6b30f8d

Browse files
committed
rp2: Sleep changes.
Stop using soft timer for mp_wfe_or_timeout. Now uses the alarm pool again as issues with this code have been fixed. This resolves the "sev" issue that stops the rp2 port going idle. Change the sleep code to use the hardware timer library and alarm 1 as alarm 2 is used by and soft timers and 3 is used by the alarm pool Signed-off-by: Peter Harper <[email protected]>
1 parent 3b13d7a commit 6b30f8d

File tree

2 files changed

+22
-26
lines changed

2 files changed

+22
-26
lines changed

ports/rp2/modmachine.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ static void mp_machine_idle(void) {
121121
MICROPY_INTERNAL_WFE(1);
122122
}
123123

124+
static void alarm_sleep_callback(uint alarm_id) {
125+
}
126+
124127
static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
125128
mp_int_t delay_ms = 0;
126129
bool use_timer_alarm = false;
@@ -190,22 +193,17 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
190193
// Disable ROSC.
191194
rosc_hw->ctrl = ROSC_CTRL_ENABLE_VALUE_DISABLE << ROSC_CTRL_ENABLE_LSB;
192195

196+
// pico-sdk alarm pool uses 3
197+
// micropython soft timers use 2
198+
int alarm_num = 1;
193199
if (n_args == 0) {
194200
#if MICROPY_PY_NETWORK_CYW43
195201
gpio_set_dormant_irq_enabled(CYW43_PIN_WL_HOST_WAKE, GPIO_IRQ_LEVEL_HIGH, true);
196202
#endif
197203
xosc_dormant();
198204
} else {
199-
bool timer3_enabled = irq_is_enabled(3);
200-
201-
const uint32_t alarm_num = 3;
202-
const uint32_t irq_num = TIMER_ALARM_IRQ_NUM(timer_hw, alarm_num);
205+
hardware_alarm_claim(alarm_num);
203206
if (use_timer_alarm) {
204-
// Make sure ALARM3/IRQ3 is enabled on _this_ core
205-
if (!timer3_enabled) {
206-
irq_set_enabled(irq_num, true);
207-
}
208-
hw_set_bits(&timer_hw->inte, 1u << alarm_num);
209207
// Use timer alarm to wake.
210208
clocks_hw->sleep_en0 = 0x0;
211209
#if PICO_RP2040
@@ -215,8 +213,12 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
215213
#else
216214
#error Unknown processor
217215
#endif
218-
timer_hw->intr = 1u << alarm_num; // clear any IRQ
219-
timer_hw->alarm[alarm_num] = timer_hw->timerawl + delay_ms * 1000;
216+
hardware_alarm_set_callback(alarm_num, alarm_sleep_callback);
217+
if (hardware_alarm_set_target(alarm_num, make_timeout_time_ms(delay_ms))) {
218+
hardware_alarm_set_callback(alarm_num, NULL);
219+
hardware_alarm_unclaim(alarm_num);
220+
alarm_num = -1;
221+
}
220222
} else {
221223
// TODO: Use RTC alarm to wake.
222224
clocks_hw->sleep_en0 = 0x0;
@@ -246,11 +248,10 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
246248
#endif
247249

248250
// Go into low-power mode.
249-
__wfi();
250-
251-
if (!timer3_enabled) {
252-
irq_set_enabled(irq_num, false);
251+
if (alarm_num >= 0) {
252+
__wfi();
253253
}
254+
254255
clocks_hw->sleep_en0 |= ~(0u);
255256
clocks_hw->sleep_en1 |= ~(0u);
256257
}
@@ -264,6 +265,11 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
264265

265266
// Re-sync mp_hal_time_ns() counter with aon timer.
266267
mp_hal_time_ns_set_from_rtc();
268+
if (alarm_num >= 0) {
269+
hardware_alarm_cancel(alarm_num);
270+
hardware_alarm_set_callback(alarm_num, NULL);
271+
hardware_alarm_unclaim(alarm_num);
272+
}
267273
}
268274

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

ports/rp2/mphalport.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -266,15 +266,5 @@ void soft_timer_init(void) {
266266
}
267267

268268
void mp_wfe_or_timeout(uint32_t timeout_ms) {
269-
soft_timer_entry_t timer;
270-
271-
// Note the timer doesn't have an associated callback, it just exists to create a
272-
// hardware interrupt to wake the CPU
273-
soft_timer_static_init(&timer, SOFT_TIMER_MODE_ONE_SHOT, 0, NULL);
274-
soft_timer_insert(&timer, timeout_ms);
275-
276-
__wfe();
277-
278-
// Clean up the timer node if it's not already
279-
soft_timer_remove(&timer);
269+
best_effort_wfe_or_timeout(delayed_by_ms(get_absolute_time(), timeout_ms));
280270
}

0 commit comments

Comments
 (0)