1+ /*
2+ EEPROM.h - EEPROM library
3+ Original Copyright (c) 2006 David A. Mellis. All right reserved.
4+ New version by Christopher Andrews 2015.
5+
6+ Copy of https://github.com/arduino/ArduinoCore-megaavr/blob/c8a1dd996c783777ec46167cfd8ad3fd2e6df185/libraries/EEPROM/src/EEPROM.h
7+ modified by James Foster 2020 to work with Arduino CI.
8+
9+ This library is free software; you can redistribute it and/or
10+ modify it under the terms of the GNU Lesser General Public
11+ License as published by the Free Software Foundation; either
12+ version 2.1 of the License, or (at your option) any later version.
13+
14+ This library is distributed in the hope that it will be useful,
15+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17+ Lesser General Public License for more details.
18+
19+ You should have received a copy of the GNU Lesser General Public
20+ License along with this library; if not, write to the Free Software
21+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22+ */
23+
24+ #ifndef EEPROM_h
25+ #define EEPROM_h
26+
27+ #include < inttypes.h>
28+ #include < avr/io.h>
29+
30+ // I see EEPROM_SIZE defined in various arv/io*.h files; why isn't it defined here?
31+ #define EEPROM_SIZE (4096 )
32+ // Is this all the custom code required?
33+ static uint8_t eeprom[EEPROM_SIZE];
34+ inline uint8_t eeprom_read_byte ( uint8_t * index ) { return eeprom[(unsigned long ) index % EEPROM_SIZE]; }
35+ inline void eeprom_write_byte ( uint8_t * index, uint8_t value ) { eeprom[(unsigned long ) index % EEPROM_SIZE] = value; }
36+
37+ /* **
38+ EERef class.
39+
40+ This object references an EEPROM cell.
41+ Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
42+ This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
43+ ***/
44+
45+ struct EERef {
46+
47+ EERef ( const int index )
48+ : index( index ) {}
49+
50+ // Access/read members.
51+ uint8_t operator *() const { return eeprom_read_byte ( (uint8_t *) index ); }
52+ operator uint8_t () const { return **this ; }
53+
54+ // Assignment/write members.
55+ EERef &operator =( const EERef &ref ) { return *this = *ref; }
56+ EERef &operator =( uint8_t in ) { return eeprom_write_byte ( (uint8_t *) index, in ), *this ; }
57+ EERef &operator +=( uint8_t in ) { return *this = **this + in; }
58+ EERef &operator -=( uint8_t in ) { return *this = **this - in; }
59+ EERef &operator *=( uint8_t in ) { return *this = **this * in; }
60+ EERef &operator /=( uint8_t in ) { return *this = **this / in; }
61+ EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
62+ EERef &operator %=( uint8_t in ) { return *this = **this % in; }
63+ EERef &operator &=( uint8_t in ) { return *this = **this & in; }
64+ EERef &operator |=( uint8_t in ) { return *this = **this | in; }
65+ EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
66+ EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
67+
68+ EERef &update ( uint8_t in ) { return in != *this ? *this = in : *this ; }
69+
70+ /* * Prefix increment/decrement **/
71+ EERef& operator ++() { return *this += 1 ; }
72+ EERef& operator --() { return *this -= 1 ; }
73+
74+ /* * Postfix increment/decrement **/
75+ uint8_t operator ++ (int ){
76+ uint8_t ret = **this ;
77+ return ++(*this ), ret;
78+ }
79+
80+ uint8_t operator -- (int ){
81+ uint8_t ret = **this ;
82+ return --(*this ), ret;
83+ }
84+
85+ int index; // Index of current EEPROM cell.
86+ };
87+
88+ /* **
89+ EEPtr class.
90+
91+ This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
92+ Just like a normal pointer type, this can be dereferenced and repositioned using
93+ increment/decrement operators.
94+ ***/
95+
96+ struct EEPtr {
97+
98+ EEPtr ( const int index )
99+ : index( index ) {}
100+
101+ operator int () const { return index; }
102+ EEPtr &operator =( int in ) { return index = in, *this ; }
103+
104+ // Iterator functionality.
105+ bool operator !=( const EEPtr &ptr ) { return index != ptr.index ; }
106+ EERef operator *() { return index; }
107+
108+ /* * Prefix & Postfix increment/decrement **/
109+ EEPtr& operator ++() { return ++index, *this ; }
110+ EEPtr& operator --() { return --index, *this ; }
111+ EEPtr operator ++ (int ) { return index++; }
112+ EEPtr operator -- (int ) { return index--; }
113+
114+ int index; // Index of current EEPROM cell.
115+ };
116+
117+ /* **
118+ EEPROMClass class.
119+
120+ This object represents the entire EEPROM space.
121+ It wraps the functionality of EEPtr and EERef into a basic interface.
122+ This class is also 100% backwards compatible with earlier Arduino core releases.
123+ ***/
124+
125+ struct EEPROMClass {
126+
127+ // Basic user access methods.
128+ EERef operator []( const int idx ) { return idx; }
129+ uint8_t read ( int idx ) { return EERef ( idx ); }
130+ void write ( int idx, uint8_t val ) { (EERef ( idx )) = val; }
131+ void update ( int idx, uint8_t val ) { EERef ( idx ).update ( val ); }
132+
133+ // STL and C++11 iteration capability.
134+ EEPtr begin () { return 0x00 ; }
135+ EEPtr end () { return length (); } // Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
136+ uint16_t length () { return EEPROM_SIZE; }
137+
138+ // Functionality to 'get' and 'put' objects to and from EEPROM.
139+ template < typename T > T &get ( int idx, T &t ){
140+ EEPtr e = idx;
141+ uint8_t *ptr = (uint8_t *) &t;
142+ for ( int count = sizeof (T) ; count ; --count, ++e ) *ptr++ = *e;
143+ return t;
144+ }
145+
146+ template < typename T > const T &put ( int idx, const T &t ){
147+ EEPtr e = idx;
148+ const uint8_t *ptr = (const uint8_t *) &t;
149+ for ( int count = sizeof (T) ; count ; --count, ++e ) (*e).update ( *ptr++ );
150+ return t;
151+ }
152+ };
153+
154+ static EEPROMClass EEPROM;
155+ #endif
0 commit comments