Power Manager

Overview

The power manager is a platform level software module that manages the system's energy modes. Its main purpose is to transition the system to a low energy mode when the processor has nothing to execute. The energy mode the system will transition to is determined each time the system goes to sleep using requirements. These requirements are set by the different software modules (drivers, stacks, application code, etc...). The power manager also ensures a strict control of some power hungry resources such as the high frequency external oscillator (normally called HFXO or SYXO).

Energy modes overview

As a general rule, the following energy modes are available. The description provides an overview of what functionalities are lost in comparison to the previous energy mode.

Energy Mode Description
EM0 System is fully operational. All peripherals are available. The CPU is executing code.
EM1 The CPU is in sleep mode and is not executing any code.
EM2 High frequency clock sources are shut down. Peripherals that require a high frequency clock are unavailable or have limited functionalities.
EM3 Low frequency clock sources are shut down. Peripherals that require a low frequency clock are unavailable.

* The EM4 energy mode has been omitted from this list as it is not supported by the power manager.

Once the system enters a low energy mode, the way to wake it up to EM0 is via interruptions. Once an interruption occurs, the system goes back to the highest energy mode (EM0). However, if the system was in a deep sleep mode (EM2 or EM3), the system may not wake up in a fully restored mode. See section Waking up from sleep for more information.

For more information on the different energy modes, refer to your device's user manual.

Power manager design considerations

The power manager acts as the middleman between the different software modules and the device.

Power Manager Interactions

Any piece of software can interact with the power manager. There are two main interfaces, as described below.

Requirements

APIs allow you to add and remove requirements on energy modes (EM1, EM2 and EM3). Refer to your chip's reference manual to determine what operations are possible in each energy mode.

The normal use case for these APIs is to add a requirement on a given energy mode before starting a given operation (using one or more peripherals) and removing this requirement once the operation is completed. The more efficient and refined are your operations and the add/remove requirements blocks, the more power efficient your application will be.

For example, when transmitting data on a USART, the system can go to sleep. However, it can only sleep in EM1 mode as otherwise the USART would stop working. The correct way of handling this is to add a requirement on EM1 when the transfer is set up, and remove the requirement on EM1 once the transfer complete ISR is triggered.

The requirements are added and removed via the following APIs:

void sl_power_manager_add_em_requirement(sl_power_manager_em_t em);
void sl_power_manager_remove_em_requirement(sl_power_manager_em_t em);

You must always call the functions sl_power_manager_add_em_requirement() and sl_power_manager_remove_em_requirement() in pair. If you omit to remove a requirement previously added on a given energy mode, that will cause your application to be unable to sleep to a lower energy mode.

You can add and remove requirements from ISR. This is useful to perform a full restore of the different clock sources when waking-up from a deep sleep energy mode (more information on that in the Waking up from deep sleep section). Upon return from a function call to sl_power_manager_add_em_requirement() , the power manager guarantees that all resources related to the requested energy mode are fully restored and available. You should however add requirements from an ISR only when this is absolutely necessary, as this can impact power consumption and interrupt latency.

* Note that software provided by Silicon Labs as part of the different SDKs has, for the most part, a proper and efficient integration with the power manager. You don't have to add and remove requirements for operations performed by these SDK functions unless stated otherwise in the module's user manual.

Notifications

The power manager offers a notification mechanism. This mechanism allows any piece of software to be notified of any energy mode transition. When transitioning from a high energy mode to a lower one (for example, from EM0 to EM2), the listeners are notified before the transition. When transitioning from a low energy mode to a high energy mode (from EM2 to EM0, for example), the listeners are notified after the transition is completed. The main purpose of these notifications is for the different software modules to "adapt" to the new energy mode applied. For instance, a given software module may not need to have a requirement on EM1 to perform a given operation, but may have to do some modifications to continue to perform its operation in EM2. These modifications can be applied in the notification callback. You must use these notifications from your application if you need to perform such operations. Note that the notifications may be called from an ISR context.

The following API is available to subscribe to notifications. The events to subscribe to are configurable.

void sl_power_manager_subscribe_em_transition_event(sl_power_manager_em_transition_event_handle_t     *event_handle,
                                                    const sl_power_manager_em_transition_event_info_t *event_info);

*Note that it is not possible to add and remove requirements from a notification.

The process of entering a sleep mode

When using an operating system

When your application uses an Operating System (Micrium OS kernel or FreeRTOS, for example), the process of going to sleep is fully handled by the OS. The system will automatically enter the lowest possible energy mode (depending on the requirements currently set) when the OS enters idle mode (i.e. when all the tasks are pending on something, delayed or suspended). The power manager will ensure the system resumes its operations as soon as a task is resumed, posted or that its delay expires.

Baremetal applications

When on a baremetal environment, the process of bringing the system into sleep is your application's duty. You are required to call a function named sl_power_manager_sleep() when your application is idling. Once you call this function, the power manager will enter in a sleep loop and won't exit this loop until a system wakeup is requested after an ISR. Two entry points to this sleep loop are provided and used by the power manager to determine if it is safe to enter/return to a low energy mode. These entry points are implemented as function callbacks. The power manager offers a contributions mechanism, as multiple different software modules can contribute to the decision. The software provided by Silicon Labs offers a full integration by contributing to these callbacks when needed.

Entry point Description Algorithm description
is_ok_to_sleep This entry point is only called once at the beginning of the sl_power_manager_sleep() function. It is used to query your application to ensure that no last minute event occurred that would normally prevent the system from entering sleep. The functions provided by the different contributors are called one by one and return a boolean value.
sleep_on_isr_exit This function is called each time an interrupt (or multiple interrupts) wakes the system up, before re-entering sleep. It is used to determine if the system should go back to sleep or wake-up. The functions provided by the different software modules are called one by one and return one of these states:
  • SL_POWER_MANAGER_IGNORE : Returned when the software module did not cause the system wakeup.
  • SL_POWER_MANAGER_SLEEP : Returned when the software module did cause the system wakeup, but the system should go back to sleep.
  • SL_POWER_MANAGER_WAKEUP : Returned when the software module did cause the system wakeup, and the system should not go back to sleep.
If any function returns SL_POWER_MANAGER_WAKEUP , the decision is taken to not go back to sleep. If any software module return SL_POWER_MANAGER_SLEEP and none return SL_POWER_MANAGER_WAKEUP , the decision is taken to go back to sleep. Any other combinations will result in a decision of not going back to sleep.

Two fixed functions are available for your application to implement and contribute to these two entry points decision:

Waking up from sleep

The device wakes up from sleep when an interruption occurs. This causes the system to go back to the EM0 energy mode and the CPU to resume code execution (and execute interrupt's ISR). The state of the system when executing the interrupt's ISR will however differ depending on the energy mode the system was sleeping into.

Energy mode the system was sleeping into System restore state
EM1 On ISR entry, the system will be fully restored as it was before entering sleep mode.
EM2 or EM3 (deep sleep) Depending on the wakeup source, some clock sources may not be restored. See following section for more information.

Waking up from deep sleep

When waking up from deep sleep and executing the interrupt's ISR, the device only restores a fast startup RC oscillator to provide a high frequency clock source for the CPU. The reason being that the process of restoring all the clock sources can be time consuming and requires energy. Depending on the operation that needs to be performed in these ISR, having only one RC oscillator clocking the CPU may be sufficient. It is more energy efficient to not restore all the clock sources in the cases where an ISR with simple processing is executed and the system can get back to a deep sleep mode.

See the sections Synchronous events and Asynchronous events for more information on the events that cause a full clock sources restore by the power manager. Note that when the system gets back to thread mode (if an os task is posted or if a decision to wake-up is taken using the sleep_on_isr_exit entry point in a baremetal application) the power manager will always perform a full restore before.

Following table provides examples of clock sources that are not always automatically restored when waking up from deep sleep.

Energy mode the system was sleeping to Clock sources
EM2 HFXO/SYXO, DPLL
EM3 Clock sources from EM2 + LFXO and LFRCO

Synchronous events

Synchronous events are real-time timed events that are expected to occur in the future. Processing these events will require a full restore of the clock sources. Since the process of restoring the clock sources can be time consuming, the power manager will ensure to wake up in advance and proceed to a full restore of the clock sources in order to be ready on time to process the synchronous event.

To register an event that will be considered as synchronous by the power manager, you must use the timer functionality provided by the sl_sleeptimer module. Any timer (periodic or one-shot) created with the argument option_flags set to 0 will be considered as a synchronous event that requires a full restore of the clock sources on expiration. If you create a timer with the option flag SL_SLEEPTIMER_NO_HIGH_PRECISION_HF_CLOCKS_REQUIRED_FLAG , you won't have a guarantee that all the clock sources will be restored on expiration. For more information on how to create a timer, refer to the sl_sleeptimer user manual.

Asynchronous events

Asynchronous events are any other events (ISRs) that occur in the system. Those events are unexpected by their nature. When they occur and the system was deep sleeping, the various clock sources are not guaranteed to be restored. As for normal operations, if you need to perform or initiate an operation that requires some specific clock sources from your ISR, you must add a requirement on the necessary energy mode to force a restore of the clock sources. If you add a requirement on EM2, upon return of the function sl_power_manager_add_em_requirement() the low frequency clock sources are guaranteed to be available and ready. If you add a requirement on EM1, upon return of the function sl_power_manager_add_em_requirement() the high and low frequency clock sources are guaranteed to be available and ready.

Note that a call to sl_power_manager_add_em_requirement() that triggers a high frequency clock restore will take some time to execute and will stop the CPU for some time. If this is a problem for your application, consider making sure that a requirement on EM1 is added before entering sleep mode.

The time required to restore the clock sources depends on many factors. Refer to your device's datasheet and user manual for more details.

Tips and tricks to optimize your power consumption with the power manager

Refine your requirement blocks as much as possible

You may be tempted to have a very broad coverage of operations between the moment you add a requirement and the moment you remove it. While this offers some simplicity benefits, this is not very efficient. In order to achieve better power consumption, the periods where a requirement is added must be as small and as refined as possible. This will avoid cases where the system enters sleep mode in a high energy mode when it could enter a lower one.

Fine tune the restore time overhead

As described earlier, restoring the clock sources (especially the high-frequency clock sources) can be time consuming. Since this restore time can vary depending on many factors (external crystal type, ambient temperature, etc) the power manager implements a mechanism where it measures the time required to restore some high frequency clock sources. This restore time is used when deep sleeping to trigger a clock sources restore in advance in expectation of an upcoming synchronous event. In order to maintain real-time responsiveness of your application, it is vital to have a restore time that is not too short, as that would cause the clock sources not to be ready on time. For that reason, the power manager always adds a safety margin to the restore time it measures. However, since the system consumes more power when these clock sources are restored, the shorter this restore time is, the better will the energy consumption be. The functions sl_power_manager_schedule_wakeup_get_restore_overhead_tick() and sl_power_manager_schedule_wakeup_set_restore_overhead_tick() are offered to fine tune this safety overhead.