1 /*
2  * Copyright (c) 2023 - 2025, 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 NRFY_RRAMC_H__
35 #define NRFY_RRAMC_H__
36 
37 #include <nrfx.h>
38 #include <hal/nrf_rramc.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 NRFY_STATIC_INLINE void __nrfy_internal_rramc_event_enabled_clear(NRF_RRAMC_Type *  p_reg,
45                                                                   uint32_t          mask,
46                                                                   nrf_rramc_event_t event);
47 
48 NRFY_STATIC_INLINE uint32_t __nrfy_internal_rramc_event_handle(NRF_RRAMC_Type *  p_reg,
49                                                                uint32_t          mask,
50                                                                nrf_rramc_event_t event);
51 
52 NRFY_STATIC_INLINE uint32_t __nrfy_internal_rramc_events_process(NRF_RRAMC_Type * p_reg,
53                                                                  uint32_t         mask);
54 
55 NRFY_STATIC_INLINE void __nrfy_internal_rramc_config_get(NRF_RRAMC_Type const * p_reg,
56                                                          nrf_rramc_config_t *   p_config);
57 
58 NRFY_STATIC_INLINE void __nrfy_internal_rramc_config_set(NRF_RRAMC_Type *           p_reg,
59                                                          nrf_rramc_config_t const * p_config);
60 
61 NRFY_STATIC_INLINE void __nrfy_internal_rramc_byte_write(NRF_RRAMC_Type * p_reg,
62                                                          uint32_t         addr,
63                                                          uint8_t          value);
64 
65 NRFY_STATIC_INLINE void __nrfy_internal_rramc_word_write(NRF_RRAMC_Type * p_reg,
66                                                          uint32_t         addr,
67                                                          uint32_t         value);
68 
69 NRFY_STATIC_INLINE bool __nrfy_internal_rramc_is_otp_word_writable(uint32_t index);
70 
71 /**
72  * @defgroup nrfy_rramc RRAMC HALY
73  * @{
74  * @ingroup nrf_rramc
75  * @brief   Hardware access layer with cache and barrier support for managing the RRAMC peripheral.
76  */
77 
78 /**
79  * @brief Value representing the number of bytes in a word.
80  *
81  * It is used in loops iterating over bytes contained in a word or in word-alignment checks.
82  */
83 #define NRFY_RRAMC_BYTES_IN_WORD 4
84 
85 /**
86  * @brief Value representing the number of words in a buffer line.
87  *
88  * It is used in loops iterating over words contained in buffer lines.
89  */
90 #define NRFY_RRAMC_WORDS_IN_BUFER_LINE 4
91 
92 /** @brief Value representing resistive random access memory (RRAM) base address. */
93 #define NRFY_RRAMC_RRAM_BASE_ADDRESS NRF_MEMORY_FLASH_BASE
94 
95 /** @brief Default value for waiting for a next write. */
96 #define NRFY_RRAMC_READY_NEXT_TIMEOUT_DEFAULT RRAMC_READYNEXTTIMEOUT_ResetValue
97 
98 /** @brief RRAMC configuration structure. */
99 typedef struct
100 {
101     nrf_rramc_config_t             config;          ///< Mode and buffer size configuration.
102     nrf_rramc_ready_next_timeout_t preload_timeout; ///< Preload timeout value for waiting for a next write.
103     nrf_rramc_power_t              power;           ///< RRAMC power configuration.
104 } nrfy_rramc_config_t;
105 
106 /**
107  * @brief Function for configuring the RRAMC.
108  *
109  * @param[in] p_reg    Pointer to the structure of registers of the peripheral.
110  * @param[in] p_config Pointer to the structure of configuration of the peripheral.
111  */
nrfy_rramc_configure(NRF_RRAMC_Type * p_reg,nrfy_rramc_config_t const * p_config)112 NRFY_STATIC_INLINE void nrfy_rramc_configure(NRF_RRAMC_Type *            p_reg,
113                                              nrfy_rramc_config_t const * p_config)
114 {
115     nrf_rramc_config_set(p_reg, &p_config->config);
116     nrf_rramc_ready_next_timeout_set(p_reg, &p_config->preload_timeout);
117     nrf_rramc_power_config_set(p_reg, &p_config->power);
118     nrf_barrier_w();
119     nrf_barrier_r();
120     while (!nrf_rramc_write_ready_check(p_reg))
121     {}
122     nrf_barrier_r();
123 }
124 
125 /**
126  * @brief Function for initializing the specified RRAMC interrupts.
127  *
128  * @param[in] p_reg        Pointer to the structure of registers of the peripheral.
129  * @param[in] mask         Mask of interrupts to be initialized.
130  * @param[in] irq_priority Interrupt priority.
131  * @param[in] enable       True if interrupts associated with the event mask are to be enabled, false otherwise.
132  */
nrfy_rramc_int_init(NRF_RRAMC_Type * p_reg,uint32_t mask,uint8_t irq_priority,bool enable)133 NRFY_STATIC_INLINE void nrfy_rramc_int_init(NRF_RRAMC_Type * p_reg,
134                                             uint32_t         mask,
135                                             uint8_t          irq_priority,
136                                             bool             enable)
137 {
138     __nrfy_internal_rramc_event_enabled_clear(p_reg, mask, NRF_RRAMC_EVENT_ERROR_ACCESS);
139     __nrfy_internal_rramc_event_enabled_clear(p_reg, mask, NRF_RRAMC_EVENT_READY);
140     __nrfy_internal_rramc_event_enabled_clear(p_reg, mask, NRF_RRAMC_EVENT_READY_NEXT);
141     __nrfy_internal_rramc_event_enabled_clear(p_reg, mask, NRF_RRAMC_EVENT_WOKENUP);
142 
143     nrf_barrier_w();
144     NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_reg), irq_priority);
145     NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_reg));
146     if (enable)
147     {
148         nrf_rramc_int_enable(p_reg, mask);
149     }
150     nrf_barrier_w();
151 }
152 
153 /**
154  * @brief Function for uninitializing the RRAMC interrupts.
155  *
156  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
157  */
nrfy_rramc_int_uninit(NRF_RRAMC_Type * p_reg)158 NRFY_STATIC_INLINE void nrfy_rramc_int_uninit(NRF_RRAMC_Type * p_reg)
159 {
160     NRFX_IRQ_DISABLE(nrfx_get_irq_number(p_reg));
161     nrf_barrier_w();
162 }
163 
164 /**
165  * @brief Function for processing the specified RRAMC events.
166  *
167  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
168  * @param[in] mask  Mask of events to be processed, created by @ref NRFY_EVENT_TO_INT_BITMASK().
169  *
170  * @return Mask of events that were generated and processed.
171  *         To be checked against the result of @ref NRFY_EVENT_TO_INT_BITMASK().
172  */
nrfy_rramc_events_process(NRF_RRAMC_Type * p_reg,uint32_t mask)173 NRFY_STATIC_INLINE uint32_t nrfy_rramc_events_process(NRF_RRAMC_Type * p_reg, uint32_t mask)
174 {
175     uint32_t evt_mask = __nrfy_internal_rramc_events_process(p_reg, mask);
176 
177     nrf_barrier_w();
178     return evt_mask;
179 }
180 
181 /**
182  * @brief Function for writing a single byte to RRAM.
183  *
184  * @note Depending on the source of the code being executed,
185  *       the CPU may be halted during the operation.
186  *       Refer to the Product Specification for more information.
187  *
188  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
189  * @param[in] address Address to where data is to be written.
190  * @param[in] value   Value to be written.
191  */
nrfy_rramc_byte_write(NRF_RRAMC_Type * p_reg,uint32_t address,uint8_t value)192 NRFY_STATIC_INLINE void nrfy_rramc_byte_write(NRF_RRAMC_Type * p_reg,
193                                               uint32_t         address,
194                                               uint8_t          value)
195 {
196     nrf_rramc_config_t rramc_config;
197     nrf_rramc_config_t prev_rramc_config;
198 
199     __nrfy_internal_rramc_config_get(p_reg, &rramc_config);
200     prev_rramc_config = rramc_config;
201     rramc_config.mode_write = true;
202 
203     __nrfy_internal_rramc_config_set(p_reg, &rramc_config);
204     __nrfy_internal_rramc_byte_write(p_reg, address, value);
205     __nrfy_internal_rramc_config_set(p_reg, &prev_rramc_config);
206 }
207 
208 /**
209  * @brief Function for writing consecutive bytes to RRAM.
210  *
211  * @note Depending on the source of the code being executed,
212  *       the CPU may be halted during the operation.
213  *       Refer to the Product Specification for more information.
214  *
215  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
216  * @param[in] address   Address to where data is to be written.
217  * @param[in] src       Pointer to data to be copied.
218  * @param[in] num_bytes Number of bytes to be written.
219  */
nrfy_rramc_bytes_write(NRF_RRAMC_Type * p_reg,uint32_t address,void const * src,uint32_t num_bytes)220 NRFY_STATIC_INLINE void nrfy_rramc_bytes_write(NRF_RRAMC_Type * p_reg,
221                                                uint32_t         address,
222                                                void const *     src,
223                                                uint32_t         num_bytes)
224 {
225     nrf_rramc_config_t rramc_config;
226     nrf_rramc_config_t prev_rramc_config;
227 
228     __nrfy_internal_rramc_config_get(p_reg, &rramc_config);
229     prev_rramc_config = rramc_config;
230     rramc_config.mode_write = true;
231 
232     __nrfy_internal_rramc_config_set(p_reg, &rramc_config);
233     for (uint32_t i = 0; i < num_bytes; i++)
234     {
235         __nrfy_internal_rramc_byte_write(p_reg, address + i, ((uint8_t const *)src)[i]);
236     }
237     __nrfy_internal_rramc_config_set(p_reg, &prev_rramc_config);
238 }
239 
240 /**
241  * @brief Function for reading a byte from the RRAM.
242  *
243  * @param[in] address Address of the byte to be read.
244  *
245  * @return Value read from RRAM.
246  */
nrfy_rramc_byte_read(uint32_t address)247 NRFY_STATIC_INLINE uint8_t nrfy_rramc_byte_read(uint32_t address)
248 {
249     nrf_barrier_r();
250     uint8_t byte = nrf_rramc_byte_read(address);
251     nrf_barrier_r();
252     return byte;
253 }
254 
255 /**
256  * @brief Function for writing a 32-bit word to RRAM.
257  *
258  * @note Depending on the source of the code being executed,
259  *       the CPU may be halted during the operation.
260  *       Refer to the Product Specification for more information.
261  *
262  * @param[in] p_reg   Pointer to the structure of registers of the peripheral.
263  * @param[in] address Address to where data is to be written. Must be word-aligned.
264  * @param[in] value   Value to be written.
265  */
nrfy_rramc_word_write(NRF_RRAMC_Type * p_reg,uint32_t address,uint32_t value)266 NRFY_STATIC_INLINE void nrfy_rramc_word_write(NRF_RRAMC_Type * p_reg,
267                                               uint32_t         address,
268                                               uint32_t         value)
269 {
270     nrf_rramc_config_t rramc_config;
271     nrf_rramc_config_t prev_rramc_config;
272 
273     __nrfy_internal_rramc_config_get(p_reg, &rramc_config);
274     prev_rramc_config = rramc_config;
275     rramc_config.mode_write = true;
276 
277     __nrfy_internal_rramc_config_set(p_reg, &rramc_config);
278     __nrfy_internal_rramc_word_write(p_reg, address, value);
279     __nrfy_internal_rramc_config_set(p_reg, &prev_rramc_config);
280 }
281 
282 /**
283  * @brief Function for writing consecutive 32-bit words to RRAM.
284  *
285  * @note Depending on the source of the code being executed,
286  *       the CPU may be halted during the operation.
287  *       Refer to the Product Specification for more information.
288  *
289  * @param[in] p_reg     Pointer to the structure of registers of the peripheral.
290  * @param[in] address   Address to where data is to be written. Must be word-aligned.
291  * @param[in] src       Pointer to data to be copied. Must be word-aligned.
292  * @param[in] num_words Number of words to be written.
293  */
nrfy_rramc_words_write(NRF_RRAMC_Type * p_reg,uint32_t address,void const * src,uint32_t num_words)294 NRFY_STATIC_INLINE void nrfy_rramc_words_write(NRF_RRAMC_Type * p_reg,
295                                                uint32_t         address,
296                                                void const *     src,
297                                                uint32_t         num_words)
298 {
299     nrf_rramc_config_t rramc_config;
300     nrf_rramc_config_t prev_rramc_config;
301 
302     __nrfy_internal_rramc_config_get(p_reg, &rramc_config);
303     prev_rramc_config = rramc_config;
304     rramc_config.mode_write = true;
305 
306     __nrfy_internal_rramc_config_set(p_reg, &rramc_config);
307     for (uint32_t i = 0; i < num_words; i++)
308     {
309         __nrfy_internal_rramc_word_write(p_reg,
310                                          address + (NRFY_RRAMC_BYTES_IN_WORD * i),
311                                          ((uint32_t const *)src)[i]);
312     }
313     __nrfy_internal_rramc_config_set(p_reg, &prev_rramc_config);
314 }
315 
316 /**
317  * @brief Function for reading a 32-bit word from the RRAM.
318  *
319  * @param[in] address Address of the word to be read.
320  *
321  * @return Value read from RRAM.
322  */
nrfy_rramc_word_read(uint32_t address)323 NRFY_STATIC_INLINE uint32_t nrfy_rramc_word_read(uint32_t address)
324 {
325     nrf_barrier_r();
326     uint32_t word = nrf_rramc_word_read(address);
327     nrf_barrier_r();
328     return word;
329 }
330 
331 /**
332  * @brief Function for reading a given number of bytes from the RRAM into the specified buffer.
333  *
334  * @param[out] dst       Pointer to the buffer to store the data.
335  * @param[in]  address   Address of the first byte to be read.
336  * @param[in]  num_bytes Number of bytes to be read.
337  */
nrfy_rramc_buffer_read(void * dst,uint32_t address,uint32_t num_bytes)338 NRFY_STATIC_INLINE void nrfy_rramc_buffer_read(void *   dst,
339                                                uint32_t address,
340                                                uint32_t num_bytes)
341 {
342     nrf_barrier_r();
343     nrf_rramc_buffer_read(dst, address, num_bytes);
344     nrf_barrier_r();
345 }
346 
347 /**
348  * @brief Function for reading a word from the OTP in UICR.
349  *
350  * OTP is a region of the UICR present in some chips. This function must be used
351  * to read word data from this region since unaligned accesses are not
352  * available on the OTP RRAM area.
353  *
354  * @param[in] index Address (index) in OTP table from which a word is to be read.
355  *
356  * @retval The contents at @p index.
357  */
nrfy_rramc_otp_word_read(uint32_t index)358 NRFY_STATIC_INLINE uint32_t nrfy_rramc_otp_word_read(uint32_t index)
359 {
360     NRFX_ASSERT(index < UICR_OTP_MaxCount);
361 #if !defined(NRF_TRUSTZONE_NONSECURE)
362     nrf_barrier_r();
363     uint32_t val32 = NRF_UICR->OTP[index];
364     nrf_barrier_r();
365     return val32;
366 #else
367     return 0xFFFFFFFF;
368 #endif
369 }
370 
371 /**
372  * @brief Function for writing a 32-bit word at index position to OTP region in UICR.
373  *
374  * The OTP is only able to write '0' to bits in the UICR that are erased (set to '1').
375  * It cannot rewrite a bit back to '1'. This function checks if the value currently
376  * residing at the specified index can be transformed to the desired value
377  * without any '0' to '1' transitions. If yes, then perform the write operation.
378  *
379  * @param[in] p_reg Pointer to the structure of registers of the peripheral.
380  * @param[in] index Address (index) in OTP table to which a word it to be written.
381  * @param[in] value Value to be written.
382  *
383  * @retval true  Word can be written into the specified OTP index address.
384  * @retval false Word cannot be written into the specified OTP index address.
385  *               Erase UICR or change index address.
386  */
nrfy_rramc_otp_word_write(NRF_RRAMC_Type * p_reg,uint32_t index,uint32_t value)387 NRFY_STATIC_INLINE bool nrfy_rramc_otp_word_write(NRF_RRAMC_Type * p_reg,
388                                                   uint32_t         index,
389                                                   uint32_t         value)
390 {
391     NRFX_ASSERT(index < UICR_OTP_MaxCount);
392 
393 #if !defined(NRF_TRUSTZONE_NONSECURE)
394     if (!__nrfy_internal_rramc_is_otp_word_writable(index))
395     {
396         return false;
397     }
398 
399     nrf_rramc_config_t rramc_config;
400     nrf_rramc_config_t prev_rramc_config;
401 
402     __nrfy_internal_rramc_config_get(p_reg, &rramc_config);
403     prev_rramc_config = rramc_config;
404     rramc_config.mode_write = true;
405 
406     __nrfy_internal_rramc_config_set(p_reg, &rramc_config);
407     NRF_UICR->OTP[index] = value;
408     __nrfy_internal_rramc_config_set(p_reg, &prev_rramc_config);
409 
410     return true;
411 #else
412     (void)index;
413     (void)value;
414 
415     return false;
416 #endif
417 }
418 
419 /** @refhal{nrf_rramc_task_trigger} */
nrfy_rramc_task_trigger(NRF_RRAMC_Type * p_reg,nrf_rramc_task_t task)420 NRFY_STATIC_INLINE void nrfy_rramc_task_trigger(NRF_RRAMC_Type * p_reg, nrf_rramc_task_t task)
421 {
422     nrf_rramc_task_trigger(p_reg, task);
423     nrf_barrier_w();
424 }
425 
426 /** @refhal{nrf_rramc_task_address_get} */
nrfy_rramc_task_address_get(NRF_RRAMC_Type const * p_reg,nrf_rramc_task_t task)427 NRFY_STATIC_INLINE uint32_t nrfy_rramc_task_address_get(NRF_RRAMC_Type const * p_reg,
428                                                         nrf_rramc_task_t       task)
429 {
430     return nrf_rramc_task_address_get(p_reg, task);
431 }
432 
433 /** @refhal{nrf_rramc_event_clear} */
nrfy_rramc_event_clear(NRF_RRAMC_Type * p_reg,nrf_rramc_event_t event)434 NRFY_STATIC_INLINE void nrfy_rramc_event_clear(NRF_RRAMC_Type * p_reg, nrf_rramc_event_t event)
435 {
436     nrf_rramc_event_clear(p_reg, event);
437     nrf_barrier_w();
438 }
439 
440 /** @refhal{nrf_rramc_event_check} */
nrfy_rramc_event_check(NRF_RRAMC_Type const * p_reg,nrf_rramc_event_t event)441 NRFY_STATIC_INLINE bool nrfy_rramc_event_check(NRF_RRAMC_Type const * p_reg,
442                                                nrf_rramc_event_t      event)
443 {
444     nrf_barrier_r();
445     bool check = nrf_rramc_event_check(p_reg, event);
446     nrf_barrier_r();
447     return check;
448 }
449 
450 /** @refhal{nrf_rramc_event_address_get} */
nrfy_rramc_event_address_get(NRF_RRAMC_Type const * p_reg,nrf_rramc_event_t event)451 NRFY_STATIC_INLINE uint32_t nrfy_rramc_event_address_get(NRF_RRAMC_Type const * p_reg,
452                                                          nrf_rramc_event_t      event)
453 {
454     return nrf_rramc_event_address_get(p_reg, event);
455 }
456 
457 /** @refhal{nrf_rramc_int_enable} */
nrfy_rramc_int_enable(NRF_RRAMC_Type * p_reg,uint32_t mask)458 NRFY_STATIC_INLINE void nrfy_rramc_int_enable(NRF_RRAMC_Type * p_reg, uint32_t mask)
459 {
460     nrf_rramc_int_enable(p_reg, mask);
461     nrf_barrier_w();
462 }
463 
464 /** @refhal{nrf_rramc_int_disable} */
nrfy_rramc_int_disable(NRF_RRAMC_Type * p_reg,uint32_t mask)465 NRFY_STATIC_INLINE void nrfy_rramc_int_disable(NRF_RRAMC_Type * p_reg, uint32_t mask)
466 {
467     nrf_rramc_int_disable(p_reg, mask);
468     nrf_barrier_w();
469 }
470 
471 /** @refhal{nrf_rramc_int_enable_check} */
nrfy_rramc_int_enable_check(NRF_RRAMC_Type const * p_reg,uint32_t mask)472 NRFY_STATIC_INLINE uint32_t nrfy_rramc_int_enable_check(NRF_RRAMC_Type const * p_reg, uint32_t mask)
473 {
474     nrf_barrier_rw();
475     uint32_t check = nrf_rramc_int_enable_check(p_reg, mask);
476     nrf_barrier_r();
477     return check;
478 }
479 
480 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
481 /** @refhal{nrf_rramc_subscribe_set} */
nrfy_rramc_subscribe_set(NRF_RRAMC_Type * p_reg,nrf_rramc_task_t task,uint8_t channel)482 NRFY_STATIC_INLINE void nrfy_rramc_subscribe_set(NRF_RRAMC_Type * p_reg,
483                                                  nrf_rramc_task_t task,
484                                                  uint8_t          channel)
485 {
486     nrf_rramc_subscribe_set(p_reg, task, channel);
487     nrf_barrier_w();
488 }
489 
490 /** @refhal{nrf_rramc_subscribe_clear} */
nrfy_rramc_subscribe_clear(NRF_RRAMC_Type * p_reg,nrf_rramc_task_t task)491 NRFY_STATIC_INLINE void nrfy_rramc_subscribe_clear(NRF_RRAMC_Type * p_reg, nrf_rramc_task_t task)
492 {
493     nrf_rramc_subscribe_clear(p_reg, task);
494     nrf_barrier_w();
495 }
496 
497 /** @refhal{nrf_rramc_publish_set} */
nrfy_rramc_publish_set(NRF_RRAMC_Type * p_reg,nrf_rramc_event_t event,uint8_t channel)498 NRFY_STATIC_INLINE void nrfy_rramc_publish_set(NRF_RRAMC_Type *  p_reg,
499                                                nrf_rramc_event_t event,
500                                                uint8_t           channel)
501 {
502     nrf_rramc_publish_set(p_reg, event, channel);
503     nrf_barrier_w();
504 }
505 
506 /** @refhal{nrf_rramc_publish_clear} */
nrfy_rramc_publish_clear(NRF_RRAMC_Type * p_reg,nrf_rramc_event_t event)507 NRFY_STATIC_INLINE void nrfy_rramc_publish_clear(NRF_RRAMC_Type *  p_reg, nrf_rramc_event_t event)
508 {
509     nrf_rramc_publish_clear(p_reg, event);
510     nrf_barrier_w();
511 }
512 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__)
513 
514 /** @refhal{nrf_rramc_ready_check} */
nrfy_rramc_ready_check(NRF_RRAMC_Type * p_reg)515 NRFY_STATIC_INLINE bool nrfy_rramc_ready_check(NRF_RRAMC_Type * p_reg)
516 {
517     nrf_barrier_r();
518     bool check = nrf_rramc_ready_check(p_reg);
519     nrf_barrier_r();
520     return check;
521 }
522 
523 /** @refhal{nrf_rramc_write_ready_check} */
nrfy_rramc_write_ready_check(NRF_RRAMC_Type * p_reg)524 NRFY_STATIC_INLINE bool nrfy_rramc_write_ready_check(NRF_RRAMC_Type * p_reg)
525 {
526     nrf_barrier_r();
527     bool check = nrf_rramc_write_ready_check(p_reg);
528     nrf_barrier_r();
529     return check;
530 }
531 
532 /** @refhal{nrf_rramc_error_access_addr_get} */
nrfy_rramc_error_access_addr_get(NRF_RRAMC_Type const * p_reg)533 NRFY_STATIC_INLINE uint32_t nrfy_rramc_error_access_addr_get(NRF_RRAMC_Type const * p_reg)
534 {
535     nrf_barrier_r();
536     uint32_t error_addr = nrf_rramc_error_access_addr_get(p_reg);
537     nrf_barrier_r();
538     return error_addr;
539 }
540 
541 /** @refhal{nrf_rramc_empty_buffer_check} */
nrfy_rramc_empty_buffer_check(NRF_RRAMC_Type const * p_reg)542 NRFY_STATIC_INLINE bool nrfy_rramc_empty_buffer_check(NRF_RRAMC_Type const * p_reg)
543 {
544     nrf_barrier_r();
545     bool check = nrf_rramc_empty_buffer_check(p_reg);
546     nrf_barrier_r();
547     return check;
548 }
549 
550 /** @refhal{nrf_rramc_config_get} */
nrfy_rramc_config_get(NRF_RRAMC_Type const * p_reg,nrf_rramc_config_t * p_config)551 NRFY_STATIC_INLINE void nrfy_rramc_config_get(NRF_RRAMC_Type const * p_reg,
552                                               nrf_rramc_config_t *   p_config)
553 {
554     __nrfy_internal_rramc_config_get(p_reg, p_config);
555 }
556 
557 /** @refhal{nrf_rramc_config_set} */
nrfy_rramc_config_set(NRF_RRAMC_Type * p_reg,nrf_rramc_config_t const * p_config)558 NRFY_STATIC_INLINE void nrfy_rramc_config_set(NRF_RRAMC_Type *           p_reg,
559                                               nrf_rramc_config_t const * p_config)
560 {
561     __nrfy_internal_rramc_config_set(p_reg, p_config);
562 }
563 
564 /** @refhal{nrf_rramc_ready_next_timeout_get} */
nrfy_rramc_ready_next_timeout_get(NRF_RRAMC_Type const * p_reg,nrf_rramc_ready_next_timeout_t * p_config)565 NRFY_STATIC_INLINE void nrfy_rramc_ready_next_timeout_get(NRF_RRAMC_Type const *           p_reg,
566                                                           nrf_rramc_ready_next_timeout_t * p_config)
567 {
568     nrf_barrier_r();
569     nrf_rramc_ready_next_timeout_get(p_reg, p_config);
570     nrf_barrier_r();
571 }
572 
573 /** @refhal{nrf_rramc_ready_next_timeout_set} */
574 NRFY_STATIC_INLINE void
nrfy_rramc_ready_next_timeout_set(NRF_RRAMC_Type * p_reg,nrf_rramc_ready_next_timeout_t const * p_config)575 nrfy_rramc_ready_next_timeout_set(NRF_RRAMC_Type *                       p_reg,
576                                   nrf_rramc_ready_next_timeout_t const * p_config)
577 {
578     nrf_rramc_ready_next_timeout_set(p_reg, p_config);
579     nrf_barrier_w();
580 }
581 
582 /** @refhal{nrf_rramc_power_config_get} */
nrfy_rramc_power_config_get(NRF_RRAMC_Type const * p_reg,nrf_rramc_power_t * p_config)583 NRFY_STATIC_INLINE void nrfy_rramc_power_config_get(NRF_RRAMC_Type const * p_reg,
584                                                     nrf_rramc_power_t *    p_config)
585 {
586     nrf_barrier_r();
587     nrf_rramc_power_config_get(p_reg, p_config);
588     nrf_barrier_r();
589 }
590 
591 /** @refhal{nrf_rramc_power_config_set} */
nrfy_rramc_power_config_set(NRF_RRAMC_Type * p_reg,nrf_rramc_power_t const * p_config)592 NRFY_STATIC_INLINE void nrfy_rramc_power_config_set(NRF_RRAMC_Type *          p_reg,
593                                                     nrf_rramc_power_t const * p_config)
594 {
595     nrf_rramc_power_config_set(p_reg, p_config);
596     nrf_barrier_w();
597 }
598 
599 /** @refhal{nrf_rramc_erase_all_check} */
nrfy_rramc_erase_all_check(NRF_RRAMC_Type const * p_reg)600 NRFY_STATIC_INLINE bool nrfy_rramc_erase_all_check(NRF_RRAMC_Type const * p_reg)
601 {
602     nrf_barrier_r();
603     bool check = nrf_rramc_erase_all_check(p_reg);
604     nrf_barrier_r();
605     return check;
606 }
607 
608 /** @refhal{nrf_rramc_erase_all_set} */
nrfy_rramc_erase_all_set(NRF_RRAMC_Type * p_reg)609 NRFY_STATIC_INLINE void nrfy_rramc_erase_all_set(NRF_RRAMC_Type * p_reg)
610 {
611     nrf_rramc_config_t rramc_config;
612     nrf_rramc_config_t prev_rramc_config;
613 
614     __nrfy_internal_rramc_config_get(p_reg, &rramc_config);
615     prev_rramc_config = rramc_config;
616     rramc_config.mode_write = true;
617 
618     __nrfy_internal_rramc_config_set(p_reg, &rramc_config);
619     nrf_rramc_erase_all_set(p_reg);
620     __nrfy_internal_rramc_config_set(p_reg, &prev_rramc_config);
621 }
622 
623 /** @} */
624 
__nrfy_internal_rramc_event_enabled_clear(NRF_RRAMC_Type * p_reg,uint32_t mask,nrf_rramc_event_t event)625 NRFY_STATIC_INLINE void __nrfy_internal_rramc_event_enabled_clear(NRF_RRAMC_Type *  p_reg,
626                                                                   uint32_t          mask,
627                                                                   nrf_rramc_event_t event)
628 {
629     if (mask & NRFY_EVENT_TO_INT_BITMASK(event))
630     {
631         nrf_rramc_event_clear(p_reg, event);
632     }
633 }
634 
__nrfy_internal_rramc_event_handle(NRF_RRAMC_Type * p_reg,uint32_t mask,nrf_rramc_event_t event)635 NRFY_STATIC_INLINE uint32_t __nrfy_internal_rramc_event_handle(NRF_RRAMC_Type *  p_reg,
636                                                                uint32_t          mask,
637                                                                nrf_rramc_event_t event)
638 {
639     if ((mask & NRFY_EVENT_TO_INT_BITMASK(event)) && nrf_rramc_event_check(p_reg, event))
640     {
641         nrf_rramc_event_clear(p_reg, event);
642         return NRFY_EVENT_TO_INT_BITMASK(event);
643     }
644     return 0;
645 }
646 
__nrfy_internal_rramc_events_process(NRF_RRAMC_Type * p_reg,uint32_t mask)647 NRFY_STATIC_INLINE uint32_t __nrfy_internal_rramc_events_process(NRF_RRAMC_Type * p_reg,
648                                                                  uint32_t         mask)
649 {
650     uint32_t evt_mask = 0;
651 
652     nrf_barrier_r();
653     evt_mask =  __nrfy_internal_rramc_event_handle(p_reg, mask, NRF_RRAMC_EVENT_ERROR_ACCESS);
654     evt_mask |= __nrfy_internal_rramc_event_handle(p_reg, mask, NRF_RRAMC_EVENT_READY);
655     evt_mask |= __nrfy_internal_rramc_event_handle(p_reg, mask, NRF_RRAMC_EVENT_READY_NEXT);
656     evt_mask |= __nrfy_internal_rramc_event_handle(p_reg, mask, NRF_RRAMC_EVENT_WOKENUP);
657     nrf_barrier_w();
658 
659     return evt_mask;
660 }
661 
__nrfy_internal_rramc_config_get(NRF_RRAMC_Type const * p_reg,nrf_rramc_config_t * p_config)662 NRFY_STATIC_INLINE void __nrfy_internal_rramc_config_get(NRF_RRAMC_Type const * p_reg,
663                                                          nrf_rramc_config_t *   p_config)
664 {
665     nrf_barrier_r();
666     nrf_rramc_config_get(p_reg, p_config);
667     nrf_barrier_r();
668 }
669 
__nrfy_internal_rramc_config_set(NRF_RRAMC_Type * p_reg,nrf_rramc_config_t const * p_config)670 NRFY_STATIC_INLINE void __nrfy_internal_rramc_config_set(NRF_RRAMC_Type *           p_reg,
671                                                          nrf_rramc_config_t const * p_config)
672 {
673     nrf_rramc_config_set(p_reg, p_config);
674     nrf_barrier_w();
675     nrf_barrier_r();
676     while (!nrf_rramc_ready_check(p_reg))
677     {}
678     nrf_barrier_r();
679 }
680 
__nrfy_internal_rramc_byte_write(NRF_RRAMC_Type * p_reg,uint32_t addr,uint8_t value)681 NRFY_STATIC_INLINE void __nrfy_internal_rramc_byte_write(NRF_RRAMC_Type * p_reg,
682                                                          uint32_t         addr,
683                                                          uint8_t          value)
684 {
685     nrf_barrier_r();
686     while (!nrf_rramc_write_ready_check(p_reg))
687     {}
688     nrf_barrier_r();
689 
690     nrf_rramc_byte_write(addr, value);
691     nrf_barrier_w();
692 }
693 
__nrfy_internal_rramc_word_write(NRF_RRAMC_Type * p_reg,uint32_t addr,uint32_t value)694 NRFY_STATIC_INLINE void __nrfy_internal_rramc_word_write(NRF_RRAMC_Type * p_reg,
695                                                          uint32_t         addr,
696                                                          uint32_t         value)
697 {
698     nrf_barrier_r();
699     while (!nrf_rramc_write_ready_check(p_reg))
700     {}
701     nrf_barrier_r();
702 
703     nrf_rramc_word_write(addr, value);
704     nrf_barrier_w();
705 }
706 
__nrfy_internal_rramc_is_otp_word_writable(uint32_t index)707 NRFY_STATIC_INLINE bool __nrfy_internal_rramc_is_otp_word_writable(uint32_t index)
708 {
709 #if !defined(NRF_TRUSTZONE_NONSECURE)
710     nrf_barrier_r();
711     uint32_t val_on_addr = NRF_UICR->OTP[index];
712     nrf_barrier_r();
713     return (val_on_addr == 0xFFFFFFFF);
714 #else
715     return false;
716 #endif
717 }
718 
719 #ifdef __cplusplus
720 }
721 #endif
722 
723 #endif // NRFY_RRAMC_H__
724