Personally, I'm using this class definition or let say lib modification:
class _EEPROM
{
public:
_EEPROM();
/* functions & methods */
uint8_t read_byte (uint16_t __address)
{ return(eeprom_read_byte((const uint8_t *)__address)); }
uint16_t read_word (uint16_t __address)
{ return(eeprom_read_word((const uint16_t *)__address)); }
uint32_t read_dword (uint16_t __address)
{ return(eeprom_read_dword((const uint32_t *)__address)); }
uint64_t read_qword (uint16_t __address);
void read_block (void *__data, uint16_t __address, size_t n)
{ eeprom_read_block(__data, (const void *)__address, n); }
void write_byte (uint16_t __address, uint8_t value)
{ eeprom_write_byte((uint8_t *)__address, value); }
void write_word (uint16_t __address, uint16_t value)
{ eeprom_write_word((uint16_t *)__address, value); }
void write_dword (uint16_t __address, uint32_t value)
{ eeprom_write_dword((uint32_t *)__address, value); }
void write_qword (uint16_t __address, uint64_t value)
{ this->write_block((const void *)&value, __address, 8); }
void write_block (const void *__data, uint16_t __address, size_t n)
{ eeprom_write_block(__data, (void *)__address, n); }
void update_byte (uint16_t __address, uint8_t value);
void update_word (uint16_t __address, uint16_t value)
{ this->update_block((const void *)&value, __address, 2); }
void update_dword(uint16_t __address, uint32_t value)
{ this->update_block((const void *)&value, __address, 4); }
void update_qword(uint16_t __address, uint64_t value)
{ this->update_block((const void *)&value, __address, 8); }
void update_block(const void *__data, uint16_t __address, size_t n);
};
// --------------------------------------------------------------------------------------
//
// ****************
// * read_qword *
// ****************
//
// Read 8-byte unsigned integer from EEPROM address
uint64_t _EEPROM::read_qword(uint16_t __address)
{
uint64_t data;
this->read_block(&data,__address, 8);
return(data);
}
// --------------------------------------------------------------------------------------
//
// *****************
// * update_byte *
// *****************
//
// Update one byte to EEPROM address (write only if it is different)
void _EEPROM::update_byte(uint16_t __address, uint8_t value)
{ if(this->read_byte(__address) != value) this->write_byte(__address, value); }
// --------------------------------------------------------------------------------------
//
// ******************
// * update_block *
// ******************
//
// Update n-byte unsigned integer to EEPROM address (write only if it is different)
void _EEPROM::update_block(const void *__data, uint16_t __address, size_t n)
{
uint8_t *_p_data = (uint8_t *)__data;
while(n--) {
if(this->read_byte(__address) != *_p_data) this->write_byte(__address, *_p_data);
__address++;
_p_data++;
}
}