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