/* * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include #include #include #include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { #endif #if SOC_PMU_SUPPORTED #include "hal/pmu_hal.h" #include "pmu_param.h" #define RTC_SLEEP_PD_DIG PMU_SLEEP_PD_TOP //!< Deep sleep (power down digital domain, includes all power domains // except CPU, Modem, LP peripheral, AON,VDDSDIO, MEM and clock power domains) #define RTC_SLEEP_PD_RTC_PERIPH PMU_SLEEP_PD_LP_PERIPH //!< Power down RTC peripherals #define RTC_SLEEP_PD_VDDSDIO PMU_SLEEP_PD_VDDSDIO //!< Power down VDDSDIO regulator #define RTC_SLEEP_PD_CPU PMU_SLEEP_PD_CPU //!< Power down CPU when in lightsleep, but not restart #define RTC_SLEEP_PD_DIG_PERIPH PMU_SLEEP_PD_HP_PERIPH //!< Power down DIG peripherals #define RTC_SLEEP_PD_INT_8M PMU_SLEEP_PD_RC_FAST //!< Power down Internal 20M oscillator #define RTC_SLEEP_PD_XTAL PMU_SLEEP_PD_XTAL //!< Power down main XTAL #define RTC_SLEEP_PD_MODEM PMU_SLEEP_PD_MODEM //!< Power down modem(include wifi, ble and 15.4) //These flags are not power domains, but will affect some sleep parameters #define RTC_SLEEP_DIG_USE_8M BIT(16) #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #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 #if SOC_PM_SUPPORT_EXT0_WAKEUP #define RTC_EXT0_TRIG_EN PMU_EXT0_WAKEUP_EN //!< EXT0 wakeup #else #define RTC_EXT0_TRIG_EN 0 #endif #if SOC_PM_SUPPORT_EXT1_WAKEUP #define RTC_EXT1_TRIG_EN PMU_EXT1_WAKEUP_EN //!< EXT1 wakeup #endif #define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup #define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup #define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only) #define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only) #define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) #define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only) #define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN #if SOC_LP_CORE_SUPPORTED #define RTC_LP_CORE_TRIG_EN PMU_LP_CORE_WAKEUP_EN //!< LP core wakeup #endif //SOC_LP_CORE_SUPPORTED #define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO #define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO /** * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip */ #define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \ RTC_TIMER_TRIG_EN | \ RTC_WIFI_TRIG_EN | \ RTC_UART0_TRIG_EN | \ RTC_UART1_TRIG_EN | \ RTC_BT_TRIG_EN | \ RTC_XTAL32K_DEAD_TRIG_EN | \ RTC_USB_TRIG_EN | \ RTC_BROWNOUT_DET_TRIG_EN) #if SOC_PM_SUPPORT_EXT0_WAKEUP #define PMU_EXT0_WAKEUP_EN BIT(0) #endif #if SOC_PM_SUPPORT_EXT1_WAKEUP #define PMU_EXT1_WAKEUP_EN BIT(1) #endif #define PMU_GPIO_WAKEUP_EN BIT(2) #define PMU_WIFI_BEACON_WAKEUP_EN BIT(3) #define PMU_LP_TIMER_WAKEUP_EN BIT(4) #define PMU_WIFI_SOC_WAKEUP_EN BIT(5) #define PMU_UART0_WAKEUP_EN BIT(6) #define PMU_UART1_WAKEUP_EN BIT(7) #define PMU_SDIO_WAKEUP_EN BIT(8) #define PMU_BLE_SOC_WAKEUP_EN BIT(10) #if SOC_LP_CORE_SUPPORTED #define PMU_LP_CORE_WAKEUP_EN BIT(11) #endif //SOC_LP_CORE_SUPPORTED #define PMU_USB_WAKEUP_EN BIT(14) #define PMU_SLEEP_PD_TOP BIT(0) #define PMU_SLEEP_PD_VDDSDIO BIT(1) #define PMU_SLEEP_PD_MODEM BIT(2) #define PMU_SLEEP_PD_HP_PERIPH BIT(3) #define PMU_SLEEP_PD_CPU BIT(4) #define PMU_SLEEP_PD_AON BIT(5) #define PMU_SLEEP_PD_MEM_G0 BIT(6) #define PMU_SLEEP_PD_MEM_G1 BIT(7) #define PMU_SLEEP_PD_MEM_G2 BIT(8) #define PMU_SLEEP_PD_MEM_G3 BIT(9) #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) #define PMU_SLEEP_PD_XTAL BIT(10) #define PMU_SLEEP_PD_RC_FAST BIT(11) #define PMU_SLEEP_PD_XTAL32K BIT(12) #define PMU_SLEEP_PD_RC32K BIT(13) #define PMU_SLEEP_PD_LP_PERIPH BIT(14) typedef struct { pmu_hal_context_t *hal; void *mc; } pmu_context_t; pmu_context_t * PMU_instance(void); typedef enum pmu_hp_sysclk_src { PMU_HP_SYSCLK_XTAL = 0, PMU_HP_SYSCLK_PLL, PMU_HP_SYSCLK_FOSC } pmu_hp_sysclk_src_t; typedef enum pmu_sleep_protect_mode { PMU_SLEEP_PROTECT_HP_SLEEP = 0, PMU_SLEEP_PROTECT_XTAL, PMU_SLEEP_PROTECT_HP_LP_SLEEP, PMU_SLEEP_PROTECT_DISABLE } pmu_sleep_protect_mode_t; typedef enum pmu_sleep_regdma_entry { PMU_SLEEP_REGDMA_ENTRY_0 = 0, PMU_SLEEP_REGDMA_ENTRY_1, PMU_SLEEP_REGDMA_ENTRY_2, PMU_SLEEP_REGDMA_ENTRY_3, PMU_SLEEP_REGDMA_ENTRY_MAX } pmu_sleep_regdma_entry_t; /** * @brief PMU ICG modem code of HP system */ typedef enum { PMU_HP_ICG_MODEM_CODE_SLEEP = 0, PMU_HP_ICG_MODEM_CODE_MODEM = 1, PMU_HP_ICG_MODEM_CODE_ACTIVE = 2, } pmu_hp_icg_modem_mode_t; /** * @brief Enable_regdma_backup. */ void pmu_sleep_enable_regdma_backup(void); /** * @brief Disable_regdma_backup. */ void pmu_sleep_disable_regdma_backup(void); /** * @brief Get sleep PLL enable status * * @return true if PLL is enabled by PMU in modem state */ bool pmu_sleep_pll_already_enabled(void); /** * @brief Calculate the hardware time overhead during sleep to compensate for sleep time * * @param pd_flags flags indicates the power domain that will be powered down * @param slowclk_period re-calibrated slow clock period * @param fastclk_period re-calibrated fast clock period * * @return hardware time overhead in us */ uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period); /** * @brief Get default sleep configuration * @param config pmu_sleep_config instance * @param pd_flags flags indicates the power domain that will be powered down * @param adjustment total software and hardware time overhead * @param slowclk_period re-calibrated slow clock period in microseconds, * Q13.19 fixed point format * @param fastclk_period re-calibrated fast clock period in microseconds, * Q13.19 fixed point format * @param dslp configuration for deep sleep mode * @return hardware time overhead in us */ 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); /** * @brief Prepare the chip to enter sleep mode * * This function configures various power/analog parameters and lp/lp system configuration * used in sleep state machines * * This function does not actually enter sleep mode; this is done using * pmu_sleep_start function. Software may do some other actions between * pmu_sleep_init and pmu_sleep_start, such as set wakeup timer and configure * wakeup sources. * * @param config sleep mode configuration * * @param dslp is initialize for deep sleep mode */ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp); /** * @brief Enter deep or light sleep mode * * This function enters the sleep mode previously configured using pmu_sleep_init * function. Before entering sleep, software should configure wake up sources * appropriately (set up GPIO wakeup registers, timer wakeup registers, * and so on). * * If deep sleep mode was configured using pmu_sleep_init, and sleep is not * rejected by hardware (based on reject_opt flags), this function never returns. * When the chip wakes up from deep sleep, CPU is reset and execution starts * from ROM bootloader. * * If light sleep mode was configured using pmu_sleep_init, this function * returns on wakeup, or if sleep is rejected by hardware. * * @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags * combined with OR) * @param reject_opt bit mask of sleep reject reasons, used to * prevent wakeup source set before the sleep request) * @param lslp_mem_inf_fpu If non-zero then the low power config is restored * immediately on wake. Recommended for light sleep, * has no effect if the system goes into deep sleep. * * @return non-zero if sleep was rejected by hardware */ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); /** * @brief Initialize PMU related power/clock/digital parameters and functions */ void pmu_init(void); #endif //#if SOC_PMU_SUPPORTED #ifdef __cplusplus } #endif