Power Manager#
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...). Power manager also ensures a strict control of some power hungry resources such as the high frequency external oscillator (normally called HFXO). Power manager also offers a notification mechanism through which any piece of software module can be notified of energy mode transitions through callbacks.
Note
Sleep Driver is deprecated. Use Power Manager for all sleep-related operations. See AN1358: Migrating from Sleep Driver to Power Manager for information on how to migrate from Sleep Driver to Power Manager.
Emlib EMU functions EMU_EnterEM1()/EMU_EnterEM2()/EMU_EnterEM3() must not be used when the Power Manager is present. The Power Manager module must be the one deciding at which EM level the device sleeps to ensure the application properly works. Using both at the same time could lead to undefined behavior in the application.
Initialization#
Power manager must be initialized prior to any call to power manager API. If sl_system is used, only sl_system_init() must be called, otherwise sl_power_manager_init() must be called manually. Note that power manager must be initialized after the clock(s), when initialized manually, as the power manager check which oscillators are used during the initialization phase.
Add and remove requirements#
The drivers should add and remove energy mode requirements, at runtime, on the lowest energy mode for them depending on their state. When calling sl_power_manager_sleep(), the lowest possible Energy mode will be automatically selected.
It is possible to add and remove requirements from ISR. If a specific energy mode is required in the ISR, but not required to generate the interrupt, a requirement on the energy mode can be added from the ISR. It is guaranteed that the associated clock will be active once sl_power_manager_add_requirement() returns. The EM requirement can be also be removed from an ISR.
Requirements should not be removed if it was not previously added.
Subscribe to events#
It possible to get notified when the system transition from a power level to another power level. This can allow to do some operations depending on which level the system goes, such as saving/restoring context.
Sleep#
When the software has no more operation and only need to wait for an event, the software must call sl_power_manager_sleep(). This is automatically done when the kernel is present, but it needs to be called from the super loop in a baremetal project.
Query callback functions#
Is OK to sleep#
Between the time sl_power_manager_sleep
is called and the MCU is really put in a lower Energy mode, it is possible that an ISR occur and require the system to resume at that time instead of sleeping. So a callback is called in a critical section to validate that the MCU can go to sleep.
In case of an application that runs on an RTOS, the RTOS will take care of determining if it is ok to sleep. In case of a baremetal application, the function sl_power_manager_is_ok_to_sleep()
will be generated automatically by Simplicity Studio's wizard. The function will look at multiple software modules from the SDK to take a decision. The application can contribute to the decision by defining the function app_is_ok_to_sleep()
. If any of the software modules (including the application via app_is_ok_to_sleep()
) return false, the process of entering in sleep will be aborted.
Sleep on ISR exit#
When the system enters sleep, the only way to wake it up is via an interrupt or exception. By default, power manager will assume that when an interrupt occurs and the corresponding ISR has been executed, the system must not go back to sleep. However, in the case where all the processing related to this interrupt is performed in the ISR, it is possible to go back to sleep by using this hook.
In case of an application that runs on an RTOS, the RTOS will take care of determining if the system can go back to sleep on ISR exit. Power manager will ensure the system resumes its operations as soon as a task is resumed, posted or that its delay expires. In case of a baremetal application, the function sl_power_manager_sleep_on_isr_exit()
will be generated automatically by Simplicity Studio's wizard. The function will look at multiple software modules from the SDK to take a decision. The application can contribute to the decision by defining the function app_sleep_on_isr_exit()
. The generated function will take a decision based on the value returned by the different software modules (including the application via app_sleep_on_isr_exit()
):
SL_POWER_MANAGER_IGNORE
: if the software module did not cause the system wakeup and/or doesn't want to contribute to the decision. SL_POWER_MANAGER_SLEEP
: if the software module did cause the system wakeup, but the system should go back to sleep. SL_POWER_MANAGER_WAKEUP
: if the software module did cause the system wakeup, and the system should not go back to sleep.
If any software module returned SL_POWER_MANAGER_SLEEP
and none returned SL_POWER_MANAGER_WAKEUP
, the system will go back to sleep. Any other combination will cause the system not to go back to sleep.
Debugging feature#
By setting the configuration define SL_POWER_MANAGER_DEBUG to 1, it is possible to record the requirements currently set and their owner. It is possible to print at any time a table that lists all the added requirements and their owner. This table can be printed by caling the function sl_power_manager_debug_print_em_requirements(). Make sure to add the following define
#define CURRENT_MODULE_NAME "<Module printable name here>"
to any application code source file that adds and removes requirements.
Usage Example#
#define EM_EVENT_MASK_ALL (SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0 \
| SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1 \
| SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2 \
| SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3)
sl_power_manager_em_transition_event_handle_t event_handle;
sl_power_manager_em_transition_event_info_t event_info = {
.event_mask = EM_EVENT_MASK_ALL,
.on_event = my_events_callback,
}
void main(void)
{
// Initialize power manager; not needed if sl_system_init() is used.
sl_power_manager_init();
// Limit sleep level to EM1
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
// Subscribe to all event types; get notified for every power transition.
sl_power_manager_subscribe_em_transition_event(&event_handle, &event_info);
while (1) {
// Actions
[...]
if (completed) {
// Remove energy mode requirement, can go to EM2 or EM3 now, depending on the configuration
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
}
// Sleep to lowest possible energy mode; This call is not needed when using the kernel.
sl_power_manager_sleep();
// Will resume after an interrupt or exception
}
}
void my_events_callback(sl_power_manager_em_t from,
sl_power_manager_em_t to)
{
printf("Event:%s-%s\r\n", string_lookup_table[from], string_lookup_table[to]);
}
Modules#
sl_power_manager_em_transition_event_info_t
sl_power_manager_em_transition_event_handle_t
Enumerations#
Energy modes.
On ISR Exit Hook answer.
Typedefs#
Mask of all the event(s) to listen to.
Typedef for the user supplied callback function which is called when an energy mode transition occurs.
Functions#
Initialize Power Manager module.
Sleep at the lowest allowed energy mode.
Adds requirement on given energy mode.
Removes requirement on given energy mode.
Registers a callback to be called on given Energy Mode transition(s).
Unregisters an event callback handle on Energy mode transition.
Get configurable overhead value for early restore time in Sleeptimer ticks when a schedule wake-up is set.
Set configurable overhead value for early restore time in Sleeptimer ticks used for schedule wake-up.
Get configurable minimum off-time value for schedule wake-up in Sleeptimer ticks.
Set configurable minimum off-time value for schedule wake-up in Sleeptimer ticks.
Enable or disable fast wake-up in EM2 and EM3.
Determines if the HFXO interrupt was part of the last wake-up and/or if the HFXO early wakeup expired during the last ISR and if it was the only timer to expire in that period.
Enter energy mode 4 (EM4).
When EM4 pin retention is set to power_manager_pin_retention_latch, then pins are retained through EM4 entry and wakeup.
Energy mode 4 pre-sleep hook function.
Print a table that describes the current requirements on each energy mode and their owner.
Macros#
current module name
sl power manager event transition entering em0
sl power manager event transition leaving em0
sl power manager event transition entering em1
sl power manager event transition leaving em1
sl power manager event transition entering em2
sl power manager event transition leaving em2
sl power manager event transition entering em3 (DEPRECATED)
sl power manager event transition leaving em3 (DEPRECATED)
Enumeration Documentation#
sl_power_manager_em_t#
sl_power_manager_em_t
Energy modes.
Enumerator | |
---|---|
SL_POWER_MANAGER_EM0 | Run Mode (Energy Mode 0) |
SL_POWER_MANAGER_EM1 | Sleep Mode (Energy Mode 1) |
SL_POWER_MANAGER_EM2 | Deep Sleep Mode (Energy Mode 2) |
SL_POWER_MANAGER_EM3 | Stop Mode (Energy Mode 3) |
SL_POWER_MANAGER_EM4 | Shutoff Mode (Energy Mode 4) |
243
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_on_isr_exit_t#
sl_power_manager_on_isr_exit_t
On ISR Exit Hook answer.
Enumerator | |
---|---|
SL_POWER_MANAGER_IGNORE | The module did not trigger an ISR and it doesn't want to contribute to the decision. |
SL_POWER_MANAGER_SLEEP | The module was the one that caused the system wakeup and the system SHOULD go back to sleep. |
SL_POWER_MANAGER_WAKEUP | The module was the one that caused the system wakeup and the system MUST NOT go back to sleep. |
277
of file platform/service/power_manager/inc/sl_power_manager.h
Typedef Documentation#
sl_power_manager_em_transition_event_t#
typedef uint32_t sl_power_manager_em_transition_event_t
Mask of all the event(s) to listen to.
252
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_em_transition_on_event_t#
typedef void(* sl_power_manager_em_transition_on_event_t) (sl_power_manager_em_t from, sl_power_manager_em_t to) )(sl_power_manager_em_t from, sl_power_manager_em_t to)
Typedef for the user supplied callback function which is called when an energy mode transition occurs.
N/A | from | Energy mode we are leaving. |
N/A | to | Energy mode we are entering. |
261
of file platform/service/power_manager/inc/sl_power_manager.h
Function Documentation#
sl_power_manager_init#
sl_status_t sl_power_manager_init (void )
Initialize Power Manager module.
N/A |
Returns
Status code
309
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_sleep#
void sl_power_manager_sleep (void )
Sleep at the lowest allowed energy mode.
N/A |
Note
Must not be called from ISR
Note
This function will expect and call a callback with the following signature:
bool sl_power_manager_is_ok_to_sleep(void)
.This function can be used to cancel a sleep action and handle the possible race condition where an ISR that would cause a wakeup is triggered right after the decision to call sl_power_manager_sleep() has been made.
This function must NOT be called with interrupts disabled. This means both BASEPRI and PRIMASK MUST have a value of 0 when invoking this function.
Usage example:
void main(void)
{
sl_power_manager_init();
while (1) {
tick();
sl_power_manager_sleep();
}
}
342
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_add_em_requirement#
void sl_power_manager_add_em_requirement (sl_power_manager_em_t em)
Adds requirement on given energy mode.
N/A | em | Energy mode to add the requirement to:
|
Note
Adding EM requirements on SL_POWER_MANAGER_EM2 is now DEPRECATED. The calls can simply be removed since the system will go to deepsleep (EM2/EM3) in the absence of EM1 requirements.
356
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_remove_em_requirement#
void sl_power_manager_remove_em_requirement (sl_power_manager_em_t em)
Removes requirement on given energy mode.
N/A | em | Energy mode to remove the requirement to:
|
Note
Removing EM requirements on SL_POWER_MANAGER_EM2 is now DEPRECATED. The calls can simply be removed since the system will go to deepsleep (EM2/EM3) in the absence of EM1 requirements.
379
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_subscribe_em_transition_event#
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)
Registers a callback to be called on given Energy Mode transition(s).
N/A | event_handle | Event handle (no initialization needed). |
N/A | event_info | Event info structure that contains the event mask and the callback that must be called. |
Note
Adding and removing requirement(s) from a callback on a transition event is not supported.
The parameters passed must be persistent, meaning that they need to survive until the callback fires.
SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3 and SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3 are now DEPRECATED and should not be used in the event_info argument.
Usage example:
#define EM_EVENT_MASK_ALL ( SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0 \
| SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1 \
| SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2 \
| SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2)
sl_power_manager_em_transition_event_handle_t event_handle;
sl_power_manager_em_transition_event_info_t event_info = {
.event_mask = EM_EVENT_MASK_ALL,
.on_event = my_callback,
};
void my_callback(sl_power_manager_em_t from,
sl_power_manager_em_t to)
{
[...]
}
void main(void)
{
sl_power_manager_init();
sl_power_manager_subscribe_em_transition_event(&event_handle, &event_info);
}
437
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_unsubscribe_em_transition_event#
void sl_power_manager_unsubscribe_em_transition_event (sl_power_manager_em_transition_event_handle_t * event_handle)
Unregisters an event callback handle on Energy mode transition.
N/A | event_handle | Event handle which must be unregistered (must have been registered previously). |
Note
An EFM_ASSERT is thrown if the handle is not found.
448
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_schedule_wakeup_get_restore_overhead_tick#
int32_t sl_power_manager_schedule_wakeup_get_restore_overhead_tick (void )
Get configurable overhead value for early restore time in Sleeptimer ticks when a schedule wake-up is set.
N/A |
Returns
Current overhead value for early restore time.
Note
This function will do nothing when a project contains the power_manager_no_deepsleep component, which configures the lowest energy mode as EM1.
460
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_schedule_wakeup_set_restore_overhead_tick#
void sl_power_manager_schedule_wakeup_set_restore_overhead_tick (int32_t overhead_tick)
Set configurable overhead value for early restore time in Sleeptimer ticks used for schedule wake-up.
N/A | overhead_tick | Overhead value to set for early restore time. |
Must be called after initialization else the value will be overwritten.
Note
The overhead value can also be negative to remove time from the restore process.
This function will do nothing when a project contains the power_manager_no_deepsleep component, which configures the lowest energy mode as EM1.
476
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_schedule_wakeup_get_minimum_offtime_tick#
uint32_t sl_power_manager_schedule_wakeup_get_minimum_offtime_tick (void )
Get configurable minimum off-time value for schedule wake-up in Sleeptimer ticks.
N/A |
Returns
Current minimum off-time value for schedule wake-up.
Note
Turning on external high frequency clock, such as HFXO, requires more energy since we must supply higher current for the wake-up. Therefore, when an 'external high frequency clock enable' is scheduled in 'x' time, there is a threshold 'x' value where turning off the clock is not worthwhile since the energy consumed by taking into account the wake-up will be greater than if we just keep the clock on until the next scheduled clock enabled. This threshold value is what we refer as the minimum off-time.
This function will do nothing when a project contains the power_manager_no_deepsleep component, which configures the lowest energy mode as EM1.
497
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_schedule_wakeup_set_minimum_offtime_tick#
void sl_power_manager_schedule_wakeup_set_minimum_offtime_tick (uint32_t minimum_offtime_tick)
Set configurable minimum off-time value for schedule wake-up in Sleeptimer ticks.
N/A | minimum_offtime_tick | minimum off-time value to set for schedule wake-up. |
Note
Turning on external high frequency clock, such as HFXO, requires more energy since we must supply higher current for the wake-up. Therefore, when an 'external high frequency clock enable' is scheduled in 'x' time, there is a threshold 'x' value where turning off the clock is not worthwhile since the energy consumed by taking into account the wake-up will be greater than if we just keep the clock on until the next scheduled clock enabled. This threshold value is what we refer as the minimum off-time.
This function will do nothing when a project contains the power_manager_no_deepsleep component, which configures the lowest energy mode as EM1.
519
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_em23_voltage_scaling_enable_fast_wakeup#
void sl_power_manager_em23_voltage_scaling_enable_fast_wakeup (bool enable)
Enable or disable fast wake-up in EM2 and EM3.
N/A | enable | True False variable act as a switch for this api |
Note
Will also update the wake up time from EM2 to EM0.
This function will do nothing when a project contains the power_manager_no_deepsleep component, which configures the lowest energy mode as EM1.
532
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_is_latest_wakeup_internal#
bool sl_power_manager_is_latest_wakeup_internal (void )
Determines if the HFXO interrupt was part of the last wake-up and/or if the HFXO early wakeup expired during the last ISR and if it was the only timer to expire in that period.
N/A |
Returns
true if power manager sleep can return to sleep, false otherwise.
Note
This function will always return false in case a requirement is added on SL_POWER_MANAGER_EM1, since we will never sleep at a lower level than EM1.
547
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_enter_em4#
void sl_power_manager_enter_em4 (void )
Enter energy mode 4 (EM4).
N/A |
Note
You should not expect to return from this function. Once the device enters EM4, only a power on reset or external reset pin can wake the device.
On xG22 devices, this function re-configures the IADC if EM4 entry is possible.
559
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_em4_unlatch_pin_retention#
void sl_power_manager_em4_unlatch_pin_retention (void )
When EM4 pin retention is set to power_manager_pin_retention_latch, then pins are retained through EM4 entry and wakeup.
N/A |
The pin state is released by calling this function. The feature allows peripherals or GPIO to be re-initialized after EM4 exit (reset), and when initialization is done, this function can release pins and return control to the peripherals or GPIO.
Note
When the EM4 Pin Retention feature is not available on a device, calling this function will do nothing.
572
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_em4_presleep_hook#
void sl_power_manager_em4_presleep_hook (void )
Energy mode 4 pre-sleep hook function.
N/A |
Note
This function is called by sl_power_manager_enter_em4 just prior to the sequence of writes to put the device in EM4. The function implementation does not perform anything, but it is SL_WEAK so that it can be re-implemented in application code if actions are needed.
583
of file platform/service/power_manager/inc/sl_power_manager.h
sl_power_manager_debug_print_em_requirements#
void sl_power_manager_debug_print_em_requirements (void )
Print a table that describes the current requirements on each energy mode and their owner.
N/A |
52
of file platform/service/power_manager/inc/sl_power_manager_debug.h
Macro Definition Documentation#
CURRENT_MODULE_NAME#
#define CURRENT_MODULE_NAMEValue:
"Anonymous"
current module name
226
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0#
#define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0Value:
(1 << 0)
sl power manager event transition entering em0
230
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0#
#define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0Value:
(1 << 1)
sl power manager event transition leaving em0
231
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1#
#define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1Value:
(1 << 2)
sl power manager event transition entering em1
232
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1#
#define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1Value:
(1 << 3)
sl power manager event transition leaving em1
233
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2#
#define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2Value:
(1 << 4)
sl power manager event transition entering em2
234
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2#
#define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2Value:
(1 << 5)
sl power manager event transition leaving em2
235
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3#
#define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3Value:
(1 << 6)
sl power manager event transition entering em3 (DEPRECATED)
236
of file platform/service/power_manager/inc/sl_power_manager.h
SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3#
#define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3Value:
(1 << 7)
sl power manager event transition leaving em3 (DEPRECATED)
237
of file platform/service/power_manager/inc/sl_power_manager.h