EEPROM fails after writing 255 times

cron-dk
Posts: 6
Joined: Thu Jun 01, 2017 10:43 am

EEPROM fails after writing 255 times

Post by 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:

Code: Select all

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 );
  }
}
It should write to all address locations from address 100 to 400, but it fails at address 355. Am i doing something wrong here? As far as I understant I should be able to write 512 uint16 to one bank?

Best regards,
Alex Jensen

User avatar
Pito
Posts: 1522
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: EEPROM fails after writing 255 times

Post by Pito » Fri Jun 02, 2017 10:40 am

What stm32 chip do you use? There are 2 page sizes based on the chip used.
Pukao Hats Cleaning Services Ltd.

cron-dk
Posts: 6
Joined: Thu Jun 01, 2017 10:43 am

Re: EEPROM fails after writing 255 times

Post by cron-dk » Fri Jun 02, 2017 2:33 pm

STM32F103C8T6

User avatar
Pito
Posts: 1522
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: EEPROM fails after writing 255 times

Post by Pito » Fri Jun 02, 2017 3:41 pm

C8T6 is only 64kB flash officially :)
Pukao Hats Cleaning Services Ltd.

rmdMoba
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: EEPROM fails after writing 255 times

Post by 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
Posts: 6
Joined: Thu Jun 01, 2017 10:43 am

Re: EEPROM fails after writing 255 times

Post by 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
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: EEPROM fails after writing 255 times

Post by rmdMoba » Fri Jun 02, 2017 8:37 pm

cron-dk wrote:Is the main program really scattered all over the memory pages?
I don't think so. When I use the integrated serial bootloader, it tells me which adresses it writes to. And this is a contiguous block from the beginning of the flash.

Code: Select all

Wrote address 0x08000100 (0.82%) 
Wrote address 0x08000200 (1.63%) 
Wrote address 0x08000300 (2.45%) 
Wrote address 0x08000400 (3.26%) 
....
Wrote address 0x08007800 (97.91%) 
Wrote address 0x08007900 (98.73%) 
Wrote address 0x08007a00 (99.54%) 
Wrote address 0x08007a90 (100.00%) Done.
The size of the program that the compiler tells corresponds exactly to the last written address.

cron-dk
Posts: 6
Joined: Thu Jun 01, 2017 10:43 am

Re: EEPROM fails after writing 255 times

Post by 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
Posts: 16
Joined: Thu May 11, 2017 10:44 am

Re: EEPROM fails after writing 255 times

Post by 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?
I never used that bootloader, but afaik the code starts directly after the bootloader.
cron-dk wrote:When I try to write to continous number of pages above page 100 in a bigger sketch, I fail writing to some pages.
I don't really understand what you mean with this. The EEPROM library is designed to use only one page at a time. There are two pages to enhance the endurance. They are used alternatively, so in fact you need twice the space for your data. To emulate 255 EEPROM Cells, you need 2kbytes of flash. If you want to store more data, you must increase the pagesize. Usually these pages reside at the end of the available flash. But in the library there seems to be a problem to determine the flash size resp. the type of chip used.

Here you can read how the EEPROM emulation works.
If you really have to write a lot of data, maybe its better to use an external EEPROM.

cron-dk
Posts: 6
Joined: Thu Jun 01, 2017 10:43 am

Re: EEPROM fails after writing 255 times

Post by 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:

Code: Select all

#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: 

Code: Select all

....
Page: 60, Addr: 251, Value: 1111, OK
Page: 60, Addr: 252, Value: 1111, OK
Page: 60, Addr: 253, Value: 1111, OK
Page: 60, Addr: 254, Value: 1111, OK
Page: 60, Addr: 0, Value: 9999, ERROR number: 129
Page: 60, Addr: 1, Value: 9999, ERROR number: 129
Page: 60, Addr: 2, Value: 9999, ERROR number: 129
Page: 60, Addr: 3, Value: 9999, ERROR number: 129
...
I would like store as much as possible without external eeprom, if possible. I want to build a class that takes a "virtual linear" address and converts it to a bank and an address... I have the code in place, all I need is to understand how the eeprom works.

Best regards,
Alex

Post Reply