Hi everyone! I am executing the following code:
main.cpp
#include "../lib/lib2/lib2.h"
using namespace std;
// define pins
#define CTL1 2
#define CTL2 3
LIB2 * eeprom;
void (* reboot) (void) = 0;
void setup() {
Serial.begin(115200);
while(!Serial && !Serial.available()) {}
Log.begin(LOG_LEVEL_VERBOSE, &Serial);
pinMode(CTL1, INPUT);
pinMode(CTL2, INPUT);
eeprom = new LIB2();
eeprom->initParam("state", sizeof(uint8_t), (uint16_t *)0);
eeprom->initParam("mode", sizeof(uint8_t), (uint16_t *)0);
eeprom->begin();
eeprom->increment("state");
}
void loop() {
if(digitalRead(CTL1) == HIGH) {
eeprom->increment("mode");
}
if(digitalRead(CTL2) == HIGH) {
eeprom->reset();
reboot();
}
}
lib2.cpp
#include "lib2.h"
using namespace std;
LIB2::LIB2() {}
/**
* Add parameter
* @method LIB2::init
*/
void LIB2::begin() {
if(_DATA.size() <= 0) {
exit(201);
}
firstStart();
if(!_FIRST_START) {
readMem();
}
}
/**
* [LIB2::firstStart description]
* @method LIB2::firstStart
*/
void LIB2::firstStart() {
uint8_t * addr = &_FSBIT;
uint8_t f = eeprom_read_byte(addr);
if(f <= 0) {
Log.notice(F("\n\n::: First start: %d\n"), f);
_FIRST_START = true;
reset();
eeprom_write_byte(addr, 0x0F);
eepromSave();
} else {
Log.notice(F("\n\n::: Not empty: %d\n"), f);
_FIRST_START = false;
}
}
/**
* Reset EEPROM to "defaults"
*/
void LIB2::reset() {
uint16_t addr = 0;
uint8_t dump[16];
memset(dump, 0x00, sizeof(dump));
while(addr < E2END) {
eeprom_write_block(dump, (void *)addr, sizeof(dump));
eeprom_busy_wait();
addr += sizeof(dump);
}
}
/**
* Read data from EEPROM
* @method LIB2::readMem
*/
void LIB2::readMem() {
auto i = _DATA.begin();
for (; i < _DATA.end(); i++) {
if((i->addr + (i->size * 8)) < E2END) {
eeprom_read_block(i->value, (void *)i->addr, i->size);
eeprom_busy_wait();
Log.notice(F("READ %s = %d from %d -> %d \n"), i->param, i->value, i->addr, i->size);
}
}
}
/**
* Write data to EEPROM
* @method LIB2::eepromSave
*/
void LIB2::eepromSave() {
auto i = _DATA.begin();
for (; i < _DATA.end(); i++) {
if(_FIRST_START) {
Log.notice(F("WRITE %s : %d -> %d of %d\n"), i->param, i->value, i->addr, i->size);
eeprom_write_block(i->value, (void *)i->addr, i->size);
} else {
Log.notice(F("UPDATE %s : %d -> %d of %d\n"), i->param, i->value, i->addr, i->size);
eeprom_update_block(i->value, (void *)i->addr, i->size);
}
}
}
/**
* Update the only parameter
* @method LIB2::eepromSaveParam
* @param param [description]
*/
void LIB2::eepromSaveParam(const char *param) {
auto i = _DATA.begin();
for (; i < _DATA.end(); i++) {
if(strcmp(i->param, param) == 0) {
Log.notice(F("UPDATE %s : %d | %d -> %d\n"), i->param, i->value, i->addr, i->size);
eeprom_write_block(i->value, (void *)i->addr, i->size);
eeprom_busy_wait();
break;
}
}
}
/**
* Dummy counter incrementor
* @method stat
* @param param [description]
*/
void LIB2::increment(char const * param) {
auto i = _DATA.begin();
for (; i < _DATA.end(); i++) {
if(strcmp(i->param, param) == 0) {
i->value = (void *)((uint16_t)i->value + 1);
Log.notice(F("+ %s = %d\n"), i->param, i->value);
break;
}
}
eepromSaveParam(param);
}
lib2.h
#ifndef LIB2_H
#define LIB2_H
#include <ArduinoLog.h>
#include <avr/eeprom.h>
#include <vector>
#define eeprom_busy_wait() \
do {} while (!eeprom_is_ready())
class LIB2 {
public:
String tmp();
LIB2();
~LIB2() {
eepromSave();
_DATA.clear();
};
void begin();
void eepromSave();
void eepromSaveParam(char const * param);
void reset();
void increment(char const * param);
template <typename T> void initParam(char const * param, size_t s, T * value = NULL) {
_D a;
if(_DATA.size() > 0) {
_D pelt = _DATA[_DATA.size() - 1];
a.addr = pelt.addr + pelt.size;
} else {
a.addr = _MEMBIT;
}
a.size = s;
a.param = param;
a.value = value;
_DATA.push_back(a);
};
protected:
void readMem();
private:
uint8_t _FSBIT = 0;
uint8_t _MEMBIT = 16;
struct _D {
char const * param;
void * value;
size_t size = 0;
uint16_t addr = 0;
};
std::vector<_D> _DATA;
bool _FIRST_START = false;
void firstStart();
};
#endif
The procedure:
- reset eeprom
- change parameters
- check data that were stored
MCU: atmega328p
Once it reads back parameters from EEPROM, they are anything but required uint16s.
Anyone has an idea where I messed up?
Thanks,