Teensy 4.0 and EEPROM.h problem

casting will result in correct operations & results - not backing up is even better !

I have nailed down one culprit: the calculation of the EEPROM address whenever a "backup" is done is temporarily converted/promoted to a result with more bits than the "uint16_t" requires (to allow for rollover) as follows:

Code:
  _adr_EEPROM = (_adr_EEPROM - 1) % EEPROMsiz;

If/when "_adr_EEPROM" happens to be "0", the result of subtracting "1" is an intermediate value of "-1". Without immediately casting that intermediate result to "uint16_t", the results are not as expected. The following change to every "backup" calculation allows for correct results in all cases:

Code:
  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;

Now, the *REAL* question is thus: why backup at all ?? Why not just start writing after the last 0xFF that was found ?? In spite of the attempted "wear-leveling" actually resulting in "wear-inducing" (as pointed out by KurtE several times), isn't the implementation of "backing up" actually double-writing some locations unnecessarily ??

Getting rid of all "backup calculations" also allows for correct results in all cases, & is actually simpler as well. Go with KISS !!

Mark J Culross
KD5RXT

Here's the current test code:

Code:
#include <EEPROM.h>
#define EEPROMsiz 1024

#define DO_READ false
#define DO_WRITE true

class StringsTointEEPROM
{
  public:
    //constructor
    StringsTointEEPROM();
    // Methods
    void format_eeprom();
    int begin();
    void save_string_to_eeprom(char *stringIn);
    void save_nstrings_to_eeprom(int nbstring, char *stringsIn[]);
    void print_strings_from_eeprom();
    int get_string_from_eeprom(char *stringOut); //return 0 if MT
    int get_nstrings_from_eeprom(int nbstring, char *stringsOut[]); //return 0 if MT
  private:
    int find_eeprom_address();
    uint16_t _adr_EEPROM;
};

StringsTointEEPROM::StringsTointEEPROM()
{
}

void  StringsTointEEPROM::format_eeprom()
{
  for (int i = 0; i < EEPROMsiz; i++) EEPROM.write(i, 0xff);
}

int StringsTointEEPROM::begin()
{
  return find_eeprom_address();
}

#define PERTINENT_DEBUG

void printDetails(uint16_t adrEEPROM, uint8_t dat, bool readWrite)
{
#ifdef PERTINENT_DEBUG
   if (adrEEPROM == 65535)
   {
#endif
      if (readWrite)  // false = DO_READ
      {
         Serial.print("WRITE: ");
      } else {
         Serial.print(" READ: ");
      }

      Serial.print(adrEEPROM / 1000);
      Serial.print((adrEEPROM / 100) % 10);
      Serial.print((adrEEPROM / 10) % 10);
      Serial.print(adrEEPROM % 10);
      Serial.print(" : ");
      Serial.println(dat);
#ifdef PERTINENT_DEBUG
   }
#endif
}

#define REMOVE_BACKUP

void StringsTointEEPROM::save_string_to_eeprom(char *stringIn)
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i;
  uint8_t len, val = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    printDetails(_adr_EEPROM, val, DO_READ);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
#ifndef REMOVE_BACKUP
  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
#endif
  EEPROM.write(_adr_EEPROM, 0xaa); //write sync
  printDetails(_adr_EEPROM, 0xaa, DO_WRITE);
  _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  len = strlen(stringIn);
  EEPROM.write(_adr_EEPROM, len); //write nchar
  printDetails(_adr_EEPROM, len, DO_WRITE);
  _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  for (i = 0; i < len; i++)
  {
    EEPROM.write(_adr_EEPROM, stringIn[i]);//write string
    printDetails(_adr_EEPROM, stringIn[i], DO_WRITE);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
  EEPROM.write(_adr_EEPROM, 0xff); //write end of string
  printDetails(_adr_EEPROM, 0xf, DO_WRITE);
}

void StringsTointEEPROM::save_nstrings_to_eeprom(int nbstring, char *stringsIn[])
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i, iter = 0;
  uint8_t len, val = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    printDetails(_adr_EEPROM, val, DO_READ);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
#ifndef REMOVE_BACKUP
  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
#endif
  while (nbstring > 0)
  {
    EEPROM.write(_adr_EEPROM, 0xaa); //write sync
    printDetails(_adr_EEPROM, 0xaa, DO_WRITE);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    len = strlen(stringsIn[iter]);
    EEPROM.write(_adr_EEPROM, len); //write nchar
    printDetails(_adr_EEPROM, len, DO_WRITE);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    for (i = 0; i < len; i++)
    {
      EEPROM.write(_adr_EEPROM, stringsIn[iter][i]);//write string
      printDetails(_adr_EEPROM, stringsIn[iter][i], DO_WRITE);
      _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    }
    nbstring--;
    iter++;
  }
  EEPROM.write(_adr_EEPROM, 0xff); //write end of string
  printDetails(_adr_EEPROM, 0xff, DO_WRITE);
}
void  StringsTointEEPROM::print_strings_from_eeprom()
{
  int i, cntr = 0;
  uint8_t len, val = 0;
  uint16_t adr_EEPROM = _adr_EEPROM;
  while (val != 0xff) //find end of latest string
  {
    val = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
  }
  while (1) //display all strings that were stored in EEPROM in FIFO order
  {
    val = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
    while (val != 0xaa) //find sync (could be long if EEPROM not full)
    {
      adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
      val = EEPROM.read(adr_EEPROM);
      printDetails(adr_EEPROM, val, DO_READ);
      cntr++;
      if (cntr == EEPROMsiz)
      {
        Serial.println("EEPROM is  MT");
        break;
      }
    }//while (val!=0xaa)
    if (cntr == EEPROMsiz) break;
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
    len = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, len, DO_READ);
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
    for (i = 0; i < len; i++)
    {
      Serial.print((char)EEPROM.read(adr_EEPROM));
       printDetails(_adr_EEPROM, (char)EEPROM.read(adr_EEPROM), DO_READ);
      adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
    }//for(i = 0; i < len; i++)
    Serial.println();
    val = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
    if (val == 0xff) break; //break if EEPROM not full or 1 full circle
    else val = 0;
  }//while(1)
}

int StringsTointEEPROM::get_string_from_eeprom(char *stringOut)
{
  //get latest string from eeprom
  int i, cntr = 0;
  uint8_t len, val = 0;
  uint16_t adr_EEPROM = _adr_EEPROM;
  while (val != 0xff) //find end of latest string
  {
    val = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
  }
#ifndef REMOVE_BACKUP
  adr_EEPROM = (uint16_t)(adr_EEPROM - 1) % EEPROMsiz;
#endif
  while (val != 0xaa) //find sync
  {
    val = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
#ifndef REMOVE_BACKUP
    adr_EEPROM = (uint16_t)(adr_EEPROM - 1) % EEPROMsiz; //back up
#endif
    cntr++;
    if (cntr == EEPROMsiz) break; //EEPROM is MT
  }//while (val!=0xaa)
  if (cntr == EEPROMsiz) return 0;
  adr_EEPROM = (adr_EEPROM + 2) % EEPROMsiz; //get to len
  len = EEPROM.read(adr_EEPROM);
  printDetails(adr_EEPROM, len, DO_READ);
  adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
  for (i = 0; i < len; i++)
  {
    stringOut[i] = (char)EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, stringOut[i], DO_READ);
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
  }//for(i = 1; i < len; i++)
  stringOut[len] = '\0';
  return 1;
}

int StringsTointEEPROM::get_nstrings_from_eeprom(int nbstring, char *stringsOut[])
{
  int i, cntr = 0, stringno;
  uint8_t len, val = 0;
  uint16_t adr_EEPROM = _adr_EEPROM;
  while (val != 0xff) //find end of latest string
  {
    val = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
  }
#ifndef REMOVE_BACKUP
  adr_EEPROM = (uint16_t)(adr_EEPROM - 1) % EEPROMsiz;
#endif
  for (stringno = 0; stringno < nbstring; stringno++)
  {
    while (val != 0xaa) //find sync
    {
      val = EEPROM.read(adr_EEPROM);
      printDetails(adr_EEPROM, val, DO_READ);
#ifndef REMOVE_BACKUP
      adr_EEPROM = (uint16_t)(adr_EEPROM - 1) % EEPROMsiz; //back up
#endif
      cntr++;
      if (cntr == EEPROMsiz) break; //EEPROM is MT
    }//while (val!=0xaa)
    val = 0;
    if (cntr == EEPROMsiz) return 0;
  }//for (stringno=0;stringno<laststring+1;stringno++)
  adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz; //get to len
  for (stringno = 0; stringno < nbstring; stringno++)
  {
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz; //get to len
    len = EEPROM.read(adr_EEPROM);
    printDetails(adr_EEPROM, val, DO_READ);
    adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
    for (i = 0; i < len; i++)
    {
      stringsOut[stringno][i] = (char)EEPROM.read(adr_EEPROM);
      printDetails(adr_EEPROM, stringsOut[stringno][i], DO_READ);
      adr_EEPROM = (adr_EEPROM + 1) % EEPROMsiz;
    }//for(i = 0; i < len; i++)
    stringsOut[stringno][len] = '\0';
  }//for (stringno=0;stringno<nbstring;stringno++)
  return 1;
}

int  StringsTointEEPROM::find_eeprom_address()
{
  uint8_t val = 0;
  int cntr = 0;
  _adr_EEPROM = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    printDetails(_adr_EEPROM, val, DO_READ);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    cntr++;
    if (cntr == EEPROMsiz) return 0;
  }
#ifndef REMOVE_BACKUP
  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
#endif
  return 1;
}


#if defined(ARDUINO_TEENSY40)
#define FLASH_BASEADDR 0x601F0000
#define FLASH_SECTORS  15
#elif defined(ARDUINO_TEENSY41)
#define FLASH_BASEADDR 0x607C0000
#define FLASH_SECTORS  63
#elif defined(ARDUINO_TEENSY_MICROMOD)
#define FLASH_BASEADDR 0x60FC0000
#define FLASH_SECTORS  63
#endif
extern "C" void eepromemu_flash_erase_sector(void *addr);


bool flash_sector_has_data(uint32_t addr) {
  const uint32_t *p = (const uint32_t *)addr;
  for (unsigned int i = 0; i < 4096; i += 4) {
    if (*p++ != 0xFFFFFFFF) return true;
  }
  return false;
}

void wipe_eeprom() {
#if defined(FLASH_BASEADDR) && defined(FLASH_SECTORS)
  Serial.print("Wiping EEPROM");
  uint32_t addr = FLASH_BASEADDR;
  for (unsigned int i = 0; i < FLASH_SECTORS; i++) {
    Serial.print(".");
    if (flash_sector_has_data(addr)) {
      eepromemu_flash_erase_sector((void *)addr);
    }
    addr += 4096;
  }
  Serial.println();
#else
  for ( unsigned int i = 0 ; i < EEPROM.length() ; i++ ) {
    EEPROM.write(i, 0xFF);
  }
#endif
}


#define TABLESIZ 6
StringsTointEEPROM inteeprom; //internal Arduino EEPROM Library for storing and retreiving c-strings

char eaudgc[10] = "25";
char eaucm[10] = "15";
char eautime[10] = "(05:30)";
char airdgc[10] = "18";
char airhum[10] = "33";
char airtime[10] = "(06:30)";
char *tableadr[] = {eaudgc, eaucm, eautime, airdgc, airhum, airtime};
unsigned long int millistart;
unsigned long milliduration;


// STRUCTURE OF A STORED STRING
//-----------------------------
// sync (0xaa)
// nchar(0..255)
// char[0]
// char[1]
//  ..
// char[nchar-1]
// 0xff (end of latest string)
//-----------------------------


void setup() {
  int i, iter, nbytes = 0;
  Serial.begin(115200);
  while (!Serial) ; // wait for Arduino Serial Monitor
  delay(10);
  wipe_eeprom(); // for consistent test result

  //inteeprom.format_eeprom(); //needs to be formatted once
  if (inteeprom.begin() == 0) Serial.println("begin() ERROR, Format the EEPROM");
  for (i = 0; i < TABLESIZ; i++) nbytes += (strlen(tableadr[i]));
  millistart = millis();
  inteeprom.save_nstrings_to_eeprom(TABLESIZ, tableadr);
  milliduration = millis() - millistart;
  Serial.print("execution time for save_nstrings_to_eeprom() is ");
  Serial.print((float)milliduration / (float)nbytes);
  Serial.println("ms per byte");
  Serial.println("latest 6 strings read from EEPROM");
  millistart = millis();
  if (inteeprom.get_nstrings_from_eeprom(TABLESIZ, tableadr) == 0) Serial.println("EEPROM is MT"); //read string
  milliduration = millis() - millistart;
  Serial.println(eaudgc);
  Serial.println(eaucm);
  Serial.println(eautime);
  Serial.println(airdgc);
  Serial.println(airhum);
  Serial.println(airtime);
  Serial.print("total execution time for get_nstrings_from_eeprom() is ");
  Serial.print(milliduration);
  Serial.println("ms");
  inteeprom.save_nstrings_to_eeprom(TABLESIZ, tableadr);
  for (iter = 0; iter < 500; iter++)
  {
    inteeprom.get_nstrings_from_eeprom(TABLESIZ, tableadr);
    Serial.print("iter: ");
    Serial.print(iter);
    Serial.print(" eaudgc: ");
    Serial.println(eaudgc);
    delay(1);
    if (strcmp(eaudgc, "25") == 0) strcpy(eaudgc, "1"); else strcpy(eaudgc, "25"); //modify 1st string and test reliability
    inteeprom.save_nstrings_to_eeprom(TABLESIZ, tableadr);
  }
}

void loop() {
}
 
I am also now not convinced it is an error in EEPROM library...

Not to say that there are none... but I thought if it were one, that it would be when we filled a page and compressed, but it is not running up to point of
filling the pages.

To show it easier, I changed #define EEPROMsiz 256 //1024
I also moved: uint16_t _adr_EEPROM;
To be public and printed out the value before and after the read...

Code:
Wiping EEPROM...............
execution time for save_nstrings_to_eeprom() is 0.05ms per byte
latest 6 strings read from EEPROM
25
15
(05:30)
18
33
(06:30)
total execution time for get_nstrings_from_eeprom() is 0ms
iter: 0 (68 68) em: 36
iter: 1 (101 101) em: 27
iter: 2 (135 135) em: 34
iter: 3 (168 168) em: 34
iter: 4 (202 202) em: 38
iter: 5 (235 235) em: 38
iter: 6 (13 13) em: 33
iter: 7 (46 46) em: 37
iter: 8 (80 80) em: 45
iter: 9 (113 113) em: 45
iter: 10 (147 147) em: 47
iter: 11 (180 180) em: 53
iter: 12 (214 214) em: 48
iter: 13 (247 247) em: 55
iter: 14 (25 25) 0:(06:30)!=25 1:25!=15 2:15!=(05:30) 3:(05:30)!=18 4:18!=33 5:33!=(06:30) em: 62
####################### Error in Iteration ######################
Page 0 addr: 0x601f0000
Before
20200000 - 00 AA 01 02 02 32 03 35  04 07 05 28 06 30 07 36  : .....2.5 ...(.0.6
20200010 - 08 31 09 38 0A AA 0B 02  0C 35 0D 3A 0E 33 0F 30  : .1.8.... .5.:.3.0
20200020 - 10 02 11 31 12 35 13 AA  02 33 03 33 04 33 05 30  : ...1.5.. .3.3.3.0
20200030 - 06 29 07 AA 08 35 09 AA  0A 07 0B 28 0C FF 0C AA  : .)...5.. ...(....
20200040 - 0D 02 0E 32 0F 35 10 28  11 30 12 36 13 3A FF FF  : ...2.5.( .0.6.:..
20200050 - FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF  : ........ ........
...	 249 duplicate line(s) removed.
20200FF0 - FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF  : ........ ........
After
601F0000 - 00 AA 01 02 02 32 03 35  04 07 05 28 06 30 07 36  : .....2.5 ...(.0.6
601F0010 - 08 31 09 38 0A AA 0B 02  0C 35 0D 3A 0E 33 0F 30  : .1.8.... .5.:.3.0
601F0020 - 10 02 11 31 12 35 13 AA  02 33 03 33 04 33 05 30  : ...1.5.. .3.3.3.0
601F0030 - 06 29 07 AA 08 35 09 AA  0A 07 0B 28 0C FF 0C AA  : .)...5.. ...(....
601F0040 - 0D 02 0E 32 0F 35 10 28  11 30 12 36 13 3A 00 07  : ...2.5.( .0.6.:..
601F0050 - 01 28 02 30 03 35 FF FF  FF FF FF FF FF FF FF FF  : .(.0.5.. ........
601F0060 - FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF  : ........ ........
...	 248 duplicate line(s) removed.
601F0FF0 - FF FF FF FF FF FF FF FF  FF FF FF FF FF FF FF FF  : ........ ........
...
As you can see there is still a lot of room before and after this iteration...


Another Side note:

Remember when porting code from one processor to another, code that works on one, might now on the other. Especially when you are moving from something like an 8 bit AVR processor to a 32 bit Arm processor.

Things to check for include things like:

word size: Things like int on avr maybe only 8 or 16 bits in size, on Teensy they are 32 bits.
Things like the order of bytes in things like WORD or DWORD... (little first or big first)
Things like: char is it signed or not?


Good luck, hope you track it down.

Kurt
 
I decided to take a different look at this problem. I added some debug spits to detail all of the EEPROM addresses & the data READ/WRTTEN from/to those addresses. Something strange popped out as a result: it appears that the operations constraining the EEPROM address to the range 0-1023 are not always resulting in proper values (instead of the expected EEPROM address value of "1023", it is sometimes resulting in a EEPROM address of "65535"), which may or may not cause a problem (as Paul found, it is consistently a problem for passes 121, 270, & 493, but not for others, such as 29, 60, 90, 158, 195, 232, 269, 307, 344, 381, 418, & 456).

"

Yes, I think it's maybe my bug. I modified my library cpp file. Casted my decrement by 1 everywhere:

_adr_EEPROM=(_adr_EEPROM-1)%EEPROMsiz; BECOMES _adr_EEPROM=(uint16_t)(_adr_EEPROM-1)%EEPROMsiz;

No more bad values after 5 tests. I'll try running my sensor monitor complete code with this new library and let you know. Sorry if it's me!

Here's the modified complete code:

Code:
////////////////// LIBRARY INCLUDE FILE ///////////////////////

#ifndef sti
#define sti

#if (ARDUINO >=100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif
#include <EEPROM.h>
#define EEPROMsiz 1024

class StringsTointEEPROM
{
	public:
		//constructor
		StringsTointEEPROM();
		// Methods
		void format_eeprom();
		int begin();
		void save_string_to_eeprom(char *stringIn);
    		void save_nstrings_to_eeprom(int nbstring,char *stringsIn[]);
		void print_strings_from_eeprom();
		int get_string_from_eeprom(char *stringOut); //return 0 if MT
		int get_nstrings_from_eeprom(int nbstring, char *stringsOut[]); //return 0 if MT
	private:
		int find_eeprom_address();
		uint16_t _adr_EEPROM;
};
#endif

////////////// LIBRARY CPP FILE (modified)  //////////////////////////


#include <stringsToint_EEPROM.h>

StringsTointEEPROM::StringsTointEEPROM()
{
}

void  StringsTointEEPROM::format_eeprom()
{
  for (int i=0;i<EEPROMsiz;i++) EEPROM.write(i,0xff);
}

int StringsTointEEPROM::begin()
{
  return find_eeprom_address();
}

void StringsTointEEPROM::save_string_to_eeprom(char *stringIn)
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i;
  uint8_t len,val=0;
  while (val!=0xff)
  { 
    val=EEPROM.read(_adr_EEPROM);
    _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
  }
  _adr_EEPROM=(uint16_t)(_adr_EEPROM-1)%EEPROMsiz;
  EEPROM.write(_adr_EEPROM,0xaa); //write sync
  _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
  len=strlen(stringIn); 
  EEPROM.write(_adr_EEPROM,len);//write nchar
  _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
  for(i = 0; i < len; i++)
  { 
    EEPROM.write(_adr_EEPROM, stringIn[i]);//write string
    _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
  }
  EEPROM.write(_adr_EEPROM,0xff); //write end of string
}

void StringsTointEEPROM::save_nstrings_to_eeprom(int nbstring,char *stringsIn[])
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i,iter=0;
  uint8_t len,val=0;
  while (val!=0xff)
  { 
    val=EEPROM.read(_adr_EEPROM);
    _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
  }
  _adr_EEPROM=(uint16_t)(_adr_EEPROM-1)%EEPROMsiz;
  while (nbstring>0)
  {
    EEPROM.write(_adr_EEPROM,0xaa); //write sync
    _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
    len=strlen(stringsIn[iter]); 
    EEPROM.write(_adr_EEPROM,len);//write nchar
    _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
    for(i = 0; i < len; i++)
    { 
      EEPROM.write(_adr_EEPROM, stringsIn[iter][i]);//write string
      _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
    }
    nbstring--;
    iter++;
  }
  EEPROM.write(_adr_EEPROM,0xff); //write end of string
}
void  StringsTointEEPROM::print_strings_from_eeprom()
{
  int i,cntr=0;
  uint8_t len,val=0;
  uint16_t adr_EEPROM=_adr_EEPROM;
  while (val!=0xff) //find end of latest string
  { 
    val=EEPROM.read(adr_EEPROM);
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
  }
  while(1) //display all strings that were stored in EEPROM in FIFO order
  {
    val=EEPROM.read(adr_EEPROM);
    while (val!=0xaa) //find sync (could be long if EEPROM not full)
    { 
      adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
      val=EEPROM.read(adr_EEPROM);
      cntr++;
      if (cntr==EEPROMsiz)
      {
        Serial.println("EEPROM is  MT");
        break;
      }
    }//while (val!=0xaa)
    if (cntr==EEPROMsiz) break;
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
    len=EEPROM.read(adr_EEPROM);
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
    for(i = 0; i < len; i++)
    { 
      Serial.print((char)EEPROM.read(adr_EEPROM));
      adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
    }//for(i = 0; i < len; i++)
    Serial.println();
    val=EEPROM.read(adr_EEPROM);
    if (val==0xff) break; //break if EEPROM not full or 1 full circle
    else val=0;
  }//while(1)
}

int StringsTointEEPROM::get_string_from_eeprom(char *stringOut)
{
  //get latest string from eeprom
  int i,cntr=0;
  uint8_t len,val=0;
  uint16_t adr_EEPROM=_adr_EEPROM;
  while (val!=0xff) //find end of latest string
  { 
    val=EEPROM.read(adr_EEPROM);
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
  }
  adr_EEPROM=(uint16_t)(adr_EEPROM-1)%EEPROMsiz;
  while (val!=0xaa) //find sync
  { 
    val=EEPROM.read(adr_EEPROM);
    adr_EEPROM=(uint16_t)(adr_EEPROM-1)%EEPROMsiz; //back up
    cntr++;
    if (cntr==EEPROMsiz) break; //EEPROM is MT
  }//while (val!=0xaa)
  if (cntr==EEPROMsiz) return 0;
  adr_EEPROM=(adr_EEPROM+2)%EEPROMsiz; //get to len
  len=EEPROM.read(adr_EEPROM);
  adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
  for(i = 0; i < len; i++)
  { 
    stringOut[i]=(char)EEPROM.read(adr_EEPROM);
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
  }//for(i = 1; i < len; i++)
  stringOut[len]='\0';
  return 1;
}

int StringsTointEEPROM::get_nstrings_from_eeprom(int nbstring,char *stringsOut[])
{
  int i,cntr=0,stringno;
  uint8_t len,val=0;
  uint16_t adr_EEPROM=_adr_EEPROM;
  while (val!=0xff) //find end of latest string
  { 
    val=EEPROM.read(adr_EEPROM);
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
  }
  adr_EEPROM=(uint16_t)(adr_EEPROM-1)%EEPROMsiz;
  for (stringno=0;stringno<nbstring;stringno++)
  {
    while (val!=0xaa) //find sync
    { 
      val=EEPROM.read(adr_EEPROM);
      adr_EEPROM=(uint16_t)(adr_EEPROM-1)%EEPROMsiz; //back up
      cntr++;
      if (cntr==EEPROMsiz) break; //EEPROM is MT
    }//while (val!=0xaa)
    val=0;
    if (cntr==EEPROMsiz) return 0;
  }//for (stringno=0;stringno<laststring+1;stringno++)
  adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz; //get to len
  for (stringno=0;stringno<nbstring;stringno++)
  {
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz; //get to len
    len=EEPROM.read(adr_EEPROM);
    adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
    for(i = 0; i < len; i++)
    { 
      stringsOut[stringno][i]=(char)EEPROM.read(adr_EEPROM);
      adr_EEPROM=(adr_EEPROM+1)%EEPROMsiz;
    }//for(i = 0; i < len; i++)
    stringsOut[stringno][len]='\0';
  }//for (stringno=0;stringno<nbstring;stringno++)
  return 1;
}

int  StringsTointEEPROM::find_eeprom_address()
{
  uint8_t val=0;
  int cntr=0;
  _adr_EEPROM=0;
  while (val!=0xff)
  {
    val=EEPROM.read(_adr_EEPROM);
    _adr_EEPROM=(_adr_EEPROM+1)%EEPROMsiz;
    cntr++;
    if (cntr==EEPROMsiz) return 0;
  }
  _adr_EEPROM=(uint16_t)(_adr_EEPROM-1)%EEPROMsiz;
  return 1; 
}



////////////////////////////////////// TEST FILE ////////////////////////////////

#include <StringsToint_EEPROM.h>
#define TABLESIZ 6
StringsTointEEPROM inteeprom; //internal Arduino EEPROM Library for storing and retreiving c-strings

char eaudgc[10]="25";
char eaucm[10]="15";
char eautime[10]="(05:30)";
char airdgc[10]="18";
char airhum[10]="33";
char airtime[10]="(06:30)";
char *tableadr[]={eaudgc,eaucm,eautime,airdgc,airhum,airtime};
unsigned long int millistart;
unsigned long milliduration;


// STRUCTURE OF A STORED STRING
//-----------------------------
// sync (0xaa)
// nchar(0..255)
// char[0]
// char[1]
//  ..
// char[nchar-1]
// 0xff (end of latest string)
//-----------------------------


void setup() {
  int i,iter,nbytes=0;
  Serial.begin(115200);
  delay(1000);
  //inteeprom.format_eeprom(); //needs to be formatted once
  if (inteeprom.begin()==0) Serial.println("begin() ERROR, Format the EEPROM");
  for (i=0;i<TABLESIZ;i++) nbytes+=(strlen(tableadr[i]));
  millistart=millis();
  inteeprom.save_nstrings_to_eeprom(TABLESIZ,tableadr);
  milliduration=millis()-millistart;
  Serial.print("execution time for save_nstrings_to_eeprom() is ");
  Serial.print((float)milliduration/(float)nbytes);
  Serial.println("ms per byte");
  Serial.println("latest 6 strings read from EEPROM");
  millistart=millis();
  if (inteeprom.get_nstrings_from_eeprom(TABLESIZ,tableadr)==0) Serial.println("EEPROM is MT"); //read string
  milliduration=millis()-millistart;
  Serial.println(eaudgc);
  Serial.println(eaucm);
  Serial.println(eautime);
  Serial.println(airdgc);
  Serial.println(airhum);
  Serial.println(airtime);
  Serial.print("total execution time for get_nstrings_from_eeprom() is ");
  Serial.print(milliduration);
  Serial.println("ms");
  inteeprom.save_nstrings_to_eeprom(TABLESIZ,tableadr);
  for (iter=0;iter<100;iter++)
  {
    inteeprom.get_nstrings_from_eeprom(TABLESIZ,tableadr);
    Serial.print("iter: ");
    Serial.print(iter);
    Serial.print(" eaudgc: ");
    Serial.println(eaudgc);
    delay(1000);
    if (strcmp(eaudgc,"25")==0) strcpy(eaudgc,"1"); else strcpy(eaudgc,"25"); //modify 1st string and test reliability
    inteeprom.save_nstrings_to_eeprom(TABLESIZ,tableadr);
  }
}

void loop() {
  // put your main code here, to run repeatedly:
}
 
Without immediately casting that intermediate result to "uint16_t", the results are not as expected.

Wow, good catch. That would also explain why works on AVR. C++ "integer promotion" on AVR is to 16 bits. On ARM it's 32 bits.


I am also now not convinced it is an error in EEPROM library...

Not to say that there are none... but I thought if it were one, that it would be when we filled a page and compressed, but it is not running up to point of filling the pages.

Yes, agreed, the page full case is where bugs are most likely. The long elusive EEPROM bug we had on Teensy LC until recently was in that case. Still, I try not to assume the core library and EEPROM library are bug free. Sometimes the most subtle bugs are discovered many years after code has been widely used.
 
Without immediately casting that intermediate result to "uint16_t", the results are not as expected.

Wow, good catch. That would also explain why works on AVR. C++ "integer promotion" on AVR is to 16 bits. On ARM it's 32 bits.
...

Indeed! My testing never changed any string lengths - and even wrapping as it did must have always avoided that "0-1" spot given the sample string's provided length.
 
Yes, agreed, the page full case is where bugs are most likely. The long elusive EEPROM bug we had on Teensy LC until recently was in that case. Still, I try not to assume the core library and EEPROM library are bug free. Sometimes the most subtle bugs are discovered many years after code has been widely used.

Yes - which is why in T4 beta days we had the example sketch that I posted earlier that we used to walk through and see how it compressed...
Again was checking today for example to make sure the test in write < 2048 was correct or not...

And then why I added the debug output stuff including the dumps in to today version of the test sketch.

P.S. Bill - Still think you would be better off with the KISS version. Or if you really want to use your version,
experiment setting the: #define EEPROMsiz 256 //1024

To a smaller size. Might try even 128.

And then run your test or real code for a bit and try dumping the pages like I showed and see what is there.

Paul and others. The next thing I was going to do, was to hack eeprom.c
Code:
[COLOR="#FF0000"]uint32_t eeprom_count_sector_rewrites = 0;[/COLOR]

void eeprom_write_byte(uint8_t *addr_ptr, uint8_t data)
{
	uint32_t addr = (uint32_t)addr_ptr;
	uint32_t sector, offset, index, i;
	uint16_t *p, *end;
	uint8_t olddata=0xFF;
	uint8_t buf[256];

	if (addr > E2END) return;
	if (!initialized) eeprom_initialize();

	sector = (addr >> 2) % FLASH_SECTORS; 
	offset = (addr & 3) | (((addr >> 2) / FLASH_SECTORS) << 2);
	//printf("ee_wr, addr=%u, sector=%u, offset=%u, len=%u\n",
		//addr, sector, offset, sector_index[sector]);
	p = (uint16_t *)(FLASH_BASEADDR + sector * 4096);
	end = p + sector_index[sector];
	while (p < end) {
		uint16_t val = *p++;
		if ((val & 255) == offset) olddata = val >> 8;
	}
	if (data == olddata) return;
	if (sector_index[sector] < 2048) {
		//printf("ee_wr, writing\n");
		uint16_t newdata = offset | (data << 8);
		eepromemu_flash_write(end, &newdata, 2);
		sector_index[sector] = sector_index[sector] + 1;
	} else {
		//printf("ee_wr, erase then write\n");
		memset(buf, 0xFF, sizeof(buf));
		p = (uint16_t *)(FLASH_BASEADDR + sector * 4096);
		end = p + 2048;
		while (p < end) {
			uint16_t val = *p++;
			buf[val & 255] = val >> 8;
		}
		buf[offset] = data;
		p = (uint16_t *)(FLASH_BASEADDR + sector * 4096);
		eepromemu_flash_erase_sector(p);
		index = 0;
		for (i=0; i < 256; i++) {
			if (buf[i] != 0xFF) {
				// TODO: combining these to larger write
				// would (probably) be more efficient
				uint16_t newval = i | (buf[i] << 8);
				eepromemu_flash_write(p + index, &newval, 2);
				index = index + 1;
			}
		}
		sector_index[sector] = index;
[COLOR="#FF0000"]                eeprom_count_sector_rewrites++;[/COLOR]
	}
}
So I would have a count of times during a run that we actually had to do an erase/compress operation.

Then in example, extern "c" that variable and print it after each loop, so you can get an idea of just how often that happens...
 
Wow, good catch. That would also explain why works on AVR. C++ "integer promotion" on AVR is to 16 bits. On ARM it's 32 bits.

Glad I could help in some small way. I am making great use of the T4.1 EEPROM for saving presets in the current implementation of my TeensyMIDIPolySynth, so along the way, I have instrumented my code for lots of EEPROM troubleshooting (all trouble was with incorrect implementation in my code, certainly *not* with the EEPROM emulation !!). That particular EEPROM emulation capability is extremely nice to have at our disposal !!

Thanks for everything that you do with & for the entire Teensy community !! Much appreciated !!

Mark J Culross
KD5RXT
 
_adr_EEPROM=(_adr_EEPROM-1)%EEPROMsiz; BECOMES _adr_EEPROM=(uint16_t)(_adr_EEPROM-1)%EEPROMsiz;

Seems like it's more about promotion (conversion?) from unsigned to signed than from 16 to 32 bits, and would still be wrong on AVR.

(_adr_EEPROM-1) is a signed value because the constant "1" is signed. When _adr_EEPROM is zero, modulo operation is (-1 % 1024) = -1, and then the implicit cast in the assignment to _adr_EEPROM yields 65535. With the explicit cast to uint16_t, the modulo operation is (65535 % 1024) = 1023

It's odd to see the modulo operator used to wrap a decreasing index from 0 to 1023, and it only works for EEPROM_SIZE being a power of 2. I tested the fixes below, and they also work because the left-hand operator of the modulo is unsigned.

(_adr_EEPROM-1UL) % EEPROM_SIZE
(--_adr_EEPROM) % EEPROM_SIZE
 
I have nailed down one culprit: the calculation of the EEPROM address whenever a "backup" is done is temporarily converted/promoted to a result with more bits than the "uint16_t" requires (to allow for rollover) as follows:

Code:
  _adr_EEPROM = (_adr_EEPROM - 1) % EEPROMsiz;

If/when "_adr_EEPROM" happens to be "0", the result of subtracting "1" is an intermediate value of "-1". Without immediately casting that intermediate result to "uint16_t", the results are not as expected. The following change to every "backup" calculation allows for correct results in all cases:

Code:
  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;

Now, the *REAL* question is thus: why backup at all ?? Why not just start writing after the last 0xFF that was found ?? In spite of the attempted "wear-leveling" actually resulting in "wear-inducing" (as pointed out by KurtE several times), isn't the implementation of "backing up" actually double-writing some locations unnecessarily ??

Getting rid of all "backup calculations" also allows for correct results in all cases, & is actually simpler as well. Go with KISS !!

Mark J Culross
KD5RXT

Yes, I modified my library with the casting of the decrementation. I ran my full code for about 12 hours with no glitch. You sure nailed it & I thank you. Sorry for taking the time away from you and several others.

BTW, I had to back up in my code to get to the beginnining of the last 6 stored streams before the 0xff in the "EEPROM" before recovering(reading) them. Please note that I am only reading before I back up. I am not rewriting.
 
actually double-writing some locations

BTW, I had to back up in my code to get to the beginining of the last 6 stored streams before the 0xff in the "EEPROM" before recovering(reading) them. Please note that I am only reading before I back up. I am not rewriting.

I disagree, or maybe I just don't understand your comment. There appear to be instances where you backup, then write:

Code:
void StringsTointEEPROM::save_string_to_eeprom(char *stringIn)
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i;
  uint8_t len, val = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
[COLOR="#FF0000"]  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
  EEPROM.write(_adr_EEPROM, 0xaa); //write sync
[/COLOR]  _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  len = strlen(stringIn);
  EEPROM.write(_adr_EEPROM, len); //write nchar
  _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  for (i = 0; i < len; i++)
  {
    EEPROM.write(_adr_EEPROM, stringIn[i]);//write string
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
  EEPROM.write(_adr_EEPROM, 0xff); //write end of string
}

void StringsTointEEPROM::save_nstrings_to_eeprom(int nbstring, char *stringsIn[])
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i, iter = 0;
  uint8_t len, val = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
[COLOR="#FF0000"]  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
  while (nbstring > 0)
  {
    EEPROM.write(_adr_EEPROM, 0xaa); //write sync
[/COLOR]    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    len = strlen(stringsIn[iter]);
    EEPROM.write(_adr_EEPROM, len); //write nchar
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    for (i = 0; i < len; i++)
    {
      EEPROM.write(_adr_EEPROM, stringsIn[iter][i]);//write string
      _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    }
    nbstring--;
    iter++;
  }
  EEPROM.write(_adr_EEPROM, 0xff); //write end of string
}

Unless I am somehow misreading this, it sure looks like you are overwriting the 0xFF with 0xAA after a backup ?!? That's what prompted my reference to "actually double-writing some locations" earlier.

Mark J Culross
KD5RXT
 
I disagree, or maybe I just don't understand your comment. There appear to be instances where you backup, then write:

Code:
void StringsTointEEPROM::save_string_to_eeprom(char *stringIn)
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i;
  uint8_t len, val = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
[COLOR="#FF0000"]  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
  EEPROM.write(_adr_EEPROM, 0xaa); //write sync
[/COLOR]  _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  len = strlen(stringIn);
  EEPROM.write(_adr_EEPROM, len); //write nchar
  _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  for (i = 0; i < len; i++)
  {
    EEPROM.write(_adr_EEPROM, stringIn[i]);//write string
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
  EEPROM.write(_adr_EEPROM, 0xff); //write end of string
}

void StringsTointEEPROM::save_nstrings_to_eeprom(int nbstring, char *stringsIn[])
{
  // sync (0xaa)
  // nchar(0..255)
  // char[0]
  // char[1]
  //  ..
  // char[nchar-1]
  // 0xff (end of latest string)
  int i, iter = 0;
  uint8_t len, val = 0;
  while (val != 0xff)
  {
    val = EEPROM.read(_adr_EEPROM);
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
  }
[COLOR="#FF0000"]  _adr_EEPROM = (uint16_t)(_adr_EEPROM - 1) % EEPROMsiz;
  while (nbstring > 0)
  {
    EEPROM.write(_adr_EEPROM, 0xaa); //write sync
[/COLOR]    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    len = strlen(stringsIn[iter]);
    EEPROM.write(_adr_EEPROM, len); //write nchar
    _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    for (i = 0; i < len; i++)
    {
      EEPROM.write(_adr_EEPROM, stringsIn[iter][i]);//write string
      _adr_EEPROM = (_adr_EEPROM + 1) % EEPROMsiz;
    }
    nbstring--;
    iter++;
  }
  EEPROM.write(_adr_EEPROM, 0xff); //write end of string
}

Unless I am somehow misreading this, it sure looks like you are overwriting the 0xFF with 0xAA after a backup ?!? That's what prompted my reference to "actually double-writing some locations" earlier.

Mark J Culross
KD5RXT

In this function, I'm appending another string to the previous n strings already stored in the "EEPROM". I have to overwrite the 0xff. When the EEPROM is full there is only one 0xff. That's how the read function (and the begin() in case of power on) finds the address of the most recent string. If I have only 1 string to read (5 characters for air temperature for example), update, and append/write, then I will write 0xaa,nchar,char0,char1,..,char4,0xff. (8 writes). The EEPROM will be filled after 1024/8 or 128 updates of the sensor temperature value. These addresses will be written (circular addressing mode) every 128 sensor updates instead of every sensor update.
 
Just a quick update, I updated my version of the sketch to have additional debug stuff in it.

I did update the version of the code that you are using to match. And it did run through 5000 iterations without an error discovered...
i.e. all of the read values matched the write values...

I am mainly posting here as a way to remember some of the debug stuff later.

What changes in the debugging code include:
a) Use the dump_eeprom function out of my earlier t4_test_eeprom function, that we were using to help debug the eeprom code back in beta time frame.
b) Added code to detect when the EEPROM flash pages are Erased and rewritten with only the latest data. I do that by in each iteration of the code, I walk the 15 flash pages (63 on T4.1/mmon), and look for the index of the first value that is 0xffff. If the index is < previous iteration we are pretty sure it must have erased...

And I try to print out this data during the run...

The end of the last run I did with your code looks like:
Code:
iter: 4993 (165 165) em: 1341 pages flashed: 64
iter: 4994 (199 199) em: 1271 pages flashed: 64
iter: 4995 (232 232) em: 1375 pages flashed: 64
iter: 4996 (10 10) em: 968 pages flashed: 64
iter: 4997 (43 43) em: 1324 pages flashed: 64
iter: 4998 (77 77) em: 1330 pages flashed: 64
iter: 4999 (110 110) em: 1344 pages flashed: 64

*** End of run ***
Count of errors: 0
Strings:  0:1 25 1:15 15 2:(05:30) (05:30) 3:18 18 4:33 33 5:(06:30) (06:30)
Dump EEPROM pages
EEPROM length: 1080
Contents:
0:33 1:aa 2:7 3:28 4:30 5:36 6:3a 7:33 8:30 9:29 a:aa b:1 c:31 d:aa e:2 f:31 
10:35 11:aa 12:7 13:28 14:30 15:35 16:3a 17:33 18:30 19:29 1a:aa 1b:2 1c:31 1d:38 1e:aa 1f:2 
20:33 21:33 22:aa 23:7 24:28 25:30 26:36 27:3a 28:33 29:30 2a:29 2b:aa 2c:2 2d:32 2e:35 2f:aa 
30:2 31:31 32:35 33:aa 34:7 35:28 36:30 37:35 38:3a 39:33 3a:30 3b:29 3c:aa 3d:2 3e:31 3f:38 
40:aa 41:2 42:33 43:33 44:aa 45:7 46:28 47:30 48:36 49:3a 4a:33 4b:30 4c:29 4d:aa 4e:1 4f:31 
50:aa 51:2 52:31 53:35 54:aa 55:7 56:28 57:30 58:35 59:3a 5a:33 5b:30 5c:29 5d:aa 5e:2 5f:31 
60:38 61:aa 62:2 63:33 64:33 65:aa 66:7 67:28 68:30 69:36 6a:3a 6b:33 6c:30 6d:29 6e:aa 6f:2 
70:32 71:35 72:aa 73:2 74:31 75:35 76:aa 77:7 78:28 79:30 7a:35 7b:3a 7c:33 7d:30 7e:29 7f:aa 
80:2 81:31 82:38 83:aa 84:2 85:33 86:33 87:aa 88:7 89:28 8a:30 8b:36 8c:3a 8d:33 8e:30 8f:29 
90:ff 91:33 92:30 93:29 94:aa 95:2 96:31 97:38 98:aa 99:2 9a:33 9b:33 9c:aa 9d:7 9e:28 9f:30 
a0:36 a1:3a a2:33 a3:30 a4:29 a5:aa a6:2 a7:32 a8:35 a9:aa aa:2 ab:31 ac:35 ad:aa ae:7 af:28 
b0:30 b1:35 b2:3a b3:33 b4:30 b5:29 b6:aa b7:2 b8:31 b9:38 ba:aa bb:2 bc:33 bd:33 be:aa bf:7 
c0:28 c1:30 c2:36 c3:3a c4:33 c5:30 c6:29 c7:aa c8:1 c9:31 ca:aa cb:2 cc:31 cd:35 ce:aa cf:7 
d0:28 d1:30 d2:35 d3:3a d4:33 d5:30 d6:29 d7:aa d8:2 d9:31 da:38 db:aa dc:2 dd:33 de:33 df:aa 
e0:7 e1:28 e2:30 e3:36 e4:3a e5:33 e6:30 e7:29 e8:aa e9:2 ea:32 eb:35 ec:aa ed:2 ee:31 ef:35 
f0:aa f1:7 f2:28 f3:30 f4:35 f5:3a f6:33 f7:30 f8:29 f9:aa fa:2 fb:31 fc:38 fd:aa fe:2 ff:33 
100:ff 101:ff 102:ff 103:ff 104:ff 105:ff 106:ff 107:ff 108:ff 109:ff 10a:ff 10b:ff 10c:ff 10d:ff 10e:ff 10f:ff 
...

Raw Data
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f0b86
  000(00)=36  001(01)=3a  002(02)=33  003(03)=30  060(04)=02  061(05)=33  062(06)=33  063(07)=aa  120(08)=30  121(09)=29  122(0a)=aa  123(0b)=02  180(0c)=aa  181(0d)=07  182(0e)=28  183(0f)=30
  240(10)=3a  241(11)=33  242(12)=30  243(13)=29  240(10)=02  241(11)=32  242(12)=35  243(13)=aa  000(00)=aa  001(01)=02  002(02)=31  003(03)=38  060(04)=28  061(05)=30  062(06)=35  063(07)=3a
  120(08)=35  121(09)=aa  122(0a)=02  123(0b)=31  180(0c)=3a  181(0d)=33  182(0e)=30  183(0f)=29  240(10)=33  241(11)=33  242(12)=aa  243(13)=07  000(00)=02  001(01)=31  002(02)=35  003(03)=aa
  060(04)=30  061(05)=29  062(06)=ff  062(06)=aa  063(07)=02  120(08)=aa  121(09)=07  122(0a)=28  123(0b)=30  180(0c)=02  181(0d)=31  182(0e)=38  183(0f)=aa  240(10)=30  241(11)=35  242(12)=3a
  243(13)=33  000(00)=28  001(01)=30  002(02)=36  003(03)=3a  060(04)=38  061(05)=aa  062(06)=02  063(07)=33  120(08)=3a  121(09)=33  122(0a)=30  123(0b)=29  180(0c)=31  181(0d)=35  182(0e)=aa
  183(0f)=07  241(11)=29  242(12)=ff  242(12)=aa  243(13)=01  000(00)=30  001(01)=29  002(02)=aa  003(03)=02  060(04)=aa  061(05)=07  062(06)=28  063(07)=30  120(08)=ff  120(08)=aa  121(09)=01
  122(0a)=31  123(0b)=aa  180(0c)=28  181(0d)=30  182(0e)=36  183(0f)=3a  240(10)=38  241(11)=aa  242(12)=02  243(13)=33  000(00)=31  001(01)=aa  002(02)=02  003(03)=31  060(04)=36  061(05)=3a
  062(06)=33  120(08)=02  121(09)=33  122(0a)=33  180(0c)=30  181(0d)=29  182(0e)=aa  183(0f)=02  240(10)=aa  241(11)=07  242(12)=28  243(13)=30  000(00)=33  002(02)=07  003(03)=28  060(04)=aa
  061(05)=02  062(06)=31  063(07)=38  120(08)=28  121(09)=30  122(0a)=35  123(0b)=3a  180(0c)=35  181(0d)=aa  182(0e)=02  183(0f)=31  240(10)=3a  241(11)=33  242(12)=30  243(13)=29  000(00)=35
  001(01)=3a  002(02)=33  003(03)=30  060(04)=02  061(05)=31  062(06)=35  063(07)=aa  120(08)=30  121(09)=29  122(0a)=ff  122(0a)=aa  123(0b)=02  180(0c)=aa  181(0d)=07  182(0e)=28  183(0f)=30
  240(10)=02  241(11)=31  242(12)=38  243(13)=aa  000(00)=ff  000(00)=aa  001(01)=02  002(02)=32  003(03)=35  060(04)=28  061(05)=30  062(06)=36  063(07)=3a  120(08)=38  121(09)=aa  122(0a)=02
  123(0b)=33  180(0c)=3a  181(0d)=33  182(0e)=30  183(0f)=29  240(10)=31  241(11)=35  242(12)=aa  243(13)=07  000(00)=02  001(01)=33  002(02)=33  003(03)=aa  060(04)=30  061(05)=29  062(06)=aa
  063(07)=02  120(08)=aa  121(09)=07  122(0a)=28  123(0b)=30  180(0c)=ff  180(0c)=aa  181(0d)=01  182(0e)=31  183(0f)=aa  240(10)=28  241(11)=30  242(12)=36  243(13)=3a  000(00)=28  001(01)=30
  002(02)=35  003(03)=3a  060(04)=31  061(05)=aa  062(06)=02  063(07)=31  120(08)=36  121(09)=3a  122(0a)=33  180(0c)=02  181(0d)=33  182(0e)=33  240(10)=30  241(11)=29  242(12)=aa  243(13)=02
  000(00)=33  002(02)=29  003(03)=ff  003(03)=aa  060(04)=33  062(06)=07  063(07)=28  120(08)=aa  121(09)=02  122(0a)=31  123(0b)=38  180(0c)=28  181(0d)=30  182(0e)=35  183(0f)=3a  240(10)=35
  241(11)=aa  242(12)=02  243(13)=31  000(00)=31  001(01)=38  002(02)=aa  003(03)=02  060(04)=35  061(05)=3a  062(06)=33  063(07)=30  120(08)=02  121(09)=31  122(0a)=35  123(0b)=aa  180(0c)=30
  181(0d)=29  182(0e)=ff  182(0e)=aa  183(0f)=02  240(10)=aa  241(11)=07  242(12)=28  243(13)=30  000(00)=35  001(01)=aa  002(02)=07  003(03)=28  060(04)=ff  060(04)=aa  061(05)=02  062(06)=32
  063(07)=35  120(08)=28  121(09)=30  122(0a)=36  123(0b)=3a  180(0c)=38  181(0d)=aa  182(0e)=02  183(0f)=33  240(10)=3a  241(11)=33  242(12)=30  243(13)=29  000(00)=36  001(01)=3a  002(02)=33
  003(03)=30  060(04)=02  061(05)=33  062(06)=33  063(07)=aa  120(08)=30  121(09)=29  122(0a)=aa  123(0b)=02  180(0c)=aa  181(0d)=07  182(0e)=28  183(0f)=30  240(10)=ff  240(10)=aa  241(11)=01
  242(12)=31  243(13)=aa  000(00)=aa  001(01)=02  002(02)=31  003(03)=38  060(04)=28  061(05)=30  062(06)=35  063(07)=3a  120(08)=31  121(09)=aa  122(0a)=02  123(0b)=31  180(0c)=36  181(0d)=3a
  182(0e)=33  240(10)=02  241(11)=33  242(12)=33  000(00)=02  001(01)=31  002(02)=35  003(03)=aa  060(04)=33  062(06)=29  063(07)=ff  063(07)=aa  120(08)=33  122(0a)=07  123(0b)=28  180(0c)=aa
  181(0d)=02  182(0e)=31  183(0f)=38  240(10)=28  241(11)=30  242(12)=35  243(13)=3a  000(00)=07  001(01)=28  002(02)=30  003(03)=36  060(04)=31  061(05)=38  062(06)=aa  063(07)=02  120(08)=35
  121(09)=3a  122(0a)=33  123(0b)=30  180(0c)=02  181(0d)=31  182(0e)=35  183(0f)=aa  240(10)=30  241(11)=29  242(12)=ff  242(12)=aa  243(13)=02  000(00)=33  001(01)=30  002(02)=29  003(03)=aa
  060(04)=35  061(05)=aa  062(06)=07  063(07)=28  120(08)=ff  120(08)=aa  121(09)=02  122(0a)=32  123(0b)=35  180(0c)=28  181(0d)=30  182(0e)=36  183(0f)=3a  240(10)=38  241(11)=aa  242(12)=02
  243(13)=33  000(00)=32  001(01)=35  002(02)=aa  003(03)=02  060(04)=36  061(05)=3a  062(06)=33  063(07)=30  120(08)=02  121(09)=33  122(0a)=33  123(0b)=aa  180(0c)=30  181(0d)=29  182(0e)=aa
  183(0f)=02  240(10)=aa  241(11)=07  242(12)=28  243(13)=30  000(00)=33  001(01)=aa  002(02)=07  003(03)=28  060(04)=aa  061(05)=02  062(06)=31  063(07)=38  120(08)=28  121(09)=30  122(0a)=35
  123(0b)=3a  180(0c)=31  181(0d)=aa  182(0e)=02  183(0f)=31  240(10)=36  241(11)=3a  242(12)=33  000(00)=35  001(01)=3a  002(02)=33  003(03)=30  060(04)=02  061(05)=31  062(06)=35  063(07)=aa
  120(08)=33  122(0a)=29  123(0b)=ff  123(0b)=aa  180(0c)=33  182(0e)=07  183(0f)=28  240(10)=aa  241(11)=02  242(12)=31  243(13)=38  000(00)=29  001(01)=ff  001(01)=aa  002(02)=01  003(03)=31
  060(04)=07  061(05)=28  062(06)=30  063(07)=36  120(08)=31  121(09)=38  122(0a)=aa  123(0b)=02  180(0c)=35  181(0d)=3a  182(0e)=33  183(0f)=30  240(10)=02  241(11)=31  242(12)=35  243(13)=aa
  000(00)=aa  001(01)=02  002(02)=33  003(03)=33  060(04)=33  061(05)=30  062(06)=29  063(07)=aa  120(08)=35  121(09)=aa  122(0a)=07  123(0b)=28  180(0c)=ff  180(0c)=aa  181(0d)=02  182(0e)=32
  183(0f)=35  240(10)=28  241(11)=30  242(12)=36  243(13)=3a  000(00)=07  001(01)=28  002(02)=30  003(03)=35  060(04)=32  061(05)=35  062(06)=aa  063(07)=02  120(08)=36  121(09)=3a  122(0a)=33
  123(0b)=30  180(0c)=02  181(0d)=33  182(0e)=33  183(0f)=aa  240(10)=30  241(11)=29  242(12)=aa  243(13)=02  000(00)=33  001(01)=30  002(02)=29  003(03)=ff  003(03)=aa  060(04)=33  061(05)=aa
  062(06)=07  063(07)=28  120(08)=aa  121(09)=02  122(0a)=31  123(0b)=38  180(0c)=28  181(0d)=30  182(0e)=35  183(0f)=3a  240(10)=31  241(11)=aa  242(12)=02  243(13)=31  000(00)=31  001(01)=38
  002(02)=aa  003(03)=02  060(04)=35  061(05)=3a  062(06)=33  063(07)=30  120(08)=02  121(09)=31  122(0a)=35  123(0b)=aa  180(0c)=33  182(0e)=29  183(0f)=ff  183(0f)=aa  240(10)=33  242(12)=07
  243(13)=28  000(00)=35  001(01)=aa  002(02)=07  003(03)=28  060(04)=29  061(05)=ff  061(05)=aa  062(06)=01  063(07)=31  120(08)=07  121(09)=28  122(0a)=30  123(0b)=36  180(0c)=31  181(0d)=38
  182(0e)=aa  183(0f)=02  240(10)=35  241(11)=3a  242(12)=33  243(13)=30  000(00)=30  001(01)=36  002(02)=3a  003(03)=33  060(04)=aa  061(05)=02  062(06)=33  063(07)=33  120(08)=33  121(09)=30
  122(0a)=29  123(0b)=aa  180(0c)=35  181(0d)=aa  182(0e)=07  183(0f)=28  240(10)=ff  240(10)=aa  241(11)=02  242(12)=32  243(13)=35  000(00)=29  001(01)=aa  002(02)=02  003(03)=31  060(04)=07
  061(05)=28  062(06)=30  063(07)=35  120(08)=32  121(09)=35  122(0a)=aa  123(0b)=02  180(0c)=36  181(0d)=3a  182(0e)=33  183(0f)=30  240(10)=02  241(11)=33  242(12)=33  243(13)=aa  000(00)=aa
  001(01)=02  002(02)=31  003(03)=35  060(04)=33  061(05)=30  062(06)=29  063(07)=ff  063(07)=aa  120(08)=33  121(09)=aa  122(0a)=07  123(0b)=28  180(0c)=aa  181(0d)=02  182(0e)=31  183(0f)=38
  240(10)=28  241(11)=30  242(12)=35  243(13)=3a  000(00)=07  001(01)=28  002(02)=30  003(03)=36  060(04)=31  061(05)=38  062(06)=aa  063(07)=02  120(08)=35  121(09)=3a  122(0a)=33  123(0b)=30
  180(0c)=02  181(0d)=31  182(0e)=35  183(0f)=aa  240(10)=33  242(12)=29  243(13)=ff  243(13)=aa  000(00)=33  001(01)=30  002(02)=29  003(03)=aa  060(04)=35  061(05)=aa  062(06)=07  063(07)=28
  120(08)=29  121(09)=ff  121(09)=aa  122(0a)=01  123(0b)=31  180(0c)=07  181(0d)=28  182(0e)=30  183(0f)=36  240(10)=31  241(11)=38  242(12)=aa  243(13)=02  000(00)=01  001(01)=31  002(02)=aa
  003(03)=02  060(04)=30  061(05)=36  062(06)=3a  063(07)=33  120(08)=aa  121(09)=02  122(0a)=33  123(0b)=33  180(0c)=33  181(0d)=30  182(0e)=29  183(0f)=aa  240(10)=35  241(11)=aa  242(12)=07
  243(13)=28  000(00)=33  001(01)=33  003(03)=07  060(04)=29  061(05)=aa  062(06)=02  063(07)=31  120(08)=07  121(09)=28  122(0a)=30  123(0b)=35  180(0c)=32  181(0d)=35  182(0e)=aa  183(0f)=02
  240(10)=36  241(11)=3a  242(12)=33  243(13)=30  000(00)=30  001(01)=35  002(02)=3a  003(03)=33  060(04)=aa  061(05)=02  062(06)=31  063(07)=35  120(08)=33  121(09)=30  122(0a)=29  123(0b)=ff
  123(0b)=aa  180(0c)=33  181(0d)=aa  182(0e)=07  183(0f)=28  240(10)=aa  241(11)=02  242(12)=31  243(13)=38  000(00)=29  001(01)=ff  001(01)=aa  002(02)=02  003(03)=32  060(04)=07  061(05)=28
  062(06)=30  063(07)=36  120(08)=31  121(09)=38  122(0a)=aa  123(0b)=02  180(0c)=35  181(0d)=3a  182(0e)=33  183(0f)=30  240(10)=02  241(11)=31  242(12)=35  243(13)=aa  000(00)=aa  001(01)=02
  002(02)=33  003(03)=33  060(04)=33  061(05)=30  062(06)=29  063(07)=aa  120(08)=35  121(09)=aa  122(0a)=07  123(0b)=28  180(0c)=29  181(0d)=ff  181(0d)=aa  182(0e)=01  183(0f)=31  240(10)=07
  241(11)=28  242(12)=30  243(13)=36  000(00)=07  001(01)=28  002(02)=30  003(03)=35  060(04)=01  061(05)=31  062(06)=aa  063(07)=02  120(08)=30  121(09)=36  122(0a)=3a  123(0b)=33  180(0c)=aa
  181(0d)=02  182(0e)=33  183(0f)=33  240(10)=33  241(11)=30  242(12)=29  243(13)=aa  000(00)=3a  001(01)=33  003(03)=29  060(04)=33  061(05)=33  063(07)=07  120(08)=29  121(09)=aa  122(0a)=02
  123(0b)=31  180(0c)=07  181(0d)=28  182(0e)=30  183(0f)=35  240(10)=32  241(11)=35  242(12)=aa  243(13)=02  000(00)=02  001(01)=31  002(02)=38  003(03)=aa  060(04)=30  061(05)=35  062(06)=3a
  063(07)=33  120(08)=aa  121(09)=02  122(0a)=31  123(0b)=35  180(0c)=33  181(0d)=30  182(0e)=29  183(0f)=ff  183(0f)=aa  240(10)=33  241(11)=aa  242(12)=07  243(13)=28  000(00)=31  001(01)=35
  002(02)=aa  003(03)=07  060(04)=29  061(05)=ff  061(05)=aa  062(06)=02  063(07)=32  120(08)=07  121(09)=28  122(0a)=30  123(0b)=36  180(0c)=31  181(0d)=38  182(0e)=aa  183(0f)=02  240(10)=35
  241(11)=3a  242(12)=33  243(13)=30  000(00)=30  001(01)=36  002(02)=3a  003(03)=33  060(04)=aa  061(05)=02  062(06)=33  063(07)=33  120(08)=33  121(09)=30  122(0a)=29  123(0b)=aa  180(0c)=35
  181(0d)=aa  182(0e)=07  183(0f)=28  240(10)=29  241(11)=ff  241(11)=aa  242(12)=01  243(13)=31  000(00)=29  001(01)=aa  002(02)=02  003(03)=31  060(04)=07  061(05)=28  062(06)=30  063(07)=35
  120(08)=01  121(09)=31  122(0a)=aa  123(0b)=02  180(0c)=30  181(0d)=36  182(0e)=3a  183(0f)=33  240(10)=aa  241(11)=02  242(12)=33  243(13)=33  000(00)=aa  001(01)=02  002(02)=31  003(03)=35
  060(04)=3a  061(05)=33  063(07)=29  120(08)=33  121(09)=33  123(0b)=07  180(0c)=29  181(0d)=aa  182(0e)=02  183(0f)=31  240(10)=07  241(11)=28  242(12)=30  243(13)=35  001(01)=07  002(02)=28
  003(03)=30  060(04)=02  061(05)=31  062(06)=38  063(07)=aa  120(08)=30  121(09)=35  122(0a)=3a  123(0b)=33  180(0c)=aa  181(0d)=02  182(0e)=31  183(0f)=35  240(10)=33  241(11)=30  242(12)=29
  243(13)=ff  243(13)=aa  000(00)=3a  001(01)=33  002(02)=30  003(03)=29  060(04)=31  061(05)=35  062(06)=aa  063(07)=07  120(08)=29  121(09)=ff  121(09)=aa  122(0a)=02  123(0b)=32  180(0c)=07
  181(0d)=28  182(0e)=30  183(0f)=36  240(10)=31  241(11)=38  242(12)=aa  243(13)=02  000(00)=02  001(01)=32  002(02)=35  003(03)=aa  060(04)=30  061(05)=36  062(06)=3a  063(07)=33  120(08)=aa
  121(09)=02  122(0a)=33  123(0b)=33  180(0c)=33  181(0d)=30  182(0e)=29  183(0f)=aa  240(10)=35  241(11)=aa  242(12)=07  243(13)=28  000(00)=33  001(01)=33  002(02)=aa  003(03)=07  060(04)=29
  061(05)=aa  062(06)=02  063(07)=31  120(08)=07  121(09)=28  122(0a)=30  123(0b)=35  180(0c)=01  181(0d)=31  182(0e)=aa  183(0f)=02  240(10)=30  241(11)=36  242(12)=3a  243(13)=33  000(00)=30
  001(01)=35  002(02)=3a  003(03)=33  060(04)=aa  061(05)=02  062(06)=31  063(07)=35  120(08)=3a  121(09)=33  123(0b)=29  180(0c)=33  181(0d)=33  183(0f)=07  240(10)=29  241(11)=aa  242(12)=02
  243(13)=31  001(01)=29  002(02)=ff  002(02)=aa  003(03)=01  061(05)=07  062(06)=28  063(07)=30  120(08)=02  121(09)=31  122(0a)=38  123(0b)=aa  180(0c)=30  181(0d)=35  182(0e)=3a  183(0f)=33
  240(10)=aa  241(11)=02  242(12)=31  243(13)=35  000(00)=38  001(01)=aa  002(02)=02  003(03)=33  060(04)=3a  061(05)=33  062(06)=30  063(07)=29  120(08)=31  121(09)=35  122(0a)=aa  123(0b)=07
  180(0c)=29  181(0d)=ff  181(0d)=aa  182(0e)=02  183(0f)=32  240(10)=07  241(11)=28  242(12)=30  243(13)=36  000(00)=aa  001(01)=07  002(02)=28  003(03)=30  060(04)=02  061(05)=32  062(06)=35
  063(07)=aa  120(08)=30  121(09)=36  122(0a)=3a  123(0b)=33  180(0c)=aa  181(0d)=02  182(0e)=33  183(0f)=33  240(10)=33  241(11)=30  242(12)=29  243(13)=aa  000(00)=3a  001(01)=33  002(02)=30
  003(03)=29  060(04)=33  061(05)=33  062(06)=aa  063(07)=07  120(08)=29  121(09)=aa  122(0a)=02  123(0b)=31  180(0c)=07  181(0d)=28  182(0e)=30  183(0f)=35  240(10)=01  241(11)=31  242(12)=aa
  243(13)=02  000(00)=02  001(01)=31  002(02)=38  003(03)=aa  060(04)=30  061(05)=35  062(06)=3a  063(07)=33  120(08)=aa  121(09)=02  122(0a)=31  123(0b)=35  180(0c)=3a  181(0d)=33  183(0f)=29
  240(10)=33  241(11)=33  243(13)=07  000(00)=31  001(01)=35  002(02)=aa  003(03)=07  061(05)=29  062(06)=ff  062(06)=aa  063(07)=01  121(09)=07  122(0a)=28  123(0b)=30  180(0c)=02  181(0d)=31
  182(0e)=38  183(0f)=aa  240(10)=30  241(11)=35  242(12)=3a  243(13)=33  000(00)=28  001(01)=30  002(02)=36  003(03)=3a  060(04)=38  061(05)=aa  062(06)=02  063(07)=33  120(08)=3a  121(09)=33
  122(0a)=30  123(0b)=29  180(0c)=31  181(0d)=35  182(0e)=aa  183(0f)=07  240(10)=29  241(11)=ff  241(11)=aa  242(12)=02  243(13)=32  000(00)=30  001(01)=29  002(02)=aa  003(03)=02  060(04)=aa
  061(05)=07  062(06)=28  063(07)=30  120(08)=02  121(09)=32  122(0a)=35  123(0b)=aa  180(0c)=30  181(0d)=36  182(0e)=3a  183(0f)=33  240(10)=aa  241(11)=02  242(12)=33  243(13)=33  000(00)=35
  001(01)=aa  002(02)=02  003(03)=31  060(04)=3a  061(05)=33  062(06)=30  063(07)=29  120(08)=33  121(09)=33  122(0a)=aa  123(0b)=07  180(0c)=29  181(0d)=aa  182(0e)=02  183(0f)=31  240(10)=07
  241(11)=28  242(12)=30  243(13)=35  000(00)=aa  001(01)=07  002(02)=28  003(03)=30  060(04)=02  061(05)=31  062(06)=38  063(07)=aa  120(08)=30  121(09)=35  122(0a)=3a  123(0b)=33  180(0c)=aa
  181(0d)=02  182(0e)=31  183(0f)=35  240(10)=3a  241(11)=33  243(13)=29  000(00)=3a  001(01)=33  002(02)=30  003(03)=29  060(04)=31  061(05)=35  062(06)=aa  063(07)=07  121(09)=29  122(0a)=ff
  122(0a)=aa  123(0b)=01  181(0d)=07  182(0e)=28  183(0f)=30  240(10)=02  241(11)=31  242(12)=38  243(13)=aa  000(00)=ff  000(00)=aa  001(01)=01  002(02)=31  003(03)=aa  060(04)=28  061(05)=30
  062(06)=36  063(07)=3a  120(08)=38  121(09)=aa  122(0a)=02  123(0b)=33  180(0c)=3a  181(0d)=33  182(0e)=30  183(0f)=29  240(10)=31  241(11)=35  242(12)=aa  243(13)=07  000(00)=02  001(01)=33
  002(02)=33  060(04)=30  061(05)=29  062(06)=aa  063(07)=02  120(08)=aa  121(09)=07  122(0a)=28  123(0b)=30  180(0c)=02  181(0d)=32  182(0e)=35  183(0f)=aa  240(10)=30  241(11)=36  242(12)=3a
  243(13)=33  000(00)=28  001(01)=30  002(02)=35  003(03)=3a  060(04)=35  061(05)=aa  062(06)=02  063(07)=31  120(08)=3a  121(09)=33  122(0a)=30  123(0b)=29  180(0c)=33  181(0d)=33  182(0e)=aa
  183(0f)=07  240(10)=29  241(11)=aa  242(12)=02  243(13)=31  000(00)=30  001(01)=29  002(02)=ff  002(02)=aa  003(03)=02  060(04)=aa  061(05)=07  062(06)=28  063(07)=30  120(08)=02  121(09)=31
  122(0a)=38  123(0b)=aa  180(0c)=30  181(0d)=35  182(0e)=3a  183(0f)=33  240(10)=aa  241(11)=02  242(12)=31  243(13)=35  000(00)=38  001(01)=aa  002(02)=02  003(03)=33  060(04)=3a  061(05)=33
  062(06)=30  063(07)=29  120(08)=31  121(09)=35  122(0a)=aa  123(0b)=07  181(0d)=29  182(0e)=ff  182(0e)=aa  183(0f)=01  241(11)=07  242(12)=28  243(13)=30  000(00)=aa  001(01)=07  002(02)=28
  003(03)=30  060(04)=ff  060(04)=aa  061(05)=01  062(06)=31  063(07)=aa  120(08)=28  121(09)=30  122(0a)=36  123(0b)=3a  180(0c)=38  181(0d)=aa  182(0e)=02  183(0f)=33  240(10)=3a  241(11)=33
  242(12)=30  243(13)=29  000(00)=36  001(01)=3a  002(02)=33  060(04)=02  061(05)=33  062(06)=33  120(08)=30  121(09)=29  122(0a)=aa  123(0b)=02  180(0c)=aa  181(0d)=07  182(0e)=28  183(0f)=30
  240(10)=02  241(11)=32  242(12)=35  243(13)=aa  000(00)=aa  001(01)=02  002(02)=31  003(03)=38  060(04)=28  061(05)=30  062(06)=35  063(07)=3a  120(08)=35  121(09)=aa  122(0a)=02  123(0b)=31
  180(0c)=3a  181(0d)=33  182(0e)=30  183(0f)=29  240(10)=33  241(11)=33  242(12)=aa  243(13)=07  000(00)=02  001(01)=31  002(02)=35  003(03)=aa  060(04)=30  061(05)=29  062(06)=ff  062(06)=aa
  063(07)=02  120(08)=aa  121(09)=07  122(0a)=28  123(0b)=30  180(0c)=02  181(0d)=31  182(0e)=38  183(0f)=aa  240(10)=30  241(11)=35  242(12)=3a  243(13)=33  000(00)=28  001(01)=30  002(02)=36
  003(03)=3a  060(04)=38  061(05)=aa  062(06)=02  063(07)=33  120(08)=3a  121(09)=33  122(0a)=30  123(0b)=29  180(0c)=31  181(0d)=35  182(0e)=aa  183(0f)=07  241(11)=29  242(12)=ff  242(12)=aa
  243(13)=01  000(00)=30  001(01)=29  002(02)=aa  003(03)=02  060(04)=aa  061(05)=07  062(06)=28  063(07)=30  120(08)=ff  120(08)=aa  121(09)=01  122(0a)=31  123(0b)=aa  180(0c)=28  181(0d)=30
  182(0e)=36  183(0f)=3a  240(10)=38  241(11)=aa  242(12)=02  243(13)=33  000(00)=31 *001(01)=aa  002(02)=02  003(03)=31  060(04)=36  061(05)=3a  062(06)=33  120(08)=02  121(09)=33  122(0a)=33
 *180(0c)=30 *181(0d)=29 *182(0e)=aa *183(0f)=02 *240(10)=aa *241(11)=07 *242(12)=28 *243(13)=30 *000(00)=33 *002(02)=07 *003(03)=28 *060(04)=aa *061(05)=02 *062(06)=31 *063(07)=38 *120(08)=28
 *121(09)=30 *122(0a)=35 *123(0b)=3a
EEprom Page:1 addresses(601f1000 - 601f2000): first free: 601f1b24
... All 15 pages.
Notes in the dumps here. The fields that have an * is the most recent version of that index so for example: *123(0b)=3a
means: this is EEPROM.read(123) will be this value. The 0b is the logical index computed for 123 and 3a is the value.
All the others like: 123(0b)=aa

Earlier up in this index are from earlier writes and will be compressed out on the next erase/write of this flash sector.
And there were 64 sectors erased and reflashed


EDIT: Note: the KISS version: had fewer sectors needing to flash, but again depending on how much your data changes may or may not be similar on your actual code:
Code:
iter: 4998 (59 59) em: 39 pages flashed: 4
iter: 4999 (59 59) em: 30 pages flashed: 4

*** End of run ***
Count of errors: 0
Strings:  0:1 25 1:15 15 2:(05:30) (05:30) 3:18 18 4:33 33 5:(06:30) (06:30)
Dump EEPROM pages
EEPROM length: 1080
Contents:
0:6 1:32 2:35 3:ff 4:ff 5:ff 6:ff 7:ff 8:ff 9:ff a:ff b:31 c:35 d:ff e:ff f:ff 
10:ff 11:ff 12:ff 13:ff 14:ff 15:28 16:30 17:35 18:3a 19:33 1a:30 1b:29 1c:ff 1d:ff 1e:ff 1f:31 
20:38 21:ff 22:ff 23:ff 24:ff 25:ff 26:ff 27:ff 28:ff 29:33 2a:33 2b:ff 2c:ff 2d:ff 2e:ff 2f:ff 
30:ff 31:ff 32:ff 33:28 34:30 35:36 36:3a 37:33 38:30 39:29 3a:ff 3b:ff 3c:ff 3d:ff 3e:ff 3f:ff 
40:ff 41:ff 42:ff 43:ff 44:ff 45:ff 46:ff 47:ff 48:ff 49:ff 4a:ff 4b:ff 4c:ff 4d:ff 4e:ff 4f:ff 
50:ff 51:ff 52:ff 53:ff 54:ff 55:ff 56:ff 57:ff 58:ff 59:ff 5a:ff 5b:ff 5c:ff 5d:ff 5e:ff 5f:ff 
60:ff 61:ff 62:ff 63:ff 64:ff 65:ff 66:ff 67:ff 68:ff 69:ff 6a:ff 6b:ff 6c:ff 6d:ff 6e:ff 6f:ff 
70:ff 71:ff 72:ff 73:ff 74:ff 75:ff 76:ff 77:ff 78:ff 79:ff 7a:ff 7b:ff 7c:ff 7d:ff 7e:ff 7f:ff 
80:ff 81:ff 82:ff 83:ff 84:ff 85:ff 86:ff 87:ff 88:ff 89:ff 8a:ff 8b:ff 8c:ff 8d:ff 8e:ff 8f:ff 
90:ff 91:ff 92:ff 93:ff 94:ff 95:ff 96:ff 97:ff 98:ff 99:ff 9a:ff 9b:ff 9c:ff 9d:ff 9e:ff 9f:ff 
a0:ff a1:ff a2:ff a3:ff a4:ff a5:ff a6:ff a7:ff a8:ff a9:ff aa:ff ab:ff ac:ff ad:ff ae:ff af:ff 
b0:ff b1:ff b2:ff b3:ff b4:ff b5:ff b6:ff b7:ff b8:ff b9:ff ba:ff bb:ff bc:ff bd:ff be:ff bf:ff 
c0:ff c1:ff c2:ff c3:ff c4:ff c5:ff c6:ff c7:ff c8:ff c9:ff ca:ff cb:ff cc:ff cd:ff ce:ff cf:ff 
d0:ff d1:ff d2:ff d3:ff d4:ff d5:ff d6:ff d7:ff d8:ff d9:ff da:ff db:ff dc:ff dd:ff de:ff df:ff 
e0:ff e1:ff e2:ff e3:ff e4:ff e5:ff e6:ff e7:ff e8:ff e9:ff ea:ff eb:ff ec:ff ed:ff ee:ff ef:ff 
f0:ff f1:ff f2:ff f3:ff f4:ff f5:ff f6:ff f7:ff f8:ff f9:ff fa:ff fb:ff fc:ff fd:ff fe:ff ff:ff 
100:ff 101:ff 102:ff 103:ff 104:ff 105:ff 106:ff 107:ff 108:ff 109:ff 10a:ff 10b:ff 10c:ff 10d:ff 10e:ff 10f:ff 
110:ff 111:ff 112:ff 113:ff 114:ff 115:ff 116:ff 117:ff 118:ff 119:ff 11a:ff 11b:ff 11c:ff 11d:ff 11e:ff 11f:ff 
120:ff 121:ff 122:ff 123:ff 124:ff 125:ff 126:ff 127:ff 128:ff 129:ff 12a:ff 12b:ff 12c:ff 12d:ff 12e:ff 12f:ff 
130:ff 131:ff 132:ff 133:ff 134:ff 135:ff 136:ff 137:ff 138:ff 139:ff 13a:ff 13b:ff 13c:ff 13d:ff 13e:ff 13f:ff 
140:ff 141:ff 142:ff 143:ff 144:ff 145:ff 146:ff 147:ff 148:ff 149:ff 14a:ff 14b:ff 14c:ff 14d:ff 14e:ff 14f:ff 
150:ff 151:ff 152:ff 153:ff 154:ff 155:ff 156:ff 157:ff 158:ff 159:ff 15a:ff 15b:ff 15c:ff 15d:ff 15e:ff 15f:ff 
160:ff 161:ff 162:ff 163:ff 164:ff 165:ff 166:ff 167:ff 168:ff 169:ff 16a:ff 16b:ff 16c:ff 16d:ff 16e:ff 16f:ff 
170:ff 171:ff 172:ff 173:ff 174:ff 175:ff 176:ff 177:ff 178:ff 179:ff 17a:ff 17b:ff 17c:ff 17d:ff 17e:ff 17f:ff 
180:ff 181:ff 182:ff 183:ff 184:ff 185:ff 186:ff 187:ff 188:ff 189:ff 18a:ff 18b:ff 18c:ff 18d:ff 18e:ff 18f:ff 
190:ff 191:ff 192:ff 193:ff 194:ff 195:ff 196:ff 197:ff 198:ff 199:ff 19a:ff 19b:ff 19c:ff 19d:ff 19e:ff 19f:ff 
1a0:ff 1a1:ff 1a2:ff 1a3:ff 1a4:ff 1a5:ff 1a6:ff 1a7:ff 1a8:ff 1a9:ff 1aa:ff 1ab:ff 1ac:ff 1ad:ff 1ae:ff 1af:ff 
1b0:ff 1b1:ff 1b2:ff 1b3:ff 1b4:ff 1b5:ff 1b6:ff 1b7:ff 1b8:ff 1b9:ff 1ba:ff 1bb:ff 1bc:ff 1bd:ff 1be:ff 1bf:ff 
1c0:ff 1c1:ff 1c2:ff 1c3:ff 1c4:ff 1c5:ff 1c6:ff 1c7:ff 1c8:ff 1c9:ff 1ca:ff 1cb:ff 1cc:ff 1cd:ff 1ce:ff 1cf:ff 
1d0:ff 1d1:ff 1d2:ff 1d3:ff 1d4:ff 1d5:ff 1d6:ff 1d7:ff 1d8:ff 1d9:ff 1da:ff 1db:ff 1dc:ff 1dd:ff 1de:ff 1df:ff 
1e0:ff 1e1:ff 1e2:ff 1e3:ff 1e4:ff 1e5:ff 1e6:ff 1e7:ff 1e8:ff 1e9:ff 1ea:ff 1eb:ff 1ec:ff 1ed:ff 1ee:ff 1ef:ff 
1f0:ff 1f1:ff 1f2:ff 1f3:ff 1f4:ff 1f5:ff 1f6:ff 1f7:ff 1f8:ff 1f9:ff 1fa:ff 1fb:ff 1fc:ff 1fd:ff 1fe:ff 1ff:ff 
200:ff 201:ff 202:ff 203:ff 204:ff 205:ff 206:ff 207:ff 208:ff 209:ff 20a:ff 20b:ff 20c:ff 20d:ff 20e:ff 20f:ff 
210:ff 211:ff 212:ff 213:ff 214:ff 215:ff 216:ff 217:ff 218:ff 219:ff 21a:ff 21b:ff 21c:ff 21d:ff 21e:ff 21f:ff 
220:ff 221:ff 222:ff 223:ff 224:ff 225:ff 226:ff 227:ff 228:ff 229:ff 22a:ff 22b:ff 22c:ff 22d:ff 22e:ff 22f:ff 
230:ff 231:ff 232:ff 233:ff 234:ff 235:ff 236:ff 237:ff 238:ff 239:ff 23a:ff 23b:ff 23c:ff 23d:ff 23e:ff 23f:ff 
240:ff 241:ff 242:ff 243:ff 244:ff 245:ff 246:ff 247:ff 248:ff 249:ff 24a:ff 24b:ff 24c:ff 24d:ff 24e:ff 24f:ff 
250:ff 251:ff 252:ff 253:ff 254:ff 255:ff 256:ff 257:ff 258:ff 259:ff 25a:ff 25b:ff 25c:ff 25d:ff 25e:ff 25f:ff 
260:ff 261:ff 262:ff 263:ff 264:ff 265:ff 266:ff 267:ff 268:ff 269:ff 26a:ff 26b:ff 26c:ff 26d:ff 26e:ff 26f:ff 
270:ff 271:ff 272:ff 273:ff 274:ff 275:ff 276:ff 277:ff 278:ff 279:ff 27a:ff 27b:ff 27c:ff 27d:ff 27e:ff 27f:ff 
280:ff 281:ff 282:ff 283:ff 284:ff 285:ff 286:ff 287:ff 288:ff 289:ff 28a:ff 28b:ff 28c:ff 28d:ff 28e:ff 28f:ff 
290:ff 291:ff 292:ff 293:ff 294:ff 295:ff 296:ff 297:ff 298:ff 299:ff 29a:ff 29b:ff 29c:ff 29d:ff 29e:ff 29f:ff 
2a0:ff 2a1:ff 2a2:ff 2a3:ff 2a4:ff 2a5:ff 2a6:ff 2a7:ff 2a8:ff 2a9:ff 2aa:ff 2ab:ff 2ac:ff 2ad:ff 2ae:ff 2af:ff 
2b0:ff 2b1:ff 2b2:ff 2b3:ff 2b4:ff 2b5:ff 2b6:ff 2b7:ff 2b8:ff 2b9:ff 2ba:ff 2bb:ff 2bc:ff 2bd:ff 2be:ff 2bf:ff 
2c0:ff 2c1:ff 2c2:ff 2c3:ff 2c4:ff 2c5:ff 2c6:ff 2c7:ff 2c8:ff 2c9:ff 2ca:ff 2cb:ff 2cc:ff 2cd:ff 2ce:ff 2cf:ff 
2d0:ff 2d1:ff 2d2:ff 2d3:ff 2d4:ff 2d5:ff 2d6:ff 2d7:ff 2d8:ff 2d9:ff 2da:ff 2db:ff 2dc:ff 2dd:ff 2de:ff 2df:ff 
2e0:ff 2e1:ff 2e2:ff 2e3:ff 2e4:ff 2e5:ff 2e6:ff 2e7:ff 2e8:ff 2e9:ff 2ea:ff 2eb:ff 2ec:ff 2ed:ff 2ee:ff 2ef:ff 
2f0:ff 2f1:ff 2f2:ff 2f3:ff 2f4:ff 2f5:ff 2f6:ff 2f7:ff 2f8:ff 2f9:ff 2fa:ff 2fb:ff 2fc:ff 2fd:ff 2fe:ff 2ff:ff 
300:ff 301:ff 302:ff 303:ff 304:ff 305:ff 306:ff 307:ff 308:ff 309:ff 30a:ff 30b:ff 30c:ff 30d:ff 30e:ff 30f:ff 
310:ff 311:ff 312:ff 313:ff 314:ff 315:ff 316:ff 317:ff 318:ff 319:ff 31a:ff 31b:ff 31c:ff 31d:ff 31e:ff 31f:ff 
320:ff 321:ff 322:ff 323:ff 324:ff 325:ff 326:ff 327:ff 328:ff 329:ff 32a:ff 32b:ff 32c:ff 32d:ff 32e:ff 32f:ff 
330:ff 331:ff 332:ff 333:ff 334:ff 335:ff 336:ff 337:ff 338:ff 339:ff 33a:ff 33b:ff 33c:ff 33d:ff 33e:ff 33f:ff 
340:ff 341:ff 342:ff 343:ff 344:ff 345:ff 346:ff 347:ff 348:ff 349:ff 34a:ff 34b:ff 34c:ff 34d:ff 34e:ff 34f:ff 
350:ff 351:ff 352:ff 353:ff 354:ff 355:ff 356:ff 357:ff 358:ff 359:ff 35a:ff 35b:ff 35c:ff 35d:ff 35e:ff 35f:ff 
360:ff 361:ff 362:ff 363:ff 364:ff 365:ff 366:ff 367:ff 368:ff 369:ff 36a:ff 36b:ff 36c:ff 36d:ff 36e:ff 36f:ff 
370:ff 371:ff 372:ff 373:ff 374:ff 375:ff 376:ff 377:ff 378:ff 379:ff 37a:ff 37b:ff 37c:ff 37d:ff 37e:ff 37f:ff 
380:ff 381:ff 382:ff 383:ff 384:ff 385:ff 386:ff 387:ff 388:ff 389:ff 38a:ff 38b:ff 38c:ff 38d:ff 38e:ff 38f:ff 
390:ff 391:ff 392:ff 393:ff 394:ff 395:ff 396:ff 397:ff 398:ff 399:ff 39a:ff 39b:ff 39c:ff 39d:ff 39e:ff 39f:ff 
3a0:ff 3a1:ff 3a2:ff 3a3:ff 3a4:ff 3a5:ff 3a6:ff 3a7:ff 3a8:ff 3a9:ff 3aa:ff 3ab:ff 3ac:ff 3ad:ff 3ae:ff 3af:ff 
3b0:ff 3b1:ff 3b2:ff 3b3:ff 3b4:ff 3b5:ff 3b6:ff 3b7:ff 3b8:ff 3b9:ff 3ba:ff 3bb:ff 3bc:ff 3bd:ff 3be:ff 3bf:ff 
3c0:ff 3c1:ff 3c2:ff 3c3:ff 3c4:ff 3c5:ff 3c6:ff 3c7:ff 3c8:ff 3c9:ff 3ca:ff 3cb:ff 3cc:ff 3cd:ff 3ce:ff 3cf:ff 
3d0:ff 3d1:ff 3d2:ff 3d3:ff 3d4:ff 3d5:ff 3d6:ff 3d7:ff 3d8:ff 3d9:ff 3da:ff 3db:ff 3dc:ff 3dd:ff 3de:ff 3df:ff 
3e0:ff 3e1:ff 3e2:ff 3e3:ff 3e4:ff 3e5:ff 3e6:ff 3e7:ff 3e8:ff 3e9:ff 3ea:ff 3eb:ff 3ec:ff 3ed:ff 3ee:ff 3ef:ff 
3f0:ff 3f1:ff 3f2:ff 3f3:ff 3f4:ff 3f5:ff 3f6:ff 3f7:ff 3f8:ff 3f9:ff 3fa:ff 3fb:ff 3fc:ff 3fd:ff 3fe:ff 3ff:ff 

Raw Data
EEprom Page:0 addresses(601f0000 - 601f1000): first free: 601f07ec
 *000(00)=06  001(01)=31  002(02)=35  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff  001(01)=32  002(02)=35  001(01)=31  002(02)=ff
  001(01)=32  002(02)=35  001(01)=31  002(02)=ff *001(01)=32 *002(02)=35
EEprom Page:1 addresses(601f1000 - 601f2000): first free: 601f1000

EEprom Page:2 addresses(601f2000 - 601f3000): first free: 601f2002
 *011(03)=31
EEprom Page:3 addresses(601f3000 - 601f4000): first free: 601f3002
 *012(00)=35
EEprom Page:4 addresses(601f4000 - 601f5000): first free: 601f4000

EEprom Page:5 addresses(601f5000 - 601f6000): first free: 601f5006
 *021(01)=28 *022(02)=30 *023(03)=35
EEprom Page:6 addresses(601f6000 - 601f7000): first free: 601f6008
 *024(00)=3a *025(01)=33 *026(02)=30 *027(03)=29
EEprom Page:7 addresses(601f7000 - 601f8000): first free: 601f7002
 *031(03)=31
EEprom Page:8 addresses(601f8000 - 601f9000): first free: 601f8002
 *032(00)=38
EEprom Page:9 addresses(601f9000 - 601fa000): first free: 601f9000

EEprom Page:10 addresses(601fa000 - 601fb000): first free: 601fa004
 *041(01)=33 *042(02)=33
EEprom Page:11 addresses(601fb000 - 601fc000): first free: 601fb000

EEprom Page:12 addresses(601fc000 - 601fd000): first free: 601fc002
 *051(03)=28
EEprom Page:13 addresses(601fd000 - 601fe000): first free: 601fd008
 *052(00)=30 *053(01)=36 *054(02)=3a *055(03)=33
EEprom Page:14 addresses(601fe000 - 601ff000): first free: 601fe004
 *056(00)=30 *057(01)=29
As only the one EEPROM page changed at all. The others just kept the first writes...
 

Attachments

  • t4_eeprom_test_stress-220714a.zip
    4.2 KB · Views: 22
Just a quick update, I updated my version of the sketch to have additional debug stuff in it.

I did update the version of the code that you are using to match. And it did run through 5000 iterations without an error discovered...
i.e. all of the read values matched the write values...

I am mainly posting here as a way to remember some of the debug stuff later.

EDIT: Note: the KISS version: had fewer sectors needing to flash, but again depending on how much your data changes may or may not be similar on your actual code:

..

OK

The read/write of the "EEPROM" occurs every time I receive outside air temperature/humidity measurements (every 62 minutes) and water temperature/level measurements (every 110 minutes). The air temp/humidity (2 strings) vary often. The time I receive this air data (1 string, hour/minute) varies every 62 minutes. For the water(eau) temp/level (2 strings) water temperature varies approx. 4 times per day for the lsb and level 10 times per day for the lsb due to the precision of the sensor. The time I rcv the water data (1 string, hour/minute) varies every 110 minutes.
 
Just to keep things in perspective, the fastest rate here is about once per hour.

If didn't have any wear leveling at all, just wrote to a fixed location and Teensy's EEPROM emulation didn't wear level at all, so every hour you ended up erasing a sector and writing it with new data in the same physical location, it'd still take 11.4 years to reach the Winbond's rated flash endurance of 100K erase/write cycles.
 
Just to keep things in perspective, the fastest rate here is about once per hour.

If didn't have any wear leveling at all, just wrote to a fixed location and Teensy's EEPROM emulation didn't wear level at all, so every hour you ended up erasing a sector and writing it with new data in the same physical location, it'd still take 11.4 years to reach the Winbond's rated flash endurance of 100K erase/write cycles.

Yes I know. I wanted to do a library for worst use cases for other projects with more data and more frequent updates. I may do them one day. Sorry I bothered y'all but thought the library would be useful for others too. I'm always looking to get a new Ferrari for the price of a Ford.
 
Please update TeensyDuino to just released version 1.57.

Using that here and Running p#2 code here gives what seems to be a correct answer:
Code:
0.00 0 4095 
0.75 1265 1393 
0.85 1538 1294 
1.00 1947 1143 
1.20 2276 1024 
1.50 2552 916 
2.00 2848 816 
2.50 3004 759 
3.00 3130 713 
5.00 3392 617 
30.00 3839 475 
100.00 4095 0

That is with the write uncommented:
Code:
...
    for (int i = 0; i < 8; i++) {

      BYTE = FocusCal[n].bytes[i];
      addr = 255 + (i + 1) * (n + 1);
      EEPROM.write(addr,  BYTE);
...

When run without the write I got NAN's because the EEPROM content was invalid.

Writing to EEPROM is non-trivial and should only be done using the PJRC supplied code.

For USE with STRUCTS you have hardcoded an 8 byte workaround. There is a better way, See Get() and Put() at the following:
docs.arduino.cc/learn/built-in-libraries/eeprom
 
That is strange that it works for you, but not me. It started to work for me after I changed the addr to

Code:
addr = 255;
  for (int nn=0;nn<12;nn++){
  for (int ii=0;ii<8;ii++){  
    
    BYTE=FocusCal[nn].bytes[ii];
    addr++;
    //EEPROM.write(addr,  BYTE);
    FocusCalr[nn].bytes[ii]= EEPROM.read(addr);

I mean, did the original code work for you if running second time the write commented (after first writing to EEPROM)
 
That is strange that it works for you, but not me. It started to work for me after I changed the addr to

...
I mean, did the original code work for you if running second time the write commented (after first writing to EEPROM)

Yes, the posted code worked here.

For better code that would not have hardcoded work/hack look into replacing with indicated get() and put() that are designed to work with such Structs or other declared types.
 
But the get() and put() have also reported problems. I rather would write directly without library to EEPROM if I would know how (or would have time to look into it)

I had already deleted the posts above before getting reply as got it working with the mentioned change. Here is the working code if someone is interested what we are discussing about.

Code:
#include <EEPROM.h>

  float     FocusCalib[12][4];

    struct CalibStuct{   
      float    trueReading;
      uint16_t toLens; //PWM to lens
      uint16_t fromLens; //analogue reading from lens
    };

    typedef union { 
      CalibStuct CalibData; 
      uint8_t bytes[12]; 
    } CALIB_UNION_T;

    CALIB_UNION_T FocusCal[12];
    CALIB_UNION_T FocusCalr[12];


    uint8_t BYTE;
    uint16_t addr;



void setup() {
 delay(3000);

  
        FocusCalib[0][0]   = 0.00;   FocusCalib[0][1]   = 0.0   ; FocusCalib[0][3]   = 4095.0;
        FocusCalib[1][0]   = 0.75;   FocusCalib[1][1]   = 1265.0; FocusCalib[1][3]   = 1393.0;
        FocusCalib[2][0]   = 0.85;   FocusCalib[2][1]   = 1538.0; FocusCalib[2][3]   = 1294.0;
        FocusCalib[3][0]   = 1.00;   FocusCalib[3][1]   = 1947.0; FocusCalib[3][3]   = 1143.0;
        FocusCalib[4][0]   = 1.20;   FocusCalib[4][1]   = 2276.0; FocusCalib[4][3]   = 1024.0;
        FocusCalib[5][0]   = 1.50;   FocusCalib[5][1]   = 2552.0; FocusCalib[5][3]   = 916.0 ;
        FocusCalib[6][0]   = 2.00;   FocusCalib[6][1]   = 2848.0; FocusCalib[6][3]   = 816.0 ;
        FocusCalib[7][0]   = 2.50;   FocusCalib[7][1]   = 3004.0; FocusCalib[7][3]   = 759.0 ;
        FocusCalib[8][0]   = 3.00;   FocusCalib[8][1]   = 3130.0; FocusCalib[8][3]   = 713.0 ;
        FocusCalib[9][0]   = 5.00;   FocusCalib[9][1]   = 3392.0; FocusCalib[9][3]   = 617.0 ;
        FocusCalib[10][0]  = 30.00;  FocusCalib[10][1]  = 3839.0; FocusCalib[10][3]  = 475.0 ;
        FocusCalib[11][0]  = 100.0;  FocusCalib[11][1]  = 4095.0; FocusCalib[11][3]  = 0.0   ; 


  for (int i=0;i<12;i++){

    FocusCal[i].CalibData.trueReading = FocusCalib[i][0];
    FocusCal[i].CalibData.toLens      = FocusCalib[i][1];
    FocusCal[i].CalibData.fromLens    = FocusCalib[i][3];
   }  

  addr = 255;
  for (int nn=0;nn<12;nn++){
  for (int ii=0;ii<8;ii++){  
    
    BYTE=FocusCal[nn].bytes[ii];
    addr++;
    //EEPROM.write(addr,  BYTE);
    FocusCalr[nn].bytes[ii]= EEPROM.read(addr);
    
    
    }
  
  Serial.print(FocusCalr[nn].CalibData.trueReading );Serial.print(" ");Serial.print(FocusCalr[nn].CalibData.toLens);Serial.print(" ");Serial.print(FocusCalr[nn].CalibData.fromLens);
  Serial.println(" ");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

For some reason if I have the addr as addr = 255 + (ii + 1) * (nn + 1); it does not work for me.

So this is the code that fails for me, just confirmed it still does.

Code:
#include <EEPROM.h>

  float     FocusCalib[12][4];

    struct CalibStuct{   
      float    trueReading;
      uint16_t toLens; //PWM to lens
      uint16_t fromLens; //analogue reading from lens
    };

    typedef union { 
      CalibStuct CalibData; 
      uint8_t bytes[12]; 
    } CALIB_UNION_T;

    CALIB_UNION_T FocusCal[12];
    CALIB_UNION_T FocusCalr[12];


    uint8_t BYTE;
    uint16_t addr;



void setup() {
 delay(3000);

  
        FocusCalib[0][0]   = 0.00;   FocusCalib[0][1]   = 0.0   ; FocusCalib[0][3]   = 4095.0;
        FocusCalib[1][0]   = 0.75;   FocusCalib[1][1]   = 1265.0; FocusCalib[1][3]   = 1393.0;
        FocusCalib[2][0]   = 0.85;   FocusCalib[2][1]   = 1538.0; FocusCalib[2][3]   = 1294.0;
        FocusCalib[3][0]   = 1.00;   FocusCalib[3][1]   = 1947.0; FocusCalib[3][3]   = 1143.0;
        FocusCalib[4][0]   = 1.20;   FocusCalib[4][1]   = 2276.0; FocusCalib[4][3]   = 1024.0;
        FocusCalib[5][0]   = 1.50;   FocusCalib[5][1]   = 2552.0; FocusCalib[5][3]   = 916.0 ;
        FocusCalib[6][0]   = 2.00;   FocusCalib[6][1]   = 2848.0; FocusCalib[6][3]   = 816.0 ;
        FocusCalib[7][0]   = 2.50;   FocusCalib[7][1]   = 3004.0; FocusCalib[7][3]   = 759.0 ;
        FocusCalib[8][0]   = 3.00;   FocusCalib[8][1]   = 3130.0; FocusCalib[8][3]   = 713.0 ;
        FocusCalib[9][0]   = 5.00;   FocusCalib[9][1]   = 3392.0; FocusCalib[9][3]   = 617.0 ;
        FocusCalib[10][0]  = 30.00;  FocusCalib[10][1]  = 3839.0; FocusCalib[10][3]  = 475.0 ;
        FocusCalib[11][0]  = 100.0;  FocusCalib[11][1]  = 4095.0; FocusCalib[11][3]  = 0.0   ; 


  for (int i=0;i<12;i++){

    FocusCal[i].CalibData.trueReading = FocusCalib[i][0];
    FocusCal[i].CalibData.toLens      = FocusCalib[i][1];
    FocusCal[i].CalibData.fromLens    = FocusCalib[i][3];
   }  

 
  for (int nn=0;nn<12;nn++){
  for (int ii=0;ii<8;ii++){  
    
    BYTE=FocusCal[nn].bytes[ii];
    addr = 255 + (ii + 1) * (nn + 1);
    //EEPROM.write(addr,  BYTE);
    FocusCalr[nn].bytes[ii]= EEPROM.read(addr);
    
    
    }
  
  Serial.print(FocusCalr[nn].CalibData.trueReading );Serial.print(" ");Serial.print(FocusCalr[nn].CalibData.toLens);Serial.print(" ");Serial.print(FocusCalr[nn].CalibData.fromLens);
  Serial.println(" ");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}
The EEPROM read is ok if done with EEPROM.write(addr, BYTE);, after first time using that the data should be on EEPROM, but I get partially corrupted data if just reading the EEPROM

Note: the above code is in transition from hardcoded calibration to calibration via UI, and happy I got now the EEPROM working.
 
Last edited:
Tested here on a T_4.1 that has a larger EEPROM space.

Didn't do the math - not sure if the initial math may be running off the end? The addr++ method versus the i+1*(n+1) math would push farther into the addr space?

This is PJRC Teensy, the get and put code should have No Trouble! If problems are seen - it will be fixed.
 
I still looked into it, and the problem very clearly was the "addr = 255 + (ii + 1) * (nn + 1);" it is just a brain fart and gives overlapping addresses. It should have been "addr1 = 255 + nn*8 + ii +1;" but the addr++; works as well. So this was just my coding error, nothing to do with the EEPROM.

I still do wonder how to write and read a specific EEPROM position without the library, should not be too difficult?

For my purpose it does not need to be fast, can have delays if needed, and writing does not hapen often, only when lens is calibrated. Reading happens at every start once everything to a global variable.
 
Last edited:
When TeensyDuino installed there is a copy of the EEPROM code for the Teensy4 family directory. It is not a simple matter of directly writing.

That code is non-trivial, it works with the processor reserved area provisions in onboard FLASH and then adds wear leveling on top of that. Code is well designed and well tested. It has likely evolved over years of Teensy, as needed to fit each new processor. For the 4.x @KurtE recently resurfaced test code written during T_4.0 Beta years ago. If that code is located - or the sources the method involved can be observed.
 
It works now, and that is fine for the prototyping. If the license would be MIT, that would be fine.

My application does not require any wear leveling.
 
Back
Top