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