Skip to content

Commit 9a42ce0

Browse files
author
Owen
authored
Merge pull request #127 from sparkfun/eeprom-variable-size
add configurable EEPROM length
2 parents c7b5cc7 + 843b8af commit 9a42ce0

File tree

3 files changed

+80
-47
lines changed

3 files changed

+80
-47
lines changed

Diff for: libraries/EEPROM/examples/Example2_AllFunctions/Example2_AllFunctions.ino

+32-26
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323

2424
void setup()
2525
{
26+
// You may choose to enable more or less EEPROM -
27+
// Default length is 1024 bytes (if setLength is not called)
28+
EEPROM.setLength(1080); // this would make the length 1080 bytes
29+
// EEPROM.setLength(AP3_EEPROM_MAX_LENGTH); // the maximum length is 8192 bytes (AP3_EEPROM_MAX_LENGTH)
30+
// Note: larger sizes will increase RAM usage and execution time
31+
2632
Serial.begin(115200);
2733
Serial.println("EEPROM Examples");
2834

@@ -44,25 +50,25 @@ void setup()
4450
Serial.println("8 bit tests");
4551
byte myValue1 = 200;
4652
byte myValue2 = 23;
47-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
53+
randomLocation = random(0, EEPROM.length() - sizeof(myValue1));
4854

4955
startTime = millis();
5056
EEPROM.write(randomLocation, myValue1); //(location, data)
5157
endTime = millis();
52-
EEPROM.put(randomLocation + 1, myValue2);
58+
EEPROM.put(randomLocation + sizeof(myValue1), myValue2);
5359

5460
Serial.printf("Write byte time: %dms\n", endTime - startTime);
5561

5662
startTime = millis();
5763
EEPROM.write(randomLocation, myValue1); //(location, data)
5864
endTime = millis();
5965

60-
Serial.printf("Write identical byte to same location (should be ~1): %dms\n", endTime - startTime);
66+
Serial.printf("Write identical byte to same location: %dms\n", endTime - startTime);
6167

6268
byte response1 = EEPROM.read(randomLocation);
63-
byte response2 = EEPROM.read(randomLocation + 1);
69+
byte response2 = EEPROM.read(randomLocation + sizeof(myValue1));
6470
Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue1, response1);
65-
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 1, myValue2, response2);
71+
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue1), myValue2, response2);
6672
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
6773

6874
Serial.println("");
@@ -72,17 +78,17 @@ void setup()
7278
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
7379
uint16_t myValue3 = 3411;
7480
int16_t myValue4 = -366;
75-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
81+
randomLocation = random(0, EEPROM.length() - sizeof(myValue3));
7682

7783
EEPROM.put(randomLocation, myValue3);
78-
EEPROM.put(randomLocation + 2, myValue4);
84+
EEPROM.put(randomLocation + sizeof(myValue3), myValue4);
7985

8086
uint16_t response3;
8187
int16_t response4;
8288
EEPROM.get(randomLocation, response3);
83-
EEPROM.get(randomLocation + 2, response4);
89+
EEPROM.get(randomLocation + sizeof(myValue3), response4);
8490
Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue3, response3);
85-
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 2, myValue4, response4);
91+
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue3), myValue4, response4);
8692
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
8793

8894
Serial.println("");
@@ -93,52 +99,52 @@ void setup()
9399
Serial.printf("Size of int: %d\n", sizeof(int));
94100
int myValue5 = -245000;
95101
unsigned int myValue6 = 400123;
96-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
102+
randomLocation = random(0, EEPROM.length() - sizeof(myValue5));
97103

98104
EEPROM.put(randomLocation, myValue5);
99-
EEPROM.put(randomLocation + 4, myValue6);
105+
EEPROM.put(randomLocation + sizeof(myValue5), myValue6);
100106

101107
int response5;
102108
unsigned int response6;
103109
EEPROM.get(randomLocation, response5);
104-
EEPROM.get(randomLocation + 4, response6);
110+
EEPROM.get(randomLocation + sizeof(myValue5), response6);
105111
Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue5, response5);
106-
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 4, myValue6, response6);
112+
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue5), myValue6, response6);
107113
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
108114

109115
//int32_t and uint32_t sequential test
110116
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
111117
int32_t myValue7 = -341002;
112118
uint32_t myValue8 = 241544;
113-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
119+
randomLocation = random(0, EEPROM.length() - sizeof(myValue7));
114120

115121
EEPROM.put(randomLocation, myValue7);
116-
EEPROM.put(randomLocation + 4, myValue8);
122+
EEPROM.put(randomLocation + sizeof(myValue7), myValue8);
117123

118124
int32_t response7;
119125
uint32_t response8;
120126
EEPROM.get(randomLocation, response7);
121-
EEPROM.get(randomLocation + 4, response8);
127+
EEPROM.get(randomLocation + sizeof(myValue7), response8);
122128
Serial.printf("Location %d should be %d: %d\n\r", randomLocation, myValue7, response7);
123-
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + 4, myValue8, response8);
129+
Serial.printf("Location %d should be %d: %d\n\r", randomLocation + sizeof(myValue7), myValue8, response8);
124130
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
125131

126132
//float (32) sequential test
127133
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
128134
Serial.printf("Size of float: %d\n", sizeof(float));
129135
float myValue9 = -7.35;
130136
float myValue10 = 5.22;
131-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
137+
randomLocation = random(0, EEPROM.length() - sizeof(myValue9));
132138

133139
EEPROM.put(randomLocation, myValue9);
134-
EEPROM.put(randomLocation + 4, myValue10);
140+
EEPROM.put(randomLocation + sizeof(myValue9), myValue10);
135141

136142
float response9;
137143
float response10;
138144
EEPROM.get(randomLocation, response9);
139-
EEPROM.get(randomLocation + 4, response10);
145+
EEPROM.get(randomLocation + sizeof(myValue9), response10);
140146
Serial.printf("Location %d should be %f: %f\n\r", randomLocation, myValue9, response9);
141-
Serial.printf("Location %d should be %f: %f\n\r", randomLocation + 4, myValue10, response10);
147+
Serial.printf("Location %d should be %f: %f\n\r", randomLocation + sizeof(myValue9), myValue10, response10);
142148
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
143149

144150
Serial.println("");
@@ -151,24 +157,24 @@ void setup()
151157
double myValue12 = 384.95734987;
152158
double myValue13 = 917.14159;
153159
double myValue14 = 254.8877;
154-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
160+
randomLocation = random(0, EEPROM.length() - sizeof(myValue11));
155161

156162
startTime = millis();
157163
EEPROM.put(randomLocation, myValue11);
158164
endTime = millis();
159165
Serial.printf("Time to record 64-bits: %dms\n", endTime - startTime);
160166

161-
EEPROM.put(randomLocation + 8, myValue12);
167+
EEPROM.put(randomLocation + sizeof(myValue11), myValue12);
162168
EEPROM.put(EEPROM.length() - sizeof(myValue13), myValue13); //Test end of EEPROM space
163169

164170
double response11;
165171
double response12;
166172
double response13;
167173
EEPROM.get(randomLocation, response11);
168-
EEPROM.get(randomLocation + 8, response12);
174+
EEPROM.get(randomLocation + sizeof(myValue11), response12);
169175
EEPROM.get(EEPROM.length() - sizeof(myValue13), response13);
170176
Serial.printf("Location %d should be %lf: %lf\n", randomLocation, myValue11, response11);
171-
Serial.printf("Location %d should be %lf: %lf\n", randomLocation + 8, myValue12, response12);
177+
Serial.printf("Location %d should be %lf: %lf\n", randomLocation + sizeof(myValue11), myValue12, response12);
172178
Serial.printf("Edge of EEPROM %d should be %lf: %lf\n", EEPROM.length() - sizeof(myValue13), myValue13, response13);
173179

174180
double response14;
@@ -183,7 +189,7 @@ void setup()
183189
//String write test
184190
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
185191
char myString[19] = "How are you today?";
186-
randomLocation = random(0, AP3_FLASH_EEPROM_SIZE);
192+
randomLocation = random(0, EEPROM.length() - sizeof(myString));
187193
EEPROM.put(randomLocation, myString);
188194

189195
char readMy[19];

Diff for: libraries/EEPROM/src/EEPROM.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@
4040
#include "EEPROM.h"
4141
#include "Arduino.h"
4242

43+
EEPROMClass EEPROM; // the (magnificent) one and only EEPROM!!!!!
44+
4345
//Write a byte to a given "EEPROM" location
44-
void write(uint16_t eepromLocation, uint8_t dataToWrite)
46+
void write(uint16_t eepromLocation, uint8_t dataToWrite, uint16_t allowedSize)
4547
{
46-
writeBlockToEEPROM(eepromLocation, &dataToWrite, 1);
48+
writeBlockToEEPROM(eepromLocation, &dataToWrite, 1, allowedSize);
4749
}
4850

4951
//Read a byte from a given location in "EEPROM"
@@ -66,23 +68,23 @@ void EEPROMClass::erase()
6668
//3) Check if new data is different from flash.
6769
//4) Erase flash page (8k)
6870
//5) Write SRAM back into flash
69-
void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize)
71+
void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize, uint16_t allowedSize)
7072
{
7173
//Error check
72-
if (eepromLocation + blockSize >= AP3_FLASH_EEPROM_SIZE)
74+
if (eepromLocation + blockSize >= allowedSize)
7375
{
74-
blockSize = AP3_FLASH_EEPROM_SIZE - eepromLocation;
76+
blockSize = allowedSize - eepromLocation;
7577
}
7678

7779
//Read the contents of current "EEPROM" to SRAM
7880
//Flash is written in 32-bit words but user passes in array of bytes
7981
//Create an array of 32-bit words but reference it a byte at a time
80-
uint32_t flashContent[AP3_FLASH_EEPROM_SIZE / 4];
82+
uint32_t flashContent[allowedSize / 4];
8183

8284
//We can't read 32bits at a time because the way flash is oriented (little endian)
8385
//So we read a byte at a time
8486
uint8_t *eepromContents = (uint8_t *)flashContent;
85-
for (uint16_t x = 0; x < AP3_FLASH_EEPROM_SIZE; x++)
87+
for (uint16_t x = 0; x < allowedSize; x++)
8688
{
8789
eepromContents[x] = *(uint8_t *)(AP3_FLASH_EEPROM_START + x);
8890
}
@@ -96,7 +98,7 @@ void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uin
9698
//Run a check here to see if the new data is the same as what's in flash. If it's the same,
9799
//just return, don't erase flash.
98100
bool theSame = true;
99-
for (uint16_t x = 0; x < AP3_FLASH_EEPROM_SIZE; x++)
101+
for (uint16_t x = 0; x < allowedSize; x++)
100102
{
101103
if (eepromContents[x] != *(uint8_t *)(AP3_FLASH_EEPROM_START + x))
102104
{
@@ -116,5 +118,10 @@ void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uin
116118
am_hal_flash_program_main(AM_HAL_FLASH_PROGRAM_KEY,
117119
flashContent,
118120
(uint32_t *)AP3_FLASH_EEPROM_START,
119-
AP3_FLASH_EEPROM_SIZE / 4);
121+
allowedSize / 4);
120122
}
123+
124+
EERef &EERef::operator=(uint8_t in)
125+
{
126+
return write(index, in, EEPROM.length()), *this;
127+
}

Diff for: libraries/EEPROM/src/EEPROM.h

+32-12
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,29 @@
5959
//The SparkFun Apollo3 linker script has been modified to limit user code space to less than 0xFE000
6060

6161
#define AP3_FLASH_EEPROM_START 0xFE000
62+
#define AP3_FLASH_PAGE_SIZE 8192
63+
#define AP3_EEPROM_MAX_LENGTH (AP3_FLASH_PAGE_SIZE - 16)
6264

63-
#if AP3_FLASH_EEPROM_START % 8192
65+
#if AP3_FLASH_EEPROM_START % AP3_FLASH_PAGE_SIZE
6466
Error : EEPROM start address must be divisble by 8192
6567
#endif
6668

67-
//By limiting EEPROM size to 1024 bytes, we reduce the amount of SRAM required and
68-
//time needed to read/write words into flash. It can be increased
69-
//to 2048 if needed
69+
//The size of the EEPROM may be (optionally) user-configured using the EEPROM.setLength()
70+
//method. Valid values are in the range [0, AP3_EEPROM_MAX_LENGTH]. Reducing the size of
71+
//EEPROM will cause data stored in the higher addresses to be lost. The default size is
72+
//set below. See Example2_AllFunctions for a usage example.
73+
74+
//Operations on psuedo-EEPROM require a read-write-modify cycle on the entire
75+
//configured memory area because flash pages cannot be partially erased. The
76+
//larger the memory area the longer this operation will take. Here are some
77+
//benchmarks:
7078
//1024 = 19ms update time
7179
//2048 = 23ms update time
72-
const int AP3_FLASH_EEPROM_SIZE = 1024; //In bytes
80+
const uint16_t AP3_DEFAULT_FLASH_EEPROM_SIZE = 1024; //In bytes
7381

7482
uint8_t read(uint16_t eepromLocation);
75-
void write(uint16_t eepromLocation, uint8_t dataToWrite);
76-
void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize);
83+
void write(uint16_t eepromLocation, uint8_t dataToWrite, uint16_t allowedSize);
84+
void writeBlockToEEPROM(uint16_t eepromLocation, const uint8_t *dataToWrite, uint16_t blockSize, uint16_t allowedSize);
7785

7886
struct EERef
7987
{
@@ -86,7 +94,7 @@ struct EERef
8694

8795
//Assignment/write members.
8896
EERef &operator=(const EERef &ref) { return *this = *ref; }
89-
EERef &operator=(uint8_t in) { return write(index, in), *this; }
97+
EERef &operator=(uint8_t in);
9098
EERef &operator+=(uint8_t in) { return *this = **this + in; }
9199
EERef &operator-=(uint8_t in) { return *this = **this - in; }
92100
EERef &operator*=(uint8_t in) { return *this = **this * in; }
@@ -163,7 +171,10 @@ struct EEPROMClass
163171
//Basic user access methods.
164172
EERef operator[](const int idx) { return idx; }
165173
uint8_t read(int idx) { return EERef(idx); }
166-
void write(int idx, uint8_t val) { (EERef(idx)) = val; }
174+
void write(int idx, uint8_t val)
175+
{
176+
(EERef(idx)) = val;
177+
}
167178
void update(int idx, uint8_t val) { EERef(idx).update(val); }
168179
void erase();
169180

@@ -174,7 +185,14 @@ struct EEPROMClass
174185
return 0x00;
175186
}
176187
EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
177-
uint16_t length() { return AP3_FLASH_EEPROM_SIZE; }
188+
uint16_t length()
189+
{
190+
return allowedSize;
191+
}
192+
void setLength(uint16_t length)
193+
{
194+
allowedSize = (length <= AP3_EEPROM_MAX_LENGTH) ? length : AP3_EEPROM_MAX_LENGTH;
195+
}
178196

179197
//Functionality to 'get' and 'put' objects to and from EEPROM.
180198
template <typename T>
@@ -192,11 +210,13 @@ struct EEPROMClass
192210
{
193211
const uint8_t *ptr = (const uint8_t *)&t;
194212

195-
writeBlockToEEPROM(idx, ptr, sizeof(T)); //Address, data, sizeOfData
213+
writeBlockToEEPROM(idx, ptr, sizeof(T), allowedSize); //Address, data, sizeOfData
196214

197215
return t;
198216
}
217+
218+
uint16_t allowedSize = AP3_DEFAULT_FLASH_EEPROM_SIZE;
199219
};
200220

201-
static EEPROMClass EEPROM __attribute__((unused));
221+
extern EEPROMClass EEPROM;
202222
#endif //_EEPROM_H

0 commit comments

Comments
 (0)