Rework how the whole thing operates

Allows other plugins to request a slice of EEPROM, and returns the starting
location of their area. Makes a CRC out of the slice sizes, so that it can
detect when the EEPROM and the Sketch become out of sync. Handling that case is
left up to the user.

As a consequence, we no longer reserve a big chunk of EEPROM for the keymap,
that just becomes another slice of it, which can be anywhere. This makes it a
bit harder to adjust the size of it, but as far as this plugin goes, playing
with the EEPROM layout will usually mean having to update its contents from
scratch, anyway.

Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
pull/365/head
Gergely Nagy 8 years ago
parent 496cff414b
commit c0d2c51730

@ -50,8 +50,9 @@ void setup () {
while (!Serial) { while (!Serial) {
} }
Serial.println (EEPROMSettings.isValid () ? "valid EEPROM settings" : "invalid EEPROM settings"); Serial.println (EEPROMSettings.isValid () ? F("valid EEPROM settings") : F("invalid EEPROM settings"));
Serial.println (EEPROMSettings.endOfSettings ()); Serial.println (EEPROMSettings.crc (), HEX);
Serial.println (EEPROMSettings.version ());
} }
void loop () { void loop () {

@ -17,12 +17,14 @@
*/ */
#include <Kaleidoscope-EEPROM-Settings.h> #include <Kaleidoscope-EEPROM-Settings.h>
#include "crc.h"
namespace FocusHooks { namespace FocusHooks {
bool settings (const char *command) { bool settings (const char *command) {
enum { enum {
ISVALID, ISVALID,
GETVERSION, GETVERSION,
CRC,
} subCommand; } subCommand;
if (strncmp_P (command, PSTR ("settings."), 9) != 0) if (strncmp_P (command, PSTR ("settings."), 9) != 0)
@ -32,6 +34,8 @@ namespace FocusHooks {
subCommand = ISVALID; subCommand = ISVALID;
else if (strcmp_P (command + 9, PSTR ("version")) == 0) else if (strcmp_P (command + 9, PSTR ("version")) == 0)
subCommand = GETVERSION; subCommand = GETVERSION;
else if (strcmp_P (command + 9, PSTR ("crc")) == 0)
subCommand = CRC;
else else
return false; return false;
@ -41,6 +45,10 @@ namespace FocusHooks {
break; break;
case GETVERSION: case GETVERSION:
Serial.println (EEPROMSettings.version ()); Serial.println (EEPROMSettings.version ());
case CRC:
Serial.print (::CRC.crc, HEX);
Serial.print (F("/"));
Serial.println (EEPROMSettings.crc (), HEX);
break; break;
} }

@ -30,4 +30,7 @@ namespace FocusHooks {
"Return whether the EEPROM settings are valid, or not.\n\n" \ "Return whether the EEPROM settings are valid, or not.\n\n" \
"settings.version\n" \ "settings.version\n" \
"----------------\n" \ "----------------\n" \
"Return the version of the EEPROM settings.") "Return the version of the EEPROM settings.\n\n" \
"settings.crc\n" \
"------------\n" \
"Return the CRC of the settings.")

@ -17,41 +17,64 @@
*/ */
#include <Kaleidoscope-EEPROM-Settings.h> #include <Kaleidoscope-EEPROM-Settings.h>
#include "crc.h"
namespace KaleidoscopePlugins { namespace KaleidoscopePlugins {
struct EEPROMSettings::settings EEPROMSettings::settings; struct EEPROMSettings::settings EEPROMSettings::settings;
bool EEPROMSettings::_isValid; bool EEPROMSettings::_isValid;
bool EEPROMSettings::sealed;
uint16_t EEPROMSettings::nextStart = sizeof (EEPROMSettings::settings);
EEPROMSettings::EEPROMSettings (void) { EEPROMSettings::EEPROMSettings (void) {
} }
void void
EEPROMSettings::begin (void) { EEPROMSettings::begin (void) {
_isValid = true;
EEPROM.get (0, settings); EEPROM.get (0, settings);
}
bool
EEPROMSettings::isValid (void) {
return _isValid;
}
uint16_t
EEPROMSettings::crc (void) {
if (sealed)
return settings.crc;
return 0;
}
void
EEPROMSettings::seal (void) {
sealed = true;
CRC.finalize ();
if (settings.magic[0] != 'K' || settings.magic[1] != 'S') { if (settings.magic[0] != 'K' || settings.magic[1] != 'S') {
settings.magic[0] = 'K'; settings.magic[0] = 'K';
settings.magic[1] = 'S'; settings.magic[1] = 'S';
settings.endOfSettings = EEPROM_SETTINGS_RESERVED - 1; settings.version = 0;
settings.crc = CRC.crc;
return update (); return update ();
} }
if (settings.endOfSettings != EEPROM_SETTINGS_RESERVED - 1) if (settings.crc != CRC.crc)
_isValid = false; _isValid = false;
} }
uint16_t uint16_t
EEPROMSettings::endOfSettings (void) { EEPROMSettings::requestSlice (uint16_t size) {
if (!isValid ()) if (sealed)
return 0; return 0;
return settings.endOfSettings;
}
bool uint16_t start = nextStart;
EEPROMSettings::isValid (void) { nextStart += size;
return _isValid;
CRC.update ((const void *)&size, sizeof (size));
return start;
} }
void void
@ -61,6 +84,8 @@ namespace KaleidoscopePlugins {
void void
EEPROMSettings::update (void) { EEPROMSettings::update (void) {
settings.crc = CRC.crc;
EEPROM.put (0, settings); EEPROM.put (0, settings);
_isValid = true; _isValid = true;
} }

@ -21,10 +21,6 @@
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <EEPROM.h> #include <EEPROM.h>
#ifndef EEPROM_SETTINGS_RESERVED
#define EEPROM_SETTINGS_RESERVED ((E2END + 1) / 2)
#endif
namespace KaleidoscopePlugins { namespace KaleidoscopePlugins {
class EEPROMSettings : public KaleidoscopePlugin { class EEPROMSettings : public KaleidoscopePlugin {
public: public:
@ -32,19 +28,25 @@ namespace KaleidoscopePlugins {
virtual void begin (void) final; virtual void begin (void) final;
static uint16_t endOfSettings (void);
static void update (void); static void update (void);
static bool isValid (void); static bool isValid (void);
static void invalidate (void); static void invalidate (void);
static uint8_t version (void); static uint8_t version (void);
static void version (uint8_t ver); static void version (uint8_t ver);
static uint16_t requestSlice (uint16_t size);
static void seal (void);
static uint16_t crc (void);
private: private:
static uint16_t nextStart;
static bool _isValid; static bool _isValid;
static bool sealed;
static struct settings { static struct settings {
char magic[2]; char magic[2];
uint8_t version; uint8_t version;
uint16_t endOfSettings; uint16_t crc;
} settings; } settings;
}; };
}; };

@ -0,0 +1,71 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
* Copyright (C) 2017 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Originally generated by pycrc v0.9, https://pycrc.org
*
* using the configuration:
* Width = 16
* Poly = 0x8005
* Xor_In = 0x0000
* ReflectIn = True
* Xor_Out = 0x0000
* ReflectOut = True
* Algorithm = bit-by-bit-fast
*/
#include "crc.h"
void
CRC_::reflect (uint8_t len) {
uint8_t i;
uint16_t newCRC;
newCRC = crc & 0x01;
for (i = 1; i < len; i++) {
crc >>= 1;
newCRC = (newCRC << 1) | (crc & 0x01);
}
crc = newCRC;
}
void
CRC_::update (const void *data, uint8_t len)
{
const uint8_t *d = (const uint8_t *)data;
uint8_t i;
bool bit;
uint8_t c;
while (len--) {
c = *d++;
for (i = 0x01; i & 0xff; i <<= 1) {
bit = crc & 0x8000;
if (c & i) {
bit = !bit;
}
crc <<= 1;
if (bit) {
crc ^= 0x8005;
}
}
crc &= 0xffff;
}
crc &= 0xffff;
}
CRC_ CRC;

@ -0,0 +1,45 @@
/* -*- mode: c++ -*-
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
* Copyright (C) 2017 Gergely Nagy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Originally generated by pycrc v0.9, https://pycrc.org
*
* using the configuration:
* Width = 16
* Poly = 0x8005
* Xor_In = 0x0000
* ReflectIn = True
* Xor_Out = 0x0000
* ReflectOut = True
* Algorithm = bit-by-bit-fast
*/
#pragma once
#include <Arduino.h>
class CRC_ {
public:
uint16_t crc = 0;
CRC_ (void) {};
void update (const void *data, uint8_t len);
void finalize (void) { reflect (16); };
void reflect (uint8_t len);
};
extern CRC_ CRC;
Loading…
Cancel
Save