So much grief - everyone spinning their wheels as the Arduino "core" code gets progressively more screwed up (as well as things that NEED fixing totally ignored).
THIS simple little bit of code solves all the problems:
/*
Copyright (c) 2017 Roger A. Krupski
All rights reserved.
*/
#ifndef _AVR_UNIVERSAL_EEPROM_H_
#define _AVR_UNIVERSAL_EEPROM_H_
// universal eeprom READ
template <typename T> T eepromRead (T *__address)
{
T __value;
uint8_t x = sizeof (__value);
uint8_t *ptr = (uint8_t *)(&__value);
while (x--) {
*(ptr + x) = (eeprom_read_byte ((uint8_t *)(__address) + x));
}
return __value;
}
// universal eeprom WRITE
template <typename T> void eepromWrite (void *__address, T __value)
{
uint8_t x = sizeof (__value);
uint8_t *ptr = (uint8_t *)(&__value);
while (x--) {
eeprom_write_byte (((uint8_t *)(__address) + x), *(ptr + x));
}
}
// universal eeprom UPDATE
template <typename T> void eepromUpdate (void *__address, T __value)
{
uint8_t x = sizeof (__value);
uint8_t *ptr = (uint8_t *)(&__value);
while (x--) {
eeprom_update_byte (((uint8_t *)(__address) + x), *(ptr + x));
}
}
#endif
Stick this into the AVR toolchain under [b]avr/include/avr[/b] and give it a name (I named mine "
** **universal_eeprom.h** **
"), then in "[b]eeprom.h[/b]" add this line (at the bottom - shown in red):
[b]/*@}*/
#ifdef __cplusplus
}
#endif
/* modified RAK */
[color=red]#include "universal_eeprom.h"[/color]
#endif /* !__ASSEMBLER__ */
#endif /* E2END || defined(__DOXYGEN__) || defined(__COMPILING_AVR_LIBC__) */
#endif /* !_AVR_EEPROM_H_ */
[/b]
Then in your sketches, simply include <avr/eeprom.h> instead of <EEPROM.h>, and use the eeprom variables as you would any other... example:
#include <avr/eeprom.h>
uint16_t ee_var EEMEM; // define the var, EEMEM places it in eeprom
uint16_t value = 1234; // value in SRAM
eepromWrite ((uint16_t *) ee_var, (uint16_t) value); // put "value" into "ee_var"
value = eepromRead ((uint16_t *) ee_var); // read eeprom "ee_var" into "value"
No matter what size variable you use, it works. Use floats or double. Use UINT64_t. No problem.
No need to go screwing around with splitting up variables that are larger than 8 bits (then what about read and write order? Big endian? Little endian? How many bytes does a double need? Where does the next var start?)
No need to worry about this BS. Just give the variables NAMES and reference them by NAME and all is taken care of.
Or... throw libraries/src/EEPROM.h into the trash can and replace it with the above, then add an "#include <avr/eeprom.h> at the top so that it can call the GCC code. You do lose "readblock", "writeblock" and "updateblock", but these are no faster than byte-for-byte copying and, worse, the syntax is backwards from what other similar functions use (for example, strncpy is strncpy (dest, src, count) whereas the writeblock and updateblock functions are backwards (src, dest, count) while readblock is correct! (yet ANOTHER source of confusion!)