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.

TMS320F28075: Issue reading from Flash

Part Number: TMS320F28075
Other Parts Discussed in Thread: CONTROLSUITE

Hi Team,

Posting for a colleague.

What I’m trying to do:

I am trying to write a small block of data to an unused FLASH memory sector.  Evenually, I will use the TI EEPROM emulation functions, but for starters I have been trying to write a small number of bytes to the FLASH using the API and then read it back in a simple function with directly addresses the memory in flash.  FYI- I am writing 8 bytes to flash, in an attempt to keep the data boundary correct.

 

What is the problem:

When I do a flash read (after a flash write), the processor encounters an unconfigured interrupt.  I’ve assumed that it was the “correctable error fault” but it does not seem to be this fault.  When I try to trap the interrupt and figure out where it came from, I don’t see any flags that point to where the interrupt came from.

 

My assumptions:

I’ve been assuming that I’m getting an ECC error, but I can’t prove it.  My flash writing code is adapted from an example that I got from controlSuite, so I assume that it is writing correctly.  But then again, I am not too savvy with flash writing, so I really don’t even know what questions to ask when it comes to what is going wrong.  I noticed there is a mention of FLASH errors in the silicon errata for this device (document SPRZ423D), but the errata specifically states that this only occurs if the error is caused by a program fetch operation, not a data read.  I am reading data, so I assume this is not applicable.  Also FYI, I am using TMS rev C silicon.

Using customer hardware with CCS Version: 6.1.1.00022. Adapted a software example. Code below:

Have: F021_API_F2837xD_FPU32.lib file in my project, and I have F021_F2837xD_C28.h #included in Fapi_UserDefinedFunctions.c.

void eeprom_write(void)
{

    uint32 u32Index = 0;
    uint16 i = 0;

    Fapi_StatusType            oReturnCheck;
    volatile Fapi_FlashStatusType       oFlashStatus;
    Fapi_FlashStatusWordType   oFlashStatusWord;

    // Disable ECC.  ECC does not have to be disabled to do FSM operations like
    // program and erase.
    // However, on Sonata Rev. 0 silicon, due to an OTP ECC errata,
    // disable ECC to avoid ECC errors while using Flash API functions that
    // read TI-OTP

    INT_DISABLE;
/*
    EALLOW;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    EDIS;
*/
    EALLOW;

    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed

       oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 120);

    if(oReturnCheck != Fapi_Status_Success)
    {
        // Check Flash API documentation for possible errors
        Example_Error(oReturnCheck);
    }

    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
        // Check Flash API documentation for possible errors
        Example_Error(oReturnCheck);
    }



    // Erase Sector B
    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
                   (uint32 *)Bzero_SectorB_start);

    // Wait until FSM is done with erase sector operation
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    // Verify that SectorB is erased.  The Erase step itself does a verify as
    // it goes.  This verify is a 2nd verification that can be done.
    oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_SectorB_start,
                   Bzero_16KSector_u32length,
                   &oFlashStatusWord);

    if(oReturnCheck != Fapi_Status_Success)
    {
        // Check Flash API documentation for possible errors
        // If Erase command fails, use Fapi_getFsmStatus() function
        // to get the FMSTAT register contents
        // to see if any of the EV bit, ESUSP bit, CSTAT bit or VOLTSTAT
        // bit is set (Refer to API documentation for more details)
        Example_Error(oReturnCheck);
    }




    // A data buffer of max 8 words can be supplied to the program function.
    // Each word is programmed until the whole buffer is programmed or a
    // problem is found. However to program a buffer that has more than 8
    // words, program function can be called in a loop to program 8 words for
    // each loop iteration until the whole buffer is programmed


/*
    // Example:  Program 0xFF bytes in Flash Sector B with out ECC
    // Disable ECC so that error is not generated when reading Flash contents
    // without ECC
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
*/

    for(i=0; i<=WORDS_IN_FLASH_BUFFER; i++)
    {
        Buffer[i] = i;
    }

    for(i=0, u32Index = Bzero_SectorB_start;
       (u32Index < (Bzero_SectorB_start + WORDS_IN_FLASH_BUFFER))
       && (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
        oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,
                       read_flash_buffer+i,
                       8,
                       0,
                       0,
                       Fapi_AutoEccGeneration);
        while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

        if(oReturnCheck != Fapi_Status_Success)
        {
            // Check Flash API documentation for possible errors
            Example_Error(oReturnCheck);
        }

        // Read FMSTAT register contents to know the status of FSM
        // after program command for any debug
        oFlashStatus = Fapi_getFsmStatus();

        // Verify the values programmed.  The Program step itself does a verify
        // as it goes.  This verify is a 2nd verification that can be done.
        oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
                       4,
                       Buffer32+(i/2),
                       &oFlashStatusWord);
        if(oReturnCheck != Fapi_Status_Success)
        {
            // Check Flash API documentation for possible errors
            Example_Error(oReturnCheck);
        }
    }

    EDIS;

    INT_ENABLE;

}


void Example_Error(Fapi_StatusType status)
{
    //  Error code will be in the status parameter
//        __asm("    ESTOP0");
}


void flash_read(void)
{
       Uint16 i;
       extern Uint16 eeprom_data_load_start;

       for (i=0; i < WORDS_IN_FLASH_BUFFER; i++)
       {
              *(read_flash_buffer + i) = *(&eeprom_data_load_start + i);
       }

       flash_pack_struct_from_buffer();         // take values from flash and pack into the eeprom_data_buffer struct

}      // end of function flash_read()



This snippet is from the .cmd file which calls out the location of the eeprom_data in the FLASH.

   eeprom_data                    : LOAD = FLASHB,
                                           LOAD_START(_eeprom_data_load_start),
                                           LOAD_END(_eeprom_data_load_end),
                                           PAGE = 0, ALIGN(4)

Thank you for the assistance,

Nate

  • Hi Nate (and Brett),

    Thanks for posting my problem here.  I would like to add a bit more information as to the conditions of the failure, and my thoughts on the matter.

    I am writing a small test pattern to FLASH using the functions attached above (eeprom_write()).  It seems like the data is being written into flash correctly, although I do notice an occasional bit flip when I'm looking at the flash memory using the memory browser.  When I try to read the data out of flash, I encounter a problem.  The CPU enters an unsupported interrupt.  I've been having some trouble identifying what interrupt is triggering.  We have a "default ISR" vectored-to for each of the interrupts that we don't use.  The PIE enables are turned off for everything so I can't figure why the default ISR is getting called, unless there is a non maskable interrupt, such as the uncorrectable flash error.  I could use some help figuring out where this interrupt is coming from.

    Assuming that the CPU is getting interrupted on a flash ECC error, my next question is why errors are getting written into the flash in the first place.  But I guess we can talk about that after I figure out how the interrupt is getting triggered.

    Thanks,

    Justin

  • Hi Justin,

    Please check the value in register NMISHDFLG (0x7066) via CCS memory watch window (or Register view) after error happens to see if there is NMI (non maskable interrupt) happening.

    Vivek Singh
  • Justin,

    I see that you are using AutoEccGeneration mode to program. This should program ECC correctly as long as you provide the address and data with the correct alignments. In your code, I see you do a verify using Fapi_doVerify(). Did that pass or fail? If you have ECC check enabled (for read path) before calling Fapi_doVerify() and if that passed without giving an ECC error interrupt, it means that ECC is programmed correctly.

    1) What is the Flash waitstate value configuration that you are using before you do CPU reads to Flash?
    2) Did you check FlashEccRegs in the registers view and notice any error address captured in below registers?
    SINGLE_ERR_ADDR_LOW
    SINGLE_ERR_ADDR_HIGH
    UNC_ERR_ADDR_LOW
    UNC_ERR_ADDR_HIGH
    3) Do you have watchdog enabled? Are you servicing it?

    Regarding Flash bits flipping in memory window:
    1) Incorrect Flash waitstate value can cause this. OR
    2) Flash should not be accessed when Flash program or erase operation is in progress. May be you are watching Flash in memory window when program or erase are in progress. Try closing the memory window when flash operation is in progress.

    Thanks and regards,
    Vamsi
  • Hi Vamsi,

    How do I check the waitstate of the flash? What should it be?

    It doesn't appear that the error address registers show anything besides zero. But I am trying it again under different conditions and I will get back to you shortly.

    -Justin
  • Justin,

    Check FRDCNTL register in FlashCtrlRegs for RWAIT field. It should be configured as 2 at 120MHz.

    Thanks and regards,
    Vamsi
  • Vamsi,

    I tried it again and this time I get evidence of an NMI. I get the addresses of sector B in the single error and UNC error registers, and I get a FLUNCERR bit in the NMISHDFLG register.

    I checked the waitstate and RWAIT field equals 2. Is there a chance that the flash is configured at the wrong frequency? I was running into something similar where I adapted a piece of code for a serial port, and the configuration was at the wrong freq and the baud rate was messed up. I'm not sure which register to check for the flash, if there even is such a configuration...

    -Justin
  • Vamsi,

    I've verified that the code which reads the flash generates an NMI, but the code that writes to the flash also generates an unexpected interrupt (but not an NMI that I can tell). It does this even when the ECC_ENABLE bit(s) is zero. I reverted back to a slightly older version of code to do this test, and the functions are copied below. The eeprom_write() function is much closer to the original example code. Note that the ECC_ENABLE is left as zero, and this still causes an interrupt. If you can help me figure out which interrupt is triggering, that would be great!

    -Justin



    void eeprom_write(void)
    {

    uint32 u32Index = 0;
    uint16 i = 0;

    Fapi_StatusType oReturnCheck;
    volatile Fapi_FlashStatusType oFlashStatus;
    Fapi_FlashStatusWordType oFlashStatusWord;

    // Disable ECC. ECC does not have to be disabled to do FSM operations like
    // program and erase.
    // However, on Sonata Rev. 0 silicon, due to an OTP ECC errata,
    // disable ECC to avoid ECC errors while using Flash API functions that
    // read TI-OTP

    INT_DISABLE;

    EALLOW;
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;
    EDIS;

    EALLOW;

    // This function is required to initialize the Flash API based on System
    // frequency before any other Flash API operation can be performed

    oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 120);//for now keeping it out

    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    Example_Error(oReturnCheck);
    }

    // Fapi_setActiveFlashBank function sets the Flash bank and FMC for further
    // Flash operations to be performed on the bank
    oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    Example_Error(oReturnCheck);
    }



    // Erase Sector B
    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
    (uint32 *)Bzero_SectorB_start);

    // Wait until FSM is done with erase sector operation
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    // Verify that SectorB is erased. The Erase step itself does a verify as
    // it goes. This verify is a 2nd verification that can be done.
    oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_SectorB_start,
    Bzero_16KSector_u32length,
    &oFlashStatusWord);

    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    // If Erase command fails, use Fapi_getFsmStatus() function
    // to get the FMSTAT register contents
    // to see if any of the EV bit, ESUSP bit, CSTAT bit or VOLTSTAT
    // bit is set (Refer to API documentation for more details)
    Example_Error(oReturnCheck);
    }




    // A data buffer of max 8 words can be supplied to the program function.
    // Each word is programmed until the whole buffer is programmed or a
    // problem is found. However to program a buffer that has more than 8
    // words, program function can be called in a loop to program 8 words for
    // each loop iteration until the whole buffer is programmed



    // Example: Program 0xFF bytes in Flash Sector B with out ECC
    // Disable ECC so that error is not generated when reading Flash contents
    // without ECC
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;

    for(i=0; i<=WORDS_IN_FLASH_BUFFER; i++)
    {
    Buffer[i] = i;
    }

    for(i=0, u32Index = Bzero_SectorB_start;
    (u32Index < (Bzero_SectorB_start + WORDS_IN_FLASH_BUFFER))
    && (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
    oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,
    Buffer+i,
    8,
    0,
    0,
    Fapi_DataOnly);
    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    Example_Error(oReturnCheck);
    }

    // Read FMSTAT register contents to know the status of FSM
    // after program command for any debug
    oFlashStatus = Fapi_getFsmStatus();

    // Verify the values programmed. The Program step itself does a verify
    // as it goes. This verify is a 2nd verification that can be done.
    oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
    4,
    Buffer32+(i/2),
    &oFlashStatusWord);
    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    Example_Error(oReturnCheck);
    }
    }


    EDIS;

    INT_ENABLE;

    }
  • Justin,

    1) Read issue:  Ok, you gave two different codes up to now.  Your latest code uses Fapi_DataOnly mode for program operation.  This mode does not program ECC.  It programs only the data.  That is why you are getting ECC errors when reading with ECC enabled.  With this, can we close your read issue?  

    2) Coming to your new issue [You are getting an interrupt when you are programming and it is not an ECC error related interrupt since ECC is disabled.  Also, you confirmed that it is not an NMI]:  

    A) If you want to know the source of the interrupt easily, you can initialize the entire PIE vector table to point to the default ISR routines as shown below (taken from controlsuite examples).

    //
    // Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
    DINT;

    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2807x_PieCtrl.c file.
    //
    InitPieCtrl();

    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example. This is useful for debug purposes.
    // The shell ISR routines are found in F2807x_DefaultIsr.c.
    // This function is found in F2807x_PieVect.c.
    //
    InitPieVectTable();

    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    B) Are you running the Flash API functions from Flash or RAM?  They should be executed from RAM only.  Flash can not be accessed when a program or erase operation is in progress.  Hence, Flash API for F2807x should be executed only from RAM as mentioned in the TRM.  If Flash API is loaded in RAM and set to execute from RAM (by assigning it to .TI.ramfunc), check whether you copied it to RAM or not using memcopy().  Make sure you allocate the functions in Fapi_UserDefinedFunctions.c file as well to .TI.ramfunc as shown in controlsuite examples.  Check if you are getting an ITRAP (ILLEGAL_ISR).      

    C) API does not enable any interrupts.  Also note that API does not configure (enable/disable) watchdog.  Did you check if you have any other interrupts enabled?  Check PIECTRL, PIEIERx, PIEIFRx registers.

    D) You did not answer my previous question regarding watchdog.  Is it enabled or disabled?  If enabled, is your application servicing it?

    3) Regarding your question related to Flash clock:  As long as,

    (i) you configure the PLL correctly to get the SYSCLK that your application needs and

    (ii) configure the wait-states correctly and

    (iii) pass that frequency value to Fapi_initializeAPI() correctly,

    the Flash clock will be configured correctly by the API.  

    Thanks and regars,

    Vamsi

  • Vamsi,

    I didn't realize the older version of code only programmed the data, and not ECC.  Let me change that to also program the ECC and I will get back you about how it runs.  I will also answer the rest of your questions with my next reply.

    Thank you,

    Justin

  • Vamsi,

    First, I checked to make certain that the FLASH APIs are being called from RAM, and I attached a snippet of the .map file below, showing that eeprom_write() is in amongst the other functions that are specified to be in 'ramfuncs'.

    GLOBAL SYMBOLS: SORTED BY Symbol Address

    page  address   name                                  

    ----  -------   ----                                  

    0     00000124  _bootloader_ram_functions_load_end    

    0     00000124  _bootloader_ram_functions_load_start  

    0     00000124  _bootloader_ram_functions_run_start  

    0     00000ce0  _Cla1SoftIntRegs                      

    0     00008000  _inv_loop                            

    0     00008000  _ram_functions_run_start              

    0     000082ab  _pfc_loop                            

    0     000084b8  _eeprom_write                        

    0     00008527  _eeprom_update_page_status            

    0     00008528  _eeprom_update_bank_status            

    0     00008529  _eeprom_get_valid_page                

    0     0000852a  _eeprom_erase                        

    0     0000852b  _isr_pfc                              

    0     00008565  _isr_inv                              

    Second, I verified that the FLASH reads do not cause a problem when the FLASH has not yet been written to (all FFFF).  When I write to FLASH using auto ECC generation, I still get an unexpected interrupt.  Putting in all of the ISR shells like you recommend, it goes into ILLEGAL_ISR.  Do you have any thoughts on why this is happening?

    Third, as far as the watchdog goes, yes it is enabled, and yes it is serviced.  I've got a function watchdog_reset() which is called from the task scheduler of the OS, so it runs frequently.  I suppose there is a chance that the OS hangs when the FLASH API is being called, and I haven't figured out how long it all takes.  Code for the watchdog_reset is below:

    void watchdog_reset(void)
    {
    EALLOW;

    // Reset watch dog counter
    WdRegs.WDKEY.all = 0x0055;
    WdRegs.WDKEY.all = 0x00AA;

    // Reset the external watchdog

    GpioDataRegs.GPBSET.bit.GPIO62 = 1;
    asm(" RPT #50 || NOP");
    GpioDataRegs.GPBCLEAR.bit.GPIO62 = 1;

    EDIS;


    }

    -Justin

  • Justin,

    ILLEGAL_ISR (ITRAP) does not occur due to reads and it occurs when the CPU fetches an illegal opcode. Make sure that your application is not erasing the Flash memory from which it is trying to execute. Check your linker command file to know the Flash memory ranges that your application is using and make sure you are not erasing them.

    Make sure to do a memcopy to copy the sections that are loaded to flash and mapped to RAM for run.

    Also, make sure that the stack is not overflowing in to some other RAM block overwriting code or data.

    Step through your code and figure out which part of the code is causing illeagal ISR and debug from there.

    Did you go through the Flash programming example and understand how it works?

    Thanks and regards,
    Vamsi
  • Hi Vamsi,

    I checked the linker command file and I believe that I am erasing sector B, and that sector is unused by the program for instructions.  Should I try using a sector of FLASH that is far away from the rest of the program?  As it is right now, program instructions are stored in sectors A & C.

    How do I "make sure that the stack is not overflowing in to some other RAM block overwriting code or data"?

    Do I need to make sure the data that I'm writing is in "page 1" vs "page 0"?

    -Justin

  • Vamsi,

    I noticed a different behavior yesterday and I wanted to tell you about it.  The example_error() function has been left blank (this is the function called when the FLASH API fails, and it is left over from the example project that I used).  In my troubleshooting yesterday, I wanted to determine if the FLASH API was failing.  So I put in a statement to increment a counter in example_error().  The statement is flash_write_error++.  Now, instead of getting illegal_isr, I get the following error (pictured below).  What do you think?

    -Justin

  • Justin,

    Above is not an error.  It is just saying that source code is not found for the API function.  That is because TI provides a API library (which you linked to your project) and not the API source.  This is not an issue.  Keep a break point post the API function call and you would not get in to this.

    Thanks and regards,

    Vamsi

  • Vamsi,

    Ok, but why does the program stop at that point if there was not an error? Before, the CPU would stop in the illegal_isr(), now it stops right where you see it in the above picture. If it is not an error, why would it stop there?

    Also, my questions from yesterday:

    I checked the linker command file and I believe that I am erasing sector B, and that sector is unused by the program for instructions. Should I try using a sector of FLASH that is far away from the rest of the program? As it is right now, program instructions are stored in sectors A & C.

    How do I "make sure that the stack is not overflowing in to some other RAM block overwriting code or data"?

    Do I need to make sure the data that I'm writing is in "page 1" vs "page 0"?

    -Justin
  • Justin,

    1) From the snapshot above, I see that the Flash API functions are executing from Flash address (they should be executed from RAM as I mentioned earlier). Can you share your linker command file and map file?

    2) Regarding your question on using another sector: As long as you are not using sector B, you should be able to erase it. However, for this debug purpose, you can try another sector and see if the issues goes off. May be there is something that is allocated there and you did notice it? Check your linker command file and map file.

    3) Regarding stack: Try increasing stack size and see if that helps. You can fill in the stack space with a constant before executing the program and then check how much of stack space is used after the execution of the program (when you get the issue). This will tell whether stack overflowed or not.

    4) Page question: Yes, you can make it page 1.

    Thanks and regards,
    Vamsi
  • Vamsi,

    I used example code from controlSuite v150.  Now I am looking at the latest version of the example that I have (v210).  I still do not see any place where the FLASH API library is specified to be copied to ramfuncs with a #pragma statement.  From the beginning, I have copied my functions that call FLASH APIs to ram, but I don't know how to specify that the APIs themselves reside in RAM.  Could you please tell me how to do this?

    -Justin

  • Justin,

    Please check the linker command file used in the example.  You will notice that .TI.ramfunc section and API library are grouped together to load to Flash and run from RAM.  See below snippet taken from linker command file.

           GROUP

           {

               .TI.ramfunc

               { -l F021_API_F2837xD_FPU32.lib}

           } LOAD = FLASHD,

             RUN  = RAMLS03,

             LOAD_START(_RamfuncsLoadStart),

             LOAD_SIZE(_RamfuncsLoadSize),

             LOAD_END(_RamfuncsLoadEnd),

             RUN_START(_RamfuncsRunStart),

             RUN_SIZE(_RamfuncsRunSize),

             RUN_END(_RamfuncsRunEnd),

             PAGE = 0    

    Thanks and regards,

    Vamsi

  • Vamsi,

    Ok, I made changes to the .cmd file and put the flash APIs in ramfuncs too. I had only put my functions that call the APIs into RAM. Now the APIs are in there too. This didn't solve my problem though. I solved the illegal_isr() problem by doubling the size of the stack. It was 0x400 long, and I made it 0x800 long. Now I don't get the illegal_isr() anymore, but when I try to read FLASH, I'm still getting weird errors (explained below).

    First, I still had the ECC enabled, and I was getting NMIs. Then I disabled the ECC, and the NMIs go away, but I am still getting strange behavior. I have my flash_read() function called periodically, and it just reads the first 16 memory addresses starting at 0x82000. See below snippet. This runs continuously. After I make the program write to flash once or twice, the flash becomes unstable. What I mean by this is: when I refresh the memory browser (pointing to 0x82000), the memory values go from a sequential test pattern (0x00 thru 0xFF) to completely random 16 bit numbers, and everytime I refresh the memory broswer, random bits across the memory map toggle. Everytime I refresh, about 10% of the numbers shown in the watch window have one HEX character change as if one bit is toggling (for example, a C becomes a 4, or an E becomes an F). If I keep refreshing the memory browser, I keep getting lots of values changing. Does this sound like something that you recognize as a common problem? I verified that this toggling of bits happens even when I disable the flash reads completely. The program is running but flash is not being written-to or read-from (as far as I can tell).


    void flash_read(void)
    {
    Uint16 i;
    // extern Uint16 eeprom_data_load_start;

    for (i=0; i<16; i++)
    {
    *(read_flash_buffer + i) = *((Uint16 *)(0x82000) + i);
    }

    } // end of function flash_read()


    Thanks,
    Justin
  • Justin,

    Did verify pass after program with ECC enabled or not?

    I strongly suggest you to first execute the Flash API example with ECC enabled and see whether verify passes or not. I will continue supporting you once you do this step.

    Thanks and regards,
    Vamsi

  • Hi Vamsi,

    I've been trying so many things that I missed your request about checking whether the program passed the verify stage. Sorry about that.

    My short answer to your question is: I don't know. The reason that I don't know is because I do not trust that the debugger sets breakpoints correctly, and I have trace variables in the code that do not seem to be behaving normally. Allow me to explain:

    When I try to set a breakpoint in the eeprom_write() function, the IDE comes back with the error (in red letters in the console) "C28xx_CPU1: Trouble Setting Breakpoint with the Action "Remain Halted" at 0x8c43: Error 0x00000008/ -1066 Error during: Break Point, Cannot set/verify breakpoint at 0x00008C43" Then right below that, I get in the console (in black letters) "C28xx_CPU1: Breakpoint Manager: Retrying with a AET breakpoint"

    When I run the program, and set a flag to cause the function to run, the program doesn't stop at the breakpoint if I put it inside the IF statement that is supposed to catch the verify stage failing. There are also other places inside the eeprom_write() function that the breakpoint will not halt the processor. But there are some places in the eeprom_write() function where a breakpoint will stop the program, such as at this statement:

    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)Bzero_SectorB_start);

    However, I also have two trace variables in the code, and they do not seem to update at all, and have weird behavior. Allow me to explain:

    At the beginning of the eeprom_write() function, I increment a trace variable flash_write_called. This is to let me know that the function was called. I also increment a trace variable in the example_error() function, called flash_write_error. I global Uint16 variables for both. When I look at these variables on the watch window, they show zero. They don't increment when I call the eeprom_write() function. When I manually change these variables in the watch window, and refresh the watch window, the values that I wrote in remain there unchanged. When I trigger the eeprom_write() function, the trace variables go back to zero! Why would this be?

    Also, in the watch window, looking at the variable "buffer" which is used to program the actual data into the FLASH using the API, when I watch that variable in the watch window, it almost always shows zero, even after I have evidence that the eeprom_write() function has run successfully. There is no code that clears this array, so once it is written-to in eeprom_write(), it should retain those values. But for the most part, the array reads all zeroes in the watch window.

    Because of the fact that I'm having trouble setting a breakpoint that sucessfully halts the processor, and that I'm getting strange behavior with trace variables makes my answer to your question uncertain. I'm trying to debug it, but I don't trust the answer that my tools are giving me. If you can shed light on what is happening here, I would greatly appreciate it.

    Thanks,
    Justin


    void eeprom_write(Uint16 addition)
    {

    uint32 u32Index = 0;
    uint16 i = 0;

    Fapi_StatusType oReturnCheck;
    volatile Fapi_FlashStatusType oFlashStatus;
    Fapi_FlashStatusWordType oFlashStatusWord;

    flash_write_called++;

    // Disable ECC. ECC does not have to be disabled to do FSM operations like
    // program and erase.
    // However, on Sonata Rev. 0 silicon, due to an OTP ECC errata,
    // disable ECC to avoid ECC errors while using Flash API functions that
    // read TI-OTP

    INT_DISABLE;
    DRTM;

    EALLOW;


    // Erase Sector B
    oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,
    (uint32 *)Bzero_SectorB_start);

    // Wait until FSM is done with erase sector operation
    while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
    // Verify that SectorB is erased. The Erase step itself does a verify as
    // it goes. This verify is a 2nd verification that can be done.
    oReturnCheck = Fapi_doBlankCheck((uint32 *)Bzero_SectorB_start,
    Bzero_16KSector_u32length,
    &oFlashStatusWord);

    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    // If Erase command fails, use Fapi_getFsmStatus() function
    // to get the FMSTAT register contents
    // to see if any of the EV bit, ESUSP bit, CSTAT bit or VOLTSTAT
    // bit is set (Refer to API documentation for more details)
    Example_Error(oReturnCheck);
    }




    // A data buffer of max 8 words can be supplied to the program function.
    // Each word is programmed until the whole buffer is programmed or a
    // problem is found. However to program a buffer that has more than 8
    // words, program function can be called in a loop to program 8 words for
    // each loop iteration until the whole buffer is programmed



    // Example: Program 0xFF bytes in Flash Sector B with out ECC
    // Disable ECC so that error is not generated when reading Flash contents
    // without ECC
    // Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0x0;

    for(i=0; i<=WORDS_IN_FLASH_BUFFER; i++)
    {
    Buffer[i] = addition;
    }

    for(i=0, u32Index = Bzero_SectorB_start;
    (u32Index < (Bzero_SectorB_start + WORDS_IN_FLASH_BUFFER))
    && (oReturnCheck == Fapi_Status_Success); i+= 8, u32Index+= 8)
    {
    oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,
    Buffer+i,
    8,
    0,
    0,
    Fapi_AutoEccGeneration);
    while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);

    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    Example_Error(oReturnCheck);
    }

    // Read FMSTAT register contents to know the status of FSM
    // after program command for any debug
    oFlashStatus = Fapi_getFsmStatus();

    // Verify the values programmed. The Program step itself does a verify
    // as it goes. This verify is a 2nd verification that can be done.
    oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
    4,
    Buffer32+(i/2),
    &oFlashStatusWord);
    if(oReturnCheck != Fapi_Status_Success)
    {
    // Check Flash API documentation for possible errors
    Example_Error(oReturnCheck);
    }
    }


    // Enable ECC
    Flash0EccRegs.ECC_ENABLE.bit.ENABLE = 0xA;

    EDIS;

    INT_ENABLE;
    ERTM;

    }
  • Justin,

    I understand. But, please pay attention to our questions and answer them so that we can help you debug in the best possible way.

    I remember I had breakpoint issue in CCSv6.
    Did you check for updates and install all of them? I will ask a CCS expert to take a look at this post.

    For now, instead of breakpoints and watch window, can you depend on the return value that you get from the verify function? You have an if loop to check whether the return value from verify is success or not. Tell me whether that if loop is entering in to the Example_error() function or not. I want you to do verify using ECC enabled. Also, for now, disable optimization if you have it enabled in the build options.

    Thanks and regards,
    Vamsi
  • Justin,

    Two more questions:

    1) How are the boot mode pins configured? Are they configured for Boot to Flash? If yes, can you change it to something else and try?

    2) Do you have any passwords programmed?

    Thanks and regards,
    Vamsi
  • Vamsi,

    Allow me to back up a bit here. A lot of the problems that I was experiencing in my previous post might be caused by the watchdog not being serviced correctly. That is why the trace variables were getting reinitialized and I assume that is why breakpoints were misbehaving. I have corrected the watchdog problem, and now the trace variables are incrementing and I have a much better idea to the answer to your previous question about whether the VERIFY stage is failing. The answer is YES, IT IS FAILING THE VERIFY OPERATION. ECC is enabled during this test.

    Another weird thing that I see here is that when I run the eeprom_write() function, the trace variable that I have at the top of the function "flash_write_called" increments 18 times as does the trace variable that I have counting the number of times that the verify stage fails. Why would the entire function run 18 times? I only call it once.

    I will check for CCS updates.

    -Justin

  • Vamsi,

    I forgot to answer these two questions that you asked in a separate message:

    1) Boot mode is configured as "boot to flash" (TRST = 0, IO72 = 1, IO84 = 1). This is hardwired on PCB and cannot be changed.
    2) No passwords are programmed.

    -Justin
  • Vamsi Gudivada said:
    I remember I had breakpoint issue in CCSv6.

    Vasmi - I believe the issue you are thinking of is related to ramfunc with the problem occurring if the program has a section that is loaded to flash and extracted to RAM at run-time and a (software) breakpoint is set in that area of RAM. Is that what is happening here?

  • Ki-Soo,

    Yes, I am having trouble getting a breakpoint to reliably work in a function that is loaded to flash and extracted to RAM. Is there a fix for this? Or will I be unable to set breakpoints in these functions?

    Thanks,
    Justin
  • Justin - can you explain how/when you are setting this breakpoint and when the error occurs? Where is the program halted when you try to set the breakpoint?

    If you can explain the exact sequence of your debug environment, that would be helpful.

    For example:
    1) Press "Debug" button to launch debugger and load the program
    2) Debug will be halted at "main"
    3) Set SW breakpoint at line 235 of file.c
    4) Error occurs
    ...
  • Justin,

    1) Good to know that you fixed your watchdog. I asked you to check on the watchdog service 12 days back.

    2) Since verify is failing, can you check the value of FMSTAT register after the program operation? You can use Fapi_getFsmStatus() function for this. Details of FMSTAT register are provided in the description of this function in section 3.2.1 Fapi_getFsmStatus() at www.ti.com/.../spnu595.pdf.

    3) Regarding why your function is getting executed 18 times: Did you initialize that variable to zero? You might have to debug your application by cutting it down and adding piece by piece.

    Note that there is an errata regarding Flash single bit ECC error with below advisory title. Check it out and configure the threshold value to a non zero value.
    Advisory Flash: A Single-Bit ECC Error May Cause Endless Calls to Single-Bit-Error ISR.

    If you have your threshold set to 0 and if there is a single bit error, you may get in to endless loop.

    4) If you have boot mode set to Flash, upon powerup, CPU will fetch from Flash and executes it. Hence make sure you have some valid code in Flash so that CPU will not execute some garbage taking device in to an unknown state before connecting the emulator.

    Thanks and regards,
    Vamsi
  • Justin,

    Also, I suggested to execute the TI provided Flash programming example and see if that works. That helps you to know if you have any setup issues/board issues etc.

    For example, few F28075 QFP users forgot to solder the PowerPAD on the bottom of the package to the ground plane of the PCB. Debug for this issue started like a Flash API debug and later I figured that the user did not solder the powerpad to the ground plane.

    In another case, 1.2V powersupply line dipped low during the Flash program operation causing a failure. Once they fixed the supply, everything worked fine. You might want to check these kind of things as well.

    Thanks and regards,
    Vamsi
  • Hi Vamsi,

    I tore apart a spare board that I have and the processor is soldered down to the powerpad.

    I have not run the actual example project on its own, but I've copy/pasted the code into my program and it runs on startup.  This works, and it has worked for a while.  It is when I try to run the flash programming routine (example project encapsulated into my eeprom_write() function) again later in my program that is causes trouble.

    I have not checked the power supply rails.  Do you think I should?

    -Justin

  • Vamsi,

    One thing I just noticed is that when I insert the watchdog servicing code into the API's watchdog function, the example project code no longer programs flash (all 0xFFFF) and I get evidence of a "verify failed". When I remove the watchdog servicing code, I get the test pattern in FLASH and no evidence of a "verify failed".

    It may not have been clear up to this point, but I have the eeprom_write() function call in two places in my code. First, I call it right out of the init stage and it gets called every time the program starts up. Then, later in the program, in the main loop, I call the eeprom_write() function upon receipt of a flag that I change from the watch window in the debugger. For some strange reason, the issue that I was seeing where the CPU was resetting when the watchdog servicing code was not included in Fapi_serviceWatchdogTimer() only happened when the eeprom_write() function was called later in the program. I never see the watchdog reset the CPU when eeprom_write() is called right after initialization (even when the watchdog servicing code is not included). Of course, at that point, interrupts have not been enabled yet. (I do shut off interrupts when I call the eeprom_write() later in the program though).

    Does anything I just mentioned make sense to you, or shed more light on my problem?

    -Justin
  • Justin,

    1) Regarding the watchdog:  Make sure to include an EALLOW at the end of the watchdog service function body to allow the later API functions to write to protected registers as required.

    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
    /* User to add their own watchdog servicing code here */

    ServiceDog(); //Your own function body

    EALLOW; // Add this EALLOW

    return(Fapi_Status_Success);
    }

    2) Regarding watchdog reset:  The frequency at which the API calls this watchdog service routine may not be enough to service the watchdog. Hence you may want to increase the time period for the watchdog to expire.  However, since Flash API is interruptible on this device, I would suggest you to enable the interrupts and service the watchdog based on a timer interrupt.  This way you are certain that the watchdog is serviced at the correct pace.  Note that the ISRs should be copied to RAM since there should not be a Flash access when an erase or program operation is in progress.

    Thanks and regards,

    Vamsi 

  • Justin,

    Is your application now able to successfully program and verify without any issue?

    Thanks and regards,
    Vamsi
  • Hi Vamsi,

    Yes, it is now working.  There were multiple problems from the beginning.  They were:

    * The functions were being called from a function that was called by an ISR.  This apparently was causing trouble (even though this is the way it works in the previous version of this firmware running on the 28069.  I believe this was causing the stack overflows.

    * First, watchdog was not being serviced (blank user defined watchdog servicing function".

    * Then, I needed an EALLOW statement at the end of the "user defined watchdog servicing function".

    * API Library was not specified to run from RAM in the CMD file.

    * Interrupts had not been disabled early on in the debugging.

    * ECC was not being calculated correctly at one point early in the debugging.

    Since I have solved these problems, and I can write to flash reliably, I have been implementing the TI EEPROM emulation functions.  These are not directly compatible with the 28075 since you cannot seem to rewrite a flash word that has already been written.  For instance, the bank status word starts out as 0xFFFF when "blank", 0xA00A when "currently in use", and 0x0000 when "full".  The problem that I have found is that I cannot rewrite the 0xA00A to become a 0x0000 (I assume because the ECC byte would need to change, and in general it won't only change bits from 1 to zero).  So I've had to modify the operation of those functions to deal with only "empty" and "used" status.  The same goes for the "page status".  Also, not being able to write a single flash word means that I need to take up an entire 8-word row in flash for what used to be a single status word.  So it also uses more memory than the same implementation in the 28069.  But I've got it working.

    Thanks for your help. 

    -Justin

  • Justin,

    Good to know that our conversation helped the debug and that your application is now up and running.

    I am closing this thread.

    Thanks and regards,
    Vamsi