2022-12-11 22:56:11 -05:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
2017-09-22 11:30:13 -04:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
/**
|
2019-03-21 00:21:01 -04:00
|
|
|
* @file esp_private/pm_impl.h
|
2017-09-22 11:30:13 -04:00
|
|
|
*
|
|
|
|
* This header file defines interface between PM lock functions (pm_locks.c)
|
|
|
|
* and the chip-specific power management (DFS/light sleep) implementation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "soc/rtc.h"
|
|
|
|
#include "esp_pm.h"
|
|
|
|
#include "esp_timer.h"
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
|
2020-07-21 05:15:19 -04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
2017-09-22 11:30:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This is an enum of possible power modes supported by the implementation
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
PM_MODE_LIGHT_SLEEP,//!< Light sleep
|
|
|
|
PM_MODE_APB_MIN, //!< Idle (no CPU frequency or APB frequency locks)
|
|
|
|
PM_MODE_APB_MAX, //!< Maximum APB frequency mode
|
|
|
|
PM_MODE_CPU_MAX, //!< Maximum CPU frequency mode
|
|
|
|
PM_MODE_COUNT //!< Number of items
|
|
|
|
} pm_mode_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the mode corresponding to a certain lock
|
|
|
|
* @param type lock type
|
|
|
|
* @param arg argument value for this lock (passed to esp_pm_lock_create)
|
|
|
|
* @return lowest power consumption mode which meets the constraints of the lock
|
|
|
|
*/
|
|
|
|
pm_mode_t esp_pm_impl_get_mode(esp_pm_lock_type_t type, int arg);
|
|
|
|
|
2021-02-22 21:17:27 -05:00
|
|
|
/**
|
|
|
|
* @brief Get CPU clock frequency by power mode
|
|
|
|
* @param mode power mode
|
|
|
|
* @return CPU clock frequency
|
|
|
|
*/
|
|
|
|
int esp_pm_impl_get_cpu_freq(pm_mode_t mode);
|
|
|
|
|
2017-09-22 11:30:13 -04:00
|
|
|
/**
|
|
|
|
* If profiling is enabled, this data type will be used to store microsecond
|
|
|
|
* timestamps.
|
|
|
|
*/
|
|
|
|
typedef int64_t pm_time_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* See \ref esp_pm_impl_switch_mode
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
MODE_LOCK,
|
|
|
|
MODE_UNLOCK
|
|
|
|
} pm_mode_switch_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Switch between power modes when lock is taken or released
|
|
|
|
* @param mode pm_mode_t corresponding to the lock being taken or released,
|
|
|
|
* as returned by \ref esp_pm_impl_get_mode
|
|
|
|
* @param lock_or_unlock
|
|
|
|
* - MODE_LOCK: lock was taken. Implementation needs to make sure
|
|
|
|
* that the constraints of the lock are met by switching to the
|
|
|
|
* given 'mode' or any of the higher power ones.
|
|
|
|
* - MODE_UNLOCK: lock was released. If all the locks for given
|
|
|
|
* mode are released, and no locks for higher power modes are
|
|
|
|
* taken, implementation can switch to one of lower power modes.
|
|
|
|
* @param now timestamp when the lock was taken or released. Passed as
|
|
|
|
* a minor optimization, so that the implementation does not need to
|
|
|
|
* call pm_get_time again.
|
|
|
|
*/
|
|
|
|
void esp_pm_impl_switch_mode(pm_mode_t mode, pm_mode_switch_t lock_or_unlock, pm_time_t now);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Call once at startup to initialize pm implementation
|
|
|
|
*/
|
2019-07-16 05:33:30 -04:00
|
|
|
void esp_pm_impl_init(void);
|
2017-09-22 11:30:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Hook function for the idle task
|
|
|
|
* Must be called from the IDLE task on each CPU before entering waiti state.
|
|
|
|
*/
|
2019-07-16 05:33:30 -04:00
|
|
|
void esp_pm_impl_idle_hook(void);
|
2017-09-22 11:30:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Hook function for the interrupt dispatcher
|
|
|
|
* Must be called soon after entering the ISR
|
|
|
|
*/
|
2019-07-16 05:33:30 -04:00
|
|
|
void esp_pm_impl_isr_hook(void);
|
2017-09-22 11:30:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Dump the information about time spent in each of the pm modes.
|
|
|
|
*
|
|
|
|
* Prints three columns:
|
|
|
|
* mode name, total time in mode (in microseconds), percentage of time in mode
|
|
|
|
*
|
|
|
|
* @param out stream to dump the information to
|
|
|
|
*/
|
|
|
|
void esp_pm_impl_dump_stats(FILE* out);
|
|
|
|
|
2018-09-25 13:10:32 -04:00
|
|
|
/**
|
|
|
|
* @brief Hook function implementing `waiti` instruction, should be invoked from idle task context
|
|
|
|
*/
|
2019-07-16 05:33:30 -04:00
|
|
|
void esp_pm_impl_waiti(void);
|
2017-09-22 11:30:13 -04:00
|
|
|
|
2020-05-07 04:15:56 -04:00
|
|
|
/**
|
|
|
|
* @brief Callback function type for peripherals to skip light sleep.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
typedef bool (* skip_light_sleep_cb_t)(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Register peripherals skip light sleep callback
|
|
|
|
*
|
|
|
|
* This function allows you to register a callback that gets the result
|
|
|
|
* that if light sleep should be skipped by peripherals.
|
2020-11-10 02:40:01 -05:00
|
|
|
* @param cb function to get the result
|
2020-05-07 04:15:56 -04:00
|
|
|
* @return
|
|
|
|
* - ESP_OK on success
|
|
|
|
* - ESP_ERR_NO_MEM if no more callback slots are available
|
|
|
|
*/
|
|
|
|
esp_err_t esp_pm_register_skip_light_sleep_callback(skip_light_sleep_cb_t cb);
|
|
|
|
|
|
|
|
/**
|
2020-11-10 02:40:01 -05:00
|
|
|
* @brief Unregisterperipherals skip light sleep callback
|
2020-05-07 04:15:56 -04:00
|
|
|
*
|
|
|
|
* This function allows you to unregister a callback which was previously
|
|
|
|
* registered using esp_register_skip_light_sleep_callback.
|
2020-11-10 02:40:01 -05:00
|
|
|
* @param cb function to get the result
|
2020-05-07 04:15:56 -04:00
|
|
|
* @return
|
|
|
|
* - ESP_OK on success
|
|
|
|
* - ESP_ERR_INVALID_STATE if the given callback hasn't been registered before
|
|
|
|
*/
|
|
|
|
esp_err_t esp_pm_unregister_skip_light_sleep_callback(skip_light_sleep_cb_t cb);
|
2020-12-30 03:42:39 -05:00
|
|
|
|
2017-09-22 11:30:13 -04:00
|
|
|
#ifdef CONFIG_PM_PROFILING
|
|
|
|
#define WITH_PROFILING
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef WITH_PROFILING
|
2019-07-16 05:33:30 -04:00
|
|
|
static inline pm_time_t IRAM_ATTR pm_get_time(void)
|
2017-09-22 11:30:13 -04:00
|
|
|
{
|
|
|
|
return esp_timer_get_time();
|
|
|
|
}
|
|
|
|
#endif // WITH_PROFILING
|
2020-07-21 05:15:19 -04:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
2020-11-10 02:40:01 -05:00
|
|
|
#endif
|