1 /*
2 * Copyright (c) 2014 - 2024, 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_RNG_H__
35 #define NRF_RNG_H__
36
37 #include <nrfx.h>
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /**
44 * @defgroup nrf_rng_hal RNG HAL
45 * @{
46 * @ingroup nrf_rng
47 * @brief Hardware access layer (HAL) for managing the Random Number Generator (RNG) peripheral.
48 */
49
50 /** @brief RNG tasks. */
51 typedef enum
52 {
53 NRF_RNG_TASK_START = offsetof(NRF_RNG_Type, TASKS_START), /**< Start the random number generator. */
54 NRF_RNG_TASK_STOP = offsetof(NRF_RNG_Type, TASKS_STOP) /**< Stop the random number generator. */
55 } nrf_rng_task_t;
56
57 /** @brief RNG events. */
58 typedef enum
59 {
60 NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */
61 } nrf_rng_event_t;
62
63 /** @brief RNG interrupts. */
64 typedef enum
65 {
66 NRF_RNG_INT_VALRDY_MASK = RNG_INTENSET_VALRDY_Msk /**< Mask for enabling or disabling an interrupt on VALRDY event. */
67 } nrf_rng_int_mask_t;
68
69 /** @brief Types of RNG shortcuts. */
70 typedef enum
71 {
72 NRF_RNG_SHORT_VALRDY_STOP_MASK = RNG_SHORTS_VALRDY_STOP_Msk /**< Mask for setting shortcut between EVENT_VALRDY and TASK_STOP. */
73 } nrf_rng_short_mask_t;
74
75
76 /**
77 * @brief Function for enabling interrupts.
78 *
79 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
80 * @param[in] mask Mask of interrupts to be enabled.
81 * Use @ref nrf_rng_int_mask_t values for bit masking.
82 */
83 NRF_STATIC_INLINE void nrf_rng_int_enable(NRF_RNG_Type * p_reg, uint32_t mask);
84
85 /**
86 * @brief Function for disabling interrupts.
87 *
88 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
89 * @param[in] mask Mask of interrupts to be disabled.
90 * Use @ref nrf_rng_int_mask_t values for bit masking.
91 */
92 NRF_STATIC_INLINE void nrf_rng_int_disable(NRF_RNG_Type * p_reg, uint32_t mask);
93
94 /**
95 * @brief Function for checking if the specified interrupts are enabled.
96 *
97 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
98 * @param[in] mask Mask of interrupts to be checked.
99 * Use @ref nrf_rng_int_mask_t values for bit masking.
100 *
101 * @return Mask of enabled interrupts.
102 */
103 NRF_STATIC_INLINE uint32_t nrf_rng_int_enable_check(NRF_RNG_Type const * p_reg, uint32_t mask);
104
105 /**
106 * @brief Function for getting the address of the specified task.
107 *
108 * This function can be used by the PPI module.
109 *
110 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
111 * @param[in] rng_task The specified task.
112 *
113 * @return Address of the specified task.
114 */
115 NRF_STATIC_INLINE uint32_t nrf_rng_task_address_get(NRF_RNG_Type const * p_reg,
116 nrf_rng_task_t rng_task);
117
118 /**
119 * @brief Function for triggering the specified task.
120 *
121 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
122 * @param[in] rng_task The specified Task.
123 */
124 NRF_STATIC_INLINE void nrf_rng_task_trigger(NRF_RNG_Type * p_reg, nrf_rng_task_t rng_task);
125
126 /**
127 * @brief Function for getting address of the specified event.
128 *
129 * This function can be used by the PPI module.
130 *
131 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
132 * @param[in] rng_event The specified event.
133 *
134 * @return Address of the specified event.
135 */
136 NRF_STATIC_INLINE uint32_t nrf_rng_event_address_get(NRF_RNG_Type const * p_reg,
137 nrf_rng_event_t rng_event);
138
139 /**
140 * @brief Function for clearing the specified event.
141 *
142 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
143 * @param[in] rng_event The specified event.
144 */
145 NRF_STATIC_INLINE void nrf_rng_event_clear(NRF_RNG_Type * p_reg, nrf_rng_event_t rng_event);
146
147 /**
148 * @brief Function for retrieving the state of the specified event.
149 *
150 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
151 * @param[in] rng_event The specified event.
152 *
153 * @retval true The event is set.
154 * @retval false The event is not set.
155 */
156 NRF_STATIC_INLINE bool nrf_rng_event_check(NRF_RNG_Type const * p_reg, nrf_rng_event_t rng_event);
157
158 /**
159 * @brief Function for setting shortcuts.
160 *
161 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
162 * @param[in] mask Mask of shortcuts.
163 */
164 NRF_STATIC_INLINE void nrf_rng_shorts_enable(NRF_RNG_Type * p_reg, uint32_t mask);
165
166 /**
167 * @brief Function for clearing shortcuts.
168 *
169 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
170 * @param[in] mask Mask of shortcuts.
171 */
172 NRF_STATIC_INLINE void nrf_rng_shorts_disable(NRF_RNG_Type * p_reg, uint32_t mask);
173
174 /**
175 * @brief Function for getting the previously generated random value.
176 *
177 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
178 *
179 * @return Previously generated random value.
180 */
181 NRF_STATIC_INLINE uint8_t nrf_rng_random_value_get(NRF_RNG_Type const * p_reg);
182
183 /**
184 * @brief Function for enabling digital error correction.
185 *
186 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
187 */
188 NRF_STATIC_INLINE void nrf_rng_error_correction_enable(NRF_RNG_Type * p_reg);
189
190 /**
191 * @brief Function for disabling digital error correction.
192 *
193 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
194 */
195 NRF_STATIC_INLINE void nrf_rng_error_correction_disable(NRF_RNG_Type * p_reg);
196
197 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
198 /**
199 * @brief Function for setting the subscribe configuration for a given
200 * RNG task.
201 *
202 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
203 * @param[in] task Task for which to set the configuration.
204 * @param[in] channel Channel through which to subscribe events.
205 */
206 NRF_STATIC_INLINE void nrf_rng_subscribe_set(NRF_RNG_Type * p_reg,
207 nrf_rng_task_t task,
208 uint8_t channel);
209
210 /**
211 * @brief Function for clearing the subscribe configuration for a given
212 * RNG task.
213 *
214 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
215 * @param[in] task Task for which to clear the configuration.
216 */
217 NRF_STATIC_INLINE void nrf_rng_subscribe_clear(NRF_RNG_Type * p_reg,
218 nrf_rng_task_t task);
219
220 /**
221 * @brief Function for setting the publish configuration for a given
222 * RNG event.
223 *
224 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
225 * @param[in] event Event for which to set the configuration.
226 * @param[in] channel Channel through which to publish the event.
227 */
228 NRF_STATIC_INLINE void nrf_rng_publish_set(NRF_RNG_Type * p_reg,
229 nrf_rng_event_t event,
230 uint8_t channel);
231
232 /**
233 * @brief Function for clearing the publish configuration for a given
234 * RNG event.
235 *
236 * @param[in] p_reg Pointer to the structure of registers of the peripheral.
237 * @param[in] event Event for which to clear the configuration.
238 */
239 NRF_STATIC_INLINE void nrf_rng_publish_clear(NRF_RNG_Type * p_reg,
240 nrf_rng_event_t event);
241 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
242
243
244 #ifndef NRF_DECLARE_ONLY
245
nrf_rng_int_enable(NRF_RNG_Type * p_reg,uint32_t mask)246 NRF_STATIC_INLINE void nrf_rng_int_enable(NRF_RNG_Type * p_reg, uint32_t mask)
247 {
248 p_reg->INTENSET = mask;
249 }
250
nrf_rng_int_disable(NRF_RNG_Type * p_reg,uint32_t mask)251 NRF_STATIC_INLINE void nrf_rng_int_disable(NRF_RNG_Type * p_reg, uint32_t mask)
252 {
253 p_reg->INTENCLR = mask;
254 }
255
nrf_rng_int_enable_check(NRF_RNG_Type const * p_reg,uint32_t mask)256 NRF_STATIC_INLINE uint32_t nrf_rng_int_enable_check(NRF_RNG_Type const * p_reg, uint32_t mask)
257 {
258 return p_reg->INTENSET & mask;
259 }
260
nrf_rng_task_address_get(NRF_RNG_Type const * p_reg,nrf_rng_task_t rng_task)261 NRF_STATIC_INLINE uint32_t nrf_rng_task_address_get(NRF_RNG_Type const * p_reg,
262 nrf_rng_task_t rng_task)
263 {
264 return nrf_task_event_address_get(p_reg, rng_task);
265 }
266
nrf_rng_task_trigger(NRF_RNG_Type * p_reg,nrf_rng_task_t rng_task)267 NRF_STATIC_INLINE void nrf_rng_task_trigger(NRF_RNG_Type * p_reg, nrf_rng_task_t rng_task)
268 {
269 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)rng_task)) = 0x1UL;
270 }
271
nrf_rng_event_address_get(NRF_RNG_Type const * p_reg,nrf_rng_event_t rng_event)272 NRF_STATIC_INLINE uint32_t nrf_rng_event_address_get(NRF_RNG_Type const * p_reg,
273 nrf_rng_event_t rng_event)
274 {
275 return nrf_task_event_address_get(p_reg, rng_event);
276 }
277
nrf_rng_event_clear(NRF_RNG_Type * p_reg,nrf_rng_event_t rng_event)278 NRF_STATIC_INLINE void nrf_rng_event_clear(NRF_RNG_Type * p_reg, nrf_rng_event_t rng_event)
279 {
280 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)rng_event)) = 0x0UL;
281 nrf_event_readback((uint8_t *)p_reg + (uint32_t)rng_event);
282 }
283
nrf_rng_event_check(NRF_RNG_Type const * p_reg,nrf_rng_event_t rng_event)284 NRF_STATIC_INLINE bool nrf_rng_event_check(NRF_RNG_Type const * p_reg, nrf_rng_event_t rng_event)
285 {
286 return nrf_event_check(p_reg, rng_event);
287 }
288
nrf_rng_shorts_enable(NRF_RNG_Type * p_reg,uint32_t mask)289 NRF_STATIC_INLINE void nrf_rng_shorts_enable(NRF_RNG_Type * p_reg, uint32_t mask)
290 {
291 p_reg->SHORTS |= mask;
292 }
293
nrf_rng_shorts_disable(NRF_RNG_Type * p_reg,uint32_t mask)294 NRF_STATIC_INLINE void nrf_rng_shorts_disable(NRF_RNG_Type * p_reg, uint32_t mask)
295 {
296 p_reg->SHORTS &= ~mask;
297 }
298
nrf_rng_random_value_get(NRF_RNG_Type const * p_reg)299 NRF_STATIC_INLINE uint8_t nrf_rng_random_value_get(NRF_RNG_Type const * p_reg)
300 {
301 return (uint8_t)(p_reg->VALUE & RNG_VALUE_VALUE_Msk);
302 }
303
nrf_rng_error_correction_enable(NRF_RNG_Type * p_reg)304 NRF_STATIC_INLINE void nrf_rng_error_correction_enable(NRF_RNG_Type * p_reg)
305 {
306 p_reg->CONFIG |= RNG_CONFIG_DERCEN_Msk;
307 }
308
nrf_rng_error_correction_disable(NRF_RNG_Type * p_reg)309 NRF_STATIC_INLINE void nrf_rng_error_correction_disable(NRF_RNG_Type * p_reg)
310 {
311 p_reg->CONFIG &= ~RNG_CONFIG_DERCEN_Msk;
312 }
313
314 #if defined(DPPI_PRESENT)
nrf_rng_subscribe_set(NRF_RNG_Type * p_reg,nrf_rng_task_t task,uint8_t channel)315 NRF_STATIC_INLINE void nrf_rng_subscribe_set(NRF_RNG_Type * p_reg,
316 nrf_rng_task_t task,
317 uint8_t channel)
318 {
319 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
320 ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
321 }
322
nrf_rng_subscribe_clear(NRF_RNG_Type * p_reg,nrf_rng_task_t task)323 NRF_STATIC_INLINE void nrf_rng_subscribe_clear(NRF_RNG_Type * p_reg,
324 nrf_rng_task_t task)
325 {
326 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
327 }
328
nrf_rng_publish_set(NRF_RNG_Type * p_reg,nrf_rng_event_t event,uint8_t channel)329 NRF_STATIC_INLINE void nrf_rng_publish_set(NRF_RNG_Type * p_reg,
330 nrf_rng_event_t event,
331 uint8_t channel)
332 {
333 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
334 ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
335 }
336
nrf_rng_publish_clear(NRF_RNG_Type * p_reg,nrf_rng_event_t event)337 NRF_STATIC_INLINE void nrf_rng_publish_clear(NRF_RNG_Type * p_reg,
338 nrf_rng_event_t event)
339 {
340 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
341 }
342 #endif // defined(DPPI_PRESENT)
343
344 #endif // NRF_DECLARE_ONLY
345
346 /** @} */
347
348 #ifdef __cplusplus
349 }
350 #endif
351
352 #endif /* NRF_RNG_H__ */
353