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

SPICE Backend

SPICE stands for Simulating Program with Integrated Circuit Emphasis. Essentially a program for simulation of electrical circuits. We will look at a very small spice backend, written in C. The project was part of CAD Lab assignment for electrical engineering students.
Since there will be many equations, i have compiled the document into a PDF using LYX, the document processor. But i will briefly explain about the project.

Circuit simulation, is an easy task, till there are only few nodes. However, as the nodes and elements increase, the complexity increases exponentially. To ease our task and solve the repetitive process of solving equations, we write a simple program.

Our job, as the end user is very simple:
1. Write a net list, containing all the information about the circuit. Please note that, you need to draw the circuit on paper, label the nodes and write the net list accordingly.
2. Invoke the program.

Simple isnt it?

Now let us look from the programmer’s perspective:
1. Read the netlist. Convert all the data into numericals and node names. Scan for all errors
2. Create the circuit as a set of structure elements.
3. Create a matrix to solve the simultaneous linear equations
4. Write the output to file

The first step is a little difficult among all of them. Parsing a file in C with numericals, especially with muultipliers like nano, pico, micro etc is not trivial.

Once done, we use linked lists to store the information about the elements, the nodes to which it is attached, the values, the dependencies if any etc. Once this is done, we traverse the linked list again to fit all the values into a neat matrix. Solving this matrix will give back all the node voltages.

Download the following file to read about the spice backend.

SPICE_Backend

A few things i wanted to add:

1. The elements as plugins to the program, so that it is possible to add new elements

2. Better matrix inversion algorithms

3. A GUI frontend

In case you want the code, please drop a comment with your mail ID, so that i can mail it to you.