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, tlvLength;
944 SysCtl_A_FlashTLV_Info *flInfo;
945 __FlashCtl_ProtectionRegister protectRegs;
946 bool res, needAnotherPulse;
947
948 /* Parsing the TLV and getting the maximum erase pulses */
949 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
950
951 if (tlvLength == 0 || flInfo->maxErasePulses == 0)
952 {
953 mTries = MAX_ERASE_NO_TLV;
954 } else
955 {
956 mTries = flInfo->maxErasePulses;
957 }
958
959 /* Saving interrupt context and disabling interrupts for program
960 * operation
961 */
962 intStatus = CPU_primask();
963 Interrupt_disableMaster();
964
965 /* Assume Failure */
966 res = false;
967
968 /* Saving off protection settings so we can restore them later */
969 __saveProtectionRegisters(&protectRegs);
970
971 for(jj=0;jj<mTries;jj++)
972 {
973 needAnotherPulse = false;
974
975 /* Clearing old mass erase flags */
976 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
977 1;
978
979 /* Performing the mass erase */
980 FLCTL_A->ERASE_CTLSTAT |= (FLCTL_A_ERASE_CTLSTAT_MODE
981 | FLCTL_A_ERASE_CTLSTAT_START);
982
983 while ((FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
984 == FLCTL_A_ERASE_CTLSTAT_STATUS_1
985 || (FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
986 == FLCTL_A_ERASE_CTLSTAT_STATUS_2)
987 {
988 __no_operation();
989 }
990
991 /* Return false if an address error */
992 if (BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT,
993 FLCTL_A_ERASE_CTLSTAT_ADDR_ERR_OFS))
994 goto MassEraseCleanup;
995
996 /* Verifying the user memory that might have been erased */
997 flashSize = SysCtl_A_getFlashSize();
998
999 /* Clearing old flag */
1000 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1001 1;
1002
1003 for (ii = 0; ii < flashSize; ii += FLASH_A_SECTOR_SIZE)
1004 {
1005 if (!FlashCtl_A_isMemoryProtected(ii))
1006 {
1007 if (!FlashCtl_A_verifyMemory((void*) ii, FLASH_A_SECTOR_SIZE,
1008 FLASH_A_1_PATTERN))
1009 {
1010 needAnotherPulse = true;
1011 }
1012 else
1013 {
1014 FlashCtl_A_protectMemory(ii,ii);
1015 }
1016 }
1017 }
1018
1019 /* Verifying the INFO memory that might be protected */
1020 flashSize = SysCtl_A_getInfoFlashSize() + __INFO_FLASH_A_TECH_START__;
1021
1022 for (ii = __INFO_FLASH_A_TECH_START__; ii < flashSize; ii +=
1023 FLASH_A_SECTOR_SIZE)
1024 {
1025 if (!FlashCtl_A_isMemoryProtected(ii))
1026 {
1027 if (!FlashCtl_A_verifyMemory((void*) ii, FLASH_A_SECTOR_SIZE,
1028 FLASH_A_1_PATTERN))
1029 {
1030 needAnotherPulse = true;
1031 }
1032 else
1033 {
1034 FlashCtl_A_protectMemory(ii,ii);
1035 }
1036 }
1037 }
1038
1039 if(!needAnotherPulse)
1040 {
1041 break;
1042 }
1043 }
1044
1045 /* If we got this far and didn't do the max number of tries,
1046 * the mass erase happened */
1047 if(jj != mTries)
1048 {
1049 res = true;
1050 }
1051
1052 MassEraseCleanup:
1053
1054 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT,
1055 FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
1056 __restoreProtectionRegisters(&protectRegs);
1057
1058 if (intStatus == 0)
1059 Interrupt_enableMaster();
1060
1061 return res;
1062 }
1063
FlashCtl_A_eraseSector(uint32_t addr)1064 bool FlashCtl_A_eraseSector(uint32_t addr)
1065 {
1066 uint_fast8_t memoryType, ii;
1067 uint32_t otpOffset = 0;
1068 uint32_t intStatus;
1069 uint_fast8_t mTries, tlvLength;
1070 SysCtl_A_FlashTLV_Info *flInfo;
1071 bool res;
1072
1073 /* Saving interrupt context and disabling interrupts for program
1074 * operation
1075 */
1076 intStatus = CPU_primask();
1077 Interrupt_disableMaster();
1078
1079 /* Assuming Failure */
1080 res = false;
1081
1082 memoryType = addr >= SysCtl_A_getFlashSize() ? FLASH_A_INFO_SPACE :
1083 FLASH_A_MAIN_SPACE;
1084
1085 /* Parsing the TLV and getting the maximum erase pulses */
1086 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
1087
1088 if (tlvLength == 0 || flInfo->maxErasePulses == 0)
1089 {
1090 mTries = MAX_ERASE_NO_TLV;
1091 } else
1092 {
1093 mTries = flInfo->maxErasePulses;
1094 }
1095
1096 /* We can only erase on 4KB boundaries */
1097 while (addr & 0xFFF)
1098 {
1099 addr--;
1100 }
1101
1102 /* Clearing the status */
1103 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1104 1;
1105
1106 if (memoryType == FLASH_A_INFO_SPACE)
1107 {
1108 otpOffset = __INFO_FLASH_A_TECH_START__;
1109 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1110 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1111 | FLCTL_A_ERASE_CTLSTAT_TYPE_1;
1112
1113 } else
1114 {
1115 otpOffset = 0;
1116 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1117 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1118 | FLCTL_A_ERASE_CTLSTAT_TYPE_0;
1119 }
1120
1121 /* Clearing old flags and setting up the erase */
1122 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_MODE_OFS) = 0;
1123 FLCTL_A->ERASE_SECTADDR = addr - otpOffset;
1124
1125 for (ii = 0; ii < mTries; ii++)
1126 {
1127 /* Clearing the status */
1128 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1129 1;
1130
1131 /* Starting the erase */
1132 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_START_OFS) =
1133 1;
1134
1135 while ((FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
1136 == FLCTL_A_ERASE_CTLSTAT_STATUS_1
1137 || (FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK)
1138 == FLCTL_A_ERASE_CTLSTAT_STATUS_2)
1139 {
1140 __no_operation();
1141 }
1142
1143 /* Return false if an address error */
1144 if (BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT,
1145 FLCTL_A_ERASE_CTLSTAT_ADDR_ERR_OFS))
1146 {
1147 goto SectorEraseCleanup;
1148 }
1149 /* Erase verifying */
1150 if (FlashCtl_A_verifyMemory((void*) addr, FLASH_A_SECTOR_SIZE,
1151 FLASH_A_1_PATTERN))
1152 {
1153 res = true;
1154 goto SectorEraseCleanup;
1155 }
1156
1157 }
1158
1159 SectorEraseCleanup:
1160
1161 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1162 1;
1163
1164 if (intStatus == 0)
1165 Interrupt_enableMaster();
1166
1167 return res;
1168 }
1169
FlashCtl_A_initiateSectorErase(uint32_t addr)1170 void FlashCtl_A_initiateSectorErase(uint32_t addr)
1171 {
1172 uint_fast8_t memoryType;
1173 uint32_t otpOffset = 0;
1174
1175 memoryType = addr >= SysCtl_A_getFlashSize() ?
1176 FLASH_A_INFO_SPACE :
1177 FLASH_A_MAIN_SPACE;
1178
1179 /* We can only erase on 4KB boundaries */
1180 while (addr & 0xFFF)
1181 {
1182 addr--;
1183 }
1184
1185 /* Clearing the status */
1186 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) =
1187 1;
1188
1189 if (memoryType == FLASH_A_INFO_SPACE)
1190 {
1191 otpOffset = __INFO_FLASH_A_TECH_START__;
1192 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1193 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1194 | FLCTL_A_ERASE_CTLSTAT_TYPE_1;
1195
1196 } else
1197 {
1198 otpOffset = 0;
1199 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT
1200 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK))
1201 | FLCTL_A_ERASE_CTLSTAT_TYPE_0;
1202 }
1203
1204 /* Clearing old flags and setting up the erase */
1205 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_MODE_OFS) = 0;
1206 FLCTL_A->ERASE_SECTADDR = addr - otpOffset;
1207
1208 /* Starting the erase */
1209 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_START_OFS) = 1;
1210
1211 }
1212
FlashCtl_A_programMemory(void * src,void * dest,uint32_t length)1213 bool FlashCtl_A_programMemory(void* src, void* dest, uint32_t length)
1214 {
1215 uint32_t destAddr, srcAddr, burstLength, intStatus;
1216 bool res;
1217 uint_fast8_t mTries, tlvLength;
1218 SysCtl_A_FlashTLV_Info *flInfo;
1219
1220 /* Saving interrupt context and disabling interrupts for program
1221 * operation
1222 */
1223 intStatus = CPU_primask();
1224 Interrupt_disableMaster();
1225
1226 /* Parsing the TLV and getting the maximum erase pulses */
1227 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
1228
1229 if (tlvLength == 0 || flInfo->maxProgramPulses == 0)
1230 {
1231 mTries = MAX_PROGRAM_NO_TLV;
1232 } else
1233 {
1234 mTries = flInfo->maxProgramPulses;
1235 }
1236
1237 /* Casting to integers */
1238 srcAddr = (uint32_t) src;
1239 destAddr = (uint32_t) dest;
1240
1241 /* Enabling word programming */
1242 FlashCtl_A_enableWordProgramming(FLASH_A_IMMEDIATE_WRITE_MODE);
1243
1244 /* Assume failure */
1245 res = false;
1246
1247 /* Taking care of byte accesses */
1248 while ((destAddr & 0x03) && length > 0)
1249 {
1250 if (!_FlashCtl_A_Program8(srcAddr, destAddr, mTries))
1251 {
1252 goto FlashProgramCleanUp;
1253 } else
1254 {
1255 srcAddr++;
1256 destAddr++;
1257 length--;
1258 }
1259 }
1260
1261 /* Taking care of word accesses */
1262 while ((destAddr & 0x0F) && (length > 3))
1263 {
1264 if (!_FlashCtl_A_Program32(srcAddr, destAddr, mTries))
1265 {
1266 goto FlashProgramCleanUp;
1267 } else
1268 {
1269 srcAddr += 4;
1270 destAddr += 4;
1271 length -= 4;
1272 }
1273 }
1274
1275 /* Taking care of burst programs */
1276 while (length > 16)
1277 {
1278 burstLength = length > 63 ? 64 : length & 0xFFFFFFF0;
1279
1280 if (!_FlashCtl_A_ProgramBurst(srcAddr, destAddr, burstLength, mTries))
1281 {
1282 goto FlashProgramCleanUp;
1283 } else
1284 {
1285 srcAddr += burstLength;
1286 destAddr += burstLength;
1287 length -= burstLength;
1288 }
1289 }
1290
1291 /* Remaining word accesses */
1292 while (length > 3)
1293 {
1294 if (!_FlashCtl_A_Program32(srcAddr, destAddr, mTries))
1295 {
1296 goto FlashProgramCleanUp;
1297 } else
1298 {
1299 srcAddr += 4;
1300 destAddr += 4;
1301 length -= 4;
1302 }
1303 }
1304
1305 /* Remaining byte accesses */
1306 while (length > 0)
1307 {
1308 if (!_FlashCtl_A_Program8(srcAddr, destAddr, mTries))
1309 {
1310 goto FlashProgramCleanUp;
1311 } else
1312 {
1313 srcAddr++;
1314 destAddr++;
1315 length--;
1316 }
1317 }
1318
1319 /* If we got this far that means that we succeeded */
1320 res = true;
1321
1322 FlashProgramCleanUp:
1323
1324 if (intStatus == 0)
1325 Interrupt_enableMaster();
1326
1327 FlashCtl_A_disableWordProgramming();
1328 return res;
1329
1330 }
FlashCtl_A_setProgramVerification(uint32_t verificationSetting)1331 void FlashCtl_A_setProgramVerification(uint32_t verificationSetting)
1332 {
1333 if ((verificationSetting & FLASH_A_BURSTPOST))
1334 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1335 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1;
1336
1337 if ((verificationSetting & FLASH_A_BURSTPRE))
1338 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1339 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1;
1340
1341 if ((verificationSetting & FLASH_A_REGPRE))
1342 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) = 1;
1343
1344 if ((verificationSetting & FLASH_A_REGPOST))
1345 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PST_OFS) = 1;
1346 }
1347
FlashCtl_A_clearProgramVerification(uint32_t verificationSetting)1348 void FlashCtl_A_clearProgramVerification(uint32_t verificationSetting)
1349 {
1350 if ((verificationSetting & FLASH_A_BURSTPOST))
1351 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1352 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0;
1353
1354 if ((verificationSetting & FLASH_A_BURSTPRE))
1355 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1356 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0;
1357
1358 if ((verificationSetting & FLASH_A_REGPRE))
1359 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) = 0;
1360
1361 if ((verificationSetting & FLASH_A_REGPOST))
1362 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PST_OFS) = 0;
1363
1364 }
1365
FlashCtl_A_enableWordProgramming(uint32_t mode)1366 void FlashCtl_A_enableWordProgramming(uint32_t mode)
1367 {
1368 if (mode == FLASH_A_IMMEDIATE_WRITE_MODE)
1369 {
1370 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 1;
1371 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS) = 0;
1372
1373 } else if (mode == FLASH_A_COLLATED_WRITE_MODE)
1374 {
1375 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 1;
1376 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS) = 1;
1377 }
1378 }
1379
FlashCtl_A_disableWordProgramming(void)1380 void FlashCtl_A_disableWordProgramming(void)
1381 {
1382 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 0;
1383 }
1384
FlashCtl_A_isWordProgrammingEnabled(void)1385 uint32_t FlashCtl_A_isWordProgrammingEnabled(void)
1386 {
1387 if (!BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS))
1388 {
1389 return 0;
1390 } else if (BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS))
1391 return FLASH_A_COLLATED_WRITE_MODE;
1392 else
1393 return FLASH_A_IMMEDIATE_WRITE_MODE;
1394 }
1395
FlashCtl_A_setWaitState(uint32_t flashBank,uint32_t waitState)1396 void FlashCtl_A_setWaitState(uint32_t flashBank, uint32_t waitState)
1397 {
1398 if (flashBank == FLASH_A_BANK0)
1399 {
1400 FLCTL_A->BANK0_RDCTL = (FLCTL_A->BANK0_RDCTL
1401 & ~FLCTL_A_BANK0_RDCTL_WAIT_MASK)
1402 | (waitState << FLCTL_A_BANK0_RDCTL_WAIT_OFS);
1403 } else if (flashBank == FLASH_A_BANK1)
1404 {
1405 FLCTL_A->BANK1_RDCTL = (FLCTL_A->BANK1_RDCTL
1406 & ~FLCTL_A_BANK1_RDCTL_WAIT_MASK)
1407 | (waitState << FLCTL_A_BANK1_RDCTL_WAIT_OFS);
1408 } else
1409 {
1410 ASSERT(false);
1411 }
1412 }
1413
FlashCtl_A_getWaitState(uint32_t flashBank)1414 uint32_t FlashCtl_A_getWaitState(uint32_t flashBank)
1415 {
1416 if (flashBank == FLASH_A_BANK0)
1417 {
1418 return (FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_WAIT_MASK)
1419 >> FLCTL_A_BANK0_RDCTL_WAIT_OFS;
1420 } else if (flashBank == FLASH_A_BANK1)
1421 {
1422 return (FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_WAIT_MASK)
1423 >> FLCTL_A_BANK1_RDCTL_WAIT_OFS;
1424 } else
1425 {
1426 ASSERT(false);
1427 return 0;
1428 }
1429 }
1430
FlashCtl_A_enableInterrupt(uint32_t flags)1431 void FlashCtl_A_enableInterrupt(uint32_t flags)
1432 {
1433 FLCTL_A->IE |= flags;
1434 }
1435
FlashCtl_A_disableInterrupt(uint32_t flags)1436 void FlashCtl_A_disableInterrupt(uint32_t flags)
1437 {
1438 FLCTL_A->IE &= ~flags;
1439 }
1440
FlashCtl_A_getInterruptStatus(void)1441 uint32_t FlashCtl_A_getInterruptStatus(void)
1442 {
1443 return FLCTL_A->IFG;
1444 }
1445
FlashCtl_A_getEnabledInterruptStatus(void)1446 uint32_t FlashCtl_A_getEnabledInterruptStatus(void)
1447 {
1448 return FlashCtl_A_getInterruptStatus() & FLCTL_A->IE;
1449 }
1450
FlashCtl_A_clearInterruptFlag(uint32_t flags)1451 void FlashCtl_A_clearInterruptFlag(uint32_t flags)
1452 {
1453 FLCTL_A->CLRIFG |= flags;
1454 }
1455
FlashCtl_A_registerInterrupt(void (* intHandler)(void))1456 void FlashCtl_A_registerInterrupt(void (*intHandler)(void))
1457 {
1458 //
1459 // Register the interrupt handler, returning an error if an error occurs.
1460 //
1461 Interrupt_registerInterrupt(INT_FLCTL, intHandler);
1462
1463 //
1464 // Enable the system control interrupt.
1465 //
1466 Interrupt_enableInterrupt(INT_FLCTL);
1467 }
1468
FlashCtl_A_unregisterInterrupt(void)1469 void FlashCtl_A_unregisterInterrupt(void)
1470 {
1471 //
1472 // Disable the interrupt.
1473 //
1474 Interrupt_disableInterrupt(INT_FLCTL);
1475
1476 //
1477 // Unregister the interrupt handler.
1478 //
1479 Interrupt_unregisterInterrupt(INT_FLCTL);
1480 }
1481
__FlashCtl_A_remaskData8Post(uint8_t data,uint32_t addr)1482 uint8_t __FlashCtl_A_remaskData8Post(uint8_t data, uint32_t addr)
1483 {
1484 uint32_t readMode, waitState, bankProgram, bankOneStart;
1485
1486 /* Changing the waitstate and read mode of whichever bank we are in */
1487 /* Finding out which bank we are in */
1488 if (addr >= SysCtl_A_getFlashSize())
1489 {
1490 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__;
1491 } else
1492 {
1493 bankOneStart = SysCtl_A_getFlashSize() / 2;
1494 }
1495
1496 bankProgram = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1;
1497
1498 /* Saving the current wait states and read mode */
1499 waitState = FlashCtl_A_getWaitState(bankProgram);
1500 readMode = FlashCtl_A_getReadMode(bankProgram);
1501
1502 /* Setting the wait state to account for the mode */
1503 FlashCtl_A_setWaitState(bankProgram, (2 * waitState) + 1);
1504
1505 /* Changing to PROGRAM VERIFY mode */
1506 FlashCtl_A_setReadMode(bankProgram, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1507
1508 data = ~(~(data) & HWREG8(addr));
1509
1510 /* Setting the wait state to account for the mode */
1511 FlashCtl_A_setReadMode(bankProgram, readMode);
1512 FlashCtl_A_setWaitState(bankProgram, waitState);
1513
1514 return data;
1515 }
1516
__FlashCtl_A_remaskData8Pre(uint8_t data,uint32_t addr)1517 uint8_t __FlashCtl_A_remaskData8Pre(uint8_t data, uint32_t addr)
1518 {
1519 uint32_t readMode, waitState, bankProgram, bankOneStart;
1520
1521 /* Changing the waitstate and read mode of whichever bank we are in */
1522 /* Finding out which bank we are in */
1523 if (addr >= SysCtl_A_getFlashSize())
1524 {
1525 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__;
1526 } else
1527 {
1528 bankOneStart = SysCtl_A_getFlashSize() / 2;
1529 }
1530
1531 bankProgram = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1;
1532
1533 /* Saving the current wait states and read mode */
1534 waitState = FlashCtl_A_getWaitState(bankProgram);
1535 readMode = FlashCtl_A_getReadMode(bankProgram);
1536
1537 /* Setting the wait state to account for the mode */
1538 FlashCtl_A_setWaitState(bankProgram, (2 * waitState) + 1);
1539
1540 /* Changing to PROGRAM VERIFY mode */
1541 FlashCtl_A_setReadMode(bankProgram, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1542
1543 data |= ~(HWREG8(addr) | data);
1544
1545 /* Setting the wait state to account for the mode */
1546 FlashCtl_A_setReadMode(bankProgram, readMode);
1547 FlashCtl_A_setWaitState(bankProgram, waitState);
1548
1549 return data;
1550 }
1551
__FlashCtl_A_remaskData32Post(uint32_t data,uint32_t addr)1552 uint32_t __FlashCtl_A_remaskData32Post(uint32_t data, uint32_t addr)
1553 {
1554 uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1555 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1556
1557 /* Changing the waitstate and read mode of whichever bank we are in */
1558 /* Finding out which bank we are in */
1559 if (addr >= SysCtl_A_getFlashSize())
1560 {
1561 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1562 } else
1563 {
1564 bank1Start = SysCtl_A_getFlashSize() / 2;
1565 }
1566
1567 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1568 bankProgramEnd = (addr + 4) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1569
1570 /* Saving the current wait states and read mode */
1571 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1572 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1573 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1574 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1575
1576 if (bankProgramStart != bankProgramEnd)
1577 {
1578 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1579 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1580 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1581 FlashCtl_A_setReadMode(bankProgramEnd,
1582 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1583 }
1584
1585 data = ~(~(data) & HWREG32(addr));
1586
1587 /* Setting the wait state to account for the mode */
1588 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1589 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1590
1591 if (bankProgramStart != bankProgramEnd)
1592 {
1593 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1594 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1595 }
1596
1597 return data;
1598 }
1599
__FlashCtl_A_remaskData32Pre(uint32_t data,uint32_t addr)1600 uint32_t __FlashCtl_A_remaskData32Pre(uint32_t data, uint32_t addr)
1601 {
1602 uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1603 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1604
1605 /* Changing the waitstate and read mode of whichever bank we are in */
1606 /* Finding out which bank we are in */
1607 if (addr >= SysCtl_A_getFlashSize())
1608 {
1609 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1610 } else
1611 {
1612 bank1Start = SysCtl_A_getFlashSize() / 2;
1613 }
1614
1615 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1616 bankProgramEnd = (addr + 4) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1617
1618 /* Saving the current wait states and read mode */
1619 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1620 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1621 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1622 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1623
1624 if (bankProgramStart != bankProgramEnd)
1625 {
1626 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1627 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1628 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1629 FlashCtl_A_setReadMode(bankProgramEnd,
1630 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1631 }
1632
1633 data |= ~(HWREG32(addr) | data);
1634
1635 /* Setting the wait state to account for the mode */
1636 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1637 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1638
1639 if (bankProgramStart != bankProgramEnd)
1640 {
1641 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1642 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1643 }
1644
1645 return data;
1646 }
1647
__FlashCtl_A_remaskBurstDataPre(uint32_t addr,uint32_t size)1648 void __FlashCtl_A_remaskBurstDataPre(uint32_t addr, uint32_t size)
1649 {
1650
1651 uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1652 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1653
1654 /* Waiting for idle status */
1655 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1656 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
1657 {
1658 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1659 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1660 }
1661
1662 /* Changing the waitstate and read mode of whichever bank we are in */
1663 /* Finding out which bank we are in */
1664 if (addr >= SysCtl_A_getFlashSize())
1665 {
1666 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1667 } else
1668 {
1669 bank1Start = SysCtl_A_getFlashSize() / 2;
1670 }
1671
1672 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1673 bankProgramEnd = (addr + size) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1674
1675 /* Saving the current wait states and read mode */
1676 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1677 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1678 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1679 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1680
1681 if (bankProgramStart != bankProgramEnd)
1682 {
1683 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1684 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1685 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1686 FlashCtl_A_setReadMode(bankProgramEnd,
1687 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1688 }
1689
1690 /* Going through each BURST program register and masking out for pre
1691 * verifcation
1692 */
1693 size = (size / 4);
1694 for (ii = 0; ii < size; ii++)
1695 {
1696 HWREG32(__getBurstProgramRegs[ii]) |=
1697 ~(HWREG32(__getBurstProgramRegs[ii]) | HWREG32(addr));
1698 addr += 4;
1699 }
1700
1701 /* Setting the wait state to account for the mode */
1702 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1703 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1704
1705 if (bankProgramStart != bankProgramEnd)
1706 {
1707 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1708 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1709 }
1710
1711 }
__FlashCtl_A_remaskBurstDataPost(uint32_t addr,uint32_t size)1712 void __FlashCtl_A_remaskBurstDataPost(uint32_t addr, uint32_t size)
1713 {
1714 uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1715 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1716
1717 /* Waiting for idle status */
1718 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1719 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0)
1720 {
1721 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT,
1722 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1723 }
1724
1725 /* Changing the waitstate and read mode of whichever bank we are in */
1726 /* Finding out which bank we are in */
1727 if (addr >= SysCtl_A_getFlashSize())
1728 {
1729 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__;
1730 } else
1731 {
1732 bank1Start = SysCtl_A_getFlashSize() / 2;
1733 }
1734
1735 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1736 bankProgramEnd = (addr + size) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1;
1737
1738 /* Saving the current wait states and read mode */
1739 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart);
1740 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart);
1741 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1742 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE);
1743
1744 if (bankProgramStart != bankProgramEnd)
1745 {
1746 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd);
1747 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd);
1748 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1749 FlashCtl_A_setReadMode(bankProgramEnd,
1750 FLASH_A_PROGRAM_VERIFY_READ_MODE);
1751 }
1752
1753 /* Going through each BURST program register and masking out for post
1754 * verifcation if needed
1755 */
1756 size = (size / 4);
1757 for (ii = 0; ii < size; ii++)
1758 {
1759 HWREG32(__getBurstProgramRegs[ii]) = ~(~(HWREG32(
1760 __getBurstProgramRegs[ii])) & HWREG32(addr));
1761
1762 addr += 4;
1763 }
1764
1765 /* Setting the wait state to account for the mode */
1766 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode);
1767 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState);
1768
1769 if (bankProgramStart != bankProgramEnd)
1770 {
1771 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode);
1772 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState);
1773 }
1774 }
1775
1776 #endif /* __MCU_HAS_FLCTL_A__ */
1777
1778