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.

CCS/MSP430I2041: How to erase flash memory

Part Number: MSP430I2041

Tool/software: Code Composer Studio

Hello you,

I have problem with my project, i need save information to flash. but i can not erase. this is my code:

void write_InfoSeg(char value) {
unsigned char *Flash_ptr; // Flash pointer
unsigned int i;

__disable_interrupt();


Flash_ptr = (unsigned char *)SEGSTART; // Initialize Flash pointer
if(FCTL3 & LOCKSEG) { // If Info Seg is stil locked
FCTL3 = FWKEY | LOCKSEG; // Clear LOCKSEG bit
}

while(BUSY & FCTL3);
FCTL3 = FWKEY; // Clear Lock bit
FCTL1 = FWKEY+ERASE; // Set Erase bit
while ((FCTL3 & BUSY) == BUSY);


FCTL1 = FWKEY | WRT; // Set WRT bit for write operation

for (i = 0; i < SEG_LEN; i++) {
*Flash_ptr++ = value; // Write value to flash
}

FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY | LOCKSEG; // Set LOCKSEG bit

__enable_interrupt();
}

Thanks

  • Hello,

    In future threads, please post code using the Syntaxhighlighter. Its icon is shown below for your reference.

    First, does "SEGSTART" point to INFO or MAIN flash memory? If it's pointing to INFO and you're trying to erase this segment, please be sure to back it up in RAM first before erasing it to preserve the device-specific TLV values found in INFO memory. Otherwise, if this data gets erased, the device will probably not work correctly and could be bricked on the next start-up. If you have enough MAIN memory, you may want to use a segment there instead of INFO to make things easier and more robust (even if INFO is backed up to RAM, there's a small chance that a power failure could occur before everything gets written back from RAM to INFO which would brick the device).

    Next, I don't see where you're configuring the Flash Controller clock source and divider. This is very important to ensure that the frequency is within the recommended range. Here's an example.

    /* Configure the Flash Controller clock source and divider */
    /*  Divide clock source by 1 to 64 using FN0 to FN5 according to: */
    /*  32*FN5 + 16*FN4 + 8*FN3 + 4*FN2 + 2*FN1 + FN0 + 1 */
    FCTL2 = FWKEY | FSSEL_1 | FN5 | FN1; // Password, MCLK, divide by 35

    In the following portion of your code, you're checking if the segment is locked but then setting (not clearing) the LOCK bit again if it is. I would remove the last two lines since you're manually clearing the LOCK bit later anyway.

    Flash_ptr = (unsigned char *)SEGSTART; // Initialize Flash pointer
    if(FCTL3 & LOCKSEG) { // If Info Seg is stil locked
    FCTL3 = FWKEY | LOCKSEG; // Clear LOCKSEG bit
    }

    Here, you're clearing the LOCK bit and then setting the ERASE bit which are good steps. However, you're not performing the dummy write which is why the erase is not happening. According to Section 5.3.2 in the MSP430i20xx User's Guide, "any erase is initiated by a dummy write into the address range to be erased. The dummy write starts the flash timing generator and the erase operation".

    while(BUSY & FCTL3);
    FCTL3 = FWKEY; // Clear Lock bit
    FCTL1 = FWKEY+ERASE; // Set Erase bit
    while ((FCTL3 & BUSY) == BUSY);
    
    
    FCTL1 = FWKEY | WRT; // Set WRT bit for write operation
    
    for (i = 0; i < SEG_LEN; i++) {
    *Flash_ptr++ = value; // Write value to flash
    }
    
    FCTL1 = FWKEY; // Clear WRT bit
    FCTL3 = FWKEY | LOCKSEG; // Set LOCKSEG bit

    Another helpful resource is the MSP430 Flash Memory Characteristics app note. Hope this helps!

    Regards,

    James

  • Thank you,

    But when I run this code after thi msp430i2041 is not working and i can not debug it

    Code: I had configuring the Flash Controller clock source and divider:  FCTL2 = FWKEY | FSSEL_1 | FN1 | FN3 | FN5; and use dumy data same bellow code

    void write_InfoSeg(void) {
        unsigned char *Flash_ptr;                   // Flash pointer
    
        __disable_interrupt();
    
        //------------------------------------------------------------------------------
        Flash_ptr = (unsigned char *)SEGSTART;      // Initialize Flash pointer
    
        //------------------------------------------------------------------------------
        if(FCTL3 & LOCKSEG) {                       // If Info Seg is stil locked
            FCTL3 = FWKEY | LOCKSEG;                // Clear LOCKSEG bit
        }
    
        //------------------------------------------------------------------------------
        while(BUSY & FCTL3);
        Flash_ptr = (unsigned char *)SEGSTART;      // Initialize Flash pointer
        FCTL1 = FWKEY + ERASE;                      // Set Erase bit
        FCTL3 = FWKEY;                              // Clear Lock bit
        *Flash_ptr = 0;                             // Dummy write to erase Flash
        // segment
        while ((FCTL3 & BUSY) == BUSY);
    
        FCTL1 = FWKEY | WRT;                        // Set WRT bit for write operation
    
        *Flash_ptr++ = (A1>> 8) & 0xFF;
        *Flash_ptr++ = (A1>> 0) & 0xFF;
    
        *Flash_ptr++ = (A2>> 8) & 0xFF;
        *Flash_ptr++ = (A2>> 0) & 0xFF;
    
        *Flash_ptr++ = (A3>> 8) & 0xFF;
        *Flash_ptr++ = (A3>> 0) & 0xFF;
    
        //    for (i = 0; i < SEG_LEN; i++) {
        //        *Flash_ptr++ = value;                   // Write value to flash
        //    }
    
        FCTL1 = FWKEY;                              // Clear WRT bit
        FCTL3 = FWKEY | LOCKSEG;                    // Set LOCKSEG bit
    
        //------------------------------------------------------------------------------
        __enable_interrupt();
    }

**Attention** This is a public forum