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