fabriziop / EEWL

The EEWL library allows to extend the EEPROM life by distributing data writes along a circular buffer.
GNU Lesser General Public License v3.0
10 stars 1 forks source link

EEPROM data corrupted #1

Closed dolence closed 1 year ago

dolence commented 1 year ago

I'm trying to use this library on my project. At first it seemed to fit perfectly my needings, but unfortunately I'm having a lot of data corruption issues.

When I save data on epprom, wait few seconds and turn the power off and turn it on again now and then eepParam.get(eepromParametros) return false causing the eeprom data to be reinitialized to the default values.

I have two blocks/circular buffers as you can see below:

Struct declaration:

#define EEPROM_PARAMETERS_LEN   30          /* 30 bytes x 40 (lenght) = 1200 bytes*/     
#define EEPROM_PARAMETROS_START 1

#define EEPROM_CONTADOR_LEN     200         /* 3 bytes x 200 (length) = 600 bytes */
#define EEPROM_CONTADOR_START   1300

struct
{
  uint8_t e_mem = 2;
  uint8_t e_aut = 1;
  uint8_t e_buz = 1;
  uint8_t e_vel[6] =  { 1, 2, 3, 4, 5, 6 };
  uint8_t e_tmp[6] =  { 1, 2, 3, 4, 5, 6 };
  uint8_t e_tmp_dec[6] =  { 0, 0, 0, 0, 0, 0 };
  uint8_t e_itv[6] =  { 1, 2, 3, 4, 5, 6 };
  uint8_t e_acl[6] =  { 1, 5, 10, 15, 20, 25 };
  uint8_t e_dcl[6] =  { 1, 5, 10, 15, 20, 25 };
} eepromParametros;

struct
{
  uint16_t e_cnt = 0;  
} eepromContadores;

EEWL eepParam(eepromParametros, EEPROM_PARAMETERS_LEN, EEPROM_PARAMETROS_START);
EEWL eepCont(eepromContadores, EEPROM_CONTADOR_LEN, EEPROM_CONTADOR_START);   

Setup() portion

  eepParam.begin();
  eepCont.begin();

  delay(10);

  if (eepParam.get(eepromParametros))  
  {       
    rtttl::begin(BUZZER_PIN, rttl_init_ok);
    while( !rtttl::done() ) rtttl::play();                 
  } else {  
    //eepParam.fastFormat();    
    //eepCont.fastFormat();

    rtttl::begin(BUZZER_PIN, rttl_init_fail);
    while( !rtttl::done() ) rtttl::play(); 

    rtttl::begin(BUZZER_PIN, rttl_init_ok);
    while( !rtttl::done() ) rtttl::play(); 
  }

  delay(2000);
  leParametros(0);
  leContadores();

Everytime a button is pressed I read the parameters and save them again directly after:

else if ( m1Btn.pressed() ) {
    beepa();    
    is_redraw = 1;

    leParametros(1);
    gravaParametros();
  }
  else if ( m2Btn.pressed() ) {        
    is_redraw = 1;
    leParametros(2);
    gravaParametros();
    beepa();
  }
  else if ( m3Btn.pressed() ) {    
    is_redraw = 1;
    leParametros(3);
    gravaParametros();
    beepa();    
  }
  else if ( m4Btn.pressed() ) {    
    is_redraw = 1;
    leParametros(4);
    gravaParametros();
    beepa();    
  }
  else if ( m5Btn.pressed() ) {    
    is_redraw = 1;
    leParametros(5);
    gravaParametros();
    beepa();    
  }
  else if ( m6Btn.pressed() ) {
    is_redraw = 1;    
    leParametros(6);
    gravaParametros();
    beepa();    
  }

void leParametros(uint8_t memoria) {
  eepParam.get(eepromParametros);

  if(memoria != 0) g_mem = memoria;
    else g_mem = eepromParametros.e_mem;  
  g_aut = eepromParametros.e_aut;
  g_buz = eepromParametros.e_buz;

  if(g_mem >= 1 && g_mem <= 6) {
    g_vel = eepromParametros.e_vel[g_mem-1];
    g_tmp = eepromParametros.e_tmp[g_mem-1];
    g_tmp_dec = eepromParametros.e_tmp_dec[g_mem-1];
    g_itv = eepromParametros.e_itv[g_mem-1];
    g_acl = eepromParametros.e_acl[g_mem-1];
    g_dcl = eepromParametros.e_dcl[g_mem-1];
  }    
}

void gravaParametros() {
  eepromParametros.e_mem = g_mem;  
  eepromParametros.e_aut = g_aut;
  eepromParametros.e_buz = g_buz;

  if(g_mem >= 1 && g_mem <= 6) {
    eepromParametros.e_vel[g_mem-1] = g_vel;
    eepromParametros.e_tmp[g_mem-1] = g_tmp;
    eepromParametros.e_tmp_dec[g_mem-1] = g_tmp_dec;
    eepromParametros.e_itv[g_mem-1] = g_itv;
    eepromParametros.e_acl[g_mem-1] = g_acl;
    eepromParametros.e_dcl[g_mem-1] = g_dcl;
  }

  eepParam.put(eepromParametros);
}

What I'am doing wrong?

EDIT: forgot to mention, I'm using an ATMEGA64. This microcontroller have 2048 bytes eeprom.

fabriziop commented 1 year ago

Hi dolence,

for each block of data stored by EEWL there is also 1 control byte, so the first buffer has size 30x40+1x40 = 1240. You start the second buffer at 1300 so that is ok. The second buffer has size 3x200+1x200 = 800 that is bad because the start at 1300 plus a size of 800 overflows the EEPROM size. I hope this can help.

Fabrizio.

dolence commented 1 year ago

Hi Fabrizio! Thank you for your fast response :)

I think I didn't get it right... Second block for example:

uint16_t e_cnt = 0; 2 bytes + 1 control byte = 3 bytes Why 1x200 added to the 3x200? Souldn't it be 3*200 = 600?

Equally, first block should be: 39 bytes + 1 control byte = 40 and 40*30 = 1200?

fabriziop commented 1 year ago

Of course you are right. You have already taken into account the extra byte. It's my mistake. From the pieces of code that you posted, I do not see anything wrong. Could there be something in the rest? Another suggestion: I never tested EEWL on an ATMEGA64, so may be useful to see if the example countPowerCycles works properly on ATMEGA64.