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