EEPROM fails after writing 255 times

cron-dk
Fri Jun 02, 2017 7:34 am
Hi,

I am trying to write a large block in an EEPROM page. But it seems to fail after 255 times of writes.
This small POC code demonstrates the problem:
void setup() {
EEPROM.PageBase0 = 0x801F000;
EEPROM.PageBase1 = 0x801F800;
EEPROM.PageSize = 0x400;
EEPROM.init();
EEPROM.format();
uint16 result;

delay(10000);
for (uint16 addr = 100; addr<400; addr++) {
Serial.println( addr );
do {
result = EEPROM.write( addr, random(65535) );
if ( result != 0 ) {
Serial.println( "FAIL!" );
delay( 2000 );
EEPROM.init();
}
} while ( result !=0 );
}
}


Pito
Fri Jun 02, 2017 10:40 am
What stm32 chip do you use? There are 2 page sizes based on the chip used.

cron-dk
Fri Jun 02, 2017 2:33 pm
STM32F103C8T6

Pito
Fri Jun 02, 2017 3:41 pm
C8T6 is only 64kB flash officially :)

rmdMoba
Fri Jun 02, 2017 4:28 pm
If you have a page size of 0x400, that means 1kbyte or 256 32bit-words. Each 32bit-word emulates ONE EEPROM-Cell and contains a 16bit address and 16 bit data. One word is reserved for management purposes, so you can store 255 values.
Regards, Franz

cron-dk
Fri Jun 02, 2017 7:59 pm
Thanks, that makes sense :)

Is there any way of knowing where to find free banks? Is there a certain place where the bootloader goes, a certain place for the main program? When I try to write to continous number of pages above page 100 in a bigger sketch, I fail writing to some pages. Is the main program really scattered all over the memory pages?

Best regards,
Alex


rmdMoba
Fri Jun 02, 2017 8:37 pm
cron-dk wrote:Is the main program really scattered all over the memory pages?

cron-dk
Sat Jun 03, 2017 9:25 am
It sounds fair that it is linear. I am using the stm32duino bootloader, so I guess that would start at address 0x08000000?
What about the code I upload via the bootloader, where will that go? right after?

Best regards,
Alex


rmdMoba
Sat Jun 03, 2017 10:07 am
cron-dk wrote: I am using the stm32duino bootloader, so I guess that would start at address 0x08000000?

cron-dk
Sat Jun 03, 2017 9:20 pm
Hi again,

I have been scratching my head a lot, I finally figured out that a page needs to be formatted before new data is written. Is that a right conclusion? In this example I first format page 60, then fill it up with one value without problem. On the next write EEPROM.write returns error code 129.

Does this have anything to do with the second page you are talking about? Here is my example:

#include "EEPROM.h"

#define PAGE_SIZE 0x400
#define MEM_START 0x8000000

void setup() {
Serial.begin(115200);
delay(10000);
formatPage( 60 );
fillPage( 60, 0x1111 );
fillPage( 60, 0x9999 ); // Second write fails
}

void loop() {
}

void fillPage( uint8 page, uint16 writeValue ) {
uint16 result;
uint16 readValue;

EEPROM.PageBase0 = MEM_START + ( page * PAGE_SIZE );
EEPROM.PageSize = PAGE_SIZE;

for ( uint16 addr = 0; addr <= 254; addr++ ) {
Serial.print( "Page: " ); Serial.print( page );
Serial.print( ", Addr: " ); Serial.print( addr );
Serial.print( ", Value: " ); Serial.print( writeValue, HEX );

result = EEPROM.write( addr, writeValue );
if ( result != 0 ) {
Serial.print( ", ERROR number: " ); Serial.println( result );
} else {
result = EEPROM.read( addr, &readValue );
if ( readValue != writeValue ) {
Serial.println( ", Read Back ERROR" );
} else Serial.println( ", OK" );
}
}
}

void formatPage( uint8_t page ) {
EEPROM.PageBase0 = MEM_START + page * PAGE_SIZE;
EEPROM.PageSize = PAGE_SIZE;
EEPROM.format();
} :twisted:


RogerClark
Sat Jun 03, 2017 11:02 pm
This is a common problem, with most MCUs which only have Flash for data storage.

There are a number of different strategies to work around the limitations of Flash memory, i.e you need to erase the whole page, just to write one byte, and have limited erase cycles.

I’m sure there is code for this for other MCUs that you could adapt. e.g the Nordic nRF51 / nRF52 SDK has library that somehow achieves it.

Also, as previously stated, the bootloader sits at 0x800000, then the sketch ( which is variable size) sits above this ( generally at 0x8002000).
So most people just use pages of flash from the end of the available space, and a lot if people assume the F103C8 has 128k even though it is sold as 64K.
Or just buy a Maple mini which is guaranteed to have 128k


cron-dk
Sun Jun 04, 2017 7:45 am
Ok, I think i figured it out… found this good implementation guide on emulated flash:

http://www.st.com/content/ccc/resource/ … 165693.pdf

Thanks for all the input :)

Best regards,
Alex


Leave a Reply

Your email address will not be published. Required fields are marked *