1 #ifndef EEPROMSettings_h
2 #define EEPROMSettings_h
7 #ifdef EEPROM_FLASH_PARTITION_NAME
9 #define EEPROM_SIZE 4096
12 #define EEPROM_SIZE EEPROM.length()
15 template <
class T, u
int32_t VERSION = 0xba5eba11>
28 uint32_t offs = validate();
32 EEPROM.get(offs, siz); offs +=
sizeof(siz);
33 if (siz ==
sizeof(*
this))
35 EEPROM.get(offs, *
this);
45 uint32_t magic = VERSION;
46 EEPROM.put(offs, magic); offs +=
sizeof(magic);
48 uint16_t siz_offs = offs; offs +=
sizeof(siz_offs);
49 EEPROM.put(offs, *
this);
50 offs +=
sizeof(*this);
53 uint16_t siz = offs-siz_offs-
sizeof(siz_offs);
55 EEPROM.put(siz_offs, siz);
59 EEPROM.get(offs, magic);
60 if (magic != kCommandListMagic)
62 magic = kCommandListMagic;
63 EEPROM.put(offs, magic); offs +=
sizeof(magic);
65 uint8_t tag = kEndTag;
66 EEPROM.put(offs, tag); offs +=
sizeof(tag);
69 #ifdef EEPROM_FLASH_PARTITION_NAME
76 uint32_t offs = validateCommandList();
79 uint8_t tag = kEndTag;
80 EEPROM.put(offs, tag);
83 #ifdef EEPROM_FLASH_PARTITION_NAME
94 uint32_t offs = validateCommandList();
101 EEPROM.get(offs, snum); offs +=
sizeof(snum);
105 EEPROM.get(offs, len); offs +=
sizeof(len) + len;
114 uint32_t offs = validateCommandList();
121 EEPROM.get(offs, snum); offs +=
sizeof(snum);
124 if (size < maxBufferSize)
125 buffer[size++] = snum;
126 EEPROM.get(offs, len); offs +=
sizeof(len) + len;
134 uint32_t offs = validateCommandList();
140 EEPROM.get(offs, snum); offs +=
sizeof(snum);
148 EEPROM.get(offs, len); offs +=
sizeof(len);
152 EEPROM.get(offs, ch); offs +=
sizeof(ch);
153 stream.print((
char)ch);
165 typedef uint32_t BMAPWORD;
166 #define BMAPWORD_GRANULARITY (sizeof(BMAPWORD))
167 #define BMAPWORD_BIT_SIZE (sizeof(BMAPWORD) * 8)
168 #define BIT_MAPWORD(bitpos) (0x1L << (BMAPWORD_BIT_SIZE - 1 - (bitpos)))
169 #define SET_MAPWORD_BIT(value, bit) {\
170 uint8_t bitpos = (value) % sizeof(usedBitmap[0]); \
171 uint8_t wordpos = (value) / sizeof(usedBitmap[0]); \
172 usedBitmap[wordpos] = (usedBitmap[wordpos] & ~(BIT_MAPWORD(bitpos))) | (uint32_t(bit) << (BMAPWORD_BIT_SIZE - 1 - bitpos)); }
173 #define MAPWORD_BIT(value) \
174 ((usedBitmap[(value) / sizeof(usedBitmap[0])] & BIT_MAPWORD((value) % sizeof(usedBitmap[0]))) != 0)
176 uint32_t usedBitmap[kMaxCommands /
sizeof(uint32_t)+1];
177 memset(&usedBitmap,
'\0',
sizeof(usedBitmap));
179 uint32_t offs = validateCommandList();
183 uint16_t scanoffs = offs;
187 EEPROM.get(scanoffs, snum); scanoffs +=
sizeof(snum);
193 EEPROM.get(scanoffs, len); scanoffs +=
sizeof(len) + len;
195 for (
unsigned i = 0; i < 100; i++)
199 uint16_t scanoffs = offs;
203 EEPROM.get(scanoffs, snum); scanoffs +=
sizeof(snum);
214 EEPROM.get(scanoffs, len); scanoffs +=
sizeof(len);
220 EEPROM.get(scanoffs, ch); scanoffs +=
sizeof(ch);
221 stream.print((
char)ch);
236 #undef SET_MAPWORD_BIT
238 #undef BMAPWORD_BIT_SIZE
239 #undef BMAPWORD_GRANULARITY
242 bool readCommand(uint8_t num,
char* cmd,
size_t cmdBufferSize,
const char* prefix =
nullptr)
244 return readCommandInternal(num, cmd, cmdBufferSize,
nullptr, prefix);
249 uint16_t writeoffs = 0;
250 if (!readCommandInternal(num,
nullptr, 0, &writeoffs))
254 uint16_t readoffs = writeoffs + 1;
255 EEPROM.get(readoffs, len); readoffs +=
sizeof(len);
261 EEPROM.get(readoffs, tag); readoffs +=
sizeof(tag);
262 EEPROM.put(writeoffs, tag); writeoffs +=
sizeof(tag);
269 EEPROM.get(readoffs, readlen); readoffs +=
sizeof(readlen);
270 EEPROM.put(writeoffs, readlen); writeoffs +=
sizeof(readlen);
274 EEPROM.get(readoffs, ch); readoffs +=
sizeof(ch);
275 EEPROM.put(writeoffs, ch); writeoffs +=
sizeof(ch);
280 #ifdef EEPROM_FLASH_PARTITION_NAME
296 uint32_t offs = validate();
300 EEPROM.get(offs, siz); offs += siz +
sizeof(siz);
303 EEPROM.get(offs, magic); offs +=
sizeof(magic);
304 if (magic == kCommandListMagic)
310 EEPROM.get(offs, tag);
313 EEPROM.put(offs, num); offs +=
sizeof(num);
315 uint8_t len = strlen(cmd);
316 EEPROM.put(offs, len); offs +=
sizeof(len);
319 EEPROM.put(offs, *cmd); offs +=
sizeof(*cmd);
325 EEPROM.put(offs, num); offs +=
sizeof(num);
327 #ifdef EEPROM_FLASH_PARTITION_NAME
334 EEPROM.get(offs, len); offs +=
sizeof(len) + len;
340 magic = kCommandListMagic;
341 EEPROM.put(offs, magic); offs +=
sizeof(magic);
343 EEPROM.put(offs, num); offs +=
sizeof(num);
345 uint8_t len = strlen(cmd);
346 EEPROM.put(offs, len); offs +=
sizeof(len);
349 EEPROM.put(offs, *cmd); offs +=
sizeof(*cmd);
355 EEPROM.put(offs, num); offs +=
sizeof(num);
357 #ifdef EEPROM_FLASH_PARTITION_NAME
367 static uint32_t constexpr kCommandListMagic = 0xf005ba11;
368 static uint8_t constexpr kEndTag = 0xff;
369 static uint8_t constexpr kMaxCommands = 100;
375 EEPROM.get(offs, magic);
376 uint32_t crc = crcFrom(
sizeof(magic));
377 if (magic == (VERSION ^ crc))
379 offs +=
sizeof(magic);
384 uint32_t validateCommandList()
386 uint32_t offs = validate();
390 EEPROM.get(offs, siz); offs += siz +
sizeof(siz);
393 EEPROM.get(offs, magic); offs +=
sizeof(magic);
394 if (magic == kCommandListMagic)
402 bool readCommandInternal(uint8_t num,
char* cmd,
size_t cmdBufferSize, uint16_t* cmdoffs =
nullptr,
const char* prefix =
nullptr)
404 uint32_t offs = validateCommandList();
410 EEPROM.get(offs, snum);
413 if (snum == num && cmdoffs !=
nullptr)
416 offs +=
sizeof(snum);
417 EEPROM.get(offs, len); offs +=
sizeof(len);
423 char* cmd_end = cmd + cmdBufferSize - 1;
424 if (prefix !=
nullptr)
426 while (prefix !=
nullptr && (ch = *prefix++) !=
'\0' && cmd < cmd_end)
433 EEPROM.get(offs, ch); offs +=
sizeof(ch);
454 uint32_t crc = crcFrom(
sizeof(uint32_t));
455 EEPROM.put(0, VERSION ^ crc);
458 static uint32_t crcFrom(
unsigned offset = 0)
460 static const uint32_t crc_table[16] PROGMEM =
462 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
463 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
464 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
465 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
470 uint8_t eepromByte = EEPROM.read(offset);
471 crc = pgm_read_uint32(&crc_table[(crc ^ eepromByte) & 0x0f]) ^ (crc >> 4);
472 crc = pgm_read_uint32(&crc_table[(crc ^ (eepromByte >> 4)) & 0x0f]) ^ (crc >> 4);
479 static inline uint32_t pgm_read_uint32(
const uint32_t* p)
481 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || \
482 defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || \
483 defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
484 return pgm_read_dword(p);