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

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.

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#

enum
SL_POWER_MANAGER_EM0 = 0
SL_POWER_MANAGER_EM1
SL_POWER_MANAGER_EM2
SL_POWER_MANAGER_EM3
SL_POWER_MANAGER_EM4
}

Energy modes.

enum
SL_POWER_MANAGER_IGNORE = (1UL << 0UL)
SL_POWER_MANAGER_SLEEP = (1UL << 1UL)
SL_POWER_MANAGER_WAKEUP = (1UL << 2UL)
}

On ISR Exit Hook answer.

Typedefs#

typedef uint32_t

Mask of all the event(s) to listen to.

typedef void(*
sl_power_manager_em_transition_on_event_t)(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.

Functions#

void

Print a table that describes the current requirements on each energy mode and their owner.

sl_status_t

Initialize Power Manager module.

void

Sleep at the lowest allowed energy mode.

void
sl_power_manager_add_em_requirement(sl_power_manager_em_t em)

Adds requirement on given energy mode.

void
sl_power_manager_remove_em_requirement(sl_power_manager_em_t em)

Removes requirement on given energy mode.

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).

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.

int32_t

Get configurable overhead value for early restore time in Sleeptimer ticks when a schedule wake-up is set.

void

Set configurable overhead value for early restore time in Sleeptimer ticks used for schedule wake-up.

uint32_t

Get configurable minimum off-time value for schedule wake-up in Sleeptimer ticks.

void

Set configurable minimum off-time value for schedule wake-up in Sleeptimer ticks.

void

Enable or disable fast wake-up in EM2 and EM3.

bool

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.

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)


Definition at line 237 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.


Definition at line 271 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.


Definition at line 246 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.

Parameters
N/Afrom

Energy mode we are leaving.

N/Ato

Energy mode we are entering.


Definition at line 255 of file platform/service/power_manager/inc/sl_power_manager.h

Function Documentation#

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.

Parameters
N/A

Definition at line 52 of file platform/service/power_manager/inc/sl_power_manager_debug.h

sl_power_manager_init#

sl_status_t sl_power_manager_init (void )

Initialize Power Manager module.

Parameters
N/A

Returns

  • Status code


Definition at line 301 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.

Parameters
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.

Usage example:

void main(void)
{
  sl_power_manager_init();
  while (1) {
    tick();
    sl_power_manager_sleep();
  }
}

Definition at line 331 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.

Parameters
N/Aem

Energy mode to add the requirement to:


Definition at line 340 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.

Parameters
N/Aem

Energy mode to remove the requirement to:


Definition at line 358 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).

Parameters
N/Aevent_handle

Event handle (no initialization needed).

N/Aevent_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.

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_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);
}

Definition at line 414 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.

Parameters
N/Aevent_handle

Event handle which must be unregistered (must have been registered previously).

Note

  • An EFM_ASSERT is thrown if the handle is not found.


Definition at line 425 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.

Parameters
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.


Definition at line 437 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.

Parameters
N/Aoverhead_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.


Definition at line 453 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.

Parameters
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.


Definition at line 474 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.

Parameters
N/Aminimum_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.


Definition at line 496 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.

Parameters
N/Aenable

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.


Definition at line 507 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.

Parameters
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.


Definition at line 521 of file platform/service/power_manager/inc/sl_power_manager.h

Macro Definition Documentation#

CURRENT_MODULE_NAME#

#define CURRENT_MODULE_NAME
Value:
"Anonymous"

Definition at line 219 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_EM0
Value:
(1 << 0)

Definition at line 223 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_EM0
Value:
(1 << 1)

Definition at line 224 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_EM1
Value:
(1 << 2)

Definition at line 225 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_EM1
Value:
(1 << 3)

Definition at line 226 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_EM2
Value:
(1 << 4)

Definition at line 227 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_EM2
Value:
(1 << 5)

Definition at line 228 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_EM3
Value:
(1 << 6)

Definition at line 229 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_EM3
Value:
(1 << 7)

Definition at line 230 of file platform/service/power_manager/inc/sl_power_manager.h