1 /*
2  * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 #include <stdint.h>
9 #include <stdbool.h>
10 #include "esp_err.h"
11 #include "sdkconfig.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /**
18  * @brief Power management config
19  *
20  * Pass a pointer to this structure as an argument to esp_pm_configure function.
21  */
22 typedef struct {
23     int max_freq_mhz;         /*!< Maximum CPU frequency, in MHz */
24     int min_freq_mhz;         /*!< Minimum CPU frequency to use when no locks are taken, in MHz */
25     bool light_sleep_enable;  /*!< Enter light sleep when no locks are taken */
26 } esp_pm_config_t;
27 
28 /**
29  * backward compatibility
30  * newer chips no longer require this typedef
31  */
32 typedef esp_pm_config_t esp_pm_config_esp32_t   __attribute__((deprecated("please use esp_pm_config_t instead")));
33 typedef esp_pm_config_t esp_pm_config_esp32s2_t __attribute__((deprecated("please use esp_pm_config_t instead")));
34 typedef esp_pm_config_t esp_pm_config_esp32s3_t __attribute__((deprecated("please use esp_pm_config_t instead")));
35 typedef esp_pm_config_t esp_pm_config_esp32c3_t __attribute__((deprecated("please use esp_pm_config_t instead")));
36 typedef esp_pm_config_t esp_pm_config_esp32c2_t __attribute__((deprecated("please use esp_pm_config_t instead")));
37 typedef esp_pm_config_t esp_pm_config_esp32c6_t __attribute__((deprecated("please use esp_pm_config_t instead")));
38 
39 /**
40  * @brief Power management constraints
41  */
42 typedef enum {
43     /**
44      * Require CPU frequency to be at the maximum value set via esp_pm_configure.
45      * Argument is unused and should be set to 0.
46      */
47     ESP_PM_CPU_FREQ_MAX,
48     /**
49      * Require APB frequency to be at the maximum value supported by the chip.
50      * Argument is unused and should be set to 0.
51      */
52     ESP_PM_APB_FREQ_MAX,
53     /**
54      * Prevent the system from going into light sleep.
55      * Argument is unused and should be set to 0.
56      */
57     ESP_PM_NO_LIGHT_SLEEP,
58 } esp_pm_lock_type_t;
59 
60 /**
61  * @brief Set implementation-specific power management configuration
62  * @param config pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32)
63  * @return
64  *      - ESP_OK on success
65  *      - ESP_ERR_INVALID_ARG if the configuration values are not correct
66  *      - ESP_ERR_NOT_SUPPORTED if certain combination of values is not supported,
67  *        or if CONFIG_PM_ENABLE is not enabled in sdkconfig
68  */
69 esp_err_t esp_pm_configure(const void* config);
70 
71 /**
72  * @brief Get implementation-specific power management configuration
73  * @param config pointer to implementation-specific configuration structure (e.g. esp_pm_config_esp32)
74  * @return
75  *      - ESP_OK on success
76  *      - ESP_ERR_INVALID_ARG if the pointer is null
77  */
78 esp_err_t esp_pm_get_configuration(void* config);
79 
80 /**
81  * @brief Opaque handle to the power management lock
82  */
83 typedef struct esp_pm_lock* esp_pm_lock_handle_t;
84 
85 
86 /**
87  * @brief Initialize a lock handle for certain power management parameter
88  *
89  * When lock is created, initially it is not taken.
90  * Call esp_pm_lock_acquire to take the lock.
91  *
92  * This function must not be called from an ISR.
93  *
94  * @param lock_type Power management constraint which the lock should control
95  * @param arg argument, value depends on lock_type, see esp_pm_lock_type_t
96  * @param name arbitrary string identifying the lock (e.g. "wifi" or "spi").
97  *             Used by the esp_pm_dump_locks function to list existing locks.
98  *             May be set to NULL. If not set to NULL, must point to a string which is valid
99  *             for the lifetime of the lock.
100  * @param[out] out_handle  handle returned from this function. Use this handle when calling
101  *                         esp_pm_lock_delete, esp_pm_lock_acquire, esp_pm_lock_release.
102  *                         Must not be NULL.
103  * @return
104  *      - ESP_OK on success
105  *      - ESP_ERR_NO_MEM if the lock structure can not be allocated
106  *      - ESP_ERR_INVALID_ARG if out_handle is NULL or type argument is not valid
107  *      - ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig
108  */
109 esp_err_t esp_pm_lock_create(esp_pm_lock_type_t lock_type, int arg,
110         const char* name, esp_pm_lock_handle_t* out_handle);
111 
112 /**
113  * @brief Take a power management lock
114  *
115  * Once the lock is taken, power management algorithm will not switch to the
116  * mode specified in a call to esp_pm_lock_create, or any of the lower power
117  * modes (higher numeric values of 'mode').
118  *
119  * The lock is recursive, in the sense that if esp_pm_lock_acquire is called
120  * a number of times, esp_pm_lock_release has to be called the same number of
121  * times in order to release the lock.
122  *
123  * This function may be called from an ISR.
124  *
125  * This function is not thread-safe w.r.t. calls to other esp_pm_lock_*
126  * functions for the same handle.
127  *
128  * @param handle handle obtained from esp_pm_lock_create function
129  * @return
130  *      - ESP_OK on success
131  *      - ESP_ERR_INVALID_ARG if the handle is invalid
132  *      - ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig
133  */
134 esp_err_t esp_pm_lock_acquire(esp_pm_lock_handle_t handle);
135 
136 /**
137  * @brief Release the lock taken using esp_pm_lock_acquire.
138  *
139  * Call to this functions removes power management restrictions placed when
140  * taking the lock.
141  *
142  * Locks are recursive, so if esp_pm_lock_acquire is called a number of times,
143  * esp_pm_lock_release has to be called the same number of times in order to
144  * actually release the lock.
145  *
146  * This function may be called from an ISR.
147  *
148  * This function is not thread-safe w.r.t. calls to other esp_pm_lock_*
149  * functions for the same handle.
150  *
151  * @param handle handle obtained from esp_pm_lock_create function
152  * @return
153  *      - ESP_OK on success
154  *      - ESP_ERR_INVALID_ARG if the handle is invalid
155  *      - ESP_ERR_INVALID_STATE if lock is not acquired
156  *      - ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig
157  */
158 esp_err_t esp_pm_lock_release(esp_pm_lock_handle_t handle);
159 
160 /**
161  * @brief Delete a lock created using esp_pm_lock
162  *
163  * The lock must be released before calling this function.
164  *
165  * This function must not be called from an ISR.
166  *
167  * @param handle handle obtained from esp_pm_lock_create function
168  * @return
169  *      - ESP_OK on success
170  *      - ESP_ERR_INVALID_ARG if the handle argument is NULL
171  *      - ESP_ERR_INVALID_STATE if the lock is still acquired
172  *      - ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig
173  */
174 esp_err_t esp_pm_lock_delete(esp_pm_lock_handle_t handle);
175 
176 /**
177  * Dump the list of all locks to stderr
178  *
179  * This function dumps debugging information about locks created using
180  * esp_pm_lock_create to an output stream.
181  *
182  * This function must not be called from an ISR. If esp_pm_lock_acquire/release
183  * are called while this function is running, inconsistent results may be
184  * reported.
185  *
186  * @param stream stream to print information to; use stdout or stderr to print
187  *               to the console; use fmemopen/open_memstream to print to a
188  *               string buffer.
189  * @return
190  *      - ESP_OK on success
191  *      - ESP_ERR_NOT_SUPPORTED if CONFIG_PM_ENABLE is not enabled in sdkconfig
192  */
193 esp_err_t esp_pm_dump_locks(FILE* stream);
194 
195 #ifdef __cplusplus
196 }
197 #endif
198