1 //*****************************************************************************
2 //
3 //! @file am_hal_flash.h
4 //!
5 //! @brief Functions for Performing Flash Operations.
6 //!
7 //! @addtogroup flash3 Flash - Flash Functionality
8 //! @ingroup apollo3_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2024, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_3_2_0-dd5f40c14b of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 #ifndef AM_HAL_FLASH_H
48 #define AM_HAL_FLASH_H
49 
50 #ifdef __cplusplus
51 extern "C"
52 {
53 #endif
54 
55 #include <stdint.h>
56 #include <stdbool.h>
57 
58 //*****************************************************************************
59 //
60 //! Flash Program keys.
61 //
62 //*****************************************************************************
63 #define AM_HAL_FLASH_PROGRAM_KEY            0x12344321
64 #define AM_HAL_FLASH_INFO_KEY               0xD894E09E
65 
66 
67 
68 //*****************************************************************************
69 //
70 //! Some helpful SRAM values and macros.
71 //
72 //*****************************************************************************
73 #define AM_HAL_FLASH_SRAM_ADDR                  SRAM_BASEADDR
74 #define AM_HAL_FLASH_SRAM_SIZE                  (384 * 1024)
75 #define AM_HAL_FLASH_SRAM_LARGEST_VALID_ADDR    (AM_HAL_FLASH_SRAM_ADDR + AM_HAL_FLASH_SRAM_SIZE - 1)
76 #define AM_HAL_FLASH_DTCM_START                 AM_HAL_FLASH_SRAM_ADDR
77 #define AM_HAL_FLASH_DTCM_END                   (AM_HAL_FLASH_SRAM_ADDR + (64 * 1024) - 1)
78 
79 //*****************************************************************************
80 //
81 //! Some helpful flash values and macros.
82 //
83 //*****************************************************************************
84 #define AM_HAL_FLASH_ADDR                   0x00000000
85 #define AM_HAL_FLASH_INSTANCE_SIZE          ( 512 * 1024 )
86 #define AM_HAL_FLASH_NUM_INSTANCES          2
87 #define AM_HAL_FLASH_PAGE_SIZE              ( 8 * 1024 )
88 #define AM_HAL_FLASH_INFO_SIZE              AM_HAL_FLASH_PAGE_SIZE
89 #define AM_HAL_FLASH_INSTANCE_PAGES         ( AM_HAL_FLASH_INSTANCE_SIZE / AM_HAL_FLASH_PAGE_SIZE )
90 #define AM_HAL_FLASH_TOTAL_SIZE             ( AM_HAL_FLASH_INSTANCE_SIZE * AM_HAL_FLASH_NUM_INSTANCES )
91 #define AM_HAL_FLASH_LARGEST_VALID_ADDR     ( AM_HAL_FLASH_ADDR + AM_HAL_FLASH_TOTAL_SIZE - 1 )
92 #define AM_HAL_FLASH_APPL_ADDR              0xC000
93 
94 //
95 //! Macros to determine whether a given address is a valid internal
96 //! flash or SRAM address.
97 //
98 #define ISADDRSRAM(x)       ((x >= AM_HAL_FLASH_SRAM_ADDR)  &&      \
99                              (x <= (AM_HAL_FLASH_SRAM_LARGEST_VALID_ADDR & ~0x3)))
100 #if AM_HAL_FLASH_ADDR == 0x0
101 #define ISADDRFLASH(x)      (x <= (AM_HAL_FLASH_LARGEST_VALID_ADDR & ~0x3))
102 #else
103 #define ISADDRFLASH(x)      ((x >= AM_HAL_FLASH_ADDR)       &&      \
104                              (x <= (AM_HAL_FLASH_LARGEST_VALID_ADDR & ~0x3)))
105 #endif
106 
107 //
108 //! Macros to describe the flash ROW layout.
109 //
110 #define AM_HAL_FLASH_ROW_WIDTH_BYTES        (512)
111 
112 //
113 //! Convert an absolute flash address to an instance
114 //
115 #define AM_HAL_FLASH_ADDR2INST(addr)        ( ( addr >> 19 ) & (AM_HAL_FLASH_NUM_INSTANCES - 1) )
116 
117 //
118 //! Convert an absolute flash address to a page number relative to the instance
119 //
120 #define AM_HAL_FLASH_ADDR2PAGE(addr)        ( ( addr >> 13 ) & 0x3F )
121 
122 //
123 //! Convert an absolute flash address to an absolute page number
124 //
125 #define AM_HAL_FLASH_ADDR2ABSPAGE(addr)     ( addr >> 13 )
126 
127 //*****************************************************************************
128 //
129 //! Given an integer number of microseconds, convert to a value representing
130 //! the number of am_hal_flash_delay() cycles that will provide that amount
131 //! of delay.  This macro is designed to take into account some of the call
132 //! overhead and latencies.
133 //!
134 //! e.g. To provide a 10us delay:
135 //!  am_hal_flash_delay( FLASH_CYCLES_US(10) );
136 //!
137 //! As of SDK 2.1, burst mode is accounted for in am_hal_flash_delay().
138 //!
139 //! The FLASH_CYCLES_US macro assumes:
140 //!  - Burst or normal mode operation.
141 //!  - If cache is not enabled, use FLASH_CYCLES_US_NOCACHE() instead.
142 //
143 //*****************************************************************************
144 #define CYCLESPERITER               (AM_HAL_CLKGEN_FREQ_MAX_MHZ / 3)
145 #define FLASH_CYCLES_US(n)          ((n * CYCLESPERITER) + 0)
146 #define FLASH_CYCLES_US_NOCACHE(n)  ( (n == 0) ? 0 : (n * CYCLESPERITER) - 5)
147 
148 //
149 //! Backward compatibility
150 //
151 #define am_hal_flash_program_otp        am_hal_flash_program_info
152 #define am_hal_flash_program_otp_sram   am_hal_flash_program_info_sram
153 
154 //*****************************************************************************
155 //
156 //! Structure of pointers to helper functions invoking flash operations.
157 //!
158 //! The functions we are pointing to here are in the Apollo 3
159 //! integrated BOOTROM.
160 //
161 //*****************************************************************************
162 typedef struct am_hal_flash_helper_struct
163 {
164     //
165     // The basics.
166     //
167     int  (*flash_mass_erase)(uint32_t, uint32_t);
168     int  (*flash_page_erase)(uint32_t, uint32_t, uint32_t);
169     int  (*flash_program_main)(uint32_t, uint32_t *, uint32_t *, uint32_t);
170     int  (*flash_program_info_area)(uint32_t,  uint32_t, uint32_t *, uint32_t, uint32_t);
171 
172     //
173     // Non-blocking variants, but be careful these are not interrupt safe so
174     // mask interrupts while these very long operations proceed.
175     //
176     int  (*flash_mass_erase_nb)(uint32_t, uint32_t);
177     int  (*flash_page_erase_nb)(uint32_t, uint32_t, uint32_t);
178     int  (*flash_page_erase2_nb)( uint32_t value, uint32_t address);
179     bool (*flash_nb_operation_complete)(void);
180 
181     //
182     // Useful utilities.
183     //
184     uint32_t (*flash_util_read_word)( uint32_t *);
185     void (*flash_util_write_word)( uint32_t *, uint32_t);
186     void (*bootrom_delay_cycles)(uint32_t ui32Cycles);
187 
188     //
189     // Essentially these are recovery options.
190     //
191     int  (*flash_info_erase)( uint32_t, uint32_t);
192     int  (*flash_info_plus_main_erase)( uint32_t, uint32_t);
193     int  (*flash_info_plus_main_erase_both)( uint32_t value);
194     int  (*flash_recovery)( uint32_t value);
195 
196     //
197     // The following functions pointers will generally never be called from
198     // user programs. They are here primarily to document these entry points
199     // which are usable from a debugger or debugger script.
200     //
201     void (*flash_program_main_from_sram)(void);
202     void (*flash_program_info_area_from_sram)(void);
203     void (*flash_erase_main_pages_from_sram)(void);
204     void (*flash_mass_erase_from_sram)(void);
205     void (*flash_info_erase_from_sram)(void);
206     void (*flash_info_plus_main_erase_from_sram)(void);
207     void (*flash_nb_operation_complete_from_sram)(void);
208     void (*flash_page_erase2_nb_from_sram)(void);
209     void (*flash_recovery_from_sram)(void);
210 
211 } g_am_hal_flash_t;
212 extern const g_am_hal_flash_t g_am_hal_flash;
213 
214 //*****************************************************************************
215 //
216 //! Define some FLASH INFO SPACE values and macros.
217 //
218 //*****************************************************************************
219 #define AM_HAL_FLASH_INFO_ADDR              0x50020000
220 #define AM_HAL_FLASH_INFO_SECURITY_O        0x10
221 #define AM_HAL_FLASH_INFO_WRITPROT_O        0x40
222 #define AM_HAL_FLASH_INFO_COPYPROT_O        0x50
223 
224 #define AM_HAL_FLASH_INFO_SECURITY_ADDR     (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_SECURITY_O)
225 #define AM_HAL_FLASH_INFO_WRITPROT_ADDR     (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_WRITPROT_O)
226 #define AM_HAL_FLASH_INFO_COPYPROT_ADDR     (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_COPYPROT_O)
227 #define AM_HAL_FLASH_INFO_CUST_TRIM_ADDR    (AM_HAL_FLASH_INFO_ADDR + 0x14)
228 
229 //
230 //! Define the customer info signature data (at AM_HAL_FLASH_INFO_ADDR).
231 //! These bits must exist in the customer info space in order for many of the
232 //! security and protection functions to work.
233 //
234 #define AM_HAL_FLASH_INFO_SIGNATURE0        0x48EAAD88
235 #define AM_HAL_FLASH_INFO_SIGNATURE1        0xC9705737
236 #define AM_HAL_FLASH_INFO_SIGNATURE2        0x0A6B8458
237 #define AM_HAL_FLASH_INFO_SIGNATURE3        0xE41A9D74
238 
239 //
240 //! Define the customer security bits (at AM_HAL_FLASH_INFO_SECURITY_ADDR)
241 //
242 #define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S       0
243 #define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S            1
244 #define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S           2
245 #define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S          3
246 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S         4
247 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S        8
248 #define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S     9
249 
250 #define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M       ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S))
251 #define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M            ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S))
252 #define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M           ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S))
253 #define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M          ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S))
254 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M         ((uint32_t)(0xF << AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S))
255 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M        ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S))
256 #define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_M     ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
257 #define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP_M          ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
258 #define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP            ((uint32_t)(0x0 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
259 
260 //
261 //! Protection chunk macros
262 //! AM_HAL_FLASH_INFO_CHUNK2ADDR: Convert a chunk number to an address
263 //! AM_HAL_FLASH_INFO_CHUNK2INST: Convert a chunk number to an instance number
264 //! AM_HAL_FLASH_INFO_ADDR2CHUNK: Convert an address to a chunk number
265 //
266 #define AM_HAL_FLASH_INFO_CHUNKSIZE         (16*1024)
267 
268 #define AM_HAL_FLASH_INFO_CHUNK2ADDR(n)     (AM_HAL_FLASH_ADDR + (n << 14))
269 #define AM_HAL_FLASH_INFO_CHUNK2INST(n)     ((n >> 5) & 1
270 #define AM_HAL_FLASH_INFO_ADDR2CHUNK(n)     ((n) >> 14)
271 
272 //*****************************************************************************
273 //
274 // Function prototypes for the helper functions
275 //
276 //*****************************************************************************
277 //*****************************************************************************
278 //
279 //! @brief This function performs a mass erase on a flash instance.
280 //!
281 //! @param ui32ProgramKey - The flash program key.
282 //! @param ui32FlashInst - The flash instance to erase.
283 //!
284 //! This function will erase the desired instance of flash.
285 //!
286 //! @note For Apollo3, each flash instance contains a maximum of 512KB.
287 //! @par
288 //! @note Interrupts are active during execution of this function. Any interrupt
289 //! taken could cause execution errors. Please see the IMPORTANT note under
290 //! Detailed Description above for more details.
291 //!
292 //! @return 0 for success, non-zero for failure.
293 //!     Failing return code indicates:
294 //!      - 1   ui32ProgramKey is invalid.
295 //!      - 2   ui32FlashInst is invalid.
296 //!      - 3   Flash controller hardware timeout.
297 //
298 //*****************************************************************************
299 extern int am_hal_flash_mass_erase(uint32_t ui32ProgramKey, uint32_t ui32FlashInst);
300 //*****************************************************************************
301 //
302 //! @brief This function performs a page erase on a flash instance.
303 //!
304 //! @param ui32ProgramKey - The flash program key.
305 //! @param ui32FlashInst - The flash instance to reference the page number with.
306 //! @param ui32PageNum - The flash page relative to the specified instance.
307 //!
308 //! This function will erase the desired flash page in the desired instance of
309 //! flash.
310 //!
311 //! @note For Apollo3, each flash page is 8KB (or AM_HAL_FLASH_PAGE_SIZE).
312 //! Each flash instance contains a maximum of 64 pages (or
313 //! AM_HAL_FLASH_INSTANCE_PAGES).
314 //! @par
315 //! @note When given an absolute flash address, a couple of helpful macros can
316 //! be utilized when calling this function.
317 //! For example:
318 //!     am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY,
319 //!                             AM_HAL_FLASH_ADDR2INST(ui32Addr),
320 //!                             AM_HAL_FLASH_ADDR2PAGE(ui32Addr) );
321 //! @par
322 //! @note Interrupts are active during execution of this function. Any interrupt
323 //! taken could cause execution errors. Please see the IMPORTANT note under
324 //! Detailed Description above for more details.
325 //!
326 //! @return 0 for success, non-zero for failure.
327 //!     Failing return code indicates:
328 //!      - 1   ui32ProgramKey is invalid.
329 //!      - 2   ui32FlashInst is invalid.
330 //!      - 3   ui32PageNum is invalid.
331 //!      - 4   Flash controller hardware timeout.
332 //
333 //*****************************************************************************
334 extern int am_hal_flash_page_erase(uint32_t ui32ProgramKey, uint32_t ui32FlashInst,
335                                    uint32_t ui32PageNum);
336 //*****************************************************************************
337 //
338 //! @brief This programs up to N words of the Main array on one flash instance.
339 //!
340 //! @param ui32ProgramKey - The programming key, AM_HAL_FLASH_PROGRAM_KEY.
341 //! @param pui32Src - Pointer to word aligned array of data to program into
342 //! the flash instance.
343 //! @param pui32Dst - Pointer to the word aligned flash location where
344 //! programming of the flash instance is to begin.
345 //! @param ui32NumWords - The number of words to be programmed.
346 //!
347 //! This function will program multiple words in main flash.
348 //!
349 //! @note Interrupts are active during execution of this function. Any interrupt
350 //! taken could cause execution errors. Please see the IMPORTANT note under
351 //! Detailed Description above for more details.
352 //!
353 //! @return 0 for success, non-zero for failure.
354 //!     Failing return code indicates:
355 //!      - 1   ui32ProgramKey is invalid.
356 //!      - 2   pui32Dst is invalid.
357 //!      - 3   Flash addressing range would be exceeded.  That is, (pui32Dst +
358 //!         (ui32NumWords * 4)) is greater than the last valid address.
359 //!      - 4   pui32Src is invalid.
360 //!      - 5   pui32Src is invalid.
361 //!      - 6   Flash controller hardware timeout.
362 //
363 //*****************************************************************************
364 extern int am_hal_flash_program_main(
365                     uint32_t ui32ProgramKey,
366                     uint32_t *pui32Src,
367                     uint32_t *pui32Dst,
368                     uint32_t ui32NumWords);
369 
370 //*****************************************************************************
371 // @name Recovery_Functions
372 // @{
373 // Recovery type functions for Customer INFO space.
374 //*****************************************************************************
375 
376 //*****************************************************************************
377 //
378 //! @brief This function programs multiple words in the customer INFO space.
379 //!
380 //! @param ui32InfoKey - The customer INFO space key.
381 //! @param ui32InfoInst - The INFO space instance, 0 or 1.
382 //! @param *pui32Src - Pointer to word aligned array of data to program into
383 //! the customer INFO space.
384 //! @param ui32Offset - Word offset into customer INFO space (offset of 0 is
385 //! the first word, 1 is second word, etc.).
386 //! @param ui32NumWords - The number of words to be programmed, must not
387 //! exceed AM_HAL_FLASH_INFO_SIZE/4.
388 //!
389 //! This function will program multiple words in the customer INFO space.
390 //!
391 //! @note Interrupts are active during execution of this function. Any interrupt
392 //! taken could cause execution errors. Please see the IMPORTANT note under
393 //! Detailed Description above for more details.
394 //!
395 //! @return 0 for success, non-zero for failure.
396 //!     Failing return code indicates:
397 //!      - 1   ui32InfoKey is invalid.
398 //!      - 2   ui32InfoInst is invalid.
399 //!      - 3   ui32Offset is invalid.
400 //!      - 4   INFO addressing range would be exceeded.  That is, (ui32Offset +
401 //!         ui32NumWords) is greater than the last valid address.
402 //!      - 5   pui32Src is invalid.
403 //!      - 6   pui32Src is invalid.
404 //!      - 7   Hardware error.
405 //!      - 8   Flash controller hardware timeout.
406 //
407 //*****************************************************************************
408 extern int      am_hal_flash_program_info(uint32_t ui32InfoKey, uint32_t ui32InfoInst,
409                                           uint32_t *pui32Src, uint32_t ui32Offset,
410                                           uint32_t ui32NumWords);
411 
412 //*****************************************************************************
413 //
414 //! @brief This function erases an instance of the customer INFO space.
415 //!
416 //! @param ui32InfoKey - The customer INFO space programming key
417 //!                      (AM_HAL_FLASH_INFO_KEY).
418 //! @param ui32Inst - The flash instance, either 0 or 1.
419 //!
420 //! This function will erase the the customer INFO space of the specified
421 //! instance.
422 //!
423 //! @note Interrupts are active during execution of this function. Any interrupt
424 //! taken could cause execution errors. Please see the IMPORTANT note under
425 //! Detailed Description above for more details.
426 //!
427 //! @return 0 for success, non-zero for failure.
428 //!     Failing return code indicates:
429 //!     - 1   ui32InfoKey is invalid.
430 //!     - 2   ui32Inst is invalid.
431 //!     - 3   Hardware error.
432 //!     - 4   Flash controller hardware timeout.
433 //
434 //*****************************************************************************
435 extern int      am_hal_flash_erase_info(uint32_t ui32InfoKey,
436                                         uint32_t ui32Inst);
437 //*****************************************************************************
438 //
439 //! @brief This function erases the main instance + the customer INFO space.
440 //!
441 //! @param ui32InfoKey - The customer INFO space key.
442 //! @param ui32Inst      - The flash instance, either 0 or 1.
443 //!
444 //! This function will erase the main flash + the customer INFO space of the
445 //! specified instance.
446 //!
447 //! @note Interrupts are active during execution of this function. Any interrupt
448 //! taken could cause execution errors. Please see the IMPORTANT note under
449 //! Detailed Description above for more details.
450 //!
451 //! @return 0 for success, non-zero for failure.
452 //!     Failing return code indicates:
453 //!     - 1   ui32InfoKey is invalid.
454 //!     - 2   ui32Inst is invalid.
455 //!     - 3   Hardware error.
456 //!     - 4   Flash controller hardware timeout.
457 //!     - 11  Internal error.
458 //!     - 12  Internal error.
459 //!     - 13  Flash controller hardware timeout.
460 //
461 //*****************************************************************************
462 extern int      am_hal_flash_erase_main_plus_info(uint32_t ui32InfoKey,
463                                                   uint32_t ui32Inst);
464 //*****************************************************************************
465 //
466 //! @brief This function erases the main flash + the customer INFO space.
467 //!
468 //! @param ui32InfoKey - The customer INFO space key.
469 //!
470 //! This function will erase both instances the main flash + the
471 //! customer INFO space.
472 //!
473 //! @note Interrupts are active during execution of this function. Any interrupt
474 //! taken could cause execution errors. Please see the IMPORTANT note under
475 //! Detailed Description above for more details.
476 //!
477 //! @return 0 for success, non-zero for failure.
478 //!     Failing return code indicates:
479 //!     - 1   ui32InfoKey is invalid, instance 0.
480 //!     - 2   Internal error, instance 0.
481 //!     - 3   Hardware error, instance 0.
482 //!     - 4   Flash controller hardware timeout, instance 0.
483 //!     - 11   Internal error.
484 //!     - 12   Internal error.
485 //!     - 13   Flash controller hardware timeout.
486 //!     - 21   ui32InfoKey is invalid, instance 1.
487 //!     - 22   Internal error, instance 1.
488 //!     - 23   Hardware error, instance 1.
489 //!     - 24   Flash controller hardware timeout, instance 1.
490 //!     - 31   Internal error, instance 1.
491 //!     - 32   Internal error, instance 1.
492 //!     - 33   Flash controller hardware timeout, instance 1.
493 //
494 //*****************************************************************************
495 extern int      am_hal_flash_erase_main_plus_info_both_instances(
496                                                   uint32_t ui32InfoKey);
497 //*****************************************************************************
498 //
499 //! @brief This function erases both main flash instances + both customer INFO
500 //! space instances.
501 //!
502 //! @param ui32RecoveryKey - The recovery key.
503 //!
504 //! This function erases both main instances and both customer INFOinstances
505 //! even if the customer INFO space is programmed to not be erasable. This
506 //! function completely erases the flash main and info instances and wipes the
507 //! SRAM. Upon completion of the erasure operations, it does a POI (power on
508 //! initialization) reset.
509 //!
510 //! @note The customer key lock is enforced by this function.  Therefore, the
511 //! customer key must be written prior to calling otherwise, the function will
512 //! fail.  Therefore, always check for a return code.  If the function returns,
513 //! a failure has occured.
514 //! @par
515 //! @note Interrupts are active during execution of this function. Any interrupt
516 //! taken could cause execution errors. Please see the IMPORTANT note under
517 //! Detailed Description above for more details.
518 //!
519 //! @return Does not return if successful.  Returns failure code otherwise.
520 //!     - Failing return code indicates:
521 //!     - 0x00000001  ui32RecoveryKey is invalid.
522 //!     - 0x00000002  Customer key lock not set.
523 //!     - 0x00001001  Internal error.
524 //!     - 0x00001002  Internal error.
525 //!     - 0x00001003  Info erase, instance 0 - hardware error.
526 //!     - 0x00001004  Info erase, instance 0 - flash controller hardware timeout.
527 //!     - 0xi000ppee  Error erasing page in instance, pp=page number, ee=error code.
528 //!                 - i=2|3, instance 0.
529 //!                 - i=4|5, instance 1.
530 //!                 - ee=1|2|3    Internal or hardware error.
531 //!                 - ee=4        Flash controller hardware timeout.
532 //
533 //*****************************************************************************
534 extern int      am_hal_flash_recovery(uint32_t ui32RecoveryKey);
535 
536 
537 //*****************************************************************************
538 //
539 //! @brief Write a given uint32 value to a valid memory or peripheral location.
540 //!
541 //! @param pui32Address - The location to be written.
542 //! @param ui32Value    - Value to be written
543 //!
544 //! @note Use this function to safely store a value to peripheral or memory locations.
545 //!
546 //! This function calls a function that resides in BOOTROM or SRAM to do the
547 //! actual write, thus completely avoiding any conflict with flash or INFO.
548 //! This function safely writes to a peripheral or memory address while executing
549 //! from SRAM, thus avoiding any conflict with flash or INFO space.
550 //
551 //*****************************************************************************
552 extern void     am_hal_flash_store_ui32(uint32_t *pui32Address, uint32_t ui32Value);
553 
554 //*****************************************************************************
555 // BOOTROM resident reader, writer and delay utility functions.
556 //*****************************************************************************
557 
558 //*****************************************************************************
559 //
560 //! @brief Read a uint32 value from a valid memory or peripheral location.
561 //! @details BOOTROM resident reader, writer and delay utility functions.
562 //! This function calls a function that resides BOOTROM or SRAM to do the actual
563 //! read, thus completely avoiding any conflict with flash or INFO space.
564 //!
565 //! @param pui32Address - The location to be read.
566 //!
567 //! @note Use this function to safely read a value from peripheral or memory locations.
568 //!
569 //! @return The value read from the given address.
570 //
571 //*****************************************************************************
572 extern uint32_t am_hal_flash_load_ui32(uint32_t *pui32Address);
573 //*****************************************************************************
574 //
575 //! @brief Use the bootrom to implement a spin loop.
576 //!
577 //! @param ui32Iterations - Number of iterations to delay.
578 //!
579 //! Use this function to implement a CPU busy waiting spin loop without cache
580 //! or delay uncertainties.
581 //!
582 //! Notes for Apollo3:
583 //! - The ROM-based function executes at 3 cycles per iteration plus the normal
584 //!   function call, entry, and exit overhead and latencies.
585 //! - Cache settings affect call overhead.  However, the cache does not affect
586 //!   the time while inside the BOOTROM function.
587 //! - The function accounts for burst vs normal mode, along with some of the
588 //!   overhead encountered with executing the function itself (such as the
589 //!   check for burst mode).
590 //! - Use of the FLASH_CYCLES_US() or FLASH_CYCLES_US_NOCACHE() macros for the
591 //!   ui32Iterations parameter will result in approximate microsecond timing.
592 //! - The parameter ui32Iterations==0 is allowed but is still incurs a delay.
593 //!
594 //! Example:
595 //! - MCU operating at 48MHz -> 20.83 ns / cycle
596 //! - Therefore each iteration (once inside the bootrom function) will consume
597 //!   62.5ns (non-burst-mode).
598 //!
599 //! @note Interrupts are not disabled during execution of this function.
600 //!       Therefore, any interrupt taken will affect the delay timing.
601 //
602 //*****************************************************************************
603 extern void     am_hal_flash_delay(uint32_t ui32Iterations);
604 //*****************************************************************************
605 //
606 //! @brief Delays for a desired amount of cycles while also waiting for a
607 //! status to change a value.
608 //!
609 //! @param ui32usMaxDelay - Maximum number of ~1uS delay loops.
610 //! @param ui32Address    - Address of the register for the status change.
611 //! @param ui32Mask       - Mask for the status change.
612 //! @param ui32Value      - Target value for the status change.
613 //!
614 //! This function will delay for approximately the given number of microseconds
615 //! while checking for a status change, exiting when either the given time has
616 //! expired or the status change is detected.
617 //!
618 //! @returns
619 //!          - 0 = timeout.
620 //!          - 1 = status change detected.
621 //
622 
623 //*****************************************************************************
624 extern uint32_t am_hal_flash_delay_status_change(
625                                  uint32_t ui32usMaxDelay,
626                                  uint32_t ui32Address,
627                                  uint32_t ui32Mask,
628                                  uint32_t ui32Value);
629 //*****************************************************************************
630 //
631 //! @brief Delays for a desired amount of cycles while also waiting for a
632 //! status to equal OR not-equal to a value.
633 //!
634 //! @param ui32usMaxDelay - Maximum number of ~1uS delay loops.
635 //! @param ui32Address    - Address of the register for the status change.
636 //! @param ui32Mask       - Mask for the status change.
637 //! @param ui32Value      - Target value for the status change.
638 //! @param bIsEqual       - Check for equal if true; not-equal if false.
639 //!
640 //! This function will delay for approximately the given number of microseconds
641 //! while checking for a status change, exiting when either the given time has
642 //! expired or the status change is detected.
643 //!
644 //! @returns
645 //!          - 0 = timeout.
646 //!          - 1 = status change detected.
647 //
648 //*****************************************************************************
649 extern uint32_t am_hal_flash_delay_status_check(
650                         uint32_t ui32usMaxDelay,
651                         uint32_t ui32Address,
652                         uint32_t ui32Mask,
653                         uint32_t ui32Value,
654                         bool bIsEqual);
655 
656 //*****************************************************************************
657 // @} // Recovery type functions for Customer INFO space
658 //*****************************************************************************
659 
660 //*****************************************************************************
661 // @name Security_Protection_INFOBLK
662 // @{
663 // These functions update security/protection bits in the customer INFO blOCK.
664 //*****************************************************************************
665 
666 //*****************************************************************************
667 //
668 //! @brief Check that the customer info bits are valid.
669 //!
670 //! Use this function to test the state of the 128 valid bits at the beginning
671 //! of customer info space. If these are not set correctly then the customer
672 //! protection bits in the INFO space will not be honored by the hardware.
673 //!
674 //! @return true if valid.
675 //
676 //*****************************************************************************
677 extern bool     am_hal_flash_customer_info_signature_check(void);
678 
679 //*****************************************************************************
680 //
681 //! @brief INFO signature set.
682 //!
683 //! @param ui32InfoKey - The customer INFO space programming key
684 //!
685 //! Use this function to set the state of the 128 valid bits at the beginning
686 //! of customer info space, if needed.
687 //!
688 //! @note Interrupts are active during execution of this function. Any interrupt
689 //! taken could cause execution errors. Please see the IMPORTANT note under
690 //! Detailed Description above for more details.
691 //!
692 //! @return
693 //!     - Zero for success.
694 //!     - Non-Zero for errors.
695 //!
696 //! Note: See am_hal_flash_program_info() for further details on return codes.
697 //
698 //*****************************************************************************
699 extern bool     am_hal_flash_info_signature_set(uint32_t ui32InfoKey);
700 
701 //*****************************************************************************
702 //
703 //! @brief Disable FLASH INFO space.
704 //!
705 //! @param ui32InfoKey - The customer INFO space programming key
706 //!
707 //! Use this function to set the state of the 128 valid bits at the beginning
708 //! of customer info space, if needed. Then disable FLASH erasure.
709 //!
710 //! @note Interrupts are active during execution of this function. Any interrupt
711 //! taken could cause execution errors. Please see the IMPORTANT note under
712 //! Detailed Description above for more details.
713 //!
714 //! @return
715 //!     - Zero for success.
716 //!     - Non-Zero for errors.
717 //!
718 //! Note: See am_hal_flash_program_info() for further details on return codes.
719 //
720 //*****************************************************************************
721 extern int32_t  am_hal_flash_info_erase_disable(uint32_t ui32InfoKey);
722 
723 //*****************************************************************************
724 //
725 //! @brief Check for Disabled FLASH INFO space.
726 //!
727 //! Use this function to determine whether FLASH INFO erasure is disabled.
728 //!
729 //! @return
730 //!     - true if FLASH INFO erase is disabled,
731 //!     - otherwise false.
732 //
733 //*****************************************************************************
734 extern bool     am_hal_flash_info_erase_disable_check(void);
735 
736 //*****************************************************************************
737 //
738 //! @brief Mask off 1 to 4 quadrants of FLASH INFO space for programming.
739 //!
740 //! Use this function to set the state of the 128 valid bits at the beginning
741 //! of customer info space, if needed. Then and the mask bits with the INFO
742 //! space programming disable bits.
743 //!
744 //! @param ui32InfoKey - The customer INFO space programming key
745 //!
746 //! @param ui32Mask    - A mask of the 4 quadrants of info space where\n
747 //!      - bit0 = First quadrant (first 2KB).
748 //!      - bit1 = Second quadrant (second 2KB).
749 //!      - bit2 = Third quadrant (third 2KB).
750 //!      - bit3 = Fourth quadrant (fourth 2KB).
751 //!
752 //! @note This function disables only, any quadrant already disabled is not
753 //! re-enabled.  That is, any ui32Mask bits specified as 0 are essentially nops.
754 //! @par
755 //! @note Interrupts are active during execution of this function. Any interrupt
756 //! taken could cause execution errors. Please see the IMPORTANT note under
757 //! Detailed Description above for more details.
758 //!
759 //! @return
760 //!     - Zero for success.
761 //!     - Non-Zero for errors.
762 //!
763 //! Note: See am_hal_flash_program_info() for further details on return codes.
764 //
765 //*****************************************************************************
766 extern int32_t  am_hal_flash_info_program_disable(uint32_t ui32InfoKey, uint32_t ui32Mask);
767 
768 //*****************************************************************************
769 //
770 //! @brief Return a mask specifying which quadrants of customer INFO space have
771 //! been disabled for programming.
772 //!
773 //! Use this function to determine whether programming of customer INFO space
774 //! has been disabled.
775 //!
776 //! @return A 4-bit mask of the disabled quadrants.
777 //!      - 0xFFFFFFFF indicates an error.
778 //!      - 0x0  indicates all customer INFO space programming is enabled.
779 //!      - 0xF  indicates all customer INFO space programming is disabled.
780 //!      - bit0 indicates the first customer INFO space is disabled for programming.
781 //!      - bit1 indicates the second customer INFO space is disabled for programming.
782 //!      - bit2 indicates the third customer INFO space is disabled for programming.
783 //!      - bit3 indicates the fourth customer INFO space is disabled for programming.
784 //
785 //*****************************************************************************
786 extern uint32_t am_hal_flash_info_program_disable_get(void);
787 
788 //*****************************************************************************
789 //
790 //! @brief Enable FLASH debugger protection (FLASH gets wiped if a debugger is
791 //! connected).
792 //!
793 //! @param ui32InfoKey - The customer INFO space programming key
794 //!
795 //! Use this function to set the state of the 128 valid bits at the beginning
796 //! of customer info space, if needed. Then set the FLASH wipe bit to zero.
797 //!
798 //! @note Interrupts are active during execution of this function. Any interrupt
799 //! taken could cause execution errors. Please see the IMPORTANT note under
800 //! Detailed Description above for more details.
801 //!
802 //! @return
803 //!     - Zero for success.
804 //!     - Non-Zero for errors.
805 //!
806 //! Note: See am_hal_flash_program_info() for further details on return codes.
807 //
808 //*****************************************************************************
809 extern int32_t  am_hal_flash_wipe_flash_enable(uint32_t ui32InfoKey);
810 
811 //*****************************************************************************
812 //
813 //! @brief check for FLASH wipe protection enabled.
814 //!
815 //! Use this function to determine if FLASH wipe protection is enabled.
816 //!
817 //! @return
818 //!     - true if FLASH wipe protection is enabled,
819 //!     - otherwise false.
820 //
821 //*****************************************************************************
822 extern bool     am_hal_flash_wipe_flash_enable_check(void);
823 
824 //*****************************************************************************
825 //
826 //! @brief Enable SRAM protection so SRAM gets wiped if a debgger is connected.
827 //!
828 //! @param ui32InfoKey - The customer INFO space programming key
829 //!
830 //! Use this function to set the state of the 128 valid bits at the beginning
831 //! of customer info space, if needed. Then set the SRAM wipe bit to zero.
832 //!
833 //! @note Interrupts are active during execution of this function. Any interrupt
834 //! taken could cause execution errors. Please see the IMPORTANT note under
835 //! Detailed Description above for more details.
836 //!
837 //! @return
838 //!     - Zero for success.
839 //!     - Non-Zero for errors.
840 //!
841 //! Note: See am_hal_flash_program_info() for further details on return codes.
842 //
843 //*****************************************************************************
844 extern int32_t  am_hal_flash_wipe_sram_enable(uint32_t ui32InfoKey);
845 
846 //*****************************************************************************
847 //
848 //! @brief check for SRAM protection enabled.
849 //!
850 //! Use this function to determine if SRAM protection is enabled.
851 //!
852 //! @return
853 //!     - true if SRAM wipe protection is enabled,
854 //!     - otherwise false.
855 //
856 //*****************************************************************************
857 extern bool     am_hal_flash_wipe_sram_enable_check(void);
858 
859 //*****************************************************************************
860 //
861 //! @brief Disable Output from ITM/SWO.
862 //!
863 //! @param ui32InfoKey - The customer INFO space programming key
864 //!
865 //! Use this function to set the state of the 128 valid bits at the beginning
866 //! of customer info space, if needed. Set the SWO disable bit to zero.
867 //!
868 //! @note Interrupts are active during execution of this function. Any interrupt
869 //! taken could cause execution errors. Please see the IMPORTANT note under
870 //! Detailed Description above for more details.
871 //!
872 //! @return
873 //!     - Zero for success.
874 //!     - Non-Zero for errors.
875 //!
876 //! Note: See am_hal_flash_program_info() for further details on return codes.
877 //
878 //*****************************************************************************
879 extern int32_t  am_hal_flash_swo_disable(uint32_t ui32InfoKey);
880 
881 //*****************************************************************************
882 //
883 //! @brief check for SWO disabled.
884 //!
885 //! Use this function to determine if the SWO is disabled.
886 //!
887 //! @return true if the ITM/SWO is disabled, otherwise false.
888 //
889 //*****************************************************************************
890 extern bool     am_hal_flash_swo_disable_check(void);
891 
892 //*****************************************************************************
893 //
894 //! @brief Disable Connections from a debugger on the SWD interface.
895 //!
896 //! @param ui32InfoKey - The customer INFO space programming key
897 //!
898 //! Use this function to set the state of the 128 valid bits at the beginning
899 //! of customer info space, if needed. Set the debugger disable bit to zero.
900 //!
901 //! @note Interrupts are active during execution of this function. Any interrupt
902 //! taken could cause execution errors. Please see the IMPORTANT note under
903 //! Detailed Description above for more details.
904 //!
905 //! @return
906 //!     - Zero for success.
907 //!     - Non-Zero for errors.
908 //!
909 //! Note: See am_hal_flash_program_info() for further details on return codes.
910 //
911 //*****************************************************************************
912 extern int32_t  am_hal_flash_debugger_disable(uint32_t ui32InfoKey);
913 
914 //*****************************************************************************
915 //
916 //! @brief check for debugger disabled.
917 //!
918 //! Use this function to determine if the debugger is disabled.
919 //!
920 //! @return
921 //!     - true if the debugger is disabled,
922 //!     - otherwise false.
923 //
924 //*****************************************************************************
925 extern bool     am_hal_flash_debugger_disable_check(void);
926 
927 //*****************************************************************************
928 //
929 //! @brief This function sets copy protection for a range of flash chunks.
930 //!
931 //! @param ui32InfoKey - The customer INFO space programming key
932 //! @param pui32StartAddress - Starting address in flash to begin protection.
933 //! @param pui32StopAddress - Ending address in flash to stop protection.
934 //!
935 //! This function will set copy protection bits for a range of flash chunks
936 //!
937 //! @note Each flash chunk contains 16KBytes and corresponds to one bit in
938 //! the protection register. Set the bit to zero to enable protection.
939 //! @par
940 //! @note Interrupts are active during execution of this function. Any interrupt
941 //! taken could cause execution errors. Please see the IMPORTANT note under
942 //! Detailed Description above for more details.
943 //!
944 //! @return
945 //!     - 0 for success.
946 //!     - 0x400000 if the protection bits were already programmed (mask the return
947 //!              value with 0x3FFFFF to ignore this case and treat as success).
948 //!     - Otherwise, non-zero for failure.
949 //!
950 //! Note: See am_hal_flash_program_info() for further details on return codes.
951 //
952 //*****************************************************************************
953 extern int32_t  am_hal_flash_copy_protect_set(uint32_t ui32InfoKey,
954                                               uint32_t *pui32StartAddress,
955                                               uint32_t *pui32StopAddress);
956 
957 //*****************************************************************************
958 //
959 //! @brief This function checks copy protection for a range of flash chunks.
960 //!
961 //! @param pui32StartAddress - Starting address in flash.
962 //! @param pui32StopAddress - Ending address in flash.
963 //!
964 //! This function will check copy protection bits for a range of flash chunks
965 //! it expects all chunks in the range to be protected.
966 //!
967 //! @note Each flash chunk contains 16KBytes and corresponds to one bit in
968 //! the protection register. Set the bit to zero to enable protection.
969 //!
970 //! @return
971 //!         - false for at least one chunk in the covered range is not protected,
972 //!         - true if all chunks in the covered range are protected.
973 //!
974 //
975 //*****************************************************************************
976 extern bool     am_hal_flash_copy_protect_check(uint32_t *pui32StartAddress,
977                                                 uint32_t *pui32StopAddress);
978 
979 //*****************************************************************************
980 //
981 //! @brief This function sets write protection for a range of flash chunks.
982 //!
983 //! @param ui32InfoKey - The customer INFO space programming key
984 //! @param pui32StartAddress - Starting address in flash to begin protection.
985 //! @param pui32StopAddress - Ending address in flash to stop protection.
986 //!
987 //! This function will set write protection bits for a range of flash chunks
988 //!
989 //! @note Each flash chunk contains 16KBytes and corresponds to one bit in
990 //! the protection register. Set the bit to zero to enable protection.
991 //! @par
992 //! @note Interrupts are active during execution of this function. Any interrupt
993 //! taken could cause execution errors. Please see the IMPORTANT note under
994 //! Detailed Description above for more details.
995 //!
996 //! @return
997 //!     - 0 for success.
998 //!     - 0x400000 if the protection bits were already programmed (mask the return
999 //!              value with 0x3FFFFF to ignore this case and treat as success).
1000 //!     - Otherwise, non-zero for failure.
1001 //!
1002 //! Note: See am_hal_flash_program_info() for further details on return codes.
1003 //
1004 //*****************************************************************************
1005 extern int32_t  am_hal_flash_write_protect_set(uint32_t ui32InfoKey,
1006                                                uint32_t *pui32StartAddress,
1007                                                uint32_t *pui32StopAddress);
1008 
1009 //*****************************************************************************
1010 //
1011 //! @brief This function checks write protection for a range of flash chunks.
1012 //!
1013 //! @param pui32StartAddress - Starting address in flash.
1014 //! @param pui32StopAddress - Ending address in flash.
1015 //!
1016 //! This function will check write protection bits for a range of flash chunks
1017 //! it expects all chunks in the range to be protected.
1018 //!
1019 //! @note Each flash chunk contains 16KBytes and corresponds to one bit in
1020 //! the protection register. Set the bit to zero to enable protection.
1021 //!
1022 //! @return
1023 //!         - false for at least one chunk in the covered range is not protected,
1024 //!         - true if all chunks in the covered range are protected.
1025 //!
1026 //
1027 //*****************************************************************************
1028 extern bool     am_hal_flash_write_protect_check(uint32_t *pui32StartAddress,
1029                                                  uint32_t *pui32StopAddress);
1030 
1031 //*****************************************************************************
1032 //
1033 //! @brief This clears the specified bits in the addressed flash word
1034 //!
1035 //! @param ui32ProgramKey - The programming key, AM_HAL_FLASH_PROGRAM_KEY.
1036 //! @param pui32Addr - Pointer to word aligned flash word to program into
1037 //! @param ui32BitMask - The bits to be cleared
1038 //!
1039 //! This function will clear one of more bits in a word in main flash.
1040 //! This function is mainly used when the same word is to be written multiple times
1041 //! few bits at a time, between erase cycle
1042 //!
1043 //! @note Interrupts are active during execution of this function. Any interrupt
1044 //! taken could cause execution errors. Please see the IMPORTANT note under
1045 //! Detailed Description above for more details.
1046 //! @par
1047 //! @note We can reprogram a bit in flash to 0 only once. This function takes
1048 //! care of not re-clearing bits if they are already programmed as 0
1049 //!
1050 //! @return 0 for success, non-zero for failure.
1051 //!
1052 //! Note: See am_hal_flash_program_main() for further details on return codes.
1053 //
1054 //*****************************************************************************
1055 extern int      am_hal_flash_clear_bits(uint32_t ui32ProgramKey,
1056                                         uint32_t *pui32Addr,
1057                                         uint32_t ui32BitMask);
1058 
1059 
1060 //*****************************************************************************
1061 // @}   Security_Protection_INFOBLK end
1062 //*****************************************************************************
1063 
1064 
1065 #ifdef __cplusplus
1066 }
1067 #endif
1068 
1069 #endif // AM_HAL_FLASH_H
1070 
1071 //*****************************************************************************
1072 //
1073 // End Doxygen group.
1074 //! @}
1075 //
1076 //*****************************************************************************
1077