cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F415xx flash self write issue

Emiliano Fusari
Associate II
Posted on March 01, 2017 at 16:55

I'm developing a firmware for a custom board based on a STM32F415xx microcontroller.

The application must read a file from the on-board SD card, parse it and save some data into the microcontroller flash.

This is working fine only the first time I write the firmware on the microcontroller.

Starting from next time it doesn't work anymore, because a few (about 20) stored values are different than the expected ones. The wrong values are always at the same addresses. If I try to move the base address but the behavior is exactly the same.

If, for example, I try to write value 0x4D I read back 0x49.

Obviously the sector I'm using doesn't contains the firmware data.

I'm using FLASH_ProgramByte in order to store the data and I erase the sectors before the write operation. The erase function is working because I checked the flash and it is filled with 0xFF. I'm also sure that the file parsing function works because the first time everything is fine.

Any idea?

7 REPLIES 7
Posted on March 01, 2017 at 16:59

Show the code that is doing the erasing and writing. Add diagnostic output so you can confirm each step, and that the data is blank prior to writing.

Make sure any pending error/status is cleared prior to starting, and ideally do this all without the interference of the debugger.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Emiliano Fusari
Associate II
Posted on March 01, 2017 at 17:24

Hi Clive,

This is the piece of code I use to erase the flash:

#define NUM_SECTORS    7

static uint16_t sector[NUM_SECTORS] = {

        FLASH_Sector_5, FLASH_Sector_6, FLASH_Sector_7, FLASH_Sector_8, FLASH_Sector_9, FLASH_Sector_10, FLASH_Sector_11

};

static boolean performEraseFlash()

{

    int i;

    FLASH_Status status;

    FLASH_Unlock();

    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);

    for (i = 0; i < NUM_SECTORS; i++)

    {

        status = FLASH_EraseSector(sector[i], VoltageRange_3);

        if (status != FLASH_COMPLETE)

        {

            FLASH_Lock();

            return FALSE;

        }

    }

    FLASH_Lock();

    return TRUE;

}

Then, in my write loop I unlock the flash again using:

FLASH_Unlock();

FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGAERR | FLASH_FLAG_WRPERR);

I tried also to don't lock and unlock the flash but it doesn't work anyway.

The write loop is:

                    wr_address = base_address + (uint32_t)data.address;

                    for (j = 0; j < data.size; j++)

                    {

                        status = FLASH_ProgramByte(wr_address, data.buffer[j]);

                        if (status != FLASH_COMPLETE)

                        {

#ifdef     DEBUG_FILE

                            debugDataSize += sprintf(&debugData[debugDataSize], '--- [%02X] ERROR1! ---', data.buffer[j]);

                            SDCard_WriteData(&dbgFile, debugData, debugDataSize);

                            SDCard_FileClose(&dbgFile);

#endif

                            FLASH_Lock();

                            return FALSE;

                        }

                        val = *(__IO uint8_t *)(wr_address);

                        if (val != data.buffer[j])

                        {

#ifdef     DEBUG_FILE

                            debugDataSize += sprintf(&debugData[debugDataSize], '--- [%02X] ERROR2! ---', data.buffer[j]);

                            SDCard_WriteData(&dbgFile, debugData, debugDataSize);

                            SDCard_FileClose(&dbgFile);

#endif

                            FLASH_Lock();

                            return FALSE;

                        }

                        wr_address++;

                    }

I got an ERROR2 into the resulting debug code...

I tried to use the debugger but obviosuly everything works perfectly in this case.

Emiliano Fusari
Associate II
Posted on March 01, 2017 at 18:00

I've already logged the addresses and data before and after FLASH_ProgramByte and there isn't anything wrong with them. This is making me crazy!

I'll try to check if the value is equal to 0xFF before the write operation as you suggested.

Posted on March 01, 2017 at 17:40

Make sure *(__IO uint8_t *)(wr_address) == 0xFF before trying the write.

Log the write address and data written/read for all the successful operations prior to the failing one. A USART might be a better destination, or the SWV if you are not single-stepping the code, or sitting a debug view over the flash controller. Provide complete log, show erase, and dump memory region before/after.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on March 01, 2017 at 18:18

I tend to write flash as aligned 32-bit data, it is faster and more efficient

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Emiliano Fusari
Associate II
Posted on March 02, 2017 at 13:57

Ok, I tried with 32-bits aligned data but the problem was still there.

Anyway, I re-checked the flash before writing it and I discovered that the portion of flash I was using wasn't completely cleared, actually.

Moving the user flash section start at the begin of the next free sector solved the problem. I tried many times and averything works perfectly now.

Clive, thanks for your support!

Posted on March 02, 2017 at 14:09

You are welcome.

We tend to carve out space so some of the small 16KB sectors are available for configuration and calibration data, as these are faster to erase than the 128KB ones.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..