1 /* 2 * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #include <stdbool.h> 10 #include <stddef.h> 11 #include <stdint.h> 12 #include <stdlib.h> 13 14 #include "soc/soc_caps.h" 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 #if SOC_PMU_SUPPORTED 21 #include "hal/pmu_hal.h" 22 #include "pmu_param.h" 23 24 #define RTC_SLEEP_PD_DIG PMU_SLEEP_PD_TOP //!< Deep sleep (power down digital domain, includes all power domains 25 // except CPU, Modem, LP peripheral, AON,VDDSDIO, MEM and clock power domains) 26 #define RTC_SLEEP_PD_RTC_PERIPH PMU_SLEEP_PD_LP_PERIPH //!< Power down RTC peripherals 27 #define RTC_SLEEP_PD_VDDSDIO PMU_SLEEP_PD_VDDSDIO //!< Power down VDDSDIO regulator 28 #define RTC_SLEEP_PD_CPU PMU_SLEEP_PD_CPU //!< Power down CPU when in lightsleep, but not restart 29 #define RTC_SLEEP_PD_DIG_PERIPH PMU_SLEEP_PD_HP_PERIPH //!< Power down DIG peripherals 30 #define RTC_SLEEP_PD_INT_8M PMU_SLEEP_PD_RC_FAST //!< Power down Internal 20M oscillator 31 #define RTC_SLEEP_PD_XTAL PMU_SLEEP_PD_XTAL //!< Power down main XTAL 32 #define RTC_SLEEP_PD_MODEM PMU_SLEEP_PD_MODEM //!< Power down modem(include wifi, ble and 15.4) 33 34 //These flags are not power domains, but will affect some sleep parameters 35 #define RTC_SLEEP_DIG_USE_8M BIT(16) 36 #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) 37 #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature 38 39 #if SOC_PM_SUPPORT_EXT0_WAKEUP 40 #define RTC_EXT0_TRIG_EN PMU_EXT0_WAKEUP_EN //!< EXT0 wakeup 41 #else 42 #define RTC_EXT0_TRIG_EN 0 43 #endif 44 45 #if SOC_PM_SUPPORT_EXT1_WAKEUP 46 #define RTC_EXT1_TRIG_EN PMU_EXT1_WAKEUP_EN //!< EXT1 wakeup 47 #else 48 #define RTC_EXT1_TRIG_EN 0 49 #endif 50 51 #define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup 52 53 #if SOC_LP_TIMER_SUPPORTED 54 #define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup 55 #else 56 #define RTC_TIMER_TRIG_EN 0 57 #endif 58 59 #if SOC_WIFI_SUPPORTED 60 #define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only) 61 #else 62 #define RTC_WIFI_TRIG_EN 0 63 #endif 64 65 #if SOC_UART_SUPPORT_WAKEUP_INT 66 #define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only) 67 #define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) 68 #else 69 #define RTC_UART0_TRIG_EN 0 70 #define RTC_UART1_TRIG_EN 0 71 #endif 72 73 #if SOC_BT_SUPPORTED 74 #define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only) 75 #else 76 #define RTC_BT_TRIG_EN 0 77 #endif 78 79 #define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN 80 81 #if SOC_LP_CORE_SUPPORTED 82 #define RTC_LP_CORE_TRIG_EN PMU_LP_CORE_WAKEUP_EN //!< LP core wakeup 83 #else 84 #define RTC_LP_CORE_TRIG_EN 0 85 #endif //SOC_LP_CORE_SUPPORTED 86 87 #define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO 88 #define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO 89 90 /** 91 * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip 92 */ 93 #define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN | \ 94 RTC_EXT1_TRIG_EN | \ 95 RTC_GPIO_TRIG_EN | \ 96 RTC_TIMER_TRIG_EN | \ 97 RTC_WIFI_TRIG_EN | \ 98 RTC_UART0_TRIG_EN | \ 99 RTC_UART1_TRIG_EN | \ 100 RTC_BT_TRIG_EN | \ 101 RTC_LP_CORE_TRIG_EN | \ 102 RTC_XTAL32K_DEAD_TRIG_EN | \ 103 RTC_USB_TRIG_EN | \ 104 RTC_BROWNOUT_DET_TRIG_EN) 105 106 #if SOC_PM_SUPPORT_EXT0_WAKEUP 107 #define PMU_EXT0_WAKEUP_EN BIT(0) 108 #endif 109 #if SOC_PM_SUPPORT_EXT1_WAKEUP 110 #define PMU_EXT1_WAKEUP_EN BIT(1) 111 #endif 112 113 #define PMU_GPIO_WAKEUP_EN BIT(2) 114 #define PMU_WIFI_BEACON_WAKEUP_EN BIT(3) 115 #define PMU_LP_TIMER_WAKEUP_EN BIT(4) 116 #define PMU_WIFI_SOC_WAKEUP_EN BIT(5) 117 #define PMU_UART0_WAKEUP_EN BIT(6) 118 #define PMU_UART1_WAKEUP_EN BIT(7) 119 #define PMU_SDIO_WAKEUP_EN BIT(8) 120 #define PMU_BLE_SOC_WAKEUP_EN BIT(10) 121 #if SOC_LP_CORE_SUPPORTED 122 #define PMU_LP_CORE_WAKEUP_EN BIT(11) 123 #endif //SOC_LP_CORE_SUPPORTED 124 #define PMU_USB_WAKEUP_EN BIT(14) 125 126 127 #define PMU_SLEEP_PD_TOP BIT(0) 128 #define PMU_SLEEP_PD_VDDSDIO BIT(1) 129 #define PMU_SLEEP_PD_MODEM BIT(2) 130 #define PMU_SLEEP_PD_HP_PERIPH BIT(3) 131 #define PMU_SLEEP_PD_CPU BIT(4) 132 133 #if SOC_PM_SUPPORT_HP_AON_PD 134 #define PMU_SLEEP_PD_HP_AON BIT(5) 135 #endif 136 137 #define PMU_SLEEP_PD_MEM_G0 BIT(6) 138 #define PMU_SLEEP_PD_MEM_G1 BIT(7) 139 #define PMU_SLEEP_PD_MEM_G2 BIT(8) 140 #define PMU_SLEEP_PD_MEM_G3 BIT(9) 141 #define PMU_SLEEP_PD_MEM (PMU_SLEEP_PD_MEM_G0|PMU_SLEEP_PD_MEM_G1|PMU_SLEEP_PD_MEM_G2|PMU_SLEEP_PD_MEM_G3) 142 #define PMU_SLEEP_PD_XTAL BIT(10) 143 #define PMU_SLEEP_PD_RC_FAST BIT(11) 144 #define PMU_SLEEP_PD_XTAL32K BIT(12) 145 #define PMU_SLEEP_PD_RC32K BIT(13) 146 #define PMU_SLEEP_PD_LP_PERIPH BIT(14) 147 148 typedef struct { 149 pmu_hal_context_t *hal; 150 void *mc; 151 } pmu_context_t; 152 153 pmu_context_t * PMU_instance(void); 154 155 typedef enum pmu_hp_sysclk_src { 156 PMU_HP_SYSCLK_XTAL = 0, 157 PMU_HP_SYSCLK_PLL, 158 PMU_HP_SYSCLK_FOSC 159 } pmu_hp_sysclk_src_t; 160 161 typedef enum pmu_sleep_protect_mode { 162 PMU_SLEEP_PROTECT_HP_SLEEP = 0, 163 PMU_SLEEP_PROTECT_XTAL, 164 PMU_SLEEP_PROTECT_HP_LP_SLEEP, 165 PMU_SLEEP_PROTECT_DISABLE 166 } pmu_sleep_protect_mode_t; 167 168 typedef enum pmu_sleep_regdma_entry { 169 PMU_SLEEP_REGDMA_ENTRY_0 = 0, 170 PMU_SLEEP_REGDMA_ENTRY_1, 171 PMU_SLEEP_REGDMA_ENTRY_2, 172 PMU_SLEEP_REGDMA_ENTRY_3, 173 PMU_SLEEP_REGDMA_ENTRY_MAX 174 } pmu_sleep_regdma_entry_t; 175 176 /** 177 * @brief PMU ICG modem code of HP system 178 */ 179 typedef enum { 180 PMU_HP_ICG_MODEM_CODE_SLEEP = 0, 181 PMU_HP_ICG_MODEM_CODE_MODEM = 1, 182 PMU_HP_ICG_MODEM_CODE_ACTIVE = 2, 183 } pmu_hp_icg_modem_mode_t; 184 185 186 /** 187 * @brief Enable_regdma_backup. 188 */ 189 void pmu_sleep_enable_regdma_backup(void); 190 191 /** 192 * @brief Disable_regdma_backup. 193 */ 194 void pmu_sleep_disable_regdma_backup(void); 195 196 /** 197 * @brief Get sleep PLL enable status 198 * 199 * @return true if PLL is enabled by PMU in modem state 200 */ 201 bool pmu_sleep_pll_already_enabled(void); 202 203 /** 204 * @brief Calculate the hardware time overhead during sleep to compensate for sleep time 205 * 206 * @param pd_flags flags indicates the power domain that will be powered down 207 * @param slowclk_period re-calibrated slow clock period 208 * @param fastclk_period re-calibrated fast clock period 209 * 210 * @return hardware time overhead in us 211 */ 212 uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period); 213 214 /** 215 * @brief Get default sleep configuration 216 * @param config pmu_sleep_config instance 217 * @param pd_flags flags indicates the power domain that will be powered down 218 * @param adjustment total software and hardware time overhead 219 * @param slowclk_period re-calibrated slow clock period in microseconds, 220 * Q13.19 fixed point format 221 * @param fastclk_period re-calibrated fast clock period in microseconds, 222 * Q13.19 fixed point format 223 * @param dslp configuration for deep sleep mode 224 225 * @return hardware time overhead in us 226 */ 227 const pmu_sleep_config_t* pmu_sleep_config_default(pmu_sleep_config_t *config, uint32_t pd_flags, uint32_t adjustment, uint32_t slowclk_period, uint32_t fastclk_period, bool dslp); 228 229 /** 230 * @brief Prepare the chip to enter sleep mode 231 * 232 * This function configures various power/analog parameters and lp/lp system configuration 233 * used in sleep state machines 234 * 235 * This function does not actually enter sleep mode; this is done using 236 * pmu_sleep_start function. Software may do some other actions between 237 * pmu_sleep_init and pmu_sleep_start, such as set wakeup timer and configure 238 * wakeup sources. 239 * 240 * @param config sleep mode configuration 241 * 242 * @param dslp is initialize for deep sleep mode 243 */ 244 void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp); 245 246 /** 247 * @brief Enter deep or light sleep mode 248 * 249 * This function enters the sleep mode previously configured using pmu_sleep_init 250 * function. Before entering sleep, software should configure wake up sources 251 * appropriately (set up GPIO wakeup registers, timer wakeup registers, 252 * and so on). 253 * 254 * If deep sleep mode was configured using pmu_sleep_init, and sleep is not 255 * rejected by hardware (based on reject_opt flags), this function never returns. 256 * When the chip wakes up from deep sleep, CPU is reset and execution starts 257 * from ROM bootloader. 258 * 259 * If light sleep mode was configured using pmu_sleep_init, this function 260 * returns on wakeup, or if sleep is rejected by hardware. 261 * 262 * @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags 263 * combined with OR) 264 * @param reject_opt bit mask of sleep reject reasons, used to 265 * prevent wakeup source set before the sleep request) 266 * @param lslp_mem_inf_fpu If non-zero then the low power config is restored 267 * immediately on wake. Recommended for light sleep, 268 * has no effect if the system goes into deep sleep. 269 * 270 * @return non-zero if sleep was rejected by hardware 271 */ 272 uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); 273 274 /** 275 * @brief Finish sleep process settings and get sleep reject status 276 * @return return sleep reject status 277 */ 278 bool pmu_sleep_finish(void); 279 280 /** 281 * @brief Initialize PMU related power/clock/digital parameters and functions 282 */ 283 void pmu_init(void); 284 285 /** 286 * @brief Enable or disable system clock in PMU HP sleep state 287 * 288 * This API only used for fix BLE 40 MHz low power clock source issue 289 * 290 * @param enable true to enable, false to disable 291 */ 292 void pmu_sleep_enable_hp_sleep_sysclk(bool enable); 293 294 /** 295 * Get the time overhead used by regdma to work on the retention link during the hardware wake-up process 296 * @return regdma time cost during hardware wake-up stage in microseconds 297 */ 298 uint32_t pmu_sleep_get_wakup_retention_cost(void); 299 300 #endif //#if SOC_PMU_SUPPORTED 301 302 #ifdef __cplusplus 303 } 304 #endif 305