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>
This commit is contained in:
iabdalkader
2025-02-03 06:54:37 +01:00
committed by Damien George
parent ff6ed730c5
commit 039df0c884
2 changed files with 51 additions and 6 deletions

View File

@@ -182,6 +182,7 @@ ALIF_SRC_C += $(addprefix $(ALIF_DFP_REL_TOP)/,\
Device/common/source/system_utils.c \ Device/common/source/system_utils.c \
Device/common/source/tcm_partition.c \ Device/common/source/tcm_partition.c \
Device/common/source/tgu_M55.c \ Device/common/source/tgu_M55.c \
Device/common/source/pm.c \
Device/core/$(MCU_CORE)/source/startup_$(MCU_CORE).c \ Device/core/$(MCU_CORE)/source/startup_$(MCU_CORE).c \
drivers/source/adc.c \ drivers/source/adc.c \
drivers/source/mhu_driver.c \ drivers/source/mhu_driver.c \

View File

@@ -28,6 +28,9 @@
// extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE. // extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE.
#include "se_services.h" #include "se_services.h"
#include "tusb.h"
extern void dcd_uninit(void);
#define MICROPY_PY_MACHINE_EXTRA_GLOBALS \ #define MICROPY_PY_MACHINE_EXTRA_GLOBALS \
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&machine_pin_type) }, \ { 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); mp_raise_NotImplementedError(NULL);
} }
static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) { #if MICROPY_HW_ENABLE_USBDEV
mp_int_t delay = -1; static void mp_machine_enable_usb(bool enable) {
if (n_args == 1) { if (enable) {
delay = mp_obj_get_int(args[0]); // 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) { 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(); mp_machine_reset();
} }