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.

Do I need to erase the segment before writing to flash?

Other Parts Discussed in Thread: MSP430F47183

I have code that erases Segment A, and then writes 8 bytes to it.  This works like a charm every time.  

However, soon as I comment out the erase segment code, it does not write to the flash.  It runs through all the code to do the write, but I don't see the flash memory change at all, whereas I do with the previous method.  I am running an MSP430F47183 at 16 MHz.  

The following are my two functions.  I call SegmentErase first, and then FlashWrite right after it.

void SegmentErase(InfoSegments whichSeg)
{
char* flashPtr = SEG_ADDR[whichSeg];// Set flash pointer to segment

WDTCTL = WDTPW | WDT_ARST_1000 | WDTCNTCL;
while(BUSY & FCTL3) // Wait for busy to clear before accessing flash registers, encapsulated in WDT timer.
;
WDTCTL = WDTPW | WDTHOLD;

FCTL2 = FWKEY | FSSEL_1 | 0x2F; // MCLK/48 for Flash Timing Generator = 333.3 kHz
FCTL3 = FWKEY | LOCKA; // Clear lock bit, must write a 1 to LOCKA to change state, writing 0 has no effect.
FCTL1 = FWKEY | ERASE | EEI; // Set Erase bit, allow interrupts

*flashPtr = 0; // Dummy write to erase Flash seg, this should do the erase.

WDTCTL = WDTPW | WDT_ARST_1000 | WDTCNTCL;
while(BUSY & FCTL3)
;
WDTCTL = WDTPW | WDTHOLD;

FCTL1 = FWKEY; // Clear erase bits
FCTL3 = FWKEY | LOCKA | LOCK; // Set locks on
}

int FlashWrite(char* addr, char* buffer, char len)
{
char* flashPtr = addr;

WDTCTL = WDTPW | WDT_ARST_1000 | WDTCNTCL;
while(BUSY & FCTL3)
;
WDTCTL = WDTPW | WDTHOLD;

FCTL2 = FWKEY | FSSEL_1 | 0x2F; // MCLK/48 for Flash Timing Generator = 333.3 kHz
FCTL3 = FWKEY | LOCKA; // Clear lock bit, must write a 1 to LOCKA to change state, writing 0 has no effect.
FCTL1 = FWKEY | WRT; // Set WRT

int i;
for (i = 0; i <= len; i++)
{
*flashPtr++ = *buffer++; // Write buffer
}

WDTCTL = WDTPW | WDT_ARST_1000 | WDTCNTCL;
while(BUSY & FCTL3)
;
WDTCTL = WDTPW | WDTHOLD;

FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY | LOCKA | LOCK; // Set locks on

return 1;
}
  • Yes, you need to erase the flash segment before writing to the same locations in memory.

  • Hi,

    you will need to erase the flash segment when you want to write at the same location. This is because when you ease the segment all bit in it will be set to a logical one and all bytes read 0xFF. When writing you set some of the bits to zero and lead to the value you want. So when you need to write entire bytes or words at the same location you need the erase when one bit in those need setting to one again.

    But at locations which are not written already or to simple set some bits to zero you can do this without the need to erase the entire segment - I use this for saving some states which change quite often to spare erase cycles which wear out the flash memory. So I only need to erase the segment every 16 writes (in my case when using bytes). Remember when using such method there is also a "cummulative write time" which should not be exceeded with time spend writing between two erase cycles.

  • Jan Kesten said:
    at locations which are not written already or to simple set some bits to zero you can do this without the need to erase the entire segment

    That's right. But
    Jan Kesten said:
    Remember when using such method there is also a "cummulative write time" which should not be exceeded
    "must not" is the proper wording here.
    And it puts the proposed incremental write to limited use.
    Each individual write operation (byte or word write) exposes a 64 byte flash block to programming voltage for a certain time (see datasheet). The maximum time is limited, above teh flash tends to show 0 bits where they were never programmed. (an erase will correct this).
    On older MSPs (1x series, and maybe 2x too), it was outside the specs to do 64 byte writes on a 64 byte block. Word writes were required (if not using block write mdoe at all).
    IIRC, the maximum was 53 write operations on a 64 byte block.
    I discovered this when thinking of a progressive marking (clear on bit after another, thus overwriting each byte up to 8  times). On 5x family, this has relaxed a bit, but still you can overwrite each byte only two or three times.

**Attention** This is a public forum