commit
d8c2fc0022
@ -0,0 +1,168 @@
|
|||||||
|
# Kaleidoscope-EEPROM-Settings
|
||||||
|
|
||||||
|
To be able to reliably store persistent configuration in `EEPROM`, we need to be
|
||||||
|
able to split up the available space for plugins to use. We also want to make
|
||||||
|
sure that we notice when the `EEPROM` contents and the firmware are out of sync.
|
||||||
|
This plugin provides the tools to do that.
|
||||||
|
|
||||||
|
It does not guard against errors, it merely provides the means to discover them,
|
||||||
|
and let the firmware Sketch handle the case in whatever way it finds reasonable.
|
||||||
|
It's a building block, and not much else. All Kaleidoscope plugins that need to
|
||||||
|
store data in `EEPROM` are encouraged to make use of this library.
|
||||||
|
|
||||||
|
## Using the plugin
|
||||||
|
|
||||||
|
There are a few steps one needs to take to use the plugin: we must first
|
||||||
|
register it, then either let other plugins request slices of `EEPROM`, or do so
|
||||||
|
ourselves. And finally, seal it, to signal that we are done setting up. At that
|
||||||
|
point, we can verify whether the contents of the `EEPROM` agree with our
|
||||||
|
firmware.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
#include <Kaleidoscope.h>
|
||||||
|
#include <Kaleidoscope-EEPROM-Settings.h>
|
||||||
|
|
||||||
|
static uint16_t settingsBase;
|
||||||
|
static struct {
|
||||||
|
bool someSettingFlag;
|
||||||
|
} testSettings;
|
||||||
|
|
||||||
|
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, /* Other plugins that use EEPROM... */);
|
||||||
|
|
||||||
|
void setup () {
|
||||||
|
Kaleidoscope.setup();
|
||||||
|
|
||||||
|
settingsBase = EEPROMSettings.requestSlice(sizeof(testSettings));
|
||||||
|
|
||||||
|
EEPROMSettings.seal();
|
||||||
|
|
||||||
|
if (!EEPROMSettings.isValid()) {
|
||||||
|
// Handle the case where the settings are out of sync...
|
||||||
|
// Flash LEDs, for example.
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EEPROM.get(settingsBase, testSettings);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plugin methods
|
||||||
|
|
||||||
|
The plugin provides the `EEPROMSettings` object, which has the following methods:
|
||||||
|
|
||||||
|
### `requestSlice(size)`
|
||||||
|
|
||||||
|
> Requests a slice of the `EEPROM`, and returns the starting address (or 0 on
|
||||||
|
> error, including when the request arrived after sealing the layout).
|
||||||
|
>
|
||||||
|
> Should only be called **before** calling `seal()`.
|
||||||
|
|
||||||
|
### `default_layer([id])`
|
||||||
|
|
||||||
|
> Sets (or returns, if called without an ID) the default layer. When the
|
||||||
|
> keyboard boots up, it will automatically switch to the configured layer - if
|
||||||
|
> any.
|
||||||
|
>
|
||||||
|
> This is the Focus counterpart of the `default_layer()` method documented
|
||||||
|
> above.
|
||||||
|
|
||||||
|
### `seal()`
|
||||||
|
|
||||||
|
> Seal the `EEPROM` layout, so no new slices can be requested. The CRC checksum
|
||||||
|
> is considered final at this time, and the `isValid()`, `crc()`, `used()` and
|
||||||
|
> `version()` methods can be used from this point onwards.
|
||||||
|
>
|
||||||
|
> If not called explicitly, the layout will be sealed automatically after
|
||||||
|
> `setup()` in the sketch finished.
|
||||||
|
|
||||||
|
### `update()`
|
||||||
|
|
||||||
|
> Updates the `EEPROM` header with the current status quo, including the version
|
||||||
|
> and the CRC checksum.
|
||||||
|
>
|
||||||
|
> This should be called when upgrading from one version to another, or when
|
||||||
|
> fixing up an out-of-sync case.
|
||||||
|
|
||||||
|
### `isValid()`
|
||||||
|
|
||||||
|
> Returns whether the `EEPROM` header is valid, that is, if it has the expected
|
||||||
|
> CRC checksum.
|
||||||
|
>
|
||||||
|
> Should only be called after calling `seal()`.
|
||||||
|
|
||||||
|
### `invalidate()`
|
||||||
|
|
||||||
|
> Invalidates the `EEPROM` header. Use when the version does not match what the
|
||||||
|
> firmware would expect. This signals to other plugins that the contents of
|
||||||
|
> `EEPROM` should not be trusted.
|
||||||
|
|
||||||
|
### `version([newVersion])`
|
||||||
|
|
||||||
|
> Sets or returns the version of the `EEPROM` layout. This is purely for use by
|
||||||
|
> the firmware, so it can attempt to upgrade the contents, if need be, or alert
|
||||||
|
> the user in there's a mismatch. Plugins do not use this property.
|
||||||
|
>
|
||||||
|
> Should only be called after calling `seal()`.
|
||||||
|
|
||||||
|
### `crc()`
|
||||||
|
|
||||||
|
> Returns the CRC checksum of the layout. Should only be used after calling
|
||||||
|
> `seal()`.
|
||||||
|
|
||||||
|
### `used()`
|
||||||
|
|
||||||
|
> Returns the amount of space requested so far.
|
||||||
|
>
|
||||||
|
> Should only be used after calling `seal()`.
|
||||||
|
|
||||||
|
## Focus commands
|
||||||
|
|
||||||
|
The plugin provides two - optional - [Focus][FocusSerial] command plugins:
|
||||||
|
`FocusSettingsCommand` and `FocusEEPROMCommand`. These must be explicitly added
|
||||||
|
to `KALEIDOSCOPE_INIT_PLUGINS` if one wishes to use them. They provide the
|
||||||
|
following commands:
|
||||||
|
|
||||||
|
[FocusSerial]: FocusSerial.md
|
||||||
|
|
||||||
|
### `settings.defaultLayer`
|
||||||
|
|
||||||
|
> Sets or returns (if called without arguments) the ID of the default layer. If
|
||||||
|
> set, the keyboard will automatically switch to the given layer when connected.
|
||||||
|
> Setting it to `255` disables the automatic switching.
|
||||||
|
|
||||||
|
### `settings.crc`
|
||||||
|
|
||||||
|
> Returns the actual, and the expected checksum of the settings.
|
||||||
|
|
||||||
|
### `settings.valid?`
|
||||||
|
|
||||||
|
> Returns either `true` or `false`, depending on whether the sealed settings are
|
||||||
|
> to be considered valid or not.
|
||||||
|
|
||||||
|
### `settings.version`
|
||||||
|
|
||||||
|
> Returns the (user-set) version of the settings.
|
||||||
|
|
||||||
|
### `eeprom.contents`
|
||||||
|
|
||||||
|
> Without argument, displays the full contents of the `EEPROM`, including the
|
||||||
|
> settings header.
|
||||||
|
>
|
||||||
|
> With arguments, the command updates as much of the `EEPROM` as arguments are
|
||||||
|
> provided. It will discard any unnecessary arguments.
|
||||||
|
|
||||||
|
### `eeprom.free`
|
||||||
|
|
||||||
|
> Returns the amount of free bytes in `EEPROM`.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
* [Kaleidoscope-FocusSerial][FocusSerial]
|
||||||
|
|
||||||
|
## Further reading
|
||||||
|
|
||||||
|
Starting from the [example][plugin:example] is the recommended way of getting
|
||||||
|
started with the plugin.
|
||||||
|
|
||||||
|
[plugin:example]: ../../examples/EEPROM-Settings/EEPROM-Settings.ino
|
@ -0,0 +1,59 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
|
||||||
|
* Copyright (C) 2017, 2018 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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, version 3.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kaleidoscope.h>
|
||||||
|
#include <Kaleidoscope-EEPROM-Settings.h>
|
||||||
|
|
||||||
|
// *INDENT-OFF*
|
||||||
|
const Key keymaps[][ROWS][COLS] PROGMEM = {
|
||||||
|
[0] = KEYMAP_STACKED
|
||||||
|
(Key_NoKey, Key_1, Key_2, Key_3, Key_4, Key_5, Key_NoKey,
|
||||||
|
Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
|
||||||
|
Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
|
||||||
|
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
|
||||||
|
|
||||||
|
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
|
||||||
|
Key_skip,
|
||||||
|
|
||||||
|
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
|
||||||
|
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
|
||||||
|
Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
|
||||||
|
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
|
||||||
|
|
||||||
|
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
|
||||||
|
Key_skip),
|
||||||
|
};
|
||||||
|
// *INDENT-ON*
|
||||||
|
|
||||||
|
KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
Kaleidoscope.setup();
|
||||||
|
|
||||||
|
while (!Serial) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println(EEPROMSettings.isValid() ? F("valid EEPROM settings") : F("invalid EEPROM settings"));
|
||||||
|
Serial.println(EEPROMSettings.crc(), HEX);
|
||||||
|
Serial.println(EEPROMSettings.version());
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Kaleidoscope.loop();
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
|
||||||
|
* Copyright (C) 2017 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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, version 3.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kaleidoscope/plugin/EEPROM-Settings.h>
|
@ -0,0 +1,217 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
|
||||||
|
* Copyright (C) 2017, 2018 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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, version 3.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Kaleidoscope-EEPROM-Settings.h>
|
||||||
|
#include <Kaleidoscope-FocusSerial.h>
|
||||||
|
#include "kaleidoscope/plugin/EEPROM-Settings/crc.h"
|
||||||
|
|
||||||
|
namespace kaleidoscope {
|
||||||
|
namespace plugin {
|
||||||
|
|
||||||
|
struct EEPROMSettings::settings EEPROMSettings::settings_;
|
||||||
|
bool EEPROMSettings::is_valid_;
|
||||||
|
bool EEPROMSettings::sealed_;
|
||||||
|
uint16_t EEPROMSettings::next_start_ = sizeof(EEPROMSettings::settings);
|
||||||
|
|
||||||
|
EventHandlerResult EEPROMSettings::onSetup() {
|
||||||
|
EEPROM.get(0, settings_);
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHandlerResult EEPROMSettings::beforeEachCycle() {
|
||||||
|
if (!sealed_)
|
||||||
|
seal();
|
||||||
|
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EEPROMSettings::isValid(void) {
|
||||||
|
return is_valid_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t EEPROMSettings::crc(void) {
|
||||||
|
if (sealed_)
|
||||||
|
return settings_.crc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EEPROMSettings::default_layer(uint8_t layer) {
|
||||||
|
if (layer == 0xff)
|
||||||
|
return settings_.default_layer;
|
||||||
|
|
||||||
|
settings_.default_layer = layer;
|
||||||
|
update();
|
||||||
|
return settings_.default_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEPROMSettings::seal(void) {
|
||||||
|
sealed_ = true;
|
||||||
|
|
||||||
|
CRC.finalize();
|
||||||
|
|
||||||
|
/* If we have a default layer set, switch to it. As 0xff is the default EEPROM
|
||||||
|
* value, treat it as not having a default layer set. */
|
||||||
|
if (settings_.default_layer != 0xff)
|
||||||
|
Layer.move(settings_.default_layer);
|
||||||
|
|
||||||
|
/* Until we set a version, consider the EEPROM contents flexible, and always
|
||||||
|
* update the CRC. This will always result in the settings being considered
|
||||||
|
* valid. */
|
||||||
|
if (settings_.version == 0xff) {
|
||||||
|
return update();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings_.crc != CRC.crc)
|
||||||
|
is_valid_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t EEPROMSettings::requestSlice(uint16_t size) {
|
||||||
|
if (sealed_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint16_t start = next_start_;
|
||||||
|
next_start_ += size;
|
||||||
|
|
||||||
|
CRC.update((const void *)&size, sizeof(size));
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEPROMSettings::invalidate(void) {
|
||||||
|
is_valid_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t EEPROMSettings::used(void) {
|
||||||
|
return next_start_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEPROMSettings::update(void) {
|
||||||
|
settings_.crc = CRC.crc;
|
||||||
|
|
||||||
|
EEPROM.put(0, settings_);
|
||||||
|
is_valid_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t EEPROMSettings::version(void) {
|
||||||
|
return settings_.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEPROMSettings::version(uint8_t ver) {
|
||||||
|
settings_.version = ver;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Focus **/
|
||||||
|
EventHandlerResult FocusSettingsCommand::onFocusEvent(const char *command) {
|
||||||
|
enum {
|
||||||
|
DEFAULT_LAYER,
|
||||||
|
IS_VALID,
|
||||||
|
GET_VERSION,
|
||||||
|
CRC,
|
||||||
|
} sub_command;
|
||||||
|
|
||||||
|
if (::Focus.handleHelp(command, PSTR("settings.defaultLayer\nsettings.valid?\nsettings.version\nsettings.crc")))
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
|
||||||
|
if (strncmp_P(command, PSTR("settings."), 9) != 0)
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
|
||||||
|
if (strcmp_P(command + 9, PSTR("defaultLayer")) == 0)
|
||||||
|
sub_command = DEFAULT_LAYER;
|
||||||
|
else if (strcmp_P(command + 9, PSTR("valid?")) == 0)
|
||||||
|
sub_command = IS_VALID;
|
||||||
|
else if (strcmp_P(command + 9, PSTR("version")) == 0)
|
||||||
|
sub_command = GET_VERSION;
|
||||||
|
else if (strcmp_P(command + 9, PSTR("crc")) == 0)
|
||||||
|
sub_command = CRC;
|
||||||
|
else
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
|
||||||
|
switch (sub_command) {
|
||||||
|
case DEFAULT_LAYER: {
|
||||||
|
if (Serial.peek() == '\n') {
|
||||||
|
Serial.println(::EEPROMSettings.default_layer());
|
||||||
|
} else {
|
||||||
|
::EEPROMSettings.default_layer(Serial.parseInt());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IS_VALID:
|
||||||
|
::Focus.printBool(::EEPROMSettings.isValid());
|
||||||
|
Serial.println();
|
||||||
|
break;
|
||||||
|
case GET_VERSION:
|
||||||
|
Serial.println(::EEPROMSettings.version());
|
||||||
|
break;
|
||||||
|
case CRC:
|
||||||
|
Serial.print(::CRC.crc, HEX);
|
||||||
|
Serial.print(F("/"));
|
||||||
|
Serial.println(::EEPROMSettings.crc(), HEX);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EventHandlerResult::EVENT_CONSUMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHandlerResult FocusEEPROMCommand::onFocusEvent(const char *command) {
|
||||||
|
enum {
|
||||||
|
CONTENTS,
|
||||||
|
FREE,
|
||||||
|
} sub_command;
|
||||||
|
|
||||||
|
if (::Focus.handleHelp(command, PSTR("eeprom.contents\neeprom.free")))
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
|
||||||
|
if (strcmp_P(command, PSTR("eeprom.contents")) == 0)
|
||||||
|
sub_command = CONTENTS;
|
||||||
|
else if (strcmp_P(command, PSTR("eeprom.free")) == 0)
|
||||||
|
sub_command = FREE;
|
||||||
|
else
|
||||||
|
return EventHandlerResult::OK;
|
||||||
|
|
||||||
|
switch (sub_command) {
|
||||||
|
case CONTENTS: {
|
||||||
|
if (Serial.peek() == '\n') {
|
||||||
|
for (uint16_t i = 0; i < EEPROM.length(); i++) {
|
||||||
|
uint8_t d = EEPROM[i];
|
||||||
|
::Focus.printNumber(d);
|
||||||
|
::Focus.printSpace();
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
} else {
|
||||||
|
for (uint16_t i = 0; i < EEPROM.length() && Serial.peek() != '\n'; i++) {
|
||||||
|
uint8_t d = Serial.parseInt();
|
||||||
|
EEPROM.update(i, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FREE:
|
||||||
|
Serial.println(EEPROM.length() - ::EEPROMSettings.used());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EventHandlerResult::EVENT_CONSUMED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kaleidoscope::plugin::EEPROMSettings EEPROMSettings;
|
||||||
|
kaleidoscope::plugin::FocusSettingsCommand FocusSettingsCommand;
|
||||||
|
kaleidoscope::plugin::FocusEEPROMCommand FocusEEPROMCommand;
|
@ -0,0 +1,75 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
|
||||||
|
* Copyright (C) 2017, 2018 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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, version 3.
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Kaleidoscope.h>
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
|
namespace kaleidoscope {
|
||||||
|
namespace plugin {
|
||||||
|
class EEPROMSettings : public kaleidoscope::Plugin {
|
||||||
|
public:
|
||||||
|
EEPROMSettings(void) {}
|
||||||
|
|
||||||
|
EventHandlerResult onSetup();
|
||||||
|
EventHandlerResult beforeEachCycle();
|
||||||
|
|
||||||
|
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);
|
||||||
|
static uint16_t used(void);
|
||||||
|
|
||||||
|
static uint8_t default_layer(uint8_t layer = 0xff);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint16_t next_start_;
|
||||||
|
static bool is_valid_;
|
||||||
|
static bool sealed_;
|
||||||
|
|
||||||
|
static struct settings {
|
||||||
|
uint8_t default_layer;
|
||||||
|
uint8_t version;
|
||||||
|
uint16_t crc;
|
||||||
|
} settings_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FocusSettingsCommand : public kaleidoscope::Plugin {
|
||||||
|
public:
|
||||||
|
FocusSettingsCommand() {}
|
||||||
|
|
||||||
|
EventHandlerResult onFocusEvent(const char *command);
|
||||||
|
};
|
||||||
|
|
||||||
|
class FocusEEPROMCommand : public kaleidoscope::Plugin {
|
||||||
|
public:
|
||||||
|
FocusEEPROMCommand() {}
|
||||||
|
|
||||||
|
EventHandlerResult onFocusEvent(const char *command);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern kaleidoscope::plugin::EEPROMSettings EEPROMSettings;
|
||||||
|
extern kaleidoscope::plugin::FocusSettingsCommand FocusSettingsCommand;
|
||||||
|
extern kaleidoscope::plugin::FocusEEPROMCommand FocusEEPROMCommand;
|
@ -0,0 +1,69 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
|
||||||
|
* Copyright (C) 2017 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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, version 3.
|
||||||
|
*
|
||||||
|
* 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,46 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-EEPROM-Settings -- Basic EEPROM settings plugin for Kaleidoscope.
|
||||||
|
* Copyright (C) 2017 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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, version 3.
|
||||||
|
*
|
||||||
|
* 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…
Reference in new issue