/* * Copyright (c) 2020, 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. */ #include #include #include #include static void DL_FlashCTL_programMemoryConfig( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd); static DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_executeCommandFromRAM( FLASHCTL_Regs *flashctl); static void DL_FlashCTL_programMemory8Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint8_t *data); static void DL_FlashCTL_programMemory16Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint16_t *data); static void DL_FlashCTL_programMemory32Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data); static void DL_FlashCTL_programMemory64Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data); #if defined(__ti_version__) || defined(__TI_COMPILER_VERSION__) #define RAMFUNC \ __attribute__((section(".TI.ramfunc"))) __attribute__((noinline)) #elif defined(__GNUC__) #define RAMFUNC __attribute__((section(".ramfunc"))) __attribute__((noinline)) #elif defined(__IAR_SYSTEMS_ICC__) #define RAMFUNC __ramfunc __attribute__((noinline)) #else #error "Compiler not supported for this function" #endif RAMFUNC static DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_executeCommandFromRAM( FLASHCTL_Regs *flashctl) { volatile uint32_t status; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; /* * After executing a flash operation, we will enter a do-while and read the * STATCMD register using the status variable. Within the loop it will * poll until DL_FLASHCTL_COMMAND_STATUS_PASSED or DL_FLASHCTL_COMMAND_STATUS_FAILED * is read from the STATCMD register. This is to ensure that it will properly poll * even when the CPU is running at maximum speeds. */ do { status = flashctl->GEN.STATCMD & (FLASHCTL_STATCMD_CMDDONE_MASK | FLASHCTL_STATCMD_CMDPASS_MASK | FLASHCTL_STATCMD_CMDINPROGRESS_MASK | FLASHCTL_STATCMD_CMDPASS_STATFAIL); } while ((DL_FLASHCTL_COMMAND_STATUS) status != (DL_FLASHCTL_COMMAND_STATUS_PASSED) && (DL_FLASHCTL_COMMAND_STATUS) status != (DL_FLASHCTL_COMMAND_STATUS_FAILED)); return ((DL_FLASHCTL_COMMAND_STATUS) status); } void DL_FlashCTL_eraseMemory(FLASHCTL_Regs *flashctl, uint32_t address, DL_FLASHCTL_COMMAND_SIZE memorySize) { /* Set command type and size */ flashctl->GEN.CMDTYPE = (uint32_t) memorySize | DL_FLASHCTL_COMMAND_TYPE_ERASE; /* Set address, address should be in the desired bank or sector to erase */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_eraseMemoryFromRAM( FLASHCTL_Regs *flashctl, uint32_t address, DL_FLASHCTL_COMMAND_SIZE memorySize) { /* Set command type and size */ flashctl->GEN.CMDTYPE = (uint32_t) memorySize | DL_FLASHCTL_COMMAND_TYPE_ERASE; /* Set address, address should be in the desired bank or sector to erase */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } bool DL_FlashCTL_massErase(FLASHCTL_Regs *flashctl) { bool status; DL_FlashCTL_unprotectMainMemory(flashctl); DL_FlashCTL_protectNonMainMemory(flashctl); DL_FlashCTL_eraseMemory( flashctl, FLASHCTL_BANK0_ADDRESS, DL_FLASHCTL_COMMAND_SIZE_BANK); status = DL_FlashCTL_waitForCmdDone(flashctl); if (DL_FactoryRegion_getDATAFlashSize() && (status == true)) { status = DL_FlashCTL_eraseDataBank(flashctl); } return (status); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_massEraseFromRAM( FLASHCTL_Regs *flashctl) { DL_FLASHCTL_COMMAND_STATUS status; DL_FlashCTL_unprotectMainMemory(flashctl); DL_FlashCTL_protectNonMainMemory(flashctl); status = DL_FlashCTL_eraseMemoryFromRAM( flashctl, FLASHCTL_BANK0_ADDRESS, DL_FLASHCTL_COMMAND_SIZE_BANK); if (DL_FactoryRegion_getDATAFlashSize() && (status != DL_FLASHCTL_COMMAND_STATUS_FAILED)) { status = DL_FlashCTL_eraseDataBankFromRAM(flashctl); } return (status); } bool DL_FlashCTL_massEraseMultiBank(FLASHCTL_Regs *flashctl) { bool status = true; uint32_t bankStartAddr = 0x0; uint8_t numBanks = DL_FactoryRegion_getNumBanks(); uint32_t flashSize = DL_FactoryRegion_getMAINFlashSize(); /* Assuming a sector size of 1KB */ uint32_t bankSize = (((uint32_t) flashSize / (uint32_t) numBanks) * 1024U); DL_FLASHCTL_BANK_SELECT bankSelect = DL_FLASHCTL_BANK_SELECT_0; bool eraseFlag = true; uint8_t bankIndex = 0; while (bankIndex < numBanks && status != false) { /* If flash bank swap policy is enabled, the primary bank will be write * and erase protected. Thus, we will not attempt an erase of the * primary bank. */ if (DL_SYSCTL_isFlashBankSwapEnabled()) { eraseFlag = (bankIndex < (numBanks / (uint8_t) 2)) ? false : true; } else { eraseFlag = true; } switch (bankIndex) { case 0: bankSelect = DL_FLASHCTL_BANK_SELECT_0; break; case 1: bankSelect = DL_FLASHCTL_BANK_SELECT_1; break; case 2: bankSelect = DL_FLASHCTL_BANK_SELECT_2; break; case 3: bankSelect = DL_FLASHCTL_BANK_SELECT_3; break; default: break; } bankStartAddr = (bankSize * bankIndex); if (eraseFlag == true) { DL_FlashCTL_enableAddressOverrideMode(flashctl); DL_FlashCTL_setBankSelect(flashctl, bankSelect); DL_FlashCTL_setRegionSelect( flashctl, DL_FLASHCTL_REGION_SELECT_MAIN); DL_FlashCTL_unprotectMainMemory(flashctl); DL_FlashCTL_protectNonMainMemory(flashctl); DL_FlashCTL_eraseMemory( flashctl, bankStartAddr, DL_FLASHCTL_COMMAND_SIZE_BANK); status = DL_FlashCTL_waitForCmdDone(flashctl); } bankIndex++; } DL_FlashCTL_disableAddressOverrideMode(flashctl); if (DL_FactoryRegion_getDATAFlashSize() && status == true) { status = DL_FlashCTL_eraseDataBank(flashctl); } return (status); } bool DL_FlashCTL_factoryReset(FLASHCTL_Regs *flashctl) { bool status; /* Erase Main Memory */ status = DL_FlashCTL_massErase(flashctl); if (status == true) { DL_FlashCTL_unprotectNonMainMemory(flashctl); DL_FlashCTL_eraseMemory(flashctl, FLASHCTL_NONMAIN_ADDRESS, DL_FLASHCTL_COMMAND_SIZE_SECTOR); status = DL_FlashCTL_waitForCmdDone(flashctl); } return (status); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_factoryResetFromRAM( FLASHCTL_Regs *flashctl) { DL_FLASHCTL_COMMAND_STATUS status; /* Erase Main Memory */ status = DL_FlashCTL_massEraseFromRAM(flashctl); if (status == DL_FLASHCTL_COMMAND_STATUS_PASSED) { DL_FlashCTL_unprotectNonMainMemory(flashctl); status = DL_FlashCTL_eraseMemoryFromRAM(flashctl, FLASHCTL_NONMAIN_ADDRESS, DL_FLASHCTL_COMMAND_SIZE_SECTOR); } return (status); } bool DL_FlashCTL_factoryResetMultiBank(FLASHCTL_Regs *flashctl) { bool status; /* Erase Main Memory */ status = DL_FlashCTL_massEraseMultiBank(flashctl); if (status == true) { DL_FlashCTL_unprotectNonMainMemory(flashctl); DL_FlashCTL_eraseMemory(flashctl, FLASHCTL_NONMAIN_ADDRESS, DL_FLASHCTL_COMMAND_SIZE_SECTOR); status = DL_FlashCTL_waitForCmdDone(flashctl); } return (status); } static void DL_FlashCTL_programMemoryConfig( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | DL_FLASHCTL_COMMAND_TYPE_PROGRAM; flashctl->GEN.CMDBYTEN = cmd; /* Set address, address should be in the sector that we want to erase */ DL_FlashCTL_setCommandAddress(flashctl, address); } static void DL_FlashCTL_programMemory8Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint8_t *data) { DL_FlashCTL_programMemoryConfig(flashctl, address, cmd); /* Set data registers */ flashctl->GEN.CMDDATA0 = *data; } static void DL_FlashCTL_programMemory16Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint16_t *data) { DL_FlashCTL_programMemoryConfig(flashctl, address, cmd); /* Set data registers */ flashctl->GEN.CMDDATA0 = *data; } static void DL_FlashCTL_programMemory32Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data) { DL_FlashCTL_programMemoryConfig(flashctl, address, cmd); /* Set data registers */ flashctl->GEN.CMDDATA0 = *data; } static void DL_FlashCTL_programMemory64Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data) { DL_FlashCTL_programMemoryConfig(flashctl, address, cmd); /* Set data registers */ flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATA1 = *(data + 1); } void DL_FlashCTL_programMemory8( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { /* Only enable the bottom 8 bits for programming*/ DL_FlashCTL_programMemory8Config( flashctl, address, DL_FLASHCTL_PROGRAM_8_WITHOUT_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM8( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { /* Only enable the bottom 8 bits for programming*/ DL_FlashCTL_programMemory8Config( flashctl, address, DL_FLASHCTL_PROGRAM_8_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory16( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { /* Enable 16 bits per data register for programming*/ DL_FlashCTL_programMemory16Config( flashctl, address, DL_FLASHCTL_PROGRAM_16_WITHOUT_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM16( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { /* Enable 16 bits per data register for programming*/ DL_FlashCTL_programMemory16Config( flashctl, address, DL_FLASHCTL_PROGRAM_16_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory32( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 32 bits per data register for programming*/ DL_FlashCTL_programMemory32Config( flashctl, address, DL_FLASHCTL_PROGRAM_32_WITHOUT_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM32( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 32 bits per data register for programming*/ DL_FlashCTL_programMemory32Config( flashctl, address, DL_FLASHCTL_PROGRAM_32_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory64( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 64 bits per data register for programming*/ DL_FlashCTL_programMemory64Config( flashctl, address, DL_FLASHCTL_PROGRAM_64_WITHOUT_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM64( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 64 bits per data register for programming*/ DL_FlashCTL_programMemory64Config( flashctl, address, DL_FLASHCTL_PROGRAM_64_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory8WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { /* Only enable the bottom 8 bits for programming*/ DL_FlashCTL_programMemory8Config( flashctl, address, DL_FLASHCTL_PROGRAM_8_WITH_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM8WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { /* Only enable the bottom 8 bits for programming*/ DL_FlashCTL_programMemory8Config( flashctl, address, DL_FLASHCTL_PROGRAM_8_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory16WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { /* Enable 16 bits per data register for programming*/ DL_FlashCTL_programMemory16Config( flashctl, address, DL_FLASHCTL_PROGRAM_16_WITH_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM16WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { /* Enable 16 bits per data register for programming*/ DL_FlashCTL_programMemory16Config( flashctl, address, DL_FLASHCTL_PROGRAM_16_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory32WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 32 bits per data register for programming*/ DL_FlashCTL_programMemory32Config( flashctl, address, DL_FLASHCTL_PROGRAM_32_WITH_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM32WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 32 bits per data register for programming*/ DL_FlashCTL_programMemory32Config( flashctl, address, DL_FLASHCTL_PROGRAM_32_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory64WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 64 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory64Config( flashctl, address, DL_FLASHCTL_PROGRAM_64_WITH_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM64WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 64 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory64Config( flashctl, address, DL_FLASHCTL_PROGRAM_64_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory8WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data, const uint8_t *eccCode) { /* Enable 8 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory8Config( flashctl, address, DL_FLASHCTL_PROGRAM_8_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM8WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data, const uint8_t *eccCode) { /* Enable 8 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory8Config( flashctl, address, DL_FLASHCTL_PROGRAM_8_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory16WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data, const uint8_t *eccCode) { /* Enable 16 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory16Config( flashctl, address, DL_FLASHCTL_PROGRAM_16_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM16WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data, const uint8_t *eccCode) { /* Enable 16 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory16Config( flashctl, address, DL_FLASHCTL_PROGRAM_16_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory32WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { /* Enable 32 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory32Config( flashctl, address, DL_FLASHCTL_PROGRAM_32_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM32WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { /* Enable 32 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory32Config( flashctl, address, DL_FLASHCTL_PROGRAM_32_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_programMemory64WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { /* Enable 64 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory64Config( flashctl, address, DL_FLASHCTL_PROGRAM_64_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM64WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { /* Enable 64 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory64Config( flashctl, address, DL_FLASHCTL_PROGRAM_64_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } bool DL_FlashCTL_programMemoryBlocking64WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { bool status = true; /* Check for valid data size */ if (dataSize == (uint32_t) 0 || ((dataSize & (uint32_t) 1) == (uint32_t) 1)) { status = false; } while ((dataSize != (uint32_t) 0) && status) { /* Clear STATCMD register before executing a flash operation */ DL_FlashCTL_executeClearStatus(flashctl); /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); DL_FlashCTL_programMemory64WithECCGenerated(flashctl, address, data); dataSize = dataSize - (uint32_t) 2; data = data + 2; address = address + (uint32_t) 8; status = DL_FlashCTL_waitForCmdDone(flashctl); } return (status); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryBlockingFromRAM64WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { DL_FLASHCTL_COMMAND_STATUS status = DL_FLASHCTL_COMMAND_STATUS_IN_PROGRESS; /* Check for valid data size */ if (dataSize == (uint32_t) 0 || ((dataSize & (uint32_t) 1) == (uint32_t) 1)) { status = DL_FLASHCTL_COMMAND_STATUS_FAILED; } while ((dataSize != (uint32_t) 0) && (status != DL_FLASHCTL_COMMAND_STATUS_FAILED)) { /* Clear STATCMD register before executing a flash operation */ DL_FlashCTL_executeClearStatus(flashctl); /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); status = DL_FlashCTL_programMemoryFromRAM64WithECCGenerated( flashctl, address, data); dataSize = dataSize - (uint32_t) 2; data = data + 2; address = address + (uint32_t) 8; } return (status); } bool DL_FlashCTL_programMemoryBlocking64WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint8_t *eccCode, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { bool status = true; /* Check for valid data size */ if (dataSize == (uint32_t) 0 || ((dataSize & (uint32_t) 1) == (uint32_t) 1)) { status = false; } while ((dataSize != (uint32_t) 0) && status) { /* Clear STATCMD register before executing a flash operation */ DL_FlashCTL_executeClearStatus(flashctl); /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); DL_FlashCTL_programMemory64WithECCManual( flashctl, address, data, eccCode); dataSize = dataSize - (uint32_t) 2; data = data + 2; eccCode = eccCode + 1; address = address + (uint32_t) 8; status = DL_FlashCTL_waitForCmdDone(flashctl); } return (status); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryBlockingFromRAM64WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint8_t *eccCode, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { DL_FLASHCTL_COMMAND_STATUS status = DL_FLASHCTL_COMMAND_STATUS_IN_PROGRESS; /* Check for valid data size */ if (dataSize == (uint32_t) 0 || ((dataSize & (uint32_t) 1) == (uint32_t) 1)) { status = DL_FLASHCTL_COMMAND_STATUS_FAILED; } while ((dataSize != (uint32_t) 0) && (status != DL_FLASHCTL_COMMAND_STATUS_FAILED)) { /* Clear STATCMD register before executing a flash operation */ DL_FlashCTL_executeClearStatus(flashctl); /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); status = DL_FlashCTL_programMemoryFromRAM64WithECCManual( flashctl, address, data, eccCode); dataSize = dataSize - (uint32_t) 2; data = data + 2; eccCode = eccCode + 1; address = address + (uint32_t) 8; } return (status); } bool DL_FlashCTL_programMemoryBlocking(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { bool status = true; /* Check for valid data size */ if (dataSize == (uint32_t) 0) { status = false; } while ((dataSize != (uint32_t) 0) && status) { /* Clear STATCMD register before executing a flash operation */ DL_FlashCTL_executeClearStatus(flashctl); /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); /* 32-bit case */ if (dataSize == (uint32_t) 1) { DL_FlashCTL_programMemory32(flashctl, address, data); dataSize = dataSize - (uint32_t) 1; data = data + 1; address = address + (uint32_t) 4; } else { /* 64-bit case */ DL_FlashCTL_programMemory64(flashctl, address, data); dataSize = dataSize - (uint32_t) 2; data = data + 2; address = address + (uint32_t) 8; } status = DL_FlashCTL_waitForCmdDone(flashctl); } return (status); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_programMemoryFromRAM( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { DL_FLASHCTL_COMMAND_STATUS status = DL_FLASHCTL_COMMAND_STATUS_IN_PROGRESS; /* Check for valid data size */ if (dataSize == (uint32_t) 0) { status = DL_FLASHCTL_COMMAND_STATUS_FAILED; } while ((dataSize != (uint32_t) 0) && (status != DL_FLASHCTL_COMMAND_STATUS_FAILED)) { /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); /* 32-bit case */ if (dataSize == (uint32_t) 1) { status = DL_FlashCTL_programMemoryFromRAM32(flashctl, address, data); dataSize = dataSize - (uint32_t) 1; data = data + 1; address = address + (uint32_t) 4; } else { /* 64-bit case */ status = DL_FlashCTL_programMemoryFromRAM64(flashctl, address, data); dataSize = dataSize - (uint32_t) 2; data = data + 2; address = address + (uint32_t) 8; } } return (status); } void DL_FlashCTL_unprotectMainMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTA = 0; flashctl->GEN.CMDWEPROTB = 0; flashctl->GEN.CMDWEPROTC = 0; } void DL_FlashCTL_unprotectDataMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTA = 0; flashctl->GEN.CMDWEPROTB = 0; flashctl->GEN.CMDWEPROTC = 0; } void DL_FlashCTL_protectMainMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTA = FLASHCTL_CMDWEPROTA_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTB = FLASHCTL_CMDWEPROTB_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTC = FLASHCTL_CMDWEPROTC_VAL_MAXIMUM; } void DL_FlashCTL_unprotectNonMainMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTNM = 0; } void DL_FlashCTL_protectNonMainMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTNM = FLASHCTL_CMDWEPROTNM_VAL_MAXIMUM; } void DL_FlashCTL_unprotectAllMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTA = 0; flashctl->GEN.CMDWEPROTB = 0; flashctl->GEN.CMDWEPROTC = 0; flashctl->GEN.CMDWEPROTNM = 0; flashctl->GEN.CMDWEPROTTR = 0; flashctl->GEN.CMDWEPROTEN = 0; } void DL_FlashCTL_protectAllMemory(FLASHCTL_Regs *flashctl) { flashctl->GEN.CMDWEPROTA = FLASHCTL_CMDWEPROTA_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTB = FLASHCTL_CMDWEPROTB_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTC = FLASHCTL_CMDWEPROTC_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTNM = FLASHCTL_CMDWEPROTNM_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTTR = FLASHCTL_CMDWEPROTTR_VAL_MAXIMUM; flashctl->GEN.CMDWEPROTEN = FLASHCTL_CMDWEPROTEN_VAL_MAXIMUM; } #ifdef DEVICE_HAS_NO_CMDWEPROTA void DL_FlashCTL_unprotectSector(FLASHCTL_Regs *flashctl, uint32_t addr, DL_FLASHCTL_REGION_SELECT regionSelect) { uint32_t sectorNumber = DL_FlashCTL_getFlashSectorNumber(flashctl, addr); uint32_t sectorInBank = DL_FlashCTL_getFlashSectorNumberInBank(flashctl, addr); uint32_t sectorMask; /* * Devices without CMDWEPROTA will use CMDWEPROTB to unprotect all sectors of MAIN memory */ if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_MAIN) { sectorMask = (uint32_t) 1 << ((sectorInBank / (uint32_t) 8) % (uint32_t) 32); flashctl->GEN.CMDWEPROTB &= ~sectorMask; } else if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_NONMAIN) { sectorMask = (uint32_t) 1 << (sectorNumber % (uint32_t) 32); flashctl->GEN.CMDWEPROTNM &= ~sectorMask; } else { ; /* Not expected to reach this else statement */ } } #else void DL_FlashCTL_unprotectSector(FLASHCTL_Regs *flashctl, uint32_t addr, DL_FLASHCTL_REGION_SELECT regionSelect) { uint32_t sectorNumber = DL_FlashCTL_getFlashSectorNumber(flashctl, addr); uint32_t sectorInBank = DL_FlashCTL_getFlashSectorNumberInBank(flashctl, addr); uint8_t numBanks = DL_FactoryRegion_getNumBanks(); uint32_t mainFlashSize = DL_FactoryRegion_getMAINFlashSize(); uint32_t physicalSectorNumber = 0; uint32_t sectorMask; if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_MAIN) { /* If the banks have been swapped, CMDWEPROTA only protects physical * bank 0 (logical bank 1 in a swap), so if the address points to this * region we must protect it using CMDWEPROTA instead of CMDWEPROTB */ if (DL_SYSCTL_isExecuteFromUpperFlashBank() && numBanks > 1) { /* physical sectors are swapped. Calculate physical sector to * determine use of CMDWEPROTA */ if (sectorNumber >= (mainFlashSize / 2)) { physicalSectorNumber = sectorNumber - (mainFlashSize / 2); } else { physicalSectorNumber = sectorNumber + (mainFlashSize / 2); } } else { physicalSectorNumber = sectorNumber; } if (physicalSectorNumber < (uint32_t) 32) { /* Use CMDWEPROTA */ sectorMask = (uint32_t) 1 << physicalSectorNumber; flashctl->GEN.CMDWEPROTA &= ~sectorMask; } else { /* Use CMDWEPROTB */ if (sectorInBank < (uint32_t) 256) { /* Single bank system */ if (DL_FactoryRegion_getNumBanks() == (uint32_t) 1) { sectorMask = (uint32_t) 1 << ((sectorInBank - (uint32_t) 32) / (uint32_t) 8); flashctl->GEN.CMDWEPROTB &= ~sectorMask; } else { /* Multi bank system */ sectorMask = (uint32_t) 1 << (sectorInBank / (uint32_t) 8); flashctl->GEN.CMDWEPROTB &= ~sectorMask; } } /* Use CMDWEPROTC */ else if (sectorInBank < (uint32_t) 511) { sectorMask = ((uint32_t) 1 << ((sectorInBank - (uint32_t) 256) / (uint32_t) 8)); flashctl->GEN.CMDWEPROTC &= ~sectorMask; } else { ; /* Not expected to reach this else statement */ } } } else if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_NONMAIN) { sectorMask = (uint32_t) 1 << (sectorNumber % (uint32_t) 32); flashctl->GEN.CMDWEPROTNM &= ~sectorMask; } else { ; /* Not expected to reach this else statement */ } } #endif #ifdef DEVICE_HAS_NO_CMDWEPROTA void DL_FlashCTL_protectSector(FLASHCTL_Regs *flashctl, uint32_t addr, DL_FLASHCTL_REGION_SELECT regionSelect) { uint32_t sectorNumber = DL_FlashCTL_getFlashSectorNumber(flashctl, addr); uint32_t sectorInBank = DL_FlashCTL_getFlashSectorNumberInBank(flashctl, addr); uint32_t sectorMask; /* * Devices without CMDWEPROTA will use CMDWEPROTB to protect all sectors of MAIN memory */ if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_MAIN) { sectorMask = ((uint32_t) 1 << (sectorInBank / (uint32_t) 8)); flashctl->GEN.CMDWEPROTB |= sectorMask; } else if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_NONMAIN) { sectorNumber = DL_FlashCTL_getFlashSectorNumber(flashctl, addr); sectorMask = (uint32_t) 1 << (sectorNumber % (uint32_t) 32); flashctl->GEN.CMDWEPROTNM |= sectorMask; } else { ; /* Not expected to reach this else statement */ } } #else void DL_FlashCTL_protectSector(FLASHCTL_Regs *flashctl, uint32_t addr, DL_FLASHCTL_REGION_SELECT regionSelect) { uint32_t sectorNumber = DL_FlashCTL_getFlashSectorNumber(flashctl, addr); uint32_t sectorInBank = DL_FlashCTL_getFlashSectorNumberInBank(flashctl, addr); uint8_t numBanks = DL_FactoryRegion_getNumBanks(); uint32_t mainFlashSize = DL_FactoryRegion_getMAINFlashSize(); uint32_t physicalSectorNumber = 0; uint32_t sectorMask; if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_MAIN) { /* If the banks have been swapped, CMDWEPROTA only protects physical * bank 0 (logical bank 1 in a swap), so if the address points to this * region we must protect it using CMDWEPROTA instead of CMDWEPROTB */ if (DL_SYSCTL_isExecuteFromUpperFlashBank() && numBanks > 1) { /* physical sectors are swapped. Calculate physical sector to * determine use of CMDWEPROTA */ if (sectorNumber >= (mainFlashSize / 2)) { physicalSectorNumber = sectorNumber - (mainFlashSize / 2); } else { physicalSectorNumber = sectorNumber + (mainFlashSize / 2); } } else { physicalSectorNumber = sectorNumber; } if (physicalSectorNumber < (uint32_t) 32) { /* Use CMDWEPROTA */ sectorMask = (uint32_t) 1 << physicalSectorNumber; flashctl->GEN.CMDWEPROTA |= sectorMask; } else { /* Use CMDWEPROTB */ if (sectorNumber < (uint32_t) 256) { /* Single bank system */ if (DL_FactoryRegion_getNumBanks() == (uint32_t) 1) { sectorMask = (uint32_t) 1 << ((sectorInBank - (uint32_t) 32) / (uint32_t) 8); flashctl->GEN.CMDWEPROTB |= sectorMask; } else { /* Multi bank system */ sectorMask = ((uint32_t) 1 << (sectorInBank / (uint32_t) 8)); flashctl->GEN.CMDWEPROTB |= sectorMask; } } /* Use CMDWEPROTC */ else if (sectorNumber < (uint32_t) 511) { sectorMask = ((uint32_t) 1 << ((sectorInBank - (uint32_t) 256) / (uint32_t) 8)); flashctl->GEN.CMDWEPROTC |= sectorMask; } else { ; /* Not expected to reach this else statement */ } } } else if ((uint32_t) regionSelect == FLASHCTL_CMDCTL_REGIONSEL_NONMAIN) { sectorNumber = DL_FlashCTL_getFlashSectorNumber(flashctl, addr); sectorMask = (uint32_t) 1 << (sectorNumber % (uint32_t) 32); flashctl->GEN.CMDWEPROTNM |= sectorMask; } else { ; /* Not expected to reach this else statement */ } } #endif static void DL_FlashCTL_readVerifyConfig( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; flashctl->GEN.CMDBYTEN = cmd; /* Set address, address should be in the sector that we want to erase */ DL_FlashCTL_setCommandAddress(flashctl, address); } static void DL_FlashCTL_readVerify8Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint8_t *data) { DL_FlashCTL_readVerifyConfig(flashctl, address, cmd); flashctl->GEN.CMDDATA0 = *data; } static void DL_FlashCTL_readVerify16Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint16_t *data) { DL_FlashCTL_readVerifyConfig(flashctl, address, cmd); flashctl->GEN.CMDDATA0 = *data; } static void DL_FlashCTL_readVerify32Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data) { DL_FlashCTL_readVerifyConfig(flashctl, address, cmd); flashctl->GEN.CMDDATA0 = *data; } static void DL_FlashCTL_readVerify64Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data) { DL_FlashCTL_readVerifyConfig(flashctl, address, cmd); /* Set data registers */ flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATA1 = *(data + 1); } void DL_FlashCTL_readVerify8( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_8_WITHOUT_ECC; flashctl->GEN.CMDDATA0 = *data; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify16( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_16_WITHOUT_ECC; flashctl->GEN.CMDDATA0 = *data; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify32( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_32_WITHOUT_ECC; flashctl->GEN.CMDDATA0 = *data; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify64( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_64_WITHOUT_ECC; flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATA1 = *(data + 1); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM8( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { DL_FlashCTL_readVerify8Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_8_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM16( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { DL_FlashCTL_readVerify16Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_16_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM32( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { DL_FlashCTL_readVerify32Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_32_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM64( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { DL_FlashCTL_readVerify64Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_64_WITHOUT_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM8WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { DL_FlashCTL_readVerify8Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_8_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM16WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { DL_FlashCTL_readVerify16Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_16_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM32WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { DL_FlashCTL_readVerify32Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_32_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM64WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { DL_FlashCTL_readVerify64Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_64_WITH_ECC, data); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM8WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data, const uint8_t *eccCode) { DL_FlashCTL_readVerify8Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_8_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM16WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data, const uint8_t *eccCode) { DL_FlashCTL_readVerify16Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_16_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM32WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { DL_FlashCTL_readVerify32Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_32_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_readVerifyFromRAM64WithECCManual( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { DL_FlashCTL_readVerify64Config( flashctl, address, DL_FLASHCTL_READ_VERIFY_64_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } void DL_FlashCTL_readVerify8WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_8_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify16WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_16_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify32WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_32_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify64WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_64_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATA1 = *(data + 1); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify8WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint8_t *data, const uint8_t *eccCode) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_8_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify16WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint16_t *data, const uint8_t *eccCode) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_16_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify32WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_32_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_readVerify64WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_READ_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Configure bytes to use for comparison, with ECC enabled */ flashctl->GEN.CMDBYTEN = DL_FLASHCTL_READ_VERIFY_64_WITH_ECC; flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATA1 = *(data + 1); flashctl->GEN.CMDDATAECC0 = *eccCode; /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_blankVerify(FLASHCTL_Regs *flashctl, uint32_t address) { /* Set command and word size. BLANKVERIFY can only be applied to a single * flash word at a time */ flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_BLANK_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_blankVerifyFromRAM( FLASHCTL_Regs *flashctl, uint32_t address) { /* Set command and word size. BLANKVERIFY can only be applied to a single * flash word at a time */ flashctl->GEN.CMDTYPE = (uint32_t) DL_FLASHCTL_COMMAND_SIZE_ONE_WORD | (uint32_t) DL_FLASHCTL_COMMAND_TYPE_BLANK_VERIFY; /* Set the address we want to verify */ DL_FlashCTL_setCommandAddress(flashctl, address); /* Jump to RAM to execute command and wait for completion */ return DL_FlashCTL_executeCommandFromRAM(flashctl); } bool DL_FlashCTL_eraseDataBank(FLASHCTL_Regs *flashctl) { bool status = true; uint32_t address = FLASHCTL_DATA_ADDRESS; uint8_t dataFlashSectors = DL_FactoryRegion_getDATAFlashSize(); while ((dataFlashSectors != (uint8_t) 0) && (status == true)) { DL_FlashCTL_executeClearStatus(flashctl); DL_FlashCTL_unprotectSector( flashctl, address, DL_FLASHCTL_REGION_SELECT_MAIN); DL_FlashCTL_eraseMemory( flashctl, address, DL_FLASHCTL_COMMAND_SIZE_SECTOR); status = DL_FlashCTL_waitForCmdDone(flashctl); address = address + (uint32_t) DL_FLASHCTL_SECTOR_SIZE; dataFlashSectors = dataFlashSectors - (uint8_t) 1; } return (status); } DL_FLASHCTL_COMMAND_STATUS DL_FlashCTL_eraseDataBankFromRAM( FLASHCTL_Regs *flashctl) { DL_FLASHCTL_COMMAND_STATUS status = DL_FLASHCTL_COMMAND_STATUS_PASSED; uint32_t address = FLASHCTL_DATA_ADDRESS; uint8_t dataFlashSectors = DL_FactoryRegion_getDATAFlashSize(); while ((dataFlashSectors != (uint8_t) 0) && (status == DL_FLASHCTL_COMMAND_STATUS_PASSED)) { DL_FlashCTL_executeClearStatus(flashctl); DL_FlashCTL_unprotectSector( flashctl, address, DL_FLASHCTL_REGION_SELECT_MAIN); status = DL_FlashCTL_eraseMemoryFromRAM( flashctl, address, DL_FLASHCTL_COMMAND_SIZE_SECTOR); address = address + (uint32_t) DL_FLASHCTL_SECTOR_SIZE; dataFlashSectors = dataFlashSectors - (uint8_t) 1; } return (status); } #ifdef DEVICE_HAS_FLASH_128_BIT_WORD static void DL_FlashCTL_programMemory128Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data); static void DL_FlashCTL_programMemoryConfigMultiWord(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, DL_FLASHCTL_COMMAND_SIZE cmdSize); /*! * @brief Enable programming 128 bits without ECC enabled */ #define DL_FLASHCTL_PROGRAM_128_WITHOUT_ECC (0x0000FFFF) /*! * @brief Enable programming 128 bits with ECC enabled */ #define DL_FLASHCTL_PROGRAM_128_WITH_ECC (0x0001FFFF) static void DL_FlashCTL_programMemoryConfigMultiWord(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, DL_FLASHCTL_COMMAND_SIZE cmdSize) { flashctl->GEN.CMDTYPE = (uint32_t) cmdSize | DL_FLASHCTL_COMMAND_TYPE_PROGRAM; flashctl->GEN.CMDBYTEN = cmd; /* Set address, address should be in the sector that we want to erase */ DL_FlashCTL_setCommandAddress(flashctl, address); } static void DL_FlashCTL_programMemory128Config(FLASHCTL_Regs *flashctl, uint32_t address, uint32_t cmd, const uint32_t *data) { DL_FlashCTL_programMemoryConfigMultiWord( flashctl, address, cmd, DL_FLASHCTL_COMMAND_SIZE_TWO_WORDS); /* Set data registers */ flashctl->GEN.CMDDATA0 = *data; flashctl->GEN.CMDDATA1 = *(data + 1); flashctl->GEN.CMDDATA2 = *(data + 2); flashctl->GEN.CMDDATA3 = *(data + 3); } void DL_FlashCTL_programMemory128( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 128 bits per data register for programming*/ DL_FlashCTL_programMemory128Config( flashctl, address, DL_FLASHCTL_PROGRAM_128_WITHOUT_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_programMemory128WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data) { /* Enable 128 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory128Config( flashctl, address, DL_FLASHCTL_PROGRAM_128_WITH_ECC, data); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } void DL_FlashCTL_programMemory128WithECCManual(FLASHCTL_Regs *flashctl, uint32_t address, const uint32_t *data, const uint8_t *eccCode) { /* Enable 128 bits per data register for programming, with ECC enabled */ DL_FlashCTL_programMemory128Config( flashctl, address, DL_FLASHCTL_PROGRAM_128_WITH_ECC, data); flashctl->GEN.CMDDATAECC0 = *eccCode; flashctl->GEN.CMDDATAECC1 = *(eccCode + 1); /* Set bit to execute command */ flashctl->GEN.CMDEXEC = FLASHCTL_CMDEXEC_VAL_EXECUTE; } bool DL_FlashCTL_programMemoryBlocking128WithECCGenerated( FLASHCTL_Regs *flashctl, uint32_t address, uint32_t *data, uint32_t dataSize, DL_FLASHCTL_REGION_SELECT regionSelect) { bool status = true; /* Check for valid data size */ if ((dataSize == (uint32_t) 0) || dataSize < (uint32_t) 4) { status = false; } while ((dataSize != (uint32_t) 0) && status) { /* Clear STATCMD register before executing a flash operation */ DL_FlashCTL_executeClearStatus(flashctl); /* Unprotect sector before every write */ DL_FlashCTL_unprotectSector(flashctl, address, regionSelect); /* 32-bit case */ if (dataSize == (uint32_t) 1) { DL_FlashCTL_programMemory32WithECCGenerated( flashctl, address, data); dataSize = dataSize - (uint32_t) 1; data = data + 1; address = address + (uint32_t) 4; } else if (dataSize < (uint32_t) 4) { /* 64-bit case */ DL_FlashCTL_programMemory64WithECCGenerated( flashctl, address, data); dataSize = dataSize - (uint32_t) 2; data = data + 2; address = address + (uint32_t) 8; } else { /* 128-bit case */ DL_FlashCTL_programMemory128WithECCGenerated( flashctl, address, data); dataSize = dataSize - (uint32_t) 4; data = data + 4; address = address + (uint32_t) 16; } status = DL_FlashCTL_waitForCmdDone(flashctl); } return (status); } #endif /* DEVICE_HAS_FLASH_128_BIT_WORD */