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
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.