Developer World
Spresense Arduino Library v3.2.0-77d75a4
EEPROM.h
1/*
2 EEPROM.h - EEPROM library
3 Copyright 2018 Sony Semiconductor Solutions Corporation
4 Original Copyright (c) 2006 David A. Mellis. All right reserved.
5 New version by Christopher Andrews 2015.
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#ifndef EEPROM_h
23#define EEPROM_h
24
25#ifdef SUBCORE
26#error "EEPROM library is NOT supported by SubCore."
27#endif
28
35#include <stdint.h>
36#include <inttypes.h>
37#include <sys/stat.h>
38#include <fcntl.h>
39
40// Emulate EEPROM through a below file on SPI-Flash
41#define EEPROM_EMU "/mnt/spif/eeprom.emu"
42
43// Default size is the smaller than a sector of SPI-Flash.
44// If you want the large capacity EEPROM, you can specify a larger size.
45#define E2END 4000
46
47/***
48 EERef class.
49
50 This object references an EEPROM cell.
51 Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
52 This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
53***/
54
55struct EERef{
56
57 EERef( const int index )
58 : index( index ) {}
59
60 //Access/read members.
61 uint8_t operator*() const;
62 void createInitialFile() const;
63 operator uint8_t() const { return **this; }
64
65 //Assignment/write members.
66 EERef &operator=( const EERef &ref ) { return *this = *ref; }
67 EERef &operator=( uint8_t in );
68 EERef &operator +=( uint8_t in ) { return *this = **this + in; }
69 EERef &operator -=( uint8_t in ) { return *this = **this - in; }
70 EERef &operator *=( uint8_t in ) { return *this = **this * in; }
71 EERef &operator /=( uint8_t in ) { return *this = **this / in; }
72 EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
73 EERef &operator %=( uint8_t in ) { return *this = **this % in; }
74 EERef &operator &=( uint8_t in ) { return *this = **this & in; }
75 EERef &operator |=( uint8_t in ) { return *this = **this | in; }
76 EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
77 EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
78
79 EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; }
80
82 EERef& operator++() { return *this += 1; }
83 EERef& operator--() { return *this -= 1; }
84
86 uint8_t operator++ (int){
87 uint8_t ret = **this;
88 return ++(*this), ret;
89 }
90
91 uint8_t operator-- (int){
92 uint8_t ret = **this;
93 return --(*this), ret;
94 }
95
96 int index; //Index of current EEPROM cell.
97};
98
99/***
100 EEPtr class.
101
102 This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
103 Just like a normal pointer type, this can be dereferenced and repositioned using
104 increment/decrement operators.
105***/
106
107struct EEPtr{
108
109 EEPtr( const int index )
110 : index( index ) {}
111
112 operator int() const { return index; }
113 EEPtr &operator=( int in ) { return index = in, *this; }
114
115 //Iterator functionality.
116 bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
117 EERef operator*() { return index; }
118
120 EEPtr& operator++() { return ++index, *this; }
121 EEPtr& operator--() { return --index, *this; }
122 EEPtr operator++ (int) { return index++; }
123 EEPtr operator-- (int) { return index--; }
124
125 int index; //Index of current EEPROM cell.
126};
127
128/***
129 EEPROMClass class.
130
131 This object represents the entire EEPROM space.
132 It wraps the functionality of EEPtr and EERef into a basic interface.
133 This class is also 100% backwards compatible with earlier Arduino core releases.
134***/
135
137
138 EEPROMClass() : initialized(0) {}
139 //Create a eeprom emulation file if it doesn't exist
140 void init() {
141 int ret;
142 FILE *fp = NULL;
143 struct stat statBuf;
144 long filesize = -1;
145 long eepromsize = E2END;
146
147 if (initialized != 0) {
148 /* Already initialized */
149 return;
150 }
151
152 /* Check whether the eeprom emulation file has already existed or not */
153 if (0 == stat(EEPROM_EMU, &statBuf)) {
154 filesize = statBuf.st_size;
155 }
156
157 if (eepromsize == filesize) {
158 /* Already existed if the file size is equal to the eeprom size */
159 initialized = 1;
160 return;
161 }
162
163 /* Create a new file */
164 if ((fp = fopen(EEPROM_EMU, "wb")) == NULL) {
165 printf("ERROR: eeprom open failure\n");
166 }
167
168 uint8_t *ptr = (uint8_t*)zalloc(eepromsize);
169 ret = fwrite(ptr, 1, eepromsize, fp);
170 if (ret != eepromsize) {
171 printf("ERROR: eeprom init failure (%d)\n", ret);
172 }
173
174 fclose(fp);
175
176 initialized = 1;
177 return;
178 }
179 //Remove the eeprom file and create the a zero-filled eeprom file
180 void clear() {
181 unlink(EEPROM_EMU);
182 initialized = 0;
183 init();
184 }
185
186 //Basic user access methods.
187 EERef operator[]( const int idx ) { init(); return idx; }
188 uint8_t read( int idx ) { init(); return EERef( idx ); }
189 void write( int idx, uint8_t val ) { init(); (EERef( idx )) = val; }
190 void update( int idx, uint8_t val ) { init(); EERef( idx ).update( val ); }
191
192 //STL and C++11 iteration capability.
193 EEPtr begin() { return 0x00; }
194 EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
195 uint16_t length() { return E2END; }
196
197 //Functionality to 'get' and 'put' objects to and from EEPROM.
198 template< typename T > T &get( int idx, T &t ){
199 int ret;
200 FILE *fp = NULL;
201
202 init();
203
204 if ((fp = fopen(EEPROM_EMU, "rb")) == NULL) {
205 printf("ERROR: eeprom open failure\n");
206 goto errout;
207 }
208
209 ret = fseek(fp, idx, SEEK_SET);
210 if (ret) {
211 printf("ERROR: eeprom seek failure\n");
212 goto errout_with_close;
213 }
214
215 ret = fread((uint8_t*)&t, 1, sizeof(T), fp);
216 if (ret != sizeof(T)) {
217 printf("ERROR: eeprom read failure (%d)\n", ret);
218 }
219
220 errout_with_close:
221 fclose(fp);
222 errout:
223 return t;
224 }
225
226 template< typename T > const T &put( int idx, const T &t ){
227 int ret;
228 FILE *fp = NULL;
229
230 init();
231
232 if ((fp = fopen(EEPROM_EMU, "rb+")) == NULL) {
233 printf("ERROR: eeprom open failure\n");
234 goto errout;
235 }
236
237 ret = fseek(fp, idx, SEEK_SET);
238 if (ret) {
239 printf("ERROR: eeprom seek failure\n");
240 goto errout_with_close;
241 }
242
243 ret = fwrite((uint8_t*)&t, 1, sizeof(T), fp);
244 if (ret != sizeof(T)) {
245 printf("ERROR: eeprom write failure (%d)\n", ret);
246 }
247
248 errout_with_close:
249 fclose(fp);
250 errout:
251 return t;
252 }
253
254 int initialized;
255};
256
257extern EEPROMClass EEPROM;
258
261#endif
Definition: EEPROM.h:136
Definition: EEPROM.h:107
EEPtr & operator++()
Definition: EEPROM.h:120
Definition: EEPROM.h:55
EERef & operator++()
Definition: EEPROM.h:82