diff --git a/libraries/EEPROM/examples/Example1_GetPut/Example1_GetPut.ino b/libraries/EEPROM/examples/Example1_GetPut/Example1_GetPut.ino
index ea86af35..b7b07be6 100644
--- a/libraries/EEPROM/examples/Example1_GetPut/Example1_GetPut.ino
+++ b/libraries/EEPROM/examples/Example1_GetPut/Example1_GetPut.ino
@@ -25,7 +25,7 @@
void setup()
{
- Serial.begin(9600);
+ Serial.begin(115200);
Serial.println("EEPROM Examples");
byte myValue1 = 200;
diff --git a/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino b/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino
index ce9f1536..98569180 100644
--- a/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino
+++ b/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino
@@ -23,14 +23,14 @@
void setup()
{
- Serial.begin(9600);
+ Serial.begin(115200);
Serial.println("EEPROM Examples");
randomSeed(analogRead(A0));
long startTime;
long endTime;
- uint16_t randomLocation;
+ int randomLocation;
//Test erase time
startTime = millis();
@@ -53,6 +53,12 @@ void setup()
Serial.printf("Write byte time: %dms\n", endTime - startTime);
+ startTime = millis();
+ EEPROM.write(randomLocation, myValue1); //(location, data)
+ endTime = millis();
+
+ Serial.printf("Write identical byte to same location (should be ~1): %dms\n", endTime - startTime);
+
byte response1 = EEPROM.read(randomLocation);
byte response2 = EEPROM.read(randomLocation + 1);
Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue1, response1);
@@ -106,8 +112,8 @@ void setup()
uint32_t myValue8 = 241544;
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
- EEPROM.update(randomLocation, myValue7);
- EEPROM.update(randomLocation + 4, myValue8);
+ EEPROM.put(randomLocation, myValue7);
+ EEPROM.put(randomLocation + 4, myValue8);
int32_t response7;
uint32_t response8;
@@ -124,8 +130,8 @@ void setup()
float myValue10 = 5.22;
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
- EEPROM.update(randomLocation, myValue9);
- EEPROM.update(randomLocation + 4, myValue10);
+ EEPROM.put(randomLocation, myValue9);
+ EEPROM.put(randomLocation + 4, myValue10);
float response9;
float response10;
@@ -143,20 +149,50 @@ void setup()
Serial.printf("Size of double: %d\n", sizeof(double));
double myValue11 = -290.3485723409857;
double myValue12 = 384.95734987;
+ double myValue13 = 917.14159;
+ double myValue14 = 254.8877;
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
- EEPROM.update(randomLocation, myValue11);
- EEPROM.update(randomLocation + 8, myValue12);
+ startTime = millis();
+ EEPROM.put(randomLocation, myValue11);
+ endTime = millis();
+ Serial.printf("Time to record 64-bits: %dms\n", endTime - startTime);
+
+ EEPROM.put(randomLocation + 8, myValue12);
+ EEPROM.put(EEPROM.length() - sizeof(myValue13), myValue13); //Test end of EEPROM space
double response11;
double response12;
+ double response13;
EEPROM.get(randomLocation, response11);
EEPROM.get(randomLocation + 8, response12);
+ EEPROM.get(EEPROM.length() - sizeof(myValue13), response13);
Serial.printf("Location %d should be %lf: %lf\n", randomLocation, myValue11, response11);
Serial.printf("Location %d should be %lf: %lf\n", randomLocation + 8, myValue12, response12);
+ Serial.printf("Edge of EEPROM %d should be %lf: %lf\n", EEPROM.length() - sizeof(myValue13), myValue13, response13);
+
+ double response14;
+ EEPROM.put(EEPROM.length() - sizeof(myValue14), myValue14); //Test the re-write of a spot
+ EEPROM.get(EEPROM.length() - sizeof(myValue14), response14);
+ Serial.printf("Rewrite of %d should be %lf: %lf\n", EEPROM.length() - sizeof(myValue14), myValue14, response14);
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- Serial.println();
+ Serial.println("");
+ Serial.println("String test");
+
+ //String write test
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ char myString[19] = "How are you today?";
+ randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
+ EEPROM.put(randomLocation, myString);
+
+ char readMy[19];
+ EEPROM.get(randomLocation, readMy);
+ Serial.printf("Location %d string should read 'How are you today?': ", randomLocation);
+ Serial.println(readMy);
+ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+ Serial.println("");
Serial.print("Flash Contents:");
for (uint16_t x = 0; x < 8 * 4; x += 4)
{
diff --git a/libraries/EEPROM/src/EEPROM.cpp b/libraries/EEPROM/src/EEPROM.cpp
index 863b2b89..f8b9b802 100644
--- a/libraries/EEPROM/src/EEPROM.cpp
+++ b/libraries/EEPROM/src/EEPROM.cpp
@@ -21,9 +21,9 @@
Flash is 0x00 to 0xFF000. EEPROM writes will start at 0xFF000 - 8192 = 0xF2000.
Page erase takes 15ms
- Writing a byte takes 30ms
- Writing a float across two words takes 30ms
- Update (no write) takes 1ms
+ Writing a byte takes 19ms
+ Writing a float across two words takes 19ms
+ Update (no write) takes ~1ms
Development environment specifics:
Arduino IDE 1.8.x
@@ -40,270 +40,81 @@
#include "EEPROM.h"
#include "Arduino.h"
-//Constructor
-ap3_EEPROM::ap3_EEPROM()
-{
-}
-
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
//Write a byte to a given "EEPROM" location
-//Automatically masks user's byte into flash without
-//affecting other bytes in this flash word
-void ap3_EEPROM::write(uint16_t eepromLocation, uint8_t dataToWrite)
+void write(uint16_t eepromLocation, uint8_t dataToWrite)
{
- uint32_t flashLocation = AP3_FLASH_EEPROM_START + eepromLocation;
- writeWordToFlash(flashLocation, (uint32_t)dataToWrite | 0xFFFFFF00);
+ writeBlockToEEPROM(eepromLocation, &dataToWrite, 1);
}
//Read a byte from a given location in "EEPROM"
-uint8_t ap3_EEPROM::read(uint16_t eepromLocation)
+uint8_t read(uint16_t eepromLocation)
{
uint32_t flashLocation = AP3_FLASH_EEPROM_START + eepromLocation;
return (*(uint8_t *)flashLocation);
}
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-//Get method is overloaded with the following variable types
-//char, byte, int, unsigned int, long, unsigned long, float, double?
-
-void ap3_EEPROM::get(uint16_t eepromLocation, uint8_t &dataToGet)
-{
- dataToGet = *(uint8_t *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, uint16_t &dataToGet)
-{
- dataToGet = *(uint16_t *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, int16_t &dataToGet)
-{
- dataToGet = *(int16_t *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, int &dataToGet)
-{
- dataToGet = *(int *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, unsigned int &dataToGet)
-{
- dataToGet = *(unsigned int *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, int32_t &dataToGet)
-{
- dataToGet = *(int32_t *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, uint32_t &dataToGet)
-{
- dataToGet = *(uint32_t *)(AP3_FLASH_EEPROM_START + eepromLocation);
-}
-void ap3_EEPROM::get(uint16_t eepromLocation, float &dataToGet)
-{
- union {
- float f;
- uint32_t b;
- } temp;
- temp.b = *(uint32_t *)(AP3_FLASH_EEPROM_START + eepromLocation);
-
- dataToGet = temp.f;
-}
-
-void ap3_EEPROM::get(uint16_t eepromLocation, double &dataToGet)
-{
- union {
- double lf;
- uint32_t b[2];
- } temp;
- temp.b[1] = *(uint32_t *)(AP3_FLASH_EEPROM_START + eepromLocation); //LSB;
- temp.b[0] = *(uint32_t *)(AP3_FLASH_EEPROM_START + eepromLocation + 4); //MSB;
- dataToGet = temp.lf;
-}
-
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-//Put method is overloaded with the following variable types
-//char, byte, int, unsigned int, long, unsigned long, float, double?
-
-void ap3_EEPROM::put(uint16_t eepromLocation, uint8_t dataToWrite)
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)dataToWrite | 0xFFFFFF00);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, uint16_t dataToWrite)
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)dataToWrite | 0xFFFF0000);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, int16_t dataToWrite)
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)dataToWrite | 0xFFFF0000);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, int dataToWrite) //ints are 32 bit on M4F
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)dataToWrite);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, unsigned int dataToWrite) //ints are 32 bit on M4F
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)dataToWrite);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, int32_t dataToWrite)
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (int32_t)dataToWrite);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, uint32_t dataToWrite)
-{
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)dataToWrite);
-}
-void ap3_EEPROM::put(uint16_t eepromLocation, float dataToWrite)
-{
- union {
- float f;
- uint32_t b;
- } temp;
- temp.f = dataToWrite;
-
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)temp.b);
-}
-
-void ap3_EEPROM::put(uint16_t eepromLocation, double dataToWrite) //64 bits
-{
- union {
- double lf;
- uint32_t b[2];
- } temp;
- temp.lf = dataToWrite;
-
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation), (uint32_t)temp.b[1]); //LSB
- writeWordToFlash((AP3_FLASH_EEPROM_START + eepromLocation + 4), (uint32_t)temp.b[0]); //MSB
-}
-
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-//The update functions simply call the put functions
-//Put automatically checks to see if a spot needs updating
-void ap3_EEPROM::update(uint16_t eepromLocation, uint8_t dataToWrite)
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, uint16_t dataToWrite)
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, int16_t dataToWrite)
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, int dataToWrite) //ints are 32 bit on M4F
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, unsigned int dataToWrite) //ints are 32 bit on M4F
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, int32_t dataToWrite)
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, uint32_t dataToWrite)
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, float dataToWrite)
-{
- put(eepromLocation, dataToWrite);
-}
-void ap3_EEPROM::update(uint16_t eepromLocation, double dataToWrite) //64 bits
-{
- put(eepromLocation, dataToWrite);
-}
-
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-uint16_t ap3_EEPROM::length()
-{
- return (AP3_FLASH_EEPROM_SIZE);
-}
-
//Erase 8k page encapsulating the EEPROM section
-void ap3_EEPROM::erase()
+void EEPROMClass::erase()
{
am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY,
AM_HAL_FLASH_ADDR2INST(AP3_FLASH_EEPROM_START),
AM_HAL_FLASH_ADDR2PAGE(AP3_FLASH_EEPROM_START));
}
-//This is the main helper function
-//Reprogram a given location with 32-bits
-//Flash is written to in words at locations that are %4=0
-//Span words if necessary
//1) Make copy of current flash contents into SRAM
-//2) Turn user's requested spot into 0xFFs
-//3) Erase flash page (8k)
-//4) Write SRAM back into flash
-//5) Write user's data onto the spot with recently created 0xFFs
-//Note - this code assumes EEPROM temp space is contained in one page
-void ap3_EEPROM::writeWordToFlash(uint32_t flashLocation, uint32_t dataToWrite)
+//2) Record user data into SRAM.
+//3) Check if new data is different from flash.
+//4) Erase flash page (8k)
+//5) Write SRAM back into flash
+void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize)
{
//Error check
- if (flashLocation >= AP3_FLASH_EEPROM_START + AP3_FLASH_EEPROM_SIZE)
+ if (eepromLocation + blockSize >= AP3_FLASH_EEPROM_SIZE)
{
- return;
+ blockSize = AP3_FLASH_EEPROM_SIZE - eepromLocation;
}
- if (flashLocation < AP3_FLASH_EEPROM_START)
+
+ //Read the contents of current "EEPROM" to SRAM
+ //Flash is written in 32-bit words but user passes in array of bytes
+ //Create an array of 32-bit words but reference it a byte at a time
+ uint32_t flashContent[AP3_FLASH_EEPROM_SIZE / 4];
+
+ //We can't read 32bits at a time because the way flash is oriented (little endian)
+ //So we read a byte at a time
+ uint8_t *eepromContents = (uint8_t *)flashContent;
+ for (uint16_t x = 0; x < AP3_FLASH_EEPROM_SIZE; x++)
{
- return;
+ eepromContents[x] = *(uint8_t *)(AP3_FLASH_EEPROM_START + x);
}
- //Check to see if location needs updating
- if (*(uint32_t *)(flashLocation) == dataToWrite)
+ //Write the caller's new data into the byte array
+ for (uint16_t x = 0; x < blockSize; x++)
{
- return;
+ eepromContents[eepromLocation + x] = dataToWrite[x];
}
- //First we have to read the contents of current "EEPROM" to SRAM
- uint32_t tempContents[AP3_FLASH_EEPROM_SIZE / 4];
- uint16_t spot = 0;
- for (uint16_t x = 0; x < AP3_FLASH_EEPROM_SIZE; x += 4)
+ //Run a check here to see if the new data is the same as what's in flash. If it's the same,
+ //just return, don't erase flash.
+ bool theSame = true;
+ for (uint16_t x = 0; x < AP3_FLASH_EEPROM_SIZE; x++)
{
- tempContents[spot++] = *(uint32_t *)(AP3_FLASH_EEPROM_START + x);
+ if (eepromContents[x] != *(uint8_t *)(AP3_FLASH_EEPROM_START + x))
+ {
+ theSame = false;
+ break;
+ }
}
+ if (theSame == true)
+ return;
//Then we erase an 8K page
am_hal_flash_page_erase(AM_HAL_FLASH_PROGRAM_KEY,
- AM_HAL_FLASH_ADDR2INST(flashLocation),
- AM_HAL_FLASH_ADDR2PAGE(flashLocation));
-
- //Zero out this word(s)
- uint8_t byteOffset = (flashLocation % 4);
- uint16_t wordLocation = (flashLocation - AP3_FLASH_EEPROM_START) / 4;
-
- //Mask in the new data into the array
- if (byteOffset == 0)
- {
- //Easy - update this word with new word
- tempContents[wordLocation] = dataToWrite;
- }
- else
- {
- //Clear the upper bytes of the first word to 0s
- tempContents[wordLocation] &= ~(0xFFFFFFFF << (byteOffset * 8));
-
- //Clear the lower bytes of the second word to 0s
- tempContents[wordLocation + 1] &= ~(0xFFFFFFFF >> ((4 - byteOffset) * 8));
-
- //OR in upper bytes of this word with new data
- uint32_t dataToWriteFirstWord = dataToWrite << (byteOffset * 8);
-
- //OR in the lower bytes of the following word with new data
- uint32_t dataToWriteSecondWord = dataToWrite >> ((4 - byteOffset) * 8);
-
- tempContents[wordLocation] |= dataToWriteFirstWord;
- tempContents[wordLocation + 1] |= dataToWriteSecondWord;
- }
+ AM_HAL_FLASH_ADDR2INST(AP3_FLASH_EEPROM_START + eepromLocation),
+ AM_HAL_FLASH_ADDR2PAGE(AP3_FLASH_EEPROM_START + eepromLocation));
//Then we write the contents of the array back
am_hal_flash_program_main(AM_HAL_FLASH_PROGRAM_KEY,
- tempContents,
+ flashContent,
(uint32_t *)AP3_FLASH_EEPROM_START,
- AP3_FLASH_EEPROM_SIZE);
+ AP3_FLASH_EEPROM_SIZE / 4);
}
-
-ap3_EEPROM EEPROM;
\ No newline at end of file
diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h
index deb359d6..56890856 100644
--- a/libraries/EEPROM/src/EEPROM.h
+++ b/libraries/EEPROM/src/EEPROM.h
@@ -8,8 +8,6 @@
https://www.sparkfun.com/products/15411
https://www.sparkfun.com/products/15412
- Written by Nathan Seidle @ SparkFun Electronics, June 16th, 2019
-
Pseudo-EEPROM on the Cortex-M4F
https://github.com/sparkfun/SparkFun_Apollo3
@@ -23,20 +21,33 @@
at 0xFE000;
Page erase takes 15ms
- Writing a byte takes 30ms
- Writing a float across two words takes 30ms
- Update (no write) takes 1ms
+ Writing a byte takes 19ms
+ Writing a float across two words takes 19ms
+ Update (no write) takes ~1ms
Development environment specifics:
Arduino IDE 1.8.x
- This program is distributed in the hope that it will be useful,
+ Original Copyright (c) 2006 David A. Mellis. All right reserved.
+ New version by Christopher Andrews 2015.
+ This copy has minor modificatons for use with Teensy, by Paul Stoffregen
+ This copy has minor modificatons for use with Artemis, by Nathan Seidle
+
+ This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ EERef class.
+
+ This object references an EEPROM cell.
+ Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
+ This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
*/
#ifndef _EEPROM_H
@@ -53,86 +64,139 @@
Error : EEPROM start address must be divisble by 8192
#endif
-//By limiting EEPROM size to 1024, we reduce the amount of SRAM required and
-//time needed to mask in individual bytes and words into flash. It can be increased
-//to 8096 if needed
-#define AP3_FLASH_EEPROM_SIZE 1024
+ //By limiting EEPROM size to 1024 bytes, we reduce the amount of SRAM required and
+ //time needed to read/write words into flash. It can be increased
+ //to 2048 if needed
+ //1024 = 19ms update time
+ //2048 = 23ms update time
+ const int AP3_FLASH_EEPROM_SIZE = 1024; //In bytes
- //class TwoWire : public Stream, public IOMaster{}
+uint8_t read(uint16_t eepromLocation);
+void write(uint16_t eepromLocation, uint8_t dataToWrite);
+void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize);
- class ap3_EEPROM
+struct EERef
{
-public:
- ap3_EEPROM();
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- //8 bit
- uint8_t read(uint16_t eepromLocation);
- void write(uint16_t eepromLocation, uint8_t dataToWrite);
- void get(uint16_t eepromLocation, uint8_t &dataToGet);
-
- //16 bit
- void get(uint16_t eepromLocation, uint16_t &dataToGet);
- void get(uint16_t eepromLocation, int16_t &dataToGet);
-
- //32 bit
- void get(uint16_t eepromLocation, int &dataToGet);
- void get(uint16_t eepromLocation, unsigned int &dataToGet);
- void get(uint16_t eepromLocation, int32_t &dataToGet);
- void get(uint16_t eepromLocation, uint32_t &dataToGet);
- void get(uint16_t eepromLocation, float &dataToGet);
-
- //64 bit
- void get(uint16_t eepromLocation, double &dataToGet);
-
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- //8 bit
- void put(uint16_t eepromLocation, uint8_t dataToWrite);
+ EERef(const int index)
+ : index(index) {}
+
+ //Access/read members.
+ uint8_t operator*() const { return read(index); }
+ operator const uint8_t() const { return **this; }
+
+ //Assignment/write members.
+ EERef &operator=(const EERef &ref) { return *this = *ref; }
+ EERef &operator=(uint8_t in) { return write(index, in), *this; }
+ EERef &operator+=(uint8_t in) { return *this = **this + in; }
+ EERef &operator-=(uint8_t in) { return *this = **this - in; }
+ EERef &operator*=(uint8_t in) { return *this = **this * in; }
+ EERef &operator/=(uint8_t in) { return *this = **this / in; }
+ EERef &operator^=(uint8_t in) { return *this = **this ^ in; }
+ EERef &operator%=(uint8_t in) { return *this = **this % in; }
+ EERef &operator&=(uint8_t in) { return *this = **this & in; }
+ EERef &operator|=(uint8_t in) { return *this = **this | in; }
+ EERef &operator<<=(uint8_t in) { return *this = **this << in; }
+ EERef &operator>>=(uint8_t in) { return *this = **this >> in; }
+
+ EERef &update(uint8_t in) { return in != *this ? *this = in : *this; }
+
+ /** Prefix increment/decrement **/
+ EERef &operator++() { return *this += 1; }
+ EERef &operator--() { return *this -= 1; }
+
+ /** Postfix increment/decrement **/
+ uint8_t operator++(int)
+ {
+ uint8_t ret = **this;
+ return ++(*this), ret;
+ }
+
+ uint8_t operator--(int)
+ {
+ uint8_t ret = **this;
+ return --(*this), ret;
+ }
+
+ int index; //Index of current EEPROM cell.
+};
- //16 bit
- void put(uint16_t eepromLocation, uint16_t dataToWrite);
- void put(uint16_t eepromLocation, int16_t dataToWrite);
+/***
+ EEPtr class.
- // 32 bit
- void put(uint16_t eepromLocation, int dataToWrite);
- void put(uint16_t eepromLocation, unsigned int dataToWrite);
- void put(uint16_t eepromLocation, int32_t dataToWrite);
- void put(uint16_t eepromLocation, uint32_t dataToWrite);
- void put(uint16_t eepromLocation, float dataToWrite);
+ This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
+ Just like a normal pointer type, this can be dereferenced and repositioned using
+ increment/decrement operators.
+***/
- //64 bit
- void put(uint16_t eepromLocation, double dataToWrite);
+struct EEPtr
+{
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+ EEPtr(const int index)
+ : index(index) {}
- //8 bit
- void update(uint16_t eepromLocation, uint8_t dataToWrite);
+ operator const int() const { return index; }
+ EEPtr &operator=(int in) { return index = in, *this; }
- //16 bit
- void update(uint16_t eepromLocation, uint16_t dataToWrite);
- void update(uint16_t eepromLocation, int16_t dataToWrite);
+ //Iterator functionality.
+ bool operator!=(const EEPtr &ptr) { return index != ptr.index; }
+ EERef operator*() { return index; }
- // 32 bit
- void update(uint16_t eepromLocation, int dataToWrite);
- void update(uint16_t eepromLocation, unsigned int dataToWrite);
- void update(uint16_t eepromLocation, int32_t dataToWrite);
- void update(uint16_t eepromLocation, uint32_t dataToWrite);
- void update(uint16_t eepromLocation, float dataToWrite);
+ /** Prefix & Postfix increment/decrement **/
+ EEPtr &operator++() { return ++index, *this; }
+ EEPtr &operator--() { return --index, *this; }
+ EEPtr operator++(int) { return index++; }
+ EEPtr operator--(int) { return index--; }
- //64 bit
- void update(uint16_t eepromLocation, double dataToWrite);
+ int index; //Index of current EEPROM cell.
+};
- //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+/***
+ EEPROMClass class.
- uint16_t length();
- void erase(); //Erase entire EEPROM
+ This object represents the entire EEPROM space.
+ It wraps the functionality of EEPtr and EERef into a basic interface.
+ This class is also 100% backwards compatible with earlier Arduino core releases.
+***/
-private:
- void writeWordToFlash(uint32_t flashLocation, uint32_t dataToWrite);
+struct EEPROMClass
+{
+ //Basic user access methods.
+ EERef operator[](const int idx) { return idx; }
+ uint8_t read(int idx) { return EERef(idx); }
+ void write(int idx, uint8_t val) { (EERef(idx)) = val; }
+ void update(int idx, uint8_t val) { EERef(idx).update(val); }
+ void erase();
+
+ //STL and C++11 iteration capability.
+ EEPtr
+ begin()
+ {
+ return 0x00;
+ }
+ EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
+ uint16_t length() { return AP3_FLASH_EEPROM_SIZE; }
+
+ //Functionality to 'get' and 'put' objects to and from EEPROM.
+ template
+ T &get(int idx, T &t)
+ {
+ EEPtr e = idx;
+ uint8_t *ptr = (uint8_t *)&t;
+ for (int count = sizeof(T); count; --count, ++e)
+ *ptr++ = *e;
+ return t;
+ }
+
+ template
+ const T &put(int idx, const T &t) //Address, data
+ {
+ const uint8_t *ptr = (const uint8_t *)&t;
+
+ writeBlockToEEPROM(idx, ptr, sizeof(T)); //Address, data, sizeOfData
+
+ return t;
+ }
};
-extern ap3_EEPROM EEPROM;
-
-#endif
+static EEPROMClass EEPROM __attribute__((unused));
+#endif //_EEPROM_H