11/*
22 EEPROM.h - EEPROM library
33 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'.
58
69 This library is free software; you can redistribute it and/or
710 modify it under the terms of the GNU Lesser General Public
1821 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1922*/
2023
21- #ifndef EEPROM_h
22- #define EEPROM_h
24+ #if defined(__AVR__) && !defined( EEPROM_h)
25+ #define EEPROM_h
2326
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
2531#include < avr/eeprom.h>
26- #include < avr/io.h>
2732
2833struct EEPtr ; // Forward declaration for EERef::opreator&
2934struct EEBit ; // Forward declaration for EERef::opreator[]
3035
3136/* **
3237 EERef class.
33-
38+
3439 This object references an EEPROM cell.
3540 Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
3641 This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
@@ -40,18 +45,18 @@ struct EERef{
4045
4146 template < typename T > EERef ( T *ptr ) : index( (int ) ptr ) {}
4247 EERef ( const int index ) : index( index ) {}
43-
48+
4449 // Access/read members.
4550 uint8_t operator *() const { return eeprom_read_byte ( (uint8_t *) index ); }
4651 operator uint8_t () const { return **this ; }
4752
48- EEPtr operator &() const ; // Defined below EEPtr
53+ EEPtr operator &() const ; // Defined below EEPtr
4954
5055 // Bit access members, defined below EEBit declaration.
5156 EEBit operator []( const int bidx );
5257 EEBit begin ();
5358 EEBit end ();
54-
59+
5560 // Assignment/write members.
5661 EERef &operator =( const EERef &ref ) { return *this = *ref; }
5762 EERef &operator =( uint8_t in ) { return eeprom_write_byte ( (uint8_t *) index, in ), *this ; }
@@ -65,24 +70,24 @@ struct EERef{
6570 EERef &operator |=( uint8_t in ) { return *this = **this | in; }
6671 EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
6772 EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
68-
73+
6974 EERef &update ( uint8_t in ) { return in != *this ? *this = in : *this ; }
70-
75+
7176 // Prefix increment/decrement
7277 EERef& operator ++() { return *this += 1 ; }
7378 EERef& operator --() { return *this -= 1 ; }
74-
79+
7580 // Postfix increment/decrement
76- uint8_t operator ++ (int ){
81+ uint8_t operator ++ (int ){
7782 uint8_t ret = **this ;
7883 return ++(*this ), ret;
7984 }
8085
81- uint8_t operator -- (int ){
86+ uint8_t operator -- (int ){
8287 uint8_t ret = **this ;
8388 return --(*this ), ret;
8489 }
85-
90+
8691 int index; // Index of current EEPROM cell.
8792};
8893
@@ -162,29 +167,29 @@ inline EEBit EERef::end() { return EEBit( index + 1, 0 );
162167
163168/* **
164169 EEPtr class.
165-
170+
166171 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
168173 increment/decrement operators.
169174***/
170175
171176struct EEPtr {
172177
173- template < typename T > EEPtr ( T *ptr ) : index( (int ) ptr ) {}
178+ template < typename T > EEPtr ( T *ptr ) : index( (int ) ptr ) {}
174179 EEPtr ( const int index ) : index( index ) {}
175180
176- // Pointer read/write.
181+ // Pointer read/write.
177182 operator int () const { return index; }
178183 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+
181186 // Iterator functionality.
182187 bool operator !=( const EEPtr &ptr ) { return index != ptr.index ; }
183188 EEPtr& operator +=( int idx ) { return index += idx, *this ; }
184189 EEPtr& operator -=( int idx ) { return index -= idx, *this ; }
185190
186191 // Dreference & member access.
187- EERef operator *() { return index; }
192+ EERef operator *() { return index; }
188193 EERef *operator ->() { return (EERef*) this ; }
189194
190195 // Prefix & Postfix increment/decrement
@@ -200,97 +205,97 @@ inline EEPtr EERef::operator&() const { return index; } //Deferred definition ti
200205
201206/* **
202207 EEPROMClass class.
203-
208+
204209 This object represents the entire EEPROM space.
205210 It wraps the functionality of EEPtr and EERef into a basic interface.
206211 This class is also 100% backwards compatible with earlier Arduino core releases.
207212***/
208213
209214class 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+ }
294299};
295300
296301static EEPROMClass EEPROM;
0 commit comments