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.

Problem - Write Information Memory - Segment C - MSP430F2232

Other Parts Discussed in Thread: MSP430F2232

Hello,

I'm using :

- MSP430F2232,

- Code Composer Studio v 6.1.1.00022

I want to save a variable in Segment C of information memory (location : 0x1040).

My problem is the value read at @1040 is always 0x00.

Does anyone have any idea of my error?

Below some of my code :


#pragma location=0x1040
unsigned char test_flash;

char cpt;


void WriteDataFlash()
{
 WDTCTL = WDTPW + WDTHOLD;    // Stop watchdog timer

 FCTL2 = FWKEY + FSSEL0 + FN1;   // MCLK/3 for Flash Timing Generator
 while(FCTL3 & BUSY) {}                     // Wait busy

 FCTL3 = FWKEY;                               // Clear Lock bit
 FCTL1 = FWKEY + ERASE;               // Set Erase bit
 while(FCTL3 & BUSY) {}                     // Wait busy

 test_flash = 55;                                    // Dummy write to erase Flash seg
 while(FCTL3 & BUSY) {}                     // Wait busy

 FCTL1 = FWKEY + WRT;                   // Set WRT bit for write operation
 while(FCTL3 & BUSY) {}                     // Wait busy

 if(cpt & 0x7F) cpt = 0;
 else  cpt++;
 test_flash = cpt;                                   // Write value to flash
 while(FCTL3 & BUSY) {}                     // Wait busy

 FCTL1 = FWKEY;                               // Clear WRT bit
 FCTL3 = FWKEY + LOCK;                 // Set LOCK bit
 while(FCTL3 & BUSY) {}                     // Wait busy

 WDTCTL = 0x5A08;                            // re enable watchdog timer
}

  • You did not do a "dummy write" to erase the segment. You did not do a write to Flash either. What is your "location" for?

    Edit: my mistake, please ignore

  • My location is for save a parameter (operational time) I must reload in case of energy failure
  • My mistake. Please ignore my previous replay.

    Who (or what) calls your WriteDataFlash()? is there a "main()"?

    Who else (or what else) has access to "cpt"? What was done to "cpt" before WriteDataFlash() is called?
  • WriteDataFlash() is called in main() function.
    Cpt is initialized to '12' before WriteDataFlash() is called.

    I find a lot of documentation which associate "#pragma location" directive with a "constant"
    #pragma location 0x____
    const unsigned char _____

    Is it possible to associate "#pragma location" directive with a variable ?
    #pragma location 0x____
    unsigned char _____
  • Laurent FUZIER said:
    Cpt is initialized to '12' before WriteDataFlash() is called.

    And inside WriteDataFlash() you have:

    if(cpt & 0x7F) cpt = 0;
    else cpt++;
    test_flash = cpt;

    Hence that Flash location is written with a 0.

  • Sorry for the mistake. It's due to a lot of try.

    But it's not the problem.

    For example, I've tried with :
    if(cpt & 0x40) cpt = 0;
    else cpt++;
    test_flash = cpt;

    For example, I've tried with :
    if(cpt >= 34) cpt = 34;
    else cpt++;
    test_flash = cpt;

    In both cases, the value read is 0x00.


    After compilation and upload program to µC, the value at @1040 is already 0x00.
    Execution of program doesn't change any value...

    Is it possible to associate "#pragma location" directive with a variable ?
    #pragma location 0x____
    unsigned char _____
  • I do not even know standard c well. And "#pragma location" is not standard c.

    If you show me the resulting object code, I may be able to tell you what it does.

    Also, I do not know your overall scheme. How is this going to work for you when power is restored after it way cutoff?

    I think even after you fix your current problem and managed to erase that segment and write one byte. It is not going to be useful to you when power is restored. Because at that moment, your code will erase that segment and write one byte too and your previously written byte is gone.
  • Pragma location (works both in CCS and IAR) is so you can place a function at specific location.
    but when used for a var it can not be shuffled in to a init-block so use: __no_init unsigned char test_flash;

    Other way around the problem:
    In the end the flashwrite/read function probably end up using a pointer for indirect addressing if there is more than 1 var or array/struct etc,
    so you can set this pointer to the absolute address of 0x1040

    // declare a pointer of the char type to point to (casted) infoc location, remove const if address could change at runtime
    char *const mybackup = (char *) 0x1040;
    char myvar = 0;

    main(void){
    if (*mybackup != 0xff) myvar = *mybackup;


    If just a single char, maybe keep tacking it on the end so you only have to erase the block every 64th time.
    If the value could be oxff, include a header 0x5a, and you can still do 32 times before erasing block

    Make sure the programmer erase info too (but not infoa) when you program the firmware.

  • I changed my code according to Tony's advice and It works well.

    Than you for your help.

**Attention** This is a public forum