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