TI MSP430 Microcontroller Writing to FLASH

FLASH.H


#ifndef _FLASH_H
#define _FLASH_H

//#include "../rs232/rs_232.h"

#define largoMAC 6      //byte
#define largoID 19      //words
#define largoIP 4       //byte
#define largoMasc 4     //byte
#define largoE 4        //byte  
#define largoTot 37        // = largoMAC + largoID +largoIP + largoMasc + largoE

// Function prototypes
int actualizarFlash(unsigned char tipo);
void write_SegA(unsigned char *mac, unsigned char *id, unsigned char *ip, unsigned char *masc, unsigned char *enlace);
void read_SegA(char offset, unsigned short largoCampo, unsigned char *campo);
//void leerCOM1(unsigned char *campo, unsigned short cuenta, unsigned short offset);

unsigned char leerIP(unsigned short octeto);

#endif /* _FLASH_H */

FLASHWRITE02.C


/**  OJO CON EL RELOJ, ESTE PROGRAMA FUNCIONA CON MCLK ENTRE 550KHz Y 900KHz. 
* SUPUESTAMENTE DCO POR DEFECTO ESTA FUNCIONANDO con un reloj en este rango de frecuencia. 
*/

#include  <msp430x16x.h>
#include <stdio.h>
#include "flash.h"

char *Flash_ptr;                                  // Puntero Flash


/**
* \brief Función que actualiza un campo guardado (quemado) en la Flash.
* \param tipo Inidica el tipo de campo a modificar.
* \return Retorna 0 si actualiza. De lo contrario, otro valor.
*/
/*int actualizarFlash(unsigned char tipo)*/
void main (void)
{
  unsigned char MAC[largoMAC] = {0x01,0xbd,0x3b,0x33,0x05,0x71};//0};
  unsigned char ID[largoID] = {"PME010709VCMEMH0001"};//0};
  unsigned char IP[largoIP] = {0xAC,0x10,0x10,0x50}; //0};        //172.16.16.80
  unsigned char MASCARA[largoMasc] = {0xFF,0xFF,0xFF,0x80};//0};  //255.255.255.128
  unsigned char ENLACE[largoE] = {0xAC,0x10,0x10,0x01};//0};
  unsigned char buffer_test[largoTot]={0};
  
  //int errorFlash = 0;
  
  WDTCTL = WDTPW + WDTHOLD;                       // Parar watchdog timer
  FCTL2 = FWKEY + FSSEL0 + FN0;                   // MCLK/2 for Flash Timing Generator
  
  write_SegA(ID,MAC,IP,MASCARA,ENLACE);  
  /*switch(tipo)
  {
    case 'm': leerCOM1(MAC, 6, 1);
              read_SegA(0, 19, ID);
              read_SegA(25, 4, IP);
              read_SegA(29, 4, MASCARA);
              read_SegA(33, 4, ENLACE);
              write_SegA(ID,MAC,IP,MASCARA,ENLACE);
              break;
    case 'd': leerCOM1(ID, 19, 1);
              read_SegA(19, 6, MAC);
              read_SegA(25, 4, IP);
              read_SegA(29, 4, MASCARA);
              read_SegA(33, 4, ENLACE);
              write_SegA(ID,MAC,IP,MASCARA,ENLACE);
              break;
    case 'p': leerCOM1(IP, 4, 1);
              read_SegA(0, 19, ID);
              read_SegA(19, 6, MAC);             
              read_SegA(29, 4, MASCARA);
              read_SegA(33, 4, ENLACE);
              write_SegA(ID,MAC,IP,MASCARA,ENLACE);
              break;
    case 's': leerCOM1(MASCARA, 4, 1);
              read_SegA(0, 19, ID);
              read_SegA(19, 6, MAC);              
              read_SegA(25, 4, IP);
              read_SegA(33, 4, ENLACE);
              write_SegA(ID,MAC,IP,MASCARA,ENLACE);
              break;
    case 'e': leerCOM1(ENLACE, 4, 1);
              read_SegA(0, 19, ID);
              read_SegA(19, 6, MAC);              
              read_SegA(25, 4, IP);
              read_SegA(29, 4, MASCARA);
              write_SegA(ID,MAC,IP,MASCARA,ENLACE);
              break;             

    default: errorFlash = 30;
  }*/
  read_SegA(0,37,buffer_test);

  //return errorFlash;
}

/** 
* \brief Función que escribe en Segmento A de la memoria de Información Flash 
*
* Escribe en el siguiente orden: ID, MAC, IP, Máscara de Subred.
* \param *id Identificación de la MSP430.
* \param *mac MAC Media Access Control address, Direccion de Control de Acceso al Medio.
* \param *ip Protocolo de Internet.
* \param *masc Máscara de Red.
* \param *enlace Puerta de Enlace de la Subred.
*/
void write_SegA(unsigned char *id, unsigned char *mac, unsigned char *ip, unsigned char *masc, unsigned char *enlace)
{
  unsigned short i;
  Flash_ptr = (char *) 0x1080;                    // Inicialización Puntero Flash
  FCTL1 = FWKEY + ERASE;                          // Set Erase bit
  FCTL3 = FWKEY;                                  // Clear Lock bit
  *Flash_ptr = 0;                                 // Dummy write to erase Flash segment

  FCTL1 = FWKEY + WRT;                            // Set WRT bit for write operation

  for(i=0; i < largoTot; i++)
  {
    if(i < largoID)                               // Escribe cada campo en el segmento A de la flash
          *Flash_ptr++ = id[i];                                   //ID
    else if (i < largoMAC + largoID && i >= largoID)
          *Flash_ptr++ = mac[i-largoID];                          //MAC
    else if (i < largoTot - largoMasc - largoE && i >= largoMAC + largoID)
          *Flash_ptr++ = ip[i-(largoMAC + largoID)];              //IP
    else if (i < largoTot - largoE && i >= largoTot - largoMasc - largoE)
          *Flash_ptr++ = masc[i-(largoTot - largoMasc - largoE)];    //MASCARA
    else if (i < largoTot && i >= largoTot - largoE)
          *Flash_ptr++ = enlace[i-(largoTot - largoE)];              //ENLACE
    _NOP();                                                     // SET BREAKPOINT HERE
  }                         
  
  FCTL1 = FWKEY;                                  // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                           // Set LOCK bit
}

/**
* \brief Función que lee los campos guardados en segmento A de la memoria Flash.
* \param offset Cantidad de byte que debe avanzar antes de leer desde el puntero de memoria Flash.
* \param largoCampo Largo del campo leído.
* \param *campo Arreglo de caracteres donde se almacenará lo leído. 
*/
void read_SegA(char offset, unsigned short largoCampo, unsigned char *campo)
{
  unsigned short i=0;
  Flash_ptr = (char *) 0x1080;                    // Re-Inicialización Puntero Flash
  
  Flash_ptr = Flash_ptr + offset;                 // offset
  /*while(offset-- > 0)                             
    Flash_ptr++;*/
 // _NOP();    
  while(i < largoCampo)                           // LECTURA DE LA FLASH
    {
    campo[i] = *Flash_ptr++;
    printf("%c", campo[i]);
    i++;
    }
  printf("\n");
}
/**
* \brief Función que lee el buffer de COM1
* \param *campo Arreglo de caracteres donde se almacenará lo leído desde el COM1.
* \param cuenta Largo del campo leído.
* \param offset Cantidad de byte que se debe avanzar antes de leer desde el buffer de COM1.

void leerCOM1(unsigned char *campo, unsigned short cuenta, unsigned short offset)
{
  unsigned short i;
  for(i = 0; i < cuenta; i++)
  {
    campo[i] = getRXBuffer_0(offset + i);
    //printf("%c",campo[i]);
  }
  _NOP();
}*/