1
1
/*
2
2
EEPROM.h - EEPROM library
3
3
Original Copyright (c) 2006 David A. Mellis. All right reserved.
4
- New version by Christopher Andrews 2015.
4
+ Version 2.0 - 2.1 Copyright (c) 2015 Christopher Andrews. All right reserved.
5
+
6
+ This library has been entirely re-written, and none of the original code has
7
+ been reused. The only original element left are the names 'EEPROM' & 'EEPROMClass'.
5
8
6
9
This library is free software; you can redistribute it and/or
7
10
modify it under the terms of the GNU Lesser General Public
18
21
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
22
*/
20
23
21
- #ifndef EEPROM_h
22
- #define EEPROM_h
24
+ #if defined(__AVR__) && !defined( EEPROM_h)
25
+ #define EEPROM_h
23
26
24
- #include < inttypes.h>
27
+ #ifndef Arduino_h // These includes are available through Arduino.h
28
+ #include < inttypes.h>
29
+ #include < avr/io.h>
30
+ #endif
25
31
#include < avr/eeprom.h>
26
- #include < avr/io.h>
27
32
28
33
struct EEPtr ; // Forward declaration for EERef::opreator&
29
34
struct EEBit ; // Forward declaration for EERef::opreator[]
30
35
31
36
/* **
32
37
EERef class.
33
-
38
+
34
39
This object references an EEPROM cell.
35
40
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
36
41
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
@@ -40,18 +45,18 @@ struct EERef{
40
45
41
46
template < typename T > EERef ( T *ptr ) : index( (int ) ptr ) {}
42
47
EERef ( const int index ) : index( index ) {}
43
-
48
+
44
49
// Access/read members.
45
50
uint8_t operator *() const { return eeprom_read_byte ( (uint8_t *) index ); }
46
51
operator uint8_t () const { return **this ; }
47
52
48
- EEPtr operator &() const ; // Defined below EEPtr
53
+ EEPtr operator &() const ; // Defined below EEPtr
49
54
50
55
// Bit access members, defined below EEBit declaration.
51
56
EEBit operator []( const int bidx );
52
57
EEBit begin ();
53
58
EEBit end ();
54
-
59
+
55
60
// Assignment/write members.
56
61
EERef &operator =( const EERef &ref ) { return *this = *ref; }
57
62
EERef &operator =( uint8_t in ) { return eeprom_write_byte ( (uint8_t *) index, in ), *this ; }
@@ -65,24 +70,24 @@ struct EERef{
65
70
EERef &operator |=( uint8_t in ) { return *this = **this | in; }
66
71
EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
67
72
EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
68
-
73
+
69
74
EERef &update ( uint8_t in ) { return in != *this ? *this = in : *this ; }
70
-
75
+
71
76
// Prefix increment/decrement
72
77
EERef& operator ++() { return *this += 1 ; }
73
78
EERef& operator --() { return *this -= 1 ; }
74
-
79
+
75
80
// Postfix increment/decrement
76
- uint8_t operator ++ (int ){
81
+ uint8_t operator ++ (int ){
77
82
uint8_t ret = **this ;
78
83
return ++(*this ), ret;
79
84
}
80
85
81
- uint8_t operator -- (int ){
86
+ uint8_t operator -- (int ){
82
87
uint8_t ret = **this ;
83
88
return --(*this ), ret;
84
89
}
85
-
90
+
86
91
int index; // Index of current EEPROM cell.
87
92
};
88
93
@@ -162,29 +167,29 @@ inline EEBit EERef::end() { return EEBit( index + 1, 0 );
162
167
163
168
/* **
164
169
EEPtr class.
165
-
170
+
166
171
This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
167
- Just like a normal pointer type, this can be dereferenced and repositioned using
172
+ Just like a normal pointer type, this can be dereferenced and repositioned using
168
173
increment/decrement operators.
169
174
***/
170
175
171
176
struct EEPtr {
172
177
173
- template < typename T > EEPtr ( T *ptr ) : index( (int ) ptr ) {}
178
+ template < typename T > EEPtr ( T *ptr ) : index( (int ) ptr ) {}
174
179
EEPtr ( const int index ) : index( index ) {}
175
180
176
- // Pointer read/write.
181
+ // Pointer read/write.
177
182
operator int () const { return index; }
178
183
EEPtr &operator =( int in ) { return index = in, *this ; }
179
- EERef operator []( int idx ) { return index + idx; }
180
-
184
+ EERef operator []( int idx ) { return index + idx; }
185
+
181
186
// Iterator functionality.
182
187
bool operator !=( const EEPtr &ptr ) { return index != ptr.index ; }
183
188
EEPtr& operator +=( int idx ) { return index += idx, *this ; }
184
189
EEPtr& operator -=( int idx ) { return index -= idx, *this ; }
185
190
186
191
// Dreference & member access.
187
- EERef operator *() { return index; }
192
+ EERef operator *() { return index; }
188
193
EERef *operator ->() { return (EERef*) this ; }
189
194
190
195
// Prefix & Postfix increment/decrement
@@ -200,97 +205,97 @@ inline EEPtr EERef::operator&() const { return index; } //Deferred definition ti
200
205
201
206
/* **
202
207
EEPROMClass class.
203
-
208
+
204
209
This object represents the entire EEPROM space.
205
210
It wraps the functionality of EEPtr and EERef into a basic interface.
206
211
This class is also 100% backwards compatible with earlier Arduino core releases.
207
212
***/
208
213
209
214
class EEPROMClass {
210
- protected:
211
-
212
- /* **
213
- EEIterator interface.
214
- This interface allows creating customized ranges within
215
- the EEPROM. Essentially intended for use with ranged for
216
- loops, or STL style iteration on subsections of the EEPROM.
217
- ***/
218
-
219
- struct EEIterator {
220
- EEIterator ( EEPtr _start, int _length ) : start(_start), length(_length) {}
221
- EEPtr begin () { return start; }
222
- EEPtr end () { return start + length; }
223
- EEPtr start;
224
- int length;
225
- };
226
-
227
- public:
228
-
229
- // Basic user access methods.
230
- EERef operator []( EERef ref ) { return ref; }
231
- EERef read ( EERef ref ) { return ref; }
232
- void write ( EERef ref, uint8_t val ) { ref = val; }
233
- void update ( EERef ref, uint8_t val ) { ref.update ( val ); }
234
-
235
- // STL and C++11 iteration capability.
236
- EEPtr begin () { return 0x00 ; }
237
- EEPtr end () { return length (); } // Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
238
- uint16_t length () { return E2END + 1 ; }
239
-
240
- // Extended iteration functionality (arbitrary regions).
241
- // These can make serialized reading/writing easy.
242
- template < typename T > EEIterator iterate( T *t ) { return EEIterator ( t, sizeof (T) ); }
243
- EEIterator iterate( EEPtr ptr, int length ) { return EEIterator ( ptr, length ); }
244
-
245
- // Bit access methods.
246
- EEBit readBit ( EERef ref, uint8_t bidx ) { return ref[ bidx ]; }
247
- void writeBit ( EERef ref, uint8_t bidx, const bool val ) { ref[ bidx ] = val; }
248
-
249
- // A helper function for the builtin eeprom_is_ready macro.
250
- bool ready () { return eeprom_is_ready (); }
251
-
252
-
253
- /*
254
- Functionality to 'get' and 'put' objects to and from EEPROM.
255
- All put() functions use the update() method of writing to the EEPROM
256
- */
257
-
258
- // Generic get() function, for any type of data.
259
- template < typename T > T &get ( EEPtr ptr, T &t ){
260
- uint8_t *dest = (uint8_t *) &t;
261
- for ( int count = sizeof (T) ; count ; --count, ++ptr ) *dest++ = *ptr;
262
- return t;
263
- }
264
-
265
- // EEMEM helper: This function retrieves an object which uses the same type as the provided object.
266
- template < typename T > T get ( T &t ){ return get (&t); }
267
- template < typename T > T get ( T *t ){
268
- T result;
269
- return get ( t, result );
270
- }
271
-
272
- // Overload get() function to deal with the String class.
273
- String &get ( EEPtr ptr, String &t ){
274
- for ( auto el : iterate(ptr, length () - ptr)){
275
- if (el) t += char (el);
276
- else break ;
277
- }
278
- return t;
279
- }
280
-
281
- // Generic put() function, for any type of data.
282
- template < typename T > const T &put ( EEPtr ptr, const T &t ){
283
- const uint8_t *src = (const uint8_t *) &t;
284
- for ( int count = sizeof (T) ; count ; --count, ++ptr ) (*ptr).update ( *src++ );
285
- return t;
286
- }
287
-
288
- // Overload of put() function to deal with the String class.
289
- const String &put ( EEPtr ptr, const String &t ){
290
- uint16_t idx = 0 ;
291
- for (auto el : iterate(ptr, t.length () + 1 )) el.update (t[idx++]); // Read past length() as String::operator[] returns 0 on an out of bounds read (for null terminator).
292
- return t;
293
- }
215
+ protected:
216
+
217
+ /* **
218
+ EEIterator interface.
219
+ This interface allows creating customized ranges within
220
+ the EEPROM. Essentially intended for use with ranged for
221
+ loops, or STL style iteration on subsections of the EEPROM.
222
+ ***/
223
+
224
+ struct EEIterator {
225
+ EEIterator ( EEPtr _start, int _length ) : start(_start), length(_length) {}
226
+ EEPtr begin () { return start; }
227
+ EEPtr end () { return start + length; }
228
+ EEPtr start;
229
+ int length;
230
+ };
231
+
232
+ public:
233
+
234
+ // Basic user access methods.
235
+ EERef operator []( EERef ref ) { return ref; }
236
+ EERef read ( EERef ref ) { return ref; }
237
+ void write ( EERef ref, uint8_t val ) { ref = val; }
238
+ void update ( EERef ref, uint8_t val ) { ref.update ( val ); }
239
+
240
+ // STL and C++11 iteration capability.
241
+ EEPtr begin () { return 0x00 ; }
242
+ EEPtr end () { return length (); } // Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
243
+ uint16_t length () { return E2END + 1 ; }
244
+
245
+ // Extended iteration functionality (arbitrary regions).
246
+ // These can make serialized reading/writing easy.
247
+ template < typename T > EEIterator iterate( T *t ) { return EEIterator ( t, sizeof (T) ); }
248
+ EEIterator iterate( EEPtr ptr, int length ) { return EEIterator ( ptr, length ); }
249
+
250
+ // Bit access methods.
251
+ EEBit readBit ( EERef ref, uint8_t bidx ) { return ref[ bidx ]; }
252
+ void writeBit ( EERef ref, uint8_t bidx, const bool val ) { ref[ bidx ] = val; }
253
+
254
+ // A helper function for the builtin eeprom_is_ready macro.
255
+ bool ready () { return eeprom_is_ready (); }
256
+
257
+
258
+ /*
259
+ Functionality to 'get' and 'put' objects to and from EEPROM.
260
+ All put() functions use the update() method of writing to the EEPROM
261
+ */
262
+
263
+ // Generic get() function, for any type of data.
264
+ template < typename T > T &get ( EEPtr ptr, T &t ){
265
+ uint8_t *dest = (uint8_t *) &t;
266
+ for ( int count = sizeof (T) ; count ; --count, ++ptr ) *dest++ = *ptr;
267
+ return t;
268
+ }
269
+
270
+ // EEMEM helper: This function retrieves an object which uses the same type as the provided object.
271
+ template < typename T > T get ( T &t ){ return get (&t); }
272
+ template < typename T > T get ( T *t ){
273
+ T result;
274
+ return get ( t, result );
275
+ }
276
+
277
+ // Overload get() function to deal with the String class.
278
+ String &get ( EEPtr ptr, String &t ){
279
+ for ( auto el : iterate(ptr, length () - ptr)){
280
+ if (el) t += char (el);
281
+ else break ;
282
+ }
283
+ return t;
284
+ }
285
+
286
+ // Generic put() function, for any type of data.
287
+ template < typename T > const T &put ( EEPtr ptr, const T &t ){
288
+ const uint8_t *src = (const uint8_t *) &t;
289
+ for ( int count = sizeof (T) ; count ; --count, ++ptr ) (*ptr).update ( *src++ );
290
+ return t;
291
+ }
292
+
293
+ // Overload of put() function to deal with the String class.
294
+ const String &put ( EEPtr ptr, const String &t ){
295
+ uint16_t idx = 0 ;
296
+ for (auto el : iterate(ptr, t.length () + 1 )) el.update (t[idx++]); // Read past length() as String::operator[] returns 0 on an out of bounds read (for null terminator).
297
+ return t;
298
+ }
294
299
};
295
300
296
301
static EEPROMClass EEPROM;
0 commit comments