1
\$\begingroup\$

I am having some trouble writing to FLASH on the MSP430F5529. I have gone through the examples provided by TI and read through the user guides and part datasheet, but have been unable to find the problem. My goal is to save the baud rate enumeration in FLASH and look it up on boot. Applicable code is below:

static const uint32_t baudRegister = 0x1980;  // Baud rate register flash location (Info A)

//Change baud rate
void changeBaud(uint8_t baudEnum) {
    eraseSegment(baudRegister);               // Erase flash segment
    writeFlashByte(baudRegister, baudEnum);   // Write baud enumeration to FLASH
    WDTCTL = 0;                               // Force uC reset
}

//Erase flash segment
void eraseSegment(uint32_t address) {
    int8_t *flash_ptr = (int8_t *)address;

    __bic_SR_register(GIE);                   // Disable interrupts

    FCTL3 = FWKEY;                            // Unlock FLASH control regs
    FCTL1 = FWKEY + ERASE;                    // Select segment erase
    *flash_ptr = 0;                           // Dummy erase byte
    FCTL3 = FWKEY + LOCK;                     // Lock FLASH control regs

    __bits_SR_register(GIE);                  // Re-enable interrupts
}

//Write byte to FLASH
void writeFlashByte(uint32_t address, uint8_t data) {
    uint8_t *ptr = (uint8_t *)address;

    __bic_SR_register(GIE);                   // Disable interrupts

    FCTL3 = FWKEY;                            // Unlock FLASH control regs
    FCTL1 = FWKEY + WRT;                      // Enable writing of segment
    *ptr = data;
    FCTL1 = FWKEY;  
    FCTL3 = FWKEY + LOCK;                     // Lock FLASH control regs

    __bis_SR_register(GIE);                   // Re-enable interrupts
}

changeBaud() is called from within main(), and it is passed an enumeration for the baud rate (example: 1 = 300bps, 2 = 600bps, ... 6 = 9600bps, 7 = 14400bps, etc).

When I run eraseSegment() the contents of the FLASH at address 0x1980 remain as 0xFFFF. I think this is expected (0xFFFF means cleared). However, when I run writeFlashByte() when I get to the line *ptr = data; it does not seem to do anything. While debugging I have confirmed that data has the correct enumeration value and ptr is the correct address, but for some reason writing data to *ptr does not load the memory with the value of data.

I am quite new to writing data to flash, so this one has me stumped. The code above is based on TI's examples available in MSPWare.

What might cause this problem?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

To erase and write to the Information memory, you have to clear the LOCKINFO bit in the FCTL4 register. This bit is usually cleared on reset already, but it doesn't hurt to check.

But information memory A is different (and 0x1980 is in that range). It has another lock bit LOCKA in FCTL3. This is set on reset and prevents erasing and writing to information memory A.

To clear that bit you have to write a 1 to it (counter intuitive).

I would suggest you use a different information memory location, as information memory A holds some calibration values from TI which you probably don't want to erase (if my memory serves me right, it's been a few years).

\$\endgroup\$
1
  • \$\begingroup\$ Right on the money. Switched to address 0x1880 (Info C) and it worked right off the bat. Many thanks! \$\endgroup\$
    – DerStrom8
    Commented Oct 23, 2018 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.