diff --git a/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino b/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino index 98569180..a82646de 100644 --- a/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino +++ b/libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino @@ -23,6 +23,12 @@ void setup() { + // You may choose to enable more or less EEPROM - + // Default length is 1024 bytes (if setLength is not called) + EEPROM.setLength(1080); // this would make the length 1080 bytes + // EEPROM.setLength(AP3_EEPROM_MAX_LENGTH); // the maximum length is 8192 bytes (AP3_EEPROM_MAX_LENGTH) + // Note: larger sizes will increase RAM usage and execution time + Serial.begin(115200); Serial.println("EEPROM Examples"); @@ -44,12 +50,12 @@ void setup() Serial.println("8 bit tests"); byte myValue1 = 200; byte myValue2 = 23; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myValue1)); startTime = millis(); EEPROM.write(randomLocation, myValue1); //(location, data) endTime = millis(); - EEPROM.put(randomLocation + 1, myValue2); + EEPROM.put(randomLocation + sizeof(myValue1), myValue2); Serial.printf("Write byte time: %dms\n", endTime - startTime); @@ -57,12 +63,12 @@ void setup() EEPROM.write(randomLocation, myValue1); //(location, data) endTime = millis(); - Serial.printf("Write identical byte to same location (should be ~1): %dms\n", endTime - startTime); + Serial.printf("Write identical byte to same location: %dms\n", endTime - startTime); byte response1 = EEPROM.read(randomLocation); - byte response2 = EEPROM.read(randomLocation + 1); + byte response2 = EEPROM.read(randomLocation + sizeof(myValue1)); Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue1, response1); - Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 1, myValue2, response2); + Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue1), myValue2, response2); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Serial.println(""); @@ -72,17 +78,17 @@ void setup() //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- uint16_t myValue3 = 3411; int16_t myValue4 = -366; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myValue3)); EEPROM.put(randomLocation, myValue3); - EEPROM.put(randomLocation + 2, myValue4); + EEPROM.put(randomLocation + sizeof(myValue3), myValue4); uint16_t response3; int16_t response4; EEPROM.get(randomLocation, response3); - EEPROM.get(randomLocation + 2, response4); + EEPROM.get(randomLocation + sizeof(myValue3), response4); Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue3, response3); - Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 2, myValue4, response4); + Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue3), myValue4, response4); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Serial.println(""); @@ -93,34 +99,34 @@ void setup() Serial.printf("Size of int: %d\n", sizeof(int)); int myValue5 = -245000; unsigned int myValue6 = 400123; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myValue5)); EEPROM.put(randomLocation, myValue5); - EEPROM.put(randomLocation + 4, myValue6); + EEPROM.put(randomLocation + sizeof(myValue5), myValue6); int response5; unsigned int response6; EEPROM.get(randomLocation, response5); - EEPROM.get(randomLocation + 4, response6); + EEPROM.get(randomLocation + sizeof(myValue5), response6); Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue5, response5); - Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 4, myValue6, response6); + Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue5), myValue6, response6); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //int32_t and uint32_t sequential test //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int32_t myValue7 = -341002; uint32_t myValue8 = 241544; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myValue7)); EEPROM.put(randomLocation, myValue7); - EEPROM.put(randomLocation + 4, myValue8); + EEPROM.put(randomLocation + sizeof(myValue7), myValue8); int32_t response7; uint32_t response8; EEPROM.get(randomLocation, response7); - EEPROM.get(randomLocation + 4, response8); + EEPROM.get(randomLocation + sizeof(myValue7), response8); Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue7, response7); - Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 4, myValue8, response8); + Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue7), myValue8, response8); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //float (32) sequential test @@ -128,17 +134,17 @@ void setup() Serial.printf("Size of float: %d\n", sizeof(float)); float myValue9 = -7.35; float myValue10 = 5.22; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myValue9)); EEPROM.put(randomLocation, myValue9); - EEPROM.put(randomLocation + 4, myValue10); + EEPROM.put(randomLocation + sizeof(myValue9), myValue10); float response9; float response10; EEPROM.get(randomLocation, response9); - EEPROM.get(randomLocation + 4, response10); + EEPROM.get(randomLocation + sizeof(myValue9), response10); Serial.printf("Location %d should be %f: %f\n\r", randomLocation, myValue9, response9); - Serial.printf("Location %d should be %f: %f\n\r", randomLocation + 4, myValue10, response10); + Serial.printf("Location %d should be %f: %f\n\r", randomLocation + sizeof(myValue9), myValue10, response10); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Serial.println(""); @@ -151,24 +157,24 @@ void setup() double myValue12 = 384.95734987; double myValue13 = 917.14159; double myValue14 = 254.8877; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myValue11)); 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(randomLocation + sizeof(myValue11), 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(randomLocation + sizeof(myValue11), 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("Location %d should be %lf: %lf\n", randomLocation + sizeof(myValue11), myValue12, response12); Serial.printf("Edge of EEPROM %d should be %lf: %lf\n", EEPROM.length() - sizeof(myValue13), myValue13, response13); double response14; @@ -183,7 +189,7 @@ void setup() //String write test //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char myString[19] = "How are you today?"; - randomLocation = random(0, AP3_FLASH_EEPROM_SIZE); + randomLocation = random(0, EEPROM.length() - sizeof(myString)); EEPROM.put(randomLocation, myString); char readMy[19]; diff --git a/libraries/EEPROM/src/EEPROM.cpp b/libraries/EEPROM/src/EEPROM.cpp index f8b9b802..62bdf1b6 100644 --- a/libraries/EEPROM/src/EEPROM.cpp +++ b/libraries/EEPROM/src/EEPROM.cpp @@ -40,10 +40,12 @@ #include "EEPROM.h" #include "Arduino.h" +EEPROMClass EEPROM; // the (magnificent) one and only EEPROM!!!!! + //Write a byte to a given "EEPROM" location -void write(uint16_t eepromLocation, uint8_t dataToWrite) +void write(uint16_t eepromLocation, uint8_t dataToWrite, uint16_t allowedSize) { - writeBlockToEEPROM(eepromLocation, &dataToWrite, 1); + writeBlockToEEPROM(eepromLocation, &dataToWrite, 1, allowedSize); } //Read a byte from a given location in "EEPROM" @@ -66,23 +68,23 @@ void EEPROMClass::erase() //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) +void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize, uint16_t allowedSize) { //Error check - if (eepromLocation + blockSize >= AP3_FLASH_EEPROM_SIZE) + if (eepromLocation + blockSize >= allowedSize) { - blockSize = AP3_FLASH_EEPROM_SIZE - eepromLocation; + blockSize = allowedSize - eepromLocation; } //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]; + uint32_t flashContent[allowedSize / 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++) + for (uint16_t x = 0; x < allowedSize; x++) { eepromContents[x] = *(uint8_t *)(AP3_FLASH_EEPROM_START + x); } @@ -96,7 +98,7 @@ void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uin //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++) + for (uint16_t x = 0; x < allowedSize; x++) { if (eepromContents[x] != *(uint8_t *)(AP3_FLASH_EEPROM_START + x)) { @@ -116,5 +118,10 @@ void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uin am_hal_flash_program_main(AM_HAL_FLASH_PROGRAM_KEY, flashContent, (uint32_t *)AP3_FLASH_EEPROM_START, - AP3_FLASH_EEPROM_SIZE / 4); + allowedSize / 4); } + +EERef &EERef::operator=(uint8_t in) +{ + return write(index, in, EEPROM.length()), *this; +} \ No newline at end of file diff --git a/libraries/EEPROM/src/EEPROM.h b/libraries/EEPROM/src/EEPROM.h index 56890856..ad1353ee 100644 --- a/libraries/EEPROM/src/EEPROM.h +++ b/libraries/EEPROM/src/EEPROM.h @@ -59,21 +59,29 @@ //The SparkFun Apollo3 linker script has been modified to limit user code space to less than 0xFE000 #define AP3_FLASH_EEPROM_START 0xFE000 +#define AP3_FLASH_PAGE_SIZE 8192 +#define AP3_EEPROM_MAX_LENGTH (AP3_FLASH_PAGE_SIZE - 16) -#if AP3_FLASH_EEPROM_START % 8192 +#if AP3_FLASH_EEPROM_START % AP3_FLASH_PAGE_SIZE Error : EEPROM start address must be divisble by 8192 #endif - //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 + //The size of the EEPROM may be (optionally) user-configured using the EEPROM.setLength() + //method. Valid values are in the range [0, AP3_EEPROM_MAX_LENGTH]. Reducing the size of + //EEPROM will cause data stored in the higher addresses to be lost. The default size is + //set below. See Example2_AllFunctions for a usage example. + + //Operations on psuedo-EEPROM require a read-write-modify cycle on the entire + //configured memory area because flash pages cannot be partially erased. The + //larger the memory area the longer this operation will take. Here are some + //benchmarks: //1024 = 19ms update time //2048 = 23ms update time - const int AP3_FLASH_EEPROM_SIZE = 1024; //In bytes + const uint16_t AP3_DEFAULT_FLASH_EEPROM_SIZE = 1024; //In bytes 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); +void write(uint16_t eepromLocation, uint8_t dataToWrite, uint16_t allowedSize); +void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize, uint16_t allowedSize); struct EERef { @@ -86,7 +94,7 @@ struct EERef //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); 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; } @@ -163,7 +171,10 @@ 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 write(int idx, uint8_t val) + { + (EERef(idx)) = val; + } void update(int idx, uint8_t val) { EERef(idx).update(val); } void erase(); @@ -174,7 +185,14 @@ struct EEPROMClass 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; } + uint16_t length() + { + return allowedSize; + } + void setLength(uint16_t length) + { + allowedSize = (length <= AP3_EEPROM_MAX_LENGTH) ? length : AP3_EEPROM_MAX_LENGTH; + } //Functionality to 'get' and 'put' objects to and from EEPROM. template @@ -192,11 +210,13 @@ struct EEPROMClass { const uint8_t *ptr = (const uint8_t *)&t; - writeBlockToEEPROM(idx, ptr, sizeof(T)); //Address, data, sizeOfData + writeBlockToEEPROM(idx, ptr, sizeof(T), allowedSize); //Address, data, sizeOfData return t; } + + uint16_t allowedSize = AP3_DEFAULT_FLASH_EEPROM_SIZE; }; -static EEPROMClass EEPROM __attribute__((unused)); +extern EEPROMClass EEPROM; #endif //_EEPROM_H