xref: /nrf52832-nimble/nordic/nrfx/hal/nrf_ccm.h (revision 150812a83cab50279bd772ef6db1bfaf255f2c5b)
1 /*
2  * Copyright (c) 2018, 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_CCM_H__
33 #define NRF_CCM_H__
34 
35 #include <nrfx.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 /**
42  * @defgroup nrf_ccm_hal AES CCM HAL
43  * @{
44  * @ingroup nrf_ccm
45  * @brief   Hardware access layer for managing the AES CCM peripheral.
46  */
47 
48 /**
49  * @brief CCM tasks.
50  */
51 typedef enum
52 {
53     /*lint -save -e30*/
54     NRF_CCM_TASK_KSGEN        = offsetof(NRF_CCM_Type, TASKS_KSGEN),        ///< Start generation of key-stream.
55     NRF_CCM_TASK_CRYPT        = offsetof(NRF_CCM_Type, TASKS_CRYPT),        ///< Start encryption/decryption.
56     NRF_CCM_TASK_STOP         = offsetof(NRF_CCM_Type, TASKS_STOP),         ///< Stop encryption/decryption.
57 #if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
58     NRF_CCM_TASK_RATEOVERRIDE = offsetof(NRF_CCM_Type, TASKS_RATEOVERRIDE), ///< Override DATARATE setting in MODE register.
59 #endif
60     /*lint -restore*/
61 } nrf_ccm_task_t;
62 
63 /**
64  * @brief CCM events.
65  */
66 typedef enum
67 {
68     /*lint -save -e30*/
69     NRF_CCM_EVENT_ENDKSGEN = offsetof(NRF_CCM_Type, EVENTS_ENDKSGEN), ///< Keystream generation complete.
70     NRF_CCM_EVENT_ENDCRYPT = offsetof(NRF_CCM_Type, EVENTS_ENDCRYPT), ///< Encrypt/decrypt complete.
71     NRF_CCM_EVENT_ERROR    = offsetof(NRF_CCM_Type, EVENTS_ERROR),    ///< CCM error event.
72     /*lint -restore*/
73 } nrf_ccm_event_t;
74 
75 /**
76  * @brief CCM interrupts.
77  */
78 typedef enum
79 {
80     NRF_CCM_INT_ENDKSGEN_MASK  = CCM_INTENSET_ENDKSGEN_Msk, ///< Interrupt on ENDKSGEN event.
81     NRF_CCM_INT_ENDCRYPT_MASK  = CCM_INTENSET_ENDCRYPT_Msk, ///< Interrupt on ENDCRYPT event.
82     NRF_CCM_INT_ERROR_MASK     = CCM_INTENSET_ERROR_Msk,    ///< Interrupt on ERROR event.
83 } nrf_ccm_int_mask_t;
84 
85 /**
86  * @brief CCM modes of operation.
87  */
88 typedef enum
89 {
90     NRF_CCM_MODE_ENCRYPTION = CCM_MODE_MODE_Encryption, ///< Encryption mode.
91     NRF_CCM_MODE_DECRYPTION = CCM_MODE_MODE_Decryption, ///< Decryption mode.
92 } nrf_ccm_mode_t;
93 
94 #if defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
95 /**
96  * @brief CCM data rates.
97  */
98 typedef enum
99 {
100     NRF_CCM_DATARATE_1M   = CCM_MODE_DATARATE_1Mbit,   ///< 1 Mbps.
101     NRF_CCM_DATARATE_2M   = CCM_MODE_DATARATE_2Mbit,   ///< 2 Mbps.
102 #if defined(CCM_MODE_DATARATE_125Kbps) || defined(__NRFX_DOXYGEN__)
103     NRF_CCM_DATARATE_125K = CCM_MODE_DATARATE_125Kbps, ///< 125 Kbps.
104 #endif
105 #if defined(CCM_MODE_DATARATE_500Kbps) || defined(__NRFX_DOXYGEN__)
106     NRF_CCM_DATARATE_500K = CCM_MODE_DATARATE_500Kbps, ///< 500 Kbps.
107 #endif
108 } nrf_ccm_datarate_t;
109 #endif // defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
110 
111 #if defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
112 /**
113  * @brief CCM packet length options.
114  */
115 typedef enum
116 {
117     NRF_CCM_LENGTH_DEFAULT  = CCM_MODE_LENGTH_Default,  ///< Default length.
118     NRF_CCM_LENGTH_EXTENDED = CCM_MODE_LENGTH_Extended, ///< Extended length.
119 } nrf_ccm_length_t;
120 #endif // defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
121 
122 /**
123  * @brief CCM configuration.
124  */
125 typedef struct {
126     nrf_ccm_mode_t     mode;
127 #if defined(CCM_MODE_DATARATE_Pos) || defined(__NRFX_DOXYGEN__)
128     nrf_ccm_datarate_t datarate;
129 #endif
130 #if defined(CCM_MODE_LENGTH_Pos) || defined(__NRFX_DOXYGEN__)
131     nrf_ccm_length_t   length;
132 #endif
133 } nrf_ccm_config_t;
134 
135 /**
136  * @brief Function for activating a specific CCM task.
137  *
138  * @param[in] p_reg Pointer to the peripheral registers structure.
139  * @param[in] task  Task to activate.
140  */
141 __STATIC_INLINE void nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,
142                                           nrf_ccm_task_t task);
143 
144 /**
145  * @brief Function for getting the address of a specific CCM task register.
146  *
147  * @param[in] p_reg Pointer to the peripheral registers structure.
148  * @param[in] task  Requested task.
149  *
150  * @return Address of the specified task register.
151  */
152 __STATIC_INLINE uint32_t nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,
153                                                   nrf_ccm_task_t       task);
154 
155 /**
156  * @brief Function for clearing a specific CCM event.
157  *
158  * @param[in] p_reg Pointer to the peripheral registers structure.
159  * @param[in] event Event to clear.
160  */
161 __STATIC_INLINE void nrf_ccm_event_clear(NRF_CCM_Type *  p_reg,
162                                          nrf_ccm_event_t event);
163 
164 /**
165  * @brief Function for checking the state of a specific CCM event.
166  *
167  * @param[in] p_reg Pointer to the peripheral registers structure.
168  * @param[in] event Event to check.
169  *
170  * @retval true  If the event is set.
171  * @retval false If the event is not set.
172  */
173 __STATIC_INLINE bool nrf_ccm_event_check(NRF_CCM_Type const * p_reg,
174                                          nrf_ccm_event_t      event);
175 
176 /**
177  * @brief Function for getting the address of a specific CCM event register.
178  *
179  * @param[in] p_reg Pointer to the peripheral registers structure.
180  * @param[in] event Requested event.
181  *
182  * @return Address of the specified event register.
183  */
184 __STATIC_INLINE uint32_t nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,
185                                                    nrf_ccm_event_t      event);
186 
187 /**
188  * @brief Function for enabling specified interrupts.
189  *
190  * @param[in] p_reg Pointer to the peripheral registers structure.
191  * @param[in] mask  Interrupts to enable.
192  */
193 __STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask);
194 
195 /**
196  * @brief Function for disabling specified interrupts.
197  *
198  * @param[in] p_reg Pointer to the peripheral registers structure.
199  * @param[in] mask  Interrupts to disable.
200  */
201 __STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask);
202 
203 /**
204  * @brief Function for retrieving the state of a given interrupt.
205  *
206  * @param[in] p_reg   Pointer to the peripheral registers structure.
207  * @param[in] ccm_int Interrupt to check.
208  *
209  * @retval true  If the interrupt is enabled.
210  * @retval false If the interrupt is not enabled.
211  */
212 __STATIC_INLINE bool nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,
213                                               nrf_ccm_int_mask_t   ccm_int);
214 
215 /**
216  * @brief Function for enabling the CCM peripheral.
217  *
218  * @param[in] p_reg  Pointer to the peripheral registers structure.
219  */
220 __STATIC_INLINE void nrf_ccm_enable(NRF_CCM_Type * p_reg);
221 
222 /**
223  * @brief Function for disabling the CCM peripheral.
224  *
225  * @param[in] p_reg  Pointer to the peripheral registers structure.
226  */
227 __STATIC_INLINE void nrf_ccm_disable(NRF_CCM_Type * p_reg);
228 
229 /**
230  * @brief Function for setting the CCM peripheral configuration.
231  *
232  * @param[in] p_reg    Pointer to the peripheral registers structure.
233  * @param[in] p_config Pointer to the structure with configuration to be set.
234  */
235 __STATIC_INLINE void nrf_ccm_configure(NRF_CCM_Type *           p_reg,
236                                        nrf_ccm_config_t const * p_config);
237 
238 #if defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) || defined(__NRFX_DOXYGEN__)
239 /**
240  * @brief Function for setting the length of key-stream generated
241  *        when the packet length is configured as extended.
242  *
243  * @param[in] p_reg Pointer to the peripheral registers structure.
244  * @param[in] size  Maximum length of the key-stream.
245  */
246 __STATIC_INLINE void nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,
247                                                uint8_t        size);
248 #endif // defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos) || defined(__NRFX_DOXYGEN__)
249 
250 /**
251  * @brief Function for getting the MIC check result.
252  *
253  * @param[in] p_reg Pointer to the peripheral registers structure.
254  *
255  * @retval true  If the MIC check passed.
256  * @retval false If the MIC check failed.
257  */
258 __STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg);
259 
260 /**
261  * @brief Function for setting the pointer to the data structure
262  *        holding the AES key and the CCM NONCE vector.
263  *
264  * @param[in] p_reg  Pointer to the peripheral registers structure.
265  * @param[in] p_data Pointer to the data structure.
266  */
267 __STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type *   p_reg,
268                                         uint32_t const * p_data);
269 
270 /**
271  * @brief Function for getting the pointer to the data structure
272  *        holding the AES key and the CCM NONCE vector.
273  *
274  * @param[in] p_reg Pointer to the peripheral registers structure.
275  *
276  * @return Pointer to the data structure.
277  */
278 __STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg);
279 
280 /**
281  * @brief Function for setting the input data pointer.
282  *
283  * @param[in] p_reg  Pointer to the peripheral registers structure.
284  * @param[in] p_data Input data pointer.
285  */
286 __STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type *   p_reg,
287                                        uint32_t const * p_data);
288 
289 /**
290  * @brief Function for getting the input data pointer.
291  *
292  * @param[in] p_reg Pointer to the peripheral registers structure.
293  *
294  * @return Input data pointer.
295  */
296 __STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg);
297 
298 /**
299  * @brief Function for setting the output data pointer.
300  *
301  * @param[in] p_reg  Pointer to the peripheral registers structure.
302  * @param[in] p_data Output data pointer.
303  */
304 __STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type *   p_reg,
305                                         uint32_t const * p_data);
306 
307 /**
308  * @brief Function for getting the output data pointer.
309  *
310  * @param[in] p_reg Pointer to the peripheral registers structure.
311  *
312  * @return Output data pointer.
313  */
314 __STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg);
315 
316 /**
317  * @brief Function for setting the pointer to the scratch area used for
318  *        temporary storage.
319  *
320  * @param[in] p_reg  Pointer to the peripheral registers structure.
321  * @param[in] p_area Pointer to the scratch area.
322  */
323 __STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type *   p_reg,
324                                             uint32_t const * p_area);
325 
326 /**
327  * @brief Function for getting the pointer to the scratch area.
328  *
329  * @param[in] p_reg Pointer to the peripheral registers structure.
330  *
331  * @return Pointer to the scratch area.
332  */
333 __STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg);
334 
335 #if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
336 /**
337  * @brief Function for setting the data rate override value.
338  *
339  * @param[in] p_reg    Pointer to the peripheral registers structure.
340  * @param[in] datarate Override value to be applied when the RATEOVERRIDE task
341  *                     is triggered.
342  */
343 __STATIC_INLINE void nrf_ccm_datarate_override_set(NRF_CCM_Type *     p_reg,
344                                                    nrf_ccm_datarate_t datarate);
345 #endif // defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos) || defined(__NRFX_DOXYGEN__)
346 
347 #ifndef SUPPRESS_INLINE_IMPLEMENTATION
348 
nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,nrf_ccm_task_t task)349 __STATIC_INLINE void nrf_ccm_task_trigger(NRF_CCM_Type * p_reg,
350                                           nrf_ccm_task_t task)
351 {
352     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
353 }
354 
nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,nrf_ccm_task_t task)355 __STATIC_INLINE uint32_t nrf_ccm_task_address_get(NRF_CCM_Type const * p_reg,
356                                                   nrf_ccm_task_t       task)
357 {
358     return ((uint32_t)p_reg + (uint32_t)task);
359 }
360 
nrf_ccm_event_clear(NRF_CCM_Type * p_reg,nrf_ccm_event_t event)361 __STATIC_INLINE void nrf_ccm_event_clear(NRF_CCM_Type *  p_reg,
362                                          nrf_ccm_event_t event)
363 {
364     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL;
365 #if __CORTEX_M == 0x04
366     volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event));
367     (void)dummy;
368 #endif
369 }
370 
nrf_ccm_event_check(NRF_CCM_Type const * p_reg,nrf_ccm_event_t event)371 __STATIC_INLINE bool nrf_ccm_event_check(NRF_CCM_Type const * p_reg,
372                                          nrf_ccm_event_t      event)
373 {
374     return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event);
375 }
376 
nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,nrf_ccm_event_t event)377 __STATIC_INLINE uint32_t nrf_ccm_event_address_get(NRF_CCM_Type const * p_reg,
378                                                    nrf_ccm_event_t      event)
379 {
380     return ((uint32_t)p_reg + (uint32_t)event);
381 }
382 
nrf_ccm_int_enable(NRF_CCM_Type * p_reg,uint32_t mask)383 __STATIC_INLINE void nrf_ccm_int_enable(NRF_CCM_Type * p_reg, uint32_t mask)
384 {
385     p_reg->INTENSET = mask;
386 }
387 
nrf_ccm_int_disable(NRF_CCM_Type * p_reg,uint32_t mask)388 __STATIC_INLINE void nrf_ccm_int_disable(NRF_CCM_Type * p_reg, uint32_t mask)
389 {
390     p_reg->INTENCLR = mask;
391 }
392 
nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,nrf_ccm_int_mask_t ccm_int)393 __STATIC_INLINE bool nrf_ccm_int_enable_check(NRF_CCM_Type const * p_reg,
394                                               nrf_ccm_int_mask_t   ccm_int)
395 {
396     return (bool)(p_reg->INTENSET & ccm_int);
397 }
398 
nrf_ccm_enable(NRF_CCM_Type * p_reg)399 __STATIC_INLINE void nrf_ccm_enable(NRF_CCM_Type * p_reg)
400 {
401     p_reg->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos);
402 }
403 
nrf_ccm_disable(NRF_CCM_Type * p_reg)404 __STATIC_INLINE void nrf_ccm_disable(NRF_CCM_Type * p_reg)
405 {
406     p_reg->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos);
407 }
408 
nrf_ccm_configure(NRF_CCM_Type * p_reg,nrf_ccm_config_t const * p_config)409 __STATIC_INLINE void nrf_ccm_configure(NRF_CCM_Type *           p_reg,
410                                        nrf_ccm_config_t const * p_config)
411 {
412     p_reg->MODE = (((uint32_t)p_config->mode     << CCM_MODE_MODE_Pos) |
413 #if defined(CCM_MODE_DATARATE_Pos)
414                    ((uint32_t)p_config->datarate << CCM_MODE_DATARATE_Pos) |
415 #endif
416 #if defined(CCM_MODE_LENGTH_Pos)
417                    ((uint32_t)p_config->length   << CCM_MODE_LENGTH_Pos) |
418 #endif
419                    0);
420 }
421 
422 #if defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,uint8_t size)423 __STATIC_INLINE void nrf_ccm_maxpacketsize_set(NRF_CCM_Type * p_reg,
424                                                uint8_t        size)
425 {
426     NRFX_ASSERT((size >= 0x1B) && (size <= 0xFB));
427 
428     p_reg->MAXPACKETSIZE = size;
429 }
430 #endif // defined(CCM_MAXPACKETSIZE_MAXPACKETSIZE_Pos)
431 
nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg)432 __STATIC_INLINE bool nrf_ccm_micstatus_get(NRF_CCM_Type const * p_reg)
433 {
434     return (bool)(p_reg->MICSTATUS);
435 }
436 
nrf_ccm_cnfptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_data)437 __STATIC_INLINE void nrf_ccm_cnfptr_set(NRF_CCM_Type *   p_reg,
438                                         uint32_t const * p_data)
439 {
440     p_reg->CNFPTR = (uint32_t)p_data;
441 }
442 
nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg)443 __STATIC_INLINE uint32_t * nrf_ccm_cnfptr_get(NRF_CCM_Type const * p_reg)
444 {
445     return (uint32_t *)(p_reg->CNFPTR);
446 }
447 
nrf_ccm_inptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_data)448 __STATIC_INLINE void nrf_ccm_inptr_set(NRF_CCM_Type *   p_reg,
449                                        uint32_t const * p_data)
450 {
451     p_reg->INPTR = (uint32_t)p_data;
452 }
453 
nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg)454 __STATIC_INLINE uint32_t * nrf_ccm_inptr_get(NRF_CCM_Type const * p_reg)
455 {
456     return (uint32_t *)(p_reg->INPTR);
457 }
458 
nrf_ccm_outptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_data)459 __STATIC_INLINE void nrf_ccm_outptr_set(NRF_CCM_Type *   p_reg,
460                                         uint32_t const * p_data)
461 {
462     p_reg->OUTPTR = (uint32_t)p_data;
463 }
464 
nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg)465 __STATIC_INLINE uint32_t * nrf_ccm_outptr_get(NRF_CCM_Type const * p_reg)
466 {
467     return (uint32_t *)(p_reg->OUTPTR);
468 }
469 
nrf_ccm_scratchptr_set(NRF_CCM_Type * p_reg,uint32_t const * p_area)470 __STATIC_INLINE void nrf_ccm_scratchptr_set(NRF_CCM_Type *   p_reg,
471                                             uint32_t const * p_area)
472 {
473     p_reg->SCRATCHPTR = (uint32_t)p_area;
474 }
475 
nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg)476 __STATIC_INLINE uint32_t * nrf_ccm_stratchptr_get(NRF_CCM_Type const * p_reg)
477 {
478     return (uint32_t *)(p_reg->SCRATCHPTR);
479 }
480 
481 #if defined(CCM_RATEOVERRIDE_RATEOVERRIDE_Pos)
nrf_ccm_datarate_override_set(NRF_CCM_Type * p_reg,nrf_ccm_datarate_t datarate)482 __STATIC_INLINE void nrf_ccm_datarate_override_set(NRF_CCM_Type *     p_reg,
483                                                    nrf_ccm_datarate_t datarate)
484 {
485     p_reg->RATEOVERRIDE = ((uint32_t)datarate << CCM_RATEOVERRIDE_RATEOVERRIDE_Pos);
486 }
487 #endif
488 
489 #endif // SUPPRESS_INLINE_IMPLEMENTATION
490 
491 /** @} */
492 
493 #ifdef __cplusplus
494 }
495 #endif
496 
497 #endif  // NRF_CCM_H__
498