Wakeup Source

The following table lists the wakeup sources that can be used to wake up the system under different power modes.

Wakeup sources

Wakeup source

Sleep CG

Sleep PG

Deep-sleep

Restriction

WLAN

X

BT

X

IPC

X

Only KM0 can use the IPC to wake up KM4.

Basic Timer4~7

X

PMC Timer

X

For internal usage

UART0~2

X

  • When using UART as a wakeup source, the Rx clock source can only be OSC2M, and do not turn off OSC4M during sleep.

  • When the baudrate is larger than 115200, it is not recommended to use UART as a wakeup source.

  • The portion of the command used to wake up that exceeds the FIFO depth (64B) will be lost.

LOGUART

X

When using LOGUART as a wakeup source:

  • If the Rx clock source is XTAL40M, do not turn off XTAL or OSC4M during sleep.

  • If the Rx clock source is OSC2M, do not turn off OSC4M during sleep.

  • The portion of the command used to wake up that exceeds the FIFO depth (16B) will be lost.

GPIO

X

I2C

X

CAP_TOUCH

X

ADC

X

SDIO

X

Key-Scan

X

BOR

PWR_DOWN

AON_TIMER

AON_WAKEPIN

RTC

Entering Sleep Mode

Sleep mode is based on FreeRTOS tickless, thus it is recommended to enter sleep mode by releasing the wakelock.

  1. Initialize the specific peripheral.

  2. Enable and register the peripheral’s interrupt.

  3. Set sleep_wevent_config[] in ambea_sleepcfg.c, and the interrupt should be registered on the same CPU selected by sleep_wevent_config[].

  4. For peripherals that need special clock settings, set ps_config[] in ameba_sleepcfg.c if needed.

  5. Register sleep/wakeup callback if needed.

  6. Enter sleep mode by releasing the wakelock in KM4 (PMU_OS needs to be released since it is acquired by default when boot).

  7. Clear the peripheral’s interrupt when wakeup.

For peripherals that need specific clock settings, such as UART and LOGUART, their setting flows are described in Section UART and LOGUART.

UART

Note

When using UART as a wakeup source, there are some restrictions:

  • The Rx clock source can only be OSC2M, and do not turn off OSC4M during sleep.

  • When the baudrate is larger than 115200, it is not recommended to use UART as a wakeup source.

  • The portion of the command used to wake up that exceeds the FIFO depth (64B) will be lost.

Configuration:

  1. Initialize UART and enable its interrupt.

  2. Set the related wakeup source (WAKE_SRC_UART0/WAKE_SRC_UART1/WAKE_SRC_UART2_BT) in sleep_wevent_config[] to WAKEUP_KM4 or WAKEUP_KM0 (based on which CPU you want to wake). The interrupt should be registered on the same CPU selected by sleep_wevent_config[].

  3. Set keep_OSC4M_on in ps_config[] to TRUE to keep OSC4M enabled during sleep mode.

  4. Switch clock to osc 2M with API RCC_PeriphClockSource_UART(UARTx_DEV, UART_RX_CLK_OSC_LP)().

  5. Enter sleep mode by releasing the wakelock in KM4 (PMU_OS needs to be released since it is acquired by default when boot).

  6. Clear the UART interrupt when wakeup.

  7. If a higher baudrate is required after waking up, it is recommended to switch to XTAL 40M Rx clock by API RCC_PeriphClockSource_UART(UART0_DEV, UART_RX_CLK_XTAL_40M)().

LOGUART

Note

When using LOGUART as a wakeup source, there are some restrictions:

  • If the Rx clock source is XTAL40M, do not turn off XTAL or OSC4M during sleep; if the Rx clock source is OSC2M, do not turn off OSC4M during sleep.

  • The portion of the command used to wake up that exceeds the FIFO depth (16B) will be lost.

Configuration:

  1. Initialize LOGUART and enable its interrupt.

  2. Set WAKE_SRC_UART_LOG in sleep_wevent_config[] to WAKEUP_KM4 or WAKEUP_KM0 (based on which CPU you want to wake). The interrupt should be registered on the same CPU selected by sleep_wevent_config[].

  3. Set xtal_mode_in_sleep to XTAL_Normal in ps_config[].

  4. Enter sleep mode by releasing the wakelock in KM4 (PMU_OS needs to be released since it is acquired by default when boot).

  5. Clear the LOGUART interrupt when wakeup.

Entering Deep-Sleep Mode

Deep-sleep can also be entered from FreeRTOS tickless flow.

When the system boots, KM4 holds the deepwakelock PMU_OS, thus freertos_ready_to_dsleep() will be checked fail and the system does not enter deep-sleep mode in idle task by default. Since freertos_ready_to_dsleep() will be checked only after freertos_ready_to_sleep() is checked pass, both the wakelock and deepwakelock need to be released for entering deep-sleep mode.

Configuration:

  1. Initialize the related peripheral and enable its interrupt.

  2. Set sleep_wakepin_config[] in ameba_sleepcfg.c when using AON wakepin as a wakeup source.

  3. Enter deep-sleep mode by releasing the deepwakelock and wakelock in KM4.

Power-Saving Configuration

Wakeup Mask Setup

For sleep mode, only one CPU is required to wake up to execute the program in some situations. The wakeup mask module is designed to implement this function. By setting a wakeup mask, you can choose to wake up only KM0, or KM4. If KM4 is chosen, KM0 will be waked up first and then KM0 will resume KM4.

Users can set the wakeup attribute in sleep_wevent_config[] in ameba_sleepcfg.c to choose which CPU you want to wake up. The wakeup attribute of each wakeup source can be set to WAKEUP_KM4 or WAKEUP_KM0 or WAKEUP_NULL, respectively indicating that this wakeup source is only to wake up KM4, or wake up KM0, or not used as a wakeup source.

/* Wakeup entry can be set to WAKEUP_NULL/WAKEUP_KM4/WAKEUP_KM0 */
WakeEvent_TypeDef sleep_wevent_config[] = {
//   Module              Wakeup
{WAKE_SRC_SDIO,          WAKEUP_NULL},
{WAKE_SRC_AON_WAKEPIN,      WAKEUP_NULL},
{WAKE_SRC_AON_TIM,        WAKEUP_NULL},
{WAKE_SRC_Keyscan,        WAKEUP_NULL},
{WAKE_SRC_PWR_DOWN,        WAKEUP_NULL},
{WAKE_SRC_BOR,          WAKEUP_NULL},
{WAKE_SRC_ADC,          WAKEUP_NULL},
{WAKE_SRC_RTC,          WAKEUP_NULL},
{WAKE_SRC_CTOUCH,        WAKEUP_NULL},
{WAKE_SRC_I2C1,          WAKEUP_NULL},
{WAKE_SRC_I2C0,          WAKEUP_NULL},
{WAKE_SRC_GPIOB,        WAKEUP_NULL},
{WAKE_SRC_GPIOA,        WAKEUP_NULL},
{WAKE_SRC_UART_LOG,        WAKEUP_NULL},
{WAKE_SRC_UART2_BT,        WAKEUP_NULL},
{WAKE_SRC_UART1,        WAKEUP_NULL},
{WAKE_SRC_UART0,        WAKEUP_NULL},
{WAKE_SRC_pmc_timer1,      WAKEUP_KM0},  /* Internal use, do not change it*/
{WAKE_SRC_pmc_timer0,      WAKEUP_KM4},  /* Internal use, do not change it*/
{WAKE_SRC_Timer7,        WAKEUP_NULL},
{WAKE_SRC_Timer6,        WAKEUP_NULL},
{WAKE_SRC_Timer5,        WAKEUP_NULL},
{WAKE_SRC_Timer4,        WAKEUP_NULL},
{WAKE_SRC_IPC_KM4,        WAKEUP_KM4},  /* IPC can only wake up KM4, do not change it*/
{WAKE_SRC_BT_WAKE_HOST,      WAKEUP_NULL},
{WAKE_SRC_KM4_WAKE_IRQ,      WAKEUP_KM0},  /* Internal use, do not change it*/
{WAKE_SRC_WIFI_FTSR_MAILBOX,  WAKEUP_KM0},  /* Wi-Fi wakeup, do not change it*/
{WAKE_SRC_WIFI_FISR_FESR_IRQ,  WAKEUP_KM0},  /* Wi-Fi wakeup, do not change it*/
{0xFFFFFFFF,          WAKEUP_NULL},
};

AON Wakepin Configuration

AON wakepin is one of the peripherals that can be set as a wakeup source. The RTL8721Dx has two AON wakepins (PB30 and PB31), which can be configured in sleep_wakepin_config[] in ameba_sleepcfg.c. The config attribute can be set to DISABLE_WAKEPIN or HIGH_LEVEL_WAKEUP or LOW_LEVEL_WAKEUP, meaning not wake up, or GPIO level high will wake up, or GPIO level low will wake up respectively.

/* can be used by sleep mode & deep sleep mode */
/* config can be set to DISABLE_WAKEPIN/HIGH_LEVEL_WAKEUP/LOW_LEVEL_WAKEUP */
WAKEPIN_TypeDef sleep_wakepin_config[] = {
//   wakepin      config
{WAKEPIN_0,    DISABLE_WAKEPIN},  /* WAKEPIN_0 corresponding to _PB_30 */
{WAKEPIN_1,    DISABLE_WAKEPIN},  /* WAKEPIN_1 corresponding to _PB_31 */
{0xFFFFFFFF,  DISABLE_WAKEPIN},
};

Note

  • By default, AON_WAKEPIN_IRQ will not be enabled in sleep_wakepin_config[], and users need to enable it by themselves.

  • The wakeup mask will not be set in sleep_wakepin_config[]. If wakepin is used for sleep mode, WAKE_SRC_AON_WAKEPIN entry needs to be set in sleep_wevent_config[].

Clock and Voltage Configuration

The XTAL, OSC4M state, and sleep mode voltage are configurable in ps_config[] in ameba_sleepcfg.c. Users can use this configuration for peripherals that need XTAL or OSC4M on in sleep mode.

PSCFG_TypeDef ps_config = {
.keep_OSC4M_on = FALSE,        /* Keep OSC4M on or off for sleep */
.xtal_mode_in_sleep = XTAL_OFF,    /* Set XTAL mode during sleep mode, see enum xtal_mode_sleep for details */
.sleep_to_08V = FALSE,        /* Default sleep to 0.7V, setting this option to TRUE will sleep to 0.8V */
};

Sleep Type Configuration

KM4 can set sleep mode to CG or PG by calling the function pmu_set_sleep_type(uint32_t type)(), and users can get CPU’s sleep mode by calling the function pmu_get_sleep_type().

Note

  • KM0 and KM4 are in the same power domain, so they will have the same sleep type, thus pmu_set_sleep_type() should be set to KM4, and KM0 will follow KM4’s sleep mode type.

  • Sleep mode is set to PG by default. If users want to change the sleep type, pmu_set_sleep_type() needs to be called before sleep.

Wi-Fi Power Saving

IEEE 802.11 power save management allows the station to enter its own sleep state. It defines that the station needs to keep awake at a certain timestamp and enter a sleep state otherwise.

WLAN driver acquires the wakelock to avoid the system entering sleep mode when WLAN needs to keep awake. And it releases the wakelock when it is permitted to enter the sleep state.

IEEE 802.11 power management allows the station to enter power-saving mode. The station cannot receive any frame during power saving. Thus AP needs to buffer these frames and requires the station to periodically wake up to check the beacon which has the information of buffered frames.

application_note/power_save/figures/timeline_of_power_saving.png

Timeline of power saving

When the system is active, and Wi-Fi is connected and enters IEEE 802.11 power management mechanism, this is called LPS in SDK; if the system enters sleep mode when Wi-Fi is connected, we call it WoWLAN mode.

In WoWLAN mode, a timer with a period of about 102ms will be set in the suspend function, and KM0 will wake up every 102ms to receive the beacon to maintain the connection.

Except LPS and WoWLAN modes, there is also an IPS mode, which can be used when Wi-Fi is not connected. The following tables list all three power-saving modes for Wi-Fi and the relationship between power modes of the system and Wi-Fi respectively.

WiFi power saving modes

Mode

Wi-Fi status

Description

SDK

IPS

Not associated:

  • RF/BB/MAC OFF

Wi-Fi driver automatically turns Wi-Fi off to save power.

IPS mode is enabled in SDK by default and is not

recommended to be disabled.

LPS

Associated:

  • RF periodically ON/OFF

  • MAC/BB always ON

LPS mode is used to implement IEEE 802.11 power management.

NP will control RF ON/OFF based on TSF and TIM IE in the beacon.

LPS mode is enabled in SDK by default but can be

disabled through API wifi_set_lps_enable().

WoWLAN

Associated:

  • RF and BB periodically ON/OFF

  • MAC periodically enters/ exits CG/PG

NP is waked up at each beacon early interrupt to receive a beacon

from the associated AP.

NP will wake up AP when receiving a data packet.

WoWLAN mode is enabled in SDK by default.

Relationship between power modes of system and Wi-Fi

System power mode

Wi-Fi power mode

Description

Active

IPS | Wi-Fi is on, but not connected.

LPS | Wi-Fi is connected and enters IEEE 802.11 power management mechanism.

Sleep

Wi-Fi OFF/IPS

WoWLAN

Wi-Fi keeps associating.

Deep-sleep

Wi-Fi OFF

Deep-sleep is not recommended if Wi-Fi needs to keep on or associated.

API to enable/disable LPS

API

Parameters

int wifi_set_lps_enable(u8 enable)

Parameter: enable

  • TRUE: enable LPS

  • FALSE: disable LPS

When Wi-Fi is connected and the system enters sleep mode, WoWLAN mode will be entered automatically, and KM0 will periodically wake up to receive the beacon to maintain the connection, this will consume some power. If you are more concerned about the system power consumption during sleep mode, and Wi-Fi is not a necessary function in your application, it is recommended to set Wi-Fi off or choose Wi-Fi IPS mode.