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.

Unable to Erase Flash in only one Sector

Other Parts Discussed in Thread: TMS570LS1115, HALCOGEN

I am trying to develop a boot loader for the TMS570LS1115.

I can erase and program successfully all sectors of Flash memory (sectors 1-13) with the exception of Erasing Sector 10 @ 0x00080000.

I am running all of the Flash Functions from RAM.

Sector 10 is blank, ie contains no code or tables.

I have disabled the Memory Protection Unit (MPU).

I am calling the functions from Privilege mode.

I have disabled Interrupts.

I am filling unused FLASH areas with the fill directive for ECC  fill=0xFFFFFFFF

see .cmd file below

/*----------------------------------------------------------------------------*/
/* Linker Settings */

--retain="*(.intvecs)"

/*----------------------------------------------------------------------------*/

MEMORY
{
VECTORS       (RX) : origin=0x00000000 length=0x00000020 fill=0xFFFFFFFF // sect0 32 bytes length

FLASH_UNUSED0 (RX) : origin=0x00000020 length=0x00003FE0 fill=0xFFFFFFFF // sect0

FLASH_BOOT0   (RX) : origin=0x00004000 length=0x0000C000 fill=0xFFFFFFFF // sect1,2,3 16k,16k,16k length = 0xC000

FLASH_BOOT1   (RX) : origin=0x00010000 length=0x0000C000 fill=0xFFFFFFFF // sect4,5,6 16K,16K,32K

FLASH_UNUSED1 (RX) : origin=0x0001C000 length=0x00004000 fill=0xFFFFFFFF 

FLASH0        (RX) : origin=0x00040000 length=0x00060000 fill=0xFFFFFFFF 

FLASH1        (RX) : origin=0x000A0000 length=0x00060000 fill=0xFFFFFFFF

STACK         (RW) : origin=0x08000000 length=0x00001500 

RAM           (RW) : origin=0x08001500 length=0x0001CB00

RAM2          (RW) : origin=0x0801e000 length=0x00002000 

}

/*----------------------------------------------------------------------------*/
/* Section Configuration */
SECTIONS
{
.intvecs : {} > VECTORS

flashAPI :

{

Flash.obj (.text)

Fapi_UserDefinedFunctions.obj (.text)

--library= F021_API_CortexR4_BE_V3D16.lib < FlashStateMachine.IssueFsmCommand.obj
                                            FlashStateMachine.SetActiveBank.obj
                                            FlashStateMachine.InitializeFlashBanks.obj
                                            FlashStateMachine.EnableMainSectors.obj
                                            FlashStateMachine.IssueFsmCommand.obj
                                            FlashStateMachine.ScaleFclk.obj
                                            Init.obj
                                            Utilities.CalculateEcc.obj
                                            Utilities.WaitDelay.obj
                                            Utilities.CalculateFletcher.obj
                                            Read.MarginByByte.obj
                                            Read.Common.obj
                                            Read.FlushPipeline.obj
                                            Read.WdService.obj
                                            Async.WithAddress.obj
                                            Program.obj > (.text)

} load = FLASH_BOOT0, run = RAM2, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)

.text : {} > FLASH0
.const : {} > FLASH0
.cinit : {} > FLASH0
.pinit : {} > FLASH0
.bss : {} > RAM
.data : {} > RAM
.sysmem : {} > RAM

FEE_TEXT_SECTION : {} > FLASH_BOOT0
FEE_CONST_SECTION : {} > FLASH_BOOT0
FEE_DATA_SECTION : {} > RAM
}

The Erase Function is getting stuck on the following code,

status = Fapi_enableMainBankSectors(0xFFFE);    /* used for API 2.01*/

My erase function is below,

void Erase_Sector( uint32_t eraseStartAddr)

{

      uint32_t Freq_In_MHz;

      uint32_t status;

      uint8_t bk = 0; 

      Freq_In_MHz = SYS_CLK_FREQ; 

      status = Fapi_initializeFlashBanks(Freq_In_MHz);                              /* used for API Rev2.01 */ 

      status = Fapi_setActiveFlashBank((Fapi_FlashBankType)bk); 

      status = Fapi_enableMainBankSectors(0xFFFE);                            /* used for API 2.01*/ 

      while( FAPI_CHECK_FSM_READY_BUSY != Fapi_Status_FsmReady ); 

      status = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, eraseStartAddr); 

      while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy ); 

      while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);

}

What am I doing wrong? This function works for every other sector with the exception of sector 10.  

Any help much appreciated,  been stuck on this for way to long.

Regards

Robert

  • Rob,


    Thanks for all the details.  Just one question ...

    Rob Price said:

    The Erase Function is getting stuck on the following code,

    status = Fapi_enableMainBankSectors(0xFFFE);    /* used for API 2.01*/

    What do you mean by stuck - do you mean that the function Fapi_enableMainBankSectors() does not return (so the CPU is stuck within this function?) or does it cause an exception of some kind?

  • Anthony,

    Sorry for the delay in response, I have finally made “some” progress.  Here are my findings so far,

    1. I noticed that some of the Fapi_xxx functions from the “F021_API_CortexR4_BE_V3D16.lib” where assembled into Flash areas outside my boot loader area/RAM execution area.  

                 So, I modified the .cmd linker file to ensure all of the functions in the library are loaded into the boot space area using the .map file output to verify. 

                  I added the following functions to flashAPI directive which were not present in various posts and the demo app.

    FlashStateMachine.EnableEepromSectors.obj

    Utilities.GetNumberOfSectors.obj

    BlankCheck.ByByte.obj

    BlankCheck.obj

    Read.LoopDword.obj

    FlashStateMachine.Hercules.IsEccAddress.obj

    Async.WithAddress.obj                                               

    Async.obj                                                             

    Read.LoopByByte.obj 

                           This fixed a lot of my problems. 

    1. I now call my boot loader functions from “User Mode” rather than “privileged mode”.  Calling Erase functions in “privileged mode “ causes the Erase process to fail. 

    What is confusing is that in the F021 Flash API Reference Guide (SPNU501G.pdf) , in section 2.1 it states that the routines must be in a privileged mode to allow access to the Flash memory controller registers.

    As part of our SIL certification process this conflict in documentation is going to cause us problems.

     Originally I started with the TI Boot loader demo project.  I might have missed something but I don’t see any attempt to run the API functions in privileged mode in the demo application. 

     Some feedback on this would be much appreciated. 

    1. Found a faulty micro that was failing to Erase giving me erratic behavior
    2. Turned of EEC checking for RAM and FLASH while performing FLASH operations

                 _coreDisableFlashEcc_();

                 _coreDisableRamEcc_();

    1. Utilized the FILL directive in the .cmd linker file to allow access to flash without generating an ECC issue. eg 

                        FLASH0        (RX) : origin=0x00040000 length=0x00060000 fill=0xFFFFFFFF 

    I am now at the point that I can erase, program and copy sections of FLASH in my application just after a POR and before I run my main application and enable interrupts.  

    However, when I try calling the boot loader functions from my Main application loop, ensuring interrupts and watchdog are disabled, I am now getting an error and branching to sys_intvects.asm. 

    prefetchEntry

            b   prefetchEntry

      I am using XDS200 debugger and CCS.   This behavior occurs in both User and privileged modes. 

     Do you have any suggestions on how to fix this problem ?

     Also, It is not clear when and how I should use the flush_Pipeline() function.  It is not referenced in the TI demo boot loader application and doesn’t appear to have any effect when I use it?

              Fapi_flushPipeline()     Flushes the pipeline buffers in the Flash memory controller

     Could you please shed some light on the when/if I should be using this function?

    regards

    Robert

  • Hi Robert,

    Wow!   Sounds like you did make quite a lot of progress and may have found an issue or two that we need to make sure get corrected.

    Which bootloader example did you start from?   I want to check to see if we need to change the linker command file in that appnote.

    Rob Price said:
    I now call my boot loader functions from “User Mode” rather than “privileged mode”.  Calling Erase functions in “privileged mode “ causes the Erase process to fail. 

    My instinct on this is that likely it's an issue with the mode change rather than user/priv.   So maybe the stack size of the privileged mode you are in isn't large enough for the operation being executed.    Otherwise almost as a rule there shouldn't be anything on the device that is accessible from user but not privileged mode.  This I think has to be debugged at a pretty low level say by stepping or by analyzing the machine state after the crash and trying to backtrack..

    Rob Price said:

    However, when I try calling the boot loader functions from my Main application loop, ensuring interrupts and watchdog are disabled, I am now getting an error and branching to sys_intvects.asm. 

    prefetchEntry

            b   prefetchEntry

    Are you using the MPU and do the MPU settings that you have configured after boot permit executing code from the bootloader sector? 
    Not having this configured correctly would be the most likely reason for a prefetch abort.


    There are some abort status registers in CP15 that will give you the exact cause of this abort and the address of the instruction that generated it.

    You'd want to know what is in the "Instruction Fault Address (IFAR)" register, the "Instruction Fault Status Register (IFSR)" and it would be nice
     even to know what is in the "Auxiliary Instruction Fault Status Register" (AIFSR).

    When you have the address from IFAR, it would be good to understand what that instruction was and what code it is from.

    I don't see the debugger (XDS200) being involved in any of this really.



    The Fapi_flushPipeline() function looks like it is part of the cleanup process after finishing programming and before returning to execute from flash.
    Which makes sense, because the pipeline is like a very tiny 'cache' and when you change the memory behind this pipeline you should flush it.

    I would assume it belongs in the flowcharts for erase and program between "Done" and jumping back to flash.  

    I'll need to ask why it's not shown there.

  • Hi Anthony,

    Another day of debugging and now understand the issue at hand.

    Isolated problem down to the RTI interrupt which is configured for FIQ rather than IRQ interrupt.

    Tried to move RTI interrupt to IRQ in HALCoGen but when recompile in CCS after change many compile errors are generated.  HALCoGen doesnt seem to like RTI configure for IRQ.  We are using RTI timer for systems ticks timer and it is critical it has the highest priority so it is not desirable to have it on IRQ anyway but would of been a good step in debugging to be able to turn of all interrupts for the boot loader code.  

    My understanding is that once the FIQ is enabled it cannot be disabled, had no sucess in disabling this interrupt which has been proven to be the root cause of the boot loader crashing.

    Isolated problem down to this line of code 

    rtiEnableNotification(rtiNOTIFICATION_COMPARE0);

    Also realized i was calling some .asm functions like

    _coreDisableFlashEcc_();
    _coreDisableRamEcc_();
    _disable_interrupt_();
    _disable_FIQ_interrupt_();

    that where outside the boot loader flash space and ram, so when erase was completed, call to these functions caused a crash.  This problem has been corrected.

    Incidentally calling the disable_FIQ_interrupt_() function has no effect on the FIQ flag.

    My problem now is how do i stop the FIQ occurring when i need to run boot loader functions?  I guess i could halt the timer counter but cant afford to upset system timer ticks.  This is a problem as i want to be able to download new firmware in the background while the system is running and program 1K segments into a backup code flash area, once all the code is downloaded and verified a copy of the new firmware can be written over the code space area.

    Also the mystery of privilege mode and user mode has been resolved.  As it turns out i have been running in privilege mode all the time. Assumed that HALCoGen init code would of defaulted into User mode after init.  

    How do i get into User mode ? i think i have seen some assembler code around to achieve this but i cant find the reference...#8?

    Any comments on how to solve these issues ?

    regards

    Robert

  • Hi Robert,

    In cmd file, you can use (.text) following the library name to copy all the obj to the RAM.

    flashAPI :
    {
    Fapi_UserDefinedFunctions.obj (.text)
    bl_flash.obj (.text)

    --library = F021_API_CortexR4_BE_V3D16.lib (.text)
    } load = FLASH_API, run = SRAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)

     

    QJ

  • Hi QJ,

    I am already loading boot code, library and wrapper into RAM and have listed the code at the beginning of the post to do this.  I have also traced in assembler my code to ensure that it is actually executing from RAM.

    Robert

  • Robert,

    The FIQ is non-maskable so you cannot disable it. Safety feature.

    ADDING:  the RTI works fine on the IRQ level.  must be a problem in the configuration somewhere.

    Would need to know more about the error you are getting though to provide guidance on how to fix.

    You really have no choice though I think other than to move RTI to IRQ.

    If RTI is your highest priority and that's why you put it at the FIQ level - you *can* adjust the priority order of the interrupts

    within the IRQ level .. without elevating to FIQ.