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 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 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 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 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 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 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 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 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 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 <= 0x03); 493 FLCTL->BANK0_INFO_WEPROT |= sectorMask; 494 break; 495 case FLASH_INFO_MEMORY_SPACE_BANK1: 496 ASSERT(sectorMask <= 0x03); 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 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 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 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 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 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 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 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 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 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 } 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 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 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 1170 void FlashCtl_disableWordProgramming(void) 1171 { 1172 BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 0; 1173 } 1174 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 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 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 1217 void FlashCtl_enableInterrupt(uint32_t flags) 1218 { 1219 FLCTL->IE |= flags; 1220 } 1221 1222 void FlashCtl_disableInterrupt(uint32_t flags) 1223 { 1224 FLCTL->IE &= ~flags; 1225 } 1226 1227 uint32_t FlashCtl_getInterruptStatus(void) 1228 { 1229 return FLCTL->IFG; 1230 } 1231 1232 uint32_t FlashCtl_getEnabledInterruptStatus(void) 1233 { 1234 return FlashCtl_getInterruptStatus() & FLCTL->IE; 1235 } 1236 1237 void FlashCtl_clearInterruptFlag(uint32_t flags) 1238 { 1239 FLCTL->CLRIFG |= flags; 1240 } 1241 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 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 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 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 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 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 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 uint32_t temp1 = HWREG32(__getBurstProgramRegs[ii]); 1487 uint32_t temp2 = HWREG32(addr); 1488 HWREG32(__getBurstProgramRegs[ii]) |= ~(temp1 | temp2); 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 } 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 uint32_t temp1 = (HWREG32(__getBurstProgramRegs[ii])); 1551 uint32_t temp2 = HWREG32(addr); 1552 HWREG32(__getBurstProgramRegs[ii]) = ~(~temp1 & temp2); 1553 1554 addr += 4; 1555 } 1556 1557 /* Setting the wait state to account for the mode */ 1558 FlashCtl_setReadMode(bankProgramStart, b0ReadMode); 1559 FlashCtl_setWaitState(bankProgramStart, b0WaitState); 1560 1561 if (bankProgramStart != bankProgramEnd) 1562 { 1563 FlashCtl_setReadMode(bankProgramEnd, b1ReadMode); 1564 FlashCtl_setWaitState(bankProgramEnd, b1WaitState); 1565 } 1566 } 1567 1568 #endif /* __MCU_HAS_FLCTL__ */ 1569