# eeprom data corruption during power failure

I recently found a problem with eeprom of a PIC16F877A which is used to control the speed of a dc motor. The drive is supposed to work on the last set speed even if the power fails. But the problem is sometimes (not always) after the power failure the set speed (which is read from eeprom) is not same as the last set speed. Usually whenever this problem happens the value is changed to default eeprom value 255 ,( but not always, some random values also). what might be the possible causes?.

• Power dropping too low before the write finishes. – Ignacio Vazquez-Abrams Mar 10 '14 at 5:04
• Does your controller have brown out detection? That can help prevent this situation. – jippie Mar 10 '14 at 6:04
• @IgnacioVazquez-Abrams have thought about the power dropping. But there is a voltage stabilizer which cuts off the supply if the mains drop below 170v. Also I would like to know how to make the system independent of the spikes in the mains ,as the highest supply voltage in the system is only 12v. – raforanz Mar 10 '14 at 6:21
• @jippie It has BOD and Its already enabled. – raforanz Mar 10 '14 at 6:22
• You don't want to cut off the supply, you want to perform an orderly shutdown. Including not writing to EEPROM after a certain point. – Ignacio Vazquez-Abrams Mar 10 '14 at 6:24

Let's assume you have some sort of a linear regulator that feeds your PIC. That regulator probably has lots of headroom (say it has 12V input and 3.3V output). The regulator will work fine in spite of the input being only 8V, for example.

You need to choose this cut-off point and feed it to a comparator that produces a logic signal called Power Good (PG). This signal will go off long before the regulator fails to regulate and the BOD kicks in.

Whenever PG is absent, you shouldn't be doing any EEPROM writes.

You should also store the setpoint with some check value. A simple scheme is use the 1s complement of speed. For example, for 0x88 speed, the 1s complement is 0x77. In C:

typedef struct {
uint8_t speed;
uint8_t speed_complement;
} SetpointSlot;


If a setpoint slot has invalid check value, you simply ignore it.

You should be storing an even multiple SetpointSlots - at least two. If your EEPROM is paged, the slots must not cross pages, and they must be spread across two pages (or more pages if they don't all fit on two pages). With 2 setpoints, you'll have each on its own page, for example.

When starting up:

1. Iterate the slots. Use the first valid one you encounter (where speed == ~speed_complement).
2. If no valid slots are found, use the defualt value.

When storing a new value, you would do the following:

1. Recall the currently used setpoint slot.
2. Erase the next setpoint slot (next in a round-robin fashion, alternating pages).
3. Write the new setpoint there.
4. Verify the written values. If they're wrong, zero them out to ensure they'll stay wrong, select the next setpoint slot and go to 1.
5. Zero-out (not erase) the current setpoint slot - but only if it's not the same slot as where the new value got stored. That could be the case if you had two slots and one of them was in a "bad" area of eeprom.