1 /*
2  * Copyright (c) 2018 - 2023, 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 NRF_REGULATORS_H__
35 #define NRF_REGULATORS_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrf_regulators_hal REGULATORS HAL
45  * @{
46  * @ingroup nrf_power
47  * @brief   Hardware access layer for managing the REGULATORS peripheral.
48  */
49 
50 #if defined(REGULATORS_MAINREGSTATUS_VREGH_Msk) || defined(__NRFX_DOXYGEN__)
51 /** @brief Symbol indicating whether MAINREGSTATUS register is present. */
52 #define NRF_REGULATORS_HAS_MAINREGSTATUS 1
53 #else
54 #define NRF_REGULATORS_HAS_MAINREGSTATUS 0
55 #endif
56 
57 #if defined(REGULATORS_POFCON_POF_Msk) || defined(__NRFX_DOXYGEN__)
58 /** @brief Symbol indicating whether power failure comparator is present. */
59 #define NRF_REGULATORS_HAS_POFCON 1
60 #else
61 #define NRF_REGULATORS_HAS_POFCON 0
62 #endif
63 
64 #if defined(REGULATORS_POFCON_THRESHOLDVDDH_Msk) || defined(__NRFX_DOXYGEN__)
65 /** @brief Symbol indicating whether power failure comparator for VDDH is present. */
66 #define NRF_REGULATORS_HAS_POFCON_VDDH 1
67 #else
68 #define NRF_REGULATORS_HAS_POFCON_VDDH 0
69 #endif
70 
71 #if defined(REGULATORS_VREGH_DCDCEN_DCDCEN_Msk) || defined(__NRFX_DOXYGEN__)
72 /** @brief Symbol indicating whether high voltage regulator is present. */
73 #define NRF_REGULATORS_HAS_DCDCEN_VDDH 1
74 #else
75 #define NRF_REGULATORS_HAS_DCDCEN_VDDH 0
76 #endif
77 
78 #if defined(REGULATORS_VREGRADIO_DCDCEN_DCDCEN_Msk) || defined(__NRFX_DOXYGEN__)
79 /** @brief Symbol indicating whether radio regulator is present. */
80 #define NRF_REGULATORS_HAS_DCDCEN_RADIO 1
81 #else
82 #define NRF_REGULATORS_HAS_DCDCEN_RADIO 0
83 #endif
84 
85 #if NRF_REGULATORS_HAS_MAINREGSTATUS
86 /** @brief Main regulator status. */
87 typedef enum
88 {
89     NRF_REGULATORS_MAINREGSTATUS_NORMAL = REGULATORS_MAINREGSTATUS_VREGH_Inactive, /**< Normal voltage mode. Voltage supplied on VDD and VDDH. */
90     NRF_REGULATORS_MAINREGSTATUS_HIGH   = REGULATORS_MAINREGSTATUS_VREGH_Active    /**< High voltage mode. Voltage supplied on VDDH. */
91 } nrf_regulators_mainregstatus_t;
92 #endif
93 
94 #if NRF_REGULATORS_HAS_POFCON
95 /** @brief Power failure comparator thresholds. */
96 typedef enum
97 {
98     NRF_REGULATORS_POFTHR_V19 = REGULATORS_POFCON_THRESHOLD_V19, /**< Set threshold to 1.9&nbsp;V. */
99     NRF_REGULATORS_POFTHR_V20 = REGULATORS_POFCON_THRESHOLD_V20, /**< Set threshold to 2.0&nbsp;V. */
100     NRF_REGULATORS_POFTHR_V21 = REGULATORS_POFCON_THRESHOLD_V21, /**< Set threshold to 2.1&nbsp;V. */
101     NRF_REGULATORS_POFTHR_V22 = REGULATORS_POFCON_THRESHOLD_V22, /**< Set threshold to 2.2&nbsp;V. */
102     NRF_REGULATORS_POFTHR_V23 = REGULATORS_POFCON_THRESHOLD_V23, /**< Set threshold to 2.3&nbsp;V. */
103     NRF_REGULATORS_POFTHR_V24 = REGULATORS_POFCON_THRESHOLD_V24, /**< Set threshold to 2.4&nbsp;V. */
104     NRF_REGULATORS_POFTHR_V25 = REGULATORS_POFCON_THRESHOLD_V25, /**< Set threshold to 2.5&nbsp;V. */
105     NRF_REGULATORS_POFTHR_V26 = REGULATORS_POFCON_THRESHOLD_V26, /**< Set threshold to 2.6&nbsp;V. */
106     NRF_REGULATORS_POFTHR_V27 = REGULATORS_POFCON_THRESHOLD_V27, /**< Set threshold to 2.7&nbsp;V. */
107     NRF_REGULATORS_POFTHR_V28 = REGULATORS_POFCON_THRESHOLD_V28, /**< Set threshold to 2.8&nbsp;V. */
108 } nrf_regulators_pof_thr_t;
109 #endif
110 
111 #if NRF_REGULATORS_HAS_POFCON_VDDH
112 /** @brief Power failure comparator thresholds for VDDH. */
113 typedef enum
114 {
115     NRF_REGULATORS_POFTHRVDDH_V27 = REGULATORS_POFCON_THRESHOLDVDDH_V27, /**< Set threshold to 2.7&nbsp;V. */
116     NRF_REGULATORS_POFTHRVDDH_V28 = REGULATORS_POFCON_THRESHOLDVDDH_V28, /**< Set threshold to 2.8&nbsp;V. */
117     NRF_REGULATORS_POFTHRVDDH_V29 = REGULATORS_POFCON_THRESHOLDVDDH_V29, /**< Set threshold to 2.9&nbsp;V. */
118     NRF_REGULATORS_POFTHRVDDH_V30 = REGULATORS_POFCON_THRESHOLDVDDH_V30, /**< Set threshold to 3.0&nbsp;V. */
119     NRF_REGULATORS_POFTHRVDDH_V31 = REGULATORS_POFCON_THRESHOLDVDDH_V31, /**< Set threshold to 3.1&nbsp;V. */
120     NRF_REGULATORS_POFTHRVDDH_V32 = REGULATORS_POFCON_THRESHOLDVDDH_V32, /**< Set threshold to 3.2&nbsp;V. */
121     NRF_REGULATORS_POFTHRVDDH_V33 = REGULATORS_POFCON_THRESHOLDVDDH_V33, /**< Set threshold to 3.3&nbsp;V. */
122     NRF_REGULATORS_POFTHRVDDH_V34 = REGULATORS_POFCON_THRESHOLDVDDH_V34, /**< Set threshold to 3.4&nbsp;V. */
123     NRF_REGULATORS_POFTHRVDDH_V35 = REGULATORS_POFCON_THRESHOLDVDDH_V35, /**< Set threshold to 3.5&nbsp;V. */
124     NRF_REGULATORS_POFTHRVDDH_V36 = REGULATORS_POFCON_THRESHOLDVDDH_V36, /**< Set threshold to 3.6&nbsp;V. */
125     NRF_REGULATORS_POFTHRVDDH_V37 = REGULATORS_POFCON_THRESHOLDVDDH_V37, /**< Set threshold to 3.7&nbsp;V. */
126     NRF_REGULATORS_POFTHRVDDH_V38 = REGULATORS_POFCON_THRESHOLDVDDH_V38, /**< Set threshold to 3.8&nbsp;V. */
127     NRF_REGULATORS_POFTHRVDDH_V39 = REGULATORS_POFCON_THRESHOLDVDDH_V39, /**< Set threshold to 3.9&nbsp;V. */
128     NRF_REGULATORS_POFTHRVDDH_V40 = REGULATORS_POFCON_THRESHOLDVDDH_V40, /**< Set threshold to 4.0&nbsp;V. */
129     NRF_REGULATORS_POFTHRVDDH_V41 = REGULATORS_POFCON_THRESHOLDVDDH_V41, /**< Set threshold to 4.1&nbsp;V. */
130     NRF_REGULATORS_POFTHRVDDH_V42 = REGULATORS_POFCON_THRESHOLDVDDH_V42, /**< Set threshold to 4.2&nbsp;V. */
131 } nrf_regulators_pof_thrvddh_t;
132 #endif
133 
134 /**
135  * @brief Function for enabling or disabling DCDC converter.
136  *
137  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
138  * @param[in] enable True if DCDC converter is to be enabled, false otherwise.
139  */
140 NRF_STATIC_INLINE void nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg, bool enable);
141 
142 /**
143  * @brief Function for putting CPU in system OFF mode.
144  *
145  * This function puts the CPU into system off mode.
146  * The only way to wake up the CPU is by reset.
147  *
148  * @note This function never returns.
149  *
150  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
151  */
152 NRF_STATIC_INLINE void nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg);
153 
154 #if NRF_REGULATORS_HAS_MAINREGSTATUS
155 /**
156  * @brief Function for getting the main supply status.
157  *
158  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
159  *
160  * @return The current main supply status.
161  */
162 NRF_STATIC_INLINE
163 nrf_regulators_mainregstatus_t nrf_regulators_mainregstatus_get(NRF_REGULATORS_Type const * p_reg);
164 #endif
165 
166 #if NRF_REGULATORS_HAS_POFCON
167 /**
168  * @brief Function for setting the power failure comparator configuration.
169  *
170  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
171  * @param[in] enable True if power failure comparator is to be enabled, false otherwise.
172  * @param[in] thr    Voltage threshold value.
173  */
174 NRF_STATIC_INLINE void nrf_regulators_pofcon_set(NRF_REGULATORS_Type *    p_reg,
175                                                  bool                     enable,
176                                                  nrf_regulators_pof_thr_t thr);
177 
178 /**
179  * @brief Function for getting the power failure comparator configuration.
180  *
181  * @param[in]  p_reg     Pointer to the structure of registers of the peripheral.
182  * @param[out] p_enabled Function sets this boolean variable to true
183  *                       if power failure comparator is enabled.
184  *                       The pointer can be NULL if we do not need this information.
185  *
186  * @return Threshold setting for power failure comparator.
187  */
188 NRF_STATIC_INLINE
189 nrf_regulators_pof_thr_t nrf_regulators_pofcon_get(NRF_REGULATORS_Type const * p_reg,
190                                                    bool *                      p_enabled);
191 #endif // NRF_REGULATORS_HAS_POFCON
192 
193 #if NRF_REGULATORS_HAS_POFCON_VDDH
194 /**
195  * @brief Function for setting the VDDH power failure comparator threshold.
196  *
197  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
198  * @param[in] thr   Threshold to be set.
199  */
200 NRF_STATIC_INLINE void nrf_regulators_pofcon_vddh_set(NRF_REGULATORS_Type *        p_reg,
201                                                       nrf_regulators_pof_thrvddh_t thr);
202 
203 /**
204  * @brief Function for getting the VDDH regulators failure comparator threshold.
205  *
206  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
207  *
208  * @return Threshold setting for regulators failure comparator.
209  */
210 NRF_STATIC_INLINE
211 nrf_regulators_pof_thrvddh_t nrf_regulators_pofcon_vddh_get(NRF_REGULATORS_Type const * p_reg);
212 #endif // NRF_REGULATORS_HAS_POFCON_VDDH
213 
214 #if NRF_REGULATORS_HAS_DCDCEN_VDDH
215 /**
216  * @brief Function for enabling or disabling the high voltage regulator.
217  *
218  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
219  * @param[in] enable True if the high voltage regulator is to be enabled, false otherwise.
220  */
221 NRF_STATIC_INLINE void nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS_Type * p_reg, bool enable);
222 #endif
223 
224 #if NRF_REGULATORS_HAS_DCDCEN_RADIO
225 /**
226  * @brief Function for enabling or disabling the radio regulator.
227  *
228  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
229  * @param[in] enable True if the radio regulator is to be enabled, false otherwise.
230  */
231 NRF_STATIC_INLINE void nrf_regulators_dcdcen_radio_set(NRF_REGULATORS_Type * p_reg, bool enable);
232 #endif
233 
234 #ifndef NRF_DECLARE_ONLY
235 
nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg,bool enable)236 NRF_STATIC_INLINE void nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg, bool enable)
237 {
238 #if defined(REGULATORS_DCDCEN_DCDCEN_Msk)
239     p_reg->DCDCEN = (enable ? REGULATORS_DCDCEN_DCDCEN_Msk : 0);
240 #else
241     p_reg->VREGMAIN.DCDCEN = (enable ? REGULATORS_VREGMAIN_DCDCEN_DCDCEN_Msk : 0);
242 #endif
243 }
244 
nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg)245 NRF_STATIC_INLINE void nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg)
246 {
247     p_reg->SYSTEMOFF = REGULATORS_SYSTEMOFF_SYSTEMOFF_Msk;
248     __DSB();
249 
250     /* Solution for simulated System OFF in debug mode */
251     while (true)
252     {
253         __WFE();
254     }
255 }
256 
257 #if NRF_REGULATORS_HAS_MAINREGSTATUS
258 NRF_STATIC_INLINE
nrf_regulators_mainregstatus_get(NRF_REGULATORS_Type const * p_reg)259 nrf_regulators_mainregstatus_t nrf_regulators_mainregstatus_get(NRF_REGULATORS_Type const * p_reg)
260 {
261     return (nrf_regulators_mainregstatus_t)p_reg->MAINREGSTATUS;
262 }
263 #endif
264 
265 #if NRF_REGULATORS_HAS_POFCON
nrf_regulators_pofcon_set(NRF_REGULATORS_Type * p_reg,bool enable,nrf_regulators_pof_thr_t thr)266 NRF_STATIC_INLINE void nrf_regulators_pofcon_set(NRF_REGULATORS_Type *    p_reg,
267                                                  bool                     enable,
268                                                  nrf_regulators_pof_thr_t thr)
269 {
270 #if NRF_REGULATORS_HAS_POFCON_VDDH
271     uint32_t pofcon = p_reg->POFCON;
272     pofcon &= ~(REGULATORS_POFCON_THRESHOLD_Msk | REGULATORS_POFCON_POF_Msk);
273     pofcon |=
274 #else // NRF_REGULATORS_HAS_POFCON_VDDH
275     p_reg->POFCON =
276 #endif
277         (((uint32_t)thr) << REGULATORS_POFCON_THRESHOLD_Pos) |
278         (enable ?
279         (REGULATORS_POFCON_POF_Enabled << REGULATORS_POFCON_POF_Pos)
280         :
281         (REGULATORS_POFCON_POF_Disabled << REGULATORS_POFCON_POF_Pos));
282 #if NRF_REGULATORS_HAS_POFCON_VDDH
283     p_reg->POFCON = pofcon;
284 #endif
285 }
286 
287 NRF_STATIC_INLINE
nrf_regulators_pofcon_get(NRF_REGULATORS_Type const * p_reg,bool * p_enabled)288 nrf_regulators_pof_thr_t nrf_regulators_pofcon_get(NRF_REGULATORS_Type const * p_reg,
289                                                    bool *                      p_enabled)
290 {
291     uint32_t pofcon = p_reg->POFCON;
292     if (NULL != p_enabled)
293     {
294         (*p_enabled) = ((pofcon & REGULATORS_POFCON_POF_Msk) >> REGULATORS_POFCON_POF_Pos)
295             == REGULATORS_POFCON_POF_Enabled;
296     }
297     return (nrf_regulators_pof_thr_t)((pofcon & REGULATORS_POFCON_THRESHOLD_Msk) >>
298                                       REGULATORS_POFCON_THRESHOLD_Pos);
299 }
300 #endif // NRF_REGULATORS_HAS_POFCON
301 
302 #if NRF_REGULATORS_HAS_POFCON_VDDH
nrf_regulators_pofcon_vddh_set(NRF_REGULATORS_Type * p_reg,nrf_regulators_pof_thrvddh_t thr)303 NRF_STATIC_INLINE void nrf_regulators_pofcon_vddh_set(NRF_REGULATORS_Type *        p_reg,
304                                                       nrf_regulators_pof_thrvddh_t thr)
305 {
306     uint32_t pofcon = p_reg->POFCON;
307     pofcon &= ~REGULATORS_POFCON_THRESHOLDVDDH_Msk;
308     pofcon |= (((uint32_t)thr) << REGULATORS_POFCON_THRESHOLDVDDH_Pos);
309     p_reg->POFCON = pofcon;
310 }
311 
312 NRF_STATIC_INLINE
nrf_regulators_pofcon_vddh_get(NRF_REGULATORS_Type const * p_reg)313 nrf_regulators_pof_thrvddh_t nrf_regulators_pofcon_vddh_get(NRF_REGULATORS_Type const * p_reg)
314 {
315     return (nrf_regulators_pof_thrvddh_t)((p_reg->POFCON & REGULATORS_POFCON_THRESHOLDVDDH_Msk) >>
316                                           REGULATORS_POFCON_THRESHOLDVDDH_Pos);
317 }
318 #endif // NRF_REGULATORS_HAS_POFCON_VDDH
319 
320 #if NRF_REGULATORS_HAS_DCDCEN_VDDH
nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS_Type * p_reg,bool enable)321 NRF_STATIC_INLINE void nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS_Type * p_reg, bool enable)
322 {
323     p_reg->VREGH.DCDCEN = (enable) ? REGULATORS_VREGH_DCDCEN_DCDCEN_Enabled :
324                                      REGULATORS_VREGH_DCDCEN_DCDCEN_Disabled;
325 }
326 #endif
327 
328 #if NRF_REGULATORS_HAS_DCDCEN_RADIO
nrf_regulators_dcdcen_radio_set(NRF_REGULATORS_Type * p_reg,bool enable)329 NRF_STATIC_INLINE void nrf_regulators_dcdcen_radio_set(NRF_REGULATORS_Type * p_reg, bool enable)
330 {
331     p_reg->VREGRADIO.DCDCEN = (enable) ? REGULATORS_VREGRADIO_DCDCEN_DCDCEN_Enabled :
332                                          REGULATORS_VREGRADIO_DCDCEN_DCDCEN_Disabled;
333 }
334 #endif
335 
336 #endif // NRF_DECLARE_ONLY
337 
338 /** @} */
339 
340 #ifdef __cplusplus
341 }
342 #endif
343 
344 #endif // NRF_REGULATORS_H__
345