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.
My application needs to store some data in FRAM to use during run time.
My question is how to determine which area of FRAM I can use to store the data?
In the liker file lnk_msp430fr5969.cmd showed the addresses of FRAM & FRAM2
And here is the MPU in the linker file:
MEMORY
{
SFR : origin = 0x0000, length = 0x0010
PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100
RAM : origin = 0x1C00, length = 0x0800
INFOA : origin = 0x1980, length = 0x0080
......
INFOD : origin = 0x1800, length = 0x0080
JTAGSIGNATURE : origin = 0xFF80, length = 0x0004, fill = 0xFFFF
BSLSIGNATURE : origin = 0xFF84, length = 0x0004, fill = 0xFFFF
IPESIGNATURE : origin = 0xFF88, length = 0x0008, fill = 0xFFFF
INT00 : origin = 0xFF90, length = 0x0002
INT01 : origin = 0xFF92, length = 0x0002
.......
RESET : origin = 0xFFFE, length = 0x0002
}
It depends on your needs.
If you don't have a lot, just use the INFO areas.
If you have a lot and are not compiling using the large model, then all of FRAM2 is available.
First, thanks David for replying.
Then you mentioned that all of FRAM2 is available. however, my project has been using some of them as above picture.
So my question is that if I use FRAM2 then would I override the .text? or the compiler would automatically move the .text to other area?
It appears that all of your code would fit in FRAM so disabling the large mode would force the compiler to put it all there. The code would be smaller and faster too.
You would have to use some specialized functions to access FRAM2 but they should be available in the library.
Thanks David. You helped me a lot for understanding the memory partition.
My new question is that: in the library, which one I should use : framctl_a.c OR framctl.c? My borad is MSP430FR5969
Thanks
Gcc has:
• unsigned char __data20_read_char(unsigned long addr); • unsigned long __data20_read_long(unsigned long addr); • unsigned short __data20_read_short(unsigned long addr); • void __data20_write_char(unsigned long addr, unsigned char src); • void __data20_write_long(unsigned long addr, unsigned long src); • void __data20_write_short(unsigned long addr, unsigned short src);
I try to write 0x02 and 0x68 to FRAM at the "INFOA" section which its address from the linker file is 0x1980.
When I read back the value is 0xFF instead of 0x2
something is wrong with the FRAM?
Here my example code:
#include <msp430.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "driverlib.h"
uint8_t val = 0x0;
int main(void) {
uint8_t dt1[2] = {0x02,0x68};
uint8_t * framPtr;
const uint16_t infoA_address = 0x1980;
const uint16_t numberOfBytes = 2;
framPtr = (uint8_t *) infoA_address;
WDT_A_hold(WDT_A_BASE);
val = 0x55;
printf("Before val=0x%x\n", val);
FRAMCtl_write8(dt1, framPtr , numberOfBytes);
//read back the location 0x1980
framPtr = (uint8_t *) infoA_address;
val = *framPtr;
printf("After val=0x%x\n", val);
return (0);
}
I don't know why you are using the FRAMctl function. The information memory is read/write enabled by default at reset so all you should need is a pointer.
David, but my purpose is use FRAM to store permanently some value. It means that the values still be there after when we cycle the power.
Please help. Thanks
Hi Chris,
Infor memory also store in FRAM, thus the value still be there after power cycle.
And for the previous question, you need enable FRAM write operation and then be able to write data into FRAM.
https://dev.ti.com/tirex/explore/node?node=AAdcVLl0EcrsqUMXhiaeEQ__IOGqZri__LATEST
Thanks!
Best Regards
Johnson
Hi Johnson, thanks for replying, but the source code from the link (i copy and paste below) did not show how to "enable FRAM write operation". Please help
void FRAMWrite(void);
unsigned char count = 0;
unsigned long data;
#if defined(__TI_COMPILER_VERSION__)
#pragma PERSISTENT(FRAM_write)
unsigned long FRAM_write[WRITE_SIZE] = {0};
#elif defined(__IAR_SYSTEMS_ICC__)
__persistent unsigned long FRAM_write[WRITE_SIZE] = {0};
#elif defined(__GNUC__)
unsigned long __attribute__((persistent)) FRAM_write[WRITE_SIZE] = {0};
#else
#error Compiler not supported!
#endif
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // Stop WDT
// Configure GPIO
P1OUT &= ~BIT0; // Clear P1.0 output latch for a defined power-on state
P1DIR |= BIT0; // Set P1.0 to output direction
// Disable the GPIO power-on default high-impedance mode to activate
// previously configured port settings
PM5CTL0 &= ~LOCKLPM5;
// Initialize dummy data
data = 0x00010001;
while(1)
{
data += 0x00010001;
FRAMWrite();
count++;
if (count > 100)
{
P1OUT ^= 0x01; // Toggle LED to show 512K bytes
count = 0; // ..have been written
data = 0x00010001;
}
}
}
void FRAMWrite(void)
{
unsigned int i=0;
for ( i= 0; i< WRITE_SIZE; i++)
{
FRAM_write[i] = data;
}
}
Hi Chris,
As the @David description, the PERSISTENT is store in info memory, thus those section will enable by default.
If you would like to write some data to other FRAM section, you have to enable FRAM write operation.
Thanks!
Best Regards
Johnson
Hi Johnson,
Here is part of my link file lnk_msp430fr5969.cmd
And I would like to store some value into the section "INFOA":
1) is it in the FRAM
2) how can I enable FRAM write operation.
Thanks
Chris
MEMORY
{
SFR : origin = 0x0000, length = 0x0010
PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100
RAM : origin = 0x1C00, length = 0x0800
INFOA : origin = 0x1980, length = 0x0080
INFOB : origin = 0x1900, length = 0x0080
INFOC : origin = 0x1880, length = 0x0080
INFOD : origin = 0x1800, length = 0x0080
FRAM : origin = 0x4400, length = 0xBB80
FRAM2 : origin = 0x10000,length = 0x3FF8 /* Boundaries changed to fix CPU47 */
JTAGSIGNATURE : origin = 0xFF80, length = 0x0004, fill = 0xFFFF
BSLSIGNATURE : origin = 0xFF84, length = 0x0004, fill = 0xFFFF
IPESIGNATURE : origin = 0xFF88, length = 0x0008, fill = 0xFFFF
INT00 : origin = 0xFF90, length = 0x0002
INT01 : origin = 0xFF92, length = 0x0002
INT02 : origin = 0xFF94, length = 0x0002
Hi Chris,
I think you can use the below code to define your variable:
#pragma DATA_SECTION(a,".infoA") unsigned char a;
And more information you can refer to this document:
https://www.ti.com/lit/an/slaa628a/slaa628a.pdf
Best Regards
Johnson
Hi John , here's my very simple example code:
///
#include <msp430.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "driverlib.h"
uint8_t val = 0x0;
#pragma DATA_SECTION(a,".infoA")
unsigned char a;
int main(void) {
WDT_A_hold(WDT_A_BASE);
val = 0x55;
a = val;
printf("val =0x%x\n", val);
printf(" a =0x%x\n", a);
return (0);
}
///
then out put when I compile and run it: (it stills does not allow to write to infoA section)
val =0x55
a =0xff
Please help
Hi Chris,
Does this question had been resloved?
Do you still need some support?
Thanks!
Best Regards
Johnson
Hi Johnson,
I tried but it was not successful. And I run into other one : I can not load the Engr.out file into the board any more the error is:
MSP430: File Loader: Verification failed: Values at address 0x04800 do not match Please verify target memory and memory map.
MSP430: GEL: File: C:\Users\Q\workspace_v10\Engr1\Debug\Engr1.out: a data verification error occurred, file load failed.
Please help
Hi Chris,
I will write a example code and post here soon after test pass.
Thanks!
Best Regards
Johnson
Hi Chris,
I test in my side for this code:
#include <msp430.h> #pragma DATA_SECTION(a,".infoA") unsigned char a = 1; int main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop WDT a = 0x55; // Disable the GPIO power-on default high-impedance mode to activate // previously configured port settings PM5CTL0 &= ~LOCKLPM5; while (1) { __delay_cycles(5000); } }
And you need to enable Write in MPU:
Test result show INFO memory write normal.
Thanks!
Best Regards
Johnson
**Attention** This is a public forum