PersistentLEDMode: Add a Focus hook, and a way to disable the auto-save

We'd like to be able to set the default LED mode via Focus, so it can be
configured via Chrysalis. However, we may not want auto-save, so make that
configurable too.

To preserve the EEPROM layout, the highest bit of the previous led mode index
setting was repurposed for the auto save setting. This lets us set the default
mode to anything between 0 and 126 (or 127, if auto save is turned off).

While there, we also add an `onNameQuery` handler, to make it easier for
Chrysalis to detect if the plugin is available.

This addresses the Kaleidoscope parts of keyboardio/Chrysalis#846.

Signed-off-by: Gergely Nagy <algernon@keyboard.io>
pull/1189/head
Gergely Nagy 3 years ago
parent 6f11d89152
commit 07dcf1dc9b
No known key found for this signature in database
GPG Key ID: AC1E90BAC433F68F

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* kaleidoscope::plugin::PersistentLEDMode -- Persist the current LED mode to Storage * kaleidoscope::plugin::PersistentLEDMode -- Persist the current LED mode to Storage
* Copyright (C) 2019 Keyboard.io, Inc. * Copyright (C) 2019-2022 Keyboard.io, Inc.
* Copyright (C) 2019 Dygma, Inc. * Copyright (C) 2019 Dygma, Inc.
* *
* This program is free software: you can redistribute it and/or modify it under * This program is free software: you can redistribute it and/or modify it under
@ -19,6 +19,7 @@
#include "kaleidoscope/plugin/PersistentLEDMode.h" #include "kaleidoscope/plugin/PersistentLEDMode.h"
#include <Kaleidoscope-EEPROM-Settings.h> // for EEPROMSettings #include <Kaleidoscope-EEPROM-Settings.h> // for EEPROMSettings
#include <Kaleidoscope-FocusSerial.h> // for Focus
#include <stdint.h> // for uint8_t, uint16_t #include <stdint.h> // for uint8_t, uint16_t
#include "kaleidoscope/Runtime.h" // for Runtime, Runtime_ #include "kaleidoscope/Runtime.h" // for Runtime, Runtime_
@ -30,32 +31,96 @@ namespace kaleidoscope {
namespace plugin { namespace plugin {
uint16_t PersistentLEDMode::settings_base_; uint16_t PersistentLEDMode::settings_base_;
uint8_t PersistentLEDMode::cached_mode_index_; struct PersistentLEDMode::settings PersistentLEDMode::settings_;
EventHandlerResult PersistentLEDMode::onSetup() { EventHandlerResult PersistentLEDMode::onSetup() {
settings_base_ = ::EEPROMSettings.requestSlice(sizeof(cached_mode_index_)); settings_base_ = ::EEPROMSettings.requestSlice(sizeof(settings_));
Runtime.storage().get(settings_base_, cached_mode_index_); Runtime.storage().get(settings_base_, settings_);
// If the index is max, assume an uninitialized EEPROM, and don't set the LED // If our slice is uninitialized, then return early, without touching the
// mode. We don't change the cached index here, `onLEDModeChange()` will do // current mode. We want auto_save by default, but because EEPROM is
// that whenever a led mode change happens. // uninitialized (0xff), that'll be set anyway, so we don't need to. This
if (cached_mode_index_ != 0xff) // saves us a storage commit.
if (Runtime.storage().isSliceUninitialized(settings_base_, sizeof(settings_)))
return EventHandlerResult::OK; return EventHandlerResult::OK;
::LEDControl.set_mode(cached_mode_index_); ::LEDControl.set_mode(settings_.default_mode_index);
return EventHandlerResult::OK; return EventHandlerResult::OK;
} }
EventHandlerResult PersistentLEDMode::onLEDModeChange() { EventHandlerResult PersistentLEDMode::onLEDModeChange() {
if (cached_mode_index_ == ::LEDControl.get_mode_index()) if (!settings_.auto_save)
return EventHandlerResult::OK; return EventHandlerResult::OK;
cached_mode_index_ = ::LEDControl.get_mode_index(); if (settings_.default_mode_index == ::LEDControl.get_mode_index())
Runtime.storage().put(settings_base_, cached_mode_index_); return EventHandlerResult::OK;
settings_.default_mode_index = ::LEDControl.get_mode_index();
Runtime.storage().put(settings_base_, settings_);
Runtime.storage().commit(); Runtime.storage().commit();
return EventHandlerResult::OK;
}
EventHandlerResult PersistentLEDMode::onFocusEvent(const char *command) {
enum {
AUTO_SAVE,
DEFAULT_MODE,
} sub_command;
if (::Focus.handleHelp(command, PSTR("led_mode.default\nled_mode.auto_save")))
return EventHandlerResult::OK;
if (strncmp_P(command, PSTR("led_mode."), 9) != 0)
return EventHandlerResult::OK;
if (strcmp_P(command + 9, PSTR("default")) == 0)
sub_command = DEFAULT_MODE;
else if (strcmp_P(command + 9, PSTR("auto_save")) == 0)
sub_command = AUTO_SAVE;
else
return EventHandlerResult::OK; return EventHandlerResult::OK;
switch (sub_command) {
case DEFAULT_MODE: {
if (::Focus.isEOL()) {
::Focus.send(settings_.default_mode_index);
} else {
uint8_t idx;
::Focus.read(idx);
settings_.default_mode_index = idx;
::LEDControl.set_mode(idx);
Runtime.storage().put(settings_base_, settings_);
Runtime.storage().commit();
}
break;
}
case AUTO_SAVE: {
if (::Focus.isEOL()) {
::Focus.send(settings_.auto_save);
} else {
uint8_t v;
::Focus.read(v);
setAutoSave(v != 0);
}
break;
}
}
return EventHandlerResult::EVENT_CONSUMED;
}
void PersistentLEDMode::setAutoSave(bool state) {
settings_.auto_save = state;
Runtime.storage().put(settings_base_, settings_);
Runtime.storage().commit();
}
EventHandlerResult PersistentLEDMode::onNameQuery() {
return ::Focus.sendName(F("PersistentLEDMode"));
} }
} // namespace plugin } // namespace plugin

@ -1,6 +1,6 @@
/* -*- mode: c++ -*- /* -*- mode: c++ -*-
* kaleidoscope::plugin::PersistentLEDMode -- Persist the current LED mode to Storage * kaleidoscope::plugin::PersistentLEDMode -- Persist the current LED mode to Storage
* Copyright (C) 2019 Keyboard.io, Inc. * Copyright (C) 2019-2022 Keyboard.io, Inc.
* Copyright (C) 2019 Dygma, Inc. * Copyright (C) 2019 Dygma, Inc.
* *
* This program is free software: you can redistribute it and/or modify it under * This program is free software: you can redistribute it and/or modify it under
@ -31,11 +31,21 @@ class PersistentLEDMode : public kaleidoscope::Plugin {
PersistentLEDMode() {} PersistentLEDMode() {}
EventHandlerResult onSetup(); EventHandlerResult onSetup();
EventHandlerResult onNameQuery();
EventHandlerResult onLEDModeChange(); EventHandlerResult onLEDModeChange();
EventHandlerResult onFocusEvent(const char *command);
void setAutoSave(bool state);
bool getAutoSave() {
return settings_.auto_save == 1;
}
private: private:
static uint16_t settings_base_; static uint16_t settings_base_;
static uint8_t cached_mode_index_; static struct settings {
uint8_t auto_save : 1;
uint8_t default_mode_index : 7;
} settings_;
}; };
} // namespace plugin } // namespace plugin

Loading…
Cancel
Save