1 /***************************************************************************//** 2 * @file 3 * @brief Power Manager Internal 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 #include "sl_power_manager.h" 32 #include "sl_slist.h" 33 #include "sl_code_classification.h" 34 35 #if defined(SL_COMPONENT_CATALOG_PRESENT) 36 #include "sl_component_catalog.h" 37 #endif 38 39 #if defined(SL_CATALOG_EMLIB_CORE_DEBUG_CONFIG_PRESENT) 40 #include "emlib_core_debug_config.h" 41 #endif 42 43 #if !defined(SL_EMLIB_CORE_ENABLE_INTERRUPT_DISABLED_TIMING) 44 #define SL_EMLIB_CORE_ENABLE_INTERRUPT_DISABLED_TIMING 0 45 #endif 46 47 #if (SL_EMLIB_CORE_ENABLE_INTERRUPT_DISABLED_TIMING == 1) 48 #include "sl_cycle_counter.h" 49 #endif 50 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 55 /******************************************************************************* 56 ******************************* DEFINES *********************************** 57 ******************************************************************************/ 58 59 #define SLI_POWER_MANAGER_EM_TABLE_SIZE 2 60 61 #define SLI_POWER_MANAGER_EM4_ENTRY_WAIT_LOOPS 200 62 /******************************************************************************* 63 ***************************** DATA TYPES ********************************* 64 ******************************************************************************/ 65 66 // Debug entry 67 typedef struct { 68 sl_slist_node_t node; 69 const char *module_name; 70 } sli_power_debug_requirement_entry_t; 71 72 /******************************************************************************* 73 ***************************** PROTOTYPES ********************************** 74 ******************************************************************************/ 75 76 void sli_power_manager_init_hardware(void); 77 78 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 79 void sli_power_manager_apply_em(sl_power_manager_em_t em); 80 81 void sli_power_manager_debug_init(void); 82 83 #if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) 84 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 85 void sli_power_manager_save_states(void); 86 87 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 88 void sli_power_manager_handle_pre_deepsleep_operations(void); 89 90 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 91 void sli_power_manager_restore_high_freq_accuracy_clk(void); 92 93 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 94 bool sli_power_manager_is_high_freq_accuracy_clk_ready(bool wait); 95 96 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 97 void sli_power_manager_restore_states(void); 98 99 /******************************************************************************* 100 * Converts microseconds time in sleeptimer ticks. 101 ******************************************************************************/ 102 uint32_t sli_power_manager_convert_delay_us_to_tick(uint32_t time_us); 103 104 /******************************************************************************* 105 * Returns the default minimum offtime for xtal high frequency oscillator. 106 ******************************************************************************/ 107 uint32_t sli_power_manager_get_default_high_frequency_minimum_offtime(void); 108 109 /******************************************************************************* 110 * Restores the Low Frequency clocks according to which LF oscillators are used. 111 ******************************************************************************/ 112 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 113 void sli_power_manager_low_frequency_restore(void); 114 115 /***************************************************************************//** 116 * Informs the power manager if the high accuracy/high frequency clock 117 * is used, prior to scheduling an early clock restore. 118 * 119 * @return true if HFXO is used, else false. 120 ******************************************************************************/ 121 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 122 bool sli_power_manager_is_high_freq_accuracy_clk_used(void); 123 #endif 124 125 /******************************************************************************* 126 * Gets the delay associated the wake-up process from EM23. 127 * 128 * @return Delay for the complete wake-up process with full restore. 129 ******************************************************************************/ 130 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 131 uint32_t sli_power_manager_get_wakeup_process_time_overhead(void); 132 133 #if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) 134 /******************************************************************************* 135 * Gets the status of power manager variable is_sleeping_waiting_for_clock_restore. 136 * 137 * @return true if Power Manager is sleeping waiting for clock restore, else false. 138 * 139 * @note FOR INTERNAL USE ONLY. 140 ******************************************************************************/ 141 bool sli_power_manager_get_clock_restore_status(void); 142 #endif 143 144 #if defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) 145 /******************************************************************************* 146 * HAL hook function for pre EM1HCLKDIV sleep. 147 * 148 * @note FOR INTERNAL USE ONLY. 149 ******************************************************************************/ 150 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 151 void sli_power_manager_em1hclkdiv_presleep_operations(void); 152 153 /******************************************************************************* 154 * HAL hook function for post EM1HCLKDIV sleep. 155 * 156 * @note FOR INTERNAL USE ONLY. 157 ******************************************************************************/ 158 SL_CODE_CLASSIFY(SL_CODE_COMPONENT_POWER_MANAGER, SL_CODE_CLASS_TIME_CRITICAL) 159 void sli_power_manager_em1hclkdiv_postsleep_operations(void); 160 #endif 161 162 #ifdef __cplusplus 163 } 164 #endif 165