This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: TM4C1294 Flash erase issue

Part Number: TM4C1294NCPDT

Tool/software:

Hi Team

I partitioned the Bootloader  Flash memory to store and boot the Firmware application Hex from bootloader

Each time during new Firmware application Hex to be upgraded I need to  Erase the old Application hex 

The size of the hex is around 800 KB

When I try to erase the Flash of old Firmware application Hex during  boot up of the Bootloader for new firmware upgrade 

It is not erasing completely 

For eg 

Bootloader code is star address 0x00000000

Bootloader end address is 0x0000c000

Firmware application Hex start address 0x0000D000

Firmware application Hex end address  0x00067570

when I erase the flash for firmware upgrade it is erasing only from 0x0000D000 to 0x0000FFFC

after 0x0000FFFC address it is not erasing 

please tell how to solve the issue I added the memory window and code snippet  for your review

after 0x0000FFFC it is not getting erased

This is my last address 

Below is my code for your reference

uint32_t *pui32App = NULL;
pui32App = (uint32_t *)FW_UPGRADE_MEMORY;
//UARTprintf("Erase secondary memory\n");
if((pui32App[0] != 0xffffffff) ||
(pui32App[1] != 0xffffffff))
{
UARTprintf("Erase secondary memory\n");
Flash_Erase(FW_UPGRADE_MEMORY,900);
}

SysCtlDelay(2000);

void Flash_vEnable(void)
{
// If the KEY flag (bit 4) is set, then the key is 0xA442.
// Otherwise, the key is 0x71D5 (pg. 583 of the TM4C123 datasheet).
if (BOOTCFG & 0x10) {
u16_Glob_flashKey = 0xA442;
}
else {
u16_Glob_flashKey = 0x71D5;
}

}

void Flash_Erase(uint32_t FlashBaseAddress,uint32_t blockCount) /*block is 1k*/
{
uint32_t i;
Flash_vEnable();
for ( i = 0; i < blockCount; i++)
{
SysCtlDelay(20);
// Clear then set the OFFSET (17:0) with the write address
FMA &= 0xFFFC0000; //clear from bit zero to 17

// Blocks are erased on 1KiB boundaries, so multiply the index by 1024
// and add this to the base address
FMA |= FlashBaseAddress + (i*FLASH_BLOCK_SIZE);

// Set the ERASE command bit
FMC = (u16_Glob_flashKey << 16) | 0x2;

// Poll the ERASE bit until it is cleared
while (FMC & 0x2);

UARTprintf("\rFlasherase count %d\r\n",i);


}
}

Please  help me to sort the issue is there any changes to be made in the code or flash configurations

.cmd file for refernce

  • void Flash_Erase(uint32_t FlashBaseAddress,uint32_t blockCount) /*block is 1k*/
    {
    uint32_t i;
    Flash_vEnable();
    for ( i = 0; i < blockCount; i++)
    {
    SysCtlDelay(20);
    // Clear then set the OFFSET (17:0) with the write address
    FMA &= 0xFFFC0000; //clear from bit zero to 17

    // Blocks are erased on 1KiB boundaries, so multiply the index by 1024
    // and add this to the base address
    FMA |= FlashBaseAddress + (i*FLASH_BLOCK_SIZE);

    // Set the ERASE command bit
    FMC = (u16_Glob_flashKey << 16) | 0x2;

    // Poll the ERASE bit until it is cleared
    while (FMC & 0x2);

    UARTprintf("\rFlasherase count %d\r\n",i);


    }

    What is your blockCount? You seem to think that a block is only 1kB. This is not true. When erasing a block, a size of 16kB is erased. You need to advance your FMA by 16kB as you loop through the range of flash that you want to erase. Refer to the Flash Memory section the datasheet. 

    The interleaved memory prefetchs 256 bits at a time. The prefetch buffers allow the maximum
    performance of a 120 MHz CPU speed to be maintained with linear code or loops that fit within the
    prefetch buffer. It is recommended that code be compiled with switches set to eliminate "literals" as
    much as possible as a literal causes a flash access for that word and a stall for the wait states. Most
    compilers support transforming literals into "in-line" code, which executes faster in a system where
    the memory subsystem is slower than the CPU.
    Because the memory is two-way interleaved and each bank individually is an 8-KB sector, when
    the user erases a sector, using the ERASE bits in the Flash Memory Control (FMC) register, it is
    a 16 KB erase. Erasing a block causes the entire contents of the block to be reset to all 1s.

  • #FLASH_BLOCK_SIZE 1024

    define FW_UPGRADE_SIZE (0x00067700 - 0x0000D000)  = 0x5 A700
    #define FW_UPGRADE_BLOCKS (FW_UPGRADE_SIZE / FLASH_BLOCK_SIZE)  = 0x 5 A700/1024 =  361 blocks

  • As I said, you need to change your FLASH_BLOCK_SIZE to 16384 and increment your address for FMA 16k at a time. 

  • can you please edit the code for 16k FMA increment i actually dont know  how to make it 

  • Why don't you refer to the bl_main.c file on how it sequences through flash blocks for erase. To to line 547 which is part of the Updater() function. ,

    g_ui32TransferAddress will be 0xD000 in you case. g_ui32TransferSize will be (0x67570 - 0xD000). FLASH_PAGE_SIZE is 0x4000. Look at how it sequence through the memory for erase based on the starting address and the size of program image to be programmed. 

     

    ui32FlashSize = g_ui32TransferAddress + g_ui32TransferSize;
    #endif

    //
    // Clear the flash access interrupt.
    //
    BL_FLASH_CL_ERR_FN_HOOK();

    //
    // Leave the boot loader present until we start getting an
    // image.
    //
    for(ui32Temp = g_ui32TransferAddress;
    ui32Temp < ui32FlashSize; ui32Temp += FLASH_PAGE_SIZE)
    {
    //
    // Erase this block.
    //
    BL_FLASH_ERASE_FN_HOOK(ui32Temp);
    }

    //
    // Return an error if an access violation occurred.
    //
    if(BL_FLASH_ERROR_FN_HOOK())
    {
    g_ui8Status = COMMAND_RET_FLASH_FAIL;
    }
    }
    while(0);

  • can you please edit with this function no  need for bootloader demo code

    uint32_t *pui32App = NULL;
    pui32App = (uint32_t *)FW_UPGRADE_MEMORY;
    //UARTprintf("Erase secondary memory\n");
    if((pui32App[0] != 0xffffffff) ||
    (pui32App[1] != 0xffffffff))
    {
    UARTprintf("Erase secondary memory\n");
    Flash_Erase(FW_UPGRADE_MEMORY,900);
    }

    SysCtlDelay(2000);

    void Flash_vEnable(void)
    {
    // If the KEY flag (bit 4) is set, then the key is 0xA442.
    // Otherwise, the key is 0x71D5 (pg. 583 of the TM4C123 datasheet).
    if (BOOTCFG & 0x10) {
    u16_Glob_flashKey = 0xA442;
    }
    else {
    u16_Glob_flashKey = 0x71D5;
    }

    }

    void Flash_Erase(uint32_t FlashBaseAddress,uint32_t blockCount) /*block is 1k*/
    {
    uint32_t i;
    Flash_vEnable();
    for ( i = 0; i < blockCount; i++)
    {
    SysCtlDelay(20);
    // Clear then set the OFFSET (17:0) with the write address
    FMA &= 0xFFFC0000; //clear from bit zero to 17

    // Blocks are erased on 1KiB boundaries, so multiply the index by 1024
    // and add this to the base address
    FMA |= FlashBaseAddress + (i*FLASH_BLOCK_SIZE);

    // Set the ERASE command bit
    FMC = (u16_Glob_flashKey << 16) | 0x2;

    // Poll the ERASE bit until it is cleared
    while (FMC & 0x2);

    UARTprintf("\rFlasherase count %d\r\n",i);


    }
    }

  • Hi Charles 

    I tried it by changing to 16 k but when ever it starts erasing only 3 blocks got erased and  the  program get struck like hanged 

  • I'm actually on vacation today.

    You are passing 900 as the number of blocks. Why? If each block is 16kB then you are sequencing through 900 * 16kB equal to 14MB of memory. You are going beyond the available flash memory. Why don't you print out the log for the block number that you are erasing. I can look after I come back next week. 

    Flash_Erase(FW_UPGRADE_MEMORY,900);