/*
 * -------------------------------------------
 *    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);
    }
}
