1 /*
2  * Copyright (c) 2019 - 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_CACHE_H__
35 #define NRF_CACHE_H__
36 
37 #include <nrfx.h>
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * @defgroup nrf_cache_hal CACHE HAL
45  * @{
46  * @ingroup nrf_cache
47  * @brief   The hardware access layer for managing the CACHE peripheral.
48  */
49 
50 #if defined(CACHEDATA_SET_WAY_DU_DATA_Data_Msk) || defined(CACHEDATA_SET_WAY_DATA0_Data_Msk) || \
51     defined(__NRFX_DOXYGEN__)
52 /** @brief Presence of the CACHEDATA feature. */
53 #define NRF_CACHE_HAS_CACHEDATA 1
54 #else
55 #define NRF_CACHE_HAS_CACHEDATA 0
56 #endif
57 
58 #if defined(CACHEDATA_SET_WAY_DU_DATA_Data_Msk) || defined(__NRFX_DOXYGEN__)
59 /** @brief Presence of the CACHE data units feature. */
60 #define NRF_CACHE_HAS_CACHEDATA_DU 1
61 #else
62 #define NRF_CACHE_HAS_CACHEDATA_DU 0
63 #endif
64 
65 #if defined(CACHEINFO_SET_WAY_INFO_TAG_Msk) || defined(CACHEINFO_SET_WAY_TAG_Msk) || \
66     defined(__NRFX_DOXYGEN__)
67 /** @brief Presence of the CACHEINFO feature. */
68 #define NRF_CACHE_HAS_CACHEINFO 1
69 #else
70 #define NRF_CACHE_HAS_CACHEINFO 0
71 #endif
72 
73 #if defined(CACHE_TASKS_INVALIDATECACHE_TASKS_INVALIDATECACHE_Msk) || defined(__NRFX_DOXYGEN__)
74 /** @brief Symbol indicating whether cache tasks are supported. */
75 #define NRF_CACHE_HAS_TASKS 1
76 #else
77 #define NRF_CACHE_HAS_TASKS 0
78 #endif
79 
80 #if defined(CACHE_TASKS_CLEANCACHE_TASKS_CLEANCACHE_Msk) || defined(__NRFX_DOXYGEN__)
81 /** @brief Symbol indicating whether the CLEAN cache/line tasks are supported. */
82 #define NRF_CACHE_HAS_TASK_CLEAN 1
83 #else
84 #define NRF_CACHE_HAS_TASK_CLEAN 0
85 #endif
86 
87 #if defined(CACHE_TASKS_FLUSHCACHE_TASKS_FLUSHCACHE_Msk) || defined(__NRFX_DOXYGEN__)
88 /** @brief Symbol indicating whether the FLUSH cache/line tasks are supported. */
89 #define NRF_CACHE_HAS_TASK_FLUSH 1
90 #else
91 #define NRF_CACHE_HAS_TASK_FLUSH 0
92 #endif
93 
94 #if defined(CACHE_TASKS_SAVE_TASKS_SAVE_Msk) || defined(__NRFX_DOXYGEN__)
95 /** @brief Symbol indicating whether save and restore tasks are supported. */
96 #define NRF_CACHE_HAS_TASK_SAVE_RESTORE 1
97 #else
98 #define NRF_CACHE_HAS_TASK_SAVE_RESTORE 0
99 #endif
100 
101 #if defined(CACHE_STATUS_READY_Msk) || defined(CACHE_STATUS_BUSY_Msk) || defined(__NRFX_DOXYGEN__)
102 /** @brief Symbol indicating whether status check is supported. */
103 #define NRF_CACHE_HAS_STATUS 1
104 #else
105 #define NRF_CACHE_HAS_STATUS 0
106 #endif
107 
108 #if defined(CACHE_MODE_MODE_Msk) || defined(__NRFX_DOXYGEN__)
109 /** @brief Symbol indicating whether splitting the dedicated RAM between cache and generic memory is supported. */
110 #define NRF_CACHE_HAS_RAM_MODE 1
111 #else
112 #define NRF_CACHE_HAS_RAM_MODE 0
113 #endif
114 
115 #if defined(CACHE_MODE_RAMSIZE_Msk) || defined(__NRFX_DOXYGEN__)
116 /** @brief Symbol indicating whether configuration of split of dedicated RAM between cache and generic memory is supported. */
117 #define NRF_CACHE_HAS_RAMSIZE 1
118 #else
119 #define NRF_CACHE_HAS_RAMSIZE 0
120 #endif
121 
122 #if defined(CACHEINFO_SET_WAY_D0_Msk) || defined(__NRFX_DOXYGEN__)
123 /** @brief Symbol indicating whether dirtiness check functionality for cache is supported. */
124 #define NRF_CACHE_HAS_CACHEINFO_DU_DIRTY 1
125 #else
126 #define NRF_CACHE_HAS_CACHEINFO_DU_DIRTY 0
127 #endif
128 
129 #if defined(CACHEINFO_SET_WAY_DUV0_Msk) || defined(CACHEINFO_SET_WAY_INFO_DUV0_Msk) || defined(__NRFX_DOXYGEN__)
130 /** @brief Symbol indicating whether data unit validation functionality for cache is supported. */
131 #define NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION 1
132 #else
133 #define NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION 0
134 #endif
135 
136 #if defined(CACHEINFO_SET_WAY_INFO_DUV0_Msk) || defined(__NRFX_DOXYGEN__)
137 /** @brief Symbol indicating whether cache info has INFO register. */
138 #define NRF_CACHE_HAS_CACHEINFO_SET_WAY_INFO 1
139 #else
140 #define NRF_CACHE_HAS_CACHEINFO_SET_WAY_INFO 0
141 #endif
142 
143 #if NRF_CACHE_HAS_CACHEDATA
144 /** @brief Max number of words in CACHEDATA data units. */
145 #define NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX CACHEDATA_SET_WAY_DU_DATA_MaxCount
146 /** @brief Max number of CACHEDATA data units. */
147 #define NRF_CACHEDATA_DATA_UNITS_MAX CACHEDATA_SET_WAY_DU_MaxCount
148 /** @brief Max number of CACHEDATA words. */
149 #define NRF_CACHEDATA_WORD_INDEX_MAX \
150         (NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX * NRF_CACHEDATA_DATA_UNITS_MAX)
151 /** @brief Max number of CACHEDATA ways. */
152 #define NRF_CACHEDATA_WAY_INDEX_MAX  CACHEDATA_SET_WAY_MaxCount
153 /** @brief Max number of CACHEDATA sets. */
154 #define NRF_CACHEDATA_SET_INDEX_MAX  CACHEDATA_SET_MaxCount
155 #endif
156 
157 #if NRF_CACHE_HAS_CACHEINFO
158 /** @brief Max number of words in CACHEINFO data units. */
159 #define NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX CACHEDATA_SET_WAY_DU_DATA_MaxCount
160 /** @brief Max number of CACHEINFO data units. */
161 #define NRF_CACHEINFO_DATA_UNITS_MAX CACHEDATA_SET_WAY_DU_MaxCount
162 /** @brief Max number of CACHEINFO words. */
163 #define NRF_CACHEINFO_WORD_INDEX_MAX \
164         (NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX * NRF_CACHEINFO_DATA_UNITS_MAX)
165 /** @brief Max number of CACHEINFO ways. */
166 #define NRF_CACHEINFO_WAY_INDEX_MAX  CACHEINFO_SET_WAY_MaxCount
167 /** @brief Max number of CACHEINFO sets. */
168 #define NRF_CACHEINFO_SET_INDEX_MAX  CACHEINFO_SET_MaxCount
169 #endif
170 
171 #if NRF_CACHE_HAS_RAMSIZE
172 /** @brief Max enumerator value of RAMSIZE field. */
173 #define NRF_CACHE_MODE_RAMSIZE_MAX CACHE_MODE_RAMSIZE_Max
174 #endif
175 
176 #if NRF_CACHE_HAS_TASKS
177 /** @brief CACHE tasks. */
178 typedef enum
179 {
180 #if NRF_CACHE_HAS_TASK_CLEAN
181     NRF_CACHE_TASK_CLEANCACHE      = offsetof(NRF_CACHE_Type, TASKS_CLEANCACHE),      /**< Clean the whole cache. */
182     NRF_CACHE_TASK_CLEANLINE       = offsetof(NRF_CACHE_Type, TASKS_CLEANLINE),       /**< Clean the cache line. */
183 #endif
184 #if NRF_CACHE_HAS_TASK_FLUSH
185     NRF_CACHE_TASK_FLUSHCACHE      = offsetof(NRF_CACHE_Type, TASKS_FLUSHCACHE),      /**< Flush the whole cache. */
186     NRF_CACHE_TASK_FLUSHLINE       = offsetof(NRF_CACHE_Type, TASKS_FLUSHLINE),       /**< Flush the cache line. */
187 #endif
188 #if NRF_CACHE_HAS_TASK_SAVE_RESTORE
189     NRF_CACHE_TASK_SAVE            = offsetof(NRF_CACHE_Type, TASKS_SAVE),            /**< Save the state to a retained memory space. */
190     NRF_CACHE_TASK_RESTORE         = offsetof(NRF_CACHE_Type, TASKS_RESTORE),         /**< Restore the state from a retained memory space. */
191 #endif
192     NRF_CACHE_TASK_INVALIDATECACHE = offsetof(NRF_CACHE_Type, TASKS_INVALIDATECACHE), /**< Invalidate the whole cache. */
193     NRF_CACHE_TASK_INVALIDATELINE  = offsetof(NRF_CACHE_Type, TASKS_INVALIDATELINE),  /**< Invalidate the cache line. */
194     NRF_CACHE_TASK_ERASE           = offsetof(NRF_CACHE_Type, TASKS_ERASE),           /**< Erase the whole cache. */
195 } nrf_cache_task_t;
196 #endif
197 
198 /** @brief Cache regions. */
199 typedef enum
200 {
201     NRF_CACHE_REGION_FLASH = 0, ///< Cache region related to Flash access.
202     NRF_CACHE_REGION_XIP   = 1, ///< Cache region related to XIP access.
203 } nrf_cache_region_t;
204 
205 #if NRF_CACHE_HAS_RAMSIZE
206 /** @brief Dedicated RAM size used for cache memory. */
207 typedef enum
208 {
209     NRF_CACHE_RAMSIZE_ALL     = CACHE_MODE_RAMSIZE_All,     ///< All RAM is used for cache memory.
210     NRF_CACHE_RAMSIZE_HALF    = CACHE_MODE_RAMSIZE_Half,    ///< Half of the RAM is used for cache memory.
211     NRF_CACHE_RAMSIZE_QUARTER = CACHE_MODE_RAMSIZE_Quarter, ///< Quarter of the RAM is used for cache memory.
212     NRF_CACHE_RAMSIZE_NONE    = CACHE_MODE_RAMSIZE_None     ///< None of the RAM is used for cache memory.
213 } nrf_cache_ramsize_t;
214 #endif
215 
216 /**
217  * @brief Function for enabling the CACHE peripheral.
218  *
219  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
220  */
221 NRF_STATIC_INLINE void nrf_cache_enable(NRF_CACHE_Type * p_reg);
222 
223 /**
224  * @brief Function for disabling the CACHE peripheral.
225  *
226  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
227  */
228 NRF_STATIC_INLINE void nrf_cache_disable(NRF_CACHE_Type * p_reg);
229 
230 /**
231  * @brief Function for checking if the CACHE peripheral is enabled.
232  *
233  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
234  *
235  * @retval true  The CACHE is enabled.
236  * @retval false The CACHE is not enabled.
237  */
238 NRF_STATIC_INLINE bool nrf_cache_enable_check(NRF_CACHE_Type const * p_reg);
239 
240 /**
241  * @brief Function for invalidating the cache content.
242  *
243  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
244  */
245 NRF_STATIC_INLINE void nrf_cache_invalidate(NRF_CACHE_Type * p_reg);
246 
247 /**
248  * @brief Function for erasing the cache content.
249  *
250  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
251  */
252 NRF_STATIC_INLINE void nrf_cache_erase(NRF_CACHE_Type * p_reg);
253 
254 /**
255  * @brief Function for checking the status of @ref nrf_cache_erase().
256  *
257  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
258  *
259  * @retval true  Erase is finished.
260  * @retval false Erase is not complete or has not started.
261  */
262 NRF_STATIC_INLINE bool nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg);
263 
264 /**
265  * @brief Function for clearing the status of the cache erase.
266  *
267  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
268  */
269 NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg);
270 
271 /**
272  * @brief Function for setting the cache profiling.
273  *
274  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
275  * @param[in] enable True if cache profiling is to be enabled, false otherwise.
276  */
277 NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable);
278 
279 /**
280  * @brief Function for clearing the cache profiling counters.
281  *
282  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
283  */
284 NRF_STATIC_INLINE void nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg);
285 
286 /**
287  * @brief Function for getting the number of cache hits for instruction fetch from the specified
288  *        cache region.
289  *
290  * @note Separate counters are used for flash region and XIP region.
291  * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
292  *
293  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
294  * @param[in] region Cache region.
295  *
296  * @return Number of instruction fetch cache hits.
297  */
298 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,
299                                                                  nrf_cache_region_t     region);
300 
301 /**
302  * @brief Function for getting the number of cache misses for instruction fetch from the specified
303  *        cache region.
304  *
305  * @note Separate counters are used for flash region and XIP region.
306  * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
307  *
308  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
309  * @param[in] region Cache region.
310  *
311  * @return Number of instruction fetch cache misses.
312  */
313 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,
314                                                                   nrf_cache_region_t     region);
315 
316 /**
317  * @brief Function for getting the number of cache hits for data fetch from the specified
318  *        cache region.
319  *
320  * @note Separate counters are used for flash region and XIP region.
321  * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
322  *
323  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
324  * @param[in] region Cache region.
325  *
326  * @return Number of data fetch cache hits.
327  */
328 NRF_STATIC_INLINE uint32_t nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,
329                                                           nrf_cache_region_t     region);
330 
331 /**
332  * @brief Function for getting the number of cache misses for data fetch from the specified
333  *        cache region.
334  *
335  * @note Separate counters are used for flash region and XIP region.
336  * @note Cache profiling must be enabled first. See @ref nrf_cache_profiling_set.
337  *
338  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
339  * @param[in] region Cache region.
340  *
341  * @return Number of data fetch cache misses.
342  */
343 NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,
344                                                            nrf_cache_region_t     region);
345 
346 #if NRF_CACHE_HAS_RAM_MODE
347 /**
348  * @brief Function for setting the cache RAM mode.
349  *
350  * When configured in the RAM mode, the accesses to internal or external flash will not be cached.
351  * In this mode, the cache data contents can be used as the read/write RAM.
352  * Only the data content of the cache is available as RAM.
353  *
354  * @note Enabling the RAM mode causes the RAM to be cleared.
355  * @note Disabling the RAM mode causes the cache to be invalidated.
356  *
357  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
358  * @param[in] enable True if the cache RAM mode is to be enabled, false otherwise.
359  */
360 NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable);
361 
362 /**
363  * @brief Function for checking whether the cache is in RAM mode.
364  *
365  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
366  *
367  * @return True if the cache RAM mode is enabled, false otherwise.
368  */
369 NRF_STATIC_INLINE bool nrf_cache_ram_mode_check(NRF_CACHE_Type const * p_reg);
370 #endif
371 
372 #if NRF_CACHE_HAS_RAMSIZE
373 /**
374  * @brief Function for setting the configuration of splitting the dedicated cache RAM.
375  *
376  * @details Dedicated cache RAM can be splitted into cache memory and generic memory.
377  *          By default, all dedicated RAM is used for cache memory.
378  *
379  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
380  * @param[in] ramsize Dedicated cache RAM split configuration.
381  */
382 NRF_STATIC_INLINE void nrf_cache_ramsize_set(NRF_CACHE_Type * p_reg, nrf_cache_ramsize_t ramsize);
383 
384 /**
385  * @brief Function for getting the configuration of splitting the dedicated cache RAM.
386  *
387  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
388  *
389  * @return Configuration of dedicated cache RAM split.
390  */
391 NRF_STATIC_INLINE nrf_cache_ramsize_t nrf_cache_ramsize_get(NRF_CACHE_Type const * p_reg);
392 #endif
393 
394 /**
395  * @brief Function for blocking the cache content access.
396  *
397  * To unlock the cache content access, a reset has to be performed.
398  *
399  * @note Blocking is ignored in the RAM mode.
400  *
401  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
402  */
403 NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg);
404 
405 /**
406  * @brief Function for blocking the cache content updates.
407  *
408  * Blocking of updates prevents updating of cache content on cache misses,
409  * but the peripheral will continue to check for instruction/data fetches
410  * in the content already present in the cache.
411  *
412  * @note Blocking is ignored in the RAM mode.
413  *
414  * @param[in] p_reg  Pointer to the structure of registers of the peripheral.
415  * @param[in] enable True if cache content update lock is to be enabled, false otherwise.
416  */
417 NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable);
418 
419 #if NRF_CACHE_HAS_CACHEDATA
420 /**
421  * @brief Function for getting the cache data word.
422  *
423  * @note When operating in the RAM mode, the cache data is accessible as a general purpose RAM.
424  *
425  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
426  * @param[in] set   Set that contains the data to get.
427  * @param[in] way   Way that contains the data to get.
428  * @param[in] word  Data word index to get.
429  *
430  * @return 32-bit data word.
431  */
432 NRF_STATIC_INLINE uint32_t nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,
433                                               uint32_t                   set,
434                                               uint8_t                    way,
435                                               uint8_t                    word);
436 #endif
437 
438 #if NRF_CACHE_HAS_CACHEINFO
439 /**
440  * @brief Function for getting the tag associated with the specified set and way.
441  *
442  * The tag is used to check if an entry in the cache matches the address that is being fetched.
443  *
444  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
445  * @param[in] set   Set that contains the tag to get.
446  * @param[in] way   Way that contains the tag to get.
447  *
448  * @return Tag value.
449  */
450 NRF_STATIC_INLINE uint32_t nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,
451                                              uint32_t                   set,
452                                              uint8_t                    way);
453 
454 /**
455  * @brief Function for checking the validity of a cache line associated with the specified set and way.
456  *
457  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
458  * @param[in] set   Set that contains the cache line to check.
459  * @param[in] way   Way that contains the cache line to check.
460  *
461  * @retval true  Cache line is valid.
462  * @retval false Cache line is invalid.
463  */
464 NRF_STATIC_INLINE bool nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,
465                                                      uint32_t                   set,
466                                                      uint8_t                    way);
467 
468 /**
469  * @brief Function for getting the most recently used way in the specified set.
470  *
471  * The most recently used way is updated on each fetch from the cache and is used for the cache replacement policy.
472  *
473  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
474  * @param[in] set   Specified set.
475  *
476  * @return The most recently used way in the specified set.
477  */
478 NRF_STATIC_INLINE uint8_t nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg, uint32_t set);
479 #endif
480 
481 #if NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION
482 /**
483  * @brief Function for checking the validity of a data unit associated with the specified set, way and word.
484  *
485  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
486  * @param[in] set   Set that contains the data unit to check.
487  * @param[in] way   Way that contains the data unit to check.
488  * @param[in] word  Data word index.
489  *
490  * @retval true  Data unit is valid.
491  * @retval false Data unit is invalid.
492  */
493 NRF_STATIC_INLINE bool nrf_cache_data_unit_validity_check(NRF_CACHEINFO_Type const * p_reg,
494                                                           uint32_t                   set,
495                                                           uint8_t                    way,
496                                                           uint8_t                    word);
497 #endif
498 
499 #if NRF_CACHE_HAS_CACHEINFO_DU_DIRTY
500 /**
501  * @brief Function for checking the dirtiness of a data unit associated with the specified set, way and word.
502  *
503  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
504  * @param[in] set   Set that contains the data unit to check.
505  * @param[in] way   Way that contains the data unit to check.
506  * @param[in] word  Data word index.
507  *
508  * @retval true  Data unit is dirty.
509  * @retval false Data unit is clean.
510  */
511 NRF_STATIC_INLINE bool nrf_cache_is_data_unit_dirty_check(NRF_CACHEINFO_Type const * p_reg,
512                                                           uint32_t                   set,
513                                                           uint8_t                    way,
514                                                           uint8_t                    word);
515 #endif
516 
517 #if NRF_CACHE_HAS_TASKS
518 /**
519  * @brief Function to set the memory address covered by the line to be maintained.
520  *
521  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
522  * @param[in] addr  Cache line adress.
523  */
524 NRF_STATIC_INLINE void nrf_cache_lineaddr_set(NRF_CACHE_Type * p_reg, uint32_t addr);
525 
526 /**
527  * @brief Function to get the memory address covered by the line to be maintained.
528  *
529  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
530  *
531  * @return Cache line adress.
532  */
533 NRF_STATIC_INLINE uint32_t nrf_cache_lineaddr_get(NRF_CACHE_Type const * p_reg);
534 
535 /**
536  * @brief Function for triggering the specified CACHE task.
537  *
538  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
539  * @param[in] task  Task.
540  */
541 NRF_STATIC_INLINE void nrf_cache_task_trigger(NRF_CACHE_Type * p_reg, nrf_cache_task_t task);
542 
543 /**
544  * @brief Function for returning the address of the specified task register.
545  *
546  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
547  * @param[in] task  Task.
548  *
549  * @return Task address.
550  */
551 NRF_STATIC_INLINE uint32_t nrf_cache_task_address_get(NRF_CACHE_Type const * p_reg,
552                                                       nrf_cache_task_t       task);
553 #endif
554 
555 #if NRF_CACHE_HAS_STATUS
556 /**
557  * @brief Function for checking if the cache is busy or not.
558  *
559  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
560  *
561  * @return True if the cache is busy, false otherwise.
562  */
563 NRF_STATIC_INLINE bool nrf_cache_busy_check(NRF_CACHE_Type const * p_reg);
564 #endif
565 
566 #ifndef NRF_DECLARE_ONLY
567 
nrf_cache_enable(NRF_CACHE_Type * p_reg)568 NRF_STATIC_INLINE void nrf_cache_enable(NRF_CACHE_Type * p_reg)
569 {
570     p_reg->ENABLE = CACHE_ENABLE_ENABLE_Enabled;
571 }
572 
nrf_cache_disable(NRF_CACHE_Type * p_reg)573 NRF_STATIC_INLINE void nrf_cache_disable(NRF_CACHE_Type * p_reg)
574 {
575     p_reg->ENABLE = CACHE_ENABLE_ENABLE_Disabled;
576 }
577 
nrf_cache_enable_check(NRF_CACHE_Type const * p_reg)578 NRF_STATIC_INLINE bool nrf_cache_enable_check(NRF_CACHE_Type const * p_reg)
579 {
580     return p_reg->ENABLE == CACHE_ENABLE_ENABLE_Enabled;
581 }
582 
nrf_cache_invalidate(NRF_CACHE_Type * p_reg)583 NRF_STATIC_INLINE void nrf_cache_invalidate(NRF_CACHE_Type * p_reg)
584 {
585 #if NRF_CACHE_HAS_TASKS
586     nrf_cache_task_trigger(p_reg, NRF_CACHE_TASK_INVALIDATECACHE);
587 #else
588     p_reg->INVALIDATE = CACHE_INVALIDATE_INVALIDATE_Invalidate;
589 #endif
590 }
591 
nrf_cache_erase(NRF_CACHE_Type * p_reg)592 NRF_STATIC_INLINE void nrf_cache_erase(NRF_CACHE_Type * p_reg)
593 {
594 #if NRF_CACHE_HAS_TASKS
595     nrf_cache_task_trigger(p_reg, NRF_CACHE_TASK_ERASE);
596 #else
597     p_reg->ERASE = CACHE_ERASE_ERASE_Erase;
598 #endif
599 }
600 
nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg)601 NRF_STATIC_INLINE bool nrf_cache_erase_status_check(NRF_CACHE_Type const * p_reg)
602 {
603 #if NRF_CACHE_HAS_STATUS
604     return (!nrf_cache_busy_check(p_reg));
605 #else
606     return (p_reg->ERASESTATUS & CACHE_ERASESTATUS_ERASESTATUS_Msk) ==
607         (CACHE_ERASESTATUS_ERASESTATUS_Finished << CACHE_ERASESTATUS_ERASESTATUS_Pos);
608 #endif
609 }
610 
nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg)611 NRF_STATIC_INLINE void nrf_cache_erase_status_clear(NRF_CACHE_Type * p_reg)
612 {
613 #if NRF_CACHE_HAS_TASKS
614     /* No task for erasing the status */
615     (void)p_reg;
616 #else
617     p_reg->ERASESTATUS = 0;
618 #endif
619 }
620 
nrf_cache_profiling_set(NRF_CACHE_Type * p_reg,bool enable)621 NRF_STATIC_INLINE void nrf_cache_profiling_set(NRF_CACHE_Type * p_reg, bool enable)
622 {
623 #if defined(CACHE_PROFILINGENABLE_ENABLE_Msk)
624     p_reg->PROFILINGENABLE =
625         (enable ? CACHE_PROFILINGENABLE_ENABLE_Enable : CACHE_PROFILINGENABLE_ENABLE_Disable);
626 #elif defined(CACHE_PROFILING_ENABLE_ENABLE_Msk)
627     p_reg->PROFILING.ENABLE =
628         (enable ? CACHE_PROFILING_ENABLE_ENABLE_Enable : CACHE_PROFILING_ENABLE_ENABLE_Disable);
629 #endif
630 }
631 
nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg)632 NRF_STATIC_INLINE void nrf_cache_profiling_counters_clear(NRF_CACHE_Type * p_reg)
633 {
634 #if defined(CACHE_PROFILINGCLEAR_CLEAR_Msk)
635     p_reg->PROFILINGCLEAR = (CACHE_PROFILINGCLEAR_CLEAR_Clear << CACHE_PROFILINGCLEAR_CLEAR_Pos);
636 #elif defined(CACHE_PROFILING_CLEAR_CLEAR_Msk)
637     p_reg->PROFILING.CLEAR = (CACHE_PROFILING_CLEAR_CLEAR_Clear << CACHE_PROFILING_CLEAR_CLEAR_Pos);
638 #endif
639 }
640 
nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)641 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_hit_counter_get(NRF_CACHE_Type const * p_reg,
642                                                                  nrf_cache_region_t     region)
643 {
644 #if defined(CACHE_PROFILING_IHIT_HITS_Msk)
645     return p_reg->PROFILING[region].IHIT;
646 #elif defined(CACHE_PROFILING_HIT_HITS_Msk)
647     (void)region;
648     return p_reg->PROFILING.HIT;
649 #endif
650 }
651 
nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)652 NRF_STATIC_INLINE uint32_t nrf_cache_instruction_miss_counter_get(NRF_CACHE_Type const * p_reg,
653                                                                   nrf_cache_region_t     region)
654 {
655 #if defined(CACHE_PROFILING_IMISS_MISSES_Msk)
656     return p_reg->PROFILING[region].IMISS;
657 #elif defined(CACHE_PROFILING_MISS_MISSES_Msk)
658     (void)region;
659     return p_reg->PROFILING.MISS;
660 #endif
661 }
662 
nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)663 NRF_STATIC_INLINE uint32_t nrf_cache_data_hit_counter_get(NRF_CACHE_Type const * p_reg,
664                                                           nrf_cache_region_t     region)
665 {
666 #if defined(CACHE_PROFILING_DHIT_HITS_Msk)
667     return p_reg->PROFILING[region].DHIT;
668 #elif defined(CACHE_PROFILING_HIT_HITS_Msk)
669     (void)region;
670     return p_reg->PROFILING.HIT;
671 #endif
672 }
673 
nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,nrf_cache_region_t region)674 NRF_STATIC_INLINE uint32_t nrf_cache_data_miss_counter_get(NRF_CACHE_Type const * p_reg,
675                                                            nrf_cache_region_t     region)
676 {
677 #if defined(CACHE_PROFILING_DMISS_MISSES_Msk)
678     return p_reg->PROFILING[region].DMISS;
679 #elif defined(CACHE_PROFILING_MISS_MISSES_Msk)
680     (void)region;
681     return p_reg->PROFILING.MISS;
682 #endif
683 }
684 
685 #if NRF_CACHE_HAS_RAM_MODE
nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg,bool enable)686 NRF_STATIC_INLINE void nrf_cache_ram_mode_set(NRF_CACHE_Type * p_reg, bool enable)
687 {
688     p_reg->MODE = ((p_reg->MODE & ~CACHE_MODE_MODE_Msk) |
689                    ((enable ? CACHE_MODE_MODE_Ram : CACHE_MODE_MODE_Cache)
690                    << CACHE_MODE_MODE_Pos));
691 }
692 
nrf_cache_ram_mode_check(NRF_CACHE_Type const * p_reg)693 NRF_STATIC_INLINE bool nrf_cache_ram_mode_check(NRF_CACHE_Type const * p_reg)
694 {
695     return (p_reg->MODE & CACHE_MODE_MODE_Msk) == (CACHE_MODE_MODE_Ram << CACHE_MODE_MODE_Pos);
696 }
697 #endif
698 
699 #if NRF_CACHE_HAS_RAMSIZE
nrf_cache_ramsize_set(NRF_CACHE_Type * p_reg,nrf_cache_ramsize_t ramsize)700 NRF_STATIC_INLINE void nrf_cache_ramsize_set(NRF_CACHE_Type * p_reg, nrf_cache_ramsize_t ramsize)
701 {
702     p_reg->MODE = ((p_reg->MODE & ~CACHE_MODE_RAMSIZE_Msk) | (ramsize << CACHE_MODE_RAMSIZE_Pos));
703 }
704 
nrf_cache_ramsize_get(NRF_CACHE_Type const * p_reg)705 NRF_STATIC_INLINE nrf_cache_ramsize_t nrf_cache_ramsize_get(NRF_CACHE_Type const * p_reg)
706 {
707     return (nrf_cache_ramsize_t)((p_reg->MODE & CACHE_MODE_RAMSIZE_Msk) >> CACHE_MODE_RAMSIZE_Pos);
708 }
709 #endif
710 
nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg)711 NRF_STATIC_INLINE void nrf_cache_read_lock_enable(NRF_CACHE_Type * p_reg)
712 {
713     p_reg->DEBUGLOCK = CACHE_DEBUGLOCK_DEBUGLOCK_Locked;
714 }
715 
nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg,bool enable)716 NRF_STATIC_INLINE void nrf_cache_update_lock_set(NRF_CACHE_Type * p_reg, bool enable)
717 {
718     p_reg->WRITELOCK =
719         (enable ? CACHE_WRITELOCK_WRITELOCK_Locked : CACHE_WRITELOCK_WRITELOCK_Unlocked);
720 }
721 
722 #if NRF_CACHE_HAS_CACHEDATA
nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,uint32_t set,uint8_t way,uint8_t word)723 NRF_STATIC_INLINE uint32_t nrf_cache_data_get(NRF_CACHEDATA_Type const * p_reg,
724                                               uint32_t                   set,
725                                               uint8_t                    way,
726                                               uint8_t                    word)
727 {
728 #if NRF_CACHE_HAS_CACHEDATA_DU
729     NRFX_ASSERT(word < NRF_CACHEDATA_WORD_INDEX_MAX);
730     NRFX_ASSERT(way < NRF_CACHEDATA_WAY_INDEX_MAX);
731     NRFX_ASSERT(set < NRF_CACHEDATA_SET_INDEX_MAX);
732 
733     uint8_t du   = (word / NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX);
734     uint8_t data = (uint8_t)(word - (du * NRF_CACHEDATA_DATA_WORDS_IN_UNIT_MAX));
735 
736     return p_reg->SET[set].WAY[way].DU[du].DATA[data];
737 #else
738     volatile CACHEDATA_SET_WAY_Type const * reg = &p_reg->SET[set].WAY[way];
739     switch (word)
740     {
741         case 0: return reg->DATA0;
742         case 1: return reg->DATA1;
743         case 2: return reg->DATA2;
744         case 3: return reg->DATA3;
745         default:
746             NRFX_ASSERT(false);
747             return 0;
748     }
749 #endif
750 }
751 #endif
752 
753 #if NRF_CACHE_HAS_CACHEINFO
nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way)754 NRF_STATIC_INLINE uint32_t nrf_cache_tag_get(NRF_CACHEINFO_Type const * p_reg,
755                                              uint32_t                   set,
756                                              uint8_t                    way)
757 {
758 #if defined(CACHEINFO_SET_WAY_INFO_TAG_Msk)
759     NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
760     NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
761     return (p_reg->SET[set].WAY[way].INFO & CACHEINFO_SET_WAY_INFO_TAG_Msk);
762 #else
763     return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_TAG_Msk);
764 #endif
765 }
766 
nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way)767 NRF_STATIC_INLINE bool nrf_cache_line_validity_check(NRF_CACHEINFO_Type const * p_reg,
768                                                      uint32_t                   set,
769                                                      uint8_t                    way)
770 {
771 #if defined(CACHEINFO_SET_WAY_INFO_V_Msk)
772     NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
773     NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
774     return (p_reg->SET[set].WAY[way].INFO & CACHEINFO_SET_WAY_INFO_V_Msk) ==
775         (CACHEINFO_SET_WAY_INFO_V_Valid << CACHEINFO_SET_WAY_INFO_V_Pos);
776 #else
777     return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_V_Msk) ==
778         (CACHEINFO_SET_WAY_V_Valid << CACHEINFO_SET_WAY_V_Pos);
779 #endif
780 }
781 
nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg,uint32_t set)782 NRF_STATIC_INLINE uint8_t nrf_cache_mru_get(NRF_CACHEINFO_Type const * p_reg, uint32_t set)
783 {
784 #if defined(CACHEINFO_SET_WAY_INFO_MRU_Pos)
785     NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
786     return ((p_reg->SET[set].WAY[0].INFO & CACHEINFO_SET_WAY_INFO_MRU_Msk) >>
787         CACHEINFO_SET_WAY_INFO_MRU_Pos);
788 #else
789     return ((p_reg->SET[set].WAY[0] & CACHEINFO_SET_WAY_MRU_Msk) >> CACHEINFO_SET_WAY_MRU_Pos);
790 #endif
791 }
792 
793 #if NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION
nrf_cache_data_unit_validity_check(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way,uint8_t word)794 NRF_STATIC_INLINE bool nrf_cache_data_unit_validity_check(NRF_CACHEINFO_Type const * p_reg,
795                                                           uint32_t                   set,
796                                                           uint8_t                    way,
797                                                           uint8_t                    word)
798 {
799     NRFX_ASSERT(word < NRF_CACHEINFO_WORD_INDEX_MAX);
800     NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
801     NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
802 
803     uint8_t du = (word / NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX);
804     switch (du)
805     {
806 #if NRF_CACHE_HAS_CACHEINFO_SET_WAY_INFO
807         case 0:
808             return (p_reg->SET[set].WAY[way].INFO &
809                     CACHEINFO_SET_WAY_INFO_DUV0_Msk) ==
810                    (CACHEINFO_SET_WAY_INFO_DUV0_Valid << CACHEINFO_SET_WAY_INFO_DUV0_Pos);
811         case 1:
812             return (p_reg->SET[set].WAY[way].INFO &
813                     CACHEINFO_SET_WAY_INFO_DUV1_Msk) ==
814                    (CACHEINFO_SET_WAY_INFO_DUV1_Valid << CACHEINFO_SET_WAY_INFO_DUV1_Pos);
815         case 2:
816             return (p_reg->SET[set].WAY[way].INFO &
817                     CACHEINFO_SET_WAY_INFO_DUV2_Msk) ==
818                    (CACHEINFO_SET_WAY_INFO_DUV2_Valid << CACHEINFO_SET_WAY_INFO_DUV2_Pos);
819         case 3:
820             return (p_reg->SET[set].WAY[way].INFO &
821                     CACHEINFO_SET_WAY_INFO_DUV3_Msk) ==
822                    (CACHEINFO_SET_WAY_INFO_DUV3_Valid << CACHEINFO_SET_WAY_INFO_DUV3_Pos);
823 #else
824         case 0:
825             return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV0_Msk) ==
826                    (CACHEINFO_SET_WAY_DUV0_Valid << CACHEINFO_SET_WAY_DUV0_Pos);
827         case 1:
828             return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV1_Msk) ==
829                    (CACHEINFO_SET_WAY_DUV1_Valid << CACHEINFO_SET_WAY_DUV1_Pos);
830         case 2:
831             return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV2_Msk) ==
832                    (CACHEINFO_SET_WAY_DUV2_Valid << CACHEINFO_SET_WAY_DUV2_Pos);
833         case 3:
834             return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_DUV3_Msk) ==
835                    (CACHEINFO_SET_WAY_DUV3_Valid << CACHEINFO_SET_WAY_DUV3_Pos);
836 #endif
837         default:
838             NRFX_ASSERT(false);
839             return false;
840     }
841 }
842 #endif // NRF_CACHE_HAS_CACHEINFO_DU_VALIDATION
843 
844 #if NRF_CACHE_HAS_CACHEINFO_DU_DIRTY
nrf_cache_is_data_unit_dirty_check(NRF_CACHEINFO_Type const * p_reg,uint32_t set,uint8_t way,uint8_t word)845 NRF_STATIC_INLINE bool nrf_cache_is_data_unit_dirty_check(NRF_CACHEINFO_Type const * p_reg,
846                                                           uint32_t                   set,
847                                                           uint8_t                    way,
848                                                           uint8_t                    word)
849 {
850     NRFX_ASSERT(word < NRF_CACHEINFO_WORD_INDEX_MAX);
851     NRFX_ASSERT(way < NRF_CACHEINFO_WAY_INDEX_MAX);
852     NRFX_ASSERT(set < NRF_CACHEINFO_SET_INDEX_MAX);
853 
854     uint8_t du = (word / NRF_CACHEINFO_DATA_WORDS_IN_UNIT_MAX);
855     switch (du)
856     {
857         case 0:
858             /* FALLTHROUGH */
859         case 1:
860             return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_D0_Msk) ==
861                 (CACHEINFO_SET_WAY_D0_Dirty << CACHEINFO_SET_WAY_D0_Pos);
862         case 2:
863             /* FALLTHROUGH */
864         case 3:
865             return (p_reg->SET[set].WAY[way] & CACHEINFO_SET_WAY_D1_Msk) ==
866                 (CACHEINFO_SET_WAY_D1_Dirty << CACHEINFO_SET_WAY_D1_Pos);
867         default:
868             NRFX_ASSERT(false);
869             return false;
870     }
871 }
872 #endif
873 #endif // NRF_CACHE_HAS_CACHEINFO
874 
875 #if NRF_CACHE_HAS_TASKS
nrf_cache_lineaddr_set(NRF_CACHE_Type * p_reg,uint32_t addr)876 NRF_STATIC_INLINE void nrf_cache_lineaddr_set(NRF_CACHE_Type * p_reg, uint32_t addr)
877 {
878     p_reg->LINEADDR = addr;
879 }
880 
nrf_cache_lineaddr_get(NRF_CACHE_Type const * p_reg)881 NRF_STATIC_INLINE uint32_t nrf_cache_lineaddr_get(NRF_CACHE_Type const * p_reg)
882 {
883     return p_reg->LINEADDR;
884 }
885 
nrf_cache_task_trigger(NRF_CACHE_Type * p_reg,nrf_cache_task_t task)886 NRF_STATIC_INLINE void nrf_cache_task_trigger(NRF_CACHE_Type * p_reg, nrf_cache_task_t task)
887 {
888     *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
889 }
890 
nrf_cache_task_address_get(NRF_CACHE_Type const * p_reg,nrf_cache_task_t task)891 NRF_STATIC_INLINE uint32_t nrf_cache_task_address_get(NRF_CACHE_Type const * p_reg,
892                                                       nrf_cache_task_t       task)
893 {
894     return (uint32_t)p_reg + (uint32_t)task;
895 }
896 #endif
897 
898 #if NRF_CACHE_HAS_STATUS
nrf_cache_busy_check(NRF_CACHE_Type const * p_reg)899 NRF_STATIC_INLINE bool nrf_cache_busy_check(NRF_CACHE_Type const * p_reg)
900 {
901 #if defined(CACHE_STATUS_READY_Msk)
902     return (p_reg->STATUS & CACHE_STATUS_READY_Msk) ==
903         (CACHE_STATUS_READY_Busy << CACHE_STATUS_READY_Pos);
904 #else
905     return (p_reg->STATUS & CACHE_STATUS_BUSY_Msk) ==
906         (CACHE_STATUS_BUSY_Busy << CACHE_STATUS_BUSY_Pos);
907 #endif
908 }
909 #endif
910 
911 #endif // NRF_DECLARE_ONLY
912 
913 /** @} */
914 
915 #ifdef __cplusplus
916 }
917 #endif
918 
919 #endif // NRF_CACHE_H__
920