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.

Write data to information memory (flash) MSP430f149

Other Parts Discussed in Thread: MSP430F149

Hi,

I'm using MSP430f149 and I want to write data like presented below to flash information memory.

parameter record note
Name "Name"
Date "01.01.2012"
Author "Alex Biz" name
Version "0100" 1.00
Serial number "12345"

So I'm going to put strings (record from table) of data into memory.

How to do that?

Regards.

Maybe

#include "io430.h"
#include <string.h>

#define INFO_MEM_SEG_A (0x010FF)
#define INFO_MEM_SEG_B (0x0107F)
int main( void )
{
 
  int size_of_string=0x0000;
  
 
  //Data information memory
  
  char* naziv="Prrikup podataka";
  char* datum_proizvodnje="20.02.2012.";
  char* proizvodac="Alo Malo";
  char* verzija_sw="0100";
  char* verzija_hw="0100";
  char* serijski_broj_uredaja="12345678";
  char* adresa_mjernog_mjesta="00000001";
  
  // Function prototypes
  void  write_SegA (char *value, int flash_ptr_val, unsigned int size_of_string);
  
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  
  // Upis podataka u trajnu INFO flash memoriju
  size_of_string = strlen(naziv);
  write_SegA (naziv, INFO_MEM_SEG_A, strlen(naziv));
  size_of_string += strlen(datum_proizvodnje);
  write_SegA (datum_proizvodnje, INFO_MEM_SEG_A + size_of_string, strlen(datum_proizvodnje));
  size_of_string += strlen(proizvodac);
  write_SegA (proizvodac, INFO_MEM_SEG_A + size_of_string, strlen(proizvodac));
  size_of_string += strlen(verzija_sw);
  write_SegA (verzija_sw, INFO_MEM_SEG_A + size_of_string, strlen(verzija_sw));
  size_of_string += strlen(verzija_hw);
  write_SegA (verzija_hw, INFO_MEM_SEG_A + size_of_string, strlen(verzija_hw));
  size_of_string += strlen(serijski_broj_uredaja);
  write_SegA (serijski_broj_uredaja, INFO_MEM_SEG_A + size_of_string, strlen(serijski_broj_uredaja));
  size_of_string += strlen(adresa_mjernog_mjesta);
  write_SegA (adresa_mjernog_mjesta, INFO_MEM_SEG_A + size_of_string, strlen(adresa_mjernog_mjesta));
  
  return 0;
}

void write_SegA (char *value, int flash_ptr_val, unsigned int size_of_string)
{
  char *Flash_ptr;                          // Flash pointer
  unsigned int i;
  
  Flash_ptr = (char *) flash_ptr_val;       // Initialize Flash pointer
  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<size_of_string; i++)
  {
    *Flash_ptr++ = *value++;                   // Write value to flash
    
  }

  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}
  • I'm using the IAR EWB and I see the code

    #include <msp430.h>
     
    const unsigned char port_bit @ 0x1800 = BIT0;
     
    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;  // disable watchdog
      P1DIR = port_bit;          // set P1.x as output
     
      while(1)
      {
        P1OUT ^= port_bit;         // toggle P1.0
    	  __delay_cycles(100000);
      }
    }

    but I don't understand it.

    How could that help me to store strings of data to Information memory?

    Regards.

  • With IAR you can specify where linker puts variable in memory space. As a result you are free to put char array in information memory and access it freely. Just remember that you can only write '0's to flash. During erase whole segment is being set to '1'. You can find byte location of your information memory in documentation. You can also use memory segment label (see http://supp.iar.com/Support/?note=39271&from=search+result).

    Also you should take a while and study Chapter 5 of MSP430x1xx Family Users Guide (http://www.ti.com/lit/ug/slau049f/slau049f.pdf).

    Regards,
    Maciej 

  • Thanks, I tried the code form salc015p ,fet140_flashwrite_01 in IAR WEB with no modifications

    /* --COPYRIGHT--,BSD_EX
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *******************************************************************************
     * 
     *                       MSP430 CODE EXAMPLE DISCLAIMER
     *
     * MSP430 code examples are self-contained low-level programs that typically
     * demonstrate a single peripheral function or device feature in a highly
     * concise manner. For this the code may rely on the device's power-on default
     * register values and settings such as the clock configuration and care must
     * be taken when combining code from several examples to avoid potential side
     * effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
     * for an API functional library-approach to peripheral configuration.
     *
     * --/COPYRIGHT--*/
    //****************************************************************************
    //  MSP-FET430P140 Demo - Flash In-System Programming, Copy SegA to SegB
    //
    //  Description: This program first erases flash seg A, then it increments all
    //  values in seg A, then it erases seg B, then  copies seg A to seg B.
    //  Assumed MCLK 550kHz - 900kHz.
    //  //* Set Breakpoint on NOP in the Mainloop to avoid Stressing Flash *//
    //
    //               MSP430F149
    //            -----------------
    //        /|\|              XIN|-
    //         | |                 |
    //         --|RST          XOUT|-
    //           |                 |
    //
    //  M. Mitchell
    //  Texas Instruments Inc.
    //  Feb 2005
    //  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.21A
    //******************************************************************************
    
    #include <msp430.h>
    
    char  value;                                // 8-bit value to write to segment A
    
    // Function prototypes
    void  write_SegA (char value);
    void  copy_A2B (void);
    
    int main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
      FCTL2 = FWKEY + FSSEL0 + FN0;             // MCLK/2 for Flash Timing Generator
      value = 0;                                // Initialize value
    
      while(1)                                  // Repeat forever
      {
        write_SegA(value++);                    // Write segment A, increment value
        copy_A2B();                             // Copy segment A to B
        _NOP();                                 // SET BREAKPOINT HERE
      }
    }
    
    void write_SegA (char value)
    {
      char *Flash_ptr;                          // Flash pointer
      unsigned int i;
    
      Flash_ptr = (char *) 0x1080;              // Initialize Flash pointer
      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<128; i++)
      {
        *Flash_ptr++ = value;                   // Write value to flash
      }
    
      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
    }
    
    
    void copy_A2B (void)
    {
      char *Flash_ptrA;                         // Segment A pointer
      char *Flash_ptrB;                         // Segment B pointer
      unsigned int i;
    
      Flash_ptrA = (char *) 0x1080;             // Initialize Flash segment A pointer
      Flash_ptrB = (char *) 0x1000;             // Initialize Flash segment B pointer
      FCTL1 = FWKEY + ERASE;                    // Set Erase bit
      FCTL3 = FWKEY;                            // Clear Lock bit
      *Flash_ptrB = 0;                          // Dummy write to erase Flash segment B
      FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
    
      for (i=0; i<128; i++)
      {
        *Flash_ptrB++ = *Flash_ptrA++;           // Copy value segment A to segment B
      }
    
      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
    }
    

    And while Download and Debug this error occurrences

    How to solve this? 

    Regards.

  • Sorry but I do not know IAR very well. You should check segments in linker script.

    This might be useful: http://supp.iar.com/Support/?note=55224

    Regards,
    Maciej 

  • It's not clear what you want to do exactly.

    In the code oyu posted, you generate string constant sin flash and assing their start address to local pointer variables. The text is already in flash to init the variables, then you write it to info memory. Doesn't make too much sense.
    You may as well define global arrays and mark them const (saves some space on stack).

    You can also define constant global arrays of arrays and assign multiple entries. If you mark an array as const, it won't take any ram space but will be placed directly into flash and used from there.

    YOu should tell a bit more detailed what you want to do in the end (wehre does the data coe from, why do you want to store it, how do you need to access it later etc.)

  • Hi Jens-Michael Gross,

    Thanks for replay.

    I'm trying to store some data that newer change to Information memory, such as serial number, software version etc.

    I found in http://www.ti.com/lit/ds/symlink/msp430f149.pdf , page 16 that segment B of information memory starts at 1000h so I wont store first a name of software in INFO memory, and the name has etc. 10 ascii characters 10B(ten bayts), and the at 100Ah I wont sore some serial number and so on.

    Lather I want to read from flash memory. If a user requests by UART protocol that hi wants to know the serial number , I have to read the serial number from INFO memory and sent it to him to PC.

    Regards  David.

  • And how do you intend to tell this data to teh device?

    The softwar eversion is likely bound to the current firmware. (Else it wouldn't be software version). So you can as well simply declare it as a constant in your source code.

    const unsigned char version = "V1.3a";

    It is then stored along with the code itself in flash. No need to copy it to info memory. Especially since the info memory eithe rwon't be updated on firmwar eupdate (in whcih case you'd have a wrong firmware version stored there) or INFO memory is cleared and rewritte on update (in which case you would again update it with data you already have in flash).

    For the serial number, there are two ways: Either you compile individual code with individual serial number. THen it can reside in code flash too (as const data like the firmware version). THis is the simplest way to go and works fine for a low production count. In fact, we're still using this method for our devices, along with other configuraiton info (like input mapping for analog, digital, 4-20mA or S0).
    Then there are flashing tools which can replace a certian area of the binary with data from a list, or jsu tincrement a memory cell for each programmed device. Like the (commercial version of) FET-Pro430 from Elprotronic. THis is fine for medium to high produciton counts, if the serial is all you need to have individually.

    The more versatile but also way more complex solution is to implement a communications interface that accepts configuration commands and receives and stores data at runtime. Here you'll indeed need to store the data in info memory (or any other, definitely unused flash section). But you also have to connect to each device initially and send it its configuraitoninformation. If the serial number is known at compiletime, then this method is totally superfluous.
    But even if you go this way, there are many different ways to do things, even in a portable way:
    You define a struct that holds your dynamic data.

    typedef ConfigData {
      unsigned int serial;
      unsigned int data1;
      char[12] name;
    };

    you define a global pointer to this struct.

    ConfigData * myData = 0x1000;

    You can then directly access the struct members through the pointer for reading them.

    printf("name: %s, serial: %d, data: %d\r\n", myData->name, myData->serial, myData->data1(;

    You can also write to the struct when you block interrupts and program the flash controller before you write to the struct members.
    This way is 100% portable across different compilers and does not use any compiler- or linker-specific pragmas or settings.

    If you write the data only once, after the device ha sbeen mass-erased, you can simply block interrupts, set the flash controlelr to write mode, then assign the data to the struct, the disable the flash controlelr and re-enable interrupts.
    If oyu want to dynamically change par tof the struct later, things are a littel bit more compilcated, as you need ot make a backup of the original data (e.g. copy the struct member by member into a second struct that was created locally), make the change int eh backup, erase the info memory, then copy the struct back.

**Attention** This is a public forum