1 //*****************************************************************************
2 //
3 //  am_hal_flash.h
4 //! @file
5 //!
6 //! @brief Functions for performing Flash operations.
7 //!
8 //! @addtogroup flash2 Flash
9 //! @ingroup apollo2hal
10 //! @{
11 //
12 //*****************************************************************************
13 
14 //*****************************************************************************
15 //
16 // Copyright (c) 2017, Ambiq Micro
17 // All rights reserved.
18 //
19 // Redistribution and use in source and binary forms, with or without
20 // modification, are permitted provided that the following conditions are met:
21 //
22 // 1. Redistributions of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // 3. Neither the name of the copyright holder nor the names of its
30 // contributors may be used to endorse or promote products derived from this
31 // software without specific prior written permission.
32 //
33 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
37 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 // POSSIBILITY OF SUCH DAMAGE.
44 //
45 // This is part of revision 1.2.11 of the AmbiqSuite Development Package.
46 //
47 //*****************************************************************************
48 #ifndef AM_HAL_FLASH_H
49 #define AM_HAL_FLASH_H
50 
51 #include <stdint.h>
52 #include <stdbool.h>
53 
54 //*****************************************************************************
55 //
56 // Flash Program keys.
57 //
58 //*****************************************************************************
59 #define AM_HAL_FLASH_PROGRAM_KEY            0x12344321
60 #define AM_HAL_FLASH_RECOVERY_KEY           0xA35C9B6D
61 #define AM_HAL_FLASH_INFO_KEY               0x12344321
62 #define AM_HAL_FLASH_OTP_KEY                (AM_HAL_FLASH_INFO_KEY)
63 
64 //*****************************************************************************
65 //
66 // Some helpful flash values and macros.
67 //
68 //*****************************************************************************
69 #define AM_HAL_FLASH_ADDR                   0x00000000
70 #define AM_HAL_FLASH_PAGE_SIZE              ( 8 * 1024 )
71 #define AM_HAL_FLASH_INFO_SIZE              AM_HAL_FLASH_PAGE_SIZE
72 #define AM_HAL_FLASH_INSTANCE_SIZE          ( 512 * 1024 )
73 #define AM_HAL_FLASH_INSTANCE_PAGES         ( AM_HAL_FLASH_INSTANCE_SIZE / AM_HAL_FLASH_PAGE_SIZE )
74 #define AM_HAL_FLASH_TOTAL_SIZE             ( AM_HAL_FLASH_INSTANCE_SIZE * 2 )
75 #define AM_HAL_FLASH_LARGEST_VALID_ADDR     ( AM_HAL_FLASH_ADDR + AM_HAL_FLASH_TOTAL_SIZE - 1 )
76 
77 //
78 // Convert an absolute flash address to a instance
79 //
80 #define AM_HAL_FLASH_ADDR2INST(addr)        ( ( addr >> 19 ) & 1 )
81 
82 //
83 // Convert an absolute flash address to a page number relative to the instance
84 //
85 #define AM_HAL_FLASH_ADDR2PAGE(addr)        ( ( addr >> 13 ) & 0x3F )
86 
87 //
88 // Convert an absolute flash address to an absolute page number
89 //
90 #define AM_HAL_FLASH_ADDR2ABSPAGE(addr)     ( addr >> 13 )
91 
92 //*****************************************************************************
93 //
94 // Given an integer number of microseconds, convert to a value representing the
95 // number of am_hal_flash_delay() cycles that will provide that amount of delay.
96 // This macro is designed to take into account some of the call overhead.
97 //
98 // e.g. To provide a 2us delay:
99 //  am_hal_flash_delay( FLASH_CYCLES_US(2) );
100 //
101 // IMPORTANT - Apollo2 is spec'ed for only 48MHz operation, so this macro
102 // assumes that.
103 //
104 //*****************************************************************************
105 #define FLASH_CYCLES_US(n)      ((n * (AM_HAL_CLKGEN_FREQ_MAX_MHZ / 3)) - 4)
106 
107 //
108 // Backward compatibility
109 //
110 #define am_hal_flash_program_otp        am_hal_flash_program_info
111 #define am_hal_flash_program_otp_sram   am_hal_flash_program_info_sram
112 
113 //*****************************************************************************
114 //
115 // Structure of function pointers to helper functions for invoking various
116 // flash operations. The functions we are pointing to here are in the Apollo 2
117 // integrated BOOTROM.
118 //
119 //*****************************************************************************
120 typedef struct am_hal_flash_helper_struct
121 {
122     //
123     // The basics.
124     //
125     int      (*flash_mass_erase)(uint32_t, uint32_t);
126     int      (*flash_page_erase)(uint32_t, uint32_t, uint32_t);
127     int      (*flash_program_main)(uint32_t,  uint32_t *,
128                                           uint32_t*, uint32_t);
129     int      (*flash_program_info)(uint32_t,   uint32_t,
130                                          uint32_t*,  uint32_t, uint32_t);
131 
132     //
133     // Non-blocking variants, but be careful these are not interrupt safe so
134     // mask interrupts while these very long operations proceed.
135     //
136     int      (*flash_mass_erase_nb)(uint32_t, uint32_t);
137     int      (*flash_page_erase_nb)(uint32_t, uint32_t, uint32_t);
138     bool     (*flash_nb_operation_complete)(void);
139 
140     //
141     // Essentially these are recovery options.
142     //
143     int      (*flash_erase_info)(uint32_t, uint32_t);
144     int      (*flash_erase_main_plus_info)(uint32_t, uint32_t);
145     int      (*flash_erase_main_plus_info_both_instances)(uint32_t);
146     void     (*flash_recovery)(uint32_t);
147 
148     //
149     // Useful utilities.
150     //
151     uint32_t (*flash_util_read_word)(uint32_t*);
152     void     (*flash_util_write_word)(uint32_t*, uint32_t);
153     void     (*delay_cycles)(uint32_t);
154 
155     //
156     // The following functions pointers will generally never be called from
157     // user programs. They are here primarily to document these entry points
158     // which are usable from a debugger or debugger script.
159     //
160     void     (*flash_program_main_sram)(void);
161     void     (*flash_program_info_sram)(void);
162     void     (*flash_erase_main_pages_sram)(void);
163     void     (*flash_mass_erase_sram)(void);
164     void     (*flash_erase_info_sram)(void);
165     void     (*flash_erase_main_plus_info_sram)(void);
166 } g_am_hal_flash_t;
167 extern g_am_hal_flash_t g_am_hal_flash;
168 
169 
170 //*****************************************************************************
171 //
172 // Define some FLASH INFO SPACE values and macros.
173 //
174 //*****************************************************************************
175 #define AM_HAL_FLASH_INFO_ADDR              0x50020000
176 #define AM_HAL_FLASH_INFO_SECURITY_O        0x10
177 #define AM_HAL_FLASH_INFO_WRITPROT_O        0x20
178 #define AM_HAL_FLASH_INFO_COPYPROT_O        0x30
179 
180 #define AM_HAL_FLASH_INFO_SECURITY_ADDR     (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_SECURITY_O)
181 #define AM_HAL_FLASH_INFO_WRITPROT_ADDR     (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_WRITPROT_O)
182 #define AM_HAL_FLASH_INFO_COPYPROT_ADDR     (AM_HAL_FLASH_INFO_ADDR + AM_HAL_FLASH_INFO_COPYPROT_O)
183 
184 //
185 // Define the customer info signature data (at AM_HAL_FLASH_INFO_ADDR).
186 // These bits must exist in the customer info space in order for many of the
187 // security and protection functions to work.
188 //
189 #define AM_HAL_FLASH_INFO_SIGNATURE0        0x48EAAD88
190 #define AM_HAL_FLASH_INFO_SIGNATURE1        0xC9705737
191 #define AM_HAL_FLASH_INFO_SIGNATURE2        0x0A6B8458
192 #define AM_HAL_FLASH_INFO_SIGNATURE3        0xE41A9D74
193 
194 //
195 // Define the customer security bits (at AM_HAL_FLASH_INFO_SECURITY_ADDR)
196 //
197 #define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S       0
198 #define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S            1
199 #define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S           2
200 #define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S          3
201 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S         4
202 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S        8
203 #define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S     9
204 
205 #define AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_M       ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_DEBUGGERPROT_S))
206 #define AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_M            ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SWOCTRL_S))
207 #define AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_M           ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_SRAMWIPE_S))
208 #define AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_M          ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_FLASHWIPE_S))
209 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_M         ((uint32_t)(0xF << AM_HAL_FLASH_INFO_SECURITY_ENINFOPRGM_S))
210 #define AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_M        ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_ENINFOERASE_S))
211 #define AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_M     ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
212 #define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP_M          ((uint32_t)(0x1 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
213 #define AM_HAL_FLASH_INFO_SECURITY_DEEPSLEEP            ((uint32_t)(0x0 << AM_HAL_FLASH_INFO_SECURITY_BOOTLOADERSPIN_S))
214 
215 //
216 // Protection chunk macros
217 // AM_HAL_FLASH_INFO_CHUNK2ADDR: Convert a chunk number to an address
218 // AM_HAL_FLASH_INFO_CHUNK2INST: Convert a chunk number to an instance number
219 // AM_HAL_FLASH_INFO_ADDR2CHUNK: Convert an address to a chunk number
220 //
221 #define AM_HAL_FLASH_INFO_CHUNKSIZE         (16*1024)
222 
223 #define AM_HAL_FLASH_INFO_CHUNK2ADDR(n)     (AM_HAL_FLASH_ADDR + (n << 14))
224 #define AM_HAL_FLASH_INFO_CHUNK2INST(n)     ((n >> 5) & 1
225 #define AM_HAL_FLASH_INFO_ADDR2CHUNK(n)     ((n) >> 14)
226 
227 #ifdef __cplusplus
228 extern "C"
229 {
230 #endif
231 
232 //*****************************************************************************
233 //
234 // Function prototypes for the helper functions
235 //
236 //*****************************************************************************
237 extern int am_hal_flash_mass_erase(uint32_t ui32Value, uint32_t ui32FlashInst);
238 extern int am_hal_flash_page_erase(uint32_t ui32Value, uint32_t ui32FlashInst,
239                                    uint32_t ui32PageNum);
240 extern int am_hal_flash_program_main(uint32_t value, uint32_t *pSrc,
241                                      uint32_t *pDst, uint32_t  NumberOfWords);
242 extern int am_hal_flash_program_info(uint32_t ui32Value, uint32_t ui32InfoInst,
243                                      uint32_t *pui32Src, uint32_t ui32Offset,
244                                      uint32_t ui32NumWords);
245 
246 //
247 // Recovery type functions for Customer INFO space.
248 //
249 extern int      am_hal_flash_erase_info(uint32_t ui32ProgramKey,
250                                         uint32_t ui32Instance);
251 extern int      am_hal_flash_erase_main_plus_info(uint32_t ui32ProgramKey,
252                                                   uint32_t ui32Instance);
253 extern int      am_hal_flash_erase_main_plus_info_both_instances(
254                                                   uint32_t ui32ProgramKey);
255 extern void     am_hal_flash_recovery(uint32_t ui32RecoveryKey);
256 
257 //
258 // BOOTROM resident reader, writer and delay utility functions.
259 //
260 extern uint32_t am_hal_flash_load_ui32(uint32_t ui32Address);
261 extern void     am_hal_flash_store_ui32(uint32_t ui32Address, uint32_t ui32Data);
262 extern void     am_hal_flash_delay(uint32_t ui32Iterations);
263 extern uint32_t am_hal_flash_delay_status_change(uint32_t ui32Iterations,
264                                                  uint32_t ui32Address,
265                                                  uint32_t ui32Mask,
266                                                  uint32_t ui32Value);
267 
268 //
269 // These functions update security/protection bits in the customer INFO blOCK.
270 //
271 extern bool     am_hal_flash_customer_info_signature_check(void);
272 extern bool     am_hal_flash_info_signature_set(void);
273 extern int32_t  am_hal_flash_info_erase_disable(void);
274 extern bool     am_hal_flash_info_erase_disable_check(void);
275 extern int32_t  am_hal_flash_info_program_disable(uint32_t ui32Mask);
276 extern uint32_t am_hal_flash_info_program_disable_get(void);
277 extern int32_t  am_hal_flash_wipe_flash_enable(void);
278 extern bool     am_hal_flash_wipe_flash_enable_check(void);
279 extern int32_t  am_hal_flash_wipe_sram_enable(void);
280 extern bool     am_hal_flash_wipe_sram_enable_check(void);
281 extern int32_t  am_hal_flash_swo_disable(void);
282 extern bool     am_hal_flash_swo_disable_check(void);
283 extern int32_t  am_hal_flash_debugger_disable(void);
284 extern bool     am_hal_flash_debugger_disable_check(void);
285 
286 extern int32_t  am_hal_flash_copy_protect_set(uint32_t *pui32StartAddress,
287                                               uint32_t *pui32StopAddress);
288 extern bool     am_hal_flash_copy_protect_check(uint32_t *pui32StartAddress,
289                                                 uint32_t *pui32StopAddress);
290 extern int32_t  am_hal_flash_write_protect_set(uint32_t *pui32StartAddress,
291                                                uint32_t *pui32StopAddress);
292 extern bool     am_hal_flash_write_protect_check(uint32_t *pui32StartAddress,
293                                                  uint32_t *pui32StopAddress);
294 
295 
296 #ifdef __cplusplus
297 }
298 #endif
299 
300 #endif // AM_HAL_FLASH_H
301 
302 //*****************************************************************************
303 //
304 // End Doxygen group.
305 //! @}
306 //
307 //*****************************************************************************
308