diff options
| -rw-r--r-- | ports/rp2/modmachine.c | 35 | ||||
| -rw-r--r-- | ports/rp2/mpconfigport.h | 3 | ||||
| -rw-r--r-- | ports/rp2/mphalport.c | 12 |
3 files changed, 23 insertions, 27 deletions
diff --git a/ports/rp2/modmachine.c b/ports/rp2/modmachine.c index 58a3a8ae4..742d20f1f 100644 --- a/ports/rp2/modmachine.c +++ b/ports/rp2/modmachine.c @@ -137,6 +137,9 @@ static void mp_machine_idle(void) { MICROPY_INTERNAL_WFE(1); } +static void alarm_sleep_callback(uint alarm_id) { +} + static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { mp_int_t delay_ms = 0; bool use_timer_alarm = false; @@ -206,6 +209,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { // Disable ROSC. rosc_hw->ctrl = ROSC_CTRL_ENABLE_VALUE_DISABLE << ROSC_CTRL_ENABLE_LSB; + bool alarm_armed = false; if (n_args == 0) { #if MICROPY_PY_NETWORK_CYW43 gpio_set_dormant_irq_enabled(CYW43_PIN_WL_HOST_WAKE, GPIO_IRQ_LEVEL_HIGH, true); @@ -214,16 +218,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { } else { uint32_t save_sleep_en0 = clocks_hw->sleep_en0; uint32_t save_sleep_en1 = clocks_hw->sleep_en1; - bool timer3_enabled = irq_is_enabled(3); - - 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 - if (!timer3_enabled) { - 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 @@ -233,8 +228,11 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { #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; + hardware_alarm_claim(MICROPY_HW_LIGHTSLEEP_ALARM_NUM); + hardware_alarm_set_callback(MICROPY_HW_LIGHTSLEEP_ALARM_NUM, alarm_sleep_callback); + if (hardware_alarm_set_target(MICROPY_HW_LIGHTSLEEP_ALARM_NUM, make_timeout_time_ms(delay_ms)) == PICO_OK) { + alarm_armed = true; + } } else { // TODO: Use RTC alarm to wake. clocks_hw->sleep_en0 = 0x0; @@ -264,10 +262,8 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { #endif // Go into low-power mode. - __wfi(); - - if (!timer3_enabled) { - irq_set_enabled(irq_num, false); + if (alarm_armed) { + __wfi(); } clocks_hw->sleep_en0 = save_sleep_en0; clocks_hw->sleep_en1 = save_sleep_en1; @@ -282,6 +278,15 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { // Re-sync mp_hal_time_ns() counter with aon timer. mp_hal_time_ns_set_from_rtc(); + + // Note: This must be done after MICROPY_END_ATOMIC_SECTION + if (use_timer_alarm) { + if (alarm_armed) { + hardware_alarm_cancel(MICROPY_HW_LIGHTSLEEP_ALARM_NUM); + } + hardware_alarm_set_callback(MICROPY_HW_LIGHTSLEEP_ALARM_NUM, NULL); + hardware_alarm_unclaim(MICROPY_HW_LIGHTSLEEP_ALARM_NUM); + } } NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) { diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index 3d6573726..877cea087 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -198,8 +198,9 @@ #define MICROPY_PY_LWIP_SOCK_RAW (MICROPY_PY_LWIP) // Hardware timer alarm index. Available range 0-3. -// Number 3 is currently used by pico-sdk (PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM) +// Number 3 is currently used by pico-sdk alarm pool (PICO_TIME_DEFAULT_ALARM_POOL_HARDWARE_ALARM_NUM) #define MICROPY_HW_SOFT_TIMER_ALARM_NUM (2) +#define MICROPY_HW_LIGHTSLEEP_ALARM_NUM (1) // fatfs configuration #define MICROPY_FATFS_ENABLE_LFN (2) diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c index caecb6950..b581b3b59 100644 --- a/ports/rp2/mphalport.c +++ b/ports/rp2/mphalport.c @@ -266,17 +266,7 @@ void soft_timer_init(void) { } void mp_wfe_or_timeout(uint32_t timeout_ms) { - soft_timer_entry_t timer; - - // Note the timer doesn't have an associated callback, it just exists to create a - // hardware interrupt to wake the CPU - soft_timer_static_init(&timer, SOFT_TIMER_MODE_ONE_SHOT, 0, NULL); - soft_timer_insert(&timer, timeout_ms); - - __wfe(); - - // Clean up the timer node if it's not already - soft_timer_remove(&timer); + best_effort_wfe_or_timeout(delayed_by_ms(get_absolute_time(), timeout_ms)); } int mp_hal_is_pin_reserved(int n) { |
