element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Personal Blogs
  • Community Hub
  • More
Personal Blogs
Legacy Personal Blogs MSP430FR2633 Saving FRAM when uploading code
  • Blog
  • Documents
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: baldengineer
  • Date Created: 10 Jul 2018 3:28 AM Date Created
  • Views 3678 views
  • Likes 6 likes
  • Comments 5 comments
  • fram
  • code composer studio
  • msp430fr2633
  • msp430
Related
Recommended

MSP430FR2633 Saving FRAM when uploading code

baldengineer
baldengineer
10 Jul 2018

On the MSP430FR2633 I needed to store an unsigned long in FRAM. The approach and examples suggested this was a straightforward task. The catch is that I wanted to avoid losing the contents when reprogramming the chip. This post is a description of what I needed to do to save variables to FRAM with the NOINIT pragma.

 

The following is based on CCS 8.0.

 

Step 1: Declare the variable

 

When using the FR2633, If you do not care what happens to the contents on re-program, saving variables in FRAM is this easy:

 

#pragma PERSISTENT(var)
unsigned long var=0;

SYSCFG0 = FRWPPW | DFWP;            // Program FRAM write enable
var++;                             // Increment the variable (aka, treat it like any other variable)
SYSCFG0 = FRWPPW | PFWP | DFWP;     // Program FRAM write protected (not writable)

 

Lines 01 and 02 set up the variable "var." The pragma PERSISTENT tells the compiler that it needs to locate the variable "var" in a specific memory space. The variable initialization is similar to initializing a variable in RAM. (In this example, it is set to 0.) A linker command file defines that memory space. I'll get to that file later. Lines 04 enables writes to FRAM, while line 06 disables the writes. Line 05 can be whatever you want. Accessing variables that exist in FRAM is no different than variables in RAM. In this example, I am just incrementing the value each time the program runs.

 

Locking and unlocking the FRAM is a quasi-optional step. The idea is that if something terrible happens, the locked FRAM is not accidentally overwritten. It would be effortless to have an array that overruns into another memory location.

 

The PERSISTENT pragma works out of the box, but it has a gotcha. Each time you re-load the code, it gets wiped out. You might be asking, what is the point of that? Well, the upside is that FRAM stores data when the processor goes into its deepest sleep (LPM5 I think). So you could dump variables stored in static RAM into FRAM. (Or on the MSP430, just keep them there.) There are some power usage costs. Saving to FRAM takes more energy than RAM. Also, there needs to be 10us after coming out of some sleep modes before you can save again to FRAM. Also, you need to configure wait states if the clock is running faster than 8 MHz. I guess that for most applications those are not serious tradeoffs.

 

The issue I have is that I'm going to be storing a value that needs to persist whenever I overwrite the code. No problem, I thought. I can just use the pragma called NOINIT instead.

 

#pragma NOINIT(var)
unsigned long var;

 

Unlike PERSISTENT, NOINIT does not initialize the variable. Instead, you can get an address, and that is about it. Sort of. It turns out that in CCA v8, the example project I loaded, has a default set to erase "main memory." I naively thought that the description excluded FRAM, but it appears not to be the case.

 

Step 2: Change Erase Options

image

I found changing to “Replace written memory locations, retain unwritten memory locations” or “Erase and download necessary segments only (Differential download)” kept the FRAM intact. I would like to understand each of these options in more detail, but that will have to wait.

 

Step 3: Editing the Linker Command File

This step really irritated me. TI has gone out of their way to hide this critical change. In the application note "MSP430TM FRAM Technology – How To and Best Practices", they outline how to "properly" use FRAM on an MSP430. Except, the document really does not. At least in the case of preserving FRAM contents during re-programming. In section 5.1, it describes NOINIT and PERSISTENT. However, it brushes off a key step for NOINIT with the following comment.

image

"Requiring a minor modication of the linker command file is such functionlity is required." What?!

 

If you study the document closer, it infers the changes needed to be made to the "linker command file." However, it never clearly states WHAT. Also, the disturbing aspect is that it is a single line of code. In most of the forum references, the closest correct answer I found was, "...read the linker user's manual."

 

The "linker command file" is generated by CCS automatically for your processor. In my case, it is the “lnk_msp430fr2633.cmd.” Inside appears to be the memory map the linker uses to put variables into a memory location. Search for ".TI.noinit," to find it in the RAM definitions.

image

Comment that line out and them scroll back up to the line marked "SECTION." There if you look at the structure, it is groups called things like "READ_WRITE_MEMORY" and "READ_ONLY_MEMORY."

image

Here I added the line at 137. It tells the linker to place "NOINIT" variables into FRAM and that they should be READ and WRITE capable. That's it.

 

In summary, you need to declare the variable (well documented), need to change the debug erase options (no documentation), and change two lines in the linker command file (obstructed documentation.) From there, my code works. I can RESET the processor, power cycle it, and re-load the code. Each time, the contents of the FRAM location are saved.

 

#include <msp430.h>

 

#pragma NOINIT(Port_event)

unsigned long Port_event;

 

int main(void)

{

    WDTCTL = WDTPW | WDTHOLD;               // Stop WDT

 

    P1OUT &= ~BIT7;

    P1DIR |= BIT7;

    PM5CTL0 &= ~LOCKLPM5;   // release power-on high z mode

 

    // Add the variable Port_event in FRAM to record the button event

    SYSCFG0 = FRWPPW | DFWP;            // Program FRAM write enable

    Port_event++;                       // Record the port event in FRAM

    if (Port_event > 0)

        P1OUT |= BIT7;

    SYSCFG0 = FRWPPW | PFWP | DFWP;     // Program FRAM write protected (not writable)

 

    __bis_SR_register(LPM4_bits | GIE);

}

 

That said, it's time to move on to the next MSP430 peripheral I need for my project. Like the other 3, I've configured so far, the examples and documentation are missing critical information.

  • Sign in to reply

Top Comments

  • fmilburn
    fmilburn over 6 years ago +1
    Thanks for outlining how this is done. I have been using the MSP430 with FRAM for a while but have not needed to keep data when reprogramming in my current projects. It is nice to know how...
  • baldengineer
    baldengineer over 6 years ago in reply to Fred27

    It's for an upcoming video project. Originally I needed I2C (or SPI), FRAM, RTC, and CapTouch controller all configured. Unfortunately, the documentation and examples for this particular processor are very lacking in everything except the CapTouch. So that's all I'm using the MSP430 to do. The rest will be controlled with another MCU. The 430 will detect a change in capacitance, then turn everything else on and off.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Fred27
    Fred27 over 6 years ago

    By the way, what's the project?

     

    I always find peripheral configuration is always the hardest part and each device has subtly different way of doing things. Once the peripherals (and clocks) are configured the actual code is normally relatively easy!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Fred27
    Fred27 over 6 years ago

    Thanks. This is very helpful - and timely. I'm currently porting a NFC reader over to the FR2633 and will be storing things like tag IDs in FRAM once I've got the TRF7970A part working properly.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 6 years ago

    Very good post.

     

    DAB

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • fmilburn
    fmilburn over 6 years ago

    Thanks for outlining how this is done.  I have been using the MSP430 with FRAM for a while but have not needed to keep data when reprogramming in my current projects.  It is nice to know how...

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube