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.

TMS320F28069: Emulating EEPROM in FLASH while running from FLASH

Part Number: TMS320F28069
Other Parts Discussed in Thread: C2000WARE

Hello,

So I´ve been trying to implement the EEPROM emulation detailed in here, into a brake module using the F28069 microcontroller. In essence there are some user defined parameters I would like to save in the FLASH so that they don't have to be set after every on/off cycle. 

After some tinkering I managed to make the EEPROM emulation work, all the while adding my own functions to replace the EEPROM_Write() and EEPROM_Read() as they did not suit my needs exactly. The thing is the program works just fine in debugging mode, but whenever I load it onto the brake module and run it from flash it suddenly stops writing anything to the flash sector I defined for EEPROM emulation. I suspect that, since the program itself is running from flash, it is interfering with the flash API functions. Whats more, there are several interrupts ocurring from the ADC, CPU timers and the EPWM; so I am also concerned that those same interrupts are preventing the flash from programming.

Is there any way I could halt all interrupts and/or flash operation for a short time while the flash API programs the data into the flash sector? Does this sound like it has any fix, or should I focus on implementing an actual EEPROM into my design?

Thanks a bunch for any help you could offer.

Cheers,

Michael

  • Michael,
    I would import the flash_API example project for the F2806x located in C2000Ware here:

    C:\ti\c2000\C2000Ware_3_04_00_00\libraries\flash_api\f2806x\Example_Flash2806x_API

    It goes through the main care abouts before programming/erasing the flash/OTP arrays.

    To your direct questions, there is a global interrupt enable/disable in the C28x core registers.

    We've set up a alias in the Device.h that you can call from C as "DINT"  This executes the assembly instruction SETC INTM, which sets the INTM(Interrupt mask) bit.  This will supercede any of the PIE enables although you can disable/enable the PIE as well if you want to retain some interrupts not globally disable all of them.

    Also, you are correct that you cannot program/erase the flash/OTP, while executing from flash/OTP.  In the case of the F2806x we have already placed the Flash API in the ROM so that you don't need to use up RAM or copy flash to RAM for the API source.  The above example will use this mapping, so you can re-use in your code.

    Let me know if you have further questions.

    Best,

    Matthew

  • Matthew,

    Thanks for pointing me in the right direction. I had checked the example file in the flash api library before, but reading through it again has given me some notion of what might be going wrong. In particular, I think unlocking the CSM module could do the trick.

    On another note. Is there anyway of moving the entire project from the FLASH/OTP to SARAM at start up? Since the code is running from flash I'm not sure how it would be possible to write to flash during normal operation. I've tried moving all time critical functions to ramfuncs but it seems that doesn't help at all. I would like to write a function that both halts all interrupt services and any code running directly from flash before programming the flash. As you mentioned, halting interrupts is straightforward with the DINT and EINT macros, however it is unclear to me how or if it is possible to cease flash operation for a brief moment while programming the user variables to flash.

    Thanks again for the help.

    Kind regards,

    Michael

  • Michael,

    Inside the .cmd file you'll see a section marked as "ramfuncs" and directive like the below:

    ramfuncs            : LOAD = FLASHA, 
                             RUN = PRAML0, 
                             LOAD_START(_RamfuncsLoadStart),
                             LOAD_END(_RamfuncsLoadEnd),
                             RUN_START(_RamfuncsRunStart),
                             PAGE = 0

    This is a directive to tell the linker that the code will be loaded to flash, but to expect it to be ran from RAM.  That is the first of 2 parts needed to run from RAM.

    The second part takes place inside the main C file and with a function call to Example_MemCopy() function:

    Example_MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
    
    void Example_MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)
    {
        while(SourceAddr < SourceEndAddr)
        { 
           *DestAddr++ = *SourceAddr++;
        }
        return;
    }
    

    This passes the symbols we assigned to the ramfuncs at link time and copies the data currently in flash to RAM.  Once this is complete once we call the functions held in this region, the linker will have made the necessary offsets to call the RAM version of the code vs the flash version.  So long as we stay in that code that was allocated to ramfuncs in the linker, we will avoid executing from the flash while we program it.

    Best,

    Matthew

  • Matthew,

    Thanks!

    I managed to fix the issue. I was using memcpy() from string.h to copy ramfuncs into ram, which apparently doesn´t work. I used the Example_MemCopy() instead and that seemed to do the trick. I also got rid of the EEPROM.c and EEPROM.h files and replaced them with my own functions, variables and defs in the main program and its corresponding header. I did them at the same time so I´m not super sure if it was just the memcpy(), but I have a hunch that it was.