mirror of
https://github.com/micropython/micropython.git
synced 2025-12-15 17:30:14 +01:00
rp2: Use pico-sdk alarm pool instead of soft timer for sleep.
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 RP2350 going idle. Also, change the lightsleep code to use the hardware timer library and alarm 1, as alarm 2 is used by and soft timers and alarm 3 is used by the alarm pool. Signed-off-by: Peter Harper <peter.harper@raspberrypi.com>
This commit is contained in:
committed by
Damien George
parent
a05766f47b
commit
ee2c78cd97
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user