I have the code example msp430g2xx3_flashwrite_01.c running and understand most of it. I can't use the existing INFOA-D (64 bytes each) memory segments though, because I need a bigger area. So I tried creating new segments in the free space between INFOA where it ends (INFOA-D are mapped in reverse) and before 0xC000 where the next item (FLASH) begins.
I tried a few different things and couldn't get any of them to work, so I made it real simple: declare a new segment the same size as INFOC (64 bytes) starting at 0x1100 and replace the SegC address location in msp430g2xx3_flashwrite_01.c with the 0x1100 address. It still doesn't work. Nothing else is different than the original working example, so it leads me to conclude that my new segment, which shows up under Memory Allocation if I select "show all", is not writable. Maybe I am just missing a setting for this? Has anyone successfully created new segments that they have written to? I could find a few examples of writing to flash in the forum but none that wrote to new segments.
Creating new segment in memory:
MEMORY
{
/* first we count up */
SFR : origin = 0x0000, length = 0x0010
PERIPHERALS_8BIT : origin = 0x0010, length = 0x00F0
PERIPHERALS_16BIT : origin = 0x0100, length = 0x0100
RAM : origin = 0x0200, length = 0x0200
/* then we count down. here in INFOC and INFOD Is where code example is working */
INFOA : origin = 0x10C0, length = 0x0040
INFOB : origin = 0x1080, length = 0x0040
INFOC : origin = 0x1040, length = 0x0040
INFOD : origin = 0x1000, length = 0x0040
/* here is my new stuff. From 0x1100 (end of INFOA) to 0xC000 (start of RAM) looks free */
XVSEG : origin = 0x1100, length = 0x0040
/* this is the original stuff */
FLASH : origin = 0xC000, length = 0x3FDE
/* okay, but now we are back to counting up? */
BSLSIGNATURE : origin = 0xFFDE, length = 0x0002, fill = 0xFFFF
INT00 : origin = 0xFFE0, length = 0x0002
INT01 : origin = 0xFFE2, length = 0x0002
INT02 : origin = 0xFFE4, length = 0x0002
INT03 : origin = 0xFFE6, length = 0x0002
INT04 : origin = 0xFFE8, length = 0x0002
INT05 : origin = 0xFFEA, length = 0x0002
INT06 : origin = 0xFFEC, length = 0x0002
INT07 : origin = 0xFFEE, length = 0x0002
INT08 : origin = 0xFFF0, length = 0x0002
INT09 : origin = 0xFFF2, length = 0x0002
INT10 : origin = 0xFFF4, length = 0x0002
INT11 : origin = 0xFFF6, length = 0x0002
INT12 : origin = 0xFFF8, length = 0x0002
INT13 : origin = 0xFFFA, length = 0x0002
INT14 : origin = 0xFFFC, length = 0x0002
RESET : origin = 0xFFFE, length = 0x0002
}
/****************************************************************************/
/* Specify the sections allocation into memory */
/****************************************************************************/
SECTIONS
{
.bss : {} > RAM /* Global & static vars */
.data : {} > RAM /* Global & static vars */
.TI.noinit : {} > RAM /* For #pragma noinit */
.sysmem : {} > RAM /* Dynamic memory allocation area */
.stack : {} > RAM (HIGH) /* Software system stack */
.text : {} > FLASH /* Code */
.cinit : {} > FLASH /* Initialization tables */
.const : {} > FLASH /* Constant data */
.bslsignature : {} > BSLSIGNATURE /* BSL Signature */
.cio : {} > RAM /* C I/O Buffer */
.pinit : {} > FLASH /* C++ Constructor tables */
.binit : {} > FLASH /* Boot-time Initialization tables */
.init_array : {} > FLASH /* C++ Constructor tables */
.mspabi.exidx : {} > FLASH /* C++ Constructor tables */
.mspabi.extab : {} > FLASH /* C++ Constructor tables */
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 15009000
#ifndef __LARGE_CODE_MODEL__
.TI.ramfunc : {} load=FLASH, run=RAM, table(BINIT)
#else
.TI.ramfunc : {} load=FLASH | FLASH2, run=RAM, table(BINIT)
#endif
#endif
#endif
.infoA : {} > INFOA /* MSP430 INFO FLASH Memory segments */
.infoB : {} > INFOB
.infoC : {} > INFOC
.infoD : {} > INFOD
.xvseg : {} > XVSEG
/* MSP430 Interrupt vectors */
TRAPINT : { * ( .int00 ) } > INT00 type = VECT_INIT
.int01 : {} > INT01
PORT1 : { * ( .int02 ) } > INT02 type = VECT_INIT
PORT2 : { * ( .int03 ) } > INT03 type = VECT_INIT
.int04 : {} > INT04
ADC10 : { * ( .int05 ) } > INT05 type = VECT_INIT
USCIAB0TX : { * ( .int06 ) } > INT06 type = VECT_INIT
USCIAB0RX : { * ( .int07 ) } > INT07 type = VECT_INIT
TIMER0_A1 : { * ( .int08 ) } > INT08 type = VECT_INIT
TIMER0_A0 : { * ( .int09 ) } > INT09 type = VECT_INIT
WDT : { * ( .int10 ) } > INT10 type = VECT_INIT
COMPARATORA : { * ( .int11 ) } > INT11 type = VECT_INIT
TIMER1_A1 : { * ( .int12 ) } > INT12 type = VECT_INIT
TIMER1_A0 : { * ( .int13 ) } > INT13 type = VECT_INIT
NMI : { * ( .int14 ) } > INT14 type = VECT_INIT
.reset : {} > RESET /* MSP430 Reset vector */
}
/****************************************************************************/
/****************************************************************************/
-l msp430g2553.cmd
Modified source code:
//******************************************************************************
// MSP430G2xx3 Demo - Flash In-System Programming, Copy SegC to SegD
//
// Description: This program first erases flash seg C, then it increments all
// values in seg C, then it erases seg D, then copies seg C to seg D.
// Assumed MCLK 771kHz - 1428kHz.
// //* Set Breakpoint on NOP in the Mainloop to avoid Stressing Flash *//
//
// MSP430G2xx3
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
//
// D. Dang
// Texas Instruments Inc.
// December 2010
// Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include <msp430.h>
char value; // 8-bit value to write to segment A
volatile char myTemp = 0;
// Function prototypes
void write_SegC (char value);
char copy_C2D (void);
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator
value = 0; // initialize value
while(1) // Repeat forever
{
write_SegC(value++); // Write segment C, increment value
myTemp = copy_C2D(); // Copy segment C to D
__no_operation(); // SET BREAKPOINT HERE
}
}
void write_SegC (char value)
{
char *Flash_ptr; // Flash pointer
unsigned int i;
Flash_ptr = (char *) 0x1100; // 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<64; i++)
{
*Flash_ptr++ = value; // Write value to flash
}
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCK; // Set LOCK bit
}
char copy_C2D (void)
{
char *Flash_ptrC; // Segment C pointer
char *Flash_ptrD; // Segment D pointer
unsigned int i;
char temp;
Flash_ptrC = (char *) 0x1100; // Initialize Flash segment C pointer
Flash_ptrD = (char *) 0x1000; // Initialize Flash segment D pointer
FCTL1 = FWKEY + ERASE; // Set Erase bit
FCTL3 = FWKEY; // Clear Lock bit
*Flash_ptrD = 0; // Dummy write to erase Flash segment D
FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
for (i=0; i<64; i++)
{
*Flash_ptrD++ = *Flash_ptrC++; // copy value segment C to segment D
}
temp = *Flash_ptrD--;
FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY + LOCK; // Set LOCK bit