MSP430 information flash

The MSP430 controllers contain small amount of flash, called "information memory" (since it's meant to contain information, of course), that you can use at your will. Programming in C, I expected GCC to do the right thing and tried to use the simple code.


#define INFO __attribute__((section(".infob")))
int stuff INFO = 1;

int main() {
	...
	stuff = 5;
	...
}

Guess what: it doesn't work. It never writes to the flash in the main. Of course, the initialization is fine, since the flash is written during programming. And yes, I know, I can't expect GCC to do the work for me, since you have to first erase whole flash and then write it. The compiler would require a lot of RAM to store the unmodified bytes, and that's not something you want to do on small chips.

After this, I read the manual and started writing custom routine. There isn't exactly much documentation on how to do it in C, so here is how I did it (only for single segment and variable, but you can write the whole segment after erase).


#define INFO __attribute__((section(".infob")))
int stuff INFO = 1;

int main() {
 	FCTL2 = FWKEY+FSSEL_1+FN1; /* MCLK / 3 */
}
	...

void writestuff(int newstuff) {
	dint();
	/* Erase memory first */
	FCTL1 = FWKEY+ERASE;
	FCTL3 = FWKEY;
	stuff = 0;
	/* Done, switch to writing */
	FCTL1 = FWKEY+WRT;
	stuff = newstuff;
	FCTL1 = FWKEY;
	FCTL3 = FWKEY+LOCK;
	eint();
}

What is it? Well, the FCTL2 register holds timing data for the flash controller; here I set it to MCLK/3, which is fine for CPU running at 1MHz, as the clock has to be between 257 - 476 kHz (at least for the MSP430G2231, take a look at the datasheet of your cpu). The FCTL3 holds only the LOCK bit, which has to be 0 for erasing/writing, and FCTL1 the ERASE and WRT bit, which indicate whether we want to erase the segment, or write to it. Easy, isn't it?

Unfortunately, I misread the manual and in my first attempt decided, that the correct method to erase the chip is FCTL1 = FWKEY+WRT+ERASE. Yeah, don't do it. It doesn't work. Moreover, do you remember what the family User's Guide says?

"A flash word must not be written more than twice between erasures. Otherwise, damage can occur."

And so it happend my flash stopped working, even after I fixed the program. Fortunately, not all the flash stopped working (but I managed to destroy all three segments before realising this), only the first 8 bytes, so I offsetted the variables further to avoid the damaged area.

And how does the damaged area look like? Luckily, it reads all 0, so you can easily check for it using the 'verify' command in the mspdebug, by declaring nonzero variable into the segment.