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) {
}
Serial.println (EEPROMSettings.isValid () ? "valid EEPROM settings" : "invalid EEPROM settings");
Serial.println (EEPROMSettings.endOfSettings ());
Serial.println (EEPROMSettings.isValid () ? F("valid EEPROM settings") : F("invalid EEPROM settings"));
Serial.println (EEPROMSettings.crc (), HEX);
Serial.println (EEPROMSettings.version ());
}
void loop () {

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

@ -30,4 +30,7 @@ namespace FocusHooks {
"Return whether the EEPROM settings are valid, or not.\n\n" \
"settings.version\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 "crc.h"
namespace KaleidoscopePlugins {
struct EEPROMSettings::settings EEPROMSettings::settings;
bool EEPROMSettings::_isValid;
bool EEPROMSettings::sealed;
uint16_t EEPROMSettings::nextStart = sizeof (EEPROMSettings::settings);
EEPROMSettings::EEPROMSettings (void) {
}
void
EEPROMSettings::begin (void) {
_isValid = true;
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') {
settings.magic[0] = 'K';
settings.magic[1] = 'S';
settings.endOfSettings = EEPROM_SETTINGS_RESERVED - 1;
settings.version = 0;
settings.crc = CRC.crc;
return update ();
}
if (settings.endOfSettings != EEPROM_SETTINGS_RESERVED - 1)
if (settings.crc != CRC.crc)
_isValid = false;
}
uint16_t
EEPROMSettings::endOfSettings (void) {
if (!isValid ())
EEPROMSettings::requestSlice (uint16_t size) {
if (sealed)
return 0;
return settings.endOfSettings;
}
bool
EEPROMSettings::isValid (void) {
return _isValid;
uint16_t start = nextStart;
nextStart += size;
CRC.update ((const void *)&size, sizeof (size));
return start;
}
void
@ -61,6 +84,8 @@ namespace KaleidoscopePlugins {
void
EEPROMSettings::update (void) {
settings.crc = CRC.crc;
EEPROM.put (0, settings);
_isValid = true;
}

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