1 /*
2 * Copyright (c) 2017 - 2025, Nordic Semiconductor ASA
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef NRFX_POWER_H__
35 #define NRFX_POWER_H__
36
37 #include <nrfx.h>
38 #include <hal/nrf_power.h>
39 #include <nrfx_power_clock.h>
40 #include "nrfx_power_compat.h"
41
42 #if defined(REGULATORS_PRESENT)
43 #include <hal/nrf_regulators.h>
44 #endif
45
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49
50 /**
51 * @defgroup nrfx_power POWER driver
52 * @{
53 * @ingroup nrf_power
54 * @brief POWER peripheral driver.
55 */
56
57 #if NRF_POWER_HAS_POFCON || (defined(REGULATORS_PRESENT) && NRF_REGULATORS_HAS_POF) \
58 || defined(__NRFX_DOXYGEN__)
59 /** @brief Symbol indicating whether the power failure comparator is supported. */
60 #define NRFX_POWER_SUPPORTS_POFCON 1
61 #else
62 #define NRFX_POWER_SUPPORTS_POFCON 0
63 #endif
64
65 #if NRF_POWER_HAS_POFCON_VDDH || (defined(REGULATORS_PRESENT) && NRF_REGULATORS_HAS_POF_VDDH) \
66 || defined(__NRFX_DOXYGEN__)
67 /** @brief Symbol indicating whether the power failure comparator for VDDH is supported. */
68 #define NRFX_POWER_SUPPORTS_POFCON_VDDH 1
69 #else
70 #define NRFX_POWER_SUPPORTS_POFCON_VDDH 0
71 #endif
72
73 #if NRF_POWER_HAS_DCDCEN_VDDH || (defined(REGULATORS_PRESENT) && NRF_REGULATORS_HAS_VREG_HIGH) \
74 || defined(__NRFX_DOXYGEN__)
75 /** @brief Symbol indicating whether the VDDH regulator is supported. */
76 #define NRFX_POWER_SUPPORTS_DCDCEN_VDDH 1
77 #else
78 #define NRFX_POWER_SUPPORTS_DCDCEN_VDDH 0
79 #endif
80
81 /**
82 * @brief Sub-power mode possible configurations
83 */
84 typedef enum
85 {
86 #if NRF_POWER_HAS_CONST_LATENCY || defined(__NRFX_DOXYGEN__)
87 NRFX_POWER_MODE_CONSTLAT, ///< Constant Latency mode.
88 #endif
89 #if NRF_POWER_HAS_LOW_POWER || defined(__NRFX_DOXYGEN__)
90 NRFX_POWER_MODE_LOWPWR ///< Low Power mode.
91 #endif
92 } nrfx_power_mode_t;
93
94 #if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
95 /**
96 * @brief Events from power system
97 */
98 typedef enum
99 {
100 NRFX_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep
101 *
102 * Keep in mind that if this interrupt is enabled,
103 * it means that CPU was waken up just after WFI by this interrupt.
104 */
105 NRFX_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */
106 }nrfx_power_sleep_evt_t;
107 #endif /* NRF_POWER_HAS_SLEEPEVT */
108
109 #if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
110 /**
111 * @brief Events from USB power system
112 */
113 typedef enum
114 {
115 NRFX_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */
116 NRFX_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */
117 NRFX_POWER_USB_EVT_READY /**< USB power regulator ready. */
118 }nrfx_power_usb_evt_t;
119
120 /**
121 * @brief USB power state
122 *
123 * The single enumerator that holds all data about current state of USB
124 * related POWER.
125 *
126 * Organized this way that higher power state has higher numeric value
127 */
128 typedef enum
129 {
130 NRFX_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected. */
131 NRFX_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready. */
132 NRFX_POWER_USB_STATE_READY /**< From the power viewpoint, USB is ready for working. */
133 }nrfx_power_usb_state_t;
134 #endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
135
136 /**
137 * @name Callback types
138 *
139 * Defined types of callback functions.
140 * @{
141 */
142 /**
143 * @brief Event handler for power failure warning.
144 */
145 typedef void (*nrfx_power_pofwarn_event_handler_t)(void);
146
147 #if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
148 /**
149 * @brief Event handler for the sleep events.
150 *
151 * @param event Event type
152 */
153 typedef void (*nrfx_power_sleep_event_handler_t)(nrfx_power_sleep_evt_t event);
154 #endif
155
156 #if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
157 /**
158 * @brief Event handler for the USB-related power events.
159 *
160 * @param event Event type
161 */
162 typedef void (*nrfx_power_usb_event_handler_t)(nrfx_power_usb_evt_t event);
163 #endif
164 /** @} */
165
166 /**
167 * @brief General power configuration
168 *
169 * Parameters required to initialize power driver.
170 */
171 typedef struct
172 {
173 /**
174 * @brief Enable main DCDC regulator.
175 *
176 * This bit only informs the driver that elements for DCDC regulator
177 * are installed and the regulator can be used.
178 * The regulator will be enabled or disabled automatically
179 * by the hardware, basing on current power requirement.
180 */
181 bool dcdcen:1;
182
183 #if NRFX_POWER_SUPPORTS_DCDCEN_VDDH
184 /**
185 * @brief Enable HV DCDC regulator.
186 *
187 * This bit only informs the driver that elements for DCDC regulator
188 * are installed and the regulator can be used.
189 * The regulator will be enabled or disabled automatically
190 * by the hardware, basing on current power requirement.
191 */
192 bool dcdcenhv: 1;
193 #endif
194 }nrfx_power_config_t;
195
196 /**
197 * @brief The configuration for power failure comparator.
198 *
199 * Configuration used to enable and configure the power failure comparator.
200 */
201 typedef struct
202 {
203 nrfx_power_pofwarn_event_handler_t handler; //!< Event handler.
204 #if NRFX_POWER_SUPPORTS_POFCON
205 nrf_power_pof_thr_t thr; //!< Threshold for power failure detection
206 #endif
207 #if NRFX_POWER_SUPPORTS_POFCON_VDDH
208 nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on the VDDH pin.
209 #endif
210 }nrfx_power_pofwarn_config_t;
211
212 #if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
213 /**
214 * @brief The configuration of sleep event processing.
215 *
216 * Configuration used to enable and configure sleep event handling.
217 */
218 typedef struct
219 {
220 nrfx_power_sleep_event_handler_t handler; //!< Event handler.
221 bool en_enter:1; //!< Enable event on sleep entering.
222 bool en_exit :1; //!< Enable event on sleep exiting.
223 }nrfx_power_sleepevt_config_t;
224 #endif
225
226 #if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
227 /**
228 * @brief The configuration of the USB-related power events.
229 *
230 * Configuration used to enable and configure USB power event handling.
231 */
232 typedef struct
233 {
234 nrfx_power_usb_event_handler_t handler; //!< Event processing.
235 }nrfx_power_usbevt_config_t;
236 #endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
237
238 /**
239 * @brief Function for getting the handler of the power failure comparator.
240 * @return Handler of the power failure comparator.
241 */
242 nrfx_power_pofwarn_event_handler_t nrfx_power_pof_handler_get(void);
243
244 #if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
245 /**
246 * @brief Function for getting the handler of the USB power.
247 * @return Handler of the USB power.
248 */
249 nrfx_power_usb_event_handler_t nrfx_power_usb_handler_get(void);
250 #endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
251
252 /**
253 * @brief Function for initializing the power module driver.
254 *
255 * Enabled power module driver processes all the interrupts from the power system.
256 *
257 * @param[in] p_config Pointer to the structure with the initial configuration.
258 *
259 * @retval NRFX_SUCCESS Successfully initialized.
260 * @retval NRFX_ERROR_ALREADY Module was already initialized.
261 */
262 nrfx_err_t nrfx_power_init(nrfx_power_config_t const * p_config);
263
264 /**
265 * @brief Function for unintializing the power module driver.
266 *
267 * Disables all the interrupt handling in the module.
268 *
269 * @sa nrfx_power_init
270 */
271 void nrfx_power_uninit(void);
272
273 /**
274 * @brief Function for checking if the power module driver is initialized.
275 *
276 * @retval true Driver is already initialized.
277 * @retval false Driver is not initialized.
278 */
279 bool nrfx_power_init_check(void);
280
281 #if NRFX_POWER_SUPPORTS_POFCON
282 /**
283 * @brief Function for initializing the power failure comparator.
284 *
285 * Configures the power failure comparator. This function does not set it up and enable it.
286 * These steps can be done with functions @ref nrfx_power_pof_enable and @ref nrfx_power_pof_disable
287 * or with the SoftDevice API (when in use).
288 *
289 * @param[in] p_config Configuration with values and event handler.
290 * If event handler is set to NULL, the interrupt will be disabled.
291 */
292 void nrfx_power_pof_init(nrfx_power_pofwarn_config_t const * p_config);
293
294 /**
295 * @brief Function for enabling the power failure comparator.
296 * Sets and enables the interrupt of the power failure comparator. This function cannot be in use
297 * when SoftDevice is enabled. If the event handler set in the init function is set to NULL, the interrupt
298 * will be disabled.
299 *
300 * @param[in] p_config Configuration with values and event handler.
301 */
302 void nrfx_power_pof_enable(nrfx_power_pofwarn_config_t const * p_config);
303
304 /**
305 * @brief Function for disabling the power failure comparator.
306 *
307 * Disables the power failure comparator interrupt.
308 */
309 void nrfx_power_pof_disable(void);
310
311 /**
312 * @brief Function for clearing the power failure comparator settings.
313 *
314 * Clears the settings of the power failure comparator.
315 */
316 void nrfx_power_pof_uninit(void);
317 #endif // NRFX_POWER_SUPPORTS_POFCON
318
319 #if NRF_POWER_HAS_SLEEPEVT || defined(__NRFX_DOXYGEN__)
320 /**
321 * @brief Function for initializing the processing of the sleep events.
322 *
323 * Configures and sets up the sleep event processing.
324 *
325 * @param[in] p_config Configuration with values and event handler.
326 *
327 * @sa nrfx_power_sleepevt_uninit
328 *
329 */
330 void nrfx_power_sleepevt_init(nrfx_power_sleepevt_config_t const * p_config);
331
332 /**
333 * @brief Function for enabling the processing of the sleep events.
334 *
335 * @param[in] p_config Configuration with values and event handler.
336 */
337 void nrfx_power_sleepevt_enable(nrfx_power_sleepevt_config_t const * p_config);
338
339 /** @brief Function for disabling the processing of the sleep events. */
340 void nrfx_power_sleepevt_disable(void);
341
342 /**
343 * @brief Function for uninitializing the processing of the sleep events.
344 *
345 * @sa nrfx_power_sleepevt_init
346 */
347 void nrfx_power_sleepevt_uninit(void);
348 #endif /* NRF_POWER_HAS_SLEEPEVT */
349
350 #if (NRF_POWER_HAS_CONST_LATENCY && NRF_POWER_HAS_LOW_POWER) || defined(__NRFX_DOXYGEN__)
351 /**
352 * @brief Function for requesting Constant Latency sub-power mode.
353 *
354 * @note This function uses a reference counter. As a result, if it is called more than once,
355 * the function @ref nrfx_power_constlat_mode_free() needs to be called the same number of
356 * times to change the mode to Low Power.
357 *
358 * @retval NRFX_SUCCESS The sub-power mode was successfully changed to Constant Latency.
359 * @retval NRFX_ERROR_ALREADY Constant Latency mode was already requested and it is the current sub-power mode.
360 */
361 nrfx_err_t nrfx_power_constlat_mode_request(void);
362
363 /**
364 * @brief Function for freeing Constant Latency sub-power mode.
365 *
366 * @note This function uses a reference counter. As a result, it needs to be called the same number
367 * of times as the @ref nrfx_power_constlat_mode_request() function to change the mode back
368 * to Low Power.
369 *
370 * @retval NRFX_SUCCESS The sub-power mode was successfully changed to Low Power.
371 * @retval NRFX_ERROR_BUSY The sub-power mode was not changed due to multiple calls to @ref nrfx_power_constlat_mode_request.
372 */
373 nrfx_err_t nrfx_power_constlat_mode_free(void);
374
375 /**
376 * @brief Function for getting the current sub-power mode.
377 *
378 * @return Current sub-power mode.
379 */
380 nrfx_power_mode_t nrfx_power_mode_get(void);
381 #endif
382
383 #if NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
384 /**
385 * @brief Function for initializing the processing of USB power event.
386 *
387 * Configures and sets up the USB power event processing.
388 *
389 * @param[in] p_config Configuration with values and event handler.
390 *
391 * @sa nrfx_power_usbevt_uninit
392 */
393 void nrfx_power_usbevt_init(nrfx_power_usbevt_config_t const * p_config);
394
395 /** @brief Function for enabling the processing of USB power event. */
396 void nrfx_power_usbevt_enable(void);
397
398 /** @brief Function for disabling the processing of USB power event. */
399 void nrfx_power_usbevt_disable(void);
400
401 /**
402 * @brief Function for uninitalizing the processing of USB power event.
403 *
404 * @sa nrfx_power_usbevt_init
405 */
406 void nrfx_power_usbevt_uninit(void);
407
408 /**
409 * @brief Function for getting the status of USB power.
410 *
411 * @return Current USB power status.
412 */
413 NRFX_STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void);
414
415 #endif // NRF_POWER_HAS_USBREG || defined(__NRFX_DOXYGEN__)
416
417 #ifndef NRFX_DECLARE_ONLY
418 #if NRF_POWER_HAS_USBREG
nrfx_power_usbstatus_get(void)419 NRFX_STATIC_INLINE nrfx_power_usb_state_t nrfx_power_usbstatus_get(void)
420 {
421 uint32_t status = nrf_power_usbregstatus_get(NRF_POWER);
422 if(0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK))
423 {
424 return NRFX_POWER_USB_STATE_DISCONNECTED;
425 }
426 if(0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK))
427 {
428 return NRFX_POWER_USB_STATE_CONNECTED;
429 }
430 return NRFX_POWER_USB_STATE_READY;
431 }
432 #endif // NRF_POWER_HAS_USBREG
433 #endif // NRFX_DECLARE_ONLY
434
435 /** @} */
436
437
438 void nrfx_power_irq_handler(void);
439
440
441 #ifdef __cplusplus
442 }
443 #endif
444
445 #endif /* NRFX_POWER_H__ */
446