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.

MSP430F5510 flash read corruption

Other Parts Discussed in Thread: MSP430F5510, MSP430F2272

Hi,

I'm currently developing a software for the MSP430F5510. It worked fine with my development PCB for months, but as soon as I tried it on another one, I got very strange issues. My software is writing text to a display with a built-in font, and I'd sometimes get missing pixels, or the text "dEbug" or "debuf" instead of "debug".

I then simplified my code until I arrived at this:

#include <msp430.h>
#include <string.h>
#include "driverlib/MSP430F5xx_6xx/ucs.h"

static const uint16_t flash_data[] = {
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static volatile uint16_t ram_data[] = {
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};

void main(void)
{
    volatile uint32_t cnt = 0;
    static const uint32_t mclk = 25000000;

    WDTCTL = WDTPW | WDTHOLD;

    UCS_clockSignalInit(UCS_FLLREF, UCS_REFOCLK_SELECT, UCS_CLOCK_DIVIDER_1);
    UCS_initFLLSettle(mclk/1000, mclk/32768);

    while (1) {
        if (memcmp(&flash_data, (void*)&ram_data, sizeof(flash_data)) != 0) {
            _op_code(0x4343); # Software breakpoint
        }
        cnt++;
    }
}

My code sometimes stops on the software breakpoint, so it seems sometimes the flash gets read incorrectly. Most of the times this happens very soon after the program starts (cnt <= 50), but sometimes it takes a lot longer (cnt = some millions). Then after the next reset it immediately happens again.

Some observations I made so far:

  • It does not seem to happen when the clock is 24MHz instead of 25MHz
  • It does not seem to happen on 2 of 4 prints I tested
  • When I use single values rather than arrays, it happens more seldom. If I use != instead of memcmp to compare them, it doesn't seem to happen (maybe it gets optimized away though?).
  • Optimisation level doesn't seem to make a difference
  • Inserting an ~1s delay before and after setting the clock doesn't make a difference
  • It seems it's always an 1 bit read as 0, i.e. I can't reproduce it if the data is 0x00 instead of 0xFF

CCSv5 project with the above minimal example: 3326.corruption_test.zip

The related parts of the schematics and layout look like this:

The supply voltage looks good for both unaffected and affected prints.

Good:

Bad:

I've seen TIs document about the flash corruption issue (slaa471), but they mention the MSP430F5510 is unaffected, and the kind of corruption doesn't seem to be the one I'm seeing.

I've also not seen anything related in the errata (slaz301j), except "Corrupted flash read when SVM low-side flag is triggered" which doesn't seem to be my issue. The chip revision is C, for both affected and unaffected prints.

Any help would be appreciated, I really have no idea what to try anymore. Thanks!

  • Hi Florian,

    I noticed something critical missing from your code - you never raised the Core Voltage level (Vcore) of the device before setting it to 25MHz. This is a really easy thing to miss, especially if you haven't used one of our F5xx/6xx series devices before.

    As you can see in the datasheet www.ti.com/lit/gpn/msp430f5510 under recommended operating conditions on p. 48, for 25MHz operation you must set the Vcore level to 3. So basically this code is running your core way out of spec because it's trying to run 25MHz at the lowest Vcore level 0 right now - this would definitely explain getting some weird and unpredictable behavior. When running parts out of spec like this, the operation is not guaranteed and device variation may cause some to fail and some to be relatively ok which would explain the variation in the behavior you are seeing amongst devices (in addition to this type of error having fairly unpredictable failure modes).

    It looks like you are using driverlib, and fortunately there's an easy one-line API you can add to fix this:

        //Set VCore = 3 for 25MHz clock
        PMM_setVCore(PMM_CORE_LEVEL_3);

    Simply put this line before you call UCS_initFLLSettle(). You can look at the driverlib example ucs_ex1_DCO12MHz for an example - you'll find this API right at the top of the code after disabling the watchdog.

    Hopefully after adding this your issue will disappear!

    -Katie

  • Hi Katie,

    oh wow!

    When I originally ported this from the msp430f2272 I did things manually instead of using the driverlib (I wasn't aware it existed, as it doesn't for the f2272). There I did increment Vcore, so I'm aware of having to do that.

    However I took this code out when I switched to the driverlib. I guess I must have assumed the call to UCS_initFLLSettle does this for me automatically.

    As expected, the issues went away after fixing that. It's mind-blowing how I didn't have any problems on the device I developed with, with 25 instead of a maximum of 8 MHz.

    Thanks!

    Florian

  • Florian - I'm so glad I was able to help!

    Do you think there's something that we could do better in our driverlib documentation to help make that PMM_setVCore API more obvious or easier for other people to find? Maybe we should put a note in the descriptions of functions like UCS_initFLLSettle that you might need to set the Vcore level first and point to the other API? Just trying to see how we can prevent others running into the same thing - I have a feeling that if you thought initFLLSettle already did this, that others have thought the same before as well.

    -Katie

  • That would've helped in my case indeed. At some point I suspected I called initFLLSettle wrong somehow and read its documentation again.
  • Katie, one thing that could be done is to add another (Boolean) parameter to UCS_initFLLSettle that tells whether to adjust Vcore. If true, the function could determine the target frequency and current frequency and add a call to PMM_setVCore before or after target frequency has been reached.
    If such a parameter exists, people will think about it. And read the documentation if they do not understand. Without it, people might make false assumptions about the functionality of the FLL_settle function, and maybe not read the documentation at all.

**Attention** This is a public forum