1 /***************************************************************************//**
2 * @file
3 * @brief Power Manager API definition.
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #ifndef SL_POWER_MANAGER_H
32 #define SL_POWER_MANAGER_H
33
34 #ifndef SL_POWER_MANAGER_DEBUG
35 #include "sl_power_manager_config.h"
36 #endif
37 #include "sl_slist.h"
38 #include "sl_status.h"
39 #include "sl_sleeptimer.h"
40 #include "sl_enum.h"
41 #include "sl_core.h"
42 #include "sl_code_classification.h"
43
44 #include <stdbool.h>
45 #include <stdint.h>
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51 /***************************************************************************//**
52 * @addtogroup power_manager Power Manager
53 *
54 * @details Power manager is a platform level software module that manages
55 * the system's energy modes. Its main purpose is to transition the system to a
56 * low energy mode when the processor has nothing to execute. The energy mode the
57 * system will transition to is determined each time the system goes to sleep
58 * using requirements. These requirements are set by the different software modules
59 * (drivers, stacks, application code, etc...). Power manager also ensures a
60 * strict control of some power hungry resources such as the high frequency
61 * external oscillator (normally called HFXO). Power manager also
62 * offers a notification mechanism through which any piece of software module can be
63 * notified of energy mode transitions through callbacks.
64 *
65 * @note Sleep Driver is deprecated. Use Power Manager for all sleep-related
66 * operations. See <a href="https://www.silabs.com/documents/
67 * public/application-notes/
68 * an1358-migrating-from-sleep-driver-to-power-manager.pdf">AN1358:
69 * Migrating from Sleep Driver to Power Manager</a> for information on how
70 * to migrate from Sleep Driver to Power Manager.
71 * @note Emlib EMU functions EMU_EnterEM1()/EMU_EnterEM2()/EMU_EnterEM3() must not
72 * be used when the Power Manager is present. The Power Manager module must be
73 * the one deciding at which EM level the device sleeps to ensure the application
74 * properly works. Using both at the same time could lead to undefined behavior
75 * in the application.
76 *
77 * @details
78 * ## Initialization
79 *
80 * Power manager must be initialized prior to any call to power manager API.
81 * If sl_system is used, only sl_system_init() must be called, otherwise
82 * sl_power_manager_init() must be called manually. Note that power manager
83 * must be initialized after the clock(s), when initialized manually, as the
84 * power manager check which oscillators are used during the initialization phase.
85 *
86 * ## Add and remove requirements
87 *
88 * The drivers should add and remove energy mode requirements, at runtime, on the
89 * lowest energy mode for them depending on their state. When calling
90 * sl_power_manager_sleep(), the lowest possible Energy mode will be automatically
91 * selected.
92 *
93 * It is possible to add and remove requirements from ISR. If a specific energy mode
94 * is required in the ISR, but not required to generate the interrupt, a requirement
95 * on the energy mode can be added from the ISR. It is guaranteed that the associated
96 * clock will be active once sl_power_manager_add_requirement() returns. The EM
97 * requirement can be also be removed from an ISR.
98 *
99 * Requirements should not be removed if it was not previously added.
100 *
101 * ## Subscribe to events
102 *
103 * It possible to get notified when the system transition from a power level to
104 * another power level. This can allow to do some operations depending on which level
105 * the system goes, such as saving/restoring context.
106 *
107 * ## Sleep
108 *
109 * When the software has no more operation and only need to wait for an event, the
110 * software must call sl_power_manager_sleep(). This is automatically done when the
111 * kernel is present, but it needs to be called from the super loop in a baremetal
112 * project.
113 *
114 * ## Query callback functions
115 *
116 * ### Is OK to sleep
117 *
118 * Between the time `sl_power_manager_sleep` is called and the MCU is really put
119 * in a lower Energy mode, it is possible that an ISR occur and require the system
120 * to resume at that time instead of sleeping. So a callback is called in a critical
121 * section to validate that the MCU can go to sleep.
122 *
123 * In case of an application that runs on an RTOS, the RTOS will take care of determining
124 * if it is ok to sleep. In case of a baremetal application, the function `sl_power_manager_is_ok_to_sleep()`
125 * will be generated automatically by Simplicity Studio's wizard.
126 * The function will look at multiple software modules from the SDK to take a decision.
127 * The application can contribute to the decision by defining the function `app_is_ok_to_sleep()`.
128 * If any of the software modules (including the application via `app_is_ok_to_sleep()`) return false,
129 * the process of entering in sleep will be aborted.
130 *
131 * ### Sleep on ISR exit
132 *
133 * When the system enters sleep, the only way to wake it up is via an interrupt or
134 * exception. By default, power manager will assume that when an interrupt
135 * occurs and the corresponding ISR has been executed, the system must not go back
136 * to sleep. However, in the case where all the processing related to this interrupt
137 * is performed in the ISR, it is possible to go back to sleep by using this hook.
138 *
139 * In case of an application that runs on an RTOS, the RTOS will take care of determining
140 * if the system can go back to sleep on ISR exit. Power manager will ensure the system resumes
141 * its operations as soon as a task is resumed, posted or that its delay expires.
142 * In case of a baremetal application, the function `sl_power_manager_sleep_on_isr_exit()` will be generated
143 * automatically by Simplicity Studio's wizard. The function will look at multiple software modules from the SDK
144 * to take a decision. The application can contribute to the decision by defining the
145 * function `app_sleep_on_isr_exit()`.
146 * The generated function will take a decision based on the value returned by the different software modules
147 * (including the application via `app_sleep_on_isr_exit()`):
148 *
149 * `SL_POWER_MANAGER_IGNORE`: if the software module did not cause the system wakeup and/or doesn't want to contribute to the decision.
150 * `SL_POWER_MANAGER_SLEEP`: if the software module did cause the system wakeup, but the system should go back to sleep.
151 * `SL_POWER_MANAGER_WAKEUP`: if the software module did cause the system wakeup, and the system should not go back to sleep.
152 *
153 * If any software module returned `SL_POWER_MANAGER_SLEEP` and none returned `SL_POWER_MANAGER_WAKEUP`,
154 * the system will go back to sleep. Any other combination will cause the system not to go back to sleep.
155 *
156 * ### Debugging feature
157 *
158 * By setting the configuration define SL_POWER_MANAGER_DEBUG to 1, it is possible
159 * to record the requirements currently set and their owner. It is possible to print
160 * at any time a table that lists all the added requirements and their owner. This
161 * table can be printed by caling the function
162 * sl_power_manager_debug_print_em_requirements().
163 * Make sure to add the following define
164 * ```
165 * #define CURRENT_MODULE_NAME "<Module printable name here>"
166 * ```
167 * to any application code source file that adds and removes requirements.
168 *
169 * ## Usage Example
170 *
171 * ```
172 * #define EM_EVENT_MASK_ALL (SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0 \
173 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0 \
174 * | SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1 \
175 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1 \
176 * | SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2 \
177 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2 \
178 * | SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3 \
179 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3)
180 *
181 * sl_power_manager_em_transition_event_handle_t event_handle;
182 * sl_power_manager_em_transition_event_info_t event_info = {
183 * .event_mask = EM_EVENT_MASK_ALL,
184 * .on_event = my_events_callback,
185 * }
186 *
187 * void main(void)
188 * {
189 * // Initialize power manager; not needed if sl_system_init() is used.
190 * sl_power_manager_init();
191 *
192 * // Limit sleep level to EM1
193 * sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
194 *
195 * // Subscribe to all event types; get notified for every power transition.
196 * sl_power_manager_subscribe_em_transition_event(&event_handle, &event_info);
197 * while (1) {
198 * // Actions
199 * [...]
200 * if (completed) {
201 * // Remove energy mode requirement, can go to EM2 or EM3 now, depending on the configuration
202 * sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
203 * }
204 *
205 * // Sleep to lowest possible energy mode; This call is not needed when using the kernel.
206 * sl_power_manager_sleep();
207 * // Will resume after an interrupt or exception
208 * }
209 * }
210 *
211 * void my_events_callback(sl_power_manager_em_t from,
212 * sl_power_manager_em_t to)
213 * {
214 * printf("Event:%s-%s\r\n", string_lookup_table[from], string_lookup_table[to]);
215 * }
216 * ```
217 *
218 * @{
219 ******************************************************************************/
220
221 // -----------------------------------------------------------------------------
222 // Defines
223
224 // Current module name for debugging features
225 #ifndef CURRENT_MODULE_NAME
226 #define CURRENT_MODULE_NAME "Anonymous" ///< current module name
227 #endif
228
229 // Power transition events
230 #define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0 (1 << 0) ///< sl power manager event transition entering em0
231 #define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0 (1 << 1) ///< sl power manager event transition leaving em0
232 #define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1 (1 << 2) ///< sl power manager event transition entering em1
233 #define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1 (1 << 3) ///< sl power manager event transition leaving em1
234 #define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2 (1 << 4) ///< sl power manager event transition entering em2
235 #define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2 (1 << 5) ///< sl power manager event transition leaving em2
236 #define SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3 (1 << 6) ///< sl power manager event transition entering em3 (DEPRECATED)
237 #define SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3 (1 << 7) ///< sl power manager event transition leaving em3 (DEPRECATED)
238
239 // -----------------------------------------------------------------------------
240 // Data Types
241
242 /// @brief Energy modes
243 typedef enum {
244 SL_POWER_MANAGER_EM0 = 0, ///< Run Mode (Energy Mode 0)
245 SL_POWER_MANAGER_EM1, ///< Sleep Mode (Energy Mode 1)
246 SL_POWER_MANAGER_EM2, ///< Deep Sleep Mode (Energy Mode 2)
247 SL_POWER_MANAGER_EM3, ///< Stop Mode (Energy Mode 3)
248 SL_POWER_MANAGER_EM4, ///< Shutoff Mode (Energy Mode 4)
249 } sl_power_manager_em_t;
250
251 /// @brief Mask of all the event(s) to listen to.
252 typedef uint32_t sl_power_manager_em_transition_event_t;
253
254 /***************************************************************************//**
255 * Typedef for the user supplied callback function which is called when
256 * an energy mode transition occurs.
257 *
258 * @param from Energy mode we are leaving.
259 * @param to Energy mode we are entering.
260 ******************************************************************************/
261 typedef void (*sl_power_manager_em_transition_on_event_t)(sl_power_manager_em_t from,
262 sl_power_manager_em_t to);
263
264 /// @brief Struct representing energy mode transition event information
265 typedef struct {
266 const sl_power_manager_em_transition_event_t event_mask; ///< Mask of the transitions on which the callback should be called.
267 const sl_power_manager_em_transition_on_event_t on_event; ///< Function that must be called when the event occurs.
268 } sl_power_manager_em_transition_event_info_t;
269
270 /// @brief Struct representing energy mode transition event handle
271 typedef struct {
272 sl_slist_node_t node; ///< List node.
273 const sl_power_manager_em_transition_event_info_t *info; ///< Handle event info.
274 } sl_power_manager_em_transition_event_handle_t;
275
276 /// On ISR Exit Hook answer
SL_ENUM(sl_power_manager_on_isr_exit_t)277 SL_ENUM(sl_power_manager_on_isr_exit_t) {
278 SL_POWER_MANAGER_IGNORE = (1UL << 0UL), ///< The module did not trigger an ISR and it doesn't want to contribute to the decision
279 SL_POWER_MANAGER_SLEEP = (1UL << 1UL), ///< The module was the one that caused the system wakeup and the system SHOULD go back to sleep
280 SL_POWER_MANAGER_WAKEUP = (1UL << 2UL), ///< The module was the one that caused the system wakeup and the system MUST NOT go back to sleep
281 };
282
283 // -----------------------------------------------------------------------------
284 // Internal Prototypes only to be used by Power Manager module
285 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
286 void sli_power_manager_update_em_requirement(sl_power_manager_em_t em,
287 bool add);
288
289 // To make sure that we are able to optimize out the string argument when the
290 // debug feature is disable, we use a pre-processor macro resulting in a no-op.
291 // We also make sure to always have a definition for the function regardless if
292 // the debug feature is enable or not for binary compatibility.
293 #if (SL_POWER_MANAGER_DEBUG == 1)
294 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
295 void sli_power_manager_debug_log_em_requirement(sl_power_manager_em_t em,
296 bool add,
297 const char *name);
298 #else
299 #define sli_power_manager_debug_log_em_requirement(em, add, name) /* no-op */
300 #endif
301
302 // -----------------------------------------------------------------------------
303 // Prototypes
304
305 /***************************************************************************//**
306 * Initialize Power Manager module.
307 * @return Status code
308 ******************************************************************************/
309 sl_status_t sl_power_manager_init(void);
310
311 /***************************************************************************//**
312 * Sleep at the lowest allowed energy mode.
313 *
314 * @note Must not be called from ISR
315 * @par
316 * @note This function will expect and call a callback with the following
317 * signature: `bool sl_power_manager_is_ok_to_sleep(void)`.
318 *
319 * @note This function can be used to cancel a sleep action and handle the
320 * possible race condition where an ISR that would cause a wakeup is
321 * triggered right after the decision to call sl_power_manager_sleep()
322 * has been made.
323 *
324 * @note This function must NOT be called with interrupts disabled. This means
325 * both BASEPRI and PRIMASK MUST have a value of 0 when invoking this
326 * function.
327 *
328 * Usage example:
329 *
330 * ```c
331 * void main(void)
332 * {
333 * sl_power_manager_init();
334 * while (1) {
335 * tick();
336 * sl_power_manager_sleep();
337 * }
338 * }
339 * ```
340 ******************************************************************************/
341 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
342 void sl_power_manager_sleep(void);
343
344 /***************************************************************************//**
345 * Adds requirement on given energy mode.
346 *
347 * @param em Energy mode to add the requirement to:
348 * - ::SL_POWER_MANAGER_EM1
349 * - ::SL_POWER_MANAGER_EM2 (DEPRECATED)
350 *
351 * @note Adding EM requirements on SL_POWER_MANAGER_EM2 is now DEPRECATED.
352 * The calls can simply be removed since the system will go to deepsleep
353 * (EM2/EM3) in the absence of EM1 requirements.
354 ******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER,SL_CODE_CLASS_TIME_CRITICAL)355 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
356 __STATIC_INLINE void sl_power_manager_add_em_requirement(sl_power_manager_em_t em)
357 {
358 CORE_DECLARE_IRQ_STATE;
359
360 CORE_ENTER_CRITICAL();
361 sli_power_manager_update_em_requirement(em, true);
362
363 sli_power_manager_debug_log_em_requirement(em, true, (const char *)CURRENT_MODULE_NAME);
364 CORE_EXIT_CRITICAL();
365 }
366
367 /***************************************************************************//**
368 * Removes requirement on given energy mode.
369 *
370 * @param em Energy mode to remove the requirement to:
371 * - ::SL_POWER_MANAGER_EM1
372 * - ::SL_POWER_MANAGER_EM2 (DEPRECATED)
373 *
374 * @note Removing EM requirements on SL_POWER_MANAGER_EM2 is now DEPRECATED.
375 * The calls can simply be removed since the system will go to deepsleep
376 * (EM2/EM3) in the absence of EM1 requirements.
377 ******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER,SL_CODE_CLASS_TIME_CRITICAL)378 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
379 __STATIC_INLINE void sl_power_manager_remove_em_requirement(sl_power_manager_em_t em)
380 {
381 CORE_DECLARE_IRQ_STATE;
382
383 CORE_ENTER_CRITICAL();
384 sli_power_manager_update_em_requirement(em, false);
385
386 sli_power_manager_debug_log_em_requirement(em, false, (const char *)CURRENT_MODULE_NAME);
387 CORE_EXIT_CRITICAL();
388 }
389
390 /***************************************************************************//**
391 * Registers a callback to be called on given Energy Mode transition(s).
392 *
393 * @param event_handle Event handle (no initialization needed).
394 *
395 * @param event_info Event info structure that contains the event mask and the
396 * callback that must be called.
397 *
398 * @note Adding and removing requirement(s) from a callback on a transition event
399 * is not supported.
400 *
401 * @note The parameters passed must be persistent, meaning that they need to survive
402 * until the callback fires.
403 *
404 * @note SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM3 and
405 * SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM3 are now DEPRECATED and should
406 * not be used in the event_info argument.
407 *
408 * Usage example:
409 *
410 * ```c
411 * #define EM_EVENT_MASK_ALL ( SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM0 \
412 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM0 \
413 * | SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM1 \
414 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM1 \
415 * | SL_POWER_MANAGER_EVENT_TRANSITION_ENTERING_EM2 \
416 * | SL_POWER_MANAGER_EVENT_TRANSITION_LEAVING_EM2)
417 *
418 * sl_power_manager_em_transition_event_handle_t event_handle;
419 * sl_power_manager_em_transition_event_info_t event_info = {
420 * .event_mask = EM_EVENT_MASK_ALL,
421 * .on_event = my_callback,
422 * };
423 *
424 * void my_callback(sl_power_manager_em_t from,
425 * sl_power_manager_em_t to)
426 * {
427 * [...]
428 * }
429 *
430 * void main(void)
431 * {
432 * sl_power_manager_init();
433 * sl_power_manager_subscribe_em_transition_event(&event_handle, &event_info);
434 * }
435 * ```
436 ******************************************************************************/
437 void sl_power_manager_subscribe_em_transition_event(sl_power_manager_em_transition_event_handle_t *event_handle,
438 const sl_power_manager_em_transition_event_info_t *event_info);
439
440 /***************************************************************************//**
441 * Unregisters an event callback handle on Energy mode transition.
442 *
443 * @param event_handle Event handle which must be unregistered (must have been
444 * registered previously).
445 *
446 * @note An EFM_ASSERT is thrown if the handle is not found.
447 ******************************************************************************/
448 void sl_power_manager_unsubscribe_em_transition_event(sl_power_manager_em_transition_event_handle_t *event_handle);
449
450 /***************************************************************************//**
451 * Get configurable overhead value for early restore time in Sleeptimer ticks
452 * when a schedule wake-up is set.
453 *
454 * @return Current overhead value for early restore time.
455 *
456 * @note This function will do nothing when a project contains the
457 * power_manager_no_deepsleep component, which configures the
458 * lowest energy mode as EM1.
459 ******************************************************************************/
460 int32_t sl_power_manager_schedule_wakeup_get_restore_overhead_tick(void);
461
462 /***************************************************************************//**
463 * Set configurable overhead value for early restore time in Sleeptimer ticks
464 * used for schedule wake-up.
465 * Must be called after initialization else the value will be overwritten.
466 *
467 * @param overhead_tick Overhead value to set for early restore time.
468 *
469 * @note The overhead value can also be negative to remove time from the restore
470 * process.
471 *
472 * @note This function will do nothing when a project contains the
473 * power_manager_no_deepsleep component, which configures the
474 * lowest energy mode as EM1.
475 ******************************************************************************/
476 void sl_power_manager_schedule_wakeup_set_restore_overhead_tick(int32_t overhead_tick);
477
478 /***************************************************************************//**
479 * Get configurable minimum off-time value for schedule wake-up in Sleeptimer
480 * ticks.
481 *
482 * @return Current minimum off-time value for schedule wake-up.
483 *
484 * @note Turning on external high frequency clock, such as HFXO, requires more
485 * energy since we must supply higher current for the wake-up.
486 * Therefore, when an 'external high frequency clock enable' is scheduled
487 * in 'x' time, there is a threshold 'x' value where turning off the clock
488 * is not worthwhile since the energy consumed by taking into account the
489 * wake-up will be greater than if we just keep the clock on until the next
490 * scheduled clock enabled. This threshold value is what we refer as the
491 * minimum off-time.
492 *
493 * @note This function will do nothing when a project contains the
494 * power_manager_no_deepsleep component, which configures the
495 * lowest energy mode as EM1.
496 ******************************************************************************/
497 uint32_t sl_power_manager_schedule_wakeup_get_minimum_offtime_tick(void);
498
499 /***************************************************************************//**
500 * Set configurable minimum off-time value for schedule wake-up in Sleeptimer
501 * ticks.
502 *
503 * @param minimum_offtime_tick minimum off-time value to set for schedule
504 * wake-up.
505 *
506 * @note Turning on external high frequency clock, such as HFXO, requires more
507 * energy since we must supply higher current for the wake-up.
508 * Therefore, when an 'external high frequency clock enable' is scheduled
509 * in 'x' time, there is a threshold 'x' value where turning off the clock
510 * is not worthwhile since the energy consumed by taking into account the
511 * wake-up will be greater than if we just keep the clock on until the next
512 * scheduled clock enabled. This threshold value is what we refer as the
513 * minimum off-time.
514 *
515 * @note This function will do nothing when a project contains the
516 * power_manager_no_deepsleep component, which configures the
517 * lowest energy mode as EM1.
518 ******************************************************************************/
519 void sl_power_manager_schedule_wakeup_set_minimum_offtime_tick(uint32_t minimum_offtime_tick);
520
521 /***************************************************************************//**
522 * Enable or disable fast wake-up in EM2 and EM3
523 *
524 * @param enable True False variable act as a switch for this api
525 *
526 * @note Will also update the wake up time from EM2 to EM0.
527 *
528 * @note This function will do nothing when a project contains the
529 * power_manager_no_deepsleep component, which configures the
530 * lowest energy mode as EM1.
531 ******************************************************************************/
532 void sl_power_manager_em23_voltage_scaling_enable_fast_wakeup(bool enable);
533
534 /**************************************************************************//**
535 * Determines if the HFXO interrupt was part of the last wake-up and/or if
536 * the HFXO early wakeup expired during the last ISR
537 * and if it was the only timer to expire in that period.
538 *
539 * @return true if power manager sleep can return to sleep,
540 * false otherwise.
541 *
542 * @note This function will always return false in case a requirement
543 * is added on SL_POWER_MANAGER_EM1, since we will
544 * never sleep at a lower level than EM1.
545 *****************************************************************************/
546 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
547 bool sl_power_manager_is_latest_wakeup_internal(void);
548
549 /***************************************************************************//**
550 * Enter energy mode 4 (EM4).
551 *
552 * @note You should not expect to return from this function. Once the device
553 * enters EM4, only a power on reset or external reset pin can wake the
554 * device.
555 *
556 * @note On xG22 devices, this function re-configures the IADC if EM4 entry
557 * is possible.
558 ******************************************************************************/
559 void sl_power_manager_enter_em4(void);
560
561 /***************************************************************************//**
562 * When EM4 pin retention is set to power_manager_pin_retention_latch,
563 * then pins are retained through EM4 entry and wakeup. The pin state is
564 * released by calling this function. The feature allows peripherals or
565 * GPIO to be re-initialized after EM4 exit (reset), and when
566 * initialization is done, this function can release pins and return
567 * control to the peripherals or GPIO.
568 *
569 * @note When the EM4 Pin Retention feature is not available on a device,
570 * calling this function will do nothing.
571 ******************************************************************************/
572 void sl_power_manager_em4_unlatch_pin_retention(void);
573
574 /***************************************************************************//**
575 * Energy mode 4 pre-sleep hook function.
576 *
577 * @note This function is called by @ref sl_power_manager_enter_em4 just
578 * prior to the sequence of writes to put the device in EM4. The
579 * function implementation does not perform anything, but it is
580 * SL_WEAK so that it can be re-implemented in application code if
581 * actions are needed.
582 ******************************************************************************/
583 void sl_power_manager_em4_presleep_hook(void);
584
585 /** @} (end addtogroup power_manager) */
586
587 #ifdef __cplusplus
588 }
589 #endif
590
591 #endif // SL_POWER_MANAGER_H
592