]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil/driverlib/flash.c
Update MSP432 projects to use updated driver library files.
[freertos] / FreeRTOS / Demo / CORTEX_M4F_MSP432_LaunchPad_IAR_CCS_Keil / driverlib / flash.c
1 /*
2  * -------------------------------------------
3  *    MSP432 DriverLib - v3_10_00_09 
4  * -------------------------------------------
5  *
6  * --COPYRIGHT--,BSD,BSD
7  * Copyright (c) 2014, Texas Instruments Incorporated
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * *  Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  *
17  * *  Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * *  Neither the name of Texas Instruments Incorporated nor the names of
22  *    its contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  * --/COPYRIGHT--*/
37 /* Standard Includes */
38 #include <stdint.h>
39
40 /* DriverLib Includes */
41 #include <flash.h>
42 #include <debug.h>
43 #include <interrupt.h>
44 #include <msp.h>
45 #include <cpu.h>
46 #include <rom.h>
47 #include <sysctl.h>
48 #include <hw_memmap.h>
49
50 static const uint32_t MAX_ERASE_NO_TLV = 50;
51 static const uint32_t MAX_PROGRAM_NO_TLV = 5;
52
53 static volatile uint32_t* __getBurstProgramRegs[16] =
54 { &FLCTL->PRGBRST_DATA0_0, &FLCTL->PRGBRST_DATA0_1,
55 &FLCTL->PRGBRST_DATA0_2, &FLCTL->PRGBRST_DATA0_3,
56 &FLCTL->PRGBRST_DATA1_0, &FLCTL->PRGBRST_DATA1_1,
57 &FLCTL->PRGBRST_DATA1_2, &FLCTL->PRGBRST_DATA1_3,
58 &FLCTL->PRGBRST_DATA2_0, &FLCTL->PRGBRST_DATA2_1,
59 &FLCTL->PRGBRST_DATA2_2, &FLCTL->PRGBRST_DATA2_3,
60 &FLCTL->PRGBRST_DATA3_0, &FLCTL->PRGBRST_DATA3_1,
61 &FLCTL->PRGBRST_DATA3_2, &FLCTL->PRGBRST_DATA3_3 };
62
63 static uint32_t getUserFlashSector(uint32_t addr)
64 {
65     if (addr > 0x1ffff)
66     {
67         addr = addr - 0x20000;
68     }
69
70     switch (addr)
71     {
72     case 0:
73         return FLASH_SECTOR0;
74     case 0x1000:
75         return FLASH_SECTOR1;
76     case 0x2000:
77         return FLASH_SECTOR2;
78     case 0x3000:
79         return FLASH_SECTOR3;
80     case 0x4000:
81         return FLASH_SECTOR4;
82     case 0x5000:
83         return FLASH_SECTOR5;
84     case 0x6000:
85         return FLASH_SECTOR6;
86     case 0x7000:
87         return FLASH_SECTOR7;
88     case 0x8000:
89         return FLASH_SECTOR8;
90     case 0x9000:
91         return FLASH_SECTOR9;
92     case 0xA000:
93         return FLASH_SECTOR10;
94     case 0xB000:
95         return FLASH_SECTOR11;
96     case 0xC000:
97         return FLASH_SECTOR12;
98     case 0xD000:
99         return FLASH_SECTOR13;
100     case 0xE000:
101         return FLASH_SECTOR14;
102     case 0xF000:
103         return FLASH_SECTOR15;
104     case 0x10000:
105         return FLASH_SECTOR16;
106     case 0x11000:
107         return FLASH_SECTOR17;
108     case 0x12000:
109         return FLASH_SECTOR18;
110     case 0x13000:
111         return FLASH_SECTOR19;
112     case 0x14000:
113         return FLASH_SECTOR20;
114     case 0x15000:
115         return FLASH_SECTOR21;
116     case 0x16000:
117         return FLASH_SECTOR22;
118     case 0x17000:
119         return FLASH_SECTOR23;
120     case 0x18000:
121         return FLASH_SECTOR24;
122     case 0x19000:
123         return FLASH_SECTOR25;
124     case 0x1A000:
125         return FLASH_SECTOR26;
126     case 0x1B000:
127         return FLASH_SECTOR27;
128     case 0x1C000:
129         return FLASH_SECTOR28;
130     case 0x1D000:
131         return FLASH_SECTOR29;
132     case 0x1E000:
133         return FLASH_SECTOR30;
134     case 0x1F000:
135         return FLASH_SECTOR31;
136     default:
137         ASSERT(false);
138         return 0;
139     }
140 }
141
142 void FlashCtl_getMemoryInfo(uint32_t addr, uint32_t *sectorNum,
143         uint32_t *bankNum)
144 {
145     uint32_t bankLimit;
146
147     bankLimit = SysCtl_getFlashSize() / 2;
148
149     if (addr > bankLimit)
150     {
151         *(sectorNum) = FLASH_BANK1;
152         addr = (addr - bankLimit);
153     } else
154     {
155         *(sectorNum) = FLASH_BANK0;
156     }
157
158     *(bankNum) = (addr - __MAIN_MEMORY_START__) / 4096;
159 }
160
161 static bool _FlashCtl_Program8(uint32_t src, uint32_t dest, uint32_t mTries)
162 {
163     uint32_t ii;
164     uint8_t data;
165
166     /* Enabling the correct verification settings  */
167     FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
168     FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
169
170     data = HWREG8(src);
171
172     for (ii = 0; ii < mTries; ii++)
173     {
174         /* Clearing flags */
175         FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED
176                 | FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE);
177
178         HWREG8(dest) = data;
179
180         while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE))
181         {
182             __no_operation();
183         }
184
185         /* Pre-Verify */
186         if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS)
187                 && BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS)))
188         {
189             data = __FlashCtl_remaskData8Pre(data, dest);
190
191             if (data != 0xFF)
192             {
193                 FlashCtl_clearProgramVerification(FLASH_REGPRE);
194                 continue;
195             }
196
197         }
198
199         /* Post Verify */
200         if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS)))
201         {
202             data = __FlashCtl_remaskData8Post(data, dest);
203
204             /* Seeing if we actually need to do another pulse */
205             if (data == 0xFF)
206                 return true;
207
208             FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
209             continue;
210         }
211
212         /* If we got this far, return true */
213         return true;
214
215     }
216
217     return false;
218
219 }
220
221 static bool _FlashCtl_Program32(uint32_t src, uint32_t dest, uint32_t mTries)
222 {
223     uint32_t ii;
224     uint32_t data;
225
226     /* Enabling the correct verification settings  */
227     FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
228     FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
229
230     data = HWREG32(src);
231
232     for (ii = 0; ii < mTries; ii++)
233     {
234         /* Clearing flags */
235         FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED
236                 | FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE);
237
238         HWREG32(dest) = data;
239
240         while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE))
241         {
242             __no_operation();
243         }
244
245         /* Pre-Verify */
246         if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS)
247                 && BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS)))
248         {
249             data = __FlashCtl_remaskData32Pre(data, dest);
250
251             if (data != 0xFFFFFFFF)
252             {
253
254                 FlashCtl_clearProgramVerification(FLASH_REGPRE);
255                 continue;
256             }
257
258         }
259
260         /* Post Verify */
261         if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS)))
262         {
263             data = __FlashCtl_remaskData32Post(data, dest);
264
265             /* Seeing if we actually need to do another pulse */
266             if (data == 0xFFFFFFFF)
267                 return true;
268
269             FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
270             continue;
271         }
272
273         /* If we got this far, return true */
274         return true;
275
276     }
277
278     return false;
279
280 }
281
282 static bool _FlashCtl_ProgramBurst(uint32_t src, uint32_t dest, uint32_t length,
283         uint32_t mTries)
284 {
285     uint32_t bCalc, otpOffset, ii, jj;
286     bool res;
287
288     /* Setting verification */
289     FlashCtl_clearProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
290     FlashCtl_setProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
291
292     /* Assume Failure */
293     res = false;
294
295     /* Waiting for idle status */
296     while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
297             != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
298     {
299         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
300                 FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
301     }
302
303     /* Setting/clearing INFO flash flags as appropriate */
304     if (dest > __MAIN_MEMORY_END__)
305     {
306         FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
307                 & ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_1;
308         otpOffset = __INFO_FLASH_TECH_START__;
309     } else
310     {
311         FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
312                 & ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_0;
313         otpOffset = __MAIN_MEMORY_START__;
314     }
315
316     bCalc = 0;
317     FLCTL->PRGBRST_STARTADDR = (dest - otpOffset);
318
319     /* Initially populating the burst registers */
320     while (bCalc < 16 && length != 0)
321     {
322         HWREG32(__getBurstProgramRegs[bCalc]) = HWREG32(src);
323         bCalc++;
324         length -= 4;
325         src += 4;
326     }
327
328     for (ii = 0; ii < mTries; ii++)
329     {
330         /* Clearing Flags */
331         FLCTL->CLRIFG |= (FLASH_BRSTPRGM_COMPLETE | FLASH_POSTVERIFY_FAILED
332                 | FLASH_PREVERIFY_FAILED);
333
334         /* Waiting for idle status */
335         while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
336                 != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
337         {
338             BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
339                     FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
340         }
341
342         /* Start the burst program */
343         FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
344                 & ~(FLCTL_PRGBRST_CTLSTAT_LEN_MASK))
345                 | ((bCalc / 4) << FLASH_BURST_PRG_BIT)
346                 | FLCTL_PRGBRST_CTLSTAT_START;
347
348         /* Waiting for the burst to complete */
349         while ((FLCTL->PRGBRST_CTLSTAT &
350         FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
351                 != FLASH_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE)
352         {
353             __no_operation();
354         }
355
356         /* Checking for errors and clearing/masking */
357
358         /* Address Error */
359         if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
360                 FLCTL_PRGBRST_CTLSTAT_ADDR_ERR_OFS))
361         {
362             goto BurstCleanUp;
363         }
364
365         /* Pre-Verify Error */
366         if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
367                 FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) && BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
368                         FLCTL_PRGBRST_CTLSTAT_PRE_ERR_OFS))
369         {
370             __FlashCtl_remaskBurstDataPre(dest, bCalc * 4);
371
372             for (jj = 0; jj < bCalc; jj++)
373             {
374                 if (HWREG32(__getBurstProgramRegs[jj])
375                         != 0xFFFFFFFF)
376                 {
377                     FlashCtl_clearProgramVerification(FLASH_BURSTPRE);
378                     break;
379                 }
380             }
381
382             if (jj != bCalc)
383                 continue;
384         }
385
386         /* Post-Verify Error */
387         if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
388                 FLCTL_PRGBRST_CTLSTAT_PST_ERR_OFS))
389         {
390             __FlashCtl_remaskBurstDataPost(dest, bCalc * 4);
391
392             for (jj = 0; jj < bCalc; jj++)
393             {
394                 if ((HWREG32(__getBurstProgramRegs[jj]))
395                         != 0xFFFFFFFF)
396                 {
397                     FlashCtl_setProgramVerification(
398                             FLASH_BURSTPOST | FLASH_BURSTPRE);
399                     break;
400                 }
401             }
402
403             if (jj != bCalc)
404                 continue;
405
406         }
407
408         /* If we got this far, the program happened */
409         res = true;
410         goto BurstCleanUp;
411     }
412
413     BurstCleanUp:
414     /* Waiting for idle status */
415     while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
416             != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
417     {
418         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
419                 FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
420     }
421     return res;
422 }
423
424 void FlashCtl_enableReadBuffering(uint_fast8_t memoryBank,
425         uint_fast8_t accessMethod)
426 {
427     if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ)
428         BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 1;
429     else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ)
430         BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 1;
431     else if (memoryBank == FLASH_BANK0
432             && accessMethod == FLASH_INSTRUCTION_FETCH)
433         BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 1;
434     else if (memoryBank == FLASH_BANK1
435             && accessMethod == FLASH_INSTRUCTION_FETCH)
436         BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 1;
437     else
438         ASSERT(false);
439 }
440
441 void FlashCtl_disableReadBuffering(uint_fast8_t memoryBank,
442         uint_fast8_t accessMethod)
443 {
444     if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ)
445         BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 0;
446     else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ)
447         BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 0;
448     else if (memoryBank == FLASH_BANK0
449             && accessMethod == FLASH_INSTRUCTION_FETCH)
450         BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 0;
451     else if (memoryBank == FLASH_BANK1
452             && accessMethod == FLASH_INSTRUCTION_FETCH)
453         BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 0;
454     else
455         ASSERT(false);
456 }
457
458 bool FlashCtl_unprotectSector(uint_fast8_t memorySpace, uint32_t sectorMask)
459 {
460     switch (memorySpace)
461     {
462     case FLASH_MAIN_MEMORY_SPACE_BANK0:
463         FLCTL->BANK0_MAIN_WEPROT &= ~sectorMask;
464         break;
465     case FLASH_MAIN_MEMORY_SPACE_BANK1:
466         FLCTL->BANK1_MAIN_WEPROT &= ~sectorMask;
467         break;
468     case FLASH_INFO_MEMORY_SPACE_BANK0:
469         ASSERT(sectorMask <= 0x04);
470         FLCTL->BANK0_INFO_WEPROT &= ~sectorMask;
471         break;
472     case FLASH_INFO_MEMORY_SPACE_BANK1:
473         ASSERT(sectorMask <= 0x04);
474         FLCTL->BANK1_INFO_WEPROT &= ~sectorMask;
475         break;
476
477     default:
478         ASSERT(false);
479
480     }
481
482     return !FlashCtl_isSectorProtected(memorySpace, sectorMask);
483 }
484
485 bool FlashCtl_protectSector(uint_fast8_t memorySpace, uint32_t sectorMask)
486 {
487     switch (memorySpace)
488     {
489     case FLASH_MAIN_MEMORY_SPACE_BANK0:
490         FLCTL->BANK0_MAIN_WEPROT |= sectorMask;
491         break;
492     case FLASH_MAIN_MEMORY_SPACE_BANK1:
493         FLCTL->BANK1_MAIN_WEPROT |= sectorMask;
494         break;
495     case FLASH_INFO_MEMORY_SPACE_BANK0:
496         ASSERT(sectorMask <= 0x04);
497         FLCTL->BANK0_INFO_WEPROT |= sectorMask;
498         break;
499     case FLASH_INFO_MEMORY_SPACE_BANK1:
500         ASSERT(sectorMask <= 0x04);
501         FLCTL->BANK1_INFO_WEPROT |= sectorMask;
502         break;
503
504     default:
505         ASSERT(false);
506
507     }
508
509     return FlashCtl_isSectorProtected(memorySpace, sectorMask);
510 }
511
512 bool FlashCtl_isSectorProtected(uint_fast8_t memorySpace, uint32_t sector)
513 {
514     switch (memorySpace)
515     {
516     case FLASH_MAIN_MEMORY_SPACE_BANK0:
517         return FLCTL->BANK0_MAIN_WEPROT & sector;
518     case FLASH_MAIN_MEMORY_SPACE_BANK1:
519         return FLCTL->BANK1_MAIN_WEPROT & sector;
520     case FLASH_INFO_MEMORY_SPACE_BANK0:
521         ASSERT(sector <= 0x04);
522         return FLCTL->BANK0_INFO_WEPROT & sector;
523     case FLASH_INFO_MEMORY_SPACE_BANK1:
524         ASSERT(sector <= 0x04);
525         return FLCTL->BANK1_INFO_WEPROT & sector;
526     default:
527         return false;
528     }
529 }
530
531 bool FlashCtl_verifyMemory(void* verifyAddr, uint32_t length,
532         uint_fast8_t pattern)
533 {
534     uint32_t memoryPattern, addr, otpOffset;
535     uint32_t b0WaitState, b1WaitState, intStatus;
536     uint32_t bankOneStart, startBank, endBank;
537     uint_fast8_t b0readMode, b1readMode;
538     uint_fast8_t memoryType;
539     bool res;
540
541     ASSERT(pattern == FLASH_0_PATTERN || pattern == FLASH_1_PATTERN);
542
543     /* Saving interrupt context and disabling interrupts for program
544      * operation
545      */
546     intStatus = CPU_primask();
547     Interrupt_disableMaster();
548
549     /* Casting and determining the memory that we need to use */
550     addr = (uint32_t) verifyAddr;
551     memoryType =
552             (addr > __MAIN_MEMORY_END__) ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
553
554     /* Assuming Failure */
555     res = false;
556
557     /* Finding out which bank we are in */
558     if(addr >  SysCtl_getFlashSize())
559     {
560         bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
561     }
562     else
563     {
564         bankOneStart = SysCtl_getFlashSize() / 2;
565     }
566     startBank = addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
567     endBank = (addr + length) < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
568
569     /* Saving context and changing read modes */
570     b0WaitState = FlashCtl_getWaitState(startBank);
571     b0readMode = FlashCtl_getReadMode(startBank);
572
573     /* Setting the wait state to account for the mode */
574     FlashCtl_setWaitState(startBank, (2 * b0WaitState) + 1);
575
576     if(startBank != endBank)
577     {
578         b1WaitState = FlashCtl_getWaitState(endBank);
579         b1readMode = FlashCtl_getReadMode(endBank);
580         FlashCtl_setWaitState(endBank, (2 * b1WaitState) + 1);
581     }
582
583     /* Changing to the relevant VERIFY mode */
584     if (pattern == FLASH_1_PATTERN)
585     {
586         FlashCtl_setReadMode(startBank, FLASH_ERASE_VERIFY_READ_MODE);
587
588         if(startBank != endBank)
589         {
590             FlashCtl_setReadMode(endBank, FLASH_ERASE_VERIFY_READ_MODE);
591         }
592
593         memoryPattern = 0xFFFFFFFF;
594     } else
595     {
596         FlashCtl_setReadMode(startBank, FLASH_PROGRAM_VERIFY_READ_MODE);
597
598         if(startBank != endBank)
599         {
600             FlashCtl_setReadMode(endBank, FLASH_PROGRAM_VERIFY_READ_MODE);
601         }
602
603         memoryPattern = 0;
604     }
605
606     /* Taking care of byte accesses */
607     while ((addr & 0x03) && (length > 0))
608     {
609         if (HWREG8(addr++) != ((uint8_t) memoryPattern))
610             goto FlashVerifyCleanup;
611         length--;
612     }
613
614     /* Making sure we are aligned by 128-bit address */
615     while (((addr & 0x0F)) && (length > 3))
616     {
617         if (HWREG32(addr) != memoryPattern)
618             goto FlashVerifyCleanup;
619
620         addr = addr + 4;
621         length = length - 4;
622     }
623
624     /* Burst Verify */
625     if (length > 63)
626     {
627         /* Setting/clearing INFO flash flags as appropriate */
628         if (addr > __MAIN_MEMORY_END__)
629         {
630             FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT
631                     & ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK)
632                     | FLCTL_RDBRST_CTLSTAT_MEM_TYPE_1;
633             otpOffset = __INFO_FLASH_TECH_START__;
634         } else
635         {
636             FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT
637                     & ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK)
638                     | FLCTL_RDBRST_CTLSTAT_MEM_TYPE_0;
639             otpOffset = __MAIN_MEMORY_START__;
640         }
641
642         /* Clearing any lingering fault flags  and preparing burst verify*/
643         BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
644                 FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
645         FLCTL->RDBRST_FAILCNT = 0;
646         FLCTL->RDBRST_STARTADDR = addr - otpOffset;
647         FLCTL->RDBRST_LEN = (length & 0xFFFFFFF0);
648         addr += FLCTL->RDBRST_LEN;
649         length = length & 0xF;
650
651         /* Starting Burst Verify */
652         FLCTL->RDBRST_CTLSTAT = (FLCTL_RDBRST_CTLSTAT_STOP_FAIL | pattern
653                 | memoryType | FLCTL_RDBRST_CTLSTAT_START);
654
655         /* While the burst read hasn't finished */
656         while ((FLCTL->RDBRST_CTLSTAT & FLCTL_RDBRST_CTLSTAT_BRST_STAT_MASK)
657                 != FLCTL_RDBRST_CTLSTAT_BRST_STAT_3)
658         {
659             __no_operation();
660         }
661
662         /* Checking  for a verification/access error/failure */
663         if (BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
664                 FLCTL_RDBRST_CTLSTAT_CMP_ERR_OFS)
665                 || BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
666                         FLCTL_RDBRST_CTLSTAT_ADDR_ERR_OFS)
667                 || FLCTL->RDBRST_FAILCNT)
668         {
669             goto FlashVerifyCleanup;
670         }
671     }
672
673     /* Remaining Words */
674     while (length > 3)
675     {
676         if (HWREG32(addr) != memoryPattern)
677             goto FlashVerifyCleanup;
678
679         addr = addr + 4;
680         length = length - 4;
681     }
682
683     /* Remaining Bytes */
684     while (length > 0)
685     {
686         if (HWREG8(addr++) != ((uint8_t) memoryPattern))
687             goto FlashVerifyCleanup;
688         length--;
689     }
690
691     /* If we got this far, that means it no failure happened */
692     res = true;
693
694     FlashVerifyCleanup:
695
696     /* Clearing the Read Burst flag and returning */
697     BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
698             FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
699
700     FlashCtl_setReadMode(startBank, b0readMode);
701     FlashCtl_setWaitState(startBank, b0WaitState);
702
703     if(startBank != endBank)
704     {
705         FlashCtl_setReadMode(endBank, b1readMode);
706         FlashCtl_setWaitState(endBank, b1WaitState);
707     }
708
709     if(intStatus == 0)
710         Interrupt_enableMaster();
711
712     return res;
713 }
714
715 bool FlashCtl_setReadMode(uint32_t flashBank, uint32_t readMode)
716 {
717
718     if (FLCTL->POWER_STAT & FLCTL_POWER_STAT_RD_2T)
719         return false;
720
721     if (flashBank == FLASH_BANK0)
722     {
723         FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL
724                 & ~FLCTL_BANK0_RDCTL_RD_MODE_MASK) | readMode;
725         while ((FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_MASK)
726                         != readMode)
727             ;
728     } else if (flashBank == FLASH_BANK1)
729     {
730         FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL
731                 & ~FLCTL_BANK1_RDCTL_RD_MODE_MASK) | readMode;
732         while ((FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_MASK)
733                         != readMode)
734             ;
735     } else
736     {
737         ASSERT(false);
738         return false;
739     }
740
741     return true;
742 }
743
744 uint32_t FlashCtl_getReadMode(uint32_t flashBank)
745 {
746     if (flashBank == FLASH_BANK0)
747     {
748         return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_MASK);
749     } else if (flashBank == FLASH_BANK1)
750     {
751         return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_MASK);
752     } else
753     {
754         ASSERT(false);
755         return 0;
756     }
757 }
758
759 void FlashCtl_initiateMassErase(void)
760 {
761     /* Clearing old mass erase flags */
762     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
763
764     /* Performing the mass erase */
765     FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE
766             | FLCTL_ERASE_CTLSTAT_START);
767 }
768
769 bool FlashCtl_performMassErase(void)
770 {
771     uint32_t userFlash, ii, sector, intStatus;
772     bool res;
773
774     /* Saving interrupt context and disabling interrupts for program
775      * operation
776      */
777     intStatus = CPU_primask();
778     Interrupt_disableMaster();
779
780     /* Assume Failure */
781     res = false;
782
783     /* Clearing old mass erase flags */
784     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
785
786     /* Performing the mass erase */
787     FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE
788             | FLCTL_ERASE_CTLSTAT_START);
789
790     while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
791             == FLCTL_ERASE_CTLSTAT_STATUS_1
792             || (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
793                     == FLCTL_ERASE_CTLSTAT_STATUS_2)
794     {
795         __no_operation();
796     }
797
798     /* Return false if an address error */
799     if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS))
800         goto MassEraseCleanup;
801
802     /* Changing to erase verify */
803     userFlash = SysCtl_getFlashSize() / 2;
804
805     for (ii = __MAIN_MEMORY_START__; ii < userFlash; ii += 4096)
806     {
807         sector = getUserFlashSector(ii);
808
809         if (!((FLCTL->BANK0_MAIN_WEPROT) & sector))
810         {
811             if (!FlashCtl_verifyMemory((void*) ii, 4096, FLASH_1_PATTERN))
812             {
813                 if (!FlashCtl_eraseSector(ii))
814                     goto MassEraseCleanup;
815             }
816         }
817
818         if (!(FLCTL->BANK1_MAIN_WEPROT & sector))
819         {
820             if (!FlashCtl_verifyMemory((void*) (ii + userFlash), 4096,
821             FLASH_1_PATTERN))
822             {
823                 if (!FlashCtl_eraseSector(ii + userFlash))
824                     goto MassEraseCleanup;
825             }
826         }
827
828         if (sector < FLCTL_BANK0_MAIN_WEPROT_PROT2)
829         {
830             if (!(FLCTL->BANK0_INFO_WEPROT & sector))
831             {
832                 if (!FlashCtl_verifyMemory(
833                         (void*) (ii + __INFO_FLASH_TECH_START__), 4096,
834                         FLASH_1_PATTERN))
835                 {
836                     if (!FlashCtl_eraseSector(ii + __INFO_FLASH_TECH_START__))
837                         goto MassEraseCleanup;
838                 }
839             }
840
841             if (!(FLCTL->BANK1_INFO_WEPROT & sector))
842             {
843                 if (!FlashCtl_verifyMemory((void*) (ii + (0x202000)), 4096,
844                 FLASH_1_PATTERN))
845                 {
846                     if (!FlashCtl_eraseSector(ii + (0x202000)))
847                         goto MassEraseCleanup;
848                 }
849             }
850
851         }
852     }
853
854     /* If we got this far, the mass erase happened */
855     res = true;
856
857     MassEraseCleanup:
858     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
859
860     if(intStatus == 0)
861         Interrupt_enableMaster();
862
863     return res;
864 }
865
866 bool FlashCtl_eraseSector(uint32_t addr)
867 {
868     uint_fast8_t memoryType, ii;
869     uint32_t otpOffset = 0;
870     uint32_t intStatus;
871     uint_fast8_t mTries, tlvLength;
872     SysCtl_FlashTLV_Info *flInfo;
873     bool res;
874
875     /* Saving interrupt context and disabling interrupts for program
876      * operation
877      */
878     intStatus = CPU_primask();
879     Interrupt_disableMaster();
880     
881     /* Assuming Failure */
882     res = false;
883
884     memoryType =
885             addr > __MAIN_MEMORY_END__ ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
886
887     /* Parsing the TLV and getting the maximum erase pulses */
888     SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
889
890     if (tlvLength == 0 || flInfo->maxErasePulses == 0)
891     {
892         mTries = MAX_ERASE_NO_TLV;
893     } else
894     {
895         mTries = flInfo->maxErasePulses;
896     }
897
898     /* We can only erase on 4KB boundaries */
899     while (addr & 0xFFF)
900     {
901         addr--;
902     }
903
904     /* Clearing the status */
905     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
906
907     if (memoryType == FLASH_INFO_SPACE)
908     {
909         otpOffset = __INFO_FLASH_TECH_START__;
910         FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
911                 & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1;
912
913     } else
914     {
915         otpOffset = __MAIN_MEMORY_START__;
916         FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
917                 & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0;
918     }
919
920     /* Clearing old flags  and setting up the erase */
921     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0;
922     FLCTL->ERASE_SECTADDR = addr - otpOffset;
923
924     for (ii = 0; ii < mTries; ii++)
925     {
926         /* Clearing the status */
927         BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) =
928                 1;
929
930         /* Starting the erase */
931         BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
932                 FLCTL_ERASE_CTLSTAT_START_OFS) = 1;
933
934         while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
935                 == FLCTL_ERASE_CTLSTAT_STATUS_1
936                 || (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
937                         == FLCTL_ERASE_CTLSTAT_STATUS_2)
938         {
939             __no_operation();
940         }
941
942         /* Return false if an address error */
943         if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
944                 FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS))
945         {
946             goto SectorEraseCleanup;
947         }
948         /* Erase verifying */
949         if (FlashCtl_verifyMemory((void*) addr, 4096, FLASH_1_PATTERN))
950         {
951             res = true;
952             goto SectorEraseCleanup;
953         }
954
955     }
956
957 SectorEraseCleanup:
958
959     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
960     
961     if(intStatus == 0)
962         Interrupt_enableMaster();
963
964     return res;
965 }
966
967 void FlashCtl_initiateSectorErase(uint32_t addr)
968 {
969     uint_fast8_t memoryType;
970     uint32_t otpOffset = 0;
971
972     memoryType =
973             addr > __MAIN_MEMORY_END__ ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
974
975     /* We can only erase on 4KB boundaries */
976     while (addr & 0xFFF)
977     {
978         addr--;
979     }
980
981     /* Clearing the status */
982     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
983
984     if (memoryType == FLASH_INFO_SPACE)
985     {
986         otpOffset = __INFO_FLASH_TECH_START__;
987         FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
988                 & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1;
989
990     } else
991     {
992         otpOffset = __MAIN_MEMORY_START__;
993         FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
994                 & ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0;
995     }
996
997     /* Clearing old flags  and setting up the erase */
998     BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0;
999     FLCTL->ERASE_SECTADDR = addr - otpOffset;
1000
1001     /* Starting the erase */
1002     BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
1003             FLCTL_ERASE_CTLSTAT_START_OFS) = 1;
1004
1005 }
1006
1007 bool FlashCtl_programMemory(void* src, void* dest, uint32_t length)
1008 {
1009     uint32_t destAddr, srcAddr, burstLength, intStatus;
1010     bool res;
1011     uint_fast8_t mTries, tlvLength;
1012     SysCtl_FlashTLV_Info *flInfo;
1013
1014     /* Saving interrupt context and disabling interrupts for program
1015      * operation
1016      */
1017     intStatus = CPU_primask();
1018     Interrupt_disableMaster();
1019
1020     /* Parsing the TLV and getting the maximum erase pulses */
1021     SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
1022
1023     if (tlvLength == 0 || flInfo->maxProgramPulses == 0)
1024     {
1025         mTries = MAX_PROGRAM_NO_TLV;
1026     } else
1027     {
1028         mTries = flInfo->maxProgramPulses;
1029     }
1030
1031     /* Casting to integers */
1032     srcAddr = (uint32_t) src;
1033     destAddr = (uint32_t) dest;
1034
1035     /* Enabling word programming */
1036     FlashCtl_enableWordProgramming(FLASH_IMMEDIATE_WRITE_MODE);
1037
1038     /* Assume failure */
1039     res = false;
1040
1041     /* Taking care of byte accesses */
1042     while ((destAddr & 0x03) && length > 0)
1043     {
1044         if (!_FlashCtl_Program8(srcAddr, destAddr, mTries))
1045         {
1046             goto FlashProgramCleanUp;
1047         } else
1048         {
1049             srcAddr++;
1050             destAddr++;
1051             length--;
1052         }
1053     }
1054
1055     /* Taking care of word accesses */
1056     while ((destAddr & 0x0F) && (length > 3))
1057     {
1058         if (!_FlashCtl_Program32(srcAddr, destAddr, mTries))
1059         {
1060             goto FlashProgramCleanUp;
1061         } else
1062         {
1063             srcAddr += 4;
1064             destAddr += 4;
1065             length -= 4;
1066         }
1067     }
1068
1069     /* Taking care of burst programs */
1070     while (length > 16)
1071     {
1072         burstLength = length > 63 ? 64 : length & 0xFFFFFFF0;
1073
1074         if (!_FlashCtl_ProgramBurst(srcAddr, destAddr, burstLength, mTries))
1075         {
1076             goto FlashProgramCleanUp;
1077         } else
1078         {
1079             srcAddr += burstLength;
1080             destAddr += burstLength;
1081             length -= burstLength;
1082         }
1083     }
1084
1085     /* Remaining word accesses */
1086     while (length > 3)
1087     {
1088         if (!_FlashCtl_Program32(srcAddr, destAddr, mTries))
1089         {
1090             goto FlashProgramCleanUp;
1091         } else
1092         {
1093             srcAddr+=4;
1094             destAddr+=4;
1095             length-=4;
1096         }
1097     }
1098
1099     /* Remaining byte accesses */
1100     while (length > 0)
1101     {
1102         if (!_FlashCtl_Program8(srcAddr, destAddr, mTries))
1103         {
1104             goto FlashProgramCleanUp;
1105         } else
1106         {
1107             srcAddr++;
1108             destAddr++;
1109             length--;
1110         }
1111     }
1112
1113     /* If we got this far that means that we succeeded  */
1114     res = true;
1115
1116     FlashProgramCleanUp:
1117
1118     if(intStatus == 0)
1119         Interrupt_enableMaster();
1120
1121     FlashCtl_disableWordProgramming();
1122     return res;
1123
1124 }
1125 void FlashCtl_setProgramVerification(uint32_t verificationSetting)
1126 {
1127     if ((verificationSetting & FLASH_BURSTPOST))
1128         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1129                 FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1;
1130
1131     if ((verificationSetting & FLASH_BURSTPRE))
1132         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1133                 FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1;
1134
1135     if ((verificationSetting & FLASH_REGPRE))
1136         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 1;
1137
1138     if ((verificationSetting & FLASH_REGPOST))
1139         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 1;
1140 }
1141
1142 void FlashCtl_clearProgramVerification(uint32_t verificationSetting)
1143 {
1144     if ((verificationSetting & FLASH_BURSTPOST))
1145         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1146                 FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0;
1147
1148     if ((verificationSetting & FLASH_BURSTPRE))
1149         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1150                 FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0;
1151
1152     if ((verificationSetting & FLASH_REGPRE))
1153         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 0;
1154
1155     if ((verificationSetting & FLASH_REGPOST))
1156         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 0;
1157
1158 }
1159
1160 void FlashCtl_enableWordProgramming(uint32_t mode)
1161 {
1162     if (mode == FLASH_IMMEDIATE_WRITE_MODE)
1163     {
1164         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1;
1165         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 0;
1166
1167     } else if (mode == FLASH_COLLATED_WRITE_MODE)
1168     {
1169         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1;
1170         BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 1;
1171     }
1172 }
1173
1174 void FlashCtl_disableWordProgramming(void)
1175 {
1176     BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 0;
1177 }
1178
1179 uint32_t FlashCtl_isWordProgrammingEnabled(void)
1180 {
1181     if (!BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS))
1182     {
1183         return 0;
1184     } else if (BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS))
1185         return FLASH_COLLATED_WRITE_MODE;
1186     else
1187         return FLASH_IMMEDIATE_WRITE_MODE;
1188 }
1189
1190 void FlashCtl_setWaitState(uint32_t flashBank, uint32_t waitState)
1191 {
1192     if (flashBank == FLASH_BANK0)
1193     {
1194         FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL
1195                 & ~FLCTL_BANK0_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK0_RDCTL_WAIT_OFS);
1196     } else if (flashBank == FLASH_BANK1)
1197     {
1198         FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL
1199                 & ~FLCTL_BANK1_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK1_RDCTL_WAIT_OFS);
1200     } else
1201     {
1202         ASSERT(false);
1203     }
1204 }
1205
1206 uint32_t FlashCtl_getWaitState(uint32_t flashBank)
1207 {
1208     if (flashBank == FLASH_BANK0)
1209     {
1210         return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_WAIT_MASK) >> FLCTL_BANK0_RDCTL_WAIT_OFS;
1211     } else if (flashBank == FLASH_BANK1)
1212     {
1213         return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_WAIT_MASK) >> FLCTL_BANK1_RDCTL_WAIT_OFS;
1214     } else
1215     {
1216         ASSERT(false);
1217         return 0;
1218     }
1219 }
1220
1221 void FlashCtl_enableInterrupt(uint32_t flags)
1222 {
1223     FLCTL->IE |= flags;
1224 }
1225
1226 void FlashCtl_disableInterrupt(uint32_t flags)
1227 {
1228     FLCTL->IE &= ~flags;
1229 }
1230
1231 uint32_t FlashCtl_getInterruptStatus(void)
1232 {
1233     return FLCTL->IFG;
1234 }
1235
1236 uint32_t FlashCtl_getEnabledInterruptStatus(void)
1237 {
1238     return FlashCtl_getInterruptStatus() & FLCTL->IE;
1239 }
1240
1241 void FlashCtl_clearInterruptFlag(uint32_t flags)
1242 {
1243     FLCTL->CLRIFG |= flags;
1244 }
1245
1246 void FlashCtl_registerInterrupt(void (*intHandler)(void))
1247 {
1248     //
1249     // Register the interrupt handler, returning an error if an error occurs.
1250     //
1251     Interrupt_registerInterrupt(INT_FLCTL, intHandler);
1252
1253     //
1254     // Enable the system control interrupt.
1255     //
1256     Interrupt_enableInterrupt(INT_FLCTL);
1257 }
1258
1259 void FlashCtl_unregisterInterrupt(void)
1260 {
1261     //
1262     // Disable the interrupt.
1263     //
1264     Interrupt_disableInterrupt(INT_FLCTL);
1265
1266     //
1267     // Unregister the interrupt handler.
1268     //
1269     Interrupt_unregisterInterrupt(INT_FLCTL);
1270 }
1271
1272 uint8_t __FlashCtl_remaskData8Post(uint8_t data, uint32_t addr)
1273 {
1274     uint32_t readMode, waitState, bankProgram, bankOneStart;
1275
1276     /* Changing the waitstate and read mode of whichever bank we are in */
1277     /* Finding out which bank we are in */
1278     if(addr >  SysCtl_getFlashSize())
1279     {
1280         bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
1281     }
1282     else
1283     {
1284         bankOneStart = SysCtl_getFlashSize() / 2;
1285     }
1286
1287     bankProgram =
1288             addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
1289
1290     /* Saving the current wait states and read mode */
1291     waitState = FlashCtl_getWaitState(bankProgram);
1292     readMode = FlashCtl_getReadMode(bankProgram);
1293
1294     /* Setting the wait state to account for the mode */
1295     FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1);
1296
1297     /* Changing to PROGRAM VERIFY mode */
1298     FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE);
1299
1300     data = ~(~(data) & HWREG8(addr));
1301
1302     /* Setting the wait state to account for the mode */
1303     FlashCtl_setReadMode(bankProgram, readMode);
1304     FlashCtl_setWaitState(bankProgram, waitState);
1305
1306     return data;
1307 }
1308
1309 uint8_t __FlashCtl_remaskData8Pre(uint8_t data, uint32_t addr)
1310 {
1311     uint32_t readMode, waitState, bankProgram, bankOneStart;
1312
1313     /* Changing the waitstate and read mode of whichever bank we are in */
1314     /* Finding out which bank we are in */
1315     if(addr >  SysCtl_getFlashSize())
1316     {
1317         bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
1318     }
1319     else
1320     {
1321         bankOneStart = SysCtl_getFlashSize() / 2;
1322     }
1323
1324     bankProgram =
1325             addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
1326
1327     /* Saving the current wait states and read mode */
1328     waitState = FlashCtl_getWaitState(bankProgram);
1329     readMode = FlashCtl_getReadMode(bankProgram);
1330
1331     /* Setting the wait state to account for the mode */
1332     FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1);
1333
1334     /* Changing to PROGRAM VERIFY mode */
1335     FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE);
1336
1337     data |= ~(HWREG8(addr) | data);
1338
1339     /* Setting the wait state to account for the mode */
1340     FlashCtl_setReadMode(bankProgram, readMode);
1341     FlashCtl_setWaitState(bankProgram, waitState);
1342
1343     return data;
1344 }
1345
1346 uint32_t __FlashCtl_remaskData32Post(uint32_t data, uint32_t addr)
1347 {
1348     uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1349     uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1350
1351     /* Changing the waitstate and read mode of whichever bank we are in */
1352     /* Finding out which bank we are in */
1353     if(addr >  SysCtl_getFlashSize())
1354     {
1355         bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1356     }
1357     else
1358     {
1359         bank1Start = SysCtl_getFlashSize() / 2;
1360     }
1361
1362     bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1363     bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1364
1365     /* Saving the current wait states and read mode */
1366     b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1367     b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1368     FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1369     FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1370
1371     if (bankProgramStart != bankProgramEnd)
1372     {
1373         b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1374         b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1375         FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1376         FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1377     }
1378
1379     data = ~(~(data) & HWREG32(addr));
1380
1381     /* Setting the wait state to account for the mode */
1382     FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1383     FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1384
1385     if (bankProgramStart != bankProgramEnd)
1386     {
1387         FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1388         FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1389     }
1390
1391     return data;
1392 }
1393
1394 uint32_t __FlashCtl_remaskData32Pre(uint32_t data, uint32_t addr)
1395 {
1396     uint32_t bankProgramStart, bankProgramEnd, bank1Start;
1397     uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1398
1399     /* Changing the waitstate and read mode of whichever bank we are in */
1400     /* Finding out which bank we are in */
1401     if(addr >  SysCtl_getFlashSize())
1402     {
1403         bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1404     }
1405     else
1406     {
1407         bank1Start = SysCtl_getFlashSize() / 2;
1408     }
1409
1410     bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1411     bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1412
1413     /* Saving the current wait states and read mode */
1414     b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1415     b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1416     FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1417     FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1418
1419     if (bankProgramStart != bankProgramEnd)
1420     {
1421         b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1422         b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1423         FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1424         FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1425     }
1426
1427     data |= ~(HWREG32(addr) | data);
1428
1429     /* Setting the wait state to account for the mode */
1430     FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1431     FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1432
1433     if (bankProgramStart != bankProgramEnd)
1434     {
1435         FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1436         FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1437     }
1438
1439     return data;
1440 }
1441
1442 void __FlashCtl_remaskBurstDataPre(uint32_t addr, uint32_t size)
1443 {
1444
1445     uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1446     uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1447
1448     /* Waiting for idle status */
1449     while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1450             != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
1451     {
1452         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1453                 FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1454     }
1455
1456     /* Changing the waitstate and read mode of whichever bank we are in */
1457     /* Finding out which bank we are in */
1458     if(addr >  SysCtl_getFlashSize())
1459     {
1460         bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1461     }
1462     else
1463     {
1464         bank1Start = SysCtl_getFlashSize() / 2;
1465     }
1466
1467     bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1468     bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1469
1470     /* Saving the current wait states and read mode */
1471     b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1472     b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1473     FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1474     FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1475
1476     if (bankProgramStart != bankProgramEnd)
1477     {
1478         b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1479         b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1480         FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1481         FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1482     }
1483
1484     /* Going through each BURST program register and masking out for pre
1485      * verifcation
1486      */
1487     size = (size / 4);
1488     for (ii = 0; ii < size; ii++)
1489     {
1490         HWREG32(__getBurstProgramRegs[ii]) |=
1491                 ~(HWREG32(__getBurstProgramRegs[ii])
1492                         | HWREG32(addr));
1493         addr += 4;
1494     }
1495
1496     /* Setting the wait state to account for the mode */
1497     FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1498     FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1499
1500     if (bankProgramStart != bankProgramEnd)
1501     {
1502         FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1503         FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1504     }
1505
1506 }
1507 void __FlashCtl_remaskBurstDataPost(uint32_t addr, uint32_t size)
1508 {
1509     uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
1510     uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
1511
1512     /* Waiting for idle status */
1513     while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
1514             != FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
1515     {
1516         BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
1517                 FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
1518     }
1519
1520     /* Changing the waitstate and read mode of whichever bank we are in */
1521     /* Finding out which bank we are in */
1522     if(addr >  SysCtl_getFlashSize())
1523     {
1524         bank1Start = __INFO_FLASH_TECH_MIDDLE__;
1525     }
1526     else
1527     {
1528         bank1Start = SysCtl_getFlashSize() / 2;
1529     }
1530
1531     bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1532     bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
1533
1534     /* Saving the current wait states and read mode */
1535     b0WaitState = FlashCtl_getWaitState(bankProgramStart);
1536     b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
1537     FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
1538     FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
1539
1540     if (bankProgramStart != bankProgramEnd)
1541     {
1542         b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
1543         b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
1544         FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
1545         FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
1546     }
1547
1548     /* Going through each BURST program register and masking out for post
1549      * verifcation if needed
1550      */
1551     size = (size / 4);
1552     for (ii = 0; ii < size; ii++)
1553     {
1554         HWREG32(__getBurstProgramRegs[ii]) = ~(~(HWREG32(
1555                 __getBurstProgramRegs[ii])) & HWREG32(addr));
1556
1557         addr += 4;
1558     }
1559
1560     /* Setting the wait state to account for the mode */
1561     FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
1562     FlashCtl_setWaitState(bankProgramStart, b0WaitState);
1563
1564     if (bankProgramStart != bankProgramEnd)
1565     {
1566         FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
1567         FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
1568     }
1569 }