EEPROM.put() & EEPROM.get() question

Hi,

I need to make my program compatible with AVR micros as well as SAMD21 ones that dont have a onboard EEPROM. In the latter case an external I2C EEPROM will be used.

So I need to redirect control of all EEPROM access to a separate function which will handle EEPROM according to the specific hardware available. Something like this :

byte getEEPROM(int addr){

#ifdef AVR

  return (EEPROM.read(addr));

#endif

#ifdef SAMD21

   return (readEEPROM(0x50,addr));     // Function that reads external I2C EEPROM

#endif}

My question is how to do something similar with EEPROM.get() and EEPROM.put() which can handle different data types.

EEPROM.get(address, data) ;

According to Arduino reference:

"data: the data to read, can be a primitive type (eg. float) or a custom struct address "
In practice data takes the name of the variable that will hold the contents of EEPROM andneeds to be initialised beforehand.

So, how can I pass this argument from my own function in a similar way as above?

You can look at the source code for the EEPROM library and do something similar.

On my Windows machine: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\src

Then, make your own for your hardware and make sure your library declares EEPROM
and then, based on the architecture, either include the standard eeprom.h or your custom eeprom.h

blh64:
You can look at the source code for the EEPROM library and do something similar.

I thought of that too. Already had a look at the EEPROM.h code but... couldn't figure out how it works. Guess my C++ skills are not up to it.

Looks like the only parts of EEPROM.h you need to change are the two lines that read and write EEPROM:

    uint8_t operator*() const            { return eeprom_read_byte( (uint8_t*) index ); }
    EERef &operator=( uint8_t in )       { return eeprom_write_byte( (uint8_t*) index, in ), *this;  }

You can probably do that by making these two #includes conditional and defining your own ‘eeprom_read_byte’ and ‘eeprom_write_byte’ functions:

#include <avr/eeprom.h>
#include <avr/io.h>

With the external eeprom you need to pay attention to page size and page boundaries. You can go wrong with a simple use of .put() if you try to block write across a boundary. The data will wrap to memory at the beginning of the page.

This is not an issue if you just define your own read() and write() functions since they act on bytes. On the other hand, this would be a wildly inefficient way to deal with an i2c device as it would involve doing an entire i2c transmission for every byte.

Depending on how much EEPROM access you will be doing, this may or may not matter.

Thank you all for your input.
Let me just add that I only use the EEPROM to store systems settings (variables) that are rarely changed.
The memory address of each variable is constant and set by #define s in the program. So there is no risk of adresss boundary overflow or anything like that at runtime.