Low Power Mode

Overview

RTL87x2G supports four power modes.

  • CPU Active
    This mode enables all features for ultimate performance. In Power active mode, if the program does not enter the idle task, the CPU remains in an Active state, and the CPU clock will be in high-speed mode, with a default clock speed of 40MHz.
  • CPU Sleep
    In Power active mode, when the system enters into the idle task, the CPU goes into sleep mode, and the CPU clock will automatically slow down. If the CPU is operating at a 40MHz clock, the clock speed will reduce to 625KHz when the CPU is in sleep mode. If a PLL clock is being used, the selection of slow clock depends on the configuration of the PLL clock source.
  • DLPS
    DLPS offers proper low power consumption and quick exit and restore time. In DLPS mode, the content of RAM is retained.
  • Power Down
    This mode has extremely low power consumption. However, in power down mode, the content of RAM is not retained. Exiting from Power Down mode requires a reboot process, which takes more time. Only LPC and PAD (without debounce) can wake up the Power Down mode.

Module usage in different power mode is shown below. This document will provide detailed information about DLPS mode

Module usage in different power mode

Mode

PAD

RAM

Bluetooth

32K clock

RTC

Peripheral

CPU

CPU Clock

CPU Active

40MHz

CPU Sleep

625KHz

DLPS

×

×

×

PowerDown

×

×

×

×

×

×

Features and Restrictions

The DLPS mode of RTL87x2G has the following features and restrictions:

  1. The system can quickly enter and exit DLPS mode.

    • Entering DLPS takes less than 1ms.

    • Bluetooth wake-up event: Exiting DLPS takes approximately 4ms.

    • Other wake-up events: Exiting DLPS takes approximately 3ms.

  2. The system can be woken up from DLPS by DLPS Wake-up Events.

  3. Due to the shutdown of CPU power in DLPS, the SWD function is unavailable. DLPS mode must be disabled during online debugging with J-Link.

Principle

In most cases, the RTL87x2G system can enter an idle state, during which high-speed clock, CPU, and peripheral components can be disabled to minimize power consumption as much as possible. However, when an event occurs that requires handling, the system will be woken up from DLPS mode. In this process, the high-speed clock, CPU, and peripherals will be re-powered on and restored to their previous status before entering DLPS mode. After restoration, the system will respond to the wake-up events accordingly. This allows for efficient power management while still being able to handle events when necessary. The processes described above are automatically handled by the system’s registered callback functions, so users do not need to worry about them.

Enter/Exit from DLPS

Conditions for Entering DLPS Mode

The system can only enter DLPS mode when the following conditions are met simultaneously:

  1. Idle task is running, and all other tasks are either blocked or suspended, with no interrupt service routines (ISRs) occurring.

  2. BT Module checks whether the conditions for entering DLPS are met.

    • Non-Link mode

      State

      Description

      Standby State

      In Standby State, no data is sent or received. BT module will enter sleep mode and no Bluetooth-related event wakes the system up.

      Advertising State

      (connectable or un-connectable)

      If Adv_Interval * 0.625ms >= 15ms, then entering DLPS is permitted; otherwise, it is not permitted.

      If Advertising Type is Direct Advertising (High duty cycle), entering DLPS mode is not permitted.

      For multi-Advertising, the condition of ‘Adv_Interval * 0.625ms >= 15ms’ also needs to be met.

      Scanning State

      In Scanning State, if (Scan Interval – Scan Window) * 0.625ms >= 15ms, then entering DLPS mode is permitted; otherwise, it is not permitted.

    • Link mode (includes two roles)

      Role

      Description

      Master Role

      In Master Role, when Connection Interval * 1.25ms >= 15ms, entering DLPS mode is permitted.

      Slave Role

      In Slave Role, when Connection Interval * (1+Slave Latency) * 1.25ms >= 15ms, entering DLPS mode is permitted.

      Note

      For multi-link mode, when a device is advertising and a connection has already been created, if the interval between the current time and the next nearest connection or advertising event time is >= 15ms, entering DLPS mode will be permitted.

  3. Platform Module checks whether the conditions for entering DLPS are met.

    1. All the DLPS check callback functions, registered by peripherals and application, return true.

    2. OS SW timer period or task delay period >= 20ms.

Note

  • If the BT module is allowed to enter DLPS but the platform module is not, the BT module will enter DLPS mode while the platform module remains active.

  • If the BT module is not allowed to enter DLPS, the system will remain in an active state.

DLPS Wake-up Events

The system can be woken up and exit the DLPS mode by one of the following events.

BT Wake-up

Occurrence of any BT event:
  1. Arrival of an advertising anchor when the BT is in advertising state.

  2. Arrival of a connection event anchor when a BT connection is established.

  3. Arrival of a scanning anchor when the BT is in scanning state.

Platform Wake-up

  1. PAD wake-up signal

    1. PAD has the function to wake up the system from DLPS mode. Users can use System_WakeUpPinEnable() to enable the wake-up function of a pin. When the polarity of a signal on the pin matches the wake-up level, the system will be woken up and then recover from DLPS mode to Active mode.

    2. If P3_2 is expected to wake up the system from DLPS mode when the signal on the pin becomes a high level, the following configuration should be set as an example.

      System_WakeUpPinEnable(P3_2, PAD_WAKEUP_POL_HIGH, PAD_WAKEUP_DEB_DISABLE);
      
    3. When calling System_WakeUpPinEnable(), setting DebounceEn to 1 enables the debounce wake-up function. If the debounce wake-up function is enabled, call System_WakeUpDebounceTime() to set the debounce time. For example, setting the debounce time to 8ms can be done as follows (the default value is 0ms if not configured).

      System_WakeUpDebounceTime(P3_2, 8);
      System_WakeUpPinEnable(P3_2, PAD_WAKEUP_POL_HIGH, PAD_WAKEUP_DEB_ENABLE);
      
    4. The System irq is a system interrupt triggered when System_WakeUpPinEnable() enables PAD wake-up, and the current pin state matches the wake-up level. By default, the system disables the system irq after entering DLPS and restores it after exiting DLPS. Therefore, if DLPS is woken up by a pin, the system will enter the system interrupt handler after the system irq is restored.

      1. When debounce wake-up is disabled, the system triggers the system irq after waking up from DLPS. Users can call System_WakeUpInterruptValue() in the system irq handler to query which pin woke up the system. Then, Pad_ClearWakeupINTPendingBit() needs to be called to clear the wake-up status of that pin.

        uint8_t System_WakeUpInterruptValue(uint8_t Pin_Num);
        void Pad_ClearWakeupINTPendingBit(uint8_t Pin_Num);
        
      2. When debounce wake-up is enabled, the system triggers the system irq after waking up from DLPS. However, users cannot determine which pin woke up DLPS. They can only call System_WakeupDebounceStatus() in the System irq handler to retrieve the debounce wake-up status. Then, they need to call System_WakeupDebounceClear() to clear the debounce wake-up status. When Debounce wake-up is enabled, only if the pin maintains the wake-up level state for a duration longer than the debounce time, DLPS will be woken up, preventing accidental wake-ups. However, the drawback is that after enabling Debounce wake-up, it is not possible to detect which specific pin woke up DLPS.

        Note

        Although the API related to Debounce includes a pin num parameter, it is mentioned here only to ensure compatibility with different IC series. 87x2G does not support detecting wake-up from different pins under the Debounce wake-up enable. For specific usage examples, please refer to DLPS usage sample. For detailed information about the relevant interfaces mentioned above, please refer to DLPS Mode APIs.

  2. RTC interrupt ( demo project: samples\io_sample\rtc\rtc_dlps\proj\rtl87x2g\mdk)

    To enable RTC HW wake-up, the following APIs should be called.

    RTC_WKConfig(RTC_COMP_WK_INDEX, ENABLE) // enable Comparator wake up
    RTC_SystemWakeupConfig(ENABLE);
    

    RTC SW wake-up: refer to SW implementation of RTC wake-up.

  3. SW Timer timeout or task delay.

  4. LPC interrupt ( demo project: samples\io_sample\lpc\voltage_detection_dlps\proj\rtl87x2g\mdk )

    To enable LPC wake-up, the following API needs to be called:

    LPC_WKCmd(ENABLE);
    
  5. AON Q-Decoder interrupt (demo project: samples\io_sample\aon_qdec\aon_qdec_dlps\proj\rtl87x2g\mdk)

    To enable AON Q-Decoder wake-up, the following API needs to be called:

    AON_QDEC_INITMask(AON_QDEC, AON_QDEC_X_WAKE_AON_MASK, DISABLE);
    

DLPS Mode Entry Flow

Prerequisite

If a module needs to be inquired before entering DLPS mode, it should first register a callback function with the Power Manager. When the Power Manager calls the callback function, each module will inform the Power Manager whether or not it should enter DLPS mode based on the return value of the callback function. The BT module is based on the platform module, meaning that the platform module should enter DLPS mode only if the BT module is allowed to enter sleep mode.

Entry flow
  1. System enters into the idle task.

  2. Inquire the BT module whether DLPS mode is allowed to be entered.

  3. BT module stores its status and enters DLPS mode.

  4. Inquire the platform module whether DLPS mode is allowed to be entered.

  5. Platform module stores its status and enters DLPS mode.

DLPS Exit Flow

After waking up from DLPS mode, the system first restores power and high-speed clock, followed by the recovery of the CPU NVIC and peripherals. Only after the platform module has completely exited DLPS mode, will the system check if other modules need to exit DLPS mode.

  1. System exit
    When the system exits DLPS mode, it triggers a Reset exception that enters the Reset Handler. In the Reset Handler, the cause of the restart is checked. If it is due to a power-on event, the system follows the restart flow. If it wakes up from DLPS mode, the Platform system follows the DLPS recovery flow to restore power, high-speed clock and OS.
  2. Platform Exit from DLPS completely
    The final stage of platform recovery is completed in the timer task, where the platform completely exits DLPS mode and completes the recovery of the CPU NVIC, peripherals, and the execution of user-defined exit callback functions.
  3. Checking for the remaining system modules to exit and recover from DLPS
    Checking if a Bluetooth event has woken up from DLPS. If so, the Bluetooth module exits DLPS and restores its state; otherwise, the Bluetooth module continues to remain in a low-power state.

Hardware Status Storage and Recovery

CPU NVIC

In entering DLPS mode, the CPU is powered off. Therefore, it is necessary to save the NVIC registers before entering DLPS mode and then restore them after exiting from DLPS mode. This process ensures that the interrupt settings are preserved and can be properly restored upon wake-up.

The SDK typically provides default implementations of the CPU_DLPS_Enter and CPU_DLPS_Exit functions to handle this saving and restoring of the NVIC registers. Users do not need to provide implementation details of these functions, as it has been implemented by system.

PAD

The PAD does not power off in DLPS mode. However, to prevent current leakage and ensure proper operation, certain settings need to be configured for the PAD before entering DLPS. Here are the recommended configurations.

  1. PADs that have not been used or are disabled in the IC should be set as {SW mode, Input mode, Pull Down}. This is the default set of pins, and users don’t need to change.

  2. PADs that have been used should be set as {SW mode, Input mode, Pull Up/Pull Down}. The selection of pull up or pull down depends on the external circuit connected to the pin. If the pin is connected to VDD, it should be pulled up. If it is connected to GND, it should be pulled down.

  3. For PADs with an external circuit voltage between VDD and GND, the pin should be set as {SW mode, Shut down mode, Pull none}. This configuration ensures that the pin is isolated from the external circuit and minimizes power leakage.

  4. PADs that have wake-up ability should be set as {SW mode, Input mode, Pull Up/Pull Down}. The pull mode for a wake-up pin should be set opposite to its wake-up polarity. For example, if a wake-up pin triggers a wake-up event when pulled low, it should be pulled high during DLPS.

  5. It is important to recover the pins to their original settings after exiting DLPS mode. This ensures that the PADs return to their intended functionality and prevent any potential issues.

Peripherals

Peripherals will be powered off when entering DLPS (Deep Low Power State), so it is important to save the related settings before entering DLPS and recover them after exiting from DLPS. Before recovering peripheral settings, the peripheral module should be enabled, and the peripheral clock should be started first.

External Sensor

When an external sensor enters or exits from DLPS, processing is performed in two different cases.

  1. If the sensor is not powered off, it does not need to be recovered.

  2. If the sensor is powered off, the application callback function must be registered, and the sensor will be re-initialized in the function.

Storage Flow

The storage of CPU, PINMUX, and peripherals has already been implemented by the system. Since pin settings during entering DLPS can vary depending on the application, the related pin settings are handled in the vendor callback function. This callback function is registered by the application using DLPS_IORegUserDlpsEnterCb() . If external sensors are used and need to be handled, the corresponding implementation should also be placed in the same DLPS enter vendor callback.

../../../../_images/IO_Store_Flow.PNG

Hardware Store Flow

Recovery Flow

The restoration of CPU, PINMUX, and peripherals has already been implemented by the system. Since pin settings during exiting from DLPS can vary depending on the application, the related pin setting is handled in the callback function. This callback function is registered by the application using DLPS_IORegUserDlpsExitCb() . If external sensors are used and need to be handled, the corresponding implementation should also be placed in the same DLPS exit vendor callback.

../../../../_images/IO_Restore_Flow.PNG

Hardware Restore Flow

Usage of DLPS Settings about Peripherals

Each application has a copy of board.h file, which contains the following DLPS settings for hardware.

/* if use user define DLPS enter/DLPS exit callback function */
#define USE_USER_DEFINE_DLPS_EXIT_CB         1
#define USE_USER_DEFINE_DLPS_ENTER_CB        1

/* if use any peripherals below, #define it  1 */
#define USE_ADC_DLPS                         0
#define USE_GPIOA_DLPS                       0
#define USE_I2C0_DLPS                        0
#define USE_I2C1_DLPS                        0
#define USE_IR_DLPS                          0
#define USE_KEYSCAN_DLPS                     0
#define USE_SPI0_DLPS                        0
#define USE_SPI1_DLPS                        0
#define USE_UART0_DLPS                       0
#define USE_UART1_DLPS                       0
#define USE_ENHTIM_DLPS                      0

If DLPS function of a peripheral needs to be enabled, the corresponding USE_XXX_ DLPS macro should be defined as ‘1’. For some peripherals, such as GDMA, user needs to call the initialization function in the DLPS exit callback function.

If any peripheral is being used, the following API should be called in the application’s PwrMgr_Init() function to register the peripheral DLPS function.

DLPS_IORegister();

If any user-defined operations need to be performed during entering or exiting from DLPS, follow the two steps below

  1. Define macro USE_USER_DEFINE_DLPS_EXIT_CB or USE_USER_DEFINE_DLPS_ENTER_CB as ‘1’ in board.h.

  2. Call the following API in the application to register and implement the callback function.

    void DlpsExitCallback(void)
    {
        //do something here
    }
    
    void DlpsEnterCallback(void)
    {
        //do something here
    }
    
    DLPS_IORegUserDlpsExitCb(DlpsExitCallback);
    DLPS_IORegUserDlpsEnterCb(DlpsEnterCallback);
    

In the case above, the functions DlpsEnterCallback and DlpsExitCallback will be executed during entering and exiting from DLPS, respectively. The application can implement specific operations within these functions, such as PAD setting or operations on peripherals.

DLPS Usage Sample

PAD Wake-up without Debounce

Register DLPS check, enter and exit vendor callback function, pull pin P3_2 low to wake up DLPS.

bool DLPS_Check(void)
{
    return true;
}

void EnterDlpsSet(void)  //DLPS Enter
{
    Pad_Config(P3_2, PAD_SW_MODE, PAD_IS_PWRON,
      PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
    System_WakeUpPinEnable(P3_2, PAD_WAKEUP_POL_LOW,
      PAD_WAKEUP_DEB_DISABLE);
}

void ExitDlpsInit(void)  //DLPS Exit
{
    Pad_Config(P3_2, PAD_PINMUX_MODE, PAD_IS_PWRON,
      PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
}

void pwr_mgr_init(void)
{
#if DLPS_EN
    power_check_cb_register(DLPS_Check);
    DLPS_IORegUserDlpsEnterCb(EnterDlpsSet);  //DLPS Enter CB
    DLPS_IORegUserDlpsExitCb(ExitDlpsInit);  //DLPS Exit CB
    DLPS_IORegister();
    bt_power_mode_set(BTPOWER_DEEP_SLEEP);
    power_mode_set(POWER_DLPS_MODE);
#endif
}

Define System irq handler to detect which pin wakes up DLPS.

void System_Handler(void)
{
    APP_PRINT_INFO0("System_Handler");
    NVIC_DisableIRQ(System_IRQn);

    if (System_WakeUpInterruptValue(P3_2) == SET)
    {
        APP_PRINT_INFO0("P3_2 Wake up");
        Pad_ClearWakeupINTPendingBit(P3_2);
        System_WakeUpPinDisable(P3_2);
    }

    NVIC_ClearPendingIRQ(System_IRQn);
}

PAD Wake-up with Debounce

Register DLPS check, enter and exit vendor callback function, pull pin P3_2 low to wake up DLPS. Set 8ms debounce wake up DLPS.

bool DLPS_Check(void)
{
    return true;
}

void EnterDlpsSet(void)
{
    Pad_Config(P3_2, PAD_SW_MODE, PAD_IS_PWRON,
      PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
    System_WakeUpPinDisable(P3_2);
    System_WakeUpDebounceTime(P3_2, 8);
    System_WakeUpPinEnable(P3_2, PAD_WAKEUP_POL_LOW, PAD_WAKEUP_DEB_ENABLE);
}

void ExitDlpsInit(void)
{
    Pad_Config(P3_2, PAD_PINMUX_MODE, PAD_IS_PWRON,
      PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_LOW);
}

void pwr_mgr_init(void)
{
#if DLPS_EN
    power_check_cb_register(DLPS_Check);
    DLPS_IORegUserDlpsEnterCb(EnterDlpsSet);
    DLPS_IORegUserDlpsExitCb(ExitDlpsInit);
    DLPS_IORegister();
    bt_power_mode_set(BTPOWER_DEEP_SLEEP);
    power_mode_set(POWER_DLPS_MODE);
#endif
}

When debounce wake-up is used, the system irq handler cannot detect which specific pin wakes up DLPS, and can only clear the debounce status.

void System_Handler(void)
{
    APP_PRINT_INFO0("System_Handler");
    NVIC_DisableIRQ(System_IRQn);

    if(System_WakeupDebounceStatus(P3_2) == SET)
    {
      System_WakeupDebounceClear(P3_2);
        DBG_DIRECT("debounce Wake up");
    }
    NVIC_ClearPendingIRQ(System_IRQn);
}

SW Implementation of RTC Wake-up

With RTC HW wake-up, the system needs to wait until the RTC timeout occurs before exiting DLPS mode. After exiting DLPS mode, the power on and system restore process is executed, and the RTC handler will be called. However, the execution of the RTC handler is delayed by the DLPS exit time.

If higher accuracy in the RTC handler is required, the user can use SW wake up DLPS. After waking up from DLPS, the RTC timeout and handler are executed. By considering the DLPS exit time, the SW wake up DLPS may wake up appropriately in advance, resulting in a more accurate execution time for the RTC handler.

The detailed procedure for using SW wake-up DLPS is as follows.

  1. Cancel the call to the RTC wake-up enable API to disable RTC HW wake-up.

  2. Add a next_wake_up_time parameter in the DLPS check callback function and calculate the next wake up time for the RTC timeout in units of 31.25us. In the check callback function, update the next_wake_up_time to the calculated value.

    uint32_t RTC_tick; // unit: 32.15us
    POWER_CheckResult RTC_Check_GT(uint32_t *next_wake_up_time)  // unit 31.25us
    {
        uint32_t wake_up_count = RTC_GetCompValue(RTC_COMP_INDEX) - RTC_GetCounter();
        if (wake_up_count > 0)
        {
            *next_wake_up_time = wake_up_count * RTC_tick;
            return POWER_CHECK_PASS;
        }
        else
        {
            return POWER_CHECK_FAIL;
        }
    }
    
  3. Register DLPS check callback.

    RTC_tick = (RTC_PRESCALER_VALUE + 1);
    power_check_cb_register(RTC_Check_GT);
    

DLPS Mode APIs