1 /* --COPYRIGHT--,BSD 2 * Copyright (c) 2017, Texas Instruments Incorporated 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of Texas Instruments Incorporated nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * --/COPYRIGHT--*/ 32 /* Standard Includes */ 33 #include <stdint.h> 34 35 /* DriverLib Includes */ 36 #include <ti/devices/msp432p4xx/driverlib/flash_a.h> 37 #include <ti/devices/msp432p4xx/driverlib/debug.h> 38 #include <ti/devices/msp432p4xx/driverlib/interrupt.h> 39 #include <ti/devices/msp432p4xx/inc/msp.h> 40 #include <ti/devices/msp432p4xx/driverlib/cpu.h> 41 #include <ti/devices/msp432p4xx/driverlib/sysctl_a.h> 42 43 /* Define to ensure that our current MSP432 has the FLCTL_A module. This 44 definition is included in the device specific header file */ 45 #ifdef __MCU_HAS_FLCTL_A__ 46 47 static const uint32_t MAX_ERASE_NO_TLV = 50; 48 static const uint32_t MAX_PROGRAM_NO_TLV = 5; 49 50 static const uint32_t __getBurstProgramRegs[16] = 51 { (uint32_t)&FLCTL_A->PRGBRST_DATA0_0, (uint32_t)&FLCTL_A->PRGBRST_DATA0_1, 52 (uint32_t) &FLCTL_A->PRGBRST_DATA0_2, (uint32_t)&FLCTL_A->PRGBRST_DATA0_3, 53 (uint32_t)&FLCTL_A->PRGBRST_DATA1_0,(uint32_t) &FLCTL_A->PRGBRST_DATA1_1, 54 (uint32_t)&FLCTL_A->PRGBRST_DATA1_2, (uint32_t)&FLCTL_A->PRGBRST_DATA1_3, 55 (uint32_t) &FLCTL_A->PRGBRST_DATA2_0, (uint32_t)&FLCTL_A->PRGBRST_DATA2_1, 56 (uint32_t)&FLCTL_A->PRGBRST_DATA2_2,(uint32_t) &FLCTL_A->PRGBRST_DATA2_3, 57 (uint32_t) &FLCTL_A->PRGBRST_DATA3_0,(uint32_t) &FLCTL_A->PRGBRST_DATA3_1, 58 (uint32_t) &FLCTL_A->PRGBRST_DATA3_2,(uint32_t) &FLCTL_A->PRGBRST_DATA3_3 }; 59 60 static void __saveProtectionRegisters(__FlashCtl_ProtectionRegister *pReg) 61 { 62 pReg->B0_INFO_R0 = FLCTL_A->BANK0_INFO_WEPROT; 63 pReg->B1_INFO_R0 = FLCTL_A->BANK1_INFO_WEPROT; 64 pReg->B0_MAIN_R0 = FLCTL_A->BANK0_MAIN_WEPROT0; 65 pReg->B0_MAIN_R1 = FLCTL_A->BANK0_MAIN_WEPROT1; 66 pReg->B0_MAIN_R2 = FLCTL_A->BANK0_MAIN_WEPROT2; 67 pReg->B0_MAIN_R3 = FLCTL_A->BANK0_MAIN_WEPROT3; 68 pReg->B0_MAIN_R4 = FLCTL_A->BANK0_MAIN_WEPROT4; 69 pReg->B0_MAIN_R5 = FLCTL_A->BANK0_MAIN_WEPROT5; 70 pReg->B0_MAIN_R6 = FLCTL_A->BANK0_MAIN_WEPROT6; 71 pReg->B0_MAIN_R7 = FLCTL_A->BANK0_MAIN_WEPROT7; 72 pReg->B1_MAIN_R0 = FLCTL_A->BANK1_MAIN_WEPROT0; 73 pReg->B1_MAIN_R1 = FLCTL_A->BANK1_MAIN_WEPROT1; 74 pReg->B1_MAIN_R2 = FLCTL_A->BANK1_MAIN_WEPROT2; 75 pReg->B1_MAIN_R3 = FLCTL_A->BANK1_MAIN_WEPROT3; 76 pReg->B1_MAIN_R4 = FLCTL_A->BANK1_MAIN_WEPROT4; 77 pReg->B1_MAIN_R5 = FLCTL_A->BANK1_MAIN_WEPROT5; 78 pReg->B1_MAIN_R6 = FLCTL_A->BANK1_MAIN_WEPROT6; 79 pReg->B1_MAIN_R7 = FLCTL_A->BANK1_MAIN_WEPROT7; 80 } 81 82 static void __restoreProtectionRegisters(__FlashCtl_ProtectionRegister *pReg) 83 { 84 FLCTL_A->BANK0_INFO_WEPROT = pReg->B0_INFO_R0; 85 FLCTL_A->BANK1_INFO_WEPROT = pReg->B1_INFO_R0; 86 FLCTL_A->BANK0_MAIN_WEPROT0 = pReg->B0_MAIN_R0; 87 FLCTL_A->BANK0_MAIN_WEPROT1 = pReg->B0_MAIN_R1; 88 FLCTL_A->BANK0_MAIN_WEPROT2 = pReg->B0_MAIN_R2; 89 FLCTL_A->BANK0_MAIN_WEPROT3 = pReg->B0_MAIN_R3; 90 FLCTL_A->BANK0_MAIN_WEPROT4 = pReg->B0_MAIN_R4; 91 FLCTL_A->BANK0_MAIN_WEPROT5 = pReg->B0_MAIN_R5; 92 FLCTL_A->BANK0_MAIN_WEPROT6 = pReg->B0_MAIN_R6; 93 FLCTL_A->BANK0_MAIN_WEPROT7 = pReg->B0_MAIN_R7; 94 FLCTL_A->BANK1_MAIN_WEPROT0 = pReg->B1_MAIN_R0; 95 FLCTL_A->BANK1_MAIN_WEPROT1 = pReg->B1_MAIN_R1; 96 FLCTL_A->BANK1_MAIN_WEPROT2 = pReg->B1_MAIN_R2; 97 FLCTL_A->BANK1_MAIN_WEPROT3 = pReg->B1_MAIN_R3; 98 FLCTL_A->BANK1_MAIN_WEPROT4 = pReg->B1_MAIN_R4; 99 FLCTL_A->BANK1_MAIN_WEPROT5 = pReg->B1_MAIN_R5; 100 FLCTL_A->BANK1_MAIN_WEPROT6 = pReg->B1_MAIN_R6; 101 FLCTL_A->BANK1_MAIN_WEPROT7 = pReg->B1_MAIN_R7; 102 } 103 104 void FlashCtl_A_getMemoryInfo(uint32_t addr, uint32_t *bankNum, 105 uint32_t *sectorNum) 106 { 107 uint32_t bankLimit; 108 109 bankLimit = SysCtl_A_getFlashSize() / 2; 110 111 if (addr > bankLimit) 112 { 113 *(bankNum) = FLASH_A_BANK1; 114 addr = (addr - bankLimit); 115 } else 116 { 117 *(bankNum) = FLASH_A_BANK0; 118 } 119 120 *(sectorNum) = (addr) / FLASH_A_SECTOR_SIZE; 121 } 122 123 static bool _FlashCtl_A_Program8(uint32_t src, uint32_t dest, uint32_t mTries) 124 { 125 uint32_t ii; 126 uint8_t data; 127 128 /* Enabling the correct verification settings */ 129 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST); 130 FlashCtl_A_clearProgramVerification(FLASH_A_BURSTPOST | FLASH_A_BURSTPRE); 131 132 data = HWREG8(src); 133 134 for (ii = 0; ii < mTries; ii++) 135 { 136 /* Clearing flags */ 137 FLCTL_A->CLRIFG |= (FLASH_A_PROGRAM_ERROR | FLASH_A_POSTVERIFY_FAILED 138 | FLASH_A_PREVERIFY_FAILED | FLASH_A_WRDPRGM_COMPLETE); 139 140 HWREG8(dest) = data; 141 142 while (!(FlashCtl_A_getInterruptStatus() & FLASH_A_WRDPRGM_COMPLETE)) 143 { 144 __no_operation(); 145 } 146 147 /* Pre-Verify */ 148 if ((BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) 149 && BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPRE_OFS))) 150 { 151 data = __FlashCtl_A_remaskData8Pre(data, dest); 152 153 if (data != 0xFF) 154 { 155 FlashCtl_A_clearProgramVerification(FLASH_A_REGPRE); 156 continue; 157 } 158 159 } 160 161 /* Post Verify */ 162 if ((BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPST_OFS))) 163 { 164 data = __FlashCtl_A_remaskData8Post(data, dest); 165 166 /* Seeing if we actually need to do another pulse */ 167 if (data == 0xFF) 168 return true; 169 170 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST); 171 continue; 172 } 173 174 /* If we got this far, return true */ 175 return true; 176 177 } 178 179 return false; 180 181 } 182 183 static bool _FlashCtl_A_Program32(uint32_t src, uint32_t dest, uint32_t mTries) 184 { 185 uint32_t ii; 186 uint32_t data; 187 188 /* Enabling the correct verification settings */ 189 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST); 190 FlashCtl_A_clearProgramVerification(FLASH_A_BURSTPOST | FLASH_A_BURSTPRE); 191 192 data = HWREG32(src); 193 194 for (ii = 0; ii < mTries; ii++) 195 { 196 /* Clearing flags */ 197 FLCTL_A->CLRIFG |= (FLASH_A_PROGRAM_ERROR | FLASH_A_POSTVERIFY_FAILED 198 | FLASH_A_PREVERIFY_FAILED | FLASH_A_WRDPRGM_COMPLETE); 199 200 HWREG32(dest) = data; 201 202 while (!(FlashCtl_A_getInterruptStatus() & FLASH_A_WRDPRGM_COMPLETE)) 203 { 204 __no_operation(); 205 } 206 207 /* Pre-Verify */ 208 if ((BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) 209 && BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPRE_OFS))) 210 { 211 data = __FlashCtl_A_remaskData32Pre(data, dest); 212 213 if (data != 0xFFFFFFFF) 214 { 215 216 FlashCtl_A_clearProgramVerification(FLASH_A_REGPRE); 217 continue; 218 } 219 220 } 221 222 /* Post Verify */ 223 if ((BITBAND_PERI(FLCTL_A->IFG, FLCTL_A_IFG_AVPST_OFS))) 224 { 225 data = __FlashCtl_A_remaskData32Post(data, dest); 226 227 /* Seeing if we actually need to do another pulse */ 228 if (data == 0xFFFFFFFF) 229 return true; 230 231 FlashCtl_A_setProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST); 232 continue; 233 } 234 235 /* If we got this far, return true */ 236 return true; 237 238 } 239 240 return false; 241 242 } 243 244 static bool _FlashCtl_A_ProgramBurst(uint32_t src, uint32_t dest, 245 uint32_t length, uint32_t mTries) 246 { 247 uint32_t bCalc, otpOffset, ii, jj; 248 bool res; 249 250 /* Setting verification */ 251 FlashCtl_A_clearProgramVerification(FLASH_A_REGPRE | FLASH_A_REGPOST); 252 FlashCtl_A_setProgramVerification(FLASH_A_BURSTPOST | FLASH_A_BURSTPRE); 253 254 /* Assume Failure */ 255 res = false; 256 257 /* Waiting for idle status */ 258 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK) 259 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0) 260 { 261 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 262 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; 263 } 264 265 /* Setting/clearing INFO flash flags as appropriate */ 266 if (dest >= SysCtl_A_getFlashSize()) 267 { 268 FLCTL_A->PRGBRST_CTLSTAT = (FLCTL_A->PRGBRST_CTLSTAT 269 & ~FLCTL_A_PRGBRST_CTLSTAT_TYPE_MASK) 270 | FLCTL_A_PRGBRST_CTLSTAT_TYPE_1; 271 otpOffset = __INFO_FLASH_A_TECH_START__; 272 } else 273 { 274 FLCTL_A->PRGBRST_CTLSTAT = (FLCTL_A->PRGBRST_CTLSTAT 275 & ~FLCTL_A_PRGBRST_CTLSTAT_TYPE_MASK) 276 | FLCTL_A_PRGBRST_CTLSTAT_TYPE_0; 277 otpOffset = 0; 278 } 279 280 bCalc = 0; 281 FLCTL_A->PRGBRST_STARTADDR = (dest - otpOffset); 282 283 /* Initially populating the burst registers */ 284 while (bCalc < 16 && length != 0) 285 { 286 HWREG32(__getBurstProgramRegs[bCalc]) = HWREG32(src); 287 bCalc++; 288 length -= 4; 289 src += 4; 290 } 291 292 for (ii = 0; ii < mTries; ii++) 293 { 294 /* Clearing Flags */ 295 FLCTL_A->CLRIFG |= (FLASH_A_BRSTPRGM_COMPLETE 296 | FLASH_A_POSTVERIFY_FAILED | FLASH_A_PREVERIFY_FAILED); 297 298 /* Waiting for idle status */ 299 while ((FLCTL_A->PRGBRST_CTLSTAT 300 & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK) 301 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0) 302 { 303 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 304 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; 305 } 306 307 /* Start the burst program */ 308 FLCTL_A->PRGBRST_CTLSTAT = (FLCTL_A->PRGBRST_CTLSTAT 309 & ~(FLCTL_A_PRGBRST_CTLSTAT_LEN_MASK)) 310 | ((bCalc / 4) << FLASH_A_BURST_PRG_BIT) 311 | FLCTL_A_PRGBRST_CTLSTAT_START; 312 313 /* Waiting for the burst to complete */ 314 while ((FLCTL_A->PRGBRST_CTLSTAT 315 & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK) 316 != FLASH_A_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE) 317 { 318 __no_operation(); 319 } 320 321 /* Checking for errors and clearing/masking */ 322 323 /* Address Error */ 324 if (BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 325 FLCTL_A_PRGBRST_CTLSTAT_ADDR_ERR_OFS)) 326 { 327 goto BurstCleanUp; 328 } 329 330 /* Pre-Verify Error */ 331 if (BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 332 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) 333 && BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 334 FLCTL_A_PRGBRST_CTLSTAT_PRE_ERR_OFS)) 335 { 336 __FlashCtl_A_remaskBurstDataPre(dest, bCalc * 4); 337 338 for (jj = 0; jj < bCalc; jj++) 339 { 340 if (HWREG32(__getBurstProgramRegs[jj]) != 0xFFFFFFFF) 341 { 342 FlashCtl_A_clearProgramVerification(FLASH_A_BURSTPRE); 343 break; 344 } 345 } 346 347 if (jj != bCalc) 348 continue; 349 } 350 351 /* Post-Verify Error */ 352 if (BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 353 FLCTL_A_PRGBRST_CTLSTAT_PST_ERR_OFS)) 354 { 355 __FlashCtl_A_remaskBurstDataPost(dest, bCalc * 4); 356 357 for (jj = 0; jj < bCalc; jj++) 358 { 359 if ((HWREG32(__getBurstProgramRegs[jj])) != 0xFFFFFFFF) 360 { 361 FlashCtl_A_setProgramVerification( 362 FLASH_A_BURSTPOST | FLASH_A_BURSTPRE); 363 break; 364 } 365 } 366 367 if (jj != bCalc) 368 continue; 369 370 } 371 372 /* If we got this far, the program happened */ 373 res = true; 374 goto BurstCleanUp; 375 } 376 377 BurstCleanUp: 378 /* Waiting for idle status */ 379 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK) 380 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0) 381 { 382 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 383 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; 384 } 385 return res; 386 } 387 388 void FlashCtl_A_enableReadBuffering(uint_fast8_t memoryBank, 389 uint_fast8_t accessMethod) 390 { 391 if (memoryBank == FLASH_A_BANK0 && accessMethod == FLASH_A_DATA_READ) 392 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFD_OFS) = 1; 393 else if (memoryBank == FLASH_A_BANK1 && accessMethod == FLASH_A_DATA_READ) 394 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFD_OFS) = 1; 395 else if (memoryBank == FLASH_A_BANK0 396 && accessMethod == FLASH_A_INSTRUCTION_FETCH) 397 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFI_OFS) = 1; 398 else if (memoryBank == FLASH_A_BANK1 399 && accessMethod == FLASH_A_INSTRUCTION_FETCH) 400 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFI_OFS) = 1; 401 else 402 ASSERT(false); 403 } 404 405 void FlashCtl_A_disableReadBuffering(uint_fast8_t memoryBank, 406 uint_fast8_t accessMethod) 407 { 408 if (memoryBank == FLASH_A_BANK0 && accessMethod == FLASH_A_DATA_READ) 409 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFD_OFS) = 0; 410 else if (memoryBank == FLASH_A_BANK1 && accessMethod == FLASH_A_DATA_READ) 411 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFD_OFS) = 0; 412 else if (memoryBank == FLASH_A_BANK0 413 && accessMethod == FLASH_A_INSTRUCTION_FETCH) 414 BITBAND_PERI(FLCTL_A->BANK0_RDCTL, FLCTL_A_BANK0_RDCTL_BUFI_OFS) = 0; 415 else if (memoryBank == FLASH_A_BANK1 416 && accessMethod == FLASH_A_INSTRUCTION_FETCH) 417 BITBAND_PERI(FLCTL_A->BANK1_RDCTL, FLCTL_A_BANK1_RDCTL_BUFI_OFS) = 0; 418 else 419 ASSERT(false); 420 } 421 422 bool FlashCtl_A_isMemoryProtected(uint32_t addr) 423 { 424 volatile uint32_t *configRegister; 425 uint32_t memoryBit, cutOffMemory; 426 427 if (addr >= SysCtl_A_getFlashSize()) 428 { 429 cutOffMemory = (SysCtl_A_getInfoFlashSize() >> 1) + __INFO_FLASH_A_TECH_START__; 430 431 if (addr < cutOffMemory) 432 { 433 memoryBit = (addr - __INFO_FLASH_A_TECH_START__) 434 / FLASH_A_SECTOR_SIZE; 435 configRegister = &FLCTL_A->BANK0_INFO_WEPROT 436 + ((memoryBit >> 5)); 437 memoryBit &= 0x1F; 438 } else 439 { 440 memoryBit = (addr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 441 configRegister = &FLCTL_A->BANK1_INFO_WEPROT 442 + ((memoryBit >> 5)); 443 memoryBit &= 0x1F; 444 } 445 } else 446 { 447 cutOffMemory = SysCtl_A_getFlashSize() >> 1; 448 449 if (addr < cutOffMemory) 450 { 451 memoryBit = addr / FLASH_A_SECTOR_SIZE; 452 configRegister = &FLCTL_A->BANK0_MAIN_WEPROT0 453 + ((memoryBit >> 5)); 454 memoryBit &= 0x1F; 455 } else 456 { 457 memoryBit = (addr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 458 configRegister = &FLCTL_A->BANK1_MAIN_WEPROT0 459 + ((memoryBit >> 5)); 460 memoryBit &= 0x1F; 461 } 462 } 463 464 return (*configRegister & (1 << memoryBit)); 465 } 466 467 bool FlashCtl_A_isMemoryRangeProtected(uint32_t startAddr, uint32_t endAddr) 468 { 469 uint32_t ii; 470 471 if (startAddr > endAddr) 472 return false; 473 474 startAddr = (startAddr & 0xFFFFF000); 475 endAddr = (endAddr & 0xFFFFF000); 476 477 for (ii = startAddr; ii <= endAddr; ii+=FLASH_A_SECTOR_SIZE) 478 { 479 if (!FlashCtl_A_isMemoryProtected(ii)) 480 return false; 481 } 482 return true; 483 } 484 485 bool FlashCtl_A_unprotectMemory(uint32_t startAddr, uint32_t endAddr) 486 { 487 uint32_t startBankBit, endBankBit, cutOffMemory; 488 volatile uint32_t* baseStartConfig, *baseEndConfig; 489 490 if (startAddr > endAddr) 491 return false; 492 493 if (endAddr >= SysCtl_A_getFlashSize()) 494 { 495 cutOffMemory = (SysCtl_A_getInfoFlashSize() >> 1) 496 + __INFO_FLASH_A_TECH_START__; 497 498 if (endAddr < cutOffMemory && startAddr < cutOffMemory) 499 { 500 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__) 501 / FLASH_A_SECTOR_SIZE; 502 endBankBit = (endAddr - __INFO_FLASH_A_TECH_START__) 503 / FLASH_A_SECTOR_SIZE; 504 FLCTL_A->BANK0_INFO_WEPROT &= ~(0xFFFFFFFF >> (31 - endBankBit)) 505 & (0xFFFFFFFF << startBankBit); 506 } else if (endAddr > cutOffMemory && startAddr > cutOffMemory) 507 { 508 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 509 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 510 FLCTL_A->BANK1_INFO_WEPROT &= ~((0xFFFFFFFF >> (31 - endBankBit)) 511 & (0xFFFFFFFF << startBankBit)); 512 } else 513 { 514 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__) 515 / FLASH_A_SECTOR_SIZE; 516 endBankBit = (endAddr - cutOffMemory)/FLASH_A_SECTOR_SIZE; 517 FLCTL_A->BANK0_INFO_WEPROT &= ~(0xFFFFFFFF << startBankBit) & 0xF; 518 FLCTL_A->BANK1_INFO_WEPROT &= ~(0xFFFFFFFF >> (31 - (endBankBit))) & 0xF; 519 } 520 521 return true; 522 523 } else 524 { 525 cutOffMemory = SysCtl_A_getFlashSize() >> 1; 526 527 if (endAddr < cutOffMemory) 528 { 529 endBankBit = endAddr / FLASH_A_SECTOR_SIZE; 530 baseEndConfig = &FLCTL_A->BANK0_MAIN_WEPROT0 531 + ((endBankBit >> 5)); 532 endBankBit &= 0x1F; 533 } else 534 { 535 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 536 baseEndConfig = &FLCTL_A->BANK1_MAIN_WEPROT0 537 + (endBankBit >> 5); 538 endBankBit &= 0x1F; 539 } 540 541 if (startAddr < cutOffMemory) 542 { 543 startBankBit = (startAddr / FLASH_A_SECTOR_SIZE); 544 baseStartConfig = &FLCTL_A->BANK0_MAIN_WEPROT0 545 + (startBankBit >> 5); 546 startBankBit &= 0x1F; 547 } else 548 { 549 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 550 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0 551 + (startBankBit >> 5); 552 startBankBit &= 0x1F; 553 } 554 555 if (baseStartConfig == baseEndConfig) 556 { 557 (*baseStartConfig) &= ~((0xFFFFFFFF >> (31 - endBankBit)) 558 & (0xFFFFFFFF << startBankBit)); 559 return true; 560 } 561 562 *baseStartConfig &= ~(0xFFFFFFFF << startBankBit); 563 564 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7) 565 { 566 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0; 567 } else 568 { 569 baseStartConfig++; 570 } 571 572 while (baseStartConfig != baseEndConfig) 573 { 574 *baseStartConfig = 0; 575 576 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7) 577 { 578 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0; 579 } else 580 { 581 baseStartConfig++; 582 } 583 } 584 585 (*baseEndConfig) &= ~(0xFFFFFFFF >> (31 - (endBankBit))); 586 } 587 588 return true; 589 590 } 591 592 bool FlashCtl_A_protectMemory(uint32_t startAddr, uint32_t endAddr) 593 { 594 uint32_t startBankBit, endBankBit, cutOffMemory; 595 volatile uint32_t* baseStartConfig, *baseEndConfig; 596 597 if (startAddr > endAddr) 598 return false; 599 600 if (endAddr >= SysCtl_A_getFlashSize()) 601 { 602 cutOffMemory = (SysCtl_A_getInfoFlashSize() >> 1) 603 + __INFO_FLASH_A_TECH_START__; 604 605 if (endAddr < cutOffMemory && startAddr < cutOffMemory) 606 { 607 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__) 608 / FLASH_A_SECTOR_SIZE; 609 endBankBit = (endAddr - __INFO_FLASH_A_TECH_START__) 610 / FLASH_A_SECTOR_SIZE; 611 FLCTL_A->BANK0_INFO_WEPROT |= (0xFFFFFFFF >> (31 - endBankBit)) 612 & (0xFFFFFFFF << startBankBit); 613 } else if (endAddr > cutOffMemory && startAddr > cutOffMemory) 614 { 615 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 616 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 617 FLCTL_A->BANK1_INFO_WEPROT |= (0xFFFFFFFF >> (31 - endBankBit)) 618 & (0xFFFFFFFF << startBankBit); 619 } else 620 { 621 startBankBit = (startAddr - __INFO_FLASH_A_TECH_START__) 622 / FLASH_A_SECTOR_SIZE; 623 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 624 FLCTL_A->BANK0_INFO_WEPROT |= (0xFFFFFFFF << startBankBit); 625 FLCTL_A->BANK1_INFO_WEPROT |= (0xFFFFFFFF >> (31 - (endBankBit))); 626 } 627 628 return true; 629 630 } else 631 { 632 cutOffMemory = SysCtl_A_getFlashSize() >> 1; 633 634 if (endAddr < cutOffMemory) 635 { 636 endBankBit = endAddr / FLASH_A_SECTOR_SIZE; 637 baseEndConfig = &FLCTL_A->BANK0_MAIN_WEPROT0 638 + ((endBankBit >> 5)); 639 endBankBit &= 0x1F; 640 } else 641 { 642 endBankBit = (endAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 643 baseEndConfig = &FLCTL_A->BANK1_MAIN_WEPROT0 644 + (endBankBit >> 5); 645 endBankBit &= 0x1F; 646 } 647 648 if (startAddr < cutOffMemory) 649 { 650 startBankBit = (startAddr / FLASH_A_SECTOR_SIZE); 651 baseStartConfig = &FLCTL_A->BANK0_MAIN_WEPROT0 652 + (startBankBit >> 5); 653 startBankBit &= 0x1F; 654 } else 655 { 656 startBankBit = (startAddr - cutOffMemory) / FLASH_A_SECTOR_SIZE; 657 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0 658 + (startBankBit >> 5); 659 startBankBit &= 0x1F; 660 } 661 662 if (baseStartConfig == baseEndConfig) 663 { 664 (*baseStartConfig) |= (0xFFFFFFFF >> (31 - endBankBit)) 665 & (0xFFFFFFFF << startBankBit); 666 return true; 667 } 668 669 *baseStartConfig |= (0xFFFFFFFF << startBankBit); 670 671 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7) 672 { 673 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0; 674 } else 675 { 676 baseStartConfig++; 677 } 678 679 while (baseStartConfig != baseEndConfig) 680 { 681 *baseStartConfig = 0xFFFFFFFF; 682 683 if (baseStartConfig == &FLCTL_A->BANK0_MAIN_WEPROT7) 684 { 685 baseStartConfig = &FLCTL_A->BANK1_MAIN_WEPROT0; 686 } else 687 { 688 baseStartConfig++; 689 } 690 } 691 692 (*baseEndConfig) |= (0xFFFFFFFF >> (31 - (endBankBit))); 693 } 694 695 return true; 696 697 } 698 699 bool FlashCtl_A_verifyMemory(void* verifyAddr, uint32_t length, 700 uint_fast8_t pattern) 701 { 702 uint32_t memoryPattern, addr, otpOffset; 703 uint32_t b0WaitState, b1WaitState, intStatus; 704 uint32_t bankOneStart, startBank, endBank; 705 uint_fast8_t b0readMode, b1readMode; 706 uint_fast8_t memoryType; 707 bool res; 708 709 ASSERT(pattern == FLASH_A_0_PATTERN || pattern == FLASH_A_1_PATTERN); 710 711 /* Saving interrupt context and disabling interrupts for program 712 * operation 713 */ 714 intStatus = CPU_primask(); 715 Interrupt_disableMaster(); 716 717 /* Casting and determining the memory that we need to use */ 718 addr = (uint32_t) verifyAddr; 719 memoryType = (addr >= SysCtl_A_getFlashSize()) ? 720 FLASH_A_INFO_SPACE : 721 FLASH_A_MAIN_SPACE; 722 723 /* Assuming Failure */ 724 res = false; 725 726 /* Finding out which bank we are in */ 727 if (addr >= SysCtl_A_getFlashSize()) 728 { 729 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__; 730 } else 731 { 732 bankOneStart = SysCtl_A_getFlashSize() / 2; 733 } 734 startBank = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1; 735 endBank = (addr + length) < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1; 736 737 /* Saving context and changing read modes */ 738 b0WaitState = FlashCtl_A_getWaitState(startBank); 739 b0readMode = FlashCtl_A_getReadMode(startBank); 740 741 /* Setting the wait state to account for the mode */ 742 FlashCtl_A_setWaitState(startBank, (2 * b0WaitState) + 1); 743 744 if (startBank != endBank) 745 { 746 b1WaitState = FlashCtl_A_getWaitState(endBank); 747 b1readMode = FlashCtl_A_getReadMode(endBank); 748 FlashCtl_A_setWaitState(endBank, (2 * b1WaitState) + 1); 749 } 750 751 /* Changing to the relevant VERIFY mode */ 752 if (pattern == FLASH_A_1_PATTERN) 753 { 754 FlashCtl_A_setReadMode(startBank, FLASH_A_ERASE_VERIFY_READ_MODE); 755 756 if (startBank != endBank) 757 { 758 FlashCtl_A_setReadMode(endBank, FLASH_A_ERASE_VERIFY_READ_MODE); 759 } 760 761 memoryPattern = 0xFFFFFFFF; 762 } else 763 { 764 FlashCtl_A_setReadMode(startBank, FLASH_A_PROGRAM_VERIFY_READ_MODE); 765 766 if (startBank != endBank) 767 { 768 FlashCtl_A_setReadMode(endBank, FLASH_A_PROGRAM_VERIFY_READ_MODE); 769 } 770 771 memoryPattern = 0; 772 } 773 774 /* Taking care of byte accesses */ 775 while ((addr & 0x03) && (length > 0)) 776 { 777 if (HWREG8(addr++) != ((uint8_t) memoryPattern)) 778 goto FlashVerifyCleanup; 779 length--; 780 } 781 782 /* Making sure we are aligned by 128-bit address */ 783 while (((addr & 0x0F)) && (length > 3)) 784 { 785 if (HWREG32(addr) != memoryPattern) 786 goto FlashVerifyCleanup; 787 788 addr = addr + 4; 789 length = length - 4; 790 } 791 792 /* Burst Verify */ 793 if (length > 63) 794 { 795 /* Setting/clearing INFO flash flags as appropriate */ 796 if (addr >= SysCtl_A_getFlashSize()) 797 { 798 FLCTL_A->RDBRST_CTLSTAT = (FLCTL_A->RDBRST_CTLSTAT 799 & ~FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_MASK) 800 | FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_1; 801 otpOffset = __INFO_FLASH_A_TECH_START__; 802 } else 803 { 804 FLCTL_A->RDBRST_CTLSTAT = (FLCTL_A->RDBRST_CTLSTAT 805 & ~FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_MASK) 806 | FLCTL_A_RDBRST_CTLSTAT_MEM_TYPE_0; 807 otpOffset = 0; 808 } 809 810 /* Clearing any lingering fault flags and preparing burst verify*/ 811 BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT, 812 FLCTL_A_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1; 813 FLCTL_A->RDBRST_FAILCNT = 0; 814 FLCTL_A->RDBRST_STARTADDR = addr - otpOffset; 815 FLCTL_A->RDBRST_LEN = (length & 0xFFFFFFF0); 816 addr += FLCTL_A->RDBRST_LEN; 817 length = length & 0xF; 818 819 /* Starting Burst Verify */ 820 FLCTL_A->RDBRST_CTLSTAT = (FLCTL_A_RDBRST_CTLSTAT_STOP_FAIL | pattern 821 | memoryType | FLCTL_A_RDBRST_CTLSTAT_START); 822 823 /* While the burst read hasn't finished */ 824 while ((FLCTL_A->RDBRST_CTLSTAT & FLCTL_A_RDBRST_CTLSTAT_BRST_STAT_MASK) 825 != FLCTL_A_RDBRST_CTLSTAT_BRST_STAT_3) 826 { 827 __no_operation(); 828 } 829 830 /* Checking for a verification/access error/failure */ 831 if (BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT, 832 FLCTL_A_RDBRST_CTLSTAT_CMP_ERR_OFS) 833 || BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT, 834 FLCTL_A_RDBRST_CTLSTAT_ADDR_ERR_OFS) 835 || FLCTL_A->RDBRST_FAILCNT) 836 { 837 goto FlashVerifyCleanup; 838 } 839 } 840 841 /* Remaining Words */ 842 while (length > 3) 843 { 844 if (HWREG32(addr) != memoryPattern) 845 goto FlashVerifyCleanup; 846 847 addr = addr + 4; 848 length = length - 4; 849 } 850 851 /* Remaining Bytes */ 852 while (length > 0) 853 { 854 if (HWREG8(addr++) != ((uint8_t) memoryPattern)) 855 goto FlashVerifyCleanup; 856 length--; 857 } 858 859 /* If we got this far, that means it no failure happened */ 860 res = true; 861 862 FlashVerifyCleanup: 863 864 /* Clearing the Read Burst flag and returning */ 865 BITBAND_PERI(FLCTL_A->RDBRST_CTLSTAT, FLCTL_A_RDBRST_CTLSTAT_CLR_STAT_OFS) = 866 1; 867 868 FlashCtl_A_setReadMode(startBank, b0readMode); 869 FlashCtl_A_setWaitState(startBank, b0WaitState); 870 871 if (startBank != endBank) 872 { 873 FlashCtl_A_setReadMode(endBank, b1readMode); 874 FlashCtl_A_setWaitState(endBank, b1WaitState); 875 } 876 877 if (intStatus == 0) 878 Interrupt_enableMaster(); 879 880 return res; 881 } 882 883 bool FlashCtl_A_setReadMode(uint32_t flashBank, uint32_t readMode) 884 { 885 886 if (FLCTL_A->POWER_STAT & FLCTL_A_POWER_STAT_RD_2T) 887 return false; 888 889 if (flashBank == FLASH_A_BANK0) 890 { 891 FLCTL_A->BANK0_RDCTL = (FLCTL_A->BANK0_RDCTL 892 & ~FLCTL_A_BANK0_RDCTL_RD_MODE_MASK) | readMode; 893 while ((FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_RD_MODE_STATUS_MASK) 894 != (readMode<<16)) 895 ; 896 } else if (flashBank == FLASH_A_BANK1) 897 { 898 FLCTL_A->BANK1_RDCTL = (FLCTL_A->BANK1_RDCTL 899 & ~FLCTL_A_BANK1_RDCTL_RD_MODE_MASK) | readMode; 900 while ((FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_RD_MODE_STATUS_MASK) 901 != (readMode<<16)) 902 ; 903 } else 904 { 905 ASSERT(false); 906 return false; 907 } 908 909 return true; 910 } 911 912 uint32_t FlashCtl_A_getReadMode(uint32_t flashBank) 913 { 914 if (flashBank == FLASH_A_BANK0) 915 { 916 return (FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_RD_MODE_STATUS_MASK) 917 >> 16; 918 } else if (flashBank == FLASH_A_BANK1) 919 { 920 return (FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_RD_MODE_STATUS_MASK) 921 >> 16; 922 } else 923 { 924 ASSERT(false); 925 return 0; 926 } 927 } 928 929 void FlashCtl_A_initiateMassErase(void) 930 { 931 /* Clearing old mass erase flags */ 932 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 933 1; 934 935 /* Performing the mass erase */ 936 FLCTL_A->ERASE_CTLSTAT |= (FLCTL_A_ERASE_CTLSTAT_MODE 937 | FLCTL_A_ERASE_CTLSTAT_START); 938 } 939 940 bool FlashCtl_A_performMassErase(void) 941 { 942 uint32_t flashSize, ii, intStatus, jj; 943 uint32_t mTries; 944 uint_fast8_t tlvLength; 945 SysCtl_A_FlashTLV_Info *flInfo; 946 __FlashCtl_ProtectionRegister protectRegs; 947 bool res, needAnotherPulse; 948 949 /* Parsing the TLV and getting the maximum erase pulses */ 950 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo); 951 952 if (tlvLength == 0 || flInfo->maxErasePulses == 0) 953 { 954 mTries = MAX_ERASE_NO_TLV; 955 } else 956 { 957 mTries = flInfo->maxErasePulses; 958 } 959 960 /* Saving interrupt context and disabling interrupts for program 961 * operation 962 */ 963 intStatus = CPU_primask(); 964 Interrupt_disableMaster(); 965 966 /* Assume Failure */ 967 res = false; 968 969 /* Saving off protection settings so we can restore them later */ 970 __saveProtectionRegisters(&protectRegs); 971 972 for(jj=0;jj<mTries;jj++) 973 { 974 needAnotherPulse = false; 975 976 /* Clearing old mass erase flags */ 977 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 978 1; 979 980 /* Performing the mass erase */ 981 FLCTL_A->ERASE_CTLSTAT |= (FLCTL_A_ERASE_CTLSTAT_MODE 982 | FLCTL_A_ERASE_CTLSTAT_START); 983 984 while ((FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK) 985 == FLCTL_A_ERASE_CTLSTAT_STATUS_1 986 || (FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK) 987 == FLCTL_A_ERASE_CTLSTAT_STATUS_2) 988 { 989 __no_operation(); 990 } 991 992 /* Return false if an address error */ 993 if (BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, 994 FLCTL_A_ERASE_CTLSTAT_ADDR_ERR_OFS)) 995 goto MassEraseCleanup; 996 997 /* Verifying the user memory that might have been erased */ 998 flashSize = SysCtl_A_getFlashSize(); 999 1000 /* Clearing old flag */ 1001 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1002 1; 1003 1004 for (ii = 0; ii < flashSize; ii += FLASH_A_SECTOR_SIZE) 1005 { 1006 if (!FlashCtl_A_isMemoryProtected(ii)) 1007 { 1008 if (!FlashCtl_A_verifyMemory((void*) ii, FLASH_A_SECTOR_SIZE, 1009 FLASH_A_1_PATTERN)) 1010 { 1011 needAnotherPulse = true; 1012 } 1013 else 1014 { 1015 FlashCtl_A_protectMemory(ii,ii); 1016 } 1017 } 1018 } 1019 1020 /* Verifying the INFO memory that might be protected */ 1021 flashSize = SysCtl_A_getInfoFlashSize() + __INFO_FLASH_A_TECH_START__; 1022 1023 for (ii = __INFO_FLASH_A_TECH_START__; ii < flashSize; ii += 1024 FLASH_A_SECTOR_SIZE) 1025 { 1026 if (!FlashCtl_A_isMemoryProtected(ii)) 1027 { 1028 if (!FlashCtl_A_verifyMemory((void*) ii, FLASH_A_SECTOR_SIZE, 1029 FLASH_A_1_PATTERN)) 1030 { 1031 needAnotherPulse = true; 1032 } 1033 else 1034 { 1035 FlashCtl_A_protectMemory(ii,ii); 1036 } 1037 } 1038 } 1039 1040 if(!needAnotherPulse) 1041 { 1042 break; 1043 } 1044 } 1045 1046 /* If we got this far and didn't do the max number of tries, 1047 * the mass erase happened */ 1048 if(jj != mTries) 1049 { 1050 res = true; 1051 } 1052 1053 MassEraseCleanup: 1054 1055 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, 1056 FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1; 1057 __restoreProtectionRegisters(&protectRegs); 1058 1059 if (intStatus == 0) 1060 Interrupt_enableMaster(); 1061 1062 return res; 1063 } 1064 1065 bool FlashCtl_A_eraseSector(uint32_t addr) 1066 { 1067 uint_fast8_t memoryType, ii; 1068 uint32_t otpOffset = 0; 1069 uint32_t intStatus; 1070 uint_fast8_t mTries, tlvLength; 1071 SysCtl_A_FlashTLV_Info *flInfo; 1072 bool res; 1073 1074 /* Saving interrupt context and disabling interrupts for program 1075 * operation 1076 */ 1077 intStatus = CPU_primask(); 1078 Interrupt_disableMaster(); 1079 1080 /* Assuming Failure */ 1081 res = false; 1082 1083 memoryType = addr >= SysCtl_A_getFlashSize() ? FLASH_A_INFO_SPACE : 1084 FLASH_A_MAIN_SPACE; 1085 1086 /* Parsing the TLV and getting the maximum erase pulses */ 1087 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo); 1088 1089 if (tlvLength == 0 || flInfo->maxErasePulses == 0) 1090 { 1091 mTries = MAX_ERASE_NO_TLV; 1092 } else 1093 { 1094 mTries = flInfo->maxErasePulses; 1095 } 1096 1097 /* We can only erase on 4KB boundaries */ 1098 while (addr & 0xFFF) 1099 { 1100 addr--; 1101 } 1102 1103 /* Clearing the status */ 1104 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1105 1; 1106 1107 if (memoryType == FLASH_A_INFO_SPACE) 1108 { 1109 otpOffset = __INFO_FLASH_A_TECH_START__; 1110 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT 1111 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK)) 1112 | FLCTL_A_ERASE_CTLSTAT_TYPE_1; 1113 1114 } else 1115 { 1116 otpOffset = 0; 1117 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT 1118 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK)) 1119 | FLCTL_A_ERASE_CTLSTAT_TYPE_0; 1120 } 1121 1122 /* Clearing old flags and setting up the erase */ 1123 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_MODE_OFS) = 0; 1124 FLCTL_A->ERASE_SECTADDR = addr - otpOffset; 1125 1126 for (ii = 0; ii < mTries; ii++) 1127 { 1128 /* Clearing the status */ 1129 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1130 1; 1131 1132 /* Starting the erase */ 1133 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_START_OFS) = 1134 1; 1135 1136 while ((FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK) 1137 == FLCTL_A_ERASE_CTLSTAT_STATUS_1 1138 || (FLCTL_A->ERASE_CTLSTAT & FLCTL_A_ERASE_CTLSTAT_STATUS_MASK) 1139 == FLCTL_A_ERASE_CTLSTAT_STATUS_2) 1140 { 1141 __no_operation(); 1142 } 1143 1144 /* Return false if an address error */ 1145 if (BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, 1146 FLCTL_A_ERASE_CTLSTAT_ADDR_ERR_OFS)) 1147 { 1148 goto SectorEraseCleanup; 1149 } 1150 /* Erase verifying */ 1151 if (FlashCtl_A_verifyMemory((void*) addr, FLASH_A_SECTOR_SIZE, 1152 FLASH_A_1_PATTERN)) 1153 { 1154 res = true; 1155 goto SectorEraseCleanup; 1156 } 1157 1158 } 1159 1160 SectorEraseCleanup: 1161 1162 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1163 1; 1164 1165 if (intStatus == 0) 1166 Interrupt_enableMaster(); 1167 1168 return res; 1169 } 1170 1171 void FlashCtl_A_initiateSectorErase(uint32_t addr) 1172 { 1173 uint_fast8_t memoryType; 1174 uint32_t otpOffset = 0; 1175 1176 memoryType = addr >= SysCtl_A_getFlashSize() ? 1177 FLASH_A_INFO_SPACE : 1178 FLASH_A_MAIN_SPACE; 1179 1180 /* We can only erase on 4KB boundaries */ 1181 while (addr & 0xFFF) 1182 { 1183 addr--; 1184 } 1185 1186 /* Clearing the status */ 1187 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_CLR_STAT_OFS) = 1188 1; 1189 1190 if (memoryType == FLASH_A_INFO_SPACE) 1191 { 1192 otpOffset = __INFO_FLASH_A_TECH_START__; 1193 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT 1194 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK)) 1195 | FLCTL_A_ERASE_CTLSTAT_TYPE_1; 1196 1197 } else 1198 { 1199 otpOffset = 0; 1200 FLCTL_A->ERASE_CTLSTAT = (FLCTL_A->ERASE_CTLSTAT 1201 & ~(FLCTL_A_ERASE_CTLSTAT_TYPE_MASK)) 1202 | FLCTL_A_ERASE_CTLSTAT_TYPE_0; 1203 } 1204 1205 /* Clearing old flags and setting up the erase */ 1206 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_MODE_OFS) = 0; 1207 FLCTL_A->ERASE_SECTADDR = addr - otpOffset; 1208 1209 /* Starting the erase */ 1210 BITBAND_PERI(FLCTL_A->ERASE_CTLSTAT, FLCTL_A_ERASE_CTLSTAT_START_OFS) = 1; 1211 1212 } 1213 1214 bool FlashCtl_A_programMemory(void* src, void* dest, uint32_t length) 1215 { 1216 uint32_t destAddr, srcAddr, burstLength, intStatus; 1217 bool res; 1218 uint_fast8_t mTries, tlvLength; 1219 SysCtl_A_FlashTLV_Info *flInfo; 1220 1221 /* Saving interrupt context and disabling interrupts for program 1222 * operation 1223 */ 1224 intStatus = CPU_primask(); 1225 Interrupt_disableMaster(); 1226 1227 /* Parsing the TLV and getting the maximum erase pulses */ 1228 SysCtl_A_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo); 1229 1230 if (tlvLength == 0 || flInfo->maxProgramPulses == 0) 1231 { 1232 mTries = MAX_PROGRAM_NO_TLV; 1233 } else 1234 { 1235 mTries = flInfo->maxProgramPulses; 1236 } 1237 1238 /* Casting to integers */ 1239 srcAddr = (uint32_t) src; 1240 destAddr = (uint32_t) dest; 1241 1242 /* Enabling word programming */ 1243 FlashCtl_A_enableWordProgramming(FLASH_A_IMMEDIATE_WRITE_MODE); 1244 1245 /* Assume failure */ 1246 res = false; 1247 1248 /* Taking care of byte accesses */ 1249 while ((destAddr & 0x03) && length > 0) 1250 { 1251 if (!_FlashCtl_A_Program8(srcAddr, destAddr, mTries)) 1252 { 1253 goto FlashProgramCleanUp; 1254 } else 1255 { 1256 srcAddr++; 1257 destAddr++; 1258 length--; 1259 } 1260 } 1261 1262 /* Taking care of word accesses */ 1263 while ((destAddr & 0x0F) && (length > 3)) 1264 { 1265 if (!_FlashCtl_A_Program32(srcAddr, destAddr, mTries)) 1266 { 1267 goto FlashProgramCleanUp; 1268 } else 1269 { 1270 srcAddr += 4; 1271 destAddr += 4; 1272 length -= 4; 1273 } 1274 } 1275 1276 /* Taking care of burst programs */ 1277 while (length > 16) 1278 { 1279 burstLength = length > 63 ? 64 : length & 0xFFFFFFF0; 1280 1281 if (!_FlashCtl_A_ProgramBurst(srcAddr, destAddr, burstLength, mTries)) 1282 { 1283 goto FlashProgramCleanUp; 1284 } else 1285 { 1286 srcAddr += burstLength; 1287 destAddr += burstLength; 1288 length -= burstLength; 1289 } 1290 } 1291 1292 /* Remaining word accesses */ 1293 while (length > 3) 1294 { 1295 if (!_FlashCtl_A_Program32(srcAddr, destAddr, mTries)) 1296 { 1297 goto FlashProgramCleanUp; 1298 } else 1299 { 1300 srcAddr += 4; 1301 destAddr += 4; 1302 length -= 4; 1303 } 1304 } 1305 1306 /* Remaining byte accesses */ 1307 while (length > 0) 1308 { 1309 if (!_FlashCtl_A_Program8(srcAddr, destAddr, mTries)) 1310 { 1311 goto FlashProgramCleanUp; 1312 } else 1313 { 1314 srcAddr++; 1315 destAddr++; 1316 length--; 1317 } 1318 } 1319 1320 /* If we got this far that means that we succeeded */ 1321 res = true; 1322 1323 FlashProgramCleanUp: 1324 1325 if (intStatus == 0) 1326 Interrupt_enableMaster(); 1327 1328 FlashCtl_A_disableWordProgramming(); 1329 return res; 1330 1331 } 1332 void FlashCtl_A_setProgramVerification(uint32_t verificationSetting) 1333 { 1334 if ((verificationSetting & FLASH_A_BURSTPOST)) 1335 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 1336 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1; 1337 1338 if ((verificationSetting & FLASH_A_BURSTPRE)) 1339 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 1340 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1; 1341 1342 if ((verificationSetting & FLASH_A_REGPRE)) 1343 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) = 1; 1344 1345 if ((verificationSetting & FLASH_A_REGPOST)) 1346 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PST_OFS) = 1; 1347 } 1348 1349 void FlashCtl_A_clearProgramVerification(uint32_t verificationSetting) 1350 { 1351 if ((verificationSetting & FLASH_A_BURSTPOST)) 1352 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 1353 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0; 1354 1355 if ((verificationSetting & FLASH_A_BURSTPRE)) 1356 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 1357 FLCTL_A_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0; 1358 1359 if ((verificationSetting & FLASH_A_REGPRE)) 1360 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PRE_OFS) = 0; 1361 1362 if ((verificationSetting & FLASH_A_REGPOST)) 1363 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_VER_PST_OFS) = 0; 1364 1365 } 1366 1367 void FlashCtl_A_enableWordProgramming(uint32_t mode) 1368 { 1369 if (mode == FLASH_A_IMMEDIATE_WRITE_MODE) 1370 { 1371 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 1; 1372 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS) = 0; 1373 1374 } else if (mode == FLASH_A_COLLATED_WRITE_MODE) 1375 { 1376 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 1; 1377 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS) = 1; 1378 } 1379 } 1380 1381 void FlashCtl_A_disableWordProgramming(void) 1382 { 1383 BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS) = 0; 1384 } 1385 1386 uint32_t FlashCtl_A_isWordProgrammingEnabled(void) 1387 { 1388 if (!BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_ENABLE_OFS)) 1389 { 1390 return 0; 1391 } else if (BITBAND_PERI(FLCTL_A->PRG_CTLSTAT, FLCTL_A_PRG_CTLSTAT_MODE_OFS)) 1392 return FLASH_A_COLLATED_WRITE_MODE; 1393 else 1394 return FLASH_A_IMMEDIATE_WRITE_MODE; 1395 } 1396 1397 void FlashCtl_A_setWaitState(uint32_t flashBank, uint32_t waitState) 1398 { 1399 if (flashBank == FLASH_A_BANK0) 1400 { 1401 FLCTL_A->BANK0_RDCTL = (FLCTL_A->BANK0_RDCTL 1402 & ~FLCTL_A_BANK0_RDCTL_WAIT_MASK) 1403 | (waitState << FLCTL_A_BANK0_RDCTL_WAIT_OFS); 1404 } else if (flashBank == FLASH_A_BANK1) 1405 { 1406 FLCTL_A->BANK1_RDCTL = (FLCTL_A->BANK1_RDCTL 1407 & ~FLCTL_A_BANK1_RDCTL_WAIT_MASK) 1408 | (waitState << FLCTL_A_BANK1_RDCTL_WAIT_OFS); 1409 } else 1410 { 1411 ASSERT(false); 1412 } 1413 } 1414 1415 uint32_t FlashCtl_A_getWaitState(uint32_t flashBank) 1416 { 1417 if (flashBank == FLASH_A_BANK0) 1418 { 1419 return (FLCTL_A->BANK0_RDCTL & FLCTL_A_BANK0_RDCTL_WAIT_MASK) 1420 >> FLCTL_A_BANK0_RDCTL_WAIT_OFS; 1421 } else if (flashBank == FLASH_A_BANK1) 1422 { 1423 return (FLCTL_A->BANK1_RDCTL & FLCTL_A_BANK1_RDCTL_WAIT_MASK) 1424 >> FLCTL_A_BANK1_RDCTL_WAIT_OFS; 1425 } else 1426 { 1427 ASSERT(false); 1428 return 0; 1429 } 1430 } 1431 1432 void FlashCtl_A_enableInterrupt(uint32_t flags) 1433 { 1434 FLCTL_A->IE |= flags; 1435 } 1436 1437 void FlashCtl_A_disableInterrupt(uint32_t flags) 1438 { 1439 FLCTL_A->IE &= ~flags; 1440 } 1441 1442 uint32_t FlashCtl_A_getInterruptStatus(void) 1443 { 1444 return FLCTL_A->IFG; 1445 } 1446 1447 uint32_t FlashCtl_A_getEnabledInterruptStatus(void) 1448 { 1449 return FlashCtl_A_getInterruptStatus() & FLCTL_A->IE; 1450 } 1451 1452 void FlashCtl_A_clearInterruptFlag(uint32_t flags) 1453 { 1454 FLCTL_A->CLRIFG |= flags; 1455 } 1456 1457 void FlashCtl_A_registerInterrupt(void (*intHandler)(void)) 1458 { 1459 // 1460 // Register the interrupt handler, returning an error if an error occurs. 1461 // 1462 Interrupt_registerInterrupt(INT_FLCTL, intHandler); 1463 1464 // 1465 // Enable the system control interrupt. 1466 // 1467 Interrupt_enableInterrupt(INT_FLCTL); 1468 } 1469 1470 void FlashCtl_A_unregisterInterrupt(void) 1471 { 1472 // 1473 // Disable the interrupt. 1474 // 1475 Interrupt_disableInterrupt(INT_FLCTL); 1476 1477 // 1478 // Unregister the interrupt handler. 1479 // 1480 Interrupt_unregisterInterrupt(INT_FLCTL); 1481 } 1482 1483 uint8_t __FlashCtl_A_remaskData8Post(uint8_t data, uint32_t addr) 1484 { 1485 uint32_t readMode, waitState, bankProgram, bankOneStart; 1486 1487 /* Changing the waitstate and read mode of whichever bank we are in */ 1488 /* Finding out which bank we are in */ 1489 if (addr >= SysCtl_A_getFlashSize()) 1490 { 1491 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__; 1492 } else 1493 { 1494 bankOneStart = SysCtl_A_getFlashSize() / 2; 1495 } 1496 1497 bankProgram = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1; 1498 1499 /* Saving the current wait states and read mode */ 1500 waitState = FlashCtl_A_getWaitState(bankProgram); 1501 readMode = FlashCtl_A_getReadMode(bankProgram); 1502 1503 /* Setting the wait state to account for the mode */ 1504 FlashCtl_A_setWaitState(bankProgram, (2 * waitState) + 1); 1505 1506 /* Changing to PROGRAM VERIFY mode */ 1507 FlashCtl_A_setReadMode(bankProgram, FLASH_A_PROGRAM_VERIFY_READ_MODE); 1508 1509 data = ~(~(data) & HWREG8(addr)); 1510 1511 /* Setting the wait state to account for the mode */ 1512 FlashCtl_A_setReadMode(bankProgram, readMode); 1513 FlashCtl_A_setWaitState(bankProgram, waitState); 1514 1515 return data; 1516 } 1517 1518 uint8_t __FlashCtl_A_remaskData8Pre(uint8_t data, uint32_t addr) 1519 { 1520 uint32_t readMode, waitState, bankProgram, bankOneStart; 1521 1522 /* Changing the waitstate and read mode of whichever bank we are in */ 1523 /* Finding out which bank we are in */ 1524 if (addr >= SysCtl_A_getFlashSize()) 1525 { 1526 bankOneStart = __INFO_FLASH_A_TECH_MIDDLE__; 1527 } else 1528 { 1529 bankOneStart = SysCtl_A_getFlashSize() / 2; 1530 } 1531 1532 bankProgram = addr < (bankOneStart) ? FLASH_A_BANK0 : FLASH_A_BANK1; 1533 1534 /* Saving the current wait states and read mode */ 1535 waitState = FlashCtl_A_getWaitState(bankProgram); 1536 readMode = FlashCtl_A_getReadMode(bankProgram); 1537 1538 /* Setting the wait state to account for the mode */ 1539 FlashCtl_A_setWaitState(bankProgram, (2 * waitState) + 1); 1540 1541 /* Changing to PROGRAM VERIFY mode */ 1542 FlashCtl_A_setReadMode(bankProgram, FLASH_A_PROGRAM_VERIFY_READ_MODE); 1543 1544 data |= ~(HWREG8(addr) | data); 1545 1546 /* Setting the wait state to account for the mode */ 1547 FlashCtl_A_setReadMode(bankProgram, readMode); 1548 FlashCtl_A_setWaitState(bankProgram, waitState); 1549 1550 return data; 1551 } 1552 1553 uint32_t __FlashCtl_A_remaskData32Post(uint32_t data, uint32_t addr) 1554 { 1555 uint32_t bankProgramStart, bankProgramEnd, bank1Start; 1556 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; 1557 1558 /* Changing the waitstate and read mode of whichever bank we are in */ 1559 /* Finding out which bank we are in */ 1560 if (addr >= SysCtl_A_getFlashSize()) 1561 { 1562 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__; 1563 } else 1564 { 1565 bank1Start = SysCtl_A_getFlashSize() / 2; 1566 } 1567 1568 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1569 bankProgramEnd = (addr + 4) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1570 1571 /* Saving the current wait states and read mode */ 1572 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart); 1573 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart); 1574 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); 1575 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE); 1576 1577 if (bankProgramStart != bankProgramEnd) 1578 { 1579 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd); 1580 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd); 1581 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); 1582 FlashCtl_A_setReadMode(bankProgramEnd, 1583 FLASH_A_PROGRAM_VERIFY_READ_MODE); 1584 } 1585 1586 data = ~(~(data) & HWREG32(addr)); 1587 1588 /* Setting the wait state to account for the mode */ 1589 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode); 1590 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState); 1591 1592 if (bankProgramStart != bankProgramEnd) 1593 { 1594 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode); 1595 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState); 1596 } 1597 1598 return data; 1599 } 1600 1601 uint32_t __FlashCtl_A_remaskData32Pre(uint32_t data, uint32_t addr) 1602 { 1603 uint32_t bankProgramStart, bankProgramEnd, bank1Start; 1604 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; 1605 1606 /* Changing the waitstate and read mode of whichever bank we are in */ 1607 /* Finding out which bank we are in */ 1608 if (addr >= SysCtl_A_getFlashSize()) 1609 { 1610 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__; 1611 } else 1612 { 1613 bank1Start = SysCtl_A_getFlashSize() / 2; 1614 } 1615 1616 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1617 bankProgramEnd = (addr + 4) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1618 1619 /* Saving the current wait states and read mode */ 1620 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart); 1621 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart); 1622 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); 1623 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE); 1624 1625 if (bankProgramStart != bankProgramEnd) 1626 { 1627 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd); 1628 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd); 1629 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); 1630 FlashCtl_A_setReadMode(bankProgramEnd, 1631 FLASH_A_PROGRAM_VERIFY_READ_MODE); 1632 } 1633 1634 data |= ~(HWREG32(addr) | data); 1635 1636 /* Setting the wait state to account for the mode */ 1637 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode); 1638 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState); 1639 1640 if (bankProgramStart != bankProgramEnd) 1641 { 1642 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode); 1643 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState); 1644 } 1645 1646 return data; 1647 } 1648 1649 void __FlashCtl_A_remaskBurstDataPre(uint32_t addr, uint32_t size) 1650 { 1651 1652 uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii; 1653 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; 1654 1655 /* Waiting for idle status */ 1656 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK) 1657 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0) 1658 { 1659 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 1660 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; 1661 } 1662 1663 /* Changing the waitstate and read mode of whichever bank we are in */ 1664 /* Finding out which bank we are in */ 1665 if (addr >= SysCtl_A_getFlashSize()) 1666 { 1667 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__; 1668 } else 1669 { 1670 bank1Start = SysCtl_A_getFlashSize() / 2; 1671 } 1672 1673 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1674 bankProgramEnd = (addr + size) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1675 1676 /* Saving the current wait states and read mode */ 1677 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart); 1678 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart); 1679 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); 1680 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE); 1681 1682 if (bankProgramStart != bankProgramEnd) 1683 { 1684 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd); 1685 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd); 1686 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); 1687 FlashCtl_A_setReadMode(bankProgramEnd, 1688 FLASH_A_PROGRAM_VERIFY_READ_MODE); 1689 } 1690 1691 /* Going through each BURST program register and masking out for pre 1692 * verifcation 1693 */ 1694 size = (size / 4); 1695 for (ii = 0; ii < size; ii++) 1696 { 1697 uint32_t temp1 = HWREG32(__getBurstProgramRegs[ii]); 1698 uint32_t temp2 = HWREG32(addr); 1699 HWREG32(__getBurstProgramRegs[ii]) |= ~(temp1 | temp2); 1700 addr += 4; 1701 } 1702 1703 /* Setting the wait state to account for the mode */ 1704 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode); 1705 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState); 1706 1707 if (bankProgramStart != bankProgramEnd) 1708 { 1709 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode); 1710 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState); 1711 } 1712 1713 } 1714 void __FlashCtl_A_remaskBurstDataPost(uint32_t addr, uint32_t size) 1715 { 1716 uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii; 1717 uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode; 1718 1719 /* Waiting for idle status */ 1720 while ((FLCTL_A->PRGBRST_CTLSTAT & FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_MASK) 1721 != FLCTL_A_PRGBRST_CTLSTAT_BURST_STATUS_0) 1722 { 1723 BITBAND_PERI(FLCTL_A->PRGBRST_CTLSTAT, 1724 FLCTL_A_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1; 1725 } 1726 1727 /* Changing the waitstate and read mode of whichever bank we are in */ 1728 /* Finding out which bank we are in */ 1729 if (addr >= SysCtl_A_getFlashSize()) 1730 { 1731 bank1Start = __INFO_FLASH_A_TECH_MIDDLE__; 1732 } else 1733 { 1734 bank1Start = SysCtl_A_getFlashSize() / 2; 1735 } 1736 1737 bankProgramStart = addr < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1738 bankProgramEnd = (addr + size) < bank1Start ? FLASH_A_BANK0 : FLASH_A_BANK1; 1739 1740 /* Saving the current wait states and read mode */ 1741 b0WaitState = FlashCtl_A_getWaitState(bankProgramStart); 1742 b0ReadMode = FlashCtl_A_getReadMode(bankProgramStart); 1743 FlashCtl_A_setWaitState(bankProgramStart, (2 * b0WaitState) + 1); 1744 FlashCtl_A_setReadMode(bankProgramStart, FLASH_A_PROGRAM_VERIFY_READ_MODE); 1745 1746 if (bankProgramStart != bankProgramEnd) 1747 { 1748 b1WaitState = FlashCtl_A_getWaitState(bankProgramEnd); 1749 b1ReadMode = FlashCtl_A_getReadMode(bankProgramEnd); 1750 FlashCtl_A_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1); 1751 FlashCtl_A_setReadMode(bankProgramEnd, 1752 FLASH_A_PROGRAM_VERIFY_READ_MODE); 1753 } 1754 1755 /* Going through each BURST program register and masking out for post 1756 * verifcation if needed 1757 */ 1758 size = (size / 4); 1759 for (ii = 0; ii < size; ii++) 1760 { 1761 uint32_t temp1 = (HWREG32(__getBurstProgramRegs[ii])); 1762 uint32_t temp2 = HWREG32(addr); 1763 HWREG32(__getBurstProgramRegs[ii]) = ~(~temp1 & temp2); 1764 1765 addr += 4; 1766 } 1767 1768 /* Setting the wait state to account for the mode */ 1769 FlashCtl_A_setReadMode(bankProgramStart, b0ReadMode); 1770 FlashCtl_A_setWaitState(bankProgramStart, b0WaitState); 1771 1772 if (bankProgramStart != bankProgramEnd) 1773 { 1774 FlashCtl_A_setReadMode(bankProgramEnd, b1ReadMode); 1775 FlashCtl_A_setWaitState(bankProgramEnd, b1WaitState); 1776 } 1777 } 1778 1779 #endif /* __MCU_HAS_FLCTL_A__ */ 1780 1781