Hello,
I am interested in saving long-type variables into flash memory, and retrieving these values at a later time. According to my understanding, the register addresses are 16-bit integers, so pointers to these registers should be of type int. Long type variables are 32-bit. However, I believe most MSP430's can only write to registers 16 bits at a time, and therefore some manipulation must be done in order to save long-type variables to flash as well as to read these variables from flash memory.
Below is my attempt to do so, and I would appreciate any feedback if there is a flaw in my approach/understanding, or if there is a better way to do this. Thanks in advance.
---------------------------------------
#define DATA_IN_FLASH 120
#include <msp430f5310.h>
/*************************************************************************************************/
/********************** Variables to be saved to / loaded from flash memory **********************/
volatile static unsigned long Test1 = 131071;
volatile static signed long Test2 = -131072;
volatile static signed int Test3 = -1310;
volatile static signed char Test4 = -31;
/********************** Variables to be saved to / loaded from flash memory **********************/
/*************************************************************************************************/
/******** Flash Memory Addresses ********/
int* Data_In_Flash = (int*) 0xf000;
int* Test1_Flash = (int*) 0xf002;
int* Test2_Flash = (int*) 0xf00a;
int* Test3_Flash = (int*) 0xf012;
int* Test4_Flash = (int*) 0xf016;
/******** Flash Memory Addresses ********/
// Functions
void WriteFlashEntry(int* address, int data);
void EraseFlash(int addr);
void Write_Flash(void);
void readFlashSegment(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
// Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation
UCSCTL2 |= 249; // Set DCO Multiplier for 8MHz
// (N + 1) * FLLRef = Fdco
// (249 + 1) * 32768 = ~8MHz
__bic_SR_register(SCG0); // Enable the FLL control loop
// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
// UG for optimization.
// 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle
__delay_cycles(250000);
if (*Data_In_Flash == DATA_IN_FLASH) {
EraseFlash(0xf000);
Write_Flash();
}
while (1) {
}
}
void Write_Flash(void) {
WriteFlashEntry(Data_In_Flash, DATA_IN_FLASH);
WriteFlashEntry(Test1_Flash, Test1 & 0x0000FFFF);
WriteFlashEntry(Test1_Flash + 4, (Test1 & 0xFFFF0000) >> 16);
WriteFlashEntry(Test2_Flash, Test2 & 0x0000FFFF);
WriteFlashEntry(Test2_Flash + 4, (Test2 & 0xFFFF0000) >> 16);
WriteFlashEntry(Test3_Flash, Test3);
WriteFlashEntry(Test4_Flash, Test4);
}
void readFlashSegment() { //writes all three channels to their respective flash memory locations
Test1 = (*Test1_Flash) + ( ( (long)(*(Test1_Flash + 4)) ) << 16);
Test2 = (*Test2_Flash) + ( ( (long)(*(Test2_Flash + 4)) ) << 16);
Test3 = *Test3_Flash;
Test4 = *Test4_Flash;
}
void WriteFlashEntry(int* address, int data) // Write the individual (integer) data to the flash address.
{
while ((BUSY & FCTL3)) ;
FCTL3 = FWKEY; // Unlock the flash.
FCTL1 = FWKEY + WRT; // Enable flash write.
*address = data; // Write the data to the flash.
while ((BUSY & FCTL3)) ;
FCTL1 = FWKEY; // Disable flash write.
FCTL3 = FWKEY + LOCK; // Lock the flash.
}
void EraseFlash(int addr) {
int* address = (int *) addr;
while ((BUSY & FCTL3)) ;
FCTL1 = FWKEY + ERASE; // Enable flash write.
FCTL3 = FWKEY; // Unlock the flash.
*address = 0x00; // Write the data to the flash.
while ((BUSY & FCTL3)) ;
FCTL1 = FWKEY; // Disable flash write.
FCTL3 = FWKEY + LOCK; // Lock the flash.
}
---------------------------------------
Sincerely,
Mehdi