1 /*
2  * Copyright (c) 2019 - 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_AAR_H__
35 #define NRF_AAR_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrf_aar_hal AAR HAL
45  * @{
46  * @ingroup nrf_aar
47  * @brief   Hardware access layer for managing the Accelerated Address Resolver (AAR) peripheral.
48  */
49 
50 /** @brief AAR events. */
51 typedef enum
52 {
53     NRF_AAR_EVENT_END         = offsetof(NRF_AAR_Type, EVENTS_END),         ///< Address resolution procedure complete.
54     NRF_AAR_EVENT_RESOLVED    = offsetof(NRF_AAR_Type, EVENTS_RESOLVED),    ///< Address resolved.
55     NRF_AAR_EVENT_NOTRESOLVED = offsetof(NRF_AAR_Type, EVENTS_NOTRESOLVED), ///< Address not resolved.
56 } nrf_aar_event_t;
57 
58 /** @brief AAR interrupts. */
59 typedef enum
60 {
61     NRF_AAR_INT_END_MASK         = AAR_INTENSET_END_Msk,         ///< Interrupt on END event.
62     NRF_AAR_INT_RESOLVED_MASK    = AAR_INTENSET_RESOLVED_Msk,    ///< Interrupt on RESOLVED event.
63     NRF_AAR_INT_NOTRESOLVED_MASK = AAR_INTENSET_NOTRESOLVED_Msk, ///< Interrupt on NOTRESOLVED event.
64 } nrf_aar_int_mask_t;
65 
66 /** @brief AAR tasks. */
67 typedef enum
68 {
69     NRF_AAR_TASK_START = offsetof(NRF_AAR_Type, TASKS_START), ///< Start address resolution procedure.
70     NRF_AAR_TASK_STOP  = offsetof(NRF_AAR_Type, TASKS_STOP),  ///< Stop address resolution procedure.
71 } nrf_aar_task_t;
72 
73 /**
74  * @brief Function for retrieving the state of the AAR event.
75  *
76  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
77  * @param[in] event Event to be checked.
78  *
79  * @retval true  Event is set.
80  * @retval false Event is not set.
81  */
82 NRF_STATIC_INLINE bool nrf_aar_event_check(NRF_AAR_Type const * p_reg,
83                                            nrf_aar_event_t      event);
84 
85 /**
86  * @brief Function for clearing the specified AAR event.
87  *
88  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
89  * @param[in] event Event to be cleared.
90  */
91 NRF_STATIC_INLINE void nrf_aar_event_clear(NRF_AAR_Type *  p_reg,
92                                            nrf_aar_event_t event);
93 
94 /**
95  * @brief Function for getting the address of the specified AAR event register.
96  *
97  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
98  * @param[in] event Event to get the address of.
99  *
100  * @return Address of the specified event register.
101  */
102 NRF_STATIC_INLINE uint32_t nrf_aar_event_address_get(NRF_AAR_Type const * p_reg,
103                                                      nrf_aar_event_t      event);
104 
105 /**
106  * @brief Function for enabling the specified interrupts.
107  *
108  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
109  * @param[in] mask  Mask of interrupts to be enabled.
110  */
111 NRF_STATIC_INLINE void nrf_aar_int_enable(NRF_AAR_Type * p_reg, uint32_t mask);
112 
113 /**
114  * @brief Function for checking if the specified interrupts are enabled.
115  *
116  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
117  * @param[in] mask  Mask of interrupts to be checked.
118  *
119  * @return Mask of enabled interrupts.
120  */
121 NRF_STATIC_INLINE uint32_t nrf_aar_int_enable_check(NRF_AAR_Type const * p_reg, uint32_t mask);
122 
123 /**
124  * @brief Function for disabling the specified interrupts.
125  *
126  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
127  * @param[in] mask  Mask of interrupts to be disabled.
128  */
129 NRF_STATIC_INLINE void nrf_aar_int_disable(NRF_AAR_Type * p_reg, uint32_t mask);
130 
131 /**
132  * @brief Function for starting an AAR task.
133  *
134  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
135  * @param[in] task  Task to be activated.
136  */
137 NRF_STATIC_INLINE void nrf_aar_task_trigger(NRF_AAR_Type * p_reg, nrf_aar_task_t task);
138 
139 /**
140  * @brief Function for getting the address of a specific AAR task register.
141  *
142  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
143  * @param[in] task  Requested AAR task.
144  *
145  * @return Address of the specified task register.
146  */
147 NRF_STATIC_INLINE uint32_t nrf_aar_task_address_get(NRF_AAR_Type const * p_reg,
148                                                     nrf_aar_task_t       task);
149 
150 /**
151  * @brief Function for enabling AAR.
152  *
153  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
154  */
155 NRF_STATIC_INLINE void nrf_aar_enable(NRF_AAR_Type * p_reg);
156 
157 /**
158  * @brief Function for disabling AAR.
159  *
160  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
161  */
162 NRF_STATIC_INLINE void nrf_aar_disable(NRF_AAR_Type * p_reg);
163 
164 /**
165  * @brief Function for setting the pointer to the Identity Resolving Keys (IRK) data structure.
166  *
167  * The size of the provided data structure must correspond to the number of keys available.
168  * Each key occupies 16 bytes.
169  *
170  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
171  * @param[in] irk_ptr Pointer to the IRK data structure. Must point to the Data RAM region.
172  *
173  * @sa nrf_aar_irk_number_set
174  */
175 NRF_STATIC_INLINE void nrf_aar_irk_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * irk_ptr);
176 
177 /**
178  * @brief Function for getting the pointer to the Identity Resolving Keys
179  *        data structure.
180  *
181  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
182  *
183  * @return Pointer to the IRK data structure.
184  */
185 NRF_STATIC_INLINE uint8_t const * nrf_aar_irk_pointer_get(NRF_AAR_Type const * p_reg);
186 
187 /**
188  * @brief Function for setting the number of keys available in the Identity Resolving Keys
189  *        data structure.
190  *
191  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
192  * @param[in] irk_num Number of keys available in the IRK data structure. Maximum is 16.
193  *                    Must correspond to the size of the provided IRK data structure.
194  *
195  * @sa nrf_aar_irk_pointer_set
196  */
197 NRF_STATIC_INLINE void nrf_aar_irk_number_set(NRF_AAR_Type * p_reg, uint8_t irk_num);
198 
199 /**
200  * @brief Function for getting the number of keys available in the Identity Resolving Keys
201  *        data structure.
202  *
203  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
204  *
205  * @return Number of keys in the IRK data structure.
206  */
207 NRF_STATIC_INLINE uint8_t nrf_aar_irk_number_get(NRF_AAR_Type const * p_reg);
208 
209 /**
210  * @brief Function for setting the pointer to the resolvable address.
211  *
212  * The resolvable address must consist of 6 bytes.
213  *
214  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
215  * @param[in] addr_ptr Pointer to the address to resolve using the available IRK keys.
216  *                     Must point to the Data RAM region.
217  */
218 NRF_STATIC_INLINE void nrf_aar_addr_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * addr_ptr);
219 
220 /**
221  * @brief Function for getting the pointer to the resolvable address.
222  *
223  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
224  *
225  * @return Pointer to the address to resolve.
226  */
227 NRF_STATIC_INLINE uint8_t const * nrf_aar_addr_pointer_get(NRF_AAR_Type const * p_reg);
228 
229 /**
230  * @brief Function for setting the pointer to the scratch data area.
231  *
232  * The scratch data area is used for temporary storage during the address resolution procedure.
233  * A space of minimum 3 bytes must be reserved for the scratch data area.
234  *
235  * @param[in] p_reg       Pointer to the structure of registers of the peripheral.
236  * @param[in] scratch_ptr Pointer to the scratch data area. Must point to the Data RAM region.
237  */
238 NRF_STATIC_INLINE void nrf_aar_scratch_pointer_set(NRF_AAR_Type * p_reg, uint8_t * scratch_ptr);
239 
240 /**
241  * @brief Function for getting the pointer to the scratch data area.
242  *
243  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
244  *
245  * @return Pointer to the scratch data area.
246  */
247 NRF_STATIC_INLINE uint8_t * nrf_aar_scratch_pointer_get(NRF_AAR_Type const * p_reg);
248 
249 /**
250  * @brief Function for getting the index of the Identity Resolving Key that was used
251  *        the last time an address was resolved.
252  *
253  * This function can be used to get the IRK index that matched the resolvable address,
254  * provided that @ref NRF_AAR_EVENT_RESOLVED occured. Otherwise, it will return
255  * the index of the last IRK stored in the IRK data structure.
256  *
257  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
258  *
259  * @return The index of the IRK that was used the last time an address was resolved.
260  */
261 NRF_STATIC_INLINE uint8_t nrf_aar_resolution_status_get(NRF_AAR_Type const * p_reg);
262 
263 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
264 /**
265  * @brief Function for setting the subscribe configuration for a given
266  *        AAR task.
267  *
268  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
269  * @param[in] task    Task for which to set the configuration.
270  * @param[in] channel Channel through which to subscribe events.
271  */
272 NRF_STATIC_INLINE void nrf_aar_subscribe_set(NRF_AAR_Type * p_reg,
273                                              nrf_aar_task_t task,
274                                              uint8_t        channel);
275 
276 /**
277  * @brief Function for clearing the subscribe configuration for a given
278  *        AAR task.
279  *
280  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
281  * @param[in] task  Task for which to clear the configuration.
282  */
283 NRF_STATIC_INLINE void nrf_aar_subscribe_clear(NRF_AAR_Type * p_reg,
284                                                nrf_aar_task_t task);
285 
286 /**
287  * @brief Function for setting the publish configuration for a given
288  *        AAR event.
289  *
290  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
291  * @param[in] event   Event for which to set the configuration.
292  * @param[in] channel Channel through which to publish the event.
293  */
294 NRF_STATIC_INLINE void nrf_aar_publish_set(NRF_AAR_Type *  p_reg,
295                                            nrf_aar_event_t event,
296                                            uint8_t         channel);
297 
298 /**
299  * @brief Function for clearing the publish configuration for a given
300  *        AAR event.
301  *
302  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
303  * @param[in] event Event for which to clear the configuration.
304  */
305 NRF_STATIC_INLINE void nrf_aar_publish_clear(NRF_AAR_Type *  p_reg,
306                                              nrf_aar_event_t event);
307 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
308 
309 #ifndef NRF_DECLARE_ONLY
nrf_aar_event_check(NRF_AAR_Type const * p_reg,nrf_aar_event_t aar_event)310 NRF_STATIC_INLINE bool nrf_aar_event_check(NRF_AAR_Type const * p_reg,
311                                            nrf_aar_event_t      aar_event)
312 {
313     return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)aar_event);
314 }
315 
nrf_aar_event_clear(NRF_AAR_Type * p_reg,nrf_aar_event_t aar_event)316 NRF_STATIC_INLINE void nrf_aar_event_clear(NRF_AAR_Type *  p_reg,
317                                            nrf_aar_event_t aar_event)
318 {
319     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)aar_event)) = 0;
320     nrf_event_readback((uint8_t *)p_reg + (uint32_t)aar_event);
321 }
322 
nrf_aar_event_address_get(NRF_AAR_Type const * p_reg,nrf_aar_event_t aar_event)323 NRF_STATIC_INLINE uint32_t nrf_aar_event_address_get(NRF_AAR_Type const * p_reg,
324                                                      nrf_aar_event_t      aar_event)
325 {
326     return (uint32_t)((uint8_t *)p_reg + (uint32_t)aar_event);
327 }
328 
nrf_aar_int_enable(NRF_AAR_Type * p_reg,uint32_t mask)329 NRF_STATIC_INLINE void nrf_aar_int_enable(NRF_AAR_Type * p_reg, uint32_t mask)
330 {
331     p_reg->INTENSET = mask;
332 }
333 
nrf_aar_int_enable_check(NRF_AAR_Type const * p_reg,uint32_t mask)334 NRF_STATIC_INLINE uint32_t nrf_aar_int_enable_check(NRF_AAR_Type const * p_reg, uint32_t mask)
335 {
336     return p_reg->INTENSET & mask;
337 }
338 
nrf_aar_int_disable(NRF_AAR_Type * p_reg,uint32_t mask)339 NRF_STATIC_INLINE void nrf_aar_int_disable(NRF_AAR_Type * p_reg, uint32_t mask)
340 {
341     p_reg->INTENCLR = mask;
342 }
343 
nrf_aar_task_trigger(NRF_AAR_Type * p_reg,nrf_aar_task_t task)344 NRF_STATIC_INLINE void nrf_aar_task_trigger(NRF_AAR_Type * p_reg, nrf_aar_task_t task)
345 {
346     *(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task) = 1;
347 }
348 
nrf_aar_task_address_get(NRF_AAR_Type const * p_reg,nrf_aar_task_t task)349 NRF_STATIC_INLINE uint32_t nrf_aar_task_address_get(NRF_AAR_Type const * p_reg,
350                                                     nrf_aar_task_t       task)
351 {
352     return (uint32_t)((uint8_t *)p_reg + (uint32_t)task);
353 }
354 
nrf_aar_enable(NRF_AAR_Type * p_reg)355 NRF_STATIC_INLINE void nrf_aar_enable(NRF_AAR_Type * p_reg)
356 {
357     p_reg->ENABLE = AAR_ENABLE_ENABLE_Enabled << AAR_ENABLE_ENABLE_Pos;
358 }
359 
nrf_aar_disable(NRF_AAR_Type * p_reg)360 NRF_STATIC_INLINE void nrf_aar_disable(NRF_AAR_Type * p_reg)
361 {
362     p_reg->ENABLE = AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos;
363 }
364 
nrf_aar_irk_pointer_set(NRF_AAR_Type * p_reg,uint8_t const * irk_ptr)365 NRF_STATIC_INLINE void nrf_aar_irk_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * irk_ptr)
366 {
367     p_reg->IRKPTR = (uint32_t)irk_ptr;
368 }
369 
nrf_aar_irk_pointer_get(NRF_AAR_Type const * p_reg)370 NRF_STATIC_INLINE uint8_t const * nrf_aar_irk_pointer_get(NRF_AAR_Type const * p_reg)
371 {
372     return (uint8_t const *)(p_reg->IRKPTR);
373 }
374 
nrf_aar_irk_number_set(NRF_AAR_Type * p_reg,uint8_t irk_num)375 NRF_STATIC_INLINE void nrf_aar_irk_number_set(NRF_AAR_Type * p_reg, uint8_t irk_num)
376 {
377     p_reg->NIRK = irk_num;
378 }
379 
nrf_aar_irk_number_get(NRF_AAR_Type const * p_reg)380 NRF_STATIC_INLINE uint8_t nrf_aar_irk_number_get(NRF_AAR_Type const * p_reg)
381 {
382     return (uint8_t)(p_reg->NIRK);
383 }
384 
nrf_aar_addr_pointer_set(NRF_AAR_Type * p_reg,uint8_t const * addr_ptr)385 NRF_STATIC_INLINE void nrf_aar_addr_pointer_set(NRF_AAR_Type * p_reg, uint8_t const * addr_ptr)
386 {
387     p_reg->ADDRPTR = (uint32_t)addr_ptr;
388 }
389 
nrf_aar_addr_pointer_get(NRF_AAR_Type const * p_reg)390 NRF_STATIC_INLINE uint8_t const * nrf_aar_addr_pointer_get(NRF_AAR_Type const * p_reg)
391 {
392     return (uint8_t const *)(p_reg->ADDRPTR);
393 }
394 
nrf_aar_scratch_pointer_set(NRF_AAR_Type * p_reg,uint8_t * scratch_ptr)395 NRF_STATIC_INLINE void nrf_aar_scratch_pointer_set(NRF_AAR_Type * p_reg, uint8_t * scratch_ptr)
396 {
397     p_reg->SCRATCHPTR = (uint32_t)scratch_ptr;
398 }
399 
nrf_aar_scratch_pointer_get(NRF_AAR_Type const * p_reg)400 NRF_STATIC_INLINE uint8_t * nrf_aar_scratch_pointer_get(NRF_AAR_Type const * p_reg)
401 {
402     return (uint8_t *)(p_reg->SCRATCHPTR);
403 }
404 
nrf_aar_resolution_status_get(NRF_AAR_Type const * p_reg)405 NRF_STATIC_INLINE uint8_t nrf_aar_resolution_status_get(NRF_AAR_Type const * p_reg)
406 {
407     return (uint8_t)(p_reg->STATUS);
408 }
409 
410 #if defined(DPPI_PRESENT)
nrf_aar_subscribe_set(NRF_AAR_Type * p_reg,nrf_aar_task_t task,uint8_t channel)411 NRF_STATIC_INLINE void nrf_aar_subscribe_set(NRF_AAR_Type * p_reg,
412                                              nrf_aar_task_t task,
413                                              uint8_t        channel)
414 {
415     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) =
416             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
417 }
418 
nrf_aar_subscribe_clear(NRF_AAR_Type * p_reg,nrf_aar_task_t task)419 NRF_STATIC_INLINE void nrf_aar_subscribe_clear(NRF_AAR_Type * p_reg,
420                                                nrf_aar_task_t task)
421 {
422     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0;
423 }
424 
nrf_aar_publish_set(NRF_AAR_Type * p_reg,nrf_aar_event_t event,uint8_t channel)425 NRF_STATIC_INLINE void nrf_aar_publish_set(NRF_AAR_Type *  p_reg,
426                                            nrf_aar_event_t event,
427                                            uint8_t         channel)
428 {
429     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) =
430             ((uint32_t)channel | NRF_SUBSCRIBE_PUBLISH_ENABLE);
431 }
432 
nrf_aar_publish_clear(NRF_AAR_Type * p_reg,nrf_aar_event_t event)433 NRF_STATIC_INLINE void nrf_aar_publish_clear(NRF_AAR_Type *  p_reg,
434                                              nrf_aar_event_t event)
435 {
436     *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0;
437 }
438 #endif // defined(DPPI_PRESENT)
439 
440 #endif // NRF_DECLARE_ONLY
441 
442 /** @} */
443 
444 #ifdef __cplusplus
445 }
446 #endif
447 
448 #endif // NRF_AAR_H__
449