1 /*
2  * Copyright (c) 2018 - 2020, Nordic Semiconductor ASA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  *    list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  *    contributors may be used to endorse or promote products derived from this
17  *    software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef NRF_REGULATORS_H__
33 #define NRF_REGULATORS_H__
34 
35 #include <nrfx.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**
42  * @defgroup nrf_regulators_hal REGULATORS HAL
43  * @{
44  * @ingroup nrf_power
45  * @brief   Hardware access layer for managing the REGULATORS peripheral.
46  */
47 
48 #if defined(REGULATORS_MAINREGSTATUS_VREGH_Msk) || defined(__NRFX_DOXYGEN__)
49 /** @brief Symbol indicating whether MAINREGSTATUS register is present. */
50 #define NRF_REGULATORS_HAS_MAINREGSTATUS 1
51 #else
52 #define NRF_REGULATORS_HAS_MAINREGSTATUS 0
53 #endif
54 
55 #if defined(REGULATORS_POFCON_POF_Msk) || defined(__NRFX_DOXYGEN__)
56 /** @brief Symbol indicating whether power failure comparator is present. */
57 #define NRF_REGULATORS_HAS_POFCON 1
58 #else
59 #define NRF_REGULATORS_HAS_POFCON 0
60 #endif
61 
62 #if defined(REGULATORS_POFCON_THRESHOLDVDDH_Msk) || defined(__NRFX_DOXYGEN__)
63 /** @brief Symbol indicating whether power failure comparator for VDDH is present. */
64 #define NRF_REGULATORS_HAS_POFCON_VDDH 1
65 #else
66 #define NRF_REGULATORS_HAS_POFCON_VDDH 0
67 #endif
68 
69 #if defined(REGULATORS_VREGH_DCDCEN_DCDCEN_Msk) || defined(__NRFX_DOXYGEN__)
70 /** @brief Symbol indicating whether high voltage regulator is present. */
71 #define NRF_REGULATORS_HAS_DCDCEN_VDDH 1
72 #else
73 #define NRF_REGULATORS_HAS_DCDCEN_VDDH 0
74 #endif
75 
76 #if defined(REGULATORS_VREGRADIO_DCDCEN_DCDCEN_Msk) || defined(__NRFX_DOXYGEN__)
77 /** @brief Symbol indicating whether radio regulator is present. */
78 #define NRF_REGULATORS_HAS_DCDCEN_RADIO 1
79 #else
80 #define NRF_REGULATORS_HAS_DCDCEN_RADIO 0
81 #endif
82 
83 #if NRF_REGULATORS_HAS_MAINREGSTATUS
84 /** @brief Main regulator status. */
85 typedef enum
86 {
87     NRF_REGULATORS_MAINREGSTATUS_NORMAL = REGULATORS_MAINREGSTATUS_VREGH_Inactive, /**< Normal voltage mode. Voltage supplied on VDD and VDDH. */
88     NRF_REGULATORS_MAINREGSTATUS_HIGH   = REGULATORS_MAINREGSTATUS_VREGH_Active    /**< High voltage mode. Voltage supplied on VDDH. */
89 } nrf_regulators_mainregstatus_t;
90 #endif
91 
92 #if NRF_REGULATORS_HAS_POFCON
93 /** @brief Power failure comparator thresholds. */
94 typedef enum
95 {
96     NRF_REGULATORS_POFTHR_V19 = REGULATORS_POFCON_THRESHOLD_V19, /**< Set threshold to 1.9&nbsp;V. */
97     NRF_REGULATORS_POFTHR_V20 = REGULATORS_POFCON_THRESHOLD_V20, /**< Set threshold to 2.0&nbsp;V. */
98     NRF_REGULATORS_POFTHR_V21 = REGULATORS_POFCON_THRESHOLD_V21, /**< Set threshold to 2.1&nbsp;V. */
99     NRF_REGULATORS_POFTHR_V22 = REGULATORS_POFCON_THRESHOLD_V22, /**< Set threshold to 2.2&nbsp;V. */
100     NRF_REGULATORS_POFTHR_V23 = REGULATORS_POFCON_THRESHOLD_V23, /**< Set threshold to 2.3&nbsp;V. */
101     NRF_REGULATORS_POFTHR_V24 = REGULATORS_POFCON_THRESHOLD_V24, /**< Set threshold to 2.4&nbsp;V. */
102     NRF_REGULATORS_POFTHR_V25 = REGULATORS_POFCON_THRESHOLD_V25, /**< Set threshold to 2.5&nbsp;V. */
103     NRF_REGULATORS_POFTHR_V26 = REGULATORS_POFCON_THRESHOLD_V26, /**< Set threshold to 2.6&nbsp;V. */
104     NRF_REGULATORS_POFTHR_V27 = REGULATORS_POFCON_THRESHOLD_V27, /**< Set threshold to 2.7&nbsp;V. */
105     NRF_REGULATORS_POFTHR_V28 = REGULATORS_POFCON_THRESHOLD_V28, /**< Set threshold to 2.8&nbsp;V. */
106 } nrf_regulators_pof_thr_t;
107 #endif
108 
109 #if NRF_REGULATORS_HAS_POFCON_VDDH
110 /** @brief Power failure comparator thresholds for VDDH. */
111 typedef enum
112 {
113     NRF_REGULATORS_POFTHRVDDH_V27 = REGULATORS_POFCON_THRESHOLDVDDH_V27, /**< Set threshold to 2.7&nbsp;V. */
114     NRF_REGULATORS_POFTHRVDDH_V28 = REGULATORS_POFCON_THRESHOLDVDDH_V28, /**< Set threshold to 2.8&nbsp;V. */
115     NRF_REGULATORS_POFTHRVDDH_V29 = REGULATORS_POFCON_THRESHOLDVDDH_V29, /**< Set threshold to 2.9&nbsp;V. */
116     NRF_REGULATORS_POFTHRVDDH_V30 = REGULATORS_POFCON_THRESHOLDVDDH_V30, /**< Set threshold to 3.0&nbsp;V. */
117     NRF_REGULATORS_POFTHRVDDH_V31 = REGULATORS_POFCON_THRESHOLDVDDH_V31, /**< Set threshold to 3.1&nbsp;V. */
118     NRF_REGULATORS_POFTHRVDDH_V32 = REGULATORS_POFCON_THRESHOLDVDDH_V32, /**< Set threshold to 3.2&nbsp;V. */
119     NRF_REGULATORS_POFTHRVDDH_V33 = REGULATORS_POFCON_THRESHOLDVDDH_V33, /**< Set threshold to 3.3&nbsp;V. */
120     NRF_REGULATORS_POFTHRVDDH_V34 = REGULATORS_POFCON_THRESHOLDVDDH_V34, /**< Set threshold to 3.4&nbsp;V. */
121     NRF_REGULATORS_POFTHRVDDH_V35 = REGULATORS_POFCON_THRESHOLDVDDH_V35, /**< Set threshold to 3.5&nbsp;V. */
122     NRF_REGULATORS_POFTHRVDDH_V36 = REGULATORS_POFCON_THRESHOLDVDDH_V36, /**< Set threshold to 3.6&nbsp;V. */
123     NRF_REGULATORS_POFTHRVDDH_V37 = REGULATORS_POFCON_THRESHOLDVDDH_V37, /**< Set threshold to 3.7&nbsp;V. */
124     NRF_REGULATORS_POFTHRVDDH_V38 = REGULATORS_POFCON_THRESHOLDVDDH_V38, /**< Set threshold to 3.8&nbsp;V. */
125     NRF_REGULATORS_POFTHRVDDH_V39 = REGULATORS_POFCON_THRESHOLDVDDH_V39, /**< Set threshold to 3.9&nbsp;V. */
126     NRF_REGULATORS_POFTHRVDDH_V40 = REGULATORS_POFCON_THRESHOLDVDDH_V40, /**< Set threshold to 4.0&nbsp;V. */
127     NRF_REGULATORS_POFTHRVDDH_V41 = REGULATORS_POFCON_THRESHOLDVDDH_V41, /**< Set threshold to 4.1&nbsp;V. */
128     NRF_REGULATORS_POFTHRVDDH_V42 = REGULATORS_POFCON_THRESHOLDVDDH_V42, /**< Set threshold to 4.2&nbsp;V. */
129 } nrf_regulators_pof_thrvddh_t;
130 #endif
131 
132 /**
133  * @brief Function for enabling or disabling DCDC converter.
134  *
135  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
136  * @param[in] enable True if DCDC converter is to be enabled, false otherwise.
137  */
138 NRF_STATIC_INLINE void nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg, bool enable);
139 
140 /**
141  * @brief Function for putting CPU in system OFF mode.
142  *
143  * This function puts the CPU into system off mode.
144  * The only way to wake up the CPU is by reset.
145  *
146  * @note This function never returns.
147  *
148  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
149  */
150 NRF_STATIC_INLINE void nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg);
151 
152 #if NRF_REGULATORS_HAS_MAINREGSTATUS
153 /**
154  * @brief Function for getting the main supply status.
155  *
156  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
157  *
158  * @return The current main supply status.
159  */
160 NRF_STATIC_INLINE
161 nrf_regulators_mainregstatus_t nrf_regulators_mainregstatus_get(NRF_REGULATORS_Type const * p_reg);
162 #endif
163 
164 #if NRF_REGULATORS_HAS_POFCON
165 /**
166  * @brief Function for setting the power failure comparator configuration.
167  *
168  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
169  * @param[in] enable True if power failure comparator is to be enabled, false otherwise.
170  * @param[in] thr    Voltage threshold value.
171  */
172 NRF_STATIC_INLINE void nrf_regulators_pofcon_set(NRF_REGULATORS_Type *    p_reg,
173                                                  bool                     enable,
174                                                  nrf_regulators_pof_thr_t thr);
175 
176 /**
177  * @brief Function for getting the power failure comparator configuration.
178  *
179  * @param[in]  p_reg     Pointer to the structure of registers of the peripheral.
180  * @param[out] p_enabled Function sets this boolean variable to true
181  *                       if power failure comparator is enabled.
182  *                       The pointer can be NULL if we do not need this information.
183  *
184  * @return Threshold setting for power failure comparator.
185  */
186 NRF_STATIC_INLINE
187 nrf_regulators_pof_thr_t nrf_regulators_pofcon_get(NRF_REGULATORS_Type const * p_reg,
188                                                    bool *                      p_enabled);
189 #endif // NRF_REGULATORS_HAS_POFCON
190 
191 #if NRF_REGULATORS_HAS_POFCON_VDDH
192 /**
193  * @brief Function for setting the VDDH power failure comparator threshold.
194  *
195  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
196  * @param[in] thr   Threshold to be set.
197  */
198 NRF_STATIC_INLINE void nrf_regulators_pofcon_vddh_set(NRF_REGULATORS_Type *        p_reg,
199                                                       nrf_regulators_pof_thrvddh_t thr);
200 
201 /**
202  * @brief Function for getting the VDDH regulators failure comparator threshold.
203  *
204  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
205  *
206  * @return Threshold setting for regulators failure comparator.
207  */
208 NRF_STATIC_INLINE
209 nrf_regulators_pof_thrvddh_t nrf_regulators_pofcon_vddh_get(NRF_REGULATORS_Type const * p_reg);
210 #endif // NRF_REGULATORS_HAS_POFCON_VDDH
211 
212 #if NRF_REGULATORS_HAS_DCDCEN_VDDH
213 /**
214  * @brief Function for enabling or disabling the high voltage regulator.
215  *
216  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
217  * @param[in] enable True if the high voltage regulator is to be enabled, false otherwise.
218  */
219 NRF_STATIC_INLINE void nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS_Type * p_reg, bool enable);
220 #endif
221 
222 #if NRF_REGULATORS_HAS_DCDCEN_RADIO
223 /**
224  * @brief Function for enabling or disabling the radio regulator.
225  *
226  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
227  * @param[in] enable True if the radio regulator is to be enabled, false otherwise.
228  */
229 NRF_STATIC_INLINE void nrf_regulators_dcdcen_radio_set(NRF_REGULATORS_Type * p_reg, bool enable);
230 #endif
231 
232 #ifndef NRF_DECLARE_ONLY
233 
nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg,bool enable)234 NRF_STATIC_INLINE void nrf_regulators_dcdcen_set(NRF_REGULATORS_Type * p_reg, bool enable)
235 {
236 #if defined(REGULATORS_DCDCEN_DCDCEN_Msk)
237     p_reg->DCDCEN = (enable ? REGULATORS_DCDCEN_DCDCEN_Msk : 0);
238 #else
239     p_reg->VREGMAIN.DCDCEN = (enable ? REGULATORS_VREGMAIN_DCDCEN_DCDCEN_Msk : 0);
240 #endif
241 }
242 
nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg)243 NRF_STATIC_INLINE void nrf_regulators_system_off(NRF_REGULATORS_Type * p_reg)
244 {
245     p_reg->SYSTEMOFF = REGULATORS_SYSTEMOFF_SYSTEMOFF_Msk;
246     __DSB();
247 
248     /* Solution for simulated System OFF in debug mode */
249     while (true)
250     {
251         __WFE();
252     }
253 }
254 
255 #if NRF_REGULATORS_HAS_MAINREGSTATUS
256 NRF_STATIC_INLINE
nrf_regulators_mainregstatus_get(NRF_REGULATORS_Type const * p_reg)257 nrf_regulators_mainregstatus_t nrf_regulators_mainregstatus_get(NRF_REGULATORS_Type const * p_reg)
258 {
259     return (nrf_regulators_mainregstatus_t)p_reg->MAINREGSTATUS;
260 }
261 #endif
262 
263 #if NRF_REGULATORS_HAS_POFCON
nrf_regulators_pofcon_set(NRF_REGULATORS_Type * p_reg,bool enable,nrf_regulators_pof_thr_t thr)264 NRF_STATIC_INLINE void nrf_regulators_pofcon_set(NRF_REGULATORS_Type *    p_reg,
265                                                  bool                     enable,
266                                                  nrf_regulators_pof_thr_t thr)
267 {
268 #if NRF_REGULATORS_HAS_POFCON_VDDH
269     uint32_t pofcon = p_reg->POFCON;
270     pofcon &= ~(REGULATORS_POFCON_THRESHOLD_Msk | REGULATORS_POFCON_POF_Msk);
271     pofcon |=
272 #else // NRF_REGULATORS_HAS_POFCON_VDDH
273     p_reg->POFCON =
274 #endif
275         (((uint32_t)thr) << REGULATORS_POFCON_THRESHOLD_Pos) |
276         (enable ?
277         (REGULATORS_POFCON_POF_Enabled << REGULATORS_POFCON_POF_Pos)
278         :
279         (REGULATORS_POFCON_POF_Disabled << REGULATORS_POFCON_POF_Pos));
280 #if NRF_REGULATORS_HAS_POFCON_VDDH
281     p_reg->POFCON = pofcon;
282 #endif
283 }
284 
285 NRF_STATIC_INLINE
nrf_regulators_pofcon_get(NRF_REGULATORS_Type const * p_reg,bool * p_enabled)286 nrf_regulators_pof_thr_t nrf_regulators_pofcon_get(NRF_REGULATORS_Type const * p_reg,
287                                                    bool *                      p_enabled)
288 {
289     uint32_t pofcon = p_reg->POFCON;
290     if (NULL != p_enabled)
291     {
292         (*p_enabled) = ((pofcon & REGULATORS_POFCON_POF_Msk) >> REGULATORS_POFCON_POF_Pos)
293             == REGULATORS_POFCON_POF_Enabled;
294     }
295     return (nrf_regulators_pof_thr_t)((pofcon & REGULATORS_POFCON_THRESHOLD_Msk) >>
296                                       REGULATORS_POFCON_THRESHOLD_Pos);
297 }
298 #endif // NRF_REGULATORS_HAS_POFCON
299 
300 #if NRF_REGULATORS_HAS_POFCON_VDDH
nrf_regulators_pofcon_vddh_set(NRF_REGULATORS_Type * p_reg,nrf_regulators_pof_thrvddh_t thr)301 NRF_STATIC_INLINE void nrf_regulators_pofcon_vddh_set(NRF_REGULATORS_Type *        p_reg,
302                                                       nrf_regulators_pof_thrvddh_t thr)
303 {
304     uint32_t pofcon = p_reg->POFCON;
305     pofcon &= ~REGULATORS_POFCON_THRESHOLDVDDH_Msk;
306     pofcon |= (((uint32_t)thr) << REGULATORS_POFCON_THRESHOLDVDDH_Pos);
307     p_reg->POFCON = pofcon;
308 }
309 
310 NRF_STATIC_INLINE
nrf_regulators_pofcon_vddh_get(NRF_REGULATORS_Type const * p_reg)311 nrf_regulators_pof_thrvddh_t nrf_regulators_pofcon_vddh_get(NRF_REGULATORS_Type const * p_reg)
312 {
313     return (nrf_regulators_pof_thrvddh_t)((p_reg->POFCON & REGULATORS_POFCON_THRESHOLDVDDH_Msk) >>
314                                           REGULATORS_POFCON_THRESHOLDVDDH_Pos);
315 }
316 #endif // NRF_REGULATORS_HAS_POFCON_VDDH
317 
318 #if NRF_REGULATORS_HAS_DCDCEN_VDDH
nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS_Type * p_reg,bool enable)319 NRF_STATIC_INLINE void nrf_regulators_dcdcen_vddh_set(NRF_REGULATORS_Type * p_reg, bool enable)
320 {
321     p_reg->VREGH.DCDCEN = (enable) ? REGULATORS_VREGH_DCDCEN_DCDCEN_Enabled :
322                                      REGULATORS_VREGH_DCDCEN_DCDCEN_Disabled;
323 }
324 #endif
325 
326 #if NRF_REGULATORS_HAS_DCDCEN_RADIO
nrf_regulators_dcdcen_radio_set(NRF_REGULATORS_Type * p_reg,bool enable)327 NRF_STATIC_INLINE void nrf_regulators_dcdcen_radio_set(NRF_REGULATORS_Type * p_reg, bool enable)
328 {
329     p_reg->VREGRADIO.DCDCEN = (enable) ? REGULATORS_VREGRADIO_DCDCEN_DCDCEN_Enabled :
330                                          REGULATORS_VREGRADIO_DCDCEN_DCDCEN_Disabled;
331 }
332 #endif
333 
334 #endif // NRF_DECLARE_ONLY
335 
336 /** @} */
337 
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 #endif // NRF_REGULATORS_H__
343