cancel
Showing results for 
Search instead for 
Did you mean: 

Flash is corrupting after a couple of immediate resets

io517
Associate
Posted on March 23, 2014 at 20:11

I want to store Device ID inside the flash permanently. So I am using internal Flash of STM I can write&read to Flash in STM After writing the value to the flash, and switch off and then I can read it without any problem. But the problem is coming a couple of different scenario such as : When I am resetting MCU immidieatly after first reset, Data inside flash is becoming 0. The other scenario is could be the data is disappearing after a while (not tested and can not get entire conditions) Any idea about this flash problem ?

IDE : Keil MDK uVision 4

Write Function:

void
EEPROM_Write(uint32_t Data)
{
/* Porgram FLASH Bank1 ********************************************************/
FLASH_UnlockBank1(); 
/* Unlock the Flash Bank1 Program Erase controller */
NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE; 
/* Define the number of page to be erased */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); 
/* Clear All pending flags */
for
(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) 
/* Erase the FLASH pages */
{
FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));
}
Address = BANK1_WRITE_START_ADDR; 
/* Program Flash Bank1 */
while
((Address < BANK1_WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE))
{
FLASHStatus = FLASH_ProgramWord(Address, Data);
Address = Address + 4;
}
FLASH_LockBank1(); 
Address = BANK1_WRITE_START_ADDR; 
/* Check the corectness of written data */
while
((Address < BANK1_WRITE_END_ADDR) && (MemoryProgramStatus != FAILED))
{
if
((*(__IO uint32_t*) Address) != Data)
{
MemoryProgramStatus = FAILED;
}
Address += 4;
}
}

Read Function

uint32_t EEPROM_Read(
void
)
{
uint32_t readValue;
FLASH_UnlockBank1();
Address = BANK1_WRITE_START_ADDR;
readValue = (*(__IO uint32_t*) Address);
FLASH_LockBank1(); 
return
readValue;
}

#flash #stm32vldiscovery #stm32vldiscovery #stm32-flash
5 REPLIES 5
Posted on March 23, 2014 at 22:10

Which STM32? They make like dozens of different ones.

What type of reset circuit are you using? An R-C network?

Could you use OTP areas for a serial number? The devices also have a 96-bit Unique ID

What are the defines for your memory region? Can you compute the number of blocks in a manner that won't fail with partial blocks?

Do you detect any errors during write or verify phases?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
io517
Associate
Posted on March 25, 2014 at 01:05

Hi clive1,

First of all, you are great man in this forum and I realized that you have solved a number of problems so far. Thank you so much. I will try to respond all of your questions as much as I can do :

The used MCU : STM32F100C8 (very similar to the MCU on stm32vldiscovery board apart from flash size)

I am forcing to system very simple reset scenario means power on and off fast.Therefore, as soon as I switch the circuit I am switching it off back and so on. 

The Serial number means in my project, each device should take adjustable and changeable ID by user during the run time. Therefore, I cannot use the device id which is inside the MCU. But thanks for your suggestion.

On the other hand, I am not checking entire errors during writing/reading phases. However, after I write the data to flash, I am reading it correctly also if switch it off and switch it on, the value is still inside the given address of flash and I can read it correctly.

The problem is coming, if the system waits too much or switch on/off power very frequently and a number of times.

Also : 

IROM 1 (default) : 0x8000000 0x400 (startup)

 

IROM 2 (default) : 0x8003000 0xCC00

IRAM 1 (default) : 0x20000000 0x2000

--------------from eeprom.h

#define BANK1_WRITE_START_ADDR  ((uint32_t)0x08000400)

#define BANK1_WRITE_END_ADDR    ((uint32_t)0x08003000)

atarimaxipad
Associate II
Posted on March 25, 2014 at 02:12

Replace the flash write and flash erase calls with calls to functions that will stop the CPU and just blink an LED forever.  Then repeat your power fail testing.

If your LED suddenly starts blinking, your CPU may be entering the write/erase blocks without you expecting it due to a changed program counter or run away execution at another address that leads to this function.

If that is the case you should guard all accesses to these functions and/or modify the functions themselves so they can only do destructive operations when called with specific 'magic' operands in specific registers.

chen
Associate II
Posted on March 25, 2014 at 18:32

Hi

I have this problem. Have not found a solution to it.

I think it is because the processor is back powered by the ST-Link (or any other thing that may be plugged in eg USB, RS232/MAX232)

Somehow, this back powering (parasitic power) causes the STM32 internal to be erased.

I have found that this problem does not happen when the ST-Link is not plugged in when re-powering the STM32

Posted on March 25, 2014 at 21:39

I think you should use a power-on-reset circuit that ensures the NRESET line is clammed low for several milli-seconds, and not rely on the supply decaying and rising to do it reliably.

I have not encountered the STM32 corrupting or losing flash content.

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