Fix RP2040 idle

Don't idle from main if we scheduled an interrupt for 0 ticks in
the future.

Have RP2040 detect wakes that happen between setting the timer and
the idle call.

Fixes #7361
This commit is contained in:
Scott Shawcroft 2023-04-21 15:59:11 -07:00
parent d078bc3ae1
commit b59f0e17be
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
2 changed files with 12 additions and 3 deletions

8
main.c
View File

@ -716,10 +716,16 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) {
// time_to_next_change is in ms and ticks are slightly shorter so // time_to_next_change is in ms and ticks are slightly shorter so
// we'll undersleep just a little. It shouldn't matter. // we'll undersleep just a little. It shouldn't matter.
if (time_to_next_change > 0) {
port_interrupt_after_ticks(time_to_next_change); port_interrupt_after_ticks(time_to_next_change);
#endif
port_idle_until_interrupt(); port_idle_until_interrupt();
} }
#else
// No status LED can we sleep until we are interrupted by some
// interaction.
port_idle_until_interrupt();
#endif
}
} }
// Done waiting, start the board back up. // Done waiting, start the board back up.

View File

@ -257,6 +257,7 @@ uint32_t port_get_saved_word(void) {
} }
static volatile bool ticks_enabled; static volatile bool ticks_enabled;
static volatile bool _woken_up;
uint64_t port_get_raw_ticks(uint8_t *subticks) { uint64_t port_get_raw_ticks(uint8_t *subticks) {
uint64_t microseconds = time_us_64(); uint64_t microseconds = time_us_64();
@ -268,6 +269,7 @@ STATIC void _tick_callback(uint alarm_num) {
supervisor_tick(); supervisor_tick();
hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977)); hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), 977));
} }
_woken_up = true;
} }
// Enable 1/1024 second tick. // Enable 1/1024 second tick.
@ -291,11 +293,12 @@ void port_interrupt_after_ticks(uint32_t ticks) {
if (!ticks_enabled) { if (!ticks_enabled) {
hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), ticks * 977)); hardware_alarm_set_target(0, delayed_by_us(get_absolute_time(), ticks * 977));
} }
_woken_up = false;
} }
void port_idle_until_interrupt(void) { void port_idle_until_interrupt(void) {
common_hal_mcu_disable_interrupts(); common_hal_mcu_disable_interrupts();
if (!background_callback_pending() && !tud_task_event_ready()) { if (!background_callback_pending() && !tud_task_event_ready() && !_woken_up) {
__DSB(); __DSB();
__WFI(); __WFI();
} }