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.

MSP430F5438 save/retrieve to/from flash on power loss

Other Parts Discussed in Thread: MSP430F5438

We have a device that rides on delivery trucks and measures dispensed product. Our software is developed on the IAR Workbench (full) for the TI MSP430F5438 (non-a)

Chip.  The power to our device is usually turned off between deliveries.  I use the on-board TI Supply voltage monitor to create an interrupt when we are losing power.  The interrupt calls a function ShutdownSaveTotals() that saves 10 parameters to a flash memory INFO segment and sets a flag in that segment.  As a wear leveling algorithm, I save the data in INFO C one time and INFO D next time.  To handle the case where power is restored during the shutdown function, I then delay and force a reset by:  WDTCTL = 0x5A24;

 

On startup, I check INFO C and INFO D to see if the flags are set.  If the flag is set, I copy the data to RAM variables and set variable nextSaveSegment to alternate between using INFO C and INFO D as a wear-leveling strategy.  I then print the recovered data to HyperTerminal using a serial port for diagnostic purposes.  Then I erase the INFO segment where the recover data was found and if the flag in the other INFO segment does not == 0xff (erased byte, unsigned char).  This ensures that the flash segments are ready for writing on the next power loss. 

 

I have done some timing checks using DIO and a scope.  It takes 28 ms to erase an INFO segment, 5 microseconds to load RAM from flash, and 1.5 ms to write RAM values to INFO segment

 

This setup has worked extremely well for several years in many different countries, but one or two of our customers are reporting lost or corrupted data.  We can find no hardware problems with their setup.  The only way we have been able to simulate their problems is to rig up a signal generator so that we are able to effect (beginning with the device running and valid data showing)  a off/on/off/on sequence on the power input.  As long as the sequence is off/on, everything works fine but the double dip mentioned above will cause data loss or corruption at certain frequencies of the sequence.  We believe this occurs because we lose power during a flash erase operation.  The frequency band of failure is quite small.  For instance, at 1.18 hz all is well, failure at 1.9 hz, and again at 1.20 hz all is well.  .  We have tried to use a larger capacitor to guarantee we will not lose power until we have erased but there is a limit to the capacitance allowed and we are almost at maximum already.

 

We developed an algorithm that (we think) ensures that valid shutdown data will be left in one INFO segment and the other is always erased, ready for the next shutdown.  For example, if, on startup, I find data in C, I load C to RAM, Erase D, Save RAM to D, then erase C. 

 

We believe this should work, but it seems that if we lose power while erasing C, it not only corrupts C, but also D.  Thus when power is restored, both C & D are invalid and default values are used in RAM rather than the lost data.  We tried a 20 ms delay between saving RAM to D and erasing C, but no improvement, just moved problem to another frequency.  On one instance, we noticed that losing power while erasing INFO C also caused the checksum protecting parameters in INFO A to fail, and another checksum protecting calibration data located in INFO B also failed.  Once we caused a checksum to fail for CODE memory (Banks 0 –  3). 

 

We are looking for insight and/or suggestions for diagnosing or avoiding these problems.

If anyone knows a better way to accomplish these goals, I would appreciate hearing from you. 

 Mike Raines

mraines@hofferflow.com

 

 

 

  • I would pre-erase flash area during stable power. Meaning that you MUST guarantee stable supply during flash erase. Cutting power of low power uC is fatal design flaw.

  • I suggest that you use the following convention to store parameters in INFO-C/D. The 64-byte sector is used to store up to 60 bytes of parameters, a 2-byte CRC, and a 2-byte Status.

    Status = 0x7E5A means the rest of this segment has been erased and verified to be correctly erased.

    Status = 0x3C42 means the parameters and CRC has been written and verified to be correctly written,

    Status = 0x0000 means the parameters and CRC are invalided.

    Status = anything else should not happen and means there is something wrong with this segment.

     

    (1) Initially, the factory programs the INFO sectors as follows:

    1a. INFO-C has Status = 0x3C42, the default initial parameters and its CRC.

    1b. INFO-D has Status = 0x7E5A and the rest of the sector erased.

     

    (2) At BOR, we expect that either INFO-C or INFO-D has Status = 0x3C42 and correct CRT. If this is so, then we copy the parameters from this INFO segment to SRAM.

     

    (3) After that, we check the Status of the other INFO segment to see if it is 0x7E5A. If this is so, then we start normal operation of this device. If it is not so, we proceed to erase it before we start normal operation of this device. To erase, follow these:

    3a. Check the power supply voltage and wait until it is high enough to sustain the erasure process.

    3b. Erase that sector.

    3c. Verify that the entire sector is indeed erased.

    3d. Write 0x5E7A to Status.

    3e. If any of the above steps fails, we force a BOR.

     

    (4) During normal operation of the device, we use SVM high-side to detect power going down and generate an interrupt as early as possible.

     

    (5) This SVM ISR should immediately shutdown peripherals, slowdown clocks, and lower CORE voltage to conserve power.

     

    (6) It may then start the following:

    6a. Check Status of INFO-C and INFO-D. One of them should have Status = 0x7E5A and the other should have Status = 0x3C42.

    6b. Copy the parameters and CRC from SRAM to the INFO segment with Status 0x7E5A.

    6c. Verify that is done correctly.

    6d. Change the Status of this INFO sector to 0x3C42.

    6e. Change the Status of the other INFO sector to 0x0000.

    6f. Delay for a while and then force a BOR.

     

    I think this scheme is very similar to what you have. But the details should make it more robust.  

  • OCY, your procedure is almost the exact setup I use for our own projects.

    Yes, it is fatal if power fails while an erase in in process. Erasre requires much power and a power fail may result in unrelated segemnts of the same bank being accidentally erased too. As already noticed.

    So the key is to erase (prepare) a sector when power is stable. and just 'invalidate' the old data when the new one is written correctly.

    Using the SVM to shutdown any peripherals and slow down CPU is an additional bonus.

    An alternative to this approach is to write data when it changes, not when power fails. This maybe result in more flash write cycles (not necessarily if there is only one data change per power cycle anyway), but depending on applicaiton it may take decades until 100k writes have been done.

    Another approach is to self-power-down the device. This can be done by a transistor that is bridged by the external event that powers the device up, but then the MSP controls the transistor to power itself. And when a power-down event is detected, the MSP will finish up its work and then switch off the transistor.

**Attention** This is a public forum