1 /*
2  * Copyright (c) 2019 - 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 NRFX_NVMC_H__
35 #define NRFX_NVMC_H__
36 
37 #include <nrfx.h>
38 #include <hal/nrf_nvmc.h>
39 #include <hal/nrf_ficr.h>
40 #include <nrf_erratas.h>
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /**
47  * @defgroup nrfx_nvmc NVMC driver
48  * @{
49  * @ingroup nrf_nvmc
50  * @brief   Non-Volatile Memory Controller (NVMC) peripheral driver.
51  */
52 
53 /**
54  * @brief Function for erasing a page in flash.
55  *
56  * This function blocks until the erase operation finishes.
57  *
58  * @note Depending on the source of the code being executed,
59  *       the CPU may be halted during the operation.
60  *       Refer to the Product Specification for more information.
61  *
62  * @param address Address of the first word in the page to erase.
63  *
64  * @retval NRFX_SUCCESS            Page erase complete.
65  * @retval NRFX_ERROR_INVALID_ADDR Address is not aligned to the size of the page.
66  */
67 nrfx_err_t nrfx_nvmc_page_erase(uint32_t address);
68 
69 /**
70  * @brief Function for erasing the user information configuration register (UICR).
71  *
72  * @note Depending on the source of the code being executed,
73  *       the CPU may be halted during the operation.
74  *       Refer to the Product Specification for more information.
75  *
76  * @retval NRFX_SUCCESS             UICR has been successfully erased.
77  * @retval NRFX_ERROR_NOT_SUPPORTED UICR erase is not supported.
78  */
79 nrfx_err_t nrfx_nvmc_uicr_erase(void);
80 
81 /**
82  * @brief Function for erasing the whole flash memory.
83  *
84  * @note All user code and UICR will be erased.
85  */
86 void nrfx_nvmc_all_erase(void);
87 
88 #if NRF_NVMC_HAS_PARTIAL_ERASE || defined(__NRFX_DOXYGEN__)
89 /**
90  * @brief Function for initiating a complete page erase split into parts (also known as partial erase).
91  *
92  * This function initiates a partial erase with the specified duration.
93  * To execute each part of the partial erase, use @ref nrfx_nvmc_page_partial_erase_continue.
94  *
95  * @param address     Address of the first word in the page to erase.
96  * @param duration_ms Time in milliseconds that each partial erase will take.
97  *
98  * @retval NRFX_SUCCESS            Partial erase started.
99  * @retval NRFX_ERROR_INVALID_ADDR Address is not aligned to the size of the page.
100  *
101  * @sa nrfx_nvmc_page_partial_erase_continue()
102  */
103 nrfx_err_t nrfx_nvmc_page_partial_erase_init(uint32_t address, uint32_t duration_ms);
104 
105 /**
106  * @brief Function for performing a part of the complete page erase (also known as partial erase).
107  *
108  * This function must be called several times to erase the whole page, once for each erase part.
109  *
110  * @note The actual time needed to perform each part of the page erase is longer than the partial
111  *       erase duration specified in the call to @ref nrfx_nvmc_page_partial_erase_init,
112  *       since the NVMC peripheral needs certain additional amount of time to handle the process.
113  *       For details regarding this additional time, see the "Electrical specification" section
114  *       for the NVMC peripheral in the Product Specification.
115  *
116  * @note Using a page that was not completely erased leads to undefined behavior.
117  *       Depending on the source of the code being executed,
118  *       the CPU may be halted during the operation.
119  *       Refer to the Product Specification for more information.
120  *
121  * @retval true  Partial erase finished.
122  * @retval false Partial erase not finished.
123  *               Call the function again to process the next part.
124  */
125 bool nrfx_nvmc_page_partial_erase_continue(void);
126 
127 #endif // NRF_NVMC_HAS_PARTIAL_ERASE || defined(__NRFX_DOXYGEN__)
128 
129 /**
130  * @brief Function for checking whether a byte is writable at the specified address.
131  *
132  * The NVMC is only able to write '0' to bits in the flash that are erased (set to '1').
133  * It cannot rewrite a bit back to '1'. This function checks if the value currently
134  * residing at the specified address can be transformed to the desired value
135  * without any '0' to '1' transitions.
136  *
137  * @param address Address to be checked.
138  * @param value   Value to be checked.
139  *
140  * @retval true  Byte can be written at the specified address.
141  * @retval false Byte cannot be written at the specified address.
142  *               Erase the page or change the address.
143  */
144 bool nrfx_nvmc_byte_writable_check(uint32_t address, uint8_t value);
145 
146 /**
147  * @brief Function for writing a single byte to flash.
148  *
149  * To determine if the flash write has been completed, use @ref nrfx_nvmc_write_done_check().
150  *
151  * @note Depending on the source of the code being executed,
152  *       the CPU may be halted during the operation.
153  *       Refer to the Product Specification for more information.
154  *
155  * @param address Address to write to.
156  * @param value   Value to write.
157  */
158 void nrfx_nvmc_byte_write(uint32_t address, uint8_t value);
159 
160 /**
161  * @brief Function for checking whether a halfword is writable at the specified address.
162  *
163  * The NVMC is only able to write '0' to bits in the Flash that are erased (set to '1').
164  * It cannot rewrite a bit back to '1'. This function checks if the value currently
165  * residing at the specified address can be transformed to the desired value
166  * without any '0' to '1' transitions.
167  *
168  * @param address Address to be checked. Must be halfword-aligned.
169  * @param value   Value to be checked.
170  *
171  * @retval true  Halfword can be written at the specified address.
172  * @retval false Halfword cannot be written at the specified address.
173  *               Erase page or change address.
174  */
175 bool nrfx_nvmc_halfword_writable_check(uint32_t address, uint16_t value);
176 
177 /**
178  * @brief Function for writing a 16-bit halfword to flash.
179  *
180  * To determine if the flash write has been completed, use @ref nrfx_nvmc_write_done_check().
181  *
182  * @note Depending on the source of the code being executed,
183  *       the CPU may be halted during the operation.
184  *       Refer to the Product Specification for more information.
185  *
186  * @param address Address to write to. Must be halfword-aligned.
187  * @param value   Value to write.
188  */
189 void nrfx_nvmc_halfword_write(uint32_t address, uint16_t value);
190 
191 /**
192  * @brief Function for checking whether a word is writable at the specified address.
193  *
194  * The NVMC is only able to write '0' to bits in the Flash that are erased (set to '1').
195  * It cannot rewrite a bit back to '1'. This function checks if the value currently
196  * residing at the specified address can be transformed to the desired value
197  * without any '0' to '1' transitions.
198  *
199  * @param address Address to be checked. Must be word-aligned.
200  * @param value   Value to be checked.
201  *
202  * @retval true  Word can be written at the specified address.
203  * @retval false Word cannot be written at the specified address.
204  *               Erase page or change address.
205  */
206 bool nrfx_nvmc_word_writable_check(uint32_t address, uint32_t value);
207 
208 /**
209  * @brief Function for writing a 32-bit word to flash.
210  *
211  * To determine if the flash write has been completed, use @ref nrfx_nvmc_write_done_check().
212  *
213  * @note Depending on the source of the code being executed,
214  *       the CPU may be halted during the operation.
215  *       Refer to the Product Specification for more information.
216  *
217  * @param address Address to write to. Must be word-aligned.
218  * @param value   Value to write.
219  */
220 void nrfx_nvmc_word_write(uint32_t address, uint32_t value);
221 
222 /**
223  * @brief Function for writing consecutive bytes to flash.
224  *
225  * To determine if the last flash write has been completed, use @ref nrfx_nvmc_write_done_check().
226  *
227  * @note Depending on the source of the code being executed,
228  *       the CPU may be halted during the operation.
229  *       Refer to the Product Specification for more information.
230  *
231  * @param address   Address to write to.
232  * @param src       Pointer to the data to copy from.
233  * @param num_bytes Number of bytes to write.
234  */
235 void nrfx_nvmc_bytes_write(uint32_t address, void const * src, uint32_t num_bytes);
236 
237 /**
238  * @brief Function for writing consecutive words to flash.
239  *
240  * To determine if the last flash write has been completed, use @ref nrfx_nvmc_write_done_check().
241  *
242  * @note Depending on the source of the code being executed,
243  *       the CPU may be halted during the operation.
244  *       Refer to the Product Specification for more information.
245  *
246  * @param address   Address to write to. Must be word-aligned.
247  * @param src       Pointer to data to copy from. Must be word-aligned.
248  * @param num_words Number of words to write.
249  */
250 void nrfx_nvmc_words_write(uint32_t address, void const * src, uint32_t num_words);
251 
252 /**
253  * @brief Function for reading a 16-bit aligned halfword from the OTP (UICR)
254  *
255  * OTP is a region of the UICR present in some chips. This function must be used
256  * to read halfword data from this region since unaligned accesses are not
257  * available on the OTP flash area.
258  *
259  * @param address Address to read from. Must be halfword-aligned.
260  *
261  * @retval The contents at @p address.
262  */
263 uint16_t nrfx_nvmc_otp_halfword_read(uint32_t address);
264 
265 /**
266  * @brief Function for reading a 32-bit aligned word from the UICR
267  *
268  * This function should be used to read from the UICR since reading
269  * the flash main memory area straight after reading the UICR results
270  * in undefined behaviour for nRF9160.
271  *
272  * @note See anomaly 7 in the errata document.
273  *
274  * @param address Address to read from. Must be word-aligned.
275  *
276  * @retval The contents at @p address.
277  */
278 NRFX_STATIC_INLINE uint32_t nrfx_nvmc_uicr_word_read(uint32_t const volatile *address);
279 
280 /**
281  * @brief Function for getting the total flash size in bytes.
282  *
283  * @return Flash total size in bytes.
284  */
285 uint32_t nrfx_nvmc_flash_size_get(void);
286 
287 /**
288  * @brief Function for getting the flash page size in bytes.
289  *
290  * @return Flash page size in bytes.
291  */
292 uint32_t nrfx_nvmc_flash_page_size_get(void);
293 
294 /**
295  * @brief Function for getting the flash page count.
296  *
297  * @return Flash page count.
298  */
299 uint32_t nrfx_nvmc_flash_page_count_get(void);
300 
301 /**
302  * @brief Function for checking if the last flash write has been completed.
303  *
304  * @retval true  Last write completed successfully.
305  * @retval false Last write is still in progress.
306  */
307 NRFX_STATIC_INLINE bool nrfx_nvmc_write_done_check(void);
308 
309 #if defined(NVMC_FEATURE_CACHE_PRESENT) || defined(__NRFX_DOXYGEN__)
310 /**
311  * @brief Function for enabling the Instruction Cache (ICache).
312  *
313  * Enabling ICache reduces the amount of accesses to flash memory,
314  * which can boost performance and lower power consumption.
315  */
316 NRFX_STATIC_INLINE void nrfx_nvmc_icache_enable(void);
317 
318 /** @brief Function for disabling ICache. */
319 NRFX_STATIC_INLINE void nrfx_nvmc_icache_disable(void);
320 
321 #endif
322 
323 #ifndef NRFX_DECLARE_ONLY
nrfx_nvmc_write_done_check(void)324 NRFX_STATIC_INLINE bool nrfx_nvmc_write_done_check(void)
325 {
326     return nrf_nvmc_ready_check(NRF_NVMC);
327 }
328 
nrfx_nvmc_uicr_word_read(uint32_t const volatile * address)329 NRFX_STATIC_INLINE uint32_t nrfx_nvmc_uicr_word_read(uint32_t const volatile *address)
330 {
331 #if NRF91_ERRATA_7_ENABLE_WORKAROUND
332     bool irq_disabled = __get_PRIMASK() == 1;
333     if (!irq_disabled)
334     {
335         __disable_irq();
336     }
337 #endif
338 
339     uint32_t value = nrf_nvmc_word_read((uint32_t)address);
340 
341 #if NRF91_ERRATA_7_ENABLE_WORKAROUND
342     __DSB();
343     if (!irq_disabled)
344     {
345         __enable_irq();
346     }
347 #endif
348 
349     return value;
350 }
351 
352 #if defined(NVMC_FEATURE_CACHE_PRESENT)
nrfx_nvmc_icache_enable(void)353 NRFX_STATIC_INLINE void nrfx_nvmc_icache_enable(void)
354 {
355     nrf_nvmc_icache_config_set(NRF_NVMC, NRF_NVMC_ICACHE_ENABLE_WITH_PROFILING);
356 }
357 
nrfx_nvmc_icache_disable(void)358 NRFX_STATIC_INLINE void nrfx_nvmc_icache_disable(void)
359 {
360     nrf_nvmc_icache_config_set(NRF_NVMC, NRF_NVMC_ICACHE_DISABLE);
361 }
362 #endif // defined(NVMC_FEATURE_CACHE_PRESENT)
363 #endif // NRFX_DECLARE_ONLY
364 
365 /** @} */
366 
367 #ifdef __cplusplus
368 }
369 #endif
370 
371 #endif // NRF_NVMC_H__
372