blob: d7c0beca953b1197cf0c8427bf3d8e6b51bf56e5 [file] [log] [blame]
/*
* -------------------------------------------
* MSP432 DriverLib - v3_10_00_09
* -------------------------------------------
*
* --COPYRIGHT--,BSD,BSD
* Copyright (c) 2014, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --/COPYRIGHT--*/
/* Standard Includes */
#include <stdint.h>
/* DriverLib Includes */
#include <flash.h>
#include <debug.h>
#include <interrupt.h>
#include <msp.h>
#include <cpu.h>
#include <rom.h>
#include <sysctl.h>
#include <hw_memmap.h>
static const uint32_t MAX_ERASE_NO_TLV = 50;
static const uint32_t MAX_PROGRAM_NO_TLV = 5;
static volatile uint32_t* __getBurstProgramRegs[16] =
{ &FLCTL->PRGBRST_DATA0_0, &FLCTL->PRGBRST_DATA0_1,
&FLCTL->PRGBRST_DATA0_2, &FLCTL->PRGBRST_DATA0_3,
&FLCTL->PRGBRST_DATA1_0, &FLCTL->PRGBRST_DATA1_1,
&FLCTL->PRGBRST_DATA1_2, &FLCTL->PRGBRST_DATA1_3,
&FLCTL->PRGBRST_DATA2_0, &FLCTL->PRGBRST_DATA2_1,
&FLCTL->PRGBRST_DATA2_2, &FLCTL->PRGBRST_DATA2_3,
&FLCTL->PRGBRST_DATA3_0, &FLCTL->PRGBRST_DATA3_1,
&FLCTL->PRGBRST_DATA3_2, &FLCTL->PRGBRST_DATA3_3 };
static uint32_t getUserFlashSector(uint32_t addr)
{
if (addr > 0x1ffff)
{
addr = addr - 0x20000;
}
switch (addr)
{
case 0:
return FLASH_SECTOR0;
case 0x1000:
return FLASH_SECTOR1;
case 0x2000:
return FLASH_SECTOR2;
case 0x3000:
return FLASH_SECTOR3;
case 0x4000:
return FLASH_SECTOR4;
case 0x5000:
return FLASH_SECTOR5;
case 0x6000:
return FLASH_SECTOR6;
case 0x7000:
return FLASH_SECTOR7;
case 0x8000:
return FLASH_SECTOR8;
case 0x9000:
return FLASH_SECTOR9;
case 0xA000:
return FLASH_SECTOR10;
case 0xB000:
return FLASH_SECTOR11;
case 0xC000:
return FLASH_SECTOR12;
case 0xD000:
return FLASH_SECTOR13;
case 0xE000:
return FLASH_SECTOR14;
case 0xF000:
return FLASH_SECTOR15;
case 0x10000:
return FLASH_SECTOR16;
case 0x11000:
return FLASH_SECTOR17;
case 0x12000:
return FLASH_SECTOR18;
case 0x13000:
return FLASH_SECTOR19;
case 0x14000:
return FLASH_SECTOR20;
case 0x15000:
return FLASH_SECTOR21;
case 0x16000:
return FLASH_SECTOR22;
case 0x17000:
return FLASH_SECTOR23;
case 0x18000:
return FLASH_SECTOR24;
case 0x19000:
return FLASH_SECTOR25;
case 0x1A000:
return FLASH_SECTOR26;
case 0x1B000:
return FLASH_SECTOR27;
case 0x1C000:
return FLASH_SECTOR28;
case 0x1D000:
return FLASH_SECTOR29;
case 0x1E000:
return FLASH_SECTOR30;
case 0x1F000:
return FLASH_SECTOR31;
default:
ASSERT(false);
return 0;
}
}
void FlashCtl_getMemoryInfo(uint32_t addr, uint32_t *sectorNum,
uint32_t *bankNum)
{
uint32_t bankLimit;
bankLimit = SysCtl_getFlashSize() / 2;
if (addr > bankLimit)
{
*(sectorNum) = FLASH_BANK1;
addr = (addr - bankLimit);
} else
{
*(sectorNum) = FLASH_BANK0;
}
*(bankNum) = (addr - __MAIN_MEMORY_START__) / 4096;
}
static bool _FlashCtl_Program8(uint32_t src, uint32_t dest, uint32_t mTries)
{
uint32_t ii;
uint8_t data;
/* Enabling the correct verification settings */
FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
data = HWREG8(src);
for (ii = 0; ii < mTries; ii++)
{
/* Clearing flags */
FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED
| FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE);
HWREG8(dest) = data;
while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE))
{
__no_operation();
}
/* Pre-Verify */
if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS)
&& BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS)))
{
data = __FlashCtl_remaskData8Pre(data, dest);
if (data != 0xFF)
{
FlashCtl_clearProgramVerification(FLASH_REGPRE);
continue;
}
}
/* Post Verify */
if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS)))
{
data = __FlashCtl_remaskData8Post(data, dest);
/* Seeing if we actually need to do another pulse */
if (data == 0xFF)
return true;
FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
continue;
}
/* If we got this far, return true */
return true;
}
return false;
}
static bool _FlashCtl_Program32(uint32_t src, uint32_t dest, uint32_t mTries)
{
uint32_t ii;
uint32_t data;
/* Enabling the correct verification settings */
FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
FlashCtl_clearProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
data = HWREG32(src);
for (ii = 0; ii < mTries; ii++)
{
/* Clearing flags */
FLCTL->CLRIFG |= (FLASH_PROGRAM_ERROR | FLASH_POSTVERIFY_FAILED
| FLASH_PREVERIFY_FAILED | FLASH_WRDPRGM_COMPLETE);
HWREG32(dest) = data;
while (!(FlashCtl_getInterruptStatus() & FLASH_WRDPRGM_COMPLETE))
{
__no_operation();
}
/* Pre-Verify */
if ((BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS)
&& BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPRE_OFS)))
{
data = __FlashCtl_remaskData32Pre(data, dest);
if (data != 0xFFFFFFFF)
{
FlashCtl_clearProgramVerification(FLASH_REGPRE);
continue;
}
}
/* Post Verify */
if ((BITBAND_PERI(FLCTL->IFG, FLCTL_IFG_AVPST_OFS)))
{
data = __FlashCtl_remaskData32Post(data, dest);
/* Seeing if we actually need to do another pulse */
if (data == 0xFFFFFFFF)
return true;
FlashCtl_setProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
continue;
}
/* If we got this far, return true */
return true;
}
return false;
}
static bool _FlashCtl_ProgramBurst(uint32_t src, uint32_t dest, uint32_t length,
uint32_t mTries)
{
uint32_t bCalc, otpOffset, ii, jj;
bool res;
/* Setting verification */
FlashCtl_clearProgramVerification(FLASH_REGPRE | FLASH_REGPOST);
FlashCtl_setProgramVerification(FLASH_BURSTPOST | FLASH_BURSTPRE);
/* Assume Failure */
res = false;
/* Waiting for idle status */
while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
!= FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
{
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
}
/* Setting/clearing INFO flash flags as appropriate */
if (dest > __MAIN_MEMORY_END__)
{
FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
& ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_1;
otpOffset = __INFO_FLASH_TECH_START__;
} else
{
FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
& ~FLCTL_PRGBRST_CTLSTAT_TYPE_MASK) | FLCTL_PRGBRST_CTLSTAT_TYPE_0;
otpOffset = __MAIN_MEMORY_START__;
}
bCalc = 0;
FLCTL->PRGBRST_STARTADDR = (dest - otpOffset);
/* Initially populating the burst registers */
while (bCalc < 16 && length != 0)
{
HWREG32(__getBurstProgramRegs[bCalc]) = HWREG32(src);
bCalc++;
length -= 4;
src += 4;
}
for (ii = 0; ii < mTries; ii++)
{
/* Clearing Flags */
FLCTL->CLRIFG |= (FLASH_BRSTPRGM_COMPLETE | FLASH_POSTVERIFY_FAILED
| FLASH_PREVERIFY_FAILED);
/* Waiting for idle status */
while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
!= FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
{
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
}
/* Start the burst program */
FLCTL->PRGBRST_CTLSTAT = (FLCTL->PRGBRST_CTLSTAT
& ~(FLCTL_PRGBRST_CTLSTAT_LEN_MASK))
| ((bCalc / 4) << FLASH_BURST_PRG_BIT)
| FLCTL_PRGBRST_CTLSTAT_START;
/* Waiting for the burst to complete */
while ((FLCTL->PRGBRST_CTLSTAT &
FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
!= FLASH_PRGBRSTCTLSTAT_BURSTSTATUS_COMPLETE)
{
__no_operation();
}
/* Checking for errors and clearing/masking */
/* Address Error */
if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_ADDR_ERR_OFS))
{
goto BurstCleanUp;
}
/* Pre-Verify Error */
if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) && BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_PRE_ERR_OFS))
{
__FlashCtl_remaskBurstDataPre(dest, bCalc * 4);
for (jj = 0; jj < bCalc; jj++)
{
if (HWREG32(__getBurstProgramRegs[jj])
!= 0xFFFFFFFF)
{
FlashCtl_clearProgramVerification(FLASH_BURSTPRE);
break;
}
}
if (jj != bCalc)
continue;
}
/* Post-Verify Error */
if (BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_PST_ERR_OFS))
{
__FlashCtl_remaskBurstDataPost(dest, bCalc * 4);
for (jj = 0; jj < bCalc; jj++)
{
if ((HWREG32(__getBurstProgramRegs[jj]))
!= 0xFFFFFFFF)
{
FlashCtl_setProgramVerification(
FLASH_BURSTPOST | FLASH_BURSTPRE);
break;
}
}
if (jj != bCalc)
continue;
}
/* If we got this far, the program happened */
res = true;
goto BurstCleanUp;
}
BurstCleanUp:
/* Waiting for idle status */
while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
!= FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
{
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
}
return res;
}
void FlashCtl_enableReadBuffering(uint_fast8_t memoryBank,
uint_fast8_t accessMethod)
{
if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ)
BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 1;
else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ)
BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 1;
else if (memoryBank == FLASH_BANK0
&& accessMethod == FLASH_INSTRUCTION_FETCH)
BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 1;
else if (memoryBank == FLASH_BANK1
&& accessMethod == FLASH_INSTRUCTION_FETCH)
BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 1;
else
ASSERT(false);
}
void FlashCtl_disableReadBuffering(uint_fast8_t memoryBank,
uint_fast8_t accessMethod)
{
if (memoryBank == FLASH_BANK0 && accessMethod == FLASH_DATA_READ)
BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFD_OFS) = 0;
else if (memoryBank == FLASH_BANK1 && accessMethod == FLASH_DATA_READ)
BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFD_OFS) = 0;
else if (memoryBank == FLASH_BANK0
&& accessMethod == FLASH_INSTRUCTION_FETCH)
BITBAND_PERI(FLCTL->BANK0_RDCTL, FLCTL_BANK0_RDCTL_BUFI_OFS) = 0;
else if (memoryBank == FLASH_BANK1
&& accessMethod == FLASH_INSTRUCTION_FETCH)
BITBAND_PERI(FLCTL->BANK1_RDCTL, FLCTL_BANK1_RDCTL_BUFI_OFS) = 0;
else
ASSERT(false);
}
bool FlashCtl_unprotectSector(uint_fast8_t memorySpace, uint32_t sectorMask)
{
switch (memorySpace)
{
case FLASH_MAIN_MEMORY_SPACE_BANK0:
FLCTL->BANK0_MAIN_WEPROT &= ~sectorMask;
break;
case FLASH_MAIN_MEMORY_SPACE_BANK1:
FLCTL->BANK1_MAIN_WEPROT &= ~sectorMask;
break;
case FLASH_INFO_MEMORY_SPACE_BANK0:
ASSERT(sectorMask <= 0x04);
FLCTL->BANK0_INFO_WEPROT &= ~sectorMask;
break;
case FLASH_INFO_MEMORY_SPACE_BANK1:
ASSERT(sectorMask <= 0x04);
FLCTL->BANK1_INFO_WEPROT &= ~sectorMask;
break;
default:
ASSERT(false);
}
return !FlashCtl_isSectorProtected(memorySpace, sectorMask);
}
bool FlashCtl_protectSector(uint_fast8_t memorySpace, uint32_t sectorMask)
{
switch (memorySpace)
{
case FLASH_MAIN_MEMORY_SPACE_BANK0:
FLCTL->BANK0_MAIN_WEPROT |= sectorMask;
break;
case FLASH_MAIN_MEMORY_SPACE_BANK1:
FLCTL->BANK1_MAIN_WEPROT |= sectorMask;
break;
case FLASH_INFO_MEMORY_SPACE_BANK0:
ASSERT(sectorMask <= 0x04);
FLCTL->BANK0_INFO_WEPROT |= sectorMask;
break;
case FLASH_INFO_MEMORY_SPACE_BANK1:
ASSERT(sectorMask <= 0x04);
FLCTL->BANK1_INFO_WEPROT |= sectorMask;
break;
default:
ASSERT(false);
}
return FlashCtl_isSectorProtected(memorySpace, sectorMask);
}
bool FlashCtl_isSectorProtected(uint_fast8_t memorySpace, uint32_t sector)
{
switch (memorySpace)
{
case FLASH_MAIN_MEMORY_SPACE_BANK0:
return FLCTL->BANK0_MAIN_WEPROT & sector;
case FLASH_MAIN_MEMORY_SPACE_BANK1:
return FLCTL->BANK1_MAIN_WEPROT & sector;
case FLASH_INFO_MEMORY_SPACE_BANK0:
ASSERT(sector <= 0x04);
return FLCTL->BANK0_INFO_WEPROT & sector;
case FLASH_INFO_MEMORY_SPACE_BANK1:
ASSERT(sector <= 0x04);
return FLCTL->BANK1_INFO_WEPROT & sector;
default:
return false;
}
}
bool FlashCtl_verifyMemory(void* verifyAddr, uint32_t length,
uint_fast8_t pattern)
{
uint32_t memoryPattern, addr, otpOffset;
uint32_t b0WaitState, b1WaitState, intStatus;
uint32_t bankOneStart, startBank, endBank;
uint_fast8_t b0readMode, b1readMode;
uint_fast8_t memoryType;
bool res;
ASSERT(pattern == FLASH_0_PATTERN || pattern == FLASH_1_PATTERN);
/* Saving interrupt context and disabling interrupts for program
* operation
*/
intStatus = CPU_primask();
Interrupt_disableMaster();
/* Casting and determining the memory that we need to use */
addr = (uint32_t) verifyAddr;
memoryType =
(addr > __MAIN_MEMORY_END__) ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
/* Assuming Failure */
res = false;
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bankOneStart = SysCtl_getFlashSize() / 2;
}
startBank = addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
endBank = (addr + length) < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
/* Saving context and changing read modes */
b0WaitState = FlashCtl_getWaitState(startBank);
b0readMode = FlashCtl_getReadMode(startBank);
/* Setting the wait state to account for the mode */
FlashCtl_setWaitState(startBank, (2 * b0WaitState) + 1);
if(startBank != endBank)
{
b1WaitState = FlashCtl_getWaitState(endBank);
b1readMode = FlashCtl_getReadMode(endBank);
FlashCtl_setWaitState(endBank, (2 * b1WaitState) + 1);
}
/* Changing to the relevant VERIFY mode */
if (pattern == FLASH_1_PATTERN)
{
FlashCtl_setReadMode(startBank, FLASH_ERASE_VERIFY_READ_MODE);
if(startBank != endBank)
{
FlashCtl_setReadMode(endBank, FLASH_ERASE_VERIFY_READ_MODE);
}
memoryPattern = 0xFFFFFFFF;
} else
{
FlashCtl_setReadMode(startBank, FLASH_PROGRAM_VERIFY_READ_MODE);
if(startBank != endBank)
{
FlashCtl_setReadMode(endBank, FLASH_PROGRAM_VERIFY_READ_MODE);
}
memoryPattern = 0;
}
/* Taking care of byte accesses */
while ((addr & 0x03) && (length > 0))
{
if (HWREG8(addr++) != ((uint8_t) memoryPattern))
goto FlashVerifyCleanup;
length--;
}
/* Making sure we are aligned by 128-bit address */
while (((addr & 0x0F)) && (length > 3))
{
if (HWREG32(addr) != memoryPattern)
goto FlashVerifyCleanup;
addr = addr + 4;
length = length - 4;
}
/* Burst Verify */
if (length > 63)
{
/* Setting/clearing INFO flash flags as appropriate */
if (addr > __MAIN_MEMORY_END__)
{
FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT
& ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK)
| FLCTL_RDBRST_CTLSTAT_MEM_TYPE_1;
otpOffset = __INFO_FLASH_TECH_START__;
} else
{
FLCTL->RDBRST_CTLSTAT = (FLCTL->RDBRST_CTLSTAT
& ~FLCTL_RDBRST_CTLSTAT_MEM_TYPE_MASK)
| FLCTL_RDBRST_CTLSTAT_MEM_TYPE_0;
otpOffset = __MAIN_MEMORY_START__;
}
/* Clearing any lingering fault flags and preparing burst verify*/
BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
FLCTL->RDBRST_FAILCNT = 0;
FLCTL->RDBRST_STARTADDR = addr - otpOffset;
FLCTL->RDBRST_LEN = (length & 0xFFFFFFF0);
addr += FLCTL->RDBRST_LEN;
length = length & 0xF;
/* Starting Burst Verify */
FLCTL->RDBRST_CTLSTAT = (FLCTL_RDBRST_CTLSTAT_STOP_FAIL | pattern
| memoryType | FLCTL_RDBRST_CTLSTAT_START);
/* While the burst read hasn't finished */
while ((FLCTL->RDBRST_CTLSTAT & FLCTL_RDBRST_CTLSTAT_BRST_STAT_MASK)
!= FLCTL_RDBRST_CTLSTAT_BRST_STAT_3)
{
__no_operation();
}
/* Checking for a verification/access error/failure */
if (BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
FLCTL_RDBRST_CTLSTAT_CMP_ERR_OFS)
|| BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
FLCTL_RDBRST_CTLSTAT_ADDR_ERR_OFS)
|| FLCTL->RDBRST_FAILCNT)
{
goto FlashVerifyCleanup;
}
}
/* Remaining Words */
while (length > 3)
{
if (HWREG32(addr) != memoryPattern)
goto FlashVerifyCleanup;
addr = addr + 4;
length = length - 4;
}
/* Remaining Bytes */
while (length > 0)
{
if (HWREG8(addr++) != ((uint8_t) memoryPattern))
goto FlashVerifyCleanup;
length--;
}
/* If we got this far, that means it no failure happened */
res = true;
FlashVerifyCleanup:
/* Clearing the Read Burst flag and returning */
BITBAND_PERI(FLCTL->RDBRST_CTLSTAT,
FLCTL_RDBRST_CTLSTAT_CLR_STAT_OFS) = 1;
FlashCtl_setReadMode(startBank, b0readMode);
FlashCtl_setWaitState(startBank, b0WaitState);
if(startBank != endBank)
{
FlashCtl_setReadMode(endBank, b1readMode);
FlashCtl_setWaitState(endBank, b1WaitState);
}
if(intStatus == 0)
Interrupt_enableMaster();
return res;
}
bool FlashCtl_setReadMode(uint32_t flashBank, uint32_t readMode)
{
if (FLCTL->POWER_STAT & FLCTL_POWER_STAT_RD_2T)
return false;
if (flashBank == FLASH_BANK0)
{
FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL
& ~FLCTL_BANK0_RDCTL_RD_MODE_MASK) | readMode;
while ((FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_MASK)
!= readMode)
;
} else if (flashBank == FLASH_BANK1)
{
FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL
& ~FLCTL_BANK1_RDCTL_RD_MODE_MASK) | readMode;
while ((FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_MASK)
!= readMode)
;
} else
{
ASSERT(false);
return false;
}
return true;
}
uint32_t FlashCtl_getReadMode(uint32_t flashBank)
{
if (flashBank == FLASH_BANK0)
{
return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_RD_MODE_MASK);
} else if (flashBank == FLASH_BANK1)
{
return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_RD_MODE_MASK);
} else
{
ASSERT(false);
return 0;
}
}
void FlashCtl_initiateMassErase(void)
{
/* Clearing old mass erase flags */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
/* Performing the mass erase */
FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE
| FLCTL_ERASE_CTLSTAT_START);
}
bool FlashCtl_performMassErase(void)
{
uint32_t userFlash, ii, sector, intStatus;
bool res;
/* Saving interrupt context and disabling interrupts for program
* operation
*/
intStatus = CPU_primask();
Interrupt_disableMaster();
/* Assume Failure */
res = false;
/* Clearing old mass erase flags */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
/* Performing the mass erase */
FLCTL->ERASE_CTLSTAT |= (FLCTL_ERASE_CTLSTAT_MODE
| FLCTL_ERASE_CTLSTAT_START);
while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
== FLCTL_ERASE_CTLSTAT_STATUS_1
|| (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
== FLCTL_ERASE_CTLSTAT_STATUS_2)
{
__no_operation();
}
/* Return false if an address error */
if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS))
goto MassEraseCleanup;
/* Changing to erase verify */
userFlash = SysCtl_getFlashSize() / 2;
for (ii = __MAIN_MEMORY_START__; ii < userFlash; ii += 4096)
{
sector = getUserFlashSector(ii);
if (!((FLCTL->BANK0_MAIN_WEPROT) & sector))
{
if (!FlashCtl_verifyMemory((void*) ii, 4096, FLASH_1_PATTERN))
{
if (!FlashCtl_eraseSector(ii))
goto MassEraseCleanup;
}
}
if (!(FLCTL->BANK1_MAIN_WEPROT & sector))
{
if (!FlashCtl_verifyMemory((void*) (ii + userFlash), 4096,
FLASH_1_PATTERN))
{
if (!FlashCtl_eraseSector(ii + userFlash))
goto MassEraseCleanup;
}
}
if (sector < FLCTL_BANK0_MAIN_WEPROT_PROT2)
{
if (!(FLCTL->BANK0_INFO_WEPROT & sector))
{
if (!FlashCtl_verifyMemory(
(void*) (ii + __INFO_FLASH_TECH_START__), 4096,
FLASH_1_PATTERN))
{
if (!FlashCtl_eraseSector(ii + __INFO_FLASH_TECH_START__))
goto MassEraseCleanup;
}
}
if (!(FLCTL->BANK1_INFO_WEPROT & sector))
{
if (!FlashCtl_verifyMemory((void*) (ii + (0x202000)), 4096,
FLASH_1_PATTERN))
{
if (!FlashCtl_eraseSector(ii + (0x202000)))
goto MassEraseCleanup;
}
}
}
}
/* If we got this far, the mass erase happened */
res = true;
MassEraseCleanup:
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
if(intStatus == 0)
Interrupt_enableMaster();
return res;
}
bool FlashCtl_eraseSector(uint32_t addr)
{
uint_fast8_t memoryType, ii;
uint32_t otpOffset = 0;
uint32_t intStatus;
uint_fast8_t mTries, tlvLength;
SysCtl_FlashTLV_Info *flInfo;
bool res;
/* Saving interrupt context and disabling interrupts for program
* operation
*/
intStatus = CPU_primask();
Interrupt_disableMaster();
/* Assuming Failure */
res = false;
memoryType =
addr > __MAIN_MEMORY_END__ ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
/* Parsing the TLV and getting the maximum erase pulses */
SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
if (tlvLength == 0 || flInfo->maxErasePulses == 0)
{
mTries = MAX_ERASE_NO_TLV;
} else
{
mTries = flInfo->maxErasePulses;
}
/* We can only erase on 4KB boundaries */
while (addr & 0xFFF)
{
addr--;
}
/* Clearing the status */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
if (memoryType == FLASH_INFO_SPACE)
{
otpOffset = __INFO_FLASH_TECH_START__;
FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
& ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1;
} else
{
otpOffset = __MAIN_MEMORY_START__;
FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
& ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0;
}
/* Clearing old flags and setting up the erase */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0;
FLCTL->ERASE_SECTADDR = addr - otpOffset;
for (ii = 0; ii < mTries; ii++)
{
/* Clearing the status */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) =
1;
/* Starting the erase */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
FLCTL_ERASE_CTLSTAT_START_OFS) = 1;
while ((FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
== FLCTL_ERASE_CTLSTAT_STATUS_1
|| (FLCTL->ERASE_CTLSTAT & FLCTL_ERASE_CTLSTAT_STATUS_MASK)
== FLCTL_ERASE_CTLSTAT_STATUS_2)
{
__no_operation();
}
/* Return false if an address error */
if (BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
FLCTL_ERASE_CTLSTAT_ADDR_ERR_OFS))
{
goto SectorEraseCleanup;
}
/* Erase verifying */
if (FlashCtl_verifyMemory((void*) addr, 4096, FLASH_1_PATTERN))
{
res = true;
goto SectorEraseCleanup;
}
}
SectorEraseCleanup:
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
if(intStatus == 0)
Interrupt_enableMaster();
return res;
}
void FlashCtl_initiateSectorErase(uint32_t addr)
{
uint_fast8_t memoryType;
uint32_t otpOffset = 0;
memoryType =
addr > __MAIN_MEMORY_END__ ? FLASH_INFO_SPACE : FLASH_MAIN_SPACE;
/* We can only erase on 4KB boundaries */
while (addr & 0xFFF)
{
addr--;
}
/* Clearing the status */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_CLR_STAT_OFS) = 1;
if (memoryType == FLASH_INFO_SPACE)
{
otpOffset = __INFO_FLASH_TECH_START__;
FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
& ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_1;
} else
{
otpOffset = __MAIN_MEMORY_START__;
FLCTL->ERASE_CTLSTAT = (FLCTL->ERASE_CTLSTAT
& ~(FLCTL_ERASE_CTLSTAT_TYPE_MASK)) | FLCTL_ERASE_CTLSTAT_TYPE_0;
}
/* Clearing old flags and setting up the erase */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT, FLCTL_ERASE_CTLSTAT_MODE_OFS) = 0;
FLCTL->ERASE_SECTADDR = addr - otpOffset;
/* Starting the erase */
BITBAND_PERI(FLCTL->ERASE_CTLSTAT,
FLCTL_ERASE_CTLSTAT_START_OFS) = 1;
}
bool FlashCtl_programMemory(void* src, void* dest, uint32_t length)
{
uint32_t destAddr, srcAddr, burstLength, intStatus;
bool res;
uint_fast8_t mTries, tlvLength;
SysCtl_FlashTLV_Info *flInfo;
/* Saving interrupt context and disabling interrupts for program
* operation
*/
intStatus = CPU_primask();
Interrupt_disableMaster();
/* Parsing the TLV and getting the maximum erase pulses */
SysCtl_getTLVInfo(TLV_TAG_FLASHCTL, 0, &tlvLength, (uint32_t**) &flInfo);
if (tlvLength == 0 || flInfo->maxProgramPulses == 0)
{
mTries = MAX_PROGRAM_NO_TLV;
} else
{
mTries = flInfo->maxProgramPulses;
}
/* Casting to integers */
srcAddr = (uint32_t) src;
destAddr = (uint32_t) dest;
/* Enabling word programming */
FlashCtl_enableWordProgramming(FLASH_IMMEDIATE_WRITE_MODE);
/* Assume failure */
res = false;
/* Taking care of byte accesses */
while ((destAddr & 0x03) && length > 0)
{
if (!_FlashCtl_Program8(srcAddr, destAddr, mTries))
{
goto FlashProgramCleanUp;
} else
{
srcAddr++;
destAddr++;
length--;
}
}
/* Taking care of word accesses */
while ((destAddr & 0x0F) && (length > 3))
{
if (!_FlashCtl_Program32(srcAddr, destAddr, mTries))
{
goto FlashProgramCleanUp;
} else
{
srcAddr += 4;
destAddr += 4;
length -= 4;
}
}
/* Taking care of burst programs */
while (length > 16)
{
burstLength = length > 63 ? 64 : length & 0xFFFFFFF0;
if (!_FlashCtl_ProgramBurst(srcAddr, destAddr, burstLength, mTries))
{
goto FlashProgramCleanUp;
} else
{
srcAddr += burstLength;
destAddr += burstLength;
length -= burstLength;
}
}
/* Remaining word accesses */
while (length > 3)
{
if (!_FlashCtl_Program32(srcAddr, destAddr, mTries))
{
goto FlashProgramCleanUp;
} else
{
srcAddr+=4;
destAddr+=4;
length-=4;
}
}
/* Remaining byte accesses */
while (length > 0)
{
if (!_FlashCtl_Program8(srcAddr, destAddr, mTries))
{
goto FlashProgramCleanUp;
} else
{
srcAddr++;
destAddr++;
length--;
}
}
/* If we got this far that means that we succeeded */
res = true;
FlashProgramCleanUp:
if(intStatus == 0)
Interrupt_enableMaster();
FlashCtl_disableWordProgramming();
return res;
}
void FlashCtl_setProgramVerification(uint32_t verificationSetting)
{
if ((verificationSetting & FLASH_BURSTPOST))
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 1;
if ((verificationSetting & FLASH_BURSTPRE))
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 1;
if ((verificationSetting & FLASH_REGPRE))
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 1;
if ((verificationSetting & FLASH_REGPOST))
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 1;
}
void FlashCtl_clearProgramVerification(uint32_t verificationSetting)
{
if ((verificationSetting & FLASH_BURSTPOST))
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_AUTO_PST_OFS) = 0;
if ((verificationSetting & FLASH_BURSTPRE))
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_AUTO_PRE_OFS) = 0;
if ((verificationSetting & FLASH_REGPRE))
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PRE_OFS) = 0;
if ((verificationSetting & FLASH_REGPOST))
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_VER_PST_OFS) = 0;
}
void FlashCtl_enableWordProgramming(uint32_t mode)
{
if (mode == FLASH_IMMEDIATE_WRITE_MODE)
{
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1;
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 0;
} else if (mode == FLASH_COLLATED_WRITE_MODE)
{
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 1;
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS) = 1;
}
}
void FlashCtl_disableWordProgramming(void)
{
BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS) = 0;
}
uint32_t FlashCtl_isWordProgrammingEnabled(void)
{
if (!BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_ENABLE_OFS))
{
return 0;
} else if (BITBAND_PERI(FLCTL->PRG_CTLSTAT, FLCTL_PRG_CTLSTAT_MODE_OFS))
return FLASH_COLLATED_WRITE_MODE;
else
return FLASH_IMMEDIATE_WRITE_MODE;
}
void FlashCtl_setWaitState(uint32_t flashBank, uint32_t waitState)
{
if (flashBank == FLASH_BANK0)
{
FLCTL->BANK0_RDCTL = (FLCTL->BANK0_RDCTL
& ~FLCTL_BANK0_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK0_RDCTL_WAIT_OFS);
} else if (flashBank == FLASH_BANK1)
{
FLCTL->BANK1_RDCTL = (FLCTL->BANK1_RDCTL
& ~FLCTL_BANK1_RDCTL_WAIT_MASK) | (waitState << FLCTL_BANK1_RDCTL_WAIT_OFS);
} else
{
ASSERT(false);
}
}
uint32_t FlashCtl_getWaitState(uint32_t flashBank)
{
if (flashBank == FLASH_BANK0)
{
return (FLCTL->BANK0_RDCTL & FLCTL_BANK0_RDCTL_WAIT_MASK) >> FLCTL_BANK0_RDCTL_WAIT_OFS;
} else if (flashBank == FLASH_BANK1)
{
return (FLCTL->BANK1_RDCTL & FLCTL_BANK1_RDCTL_WAIT_MASK) >> FLCTL_BANK1_RDCTL_WAIT_OFS;
} else
{
ASSERT(false);
return 0;
}
}
void FlashCtl_enableInterrupt(uint32_t flags)
{
FLCTL->IE |= flags;
}
void FlashCtl_disableInterrupt(uint32_t flags)
{
FLCTL->IE &= ~flags;
}
uint32_t FlashCtl_getInterruptStatus(void)
{
return FLCTL->IFG;
}
uint32_t FlashCtl_getEnabledInterruptStatus(void)
{
return FlashCtl_getInterruptStatus() & FLCTL->IE;
}
void FlashCtl_clearInterruptFlag(uint32_t flags)
{
FLCTL->CLRIFG |= flags;
}
void FlashCtl_registerInterrupt(void (*intHandler)(void))
{
//
// Register the interrupt handler, returning an error if an error occurs.
//
Interrupt_registerInterrupt(INT_FLCTL, intHandler);
//
// Enable the system control interrupt.
//
Interrupt_enableInterrupt(INT_FLCTL);
}
void FlashCtl_unregisterInterrupt(void)
{
//
// Disable the interrupt.
//
Interrupt_disableInterrupt(INT_FLCTL);
//
// Unregister the interrupt handler.
//
Interrupt_unregisterInterrupt(INT_FLCTL);
}
uint8_t __FlashCtl_remaskData8Post(uint8_t data, uint32_t addr)
{
uint32_t readMode, waitState, bankProgram, bankOneStart;
/* Changing the waitstate and read mode of whichever bank we are in */
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bankOneStart = SysCtl_getFlashSize() / 2;
}
bankProgram =
addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
/* Saving the current wait states and read mode */
waitState = FlashCtl_getWaitState(bankProgram);
readMode = FlashCtl_getReadMode(bankProgram);
/* Setting the wait state to account for the mode */
FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1);
/* Changing to PROGRAM VERIFY mode */
FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE);
data = ~(~(data) & HWREG8(addr));
/* Setting the wait state to account for the mode */
FlashCtl_setReadMode(bankProgram, readMode);
FlashCtl_setWaitState(bankProgram, waitState);
return data;
}
uint8_t __FlashCtl_remaskData8Pre(uint8_t data, uint32_t addr)
{
uint32_t readMode, waitState, bankProgram, bankOneStart;
/* Changing the waitstate and read mode of whichever bank we are in */
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bankOneStart = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bankOneStart = SysCtl_getFlashSize() / 2;
}
bankProgram =
addr < (bankOneStart) ? FLASH_BANK0 : FLASH_BANK1;
/* Saving the current wait states and read mode */
waitState = FlashCtl_getWaitState(bankProgram);
readMode = FlashCtl_getReadMode(bankProgram);
/* Setting the wait state to account for the mode */
FlashCtl_setWaitState(bankProgram, (2 * waitState) + 1);
/* Changing to PROGRAM VERIFY mode */
FlashCtl_setReadMode(bankProgram, FLASH_PROGRAM_VERIFY_READ_MODE);
data |= ~(HWREG8(addr) | data);
/* Setting the wait state to account for the mode */
FlashCtl_setReadMode(bankProgram, readMode);
FlashCtl_setWaitState(bankProgram, waitState);
return data;
}
uint32_t __FlashCtl_remaskData32Post(uint32_t data, uint32_t addr)
{
uint32_t bankProgramStart, bankProgramEnd, bank1Start;
uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
/* Changing the waitstate and read mode of whichever bank we are in */
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bank1Start = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bank1Start = SysCtl_getFlashSize() / 2;
}
bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
/* Saving the current wait states and read mode */
b0WaitState = FlashCtl_getWaitState(bankProgramStart);
b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
if (bankProgramStart != bankProgramEnd)
{
b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
}
data = ~(~(data) & HWREG32(addr));
/* Setting the wait state to account for the mode */
FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
FlashCtl_setWaitState(bankProgramStart, b0WaitState);
if (bankProgramStart != bankProgramEnd)
{
FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
}
return data;
}
uint32_t __FlashCtl_remaskData32Pre(uint32_t data, uint32_t addr)
{
uint32_t bankProgramStart, bankProgramEnd, bank1Start;
uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
/* Changing the waitstate and read mode of whichever bank we are in */
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bank1Start = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bank1Start = SysCtl_getFlashSize() / 2;
}
bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
bankProgramEnd = (addr + 4) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
/* Saving the current wait states and read mode */
b0WaitState = FlashCtl_getWaitState(bankProgramStart);
b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
if (bankProgramStart != bankProgramEnd)
{
b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
}
data |= ~(HWREG32(addr) | data);
/* Setting the wait state to account for the mode */
FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
FlashCtl_setWaitState(bankProgramStart, b0WaitState);
if (bankProgramStart != bankProgramEnd)
{
FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
}
return data;
}
void __FlashCtl_remaskBurstDataPre(uint32_t addr, uint32_t size)
{
uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
/* Waiting for idle status */
while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
!= FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
{
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
}
/* Changing the waitstate and read mode of whichever bank we are in */
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bank1Start = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bank1Start = SysCtl_getFlashSize() / 2;
}
bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
/* Saving the current wait states and read mode */
b0WaitState = FlashCtl_getWaitState(bankProgramStart);
b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
if (bankProgramStart != bankProgramEnd)
{
b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
}
/* Going through each BURST program register and masking out for pre
* verifcation
*/
size = (size / 4);
for (ii = 0; ii < size; ii++)
{
HWREG32(__getBurstProgramRegs[ii]) |=
~(HWREG32(__getBurstProgramRegs[ii])
| HWREG32(addr));
addr += 4;
}
/* Setting the wait state to account for the mode */
FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
FlashCtl_setWaitState(bankProgramStart, b0WaitState);
if (bankProgramStart != bankProgramEnd)
{
FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
}
}
void __FlashCtl_remaskBurstDataPost(uint32_t addr, uint32_t size)
{
uint32_t bankProgramStart, bankProgramEnd, bank1Start, ii;
uint32_t b0WaitState, b0ReadMode, b1WaitState, b1ReadMode;
/* Waiting for idle status */
while ((FLCTL->PRGBRST_CTLSTAT & FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_MASK)
!= FLCTL_PRGBRST_CTLSTAT_BURST_STATUS_0)
{
BITBAND_PERI(FLCTL->PRGBRST_CTLSTAT,
FLCTL_PRGBRST_CTLSTAT_CLR_STAT_OFS) = 1;
}
/* Changing the waitstate and read mode of whichever bank we are in */
/* Finding out which bank we are in */
if(addr > SysCtl_getFlashSize())
{
bank1Start = __INFO_FLASH_TECH_MIDDLE__;
}
else
{
bank1Start = SysCtl_getFlashSize() / 2;
}
bankProgramStart = addr < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
bankProgramEnd = (addr + size) < bank1Start ? FLASH_BANK0 : FLASH_BANK1;
/* Saving the current wait states and read mode */
b0WaitState = FlashCtl_getWaitState(bankProgramStart);
b0ReadMode = FlashCtl_getReadMode(bankProgramStart);
FlashCtl_setWaitState(bankProgramStart, (2 * b0WaitState) + 1);
FlashCtl_setReadMode(bankProgramStart, FLASH_PROGRAM_VERIFY_READ_MODE);
if (bankProgramStart != bankProgramEnd)
{
b1WaitState = FlashCtl_getWaitState(bankProgramEnd);
b1ReadMode = FlashCtl_getReadMode(bankProgramEnd);
FlashCtl_setWaitState(bankProgramEnd, (2 * b1WaitState) + 1);
FlashCtl_setReadMode(bankProgramEnd, FLASH_PROGRAM_VERIFY_READ_MODE);
}
/* Going through each BURST program register and masking out for post
* verifcation if needed
*/
size = (size / 4);
for (ii = 0; ii < size; ii++)
{
HWREG32(__getBurstProgramRegs[ii]) = ~(~(HWREG32(
__getBurstProgramRegs[ii])) & HWREG32(addr));
addr += 4;
}
/* Setting the wait state to account for the mode */
FlashCtl_setReadMode(bankProgramStart, b0ReadMode);
FlashCtl_setWaitState(bankProgramStart, b0WaitState);
if (bankProgramStart != bankProgramEnd)
{
FlashCtl_setReadMode(bankProgramEnd, b1ReadMode);
FlashCtl_setWaitState(bankProgramEnd, b1WaitState);
}
}