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.

Retaining data in flash during power off condition

Other Parts Discussed in Thread: MSP430G2553, MSP430FR6922

Hi Every one,

i want to retain data after power loss,and i have almost gone lot of threads in the forum, but i didn't achieve what i need!
 So i have decided to post it agian pl kindly let me know what is the fault.

Here was my plan to know the variable data is stored during power loss or not

in main's while loop using a switch performing write operation,next read that variable if the value read matches with the known value led is ON if not OFF.

Now if i press the switch with the launch pad connected to the programming pins of the controller ,the read value is matching and led is ON,and if i remove the programming pins form the launch pad it is OFF.

i have developed this code with the help of  TI sample example code of flash in MSP430G2553 and from forum posts

#include <msp430g2553.h>
int x;
int  value;
int state;
int *Flash_ptr1;
//int *Flash_ptr2;
// Function prototypes
void write_SegC (int value);
int Flash_Read(void);

void main(void)
{
WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
DCOCTL = 0;                               // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;

P2DIR |= BIT1;
P2OUT &= ~BIT1;
P2DIR |= BIT4;
P2OUT &= ~BIT4;

P2DIR &= ~BIT0;
P2SEL &= ~BIT0;
P2SEL2 &= ~BIT0;
P2REN |= BIT0;

while(1)
{
        if((P2IN&0x01)==0)
        {
         P2OUT |= BIT4;
         write_SegC(1);
         __no_operation();                       // SET BREAKPOINT HERE
        }
        else
        {P2OUT &= ~BIT4;}

        x=Flash_Read();
        if(x==1)
        P2OUT |= BIT1;
        else
        P2OUT &= ~BIT1;

}
}

void write_SegC (int value)
{
FCTL2 = FWKEY + FSSEL0 + FN1;
FCTL3 = FWKEY;
FCTL1 = FWKEY + ERASE;
Flash_ptr1=(int *) 0x1000;
*Flash_ptr1 = 0;
FCTL1 = FWKEY + WRT;
*Flash_ptr1 = value;
FCTL1 = FWKEY;
FCTL3 = FWKEY + LOCK;
}


int Flash_Read(void)
{
//Flash_ptr2=(int *) 0x1040;
//Flash_ptr2=Flash_ptr1;
state = *Flash_ptr1;
return state;
}

Write function is writing that particular value to 0x1000 location i have checked in memory browser in run mode.and even it is reading properly but that read value is lost when the power is off.or my entire program and understanding is faulty , which am unable to find it out.

Thank you in advance

  • At a global look your program looks ok, also you state that you can see and read the correct values.

    Only the number of times you can write or erase FLASH-memory in total is limited, I don’t know how much 1,000, 10,000 times? But certainly not the amount you probably already did in your contiguous looping while.

    Change your program to write it only one time and use another (healthy) segment or a new MCU.

  • Thank you for the response

    though it is in while loop write function executes only one time that is when a switch is pressed.

    i have changed the address to new segment 0X1090,still it is same when power off  and on the led remains in off state.

    should i go for new MCU?

    Thank you

  • shruthi chary said:
    write function executes only one time that is when a switch is pressed

    But it repeats as long the switch is pushed and without any delay this goes fast. You should write only on a switch change, but without a switch debouncing way this can also generate 10-~100 switch pulses.

    I don’t know what happens when FLASH has expired, I guess when you can read a value other then 0xFF FLASH will be ok.

    Be sure CCS is not erasing Info Memory -> Properties\Debug\MSP430 Properties.

    I don’t know how did you check the FLASH-byte after boot, but you should on CCS connect run to main (and Stop) or place a break point before the while(1) loop and read the FLASH contents.

  • I have checked MSP430 Properties ,it is erase main memory only

    and i have checked the contents of the memory  with break point on  the _no_operation() function pl check attached

    i  suspect now my flash is expired ,i will check once again and i will replace the MCU and this time i will execute write only one time.

  • Now you are checking after the write, you must do it before!

    But I think I see the problem; You assign the FLASH address to your Flash_ptr1 variable only when writing after that reading will be ok. But you must assign the address also before reading the byte.

  • i think that was the problem,because after assigning address in read function led is ON even after power off condition,so MCU flash is safe i presume.and also my checking was also wrong i need to check it before the write whether the data is still in the specified location am i right ?

    thank you very much

  • It looks like you are lucky and there are still some erase/write cycles left.

    But you must make your program a bit more intelligent; Erase ones and write whole FLASH while storing a pointer till segment is full and then erase, will save FLASH life time.

  • Assuming the value to be stored is never 0xffff, you can go this way:

    Map an array of data over the segment
    Look from top down for first element with 0xFFFF, write to it

    When reading, look from bottom up to first non-0xFFFF.

    So you don’t need to save  apointer. Assuming your data is a16 bit value, you can do 64 writes on one 128 byte segment before oyu need an erase cycle.
    Hint: use two segments, so you can first write o th enext segment before you erase the old one (I tmakes the lookup algorithm a bit more complex but prevents you from the need to do a lengthy and energy consuming erase before saving)

  • see my program it will retain the data after turned off(MSP430FR6922)
    #include <msp430.h>

    void FRAMWrite(void);

    unsigned char count = 0;
    //unsigned long *FRAM_write_ptr;
    unsigned char data;
    unsigned char *FRAM_write_ptr;
    //#define FRAM_TEST_START 0xD000
    #pragma PERSISTENT (X)
    unsigned char X=5;

    int main(void)
    {
    //unsigned char data;


    WDTCTL = WDTPW | WDTHOLD; // Stop WDT

    // Configure GPIO
    P1OUT &= ~BIT0; // Clear P1.0 output latch for a defined power-on state
    P1DIR |= BIT0; // Set P1.0 to output direction
    P9OUT &= ~BIT7; // Clear P1.0 output latch for a defined power-on state
    P9DIR |= BIT7;
    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;
    FRAM_write_ptr =& X;
    // Initialize dummy data
    data = 0xab;
    if(*( FRAM_write_ptr+251)==0xab)
    {
    P9OUT|=BIT7;
    }

    while(1)
    {


    data = 0xab;
    FRAM_write_ptr =& X;
    FRAMWrite(); // Endless loop
    count++;
    if (count > 100)
    {
    P1OUT ^= BIT0; // Toggle LED to show 512K bytes
    count = 0; // ..have been written
    data = 0x01;
    }
    }
    }

    void FRAMWrite(void)
    {
    unsigned int i=0;

    for ( i= 0; i<252; i++)
    {
    *FRAM_write_ptr++ = data;
    }

    }
  • Thanks for posting your code.
    However, FRAM write is instantaneous and does not need an erase cycle.
    In fact, each FRAM read access is a (re)write operation too.

    The main problem discussed above is the FLASH requirement of erasing a whole segment before you can overwrite a flash cell with a new value. A problem you don't have with FRAM. So it doesn't really help much.

    But there's another problem with your code. you have defined X to be a persistent char. You take the address of X to write to. However, your reserved persistent data space is only one byte long (the size of X). But you write far beyond into the void. Where there might or might not be writable FRAM. So far, you're filling 252 bytes of memory that belongs to unknown variables or stack or whatever (except for the first byte that belongs to X) with the value of 0xab.

**Attention** This is a public forum