1 /*
2  * Copyright (c) 2014 - 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_RNG_H__
33 #define NRF_RNG_H__
34 
35 #include <nrfx.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**
42  * @defgroup nrf_rng_hal RNG HAL
43  * @{
44  * @ingroup nrf_rng
45  * @brief   Hardware access layer (HAL) for managing the Random Number Generator (RNG) peripheral.
46  */
47 
48 /** @brief RNG tasks. */
49 typedef enum
50 {
51     NRF_RNG_TASK_START = offsetof(NRF_RNG_Type, TASKS_START), /**< Start the random number generator. */
52     NRF_RNG_TASK_STOP  = offsetof(NRF_RNG_Type, TASKS_STOP)   /**< Stop the random number generator. */
53 } nrf_rng_task_t;
54 
55 /** @brief RNG events. */
56 typedef enum
57 {
58     NRF_RNG_EVENT_VALRDY = offsetof(NRF_RNG_Type, EVENTS_VALRDY) /**< New random number generated event. */
59 } nrf_rng_event_t;
60 
61 /** @brief RNG interrupts. */
62 typedef enum
63 {
64     NRF_RNG_INT_VALRDY_MASK = RNG_INTENSET_VALRDY_Msk /**< Mask for enabling or disabling an interrupt on VALRDY event. */
65 } nrf_rng_int_mask_t;
66 
67 /** @brief Types of RNG shortcuts. */
68 typedef enum
69 {
70     NRF_RNG_SHORT_VALRDY_STOP_MASK = RNG_SHORTS_VALRDY_STOP_Msk /**< Mask for setting shortcut between EVENT_VALRDY and TASK_STOP. */
71 } nrf_rng_short_mask_t;
72 
73 
74 /**
75  * @brief Function for enabling interrupts.
76  *
77  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
78  * @param[in] mask  Mask of interrupts to be enabled.
79  */
80 NRF_STATIC_INLINE void nrf_rng_int_enable(NRF_RNG_Type * p_reg, uint32_t mask);
81 
82 /**
83  * @brief Function for disabling interrupts.
84  *
85  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
86  * @param[in] mask  Mask of interrupts to be disabled.
87  */
88 NRF_STATIC_INLINE void nrf_rng_int_disable(NRF_RNG_Type * p_reg, uint32_t mask);
89 
90 /**
91  * @brief Function for checking if the specified interrupts are enabled.
92  *
93  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
94  * @param[in] mask  Mask of interrupts to be checked.
95  *
96  * @return Mask of enabled interrupts.
97  */
98 NRF_STATIC_INLINE uint32_t nrf_rng_int_enable_check(NRF_RNG_Type const * p_reg, uint32_t mask);
99 
100 /**
101  * @brief Function for getting the address of the specified task.
102  *
103  * This function can be used by the PPI module.
104  *
105  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
106  * @param[in] rng_task The specified task.
107  *
108  * @return Address of the specified task.
109  */
110 NRF_STATIC_INLINE uint32_t nrf_rng_task_address_get(NRF_RNG_Type const * p_reg,
111                                                     nrf_rng_task_t       rng_task);
112 
113 /**
114  * @brief Function for triggering the specified task.
115  *
116  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
117  * @param[in] rng_task The specified Task.
118  */
119 NRF_STATIC_INLINE void nrf_rng_task_trigger(NRF_RNG_Type * p_reg, nrf_rng_task_t rng_task);
120 
121 /**
122  * @brief Function for getting address of the specified event.
123  *
124  * This function can be used by the PPI module.
125  *
126  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
127  * @param[in] rng_event The specified event.
128  *
129  * @return Address of the specified event.
130  */
131 NRF_STATIC_INLINE uint32_t nrf_rng_event_address_get(NRF_RNG_Type const * p_reg,
132                                                      nrf_rng_event_t      rng_event);
133 
134 /**
135  * @brief Function for clearing the specified event.
136  *
137  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
138  * @param[in] rng_event The specified event.
139  */
140 NRF_STATIC_INLINE void nrf_rng_event_clear(NRF_RNG_Type * p_reg, nrf_rng_event_t rng_event);
141 
142 /**
143  * @brief Function for retrieving the state of the specified event.
144  *
145  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
146  * @param[in] rng_event The specified event.
147  *
148  * @retval true  The event is set.
149  * @retval false The event is not set.
150  */
151 NRF_STATIC_INLINE bool nrf_rng_event_check(NRF_RNG_Type const * p_reg, nrf_rng_event_t rng_event);
152 
153 /**
154  * @brief Function for setting shortcuts.
155  *
156  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
157  * @param[in] mask  Mask of shortcuts.
158  */
159 NRF_STATIC_INLINE void nrf_rng_shorts_enable(NRF_RNG_Type * p_reg, uint32_t mask);
160 
161 /**
162  * @brief Function for clearing shortcuts.
163  *
164  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
165  * @param[in] mask  Mask of shortcuts.
166  */
167 NRF_STATIC_INLINE void nrf_rng_shorts_disable(NRF_RNG_Type * p_reg, uint32_t mask);
168 
169 /**
170  * @brief Function for getting the previously generated random value.
171  *
172  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
173  *
174  * @return Previously generated random value.
175  */
176 NRF_STATIC_INLINE uint8_t nrf_rng_random_value_get(NRF_RNG_Type const * p_reg);
177 
178 /**
179  * @brief Function for enabling digital error correction.
180  *
181  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
182  */
183 NRF_STATIC_INLINE void nrf_rng_error_correction_enable(NRF_RNG_Type * p_reg);
184 
185 /**
186  * @brief Function for disabling digital error correction.
187  *
188  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
189  */
190 NRF_STATIC_INLINE void nrf_rng_error_correction_disable(NRF_RNG_Type * p_reg);
191 
192 
193 #ifndef NRF_DECLARE_ONLY
194 
nrf_rng_int_enable(NRF_RNG_Type * p_reg,uint32_t mask)195 NRF_STATIC_INLINE void nrf_rng_int_enable(NRF_RNG_Type * p_reg, uint32_t mask)
196 {
197     p_reg->INTENSET = mask;
198 }
199 
nrf_rng_int_disable(NRF_RNG_Type * p_reg,uint32_t mask)200 NRF_STATIC_INLINE void nrf_rng_int_disable(NRF_RNG_Type * p_reg, uint32_t mask)
201 {
202     p_reg->INTENCLR = mask;
203 }
204 
nrf_rng_int_enable_check(NRF_RNG_Type const * p_reg,uint32_t mask)205 NRF_STATIC_INLINE uint32_t nrf_rng_int_enable_check(NRF_RNG_Type const * p_reg, uint32_t mask)
206 {
207     return p_reg->INTENSET & mask;
208 }
209 
nrf_rng_task_address_get(NRF_RNG_Type const * p_reg,nrf_rng_task_t rng_task)210 NRF_STATIC_INLINE uint32_t nrf_rng_task_address_get(NRF_RNG_Type const * p_reg,
211                                                     nrf_rng_task_t       rng_task)
212 {
213     return (uint32_t)((uint8_t *)p_reg + (uint32_t)rng_task);
214 }
215 
nrf_rng_task_trigger(NRF_RNG_Type * p_reg,nrf_rng_task_t rng_task)216 NRF_STATIC_INLINE void nrf_rng_task_trigger(NRF_RNG_Type * p_reg, nrf_rng_task_t rng_task)
217 {
218     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)rng_task)) = 0x1UL;
219 }
220 
nrf_rng_event_address_get(NRF_RNG_Type const * p_reg,nrf_rng_event_t rng_event)221 NRF_STATIC_INLINE uint32_t nrf_rng_event_address_get(NRF_RNG_Type const * p_reg,
222                                                      nrf_rng_event_t      rng_event)
223 {
224     return (uint32_t)((uint8_t *)p_reg + (uint32_t)rng_event);
225 }
226 
nrf_rng_event_clear(NRF_RNG_Type * p_reg,nrf_rng_event_t rng_event)227 NRF_STATIC_INLINE void nrf_rng_event_clear(NRF_RNG_Type * p_reg, nrf_rng_event_t rng_event)
228 {
229     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)rng_event)) = 0x0UL;
230     nrf_event_readback((uint8_t *)p_reg + (uint32_t)rng_event);
231 }
232 
nrf_rng_event_check(NRF_RNG_Type const * p_reg,nrf_rng_event_t rng_event)233 NRF_STATIC_INLINE bool nrf_rng_event_check(NRF_RNG_Type const * p_reg, nrf_rng_event_t rng_event)
234 {
235     return (bool) * ((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)rng_event));
236 }
237 
nrf_rng_shorts_enable(NRF_RNG_Type * p_reg,uint32_t mask)238 NRF_STATIC_INLINE void nrf_rng_shorts_enable(NRF_RNG_Type * p_reg, uint32_t mask)
239 {
240      p_reg->SHORTS |= mask;
241 }
242 
nrf_rng_shorts_disable(NRF_RNG_Type * p_reg,uint32_t mask)243 NRF_STATIC_INLINE void nrf_rng_shorts_disable(NRF_RNG_Type * p_reg, uint32_t mask)
244 {
245      p_reg->SHORTS &= ~mask;
246 }
247 
nrf_rng_random_value_get(NRF_RNG_Type const * p_reg)248 NRF_STATIC_INLINE uint8_t nrf_rng_random_value_get(NRF_RNG_Type const * p_reg)
249 {
250     return (uint8_t)(p_reg->VALUE & RNG_VALUE_VALUE_Msk);
251 }
252 
nrf_rng_error_correction_enable(NRF_RNG_Type * p_reg)253 NRF_STATIC_INLINE void nrf_rng_error_correction_enable(NRF_RNG_Type * p_reg)
254 {
255     p_reg->CONFIG |= RNG_CONFIG_DERCEN_Msk;
256 }
257 
nrf_rng_error_correction_disable(NRF_RNG_Type * p_reg)258 NRF_STATIC_INLINE void nrf_rng_error_correction_disable(NRF_RNG_Type * p_reg)
259 {
260     p_reg->CONFIG &= ~RNG_CONFIG_DERCEN_Msk;
261 }
262 
263 #endif // NRF_DECLARE_ONLY
264 
265 /** @} */
266 
267 #ifdef __cplusplus
268 }
269 #endif
270 
271 #endif /* NRF_RNG_H__ */
272