1 /* --COPYRIGHT--,BSD
2 * Copyright (c) 2017, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * --/COPYRIGHT--*/
32 /* Standard Includes */
33 #include <stdint.h>
34
35 /* DriverLib Includes */
36 #include <ti/devices/msp432p4xx/driverlib/flash_a.h>
37 #include <ti/devices/msp432p4xx/driverlib/debug.h>
38 #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
39 #include <ti/devices/msp432p4xx/inc/msp.h>
40 #include <ti/devices/msp432p4xx/driverlib/cpu.h>
41 #include <ti/devices/msp432p4xx/driverlib/sysctl_a.h>
42
43 /* Define to ensure that our current MSP432 has the FLCTL_A module. This
44 definition is included in the device specific header file */
45 #ifdef __MCU_HAS_FLCTL_A__
46
47 static const uint32_t MAX_ERASE_NO_TLV = 50;
48 static const uint32_t MAX_PROGRAM_NO_TLV = 5;
49
50 static const uint32_t __getBurstProgramRegs[16] =
51 { (uint32_t)&FLCTL_A->PRGBRST_DATA0_0, (uint32_t)&FLCTL_A->PRGBRST_DATA0_1,
52 (uint32_t) &FLCTL_A->PRGBRST_DATA0_2, (uint32_t)&FLCTL_A->PRGBRST_DATA0_3,
53 (uint32_t)&FLCTL_A->PRGBRST_DATA1_0,(uint32_t) &FLCTL_A->PRGBRST_DATA1_1,
54 (uint32_t)&FLCTL_A->PRGBRST_DATA1_2, (uint32_t)&FLCTL_A->PRGBRST_DATA1_3,
55 (uint32_t) &FLCTL_A->PRGBRST_DATA2_0, (uint32_t)&FLCTL_A->PRGBRST_DATA2_1,
56 (uint32_t)&FLCTL_A->PRGBRST_DATA2_2,(uint32_t) &FLCTL_A->PRGBRST_DATA2_3,
57 (uint32_t) &FLCTL_A->PRGBRST_DATA3_0,(uint32_t) &FLCTL_A->PRGBRST_DATA3_1,
58 (uint32_t) &FLCTL_A->PRGBRST_DATA3_2,(uint32_t) &FLCTL_A->PRGBRST_DATA3_3 };
59
__saveProtectionRegisters(__FlashCtl_ProtectionRegister * pReg)60 static void __saveProtectionRegisters(__FlashCtl_ProtectionRegister *pReg)
61 {
62 pReg->B0_INFO_R0 = FLCTL_A->BANK0_INFO_WEPROT;
63 pReg->B1_INFO_R0 = FLCTL_A->BANK1_INFO_WEPROT;
64 pReg->B0_MAIN_R0 = FLCTL_A->BANK0_MAIN_WEPROT0;
65 pReg->B0_MAIN_R1 = FLCTL_A->BANK0_MAIN_WEPROT1;
66 pReg->B0_MAIN_R2 = FLCTL_A->BANK0_MAIN_WEPROT2;
67 pReg->B0_MAIN_R3 = FLCTL_A->BANK0_MAIN_WEPROT3;
68 pReg->B0_MAIN_R4 = FLCTL_A->BANK0_MAIN_WEPROT4;
69 pReg->B0_MAIN_R5 = FLCTL_A->BANK0_MAIN_WEPROT5;
70 pReg->B0_MAIN_R6 = FLCTL_A->BANK0_MAIN_WEPROT6;
71 pReg->B0_MAIN_R7 = FLCTL_A->BANK0_MAIN_WEPROT7;
72 pReg->B1_MAIN_R0 = FLCTL_A->BANK1_MAIN_WEPROT0;
73 pReg->B1_MAIN_R1 = FLCTL_A->BANK1_MAIN_WEPROT1;
74 pReg->B1_MAIN_R2 = FLCTL_A->BANK1_MAIN_WEPROT2;
75 pReg->B1_MAIN_R3 = FLCTL_A->BANK1_MAIN_WEPROT3;
76 pReg->B1_MAIN_R4 = FLCTL_A->BANK1_MAIN_WEPROT4;
77 pReg->B1_MAIN_R5 = FLCTL_A->BANK1_MAIN_WEPROT5;
78 pReg->B1_MAIN_R6 = FLCTL_A->BANK1_MAIN_WEPROT6;
79 pReg->B1_MAIN_R7 = FLCTL_A->BANK1_MAIN_WEPROT7;
80 }
81
__restoreProtectionRegisters(__FlashCtl_ProtectionRegister * pReg)82 static void __restoreProtectionRegisters(__FlashCtl_ProtectionRegister *pReg)
83 {
84 FLCTL_A->BANK0_INFO_WEPROT = pReg->B0_INFO_R0;
85 FLCTL_A->BANK1_INFO_WEPROT = pReg->B1_INFO_R0;
86 FLCTL_A->BANK0_MAIN_WEPROT0 = pReg->B0_MAIN_R0;
87 FLCTL_A->BANK0_MAIN_WEPROT1 = pReg->B0_MAIN_R1;
88 FLCTL_A->BANK0_MAIN_WEPROT2 = pReg->B0_MAIN_R2;
89 FLCTL_A->BANK0_MAIN_WEPROT3 = pReg->B0_MAIN_R3;
90 FLCTL_A->BANK0_MAIN_WEPROT4 = pReg->B0_MAIN_R4;
91 FLCTL_A->BANK0_MAIN_WEPROT5 = pReg->B0_MAIN_R5;
92 FLCTL_A->BANK0_MAIN_WEPROT6 = pReg->B0_MAIN_R6;
93 FLCTL_A->BANK0_MAIN_WEPROT7 = pReg->B0_MAIN_R7;
94 FLCTL_A->BANK1_MAIN_WEPROT0 = pReg->B1_MAIN_R0;
95 FLCTL_A->BANK1_MAIN_WEPROT1 = pReg->B1_MAIN_R1;
96 FLCTL_A->BANK1_MAIN_WEPROT2 = pReg->B1_MAIN_R2;
97 FLCTL_A->BANK1_MAIN_WEPROT3 = pReg->B1_MAIN_R3;
98 FLCTL_A->BANK1_MAIN_WEPROT4 = pReg->B1_MAIN_R4;
99 FLCTL_A->BANK1_MAIN_WEPROT5 = pReg->B1_MAIN_R5;
100 FLCTL_A->BANK1_MAIN_WEPROT6 = pReg->B1_MAIN_R6;
101 FLCTL_A->BANK1_MAIN_WEPROT7 = pReg->B1_MAIN_R7;
102 }
103
FlashCtl_A_getMemoryInfo(uint32_t addr,uint32_t * bankNum,uint32_t * sectorNum)104 void FlashCtl_A_getMemoryInfo(uint32_t addr, uint32_t *bankNum,
105 uint32_t *sectorNum)
106 {
107 uint32_t bankLimit;
108
109 bankLimit = SysCtl_A_getFlashSize() / 2;
110
111 if (addr > bankLimit)
112 {
113 *(bankNum) = FLASH_A_BANK1;
114 addr = (addr - bankLimit);
115 } else
116 {
117 *(bankNum) = FLASH_A_BANK0;
118 }
119
120 *(sectorNum) = (addr) / FLASH_A_SECTOR_SIZE;
121 }
122
_FlashCtl_A_Program8(uint32_t src,uint32_t dest,uint32_t mTries)123 static bool _FlashCtl_A_Program8(uint32_t src, uint32_t dest, uint32_t mTries)
124 {
125 uint32_t ii;
126 uint8_t data;
127
128 /* Enabling the correct verification settings */
129 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST);
130 FlashCtl_A_clearProgramVerification(FLASH_A_BURSTPOST | FLASH_A_BURSTPRE);
131
132 data = HWREG8(src);
133
134 for (ii = 0; ii < mTries; ii++)
135 {
136 /* Clearing flags */
137 FLCTL_A->CLRIFG |= (FLASH_A_PROGRAM_ERROR | FLASH_A_POSTVERIFY_FAILED
138 | FLASH_A_PREVERIFY_FAILED | FLASH_A_WRDPRGM_COMPLETE);
139
140 HWREG8(dest) = data;
141
142 while (!(FlashCtl_A_getInterruptStatus() & FLASH_A_WRDPRGM_COMPLETE))
143 {
144 __no_operation();
145 }
146
147 /* Pre-Verify */
148 if ((BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS)
149 && BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPRE_OFS)))
150 {
151 data = __FlashCtl_A_remaskData8Pre(data, dest);
152
153 if (data != 0xFF)
154 {
155 FlashCtl_A_clearProgramVerification(FLASH_A_REGPRE);
156 continue;
157 }
158
159 }
160
161 /* Post Verify */
162 if ((BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPST_OFS)))
163 {
164 data = __FlashCtl_A_remaskData8Post(data, dest);
165
166 /* Seeing if we actually need to do another pulse */
167 if (data == 0xFF)
168 return true;
169
170 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST);
171 continue;
172 }
173
174 /* If we got this far, return true */
175 return true;
176
177 }
178
179 return false;
180
181 }
182
_FlashCtl_A_Program32(uint32_t src,uint32_t dest,uint32_t mTries)183 static bool _FlashCtl_A_Program32(uint32_t src, uint32_t dest, uint32_t mTries)
184 {
185 uint32_t ii;
186 uint32_t data;
187
188 /* Enabling the correct verification settings */
189 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST);
190 FlashCtl_A_clearProgramVerification(FLASH_A_BURSTPOST | FLASH_A_BURSTPRE);
191
192 data = HWREG32(src);
193
194 for (ii = 0; ii < mTries; ii++)
195 {
196 /* Clearing flags */
197 FLCTL_A->CLRIFG |= (FLASH_A_PROGRAM_ERROR | FLASH_A_POSTVERIFY_FAILED
198 | FLASH_A_PREVERIFY_FAILED | FLASH_A_WRDPRGM_COMPLETE);
199
200 HWREG32(dest) = data;
201
202 while (!(FlashCtl_A_getInterruptStatus() & FLASH_A_WRDPRGM_COMPLETE))
203 {
204 __no_operation();
205 }
206
207 /* Pre-Verify */
208 if ((BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS)
209 && BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPRE_OFS)))
210 {
211 data = __FlashCtl_A_remaskData32Pre(data, dest);
212
213 if (data != 0xFFFFFFFF)
214 {
215
216 FlashCtl_A_clearProgramVerification(FLASH_A_REGPRE);
217 continue;
218 }
219
220 }
221
222 /* Post Verify */
223 if ((BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPST_OFS)))
224 {
225 data = __FlashCtl_A_remaskData32Post(data, dest);
226
227 /* Seeing if we actually need to do another pulse */
228 if (data == 0xFFFFFFFF)
229 return true;
230
231 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST);
232 continue;
233 }
234
235 /* If we got this far, return true */
236 return true;
237
238 }
239
240 return false;
241
242 }
243
_FlashCtl_A_ProgramBurst(uint32_t src,uint32_t dest,uint32_t length,uint32_t mTries)244 static bool _FlashCtl_A_ProgramBurst(uint32_t src, uint32_t dest,
245 uint32_t length, uint32_t mTries)
246 {
247 uint32_t bCalc, otpOffset, ii, jj;
248 bool res;
249
250 /* Setting verification */
251 FlashCtl_A_clearProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST);
252 FlashCtl_A_setProgramVerification(FLASH_A_BURSTPOST | FLASH_A_BURSTPRE);
253
254 /* Assume Failure */
255 res = false;
256
257 /* Waiting for idle status */
258 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
259 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
260 {
261 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
262 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
263 }
264
265 /* Setting/clearing INFO flash flags as appropriate */
266 if (dest >= SysCtl_A_getFlashSize())
267 {
268 FLCTL_A->PRGBRST_CTLSTAT = (FLCTL_A->PRGBRST_CTLSTAT
269 & ~FLCTL_A_PRGBRST_CTLSTAT_TYPE_MASK)
270 | FLCTL_A_PRGBRST_CTLSTAT_TYPE_1;
271 otpOffset = __INFO_FLASH_A_TECH_START__;
272 } else
273 {
274 FLCTL_A->PRGBRST_CTLSTAT = (FLCTL_A->PRGBRST_CTLSTAT
275 & ~FLCTL_A_PRGBRST_CTLSTAT_TYPE_MASK)
276 | FLCTL_A_PRGBRST_CTLSTAT_TYPE_0;
277 otpOffset = 0;
278 }
279
280 bCalc = 0;
281 FLCTL_A->PRGBRST_STARTADDR = (dest - otpOffset);
282
283 /* Initially populating the burst registers */
284 while (bCalc < 16 && length != 0)
285 {
286 HWREG32(__getBurstProgramRegs[bCalc]) = HWREG32(src);
287 bCalc++;
288 length -= 4;
289 src += 4;
290 }
291
292 for (ii = 0; ii < mTries; ii++)
293 {
294 /* Clearing Flags */
295 FLCTL_A->CLRIFG |= (FLASH_A_BRSTPRGM_COMPLETE
296 | FLASH_A_POSTVERIFY_FAILED | FLASH_A_PREVERIFY_FAILED);
297
298 /* Waiting for idle status */
299 while ((FLCTL_A->PRGBRST_CTLSTAT
300 & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
301 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
302 {
303 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
304 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
305 }
306
307 /* Start the burst program */
308 FLCTL_A->PRGBRST_CTLSTAT = (FLCTL_A->PRGBRST_CTLSTAT
309 & ~(FLCTL_A_PRGBRST_CTLSTAT_LEN_MASK))
310 | ((bCalc / 4) << FLASH_A_BURST_PRG_BIT)
311 | FLCTL_A_PRGBRST_CTLSTAT_START;
312
313 /* Waiting for the burst to complete */
314 while ((FLCTL_A->PRGBRST_CTLSTAT
315 & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
316 != FLASH_A_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE)
317 {
318 __no_operation();
319 }
320
321 /* Checking for errors and clearing/masking */
322
323 /* Address Error */
324 if (BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
325 FLCTL_A_PRGBRST_CTLSTAT_ADDR_ERR_OFS))
326 {
327 goto BurstCleanUp;
328 }
329
330 /* Pre-Verify Error */
331 if (BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
332 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS)
333 && BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
334 FLCTL_A_PRGBRST_CTLSTAT_PRE_ERR_OFS))
335 {
336 __FlashCtl_A_remaskBurstDataPre(dest, bCalc * 4);
337
338 for (jj = 0; jj < bCalc; jj++)
339 {
340 if (HWREG32(__getBurstProgramRegs[jj]) != 0xFFFFFFFF)
341 {
342 FlashCtl_A_clearProgramVerification(FLASH_A_BURSTPRE);
343 break;
344 }
345 }
346
347 if (jj != bCalc)
348 continue;
349 }
350
351 /* Post-Verify Error */
352 if (BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
353 FLCTL_A_PRGBRST_CTLSTAT_PST_ERR_OFS))
354 {
355 __FlashCtl_A_remaskBurstDataPost(dest, bCalc * 4);
356
357 for (jj = 0; jj < bCalc; jj++)
358 {
359 if ((HWREG32(__getBurstProgramRegs[jj])) != 0xFFFFFFFF)
360 {
361 FlashCtl_A_setProgramVerification(
362 FLASH_A_BURSTPOST | FLASH_A_BURSTPRE);
363 break;
364 }
365 }
366
367 if (jj != bCalc)
368 continue;
369
370 }
371
372 /* If we got this far, the program happened */
373 res = true;
374 goto BurstCleanUp;
375 }
376
377 BurstCleanUp:
378 /* Waiting for idle status */
379 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
380 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
381 {
382 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
383 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
384 }
385 return res;
386 }
387
FlashCtl_A_enableReadBuffering(uint_fast8_t memoryBank,uint_fast8_t accessMethod)388 void FlashCtl_A_enableReadBuffering(uint_fast8_t memoryBank,
389 uint_fast8_t accessMethod)
390 {
391 if (memoryBank == FLASH_A_BANK0 && accessMethod == FLASH_A_DATA_READ)
392 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFD_OFS) = 1;
393 else if (memoryBank == FLASH_A_BANK1 && accessMethod == FLASH_A_DATA_READ)
394 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFD_OFS) = 1;
395 else if (memoryBank == FLASH_A_BANK0
396 && accessMethod == FLASH_A_INSTRUCTION_FETCH)
397 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFI_OFS) = 1;
398 else if (memoryBank == FLASH_A_BANK1
399 && accessMethod == FLASH_A_INSTRUCTION_FETCH)
400 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFI_OFS) = 1;
401 else
402 ASSERT(false);
403 }
404
FlashCtl_A_disableReadBuffering(uint_fast8_t memoryBank,uint_fast8_t accessMethod)405 void FlashCtl_A_disableReadBuffering(uint_fast8_t memoryBank,
406 uint_fast8_t accessMethod)
407 {
408 if (memoryBank == FLASH_A_BANK0 && accessMethod == FLASH_A_DATA_READ)
409 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFD_OFS) = 0;
410 else if (memoryBank == FLASH_A_BANK1 && accessMethod == FLASH_A_DATA_READ)
411 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFD_OFS) = 0;
412 else if (memoryBank == FLASH_A_BANK0
413 && accessMethod == FLASH_A_INSTRUCTION_FETCH)
414 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFI_OFS) = 0;
415 else if (memoryBank == FLASH_A_BANK1
416 && accessMethod == FLASH_A_INSTRUCTION_FETCH)
417 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFI_OFS) = 0;
418 else
419 ASSERT(false);
420 }
421
FlashCtl_A_isMemoryProtected(uint32_t addr)422 bool FlashCtl_A_isMemoryProtected(uint32_t addr)
423 {
424 volatile uint32_t *configRegister;
425 uint32_t memoryBit, cutOffMemory;
426
427 if (addr >= SysCtl_A_getFlashSize())
428 {
429 cutOffMemory = (SysCtl_A_getInfoFlashSize() >> 1) + __INFO_FLASH_A_TECH_START__;
430
431 if (addr < cutOffMemory)
432 {
433 memoryBit = (addr - __INFO_FLASH_A_TECH_START__)
434 / FLASH_A_SECTOR_SIZE;
435 configRegister = &FLCTL_A->BANK0_INFO_WEPROT
436 + ((memoryBit >> 5));
437 memoryBit &= 0x1F;
438 } else
439 {
440 memoryBit = (addr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
441 configRegister = &FLCTL_A->BANK1_INFO_WEPROT
442 + ((memoryBit >> 5));
443 memoryBit &= 0x1F;
444 }
445 } else
446 {
447 cutOffMemory = SysCtl_A_getFlashSize() >> 1;
448
449 if (addr < cutOffMemory)
450 {
451 memoryBit = addr / FLASH_A_SECTOR_SIZE;
452 configRegister = &FLCTL_A->BANK0_MAIN_WEPROT0
453 + ((memoryBit >> 5));
454 memoryBit &= 0x1F;
455 } else
456 {
457 memoryBit = (addr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
458 configRegister = &FLCTL_A->BANK1_MAIN_WEPROT0
459 + ((memoryBit >> 5));
460 memoryBit &= 0x1F;
461 }
462 }
463
464 return (*configRegister & (1 << memoryBit));
465 }
466
FlashCtl_A_isMemoryRangeProtected(uint32_t startAddr,uint32_t endAddr)467 bool FlashCtl_A_isMemoryRangeProtected(uint32_t startAddr, uint32_t endAddr)
468 {
469 uint32_t ii;
470
471 if (startAddr > endAddr)
472 return false;
473
474 startAddr = (startAddr & 0xFFFFF000);
475 endAddr = (endAddr & 0xFFFFF000);
476
477 for (ii = startAddr; ii <= endAddr; ii+=FLASH_A_SECTOR_SIZE)
478 {
479 if (!FlashCtl_A_isMemoryProtected(ii))
480 return false;
481 }
482 return true;
483 }
484
FlashCtl_A_unprotectMemory(uint32_t startAddr,uint32_t endAddr)485 bool FlashCtl_A_unprotectMemory(uint32_t startAddr, uint32_t endAddr)
486 {
487 uint32_t startBankBit, endBankBit, cutOffMemory;
488 volatile uint32_t* baseStartConfig, *baseEndConfig;
489
490 if (startAddr > endAddr)
491 return false;
492
493 if (endAddr >= SysCtl_A_getFlashSize())
494 {
495 cutOffMemory = (SysCtl_A_getInfoFlashSize() >> 1)
496 + __INFO_FLASH_A_TECH_START__;
497
498 if (endAddr < cutOffMemory && startAddr < cutOffMemory)
499 {
500 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__)
501 / FLASH_A_SECTOR_SIZE;
502 endBankBit = (endAddr - __INFO_FLASH_A_TECH_START__)
503 / FLASH_A_SECTOR_SIZE;
504 FLCTL_A->BANK0_INFO_WEPROT &= ~(0xFFFFFFFF >> (31 - endBankBit))
505 & (0xFFFFFFFF << startBankBit);
506 } else if (endAddr > cutOffMemory && startAddr > cutOffMemory)
507 {
508 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
509 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
510 FLCTL_A->BANK1_INFO_WEPROT &= ~((0xFFFFFFFF >> (31 - endBankBit))
511 & (0xFFFFFFFF << startBankBit));
512 } else
513 {
514 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__)
515 / FLASH_A_SECTOR_SIZE;
516 endBankBit = (endAddr - cutOffMemory)/FLASH_A_SECTOR_SIZE;
517 FLCTL_A->BANK0_INFO_WEPROT &= ~(0xFFFFFFFF << startBankBit) & 0xF;
518 FLCTL_A->BANK1_INFO_WEPROT &= ~(0xFFFFFFFF >> (31 - (endBankBit))) & 0xF;
519 }
520
521 return true;
522
523 } else
524 {
525 cutOffMemory = SysCtl_A_getFlashSize() >> 1;
526
527 if (endAddr < cutOffMemory)
528 {
529 endBankBit = endAddr / FLASH_A_SECTOR_SIZE;
530 baseEndConfig = &FLCTL_A->BANK0_MAIN_WEPROT0
531 + ((endBankBit >> 5));
532 endBankBit &= 0x1F;
533 } else
534 {
535 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
536 baseEndConfig = &FLCTL_A->BANK1_MAIN_WEPROT0
537 + (endBankBit >> 5);
538 endBankBit &= 0x1F;
539 }
540
541 if (startAddr < cutOffMemory)
542 {
543 startBankBit = (startAddr / FLASH_A_SECTOR_SIZE);
544 baseStartConfig = &FLCTL_A->BANK0_MAIN_WEPROT0
545 + (startBankBit >> 5);
546 startBankBit &= 0x1F;
547 } else
548 {
549 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
550 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0
551 + (startBankBit >> 5);
552 startBankBit &= 0x1F;
553 }
554
555 if (baseStartConfig == baseEndConfig)
556 {
557 (*baseStartConfig) &= ~((0xFFFFFFFF >> (31 - endBankBit))
558 & (0xFFFFFFFF << startBankBit));
559 return true;
560 }
561
562 *baseStartConfig &= ~(0xFFFFFFFF << startBankBit);
563
564 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7)
565 {
566 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0;
567 } else
568 {
569 baseStartConfig++;
570 }
571
572 while (baseStartConfig != baseEndConfig)
573 {
574 *baseStartConfig = 0;
575
576 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7)
577 {
578 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0;
579 } else
580 {
581 baseStartConfig++;
582 }
583 }
584
585 (*baseEndConfig) &= ~(0xFFFFFFFF >> (31 - (endBankBit)));
586 }
587
588 return true;
589
590 }
591
FlashCtl_A_protectMemory(uint32_t startAddr,uint32_t endAddr)592 bool FlashCtl_A_protectMemory(uint32_t startAddr, uint32_t endAddr)
593 {
594 uint32_t startBankBit, endBankBit, cutOffMemory;
595 volatile uint32_t* baseStartConfig, *baseEndConfig;
596
597 if (startAddr > endAddr)
598 return false;
599
600 if (endAddr >= SysCtl_A_getFlashSize())
601 {
602 cutOffMemory = (SysCtl_A_getInfoFlashSize() >> 1)
603 + __INFO_FLASH_A_TECH_START__;
604
605 if (endAddr < cutOffMemory && startAddr < cutOffMemory)
606 {
607 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__)
608 / FLASH_A_SECTOR_SIZE;
609 endBankBit = (endAddr - __INFO_FLASH_A_TECH_START__)
610 / FLASH_A_SECTOR_SIZE;
611 FLCTL_A->BANK0_INFO_WEPROT |= (0xFFFFFFFF >> (31 - endBankBit))
612 & (0xFFFFFFFF << startBankBit);
613 } else if (endAddr > cutOffMemory && startAddr > cutOffMemory)
614 {
615 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
616 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
617 FLCTL_A->BANK1_INFO_WEPROT |= (0xFFFFFFFF >> (31 - endBankBit))
618 & (0xFFFFFFFF << startBankBit);
619 } else
620 {
621 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__)
622 / FLASH_A_SECTOR_SIZE;
623 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
624 FLCTL_A->BANK0_INFO_WEPROT |= (0xFFFFFFFF << startBankBit);
625 FLCTL_A->BANK1_INFO_WEPROT |= (0xFFFFFFFF >> (31 - (endBankBit)));
626 }
627
628 return true;
629
630 } else
631 {
632 cutOffMemory = SysCtl_A_getFlashSize() >> 1;
633
634 if (endAddr < cutOffMemory)
635 {
636 endBankBit = endAddr / FLASH_A_SECTOR_SIZE;
637 baseEndConfig = &FLCTL_A->BANK0_MAIN_WEPROT0
638 + ((endBankBit >> 5));
639 endBankBit &= 0x1F;
640 } else
641 {
642 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
643 baseEndConfig = &FLCTL_A->BANK1_MAIN_WEPROT0
644 + (endBankBit >> 5);
645 endBankBit &= 0x1F;
646 }
647
648 if (startAddr < cutOffMemory)
649 {
650 startBankBit = (startAddr / FLASH_A_SECTOR_SIZE);
651 baseStartConfig = &FLCTL_A->BANK0_MAIN_WEPROT0
652 + (startBankBit >> 5);
653 startBankBit &= 0x1F;
654 } else
655 {
656 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE;
657 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0
658 + (startBankBit >> 5);
659 startBankBit &= 0x1F;
660 }
661
662 if (baseStartConfig == baseEndConfig)
663 {
664 (*baseStartConfig) |= (0xFFFFFFFF >> (31 - endBankBit))
665 & (0xFFFFFFFF << startBankBit);
666 return true;
667 }
668
669 *baseStartConfig |= (0xFFFFFFFF << startBankBit);
670
671 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7)
672 {
673 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0;
674 } else
675 {
676 baseStartConfig++;
677 }
678
679 while (baseStartConfig != baseEndConfig)
680 {
681 *baseStartConfig = 0xFFFFFFFF;
682
683 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7)
684 {
685 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0;
686 } else
687 {
688 baseStartConfig++;
689 }
690 }
691
692 (*baseEndConfig) |= (0xFFFFFFFF >> (31 - (endBankBit)));
693 }
694
695 return true;
696
697 }
698
FlashCtl_A_verifyMemory(void * verifyAddr,uint32_t length,uint_fast8_t pattern)699 bool FlashCtl_A_verifyMemory(void* verifyAddr, uint32_t length,
700 uint_fast8_t pattern)
701 {
702 uint32_t memoryPattern, addr, otpOffset;
703 uint32_t b0WaitState, b1WaitState, intStatus;
704 uint32_t bankOneStart, startBank, endBank;
705 uint_fast8_t b0readMode, b1readMode;
706 uint_fast8_t memoryType;
707 bool res;
708
709 ASSERT(pattern == FLASH_A_0_PATTERN || pattern == FLASH_A_1_PATTERN);
710
711 /* Saving interrupt context and disabling interrupts for program
712 * operation
713 */
714 intStatus = CPU_primask();
715 Interrupt_disableMaster();
716
717 /* Casting and determining the memory that we need to use */
718 addr = (uint32_t) verifyAddr;
719 memoryType = (addr >= SysCtl_A_getFlashSize()) ?
720 FLASH_A_INFO_SPACE :
721 FLASH_A_MAIN_SPACE;
722
723 /* Assuming Failure */
724 res = false;
725
726 /* Finding out which bank we are in */
727 if (addr >= SysCtl_A_getFlashSize())
728 {
729 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__;
730 } else
731 {
732 bankOneStart = SysCtl_A_getFlashSize() / 2;
733 }
734 startBank = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1;
735 endBank = (addr + length) < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1;
736
737 /* Saving context and changing read modes */
738 b0WaitState = FlashCtl_A_getWaitState(startBank);
739 b0readMode = FlashCtl_A_getReadMode(startBank);
740
741 /* Setting the wait state to account for the mode */
742 FlashCtl_A_setWaitState(startBank, (2 * b0WaitState) + 1);
743
744 if (startBank != endBank)
745 {
746 b1WaitState = FlashCtl_A_getWaitState(endBank);
747 b1readMode = FlashCtl_A_getReadMode(endBank);
748 FlashCtl_A_setWaitState(endBank, (2 * b1WaitState) + 1);
749 }
750
751 /* Changing to the relevant VERIFY mode */
752 if (pattern == FLASH_A_1_PATTERN)
753 {
754 FlashCtl_A_setReadMode(startBank, FLASH_A_ERASE_VERIFY_READ_MODE);
755
756 if (startBank != endBank)
757 {
758 FlashCtl_A_setReadMode(endBank, FLASH_A_ERASE_VERIFY_READ_MODE);
759 }
760
761 memoryPattern = 0xFFFFFFFF;
762 } else
763 {
764 FlashCtl_A_setReadMode(startBank, FLASH_A_PROGRAM_VERIFY_READ_MODE);
765
766 if (startBank != endBank)
767 {
768 FlashCtl_A_setReadMode(endBank, FLASH_A_PROGRAM_VERIFY_READ_MODE);
769 }
770
771 memoryPattern = 0;
772 }
773
774 /* Taking care of byte accesses */
775 while ((addr & 0x03) && (length > 0))
776 {
777 if (HWREG8(addr++) != ((uint8_t) memoryPattern))
778 goto FlashVerifyCleanup;
779 length--;
780 }
781
782 /* Making sure we are aligned by 128-bit address */
783 while (((addr & 0x0F)) && (length > 3))
784 {
785 if (HWREG32(addr) != memoryPattern)
786 goto FlashVerifyCleanup;
787
788 addr = addr + 4;
789 length = length - 4;
790 }
791
792 /* Burst Verify */
793 if (length > 63)
794 {
795 /* Setting/clearing INFO flash flags as appropriate */
796 if (addr >= SysCtl_A_getFlashSize())
797 {
798 FLCTL_A->RDBRST_CTLSTAT = (FLCTL_A->RDBRST_CTLSTAT
799 & ~FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_MASK)
800 | FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_1;
801 otpOffset = __INFO_FLASH_A_TECH_START__;
802 } else
803 {
804 FLCTL_A->RDBRST_CTLSTAT = (FLCTL_A->RDBRST_CTLSTAT
805 & ~FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_MASK)
806 | FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_0;
807 otpOffset = 0;
808 }
809
810 /* Clearing any lingering fault flags and preparing burst verify*/
811 BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT,
812 FLCTL_A_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
813 FLCTL_A->RDBRST_FAILCNT = 0;
814 FLCTL_A->RDBRST_STARTADDR = addr - otpOffset;
815 FLCTL_A->RDBRST_LEN = (length & 0xFFFFFFF0);
816 addr += FLCTL_A->RDBRST_LEN;
817 length = length & 0xF;
818
819 /* Starting Burst Verify */
820 FLCTL_A->RDBRST_CTLSTAT = (FLCTL_A_RDBRST_CTLSTAT_STOP_FAIL | pattern
821 | memoryType | FLCTL_A_RDBRST_CTLSTAT_START);
822
823 /* While the burst read hasn't finished */
824 while ((FLCTL_A->RDBRST_CTLSTAT & FLCTL_A_RDBRST_CTLSTAT_BRST_STAT_MASK)
825 != FLCTL_A_RDBRST_CTLSTAT_BRST_STAT_3)
826 {
827 __no_operation();
828 }
829
830 /* Checking for a verification/access error/failure */
831 if (BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT,
832 FLCTL_A_RDBRST_CTLSTAT_CMP_ERR_OFS)
833 || BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT,
834 FLCTL_A_RDBRST_CTLSTAT_ADDR_ERR_OFS)
835 || FLCTL_A->RDBRST_FAILCNT)
836 {
837 goto FlashVerifyCleanup;
838 }
839 }
840
841 /* Remaining Words */
842 while (length > 3)
843 {
844 if (HWREG32(addr) != memoryPattern)
845 goto FlashVerifyCleanup;
846
847 addr = addr + 4;
848 length = length - 4;
849 }
850
851 /* Remaining Bytes */
852 while (length > 0)
853 {
854 if (HWREG8(addr++) != ((uint8_t) memoryPattern))
855 goto FlashVerifyCleanup;
856 length--;
857 }
858
859 /* If we got this far, that means it no failure happened */
860 res = true;
861
862 FlashVerifyCleanup:
863
864 /* Clearing the Read Burst flag and returning */
865 BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT, FLCTL_A_RDBRST_CTLSTAT_CLR_STAT_OFS) =
866 1;
867
868 FlashCtl_A_setReadMode(startBank, b0readMode);
869 FlashCtl_A_setWaitState(startBank, b0WaitState);
870
871 if (startBank != endBank)
872 {
873 FlashCtl_A_setReadMode(endBank, b1readMode);
874 FlashCtl_A_setWaitState(endBank, b1WaitState);
875 }
876
877 if (intStatus == 0)
878 Interrupt_enableMaster();
879
880 return res;
881 }
882
FlashCtl_A_setReadMode(uint32_t flashBank,uint32_t readMode)883 bool FlashCtl_A_setReadMode(uint32_t flashBank, uint32_t readMode)
884 {
885
886 if (FLCTL_A->POWER_STAT & FLCTL_A_POWER_STAT_RD_2T)
887 return false;
888
889 if (flashBank == FLASH_A_BANK0)
890 {
891 FLCTL_A->BANK0_RDCTL = (FLCTL_A->BANK0_RDCTL
892 & ~FLCTL_A_BANK0_RDCTL_RD_MODE_MASK) | readMode;
893 while ((FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_RD_MODE_STATUS_MASK)
894 != (readMode<<16))
895 ;
896 } else if (flashBank == FLASH_A_BANK1)
897 {
898 FLCTL_A->BANK1_RDCTL = (FLCTL_A->BANK1_RDCTL
899 & ~FLCTL_A_BANK1_RDCTL_RD_MODE_MASK) | readMode;
900 while ((FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_RD_MODE_STATUS_MASK)
901 != (readMode<<16))
902 ;
903 } else
904 {
905 ASSERT(false);
906 return false;
907 }
908
909 return true;
910 }
911
FlashCtl_A_getReadMode(uint32_t flashBank)912 uint32_t FlashCtl_A_getReadMode(uint32_t flashBank)
913 {
914 if (flashBank == FLASH_A_BANK0)
915 {
916 return (FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_RD_MODE_STATUS_MASK)
917 >> 16;
918 } else if (flashBank == FLASH_A_BANK1)
919 {
920 return (FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_RD_MODE_STATUS_MASK)
921 >> 16;
922 } else
923 {
924 ASSERT(false);
925 return 0;
926 }
927 }
928
FlashCtl_A_initiateMassErase(void)929 void FlashCtl_A_initiateMassErase(void)
930 {
931 /* Clearing old mass erase flags */
932 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
933 1;
934
935 /* Performing the mass erase */
936 FLCTL_A->ERASE_CTLSTAT |= (FLCTL_A_ERASE_CTLSTAT_MODE
937 | FLCTL_A_ERASE_CTLSTAT_START);
938 }
939
FlashCtl_A_performMassErase(void)940 bool FlashCtl_A_performMassErase(void)
941 {
942 uint32_t flashSize, ii, intStatus, jj;
943 uint32_t mTries;
944 uint_fast8_t tlvLength;
945 SysCtl_A_FlashTLV_Info *flInfo;
946 __FlashCtl_ProtectionRegister protectRegs;
947 bool res, needAnotherPulse;
948
949 /* Parsing the TLV and getting the maximum erase pulses */
950 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
951
952 if (tlvLength == 0 || flInfo->maxErasePulses == 0)
953 {
954 mTries = MAX_ERASE_NO_TLV;
955 } else
956 {
957 mTries = flInfo->maxErasePulses;
958 }
959
960 /* Saving interrupt context and disabling interrupts for program
961 * operation
962 */
963 intStatus = CPU_primask();
964 Interrupt_disableMaster();
965
966 /* Assume Failure */
967 res = false;
968
969 /* Saving off protection settings so we can restore them later */
970 __saveProtectionRegisters(&protectRegs);
971
972 for(jj=0;jj<mTries;jj++)
973 {
974 needAnotherPulse = false;
975
976 /* Clearing old mass erase flags */
977 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
978 1;
979
980 /* Performing the mass erase */
981 FLCTL_A->ERASE_CTLSTAT |= (FLCTL_A_ERASE_CTLSTAT_MODE
982 | FLCTL_A_ERASE_CTLSTAT_START);
983
984 while ((FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
985 == FLCTL_A_ERASE_CTLSTAT_STATUS_1
986 || (FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
987 == FLCTL_A_ERASE_CTLSTAT_STATUS_2)
988 {
989 __no_operation();
990 }
991
992 /* Return false if an address error */
993 if (BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT,
994 FLCTL_A_ERASE_CTLSTAT_ADDR_ERR_OFS))
995 goto MassEraseCleanup;
996
997 /* Verifying the user memory that might have been erased */
998 flashSize = SysCtl_A_getFlashSize();
999
1000 /* Clearing old flag */
1001 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1002 1;
1003
1004 for (ii = 0; ii < flashSize; ii += FLASH_A_SECTOR_SIZE)
1005 {
1006 if (!FlashCtl_A_isMemoryProtected(ii))
1007 {
1008 if (!FlashCtl_A_verifyMemory((void*) ii, FLASH_A_SECTOR_SIZE,
1009 FLASH_A_1_PATTERN))
1010 {
1011 needAnotherPulse = true;
1012 }
1013 else
1014 {
1015 FlashCtl_A_protectMemory(ii,ii);
1016 }
1017 }
1018 }
1019
1020 /* Verifying the INFO memory that might be protected */
1021 flashSize = SysCtl_A_getInfoFlashSize() + __INFO_FLASH_A_TECH_START__;
1022
1023 for (ii = __INFO_FLASH_A_TECH_START__; ii < flashSize; ii +=
1024 FLASH_A_SECTOR_SIZE)
1025 {
1026 if (!FlashCtl_A_isMemoryProtected(ii))
1027 {
1028 if (!FlashCtl_A_verifyMemory((void*) ii, FLASH_A_SECTOR_SIZE,
1029 FLASH_A_1_PATTERN))
1030 {
1031 needAnotherPulse = true;
1032 }
1033 else
1034 {
1035 FlashCtl_A_protectMemory(ii,ii);
1036 }
1037 }
1038 }
1039
1040 if(!needAnotherPulse)
1041 {
1042 break;
1043 }
1044 }
1045
1046 /* If we got this far and didn't do the max number of tries,
1047 * the mass erase happened */
1048 if(jj != mTries)
1049 {
1050 res = true;
1051 }
1052
1053 MassEraseCleanup:
1054
1055 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT,
1056 FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
1057 __restoreProtectionRegisters(&protectRegs);
1058
1059 if (intStatus == 0)
1060 Interrupt_enableMaster();
1061
1062 return res;
1063 }
1064
FlashCtl_A_eraseSector(uint32_t addr)1065 bool FlashCtl_A_eraseSector(uint32_t addr)
1066 {
1067 uint_fast8_t memoryType, ii;
1068 uint32_t otpOffset = 0;
1069 uint32_t intStatus;
1070 uint_fast8_t mTries, tlvLength;
1071 SysCtl_A_FlashTLV_Info *flInfo;
1072 bool res;
1073
1074 /* Saving interrupt context and disabling interrupts for program
1075 * operation
1076 */
1077 intStatus = CPU_primask();
1078 Interrupt_disableMaster();
1079
1080 /* Assuming Failure */
1081 res = false;
1082
1083 memoryType = addr >= SysCtl_A_getFlashSize() ? FLASH_A_INFO_SPACE :
1084 FLASH_A_MAIN_SPACE;
1085
1086 /* Parsing the TLV and getting the maximum erase pulses */
1087 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
1088
1089 if (tlvLength == 0 || flInfo->maxErasePulses == 0)
1090 {
1091 mTries = MAX_ERASE_NO_TLV;
1092 } else
1093 {
1094 mTries = flInfo->maxErasePulses;
1095 }
1096
1097 /* We can only erase on 4KB boundaries */
1098 while (addr & 0xFFF)
1099 {
1100 addr--;
1101 }
1102
1103 /* Clearing the status */
1104 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1105 1;
1106
1107 if (memoryType == FLASH_A_INFO_SPACE)
1108 {
1109 otpOffset = __INFO_FLASH_A_TECH_START__;
1110 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1111 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1112 | FLCTL_A_ERASE_CTLSTAT_TYPE_1;
1113
1114 } else
1115 {
1116 otpOffset = 0;
1117 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1118 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1119 | FLCTL_A_ERASE_CTLSTAT_TYPE_0;
1120 }
1121
1122 /* Clearing old flags and setting up the erase */
1123 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_MODE_OFS) = 0;
1124 FLCTL_A->ERASE_SECTADDR = addr - otpOffset;
1125
1126 for (ii = 0; ii < mTries; ii++)
1127 {
1128 /* Clearing the status */
1129 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1130 1;
1131
1132 /* Starting the erase */
1133 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_START_OFS) =
1134 1;
1135
1136 while ((FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
1137 == FLCTL_A_ERASE_CTLSTAT_STATUS_1
1138 || (FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
1139 == FLCTL_A_ERASE_CTLSTAT_STATUS_2)
1140 {
1141 __no_operation();
1142 }
1143
1144 /* Return false if an address error */
1145 if (BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT,
1146 FLCTL_A_ERASE_CTLSTAT_ADDR_ERR_OFS))
1147 {
1148 goto SectorEraseCleanup;
1149 }
1150 /* Erase verifying */
1151 if (FlashCtl_A_verifyMemory((void*) addr, FLASH_A_SECTOR_SIZE,
1152 FLASH_A_1_PATTERN))
1153 {
1154 res = true;
1155 goto SectorEraseCleanup;
1156 }
1157
1158 }
1159
1160 SectorEraseCleanup:
1161
1162 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1163 1;
1164
1165 if (intStatus == 0)
1166 Interrupt_enableMaster();
1167
1168 return res;
1169 }
1170
FlashCtl_A_initiateSectorErase(uint32_t addr)1171 void FlashCtl_A_initiateSectorErase(uint32_t addr)
1172 {
1173 uint_fast8_t memoryType;
1174 uint32_t otpOffset = 0;
1175
1176 memoryType = addr >= SysCtl_A_getFlashSize() ?
1177 FLASH_A_INFO_SPACE :
1178 FLASH_A_MAIN_SPACE;
1179
1180 /* We can only erase on 4KB boundaries */
1181 while (addr & 0xFFF)
1182 {
1183 addr--;
1184 }
1185
1186 /* Clearing the status */
1187 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1188 1;
1189
1190 if (memoryType == FLASH_A_INFO_SPACE)
1191 {
1192 otpOffset = __INFO_FLASH_A_TECH_START__;
1193 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1194 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1195 | FLCTL_A_ERASE_CTLSTAT_TYPE_1;
1196
1197 } else
1198 {
1199 otpOffset = 0;
1200 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1201 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1202 | FLCTL_A_ERASE_CTLSTAT_TYPE_0;
1203 }
1204
1205 /* Clearing old flags and setting up the erase */
1206 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_MODE_OFS) = 0;
1207 FLCTL_A->ERASE_SECTADDR = addr - otpOffset;
1208
1209 /* Starting the erase */
1210 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_START_OFS) = 1;
1211
1212 }
1213
FlashCtl_A_programMemory(void * src,void * dest,uint32_t length)1214 bool FlashCtl_A_programMemory(void* src, void* dest, uint32_t length)
1215 {
1216 uint32_t destAddr, srcAddr, burstLength, intStatus;
1217 bool res;
1218 uint_fast8_t mTries, tlvLength;
1219 SysCtl_A_FlashTLV_Info *flInfo;
1220
1221 /* Saving interrupt context and disabling interrupts for program
1222 * operation
1223 */
1224 intStatus = CPU_primask();
1225 Interrupt_disableMaster();
1226
1227 /* Parsing the TLV and getting the maximum erase pulses */
1228 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
1229
1230 if (tlvLength == 0 || flInfo->maxProgramPulses == 0)
1231 {
1232 mTries = MAX_PROGRAM_NO_TLV;
1233 } else
1234 {
1235 mTries = flInfo->maxProgramPulses;
1236 }
1237
1238 /* Casting to integers */
1239 srcAddr = (uint32_t) src;
1240 destAddr = (uint32_t) dest;
1241
1242 /* Enabling word programming */
1243 FlashCtl_A_enableWordProgramming(FLASH_A_IMMEDIATE_WRITE_MODE);
1244
1245 /* Assume failure */
1246 res = false;
1247
1248 /* Taking care of byte accesses */
1249 while ((destAddr & 0x03) && length > 0)
1250 {
1251 if (!_FlashCtl_A_Program8(srcAddr, destAddr, mTries))
1252 {
1253 goto FlashProgramCleanUp;
1254 } else
1255 {
1256 srcAddr++;
1257 destAddr++;
1258 length--;
1259 }
1260 }
1261
1262 /* Taking care of word accesses */
1263 while ((destAddr & 0x0F) && (length > 3))
1264 {
1265 if (!_FlashCtl_A_Program32(srcAddr, destAddr, mTries))
1266 {
1267 goto FlashProgramCleanUp;
1268 } else
1269 {
1270 srcAddr += 4;
1271 destAddr += 4;
1272 length -= 4;
1273 }
1274 }
1275
1276 /* Taking care of burst programs */
1277 while (length > 16)
1278 {
1279 burstLength = length > 63 ? 64 : length & 0xFFFFFFF0;
1280
1281 if (!_FlashCtl_A_ProgramBurst(srcAddr, destAddr, burstLength, mTries))
1282 {
1283 goto FlashProgramCleanUp;
1284 } else
1285 {
1286 srcAddr += burstLength;
1287 destAddr += burstLength;
1288 length -= burstLength;
1289 }
1290 }
1291
1292 /* Remaining word accesses */
1293 while (length > 3)
1294 {
1295 if (!_FlashCtl_A_Program32(srcAddr, destAddr, mTries))
1296 {
1297 goto FlashProgramCleanUp;
1298 } else
1299 {
1300 srcAddr += 4;
1301 destAddr += 4;
1302 length -= 4;
1303 }
1304 }
1305
1306 /* Remaining byte accesses */
1307 while (length > 0)
1308 {
1309 if (!_FlashCtl_A_Program8(srcAddr, destAddr, mTries))
1310 {
1311 goto FlashProgramCleanUp;
1312 } else
1313 {
1314 srcAddr++;
1315 destAddr++;
1316 length--;
1317 }
1318 }
1319
1320 /* If we got this far that means that we succeeded */
1321 res = true;
1322
1323 FlashProgramCleanUp:
1324
1325 if (intStatus == 0)
1326 Interrupt_enableMaster();
1327
1328 FlashCtl_A_disableWordProgramming();
1329 return res;
1330
1331 }
FlashCtl_A_setProgramVerification(uint32_t verificationSetting)1332 void FlashCtl_A_setProgramVerification(uint32_t verificationSetting)
1333 {
1334 if ((verificationSetting & FLASH_A_BURSTPOST))
1335 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1336 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1;
1337
1338 if ((verificationSetting & FLASH_A_BURSTPRE))
1339 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1340 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1;
1341
1342 if ((verificationSetting & FLASH_A_REGPRE))
1343 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) = 1;
1344
1345 if ((verificationSetting & FLASH_A_REGPOST))
1346 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PST_OFS) = 1;
1347 }
1348
FlashCtl_A_clearProgramVerification(uint32_t verificationSetting)1349 void FlashCtl_A_clearProgramVerification(uint32_t verificationSetting)
1350 {
1351 if ((verificationSetting & FLASH_A_BURSTPOST))
1352 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1353 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0;
1354
1355 if ((verificationSetting & FLASH_A_BURSTPRE))
1356 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1357 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0;
1358
1359 if ((verificationSetting & FLASH_A_REGPRE))
1360 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) = 0;
1361
1362 if ((verificationSetting & FLASH_A_REGPOST))
1363 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PST_OFS) = 0;
1364
1365 }
1366
FlashCtl_A_enableWordProgramming(uint32_t mode)1367 void FlashCtl_A_enableWordProgramming(uint32_t mode)
1368 {
1369 if (mode == FLASH_A_IMMEDIATE_WRITE_MODE)
1370 {
1371 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 1;
1372 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS) = 0;
1373
1374 } else if (mode == FLASH_A_COLLATED_WRITE_MODE)
1375 {
1376 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 1;
1377 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS) = 1;
1378 }
1379 }
1380
FlashCtl_A_disableWordProgramming(void)1381 void FlashCtl_A_disableWordProgramming(void)
1382 {
1383 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 0;
1384 }
1385
FlashCtl_A_isWordProgrammingEnabled(void)1386 uint32_t FlashCtl_A_isWordProgrammingEnabled(void)
1387 {
1388 if (!BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS))
1389 {
1390 return 0;
1391 } else if (BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS))
1392 return FLASH_A_COLLATED_WRITE_MODE;
1393 else
1394 return FLASH_A_IMMEDIATE_WRITE_MODE;
1395 }
1396
FlashCtl_A_setWaitState(uint32_t flashBank,uint32_t waitState)1397 void FlashCtl_A_setWaitState(uint32_t flashBank, uint32_t waitState)
1398 {
1399 if (flashBank == FLASH_A_BANK0)
1400 {
1401 FLCTL_A->BANK0_RDCTL = (FLCTL_A->BANK0_RDCTL
1402 & ~FLCTL_A_BANK0_RDCTL_WAIT_MASK)
1403 | (waitState << FLCTL_A_BANK0_RDCTL_WAIT_OFS);
1404 } else if (flashBank == FLASH_A_BANK1)
1405 {
1406 FLCTL_A->BANK1_RDCTL = (FLCTL_A->BANK1_RDCTL
1407 & ~FLCTL_A_BANK1_RDCTL_WAIT_MASK)
1408 | (waitState << FLCTL_A_BANK1_RDCTL_WAIT_OFS);
1409 } else
1410 {
1411 ASSERT(false);
1412 }
1413 }
1414
FlashCtl_A_getWaitState(uint32_t flashBank)1415 uint32_t FlashCtl_A_getWaitState(uint32_t flashBank)
1416 {
1417 if (flashBank == FLASH_A_BANK0)
1418 {
1419 return (FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_WAIT_MASK)
1420 >> FLCTL_A_BANK0_RDCTL_WAIT_OFS;
1421 } else if (flashBank == FLASH_A_BANK1)
1422 {
1423 return (FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_WAIT_MASK)
1424 >> FLCTL_A_BANK1_RDCTL_WAIT_OFS;
1425 } else
1426 {
1427 ASSERT(false);
1428 return 0;
1429 }
1430 }
1431
FlashCtl_A_enableInterrupt(uint32_t flags)1432 void FlashCtl_A_enableInterrupt(uint32_t flags)
1433 {
1434 FLCTL_A->IE |= flags;
1435 }
1436
FlashCtl_A_disableInterrupt(uint32_t flags)1437 void FlashCtl_A_disableInterrupt(uint32_t flags)
1438 {
1439 FLCTL_A->IE &= ~flags;
1440 }
1441
FlashCtl_A_getInterruptStatus(void)1442 uint32_t FlashCtl_A_getInterruptStatus(void)
1443 {
1444 return FLCTL_A->IFG;
1445 }
1446
FlashCtl_A_getEnabledInterruptStatus(void)1447 uint32_t FlashCtl_A_getEnabledInterruptStatus(void)
1448 {
1449 return FlashCtl_A_getInterruptStatus() & FLCTL_A->IE;
1450 }
1451
FlashCtl_A_clearInterruptFlag(uint32_t flags)1452 void FlashCtl_A_clearInterruptFlag(uint32_t flags)
1453 {
1454 FLCTL_A->CLRIFG |= flags;
1455 }
1456
FlashCtl_A_registerInterrupt(void (* intHandler)(void))1457 void FlashCtl_A_registerInterrupt(void (*intHandler)(void))
1458 {
1459 //
1460 // Register the interrupt handler, returning an error if an error occurs.
1461 //
1462 Interrupt_registerInterrupt(INT_FLCTL, intHandler);
1463
1464 //
1465 // Enable the system control interrupt.
1466 //
1467 Interrupt_enableInterrupt(INT_FLCTL);
1468 }
1469
FlashCtl_A_unregisterInterrupt(void)1470 void FlashCtl_A_unregisterInterrupt(void)
1471 {
1472 //
1473 // Disable the interrupt.
1474 //
1475 Interrupt_disableInterrupt(INT_FLCTL);
1476
1477 //
1478 // Unregister the interrupt handler.
1479 //
1480 Interrupt_unregisterInterrupt(INT_FLCTL);
1481 }
1482
__FlashCtl_A_remaskData8Post(uint8_t data,uint32_t addr)1483 uint8_t __FlashCtl_A_remaskData8Post(uint8_t data, uint32_t addr)
1484 {
1485 uint32_t readMode, waitState, bankProgram, bankOneStart;
1486
1487 /* Changing the waitstate and read mode of whichever bank we are in */
1488 /* Finding out which bank we are in */
1489 if (addr >= SysCtl_A_getFlashSize())
1490 {
1491 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__;
1492 } else
1493 {
1494 bankOneStart = SysCtl_A_getFlashSize() / 2;
1495 }
1496
1497 bankProgram = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1;
1498
1499 /* Saving the current wait states and read mode */
1500 waitState = FlashCtl_A_getWaitState(bankProgram);
1501 readMode = FlashCtl_A_getReadMode(bankProgram);
1502
1503 /* Setting the wait state to account for the mode */
1504 FlashCtl_A_setWaitState(bankProgram, (2 * waitState) + 1);
1505
1506 /* Changing to PROGRAM VERIFY mode */
1507 FlashCtl_A_setReadMode(bankProgram, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1508
1509 data = ~(~(data) & HWREG8(addr));
1510
1511 /* Setting the wait state to account for the mode */
1512 FlashCtl_A_setReadMode(bankProgram, readMode);
1513 FlashCtl_A_setWaitState(bankProgram, waitState);
1514
1515 return data;
1516 }
1517
__FlashCtl_A_remaskData8Pre(uint8_t data,uint32_t addr)1518 uint8_t __FlashCtl_A_remaskData8Pre(uint8_t data, uint32_t addr)
1519 {
1520 uint32_t readMode, waitState, bankProgram, bankOneStart;
1521
1522 /* Changing the waitstate and read mode of whichever bank we are in */
1523 /* Finding out which bank we are in */
1524 if (addr >= SysCtl_A_getFlashSize())
1525 {
1526 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__;
1527 } else
1528 {
1529 bankOneStart = SysCtl_A_getFlashSize() / 2;
1530 }
1531
1532 bankProgram = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1;
1533
1534 /* Saving the current wait states and read mode */
1535 waitState = FlashCtl_A_getWaitState(bankProgram);
1536 readMode = FlashCtl_A_getReadMode(bankProgram);
1537
1538 /* Setting the wait state to account for the mode */
1539 FlashCtl_A_setWaitState(bankProgram, (2 * waitState) + 1);
1540
1541 /* Changing to PROGRAM VERIFY mode */
1542 FlashCtl_A_setReadMode(bankProgram, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1543
1544 data |= ~(HWREG8(addr) | data);
1545
1546 /* Setting the wait state to account for the mode */
1547 FlashCtl_A_setReadMode(bankProgram, readMode);
1548 FlashCtl_A_setWaitState(bankProgram, waitState);
1549
1550 return data;
1551 }
1552
__FlashCtl_A_remaskData32Post(uint32_t data,uint32_t addr)1553 uint32_t __FlashCtl_A_remaskData32Post(uint32_t data, uint32_t addr)
1554 {
1555 uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1556 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1557
1558 /* Changing the waitstate and read mode of whichever bank we are in */
1559 /* Finding out which bank we are in */
1560 if (addr >= SysCtl_A_getFlashSize())
1561 {
1562 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1563 } else
1564 {
1565 bank1Start = SysCtl_A_getFlashSize() / 2;
1566 }
1567
1568 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1569 bankProgramEnd = (addr + 4) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1570
1571 /* Saving the current wait states and read mode */
1572 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1573 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1574 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1575 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1576
1577 if (bankProgramStart != bankProgramEnd)
1578 {
1579 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1580 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1581 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1582 FlashCtl_A_setReadMode(bankProgramEnd,
1583 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1584 }
1585
1586 data = ~(~(data) & HWREG32(addr));
1587
1588 /* Setting the wait state to account for the mode */
1589 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1590 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1591
1592 if (bankProgramStart != bankProgramEnd)
1593 {
1594 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1595 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1596 }
1597
1598 return data;
1599 }
1600
__FlashCtl_A_remaskData32Pre(uint32_t data,uint32_t addr)1601 uint32_t __FlashCtl_A_remaskData32Pre(uint32_t data, uint32_t addr)
1602 {
1603 uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1604 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1605
1606 /* Changing the waitstate and read mode of whichever bank we are in */
1607 /* Finding out which bank we are in */
1608 if (addr >= SysCtl_A_getFlashSize())
1609 {
1610 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1611 } else
1612 {
1613 bank1Start = SysCtl_A_getFlashSize() / 2;
1614 }
1615
1616 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1617 bankProgramEnd = (addr + 4) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1618
1619 /* Saving the current wait states and read mode */
1620 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1621 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1622 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1623 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1624
1625 if (bankProgramStart != bankProgramEnd)
1626 {
1627 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1628 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1629 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1630 FlashCtl_A_setReadMode(bankProgramEnd,
1631 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1632 }
1633
1634 data |= ~(HWREG32(addr) | data);
1635
1636 /* Setting the wait state to account for the mode */
1637 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1638 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1639
1640 if (bankProgramStart != bankProgramEnd)
1641 {
1642 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1643 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1644 }
1645
1646 return data;
1647 }
1648
__FlashCtl_A_remaskBurstDataPre(uint32_t addr,uint32_t size)1649 void __FlashCtl_A_remaskBurstDataPre(uint32_t addr, uint32_t size)
1650 {
1651
1652 uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1653 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1654
1655 /* Waiting for idle status */
1656 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1657 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
1658 {
1659 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1660 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1661 }
1662
1663 /* Changing the waitstate and read mode of whichever bank we are in */
1664 /* Finding out which bank we are in */
1665 if (addr >= SysCtl_A_getFlashSize())
1666 {
1667 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1668 } else
1669 {
1670 bank1Start = SysCtl_A_getFlashSize() / 2;
1671 }
1672
1673 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1674 bankProgramEnd = (addr + size) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1675
1676 /* Saving the current wait states and read mode */
1677 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1678 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1679 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1680 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1681
1682 if (bankProgramStart != bankProgramEnd)
1683 {
1684 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1685 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1686 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1687 FlashCtl_A_setReadMode(bankProgramEnd,
1688 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1689 }
1690
1691 /* Going through each BURST program register and masking out for pre
1692 * verifcation
1693 */
1694 size = (size / 4);
1695 for (ii = 0; ii < size; ii++)
1696 {
1697 uint32_t temp1 = HWREG32(__getBurstProgramRegs[ii]);
1698 uint32_t temp2 = HWREG32(addr);
1699 HWREG32(__getBurstProgramRegs[ii]) |= ~(temp1 | temp2);
1700 addr += 4;
1701 }
1702
1703 /* Setting the wait state to account for the mode */
1704 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1705 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1706
1707 if (bankProgramStart != bankProgramEnd)
1708 {
1709 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1710 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1711 }
1712
1713 }
__FlashCtl_A_remaskBurstDataPost(uint32_t addr,uint32_t size)1714 void __FlashCtl_A_remaskBurstDataPost(uint32_t addr, uint32_t size)
1715 {
1716 uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1717 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1718
1719 /* Waiting for idle status */
1720 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1721 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
1722 {
1723 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1724 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1725 }
1726
1727 /* Changing the waitstate and read mode of whichever bank we are in */
1728 /* Finding out which bank we are in */
1729 if (addr >= SysCtl_A_getFlashSize())
1730 {
1731 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1732 } else
1733 {
1734 bank1Start = SysCtl_A_getFlashSize() / 2;
1735 }
1736
1737 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1738 bankProgramEnd = (addr + size) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1739
1740 /* Saving the current wait states and read mode */
1741 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1742 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1743 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1744 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1745
1746 if (bankProgramStart != bankProgramEnd)
1747 {
1748 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1749 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1750 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1751 FlashCtl_A_setReadMode(bankProgramEnd,
1752 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1753 }
1754
1755 /* Going through each BURST program register and masking out for post
1756 * verifcation if needed
1757 */
1758 size = (size / 4);
1759 for (ii = 0; ii < size; ii++)
1760 {
1761 uint32_t temp1 = (HWREG32(__getBurstProgramRegs[ii]));
1762 uint32_t temp2 = HWREG32(addr);
1763 HWREG32(__getBurstProgramRegs[ii]) = ~(~temp1 & temp2);
1764
1765 addr += 4;
1766 }
1767
1768 /* Setting the wait state to account for the mode */
1769 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1770 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1771
1772 if (bankProgramStart != bankProgramEnd)
1773 {
1774 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1775 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1776 }
1777 }
1778
1779 #endif /* __MCU_HAS_FLCTL_A__ */
1780
1781