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 emulated EEPROM bank after invoking memoryInit

Other Parts Discussed in Thread: TMS570LS1227, HALCOGEN

Hi all,

We are having an issue with using the Flash API on the TMS570LS1227 MCU. While we have tried a number of approaches and Flash commands, the simplest thing that we cannot seem to get working is to erase bank 7, which on this chip is an emulated EEPROM bank.

Strangely, we are able to successfully erase bank 7 if we do not invoke memoryInit during startup, so this doesn’t appear to be a straightforward problem of misusing the API (memoryInit is a routine from HALCoGen that causes the RAM hardware to initialize itself). We also run the PBIST module on RAM before that, along with activating ECC for both RAM and Flash. But we are unable to determine what affect invoking memoryInit is having on the Flash controller, or on the memory space that might indirectly cause this problem. Otherwise it appears that everything else in our app is running perfectly. The Flash API functions report Fapi_Status_Success, but both EV and CSTAT bits of the FMSTAT register are set after attempting the bank erase (they should both be 0). We aren’t seeing any other indication of a problem (other than the data remains in the bank after issuing the Fapi_EraseBank command).

I greatly appreciate any assistance. Thanks in advance.

Regards,

David

  • HI David,

    It is odd to see the memoryInit to have any effect on the flash program/erase operation. They are two different things. The memoryInit() will initialize the RAM. It has nothing to do with the flash controller. The flash controller does not even know about it.

    The EV means it fails for erase verify. After erase, the flash controller will try to find out if the sectors contain any '0'. If any 0 is found then it will need to re-issue erase pulses. It sets the EV flag until the max number of erase pulses are issued.

    You are using Fapi_EraseBank. Can you try Fapi_EraseSector and see if it makes a difference.
  • Hi Charles,

    Thank you for taking the time. I agree, it is quite strange.  While the Flash controller is separate from RAM, the Flash API does use RAM for its stack, so there could be an interaction, but I looked into that and didn't see anything bizarre while stepping through the Flash API disassembly of Fapi_issueAsyncCommandWithAddress. Is there anything along those lines that I could look for?

    Thank you for giving the explanation of EV, that makes sense.

    I have attempted to use Fapi_EraseSector, and the outcome is the same.

    Thanks again,

    David

  • Hi David,
    You mentioned that you test the ECC for both the flash and RAM. Can you temporarily disable these ECC tests?

    I will also discuss with other folks to see if they can shed some light.
  • Charles,

    I disabled the Flash and RAM ECC tests (checkFlashECC and checkRAMECC routines) and attempted to erase the same bank, but unfortunately that didn't help. I also tried to erase it without have either ECC enabled at all, with the same result.

    Have you been able to have a discussion with anybody?

    Thanks,
    David
  • Hi David,

      Can you read out the value at 0xFFF8_7244? This is the length of the erase pulse. What is the value of this register if you enable the memoryInit() and if you disable the memoryInit() after the erase fail with the EV bit. If they are different then somehow memoryInit() has affected the pulse length. 

      Please also tell me when did you apply memoryInit() relative to when you start the bank erase.

      Lastly, are you using the FEE emulation driver on bank7?

  • Charles,

    There is a discrepancy when I watch that location. When the bank erases properly the value of that register is 0x0 before the erase command and 0x9C40 (40,000) after the erase is complete. But when it does not work properly the value is 0x0 before the erase and remains 0x0 after the command fails. Hopefully this will help us determine the root cause.

    The memoryInit routine is called as part of startup where HALCoGen places it. The bank erase runs after using a tool we've developed to transmit data to the hardware over SCI; we are attempting to manually load some data we generate into the emulated EEPROM bank. So the erase is attempted at some arbitrary time later.

    We are not using the FEE emulation driver.

    Thoughts?

    Thanks,

    David

  • Hi David,

      For the non-working one, the erase pulse is zero and this is the reason why the EV flag is set. You are giving an erase pulse of zero length to the flash bank and it never succeeded erasing and timeout after the max number of pulses are given.

      This is what I suspect. When you start the erase, the flash API needs to calculate the length of the pulse per your device frequency and store this value to the RAM for later use. What might have happened is that it tried to store the value while the memoryInit() is ongoing. The write is simply ignored. You should wait for the memoryInit() to complete before moving to the next step.  The memoryInit() can take up to 4096 cycles to complete. Let's do a quick experiment. Put a delay after the memoryInit() like for(i=0;i<=4096;i++); This should be way more than 4096 cycles. Let me know if it works. If it works, then we should instead poll the memory initialization flag in the SYS module instead of putting hard coded number.

  • Charles,

    Thank you for the suggestion, I will give that a try.

    Looking at the memoryInit routine, it does appear to be polling the memory initialization flag that is in the SYS module that you mention. The code looks like

    while((systemREG1->MSTCGSTAT & 0x00000100U) != 0x00000100U)

    Of course I may be misunderstanding, but would like to ask.

    I will look to see if I can spot the issue you describe. Even if the memoryInit routine is properly waiting for the hardware to complete, the same or similar problem could be manifesting in a slightly different way.

    Thank you so much for your help, we're probably getting pretty close to sorting it all out.

    -David

  • Charles,

    I have found and fixed the problem. Thank you very much for pointing me down a path to getting the bank 7 erase and write working. While the issue turned out to be different than what you hypothesized, your suggestions did help me to look in helpful places.

    In case anyone else comes across this problem I will leave a description and solution.

    What happened is that we made a mistake on our end with how we were calling __TI_auto_init. Our program has two modes, one is an operational mode that runs in RAM and the other is a support mode that runs in Flash. We should have called __TI_auto_init at startup (where HALCoGen puts it) but we were only calling it in RAM after loading our operational mode code; __TI_auto_init itself was made part of the RAM code. The solution is to have a single __TI_auto_init that runs correctly no matter which mode will be used, and in our code it is invoked where HALCoGen puts it (in sys_startup.c).

    Setting up our initialization that way resulted in a boolean value that the Flash API uses called bFirstRun being set to zero when it should have had a nonzero value. When we ran memoryInit, the value was zeroed, but when it we did not run it, it was 0xC3 because of the RAM pbist module. Since it is a boolean value, the exact value did not matter. bFirstRun is used in Fapi_setActiveFlashBank, which returned Fapi_Status_Success even though bank 7 was not actually activated; the routine probably had no good way of knowing that it actually had not previously executed.. Among other things, the erase pulse length was not set to the value it should have had and remained 0. Later when we called Fapi_issueAsycCommandWithAddress along with Fapi_EraseBank nothing was actually erased and the EV flag was set because the erase pulse length was 0.

    Another approach in the Flash API that I will point out is that bFirstRun could have been named something like bInitialized or bAlreadyRun, with the initial value being 0 and then being set to 1 after it runs successfully, rather than the other way around as it is now. It's typically better to initialize variables like that to 0 especially in an embedded context for precisely this reason. But, I emphasize this is a minor point and that the mistake was ours. Similar issues have bit me in the past in my own code and it's a more robust approach to assume that your non-local variables could start at 0. I also think it would be nice if the erase pulse length register was documented in the Technical Reference Manual of the MCU; nothing is listed at that address, 0xFFF8_7244.

    Again, thank you very much for your help.

    Kind regards,

    David

  • HiDave,
    Really glad that your problem is resolved.