xref: /btstack/port/msp432p401lp-cc256x/ti/devices/msp432p4xx/driverlib/flash_a.c (revision 5fd0122a3e19d95e11e1f3eb8a08a2b2acb2557e)
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