diff options
| author | iabdalkader <i.abdalkader@gmail.com> | 2025-02-03 06:54:37 +0100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2025-04-09 00:22:32 +1000 |
| commit | 039df0c884ef0169257b3ab31255be8cd45caacf (patch) | |
| tree | 40d08d9ea1b91a575892b8370d9294e838c74489 | |
| parent | ff6ed730c534a809ea32648b0b30832b2993aaae (diff) | |
alif/modmachine: Implement proper low-power modes.
Lightsleep current is around 23mA. Deepsleep current is sub 50uA.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
| -rw-r--r-- | ports/alif/alif.mk | 1 | ||||
| -rw-r--r-- | ports/alif/modmachine.c | 56 |
2 files changed, 51 insertions, 6 deletions
diff --git a/ports/alif/alif.mk b/ports/alif/alif.mk index 158145219..35f316cae 100644 --- a/ports/alif/alif.mk +++ b/ports/alif/alif.mk @@ -182,6 +182,7 @@ ALIF_SRC_C += $(addprefix $(ALIF_DFP_REL_TOP)/,\ Device/common/source/system_utils.c \ Device/common/source/tcm_partition.c \ Device/common/source/tgu_M55.c \ + Device/common/source/pm.c \ Device/core/$(MCU_CORE)/source/startup_$(MCU_CORE).c \ drivers/source/adc.c \ drivers/source/mhu_driver.c \ diff --git a/ports/alif/modmachine.c b/ports/alif/modmachine.c index b77a207fe..98d7bffba 100644 --- a/ports/alif/modmachine.c +++ b/ports/alif/modmachine.c @@ -28,6 +28,9 @@ // extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE. #include "se_services.h" +#include "tusb.h" + +extern void dcd_uninit(void); #define MICROPY_PY_MACHINE_EXTRA_GLOBALS \ { MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \ @@ -70,15 +73,56 @@ static void mp_machine_set_freq(size_t n_args, const mp_obj_t *args) { mp_raise_NotImplementedError(NULL); } -static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { - mp_int_t delay = -1; - if (n_args == 1) { - delay = mp_obj_get_int(args[0]); +#if MICROPY_HW_ENABLE_USBDEV +static void mp_machine_enable_usb(bool enable) { + if (enable) { + // Initialize TinyUSB and DCD. + tusb_init(); + } else { + // Disconnect USB device. + tud_disconnect(); + // Deinitialize TinyUSB. + tud_deinit(TUD_OPT_RHPORT); + // Deinitialize DCD (disables IRQs). + dcd_uninit(); } - mp_hal_delay_ms(delay); +} +#endif + +static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { + #if MICROPY_HW_ENABLE_USBDEV + mp_machine_enable_usb(false); + #endif + + #ifdef MICROPY_BOARD_ENTER_STANDBY + MICROPY_BOARD_ENTER_STANDBY(); + #endif + + // This enters the deepest possible CPU sleep state, without + // losing CPU state. CPU and subsystem power will remain on. + pm_core_enter_deep_sleep(); + + #ifdef MICROPY_BOARD_EXIT_STANDBY + MICROPY_BOARD_EXIT_STANDBY(); + #endif + + #if MICROPY_HW_ENABLE_USBDEV + mp_machine_enable_usb(true); + #endif } NORETURN static void mp_machine_deepsleep(size_t n_args, const mp_obj_t *args) { - mp_machine_lightsleep(n_args, args); + #if MICROPY_HW_ENABLE_USBDEV + mp_machine_enable_usb(false); + #endif + + #ifdef MICROPY_BOARD_ENTER_STOP + MICROPY_BOARD_ENTER_STOP(); + #endif + + // If power is removed from the subsystem, the function does + // not return, and the CPU will reboot when/if the subsystem + // is next powered up. + pm_core_enter_deep_sleep_request_subsys_off(); mp_machine_reset(); } |
