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.

TM4C123bh6zrb flash erase does not work after software reset

we are trying to erase the flash from our customer boot loader program and the erase code is running from RAM. we are seeing a strange behaviour, it runs perfectly fine when we load/run the boot loader from CCS for the first time, but after a software reset the erase code does not erase the flash. Even though there is no error in FCRIS register but the flash contents don't get erased. we verified that the second time also the erase code was running from RAM only. we do disable the interrupts using ROM_IntMasterDisable() before erase code.


linker script:
==============

--retain=g_pfnVectors


MEMORY
{
    FLASH (RX)             : origin = FLASH_BL_BASE,               length = FLASH_BL_LENGTH_EXCLUDING_FUNCS  // Flash space for bootloader
    FLASH_ACCESS_FUNCS(R)       : origin = FLASH_ACCESS_FUNCS_BASE,     length = FLASH_ACCESS_FUNCS_LENGTH  // Flash space for flash access functions that need to be copied to RAM
    FLASH_APP (RWX)         : origin = FLASH_APP_BASE,              length = FLASH_END  // Flash space for IO_Module application
    SRAM (RWX)            : origin = RAM_BASE,                    length = RAM_BL_LENGTH  // RAM space for bootloader
    RAM_FLASH_ACCESS_FUNCS(RWX)    : origin = RAM_FLASH_ACCESS_FUNCS_BASE, length = FLASH_ACCESS_FUNCS_LENGTH //RAM space for the Internal Flash access functions to be moved
}

/* Section allocation in memory */

SECTIONS
{
    .intvecs:   > FLASH_BL_BASE
    .text   :   > FLASH
    .cinit  :   > FLASH
    .const  :   > FLASH
    .pinit  :   > FLASH
    .init_array : > FLASH

    .vtable :   > RAM_BASE
    .data   :   > SRAM
    .bss    :   > SRAM
    .sysmem :   > SRAM
    .stack  :   > SRAM

   .RAMCODE : load = FLASH_ACCESS_FUNCS, run = RAM_FLASH_ACCESS_FUNCS

}

__STACK_TOP = __stack + 4096;
 


Erase Code:
==============


#pragma CODE_SECTION(eraseInternalFlash,".RAMCODE")
bool eraseInternalFlash( uint32_t startAddr, uint32_t nBytes )
{
    bool retCode = false;
    BL_ASSERT(startAddr > FLASH_APP_BASE);
    BL_ASSERT(nBytes < FLASH_IMAGE_MAX_SIZE  );
    uint32_t endAddr = startAddr + nBytes;
 
 
 
 
    while(endAddr >= startAddr)
    {
        //
        // Check the arguments.
        //
        ASSERT(!(startAddr & (FLASH_ERASE_SIZE - 1)));
 
        //
        // Clear the flash access and error interrupts.
        //
        HWREG(FLASH_FCMISC) = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |
                               FLASH_FCMISC_ERMISC);
 
        //
        // Erase the block.
        //
        HWREG(FLASH_FMA) = startAddr;
        HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
 
        //
        // Wait until the block has been erased.
        //
        while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
        {
        }
 
        //
        // Return an error if an access violation or erase error occurred.
        //
        if(HWREG(FLASH_FCRIS) & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |
                                 FLASH_FCRIS_ERRIS))
        {
            retCode = false;
            break;
        }
 
        startAddr += ERASE_BLOCK;
    }
    if(startAddr >= endAddr)
    retCode = true;
 
    return retCode;
}

  • Hello Praveen

    To understand the issue better:

    1. The Boot Loader code is in place and is trying to erase the application code region?
    2. The Boot Loader code sets the address of the application code start region correctly and then attempts an erase? The status bit show that erase is complete but the debugger shows it is not?

    If you try to do the same via the debugger then does the erase happen?

    Regards
    Amit
  • 1.
    The Boot Loader code is in place and is trying to erase the application code
    region?

    yes, our bootloader sits at address 0x0000 and our application starts at 0x2800.The bootloader tries to erase the flash from 0x2800. 


    2. The Boot Loader code sets the address of the application code start region
    correctly and then attempts an erase? The status bit show that erase is
    complete but the debugger shows it is not?

     Yes.


    If you try to do the same via the debugger then does the erase happen?

    Yes, always.

  • another thing we noticed that when the erase is successful the INVDRIS bit in FCRIS is set and when it does not work INVDRIS bit is not set. although we do not check this bit when we check for errors.

    we also noticed through the debugger a glitch in flash contents while erasing, it makes the contents 0 for a while but then it comes back to old content.
  • Hello Praveen,

    The Erase code shall erase the flash only when there is a new application image being received by the Boot Loader.

    Regards
    Amit
  • Yes, we have a new application to load.
  • Hello Praveen

    Which Interface are you using for Boot Loader? Can you please check the System Clock Frequency, Crystal Source, Baud/Peripheral Clock rate.

    Also did you step debug does the FLASH control register update correctly for setting the FMA and FMC?

    Regards
    Amit
  • Can you please specify what do you mean by interface to the bootloader?

    Currently we are using the following settings.
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);

    We also tried for 40 Mhz.

  • Hello Praveen

    By interface I mean if it is UART, USB, I2C, SSI, CAN? Also to ensure we do not add another post, what is the Hardware (PC, USB2UART dongle, Advark Converter, etc) that you are using to talk via the interface to the TM4C123 device?

    Regards
    Amit
  • Amit,

    Our custom bootloaders job is to copy the appilcation from an external flash device using SPI into the internal flash and then execute the application. Before we copy the image into the internal flash, we do an erase of the internal flash starting from the location of the application(0x2800).(This is where we are facing the above problem.) The custom bootloader is never erased. The application image to be loaded is already present in the external flash.

    While the our application is running, it does a software reset using ROM_SysCtlReset() to execute our bootloader at flash location 0x0000. The bootloader then should work as specified above. We have done the fixes specified in the errata.

    But, it works as needed if we load the bootloader using CCS for the first time. We are using TI XDS100v2 USB emulator for debugging.
    While debugging we did verify that FMA and FMC did update correctly.
  • Hello Praveen

    Thanks for clarifying the same. Now it is clear as to how the boot loader and application are interacting. Since I do not have an exact setup, I would request for data

    As you mentioned INVDRIS bit gets set some times and when it does the erase is successful. Now this bit is set a location that is 0 is being requested to be programmed 1. This means that there is some code that executes that does a Flash write or commit operation by writing a bit to 1.
    Also you noticed that the locations become 0 and then come back to the original values. Is the power supply stable and current sufficient to perform an erase operation in your system.
    Lastly since, you are able to step debug the code (as you confirmed that FMA and FMC are written correctly), I am having some doubts as a read of FMC will return only the lower 4 bits if the operation did not succeed. Which could be that the Key is not getting written. Can you perform a loop where every x amount of time you do a direct write to the register FMC as 0xA4420002 and also check that Flash protection registers are not set.


    Regards
    Amit