Using flash memory in MSP430

This article is about using the flash memory in MSP430. This will not teach you C programming, using MSP430 or flash memory basics. They are well documented on the internet. This article will help all of us who are struggling to use the flash memory.

I started off a project on MSP430G2553(Now on, I will refer it as micro). Soon I realised that I needed to store a large amount of data. I needed to store 4096 bytes. However, there was only 256 bytes of EEPROM space but 16KB flash memory. Initially, I was reluctant to use the flash but had no other option. So I started off. The trouble is that flash memory is not easy to handle. But not that difficult either. Reading is straight forward. There will be a pointer to the flash space and you just need to reference that pointer. However, the trouble starts with writing data.

The flash is arranged as segments A, B, C, D and other segments. A, B, C, D are 64 byte segments and the others are 512 byte segments. A in particular is locked as it contains information about calibration. When you wish to write to a segment, you need to erase it first. Even if you want to store one single byte, you need to erase the whole segment.

Let us first look at the flash erase function


// __DINT() is in IAR workbench
void flash_erase(int *addr)
{
  _DINT();                             // Disable interrupts. This is important, otherwise,
                                       // a flash operation in progress while interrupt may
                                       // crash the system.
  while(BUSY & FCTL3);                 // Check if Flash being used
  FCTL2 = FWKEY + FSSEL_1 + FN3;       // Clk = SMCLK/4
  FCTL1 = FWKEY + ERASE;               // Set Erase bit
  FCTL3 = FWKEY;                       // Clear Lock bit
  *addr = 0;                           // Dummy write to erase Flash segment
  while(BUSY & FCTL3);                 // Check if Flash being used
  FCTL1 = FWKEY;                       // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                // Set LOCK bit
  _EINT();
}

Initially, the interrupts need to be disabled. After that, the flash must be configured in erase mode. The information about the registers can be obtained from the datasheet. FWKEY is the password for the flash memory and should be included for every action. After configuring the registers, a dummy write must be done to the given address. This will erase the whole segment. Once the erase is complete, the memory should be locked and interrupts enabled again.
Once a segment is erased, data can be written to it. In the following example, I have used two global registers, data_buffer and data_dump which hold 64 16 bit integers each.


void flash_write(int *addr, char option)
{
  _DINT();                             // Disable interrupts(IAR workbench).
  int i = 0;
  FCTL2 = FWKEY + FSSEL_1 + FN0;       // Clk = SMCLK/4
  FCTL3 = FWKEY;                       // Clear Lock bit
  FCTL1 = FWKEY + WRT;                 // Set WRT bit for write operation
  
  if(option == WRITE_FROM_BUFFER)
    for (i=0; i<64; i++)
      *addr++ = data_buffer[i];         // copy value to flash
  
  else if(option == WRITE_FROM_DUMP)
    for (i=0; i<64; i++)
      *addr++ = data_dump[i];           // copy value to flash

  FCTL1 = FWKEY;                        // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                 // Set LOCK bit
  _EINT();
}

The code is self explanatory. Though I have used data buffers, there shouldn’t be any problem writing single data. Note that each segment is 512 bytes and hence it can hold 256 integers(each integer in msp430 is 2 bytes). Hence, once a segment is erased, we can perform 4 buffer writes. Also note that addresses 0xfe00-0xffff hold interrupt vectors. Hence don’t use the segment which will overwrite these. This will result in the microcontroller malfunctioning after restart since the interrupt vector will get erased and the microcontroller will not know where to start from.
With the above two functions, let us look at a simple example where we save 256 integers


void main(){
	// Assume all initiations are done.
	// flash_erase erases a segment
	// flash_write writes 64 values
	// get_value() is any function which returns some value
	// print() is a generic function which prints the value given as input
	int *addr = (int *)0x0E000	// Address of the flash memory segment starting
	int *addr_cpy;				// A copy of the address
	int buffer[64];				// data buffer
	int i, j;
	flashs_erase(addr);
	for(j=0; j<4; j++){
		for(i=0; i<64; i++){
			buffer[i] = get_value();	// Save a value.
		}
		flash_write(addr + j*64, buffer, WRITE_FROM_BUFFER);	// Write the values to the flash
	}
	// Now print all the values
	for(i=0; i<256; i++)
		print(addr[i]);
}

That ends our article on using flash memory. Please feel free to comment. I would be more than happy to learn from you.
 

Advertisements

20 thoughts on “Using flash memory in MSP430

    • Hi Deepak,
      I think you can do a continuous conversion. I believe you can give a starting address and it is used as a pointer for storing the data. I haven’t tested it myself. After every conversion, you can increment a copy of the pointer and send the data from that address to PC using UART.

    • Hello Parthiban, unfortunately I never worked on MSP430F5152. However, I am assuming it will be almost the same. For the smaller details, you can try having a look at the data sheet.

    • Hello Adam,

      Thank you for your comment. Also, thank you for pointing that out. I might have kept addr_cpy for some debugging purpose, but it is not necessary. You can remove it from the code.

  1. Your example works well on our prototypes. Unfortunately, in production it tends to drop data bits on 20% of the MCUs that we tested. (200 failures for a lot of 1000 units.) Any suggestions?

  2. Hi Viswanath,

    Two questions, Why you use the add:0x0E000, is this a segment?, How many bytes you can store there?

    Thank for your help.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s