Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

power.deep_sleep() without wake up sources does not go to sleep #126

Closed
microbit-carlos opened this issue Sep 20, 2022 · 5 comments
Closed
Milestone

Comments

@microbit-carlos
Copy link
Contributor

microbit-carlos commented Sep 20, 2022

This might be related to this CODAL issue:

However, based on the latest conversations with @JohnVidler we were thinking the issue might be in the MakeCode extension instead of CODAL.

However, in MicroPython executing power.deep_sleep() doesn't go to sleep either. Having a brief look the MicroPython code I can't see an obvious reason why it might not go to sleep if it's supported within CODAL itself:

STATIC mp_obj_t power_deep_sleep(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_ms, ARG_wake_on, ARG_run_every };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_ms, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_wake_on, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
{ MP_QSTR_run_every, MP_ARG_BOOL, {.u_bool = false} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
microbit_hal_power_clear_wake_sources();
// Configure wake-up time, if given.
bool wake_on_ms = false;
uint32_t wake_ms = UINT32_MAX;
if (args[ARG_ms].u_obj != mp_const_none) {
wake_on_ms = true;
wake_ms = mp_obj_get_int(args[ARG_ms].u_obj);
}
// Configure wake-up sources.
mp_obj_t *items;
size_t len = get_array(&args[ARG_wake_on].u_obj, &items);
for (size_t i = 0; i < len; ++i) {
const mp_obj_type_t *type = mp_obj_get_type(items[i]);
if (microbit_obj_type_is_button(type)) {
microbit_hal_power_wake_on_button(microbit_obj_get_button_id(items[i]), true);
} else if (microbit_obj_type_is_pin(type)) {
microbit_hal_power_wake_on_pin(microbit_obj_get_pin_name(items[i]), true);
} else {
mp_raise_ValueError(MP_ERROR_TEXT("expecting a pin or button"));
}
}
// If run_every is true then check if any soft timers will expire and need to wake the device.
if (args[ARG_run_every].u_bool) {
microbit_soft_timer_set_pause(true);
uint32_t ms = microbit_soft_timer_get_ms_to_next_expiry();
if (ms != UINT32_MAX) {
// A soft timer will expire in "ms" milliseconds.
wake_on_ms = true;
if (ms < wake_ms) {
wake_ms = ms;
}
}
}
// Enter low power state.
microbit_hal_power_deep_sleep(wake_on_ms, wake_ms);
// Resume soft timer (doesn't hurt to resume even if it wasn't paused).
microbit_soft_timer_set_pause(false);
return mp_const_none;
}

void microbit_hal_power_deep_sleep(bool wake_on_ms, uint32_t ms) {
if (wake_on_ms) {
uBit.power.deepSleep(ms, true);
} else {
uBit.power.deepSleep();
}
}

Example programme to replicate with MicroPython v2.1.0-beta.3:

from microbit import *
import power

while True:
    power.deep_sleep()
    display.show(Image.SURPRISED)
    sleep(500)

This always shows the SURPRISED face and doesn't go to sleep

@dpgeorge
Copy link
Collaborator

I think this is a "feature" of the CODAL: if there are no wake up sources configured, and no timeout, then the deepSleep() call returns immediately (presumably to prevent infinite waits that cannot be interrupted, requiring a reflash of the microbit to recover).

@dpgeorge
Copy link
Collaborator

We could fix this on the MicroPython side by just calling the CODAL deepSleep(ms, true) with a large timeout, and keep calling it in a loop forever.

@microbit-carlos
Copy link
Contributor Author

This has been changed/fixed in the CODAL side in this PR, so we can just wait for the next tag to get the fix:

@microbit-carlos
Copy link
Contributor Author

This is resolved in CODAL v0.2.43, we can close it when #132 is merged, or a different commit updates CODAL in the main branch.

@dpgeorge
Copy link
Collaborator

CODAL v0.2.43 is updated here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants