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