]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - msp430-bsl/msp430-bsl.git/blob - source/driverlib/MSP430F5xx_6xx/flash.c
MSP-BSL v3.0
[msp430-bsl/msp430-bsl.git] / source / driverlib / MSP430F5xx_6xx / flash.c
1 /* --COPYRIGHT--,BSD\r
2  * Copyright (c) 2014, Texas Instruments Incorporated\r
3  * All rights reserved.\r
4  *\r
5  * Redistribution and use in source and binary forms, with or without\r
6  * modification, are permitted provided that the following conditions\r
7  * are met:\r
8  *\r
9  * *  Redistributions of source code must retain the above copyright\r
10  *    notice, this list of conditions and the following disclaimer.\r
11  *\r
12  * *  Redistributions in binary form must reproduce the above copyright\r
13  *    notice, this list of conditions and the following disclaimer in the\r
14  *    documentation and/or other materials provided with the distribution.\r
15  *\r
16  * *  Neither the name of Texas Instruments Incorporated nor the names of\r
17  *    its contributors may be used to endorse or promote products derived\r
18  *    from this software without specific prior written permission.\r
19  *\r
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\r
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31  * --/COPYRIGHT--*/\r
32 //*****************************************************************************\r
33 //\r
34 // flash.c - Driver for the flash Module.\r
35 //\r
36 //*****************************************************************************\r
37 \r
38 //*****************************************************************************\r
39 //\r
40 //! \addtogroup flash_api\r
41 //! @{\r
42 //\r
43 //*****************************************************************************\r
44 \r
45 #include "inc/hw_regaccess.h"\r
46 #include "inc/hw_memmap.h"\r
47 \r
48 #ifndef DRIVERLIB_LEGACY_MODE\r
49 \r
50 #ifdef __MSP430_HAS_FLASH__\r
51 #include "flash.h"\r
52 \r
53 #include <assert.h>\r
54 \r
55 //*****************************************************************************\r
56 //\r
57 //! \brief Erase a single segment of the flash memory.\r
58 //!\r
59 //! For devices like MSP430i204x, if the specified segment is the information\r
60 //! flash segment, the FLASH_unlockInfo API must be called prior to calling\r
61 //! this API.\r
62 //!\r
63 //! \param flash_ptr is the pointer into the flash segment to be erased\r
64 //!\r
65 //! \return None\r
66 //\r
67 //*****************************************************************************\r
68 void FLASH_segmentErase( uint8_t *flash_ptr)\r
69 {\r
70         //Clear Lock bit\r
71         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
72 \r
73         //Set Erase bit\r
74         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + ERASE;\r
75 \r
76         //Dummy write to erase Flash seg\r
77         *flash_ptr = 0;\r
78 \r
79         //test busy\r
80         while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
81 \r
82         //Clear ERASE bit\r
83         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
84 \r
85         //Set LOCK bit\r
86         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
87 }\r
88 \r
89 //*****************************************************************************\r
90 //\r
91 //! \brief Erase a single bank of the flash memory.\r
92 //!\r
93 //! This function erases a single bank of the flash memory.  This API will\r
94 //! erase the entire flash if device contains only one flash bank.\r
95 //!\r
96 //! \param flash_ptr is a pointer into the bank to be erased\r
97 //!\r
98 //! \return None\r
99 //\r
100 //*****************************************************************************\r
101 void FLASH_bankErase( uint8_t *flash_ptr)\r
102 {\r
103         //Clear Lock bit\r
104         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
105 \r
106         while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
107 \r
108         //Set MERAS bit\r
109         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + MERAS;\r
110 \r
111         //Dummy write to erase Flash seg\r
112         *flash_ptr = 0;\r
113 \r
114         //test busy\r
115         while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
116 \r
117         //Clear MERAS bit\r
118         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
119 \r
120         //Set LOCK bit\r
121         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
122 }\r
123 \r
124 //*****************************************************************************\r
125 //\r
126 //! \brief Erase all flash memory.\r
127 //!\r
128 //! This function erases all the flash memory banks. For devices like\r
129 //! MSP430i204x, this API erases main memory and information flash memory if\r
130 //! the FLASH_unlockInfo API was previously executed (otherwise the information\r
131 //! flash is not erased). Also note that erasing information flash memory in\r
132 //! the MSP430i204x impacts the TLV calibration constants located at the\r
133 //! information memory.\r
134 //!\r
135 //! \param flash_ptr is a pointer into the bank to be erased\r
136 //!\r
137 //! \return None\r
138 //\r
139 //*****************************************************************************\r
140 void FLASH_massErase( uint8_t *flash_ptr)\r
141 {\r
142         //Clear Lock bit\r
143         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
144 \r
145         while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
146 \r
147         //Set MERAS bit\r
148         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + MERAS + ERASE;\r
149 \r
150         //Dummy write to erase Flash seg\r
151         *flash_ptr = 0;\r
152 \r
153         //test busy\r
154         while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
155 \r
156         //Clear MERAS bit\r
157         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
158 \r
159         //Set LOCK bit\r
160         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
161 }\r
162 \r
163 //*****************************************************************************\r
164 //\r
165 //! \brief Erase check of the flash memory\r
166 //!\r
167 //! This function checks bytes in flash memory to make sure that they are in an\r
168 //! erased state (are set to 0xFF).\r
169 //!\r
170 //! \param flash_ptr is the pointer to the starting location of the erase check\r
171 //! \param numberOfBytes is the number of bytes to be checked\r
172 //!\r
173 //! \return STATUS_SUCCESS or STATUS_FAIL\r
174 //\r
175 //*****************************************************************************\r
176 bool FLASH_eraseCheck(uint8_t *flash_ptr,\r
177                       uint16_t numberOfBytes\r
178                       )\r
179 {\r
180         uint16_t i;\r
181 \r
182         for (i = 0; i < numberOfBytes; i++) {\r
183                 //was erasing successfull?\r
184                 if ((*(flash_ptr + i)) != 0xFF)\r
185                         return STATUS_FAIL;\r
186         }\r
187         return STATUS_SUCCESS;\r
188 }\r
189 \r
190 //*****************************************************************************\r
191 //\r
192 //! \brief Write data into the flash memory in byte format, pass by reference\r
193 //!\r
194 //! This function writes a byte array of size count into flash memory. Assumes\r
195 //! the flash memory is already erased and unlocked. FLASH_segmentErase can be\r
196 //! used to erase a segment.\r
197 //!\r
198 //! \param data_ptr is the pointer to the data to be written\r
199 //! \param flash_ptr is the pointer into which to write the data\r
200 //! \param count number of times to write the value\r
201 //!\r
202 //! \return None\r
203 //\r
204 //*****************************************************************************\r
205 void FLASH_write8(uint8_t *data_ptr,\r
206                   uint8_t *flash_ptr,\r
207                   uint16_t count\r
208                   )\r
209 {\r
210         //Clear Lock bit\r
211         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
212 \r
213         //Enable byte/word write mode\r
214         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + WRT;\r
215 \r
216         while (count > 0) {\r
217                 //test busy\r
218                 while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
219 \r
220                 //Write to Flash\r
221                 *flash_ptr++ = *data_ptr++;\r
222                 count--;\r
223         }\r
224 \r
225         //Clear WRT bit\r
226         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
227 \r
228         //Set LOCK bit\r
229         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
230 }\r
231 \r
232 //*****************************************************************************\r
233 //\r
234 //! \brief Write data into the flash memory in 16-bit word format, pass by\r
235 //! reference\r
236 //!\r
237 //! This function writes a 16-bit word array of size count into flash memory.\r
238 //! Assumes the flash memory is already erased and unlocked. FLASH_segmentErase\r
239 //! can be used to erase a segment.\r
240 //!\r
241 //! \param data_ptr is the pointer to the data to be written\r
242 //! \param flash_ptr is the pointer into which to write the data\r
243 //! \param count number of times to write the value\r
244 //!\r
245 //! \return None\r
246 //\r
247 //*****************************************************************************\r
248 void FLASH_write16(uint16_t *data_ptr,\r
249                    uint16_t *flash_ptr,\r
250                    uint16_t count\r
251                    )\r
252 {\r
253         //Clear Lock bit\r
254         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
255 \r
256         //Enable byte/word write mode\r
257         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + WRT;\r
258 \r
259         while (count > 0) {\r
260                 //test busy\r
261                 while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
262 \r
263                 //Write to Flash\r
264                 *flash_ptr++ = *data_ptr++;\r
265                 count--;\r
266         }\r
267 \r
268         //Clear WRT bit\r
269         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
270 \r
271         //Set LOCK bit\r
272         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
273 }\r
274 \r
275 //*****************************************************************************\r
276 //\r
277 //! \brief Write data into the flash memory in 32-bit word format, pass by\r
278 //! reference\r
279 //!\r
280 //! This function writes a 32-bit array of size count into flash memory.\r
281 //! Assumes the flash memory is already erased and unlocked. FLASH_segmentErase\r
282 //! can be used to erase a segment.\r
283 //!\r
284 //! \param data_ptr is the pointer to the data to be written\r
285 //! \param flash_ptr is the pointer into which to write the data\r
286 //! \param count number of times to write the value\r
287 //!\r
288 //! \return None\r
289 //\r
290 //*****************************************************************************\r
291 void FLASH_write32(uint32_t *data_ptr,\r
292                    uint32_t *flash_ptr,\r
293                    uint16_t count\r
294                    )\r
295 {\r
296         //Clear Lock bit\r
297         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
298 \r
299         //Enable long-word write\r
300         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + BLKWRT;\r
301 \r
302         while (count > 0) {\r
303                 //test busy\r
304                 while (HWREG8(FLASH_BASE + OFS_FCTL3) & BUSY) ;\r
305 \r
306                 //Write to Flash\r
307                 *flash_ptr++ = *data_ptr++;\r
308 \r
309                 count--;\r
310         }\r
311 \r
312         //Clear BLKWRT bit\r
313         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
314 \r
315         //Set LOCK bit\r
316         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
317 }\r
318 \r
319 //*****************************************************************************\r
320 //\r
321 //! \brief Write data into the flash memory in 32-bit word format, pass by\r
322 //! value\r
323 //!\r
324 //! This function writes a 32-bit data value into flash memory, count times.\r
325 //! Assumes the flash memory is already erased and unlocked. FLASH_segmentErase\r
326 //! can be used to erase a segment.\r
327 //!\r
328 //! \param value value to fill memory with\r
329 //! \param flash_ptr is the pointer into which to write the data\r
330 //! \param count number of times to write the value\r
331 //!\r
332 //! \return None\r
333 //\r
334 //*****************************************************************************\r
335 void FLASH_memoryFill32(uint32_t value,\r
336                         uint32_t *flash_ptr,\r
337                         uint16_t count\r
338                         )\r
339 {\r
340         //Clear Lock bit\r
341         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY;\r
342 \r
343         //Enable long-word write\r
344         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY + BLKWRT;\r
345 \r
346         //test busy\r
347         while (count > 0) {\r
348                 while ((HWREG8(FLASH_BASE + OFS_FCTL3)) & BUSY) ;\r
349 \r
350                 //Write to Flash\r
351                 *flash_ptr++ = value;\r
352 \r
353                 count--;\r
354         }\r
355 \r
356         //Clear BLKWRT bit\r
357         HWREG16(FLASH_BASE + OFS_FCTL1) = FWKEY;\r
358 \r
359         //Set LOCK bit\r
360         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY + LOCK;\r
361 }\r
362 \r
363 //*****************************************************************************\r
364 //\r
365 //! \brief Check FLASH status to see if it is currently busy erasing or\r
366 //! programming\r
367 //!\r
368 //! This function checks the status register to determine if the flash memory\r
369 //! is ready for writing.\r
370 //!\r
371 //! \param mask FLASH status to read\r
372 //!        Mask value is the logical OR of any of the following:\r
373 //!        - \b FLASH_READY_FOR_NEXT_WRITE\r
374 //!        - \b FLASH_ACCESS_VIOLATION_INTERRUPT_FLAG\r
375 //!        - \b FLASH_PASSWORD_WRITTEN_INCORRECTLY\r
376 //!        - \b FLASH_BUSY\r
377 //!\r
378 //! \return Logical OR of any of the following:\r
379 //!         - \b FLASH_READY_FOR_NEXT_WRITE\r
380 //!         - \b FLASH_ACCESS_VIOLATION_INTERRUPT_FLAG\r
381 //!         - \b FLASH_PASSWORD_WRITTEN_INCORRECTLY\r
382 //!         - \b FLASH_BUSY\r
383 //!         \n indicating the status of the FLASH\r
384 //\r
385 //*****************************************************************************\r
386 uint8_t FLASH_status(uint8_t mask\r
387                      )\r
388 {\r
389         return (HWREG8(FLASH_BASE + OFS_FCTL3) & mask );\r
390 }\r
391 \r
392 //*****************************************************************************\r
393 //\r
394 //! \brief Locks the information flash memory segment A\r
395 //!\r
396 //! This function is typically called after an erase or write operation on the\r
397 //! information flash segment is performed by any of the other API functions in\r
398 //! order to re-lock the information flash segment.\r
399 //!\r
400 //!\r
401 //! \return None\r
402 //\r
403 //*****************************************************************************\r
404 void FLASH_lockInfoA(void)\r
405 {\r
406         //Disable global interrupts while doing RMW operation on LOCKA bit\r
407         uint16_t gieStatus;\r
408 \r
409         gieStatus = __get_SR_register() & GIE;          //Store current SR register\r
410         __disable_interrupt();                          //Disable global interrupt\r
411 \r
412         //Set the LOCKA bit in FCTL3.\r
413         //Since LOCKA toggles when you write a 1 (and writing 0 has no effect),\r
414         //read the register, XOR with LOCKA mask, mask the lower byte\r
415         //and write it back.\r
416         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY\r
417                                           + ((HWREG16(FLASH_BASE + OFS_FCTL3) ^ LOCKA) & 0xFF);\r
418 \r
419         //Reinstate SR register to restore global interrupt enable status\r
420         __bis_SR_register(gieStatus);\r
421 }\r
422 \r
423 //*****************************************************************************\r
424 //\r
425 //! \brief Unlocks the information flash memory segment A\r
426 //!\r
427 //! This function must be called before an erase or write operation on the\r
428 //! information flash segment is performed by any of the other API functions.\r
429 //!\r
430 //!\r
431 //! \return None\r
432 //\r
433 //*****************************************************************************\r
434 void FLASH_unlockInfoA(void)\r
435 {\r
436         //Disable global interrupts while doing RMW operation on LOCKA bit\r
437         uint16_t gieStatus;\r
438 \r
439         gieStatus = __get_SR_register() & GIE;          //Store current SR register\r
440         __disable_interrupt();                          //Disable global interrupt\r
441 \r
442         //Clear the LOCKA bit in FCTL3.\r
443         //Since LOCKA toggles when you write a 1 (and writing 0 has no effect),\r
444         //read the register, mask the lower byte, and write it back.\r
445         HWREG16(FLASH_BASE + OFS_FCTL3) = FWKEY\r
446                                           + (HWREG16(FLASH_BASE + OFS_FCTL3) & 0xFF);\r
447 \r
448         //Reinstate SR register to restore global interrupt enable status\r
449         __bis_SR_register(gieStatus);\r
450 }\r
451 \r
452 \r
453 #endif\r
454 #endif\r
455 //*****************************************************************************\r
456 //\r
457 //! Close the doxygen group for flash_api\r
458 //! @}\r
459 //\r
460 //*****************************************************************************\r