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