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