From c917acb8a16dad1d231f602efee1e5757d110340 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 2 May 2020 13:23:24 +0200 Subject: [PATCH] plugin/FlashHelper: New plugin for firmware-assisted flashing This introduces a new plugin - `FlashHelper` - to aid with firmware-assisted flashing. During the flashing process, this plugin can temporarily disable the `Prog` key. Addresses the firmware part of keyboardio/Chrysalis#509. Signed-off-by: Gergely Nagy --- docs/plugins/FlashHelper.md | 71 ++++++++++++++++ examples/Features/FlashHelper/FlashHelper.ino | 52 ++++++++++++ examples/Features/FlashHelper/Makefile | 55 +++++++++++++ src/Kaleidoscope-FlashHelper.h | 20 +++++ src/kaleidoscope/device/ATmega32U4Keyboard.h | 56 ++++++++----- src/kaleidoscope/device/Base.h | 8 ++ src/kaleidoscope/device/dygma/Raise.h | 3 + src/kaleidoscope/device/keyboardio/Model01.h | 3 + src/kaleidoscope/device/olkb/Planck.h | 3 +- src/kaleidoscope/device/technomancy/Atreus.h | 7 +- src/kaleidoscope/device/technomancy/Atreus2.h | 3 +- src/kaleidoscope/plugin/FlashHelper.cpp | 82 +++++++++++++++++++ src/kaleidoscope/plugin/FlashHelper.h | 60 ++++++++++++++ 13 files changed, 396 insertions(+), 27 deletions(-) create mode 100644 docs/plugins/FlashHelper.md create mode 100644 examples/Features/FlashHelper/FlashHelper.ino create mode 100644 examples/Features/FlashHelper/Makefile create mode 100644 src/Kaleidoscope-FlashHelper.h create mode 100644 src/kaleidoscope/plugin/FlashHelper.cpp create mode 100644 src/kaleidoscope/plugin/FlashHelper.h diff --git a/docs/plugins/FlashHelper.md b/docs/plugins/FlashHelper.md new file mode 100644 index 00000000..3b217b5e --- /dev/null +++ b/docs/plugins/FlashHelper.md @@ -0,0 +1,71 @@ +# FlashHelper + +A number of keyboards supported by Kaleidoscope need a key held during reset to +enter bootloader mode. While held, any action mapped to the key will take +effect, which is something we may want to avoid in this special case. This +plugin is here to help with that: when asked via [Focus](FocusSerial.md), it +will ignore any events on the `Prog` key for a short while (or until asked to +resume). + +## Using the plugin + +Using the plugin is simple: after including the header, enable the plugin +(preferably before enabling any other plugin that handles key events). + +We also need `Focus` enabled, to take full advantage of the plugin. + +```c++ +#include +#include +#include + +KALEIDOSCOPE_INIT_PLUGINS(Focus, FlashHelper); + +void setup() { + Kaleidoscope.setup(); +} +``` + +The plugin relies on the device descriptor having set a `Prog` key. + +## Plugin methods + +The plugin provides the `FlashHelper` object, which has the following methods: + +### `.setTimeout(timeout)` +### `.getTimeout()` + +Set or get the time (in seconds) to wait before re-enabling the Prog key, after +the helper has been activated. + +The timer defaults to **10 seconds**. + +### `.activate()` +### `.deactivate()` +### `.isActive()` + +Activate, deactivate, or check the status of the flashing helper, respectively. + +## Focus commands + +The plugin provides two Focus commands: `flash.prepare` and `flash.resume`. + +### `flash.prepare` + +Prepare for flashing, by disabling the previously configured `Prog` key for a +few seconds, or until explicitly asked to resume. If the keyboard resets +meanwhile, then preparation is automatically concluded. + +### `flash.resume` + +Resume normal key event handling, and deactivate the helper plugin. + +## Dependencies + +* [Kaleidoscope-FocusSerial](FocusSerial.md) + +## Further reading + +Starting from the [example][plugin:example] is the recommended way of getting started with the plugin. + + [plugin:example]: ../../examples/Features/FlashHelper/FlashHelper.ino diff --git a/examples/Features/FlashHelper/FlashHelper.ino b/examples/Features/FlashHelper/FlashHelper.ino new file mode 100644 index 00000000..ec012e9c --- /dev/null +++ b/examples/Features/FlashHelper/FlashHelper.ino @@ -0,0 +1,52 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FlashHelper -- Firmware-assisted flashing + * Copyright (C) 2020 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 . + */ + +#include +#include +#include + +// *INDENT-OFF* +KEYMAPS( + [0] = KEYMAP_STACKED + ( + Key_0, 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(Focus, FlashHelper); + +void setup() { + Kaleidoscope.setup(); +} + +void loop() { + Kaleidoscope.loop(); +} diff --git a/examples/Features/FlashHelper/Makefile b/examples/Features/FlashHelper/Makefile new file mode 100644 index 00000000..996bde98 --- /dev/null +++ b/examples/Features/FlashHelper/Makefile @@ -0,0 +1,55 @@ +# This stub makefile for a Kaleidoscope example pulls in all the targets +# required to build the example + +UNAME_S := $(shell uname -s) + +ifeq ($(UNAME_S),Darwin) +SKETCHBOOK_DIR ?= $(HOME)/Documents/Arduino +PACKAGE_DIR ?= $(HOME)/Library/Arduino15 +else +SKETCHBOOK_DIR ?= $(HOME)/Arduino +PACKAGE_DIR ?= $(HOME)/.arduino15 +endif + + +ARDUINO_INSTALLED_ENV=$(shell ls -dt $(PACKAGE_DIR)/packages/keyboardio/hardware/avr 2>/dev/null |head -n 1) +MANUALLY_INSTALLED_ENV=$(shell ls -dt $(SKETCHBOOK_DIR)/hardware/keyboardio/avr 2>/dev/null |head -n 1) + + + +ifneq ("$(wildcard $(ARDUINO_INSTALLED_ENV)/boards.txt)","") + +ifneq ("$(wildcard $(MANUALLY_INSTALLED_ENV)/boards.txt)","") + +$(info ***************************************************************************) +$(info It appears that you have installed two copies of Kaleidoscope. One copy was) +$(info installed using Arduino's "Board Manager", while the other was installed by) +$(info hand, probably using "git".) +$(info ) +$(info This will likely cause some trouble as you try to build keyboard firmware) +$(info using Kaleidoscope. You may want to remove either: ) +$(info ) +$(info $(PACKAGE_DIR)/packages/keyboardio/ which was installed using Arduino) +$(info ) +$(info or) +$(info ) +$(info $(SKETCHBOOK_DIR)/hardware/keyboardio/ which was installed by hand.) +$(info ) +$(info ***************************************************************************) +$(info ) + +endif + +BOARD_HARDWARE_PATH = $(ARDUINO_INSTALLED_ENV) +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= build-tools/makefiles/ +KALEIDOSCOPE_BUILDER_DIR ?= $(ARDUINO_INSTALLED_ENV)/libraries/Kaleidoscope/bin/ + + + +endif + + +BOARD_HARDWARE_PATH ?= $(SKETCHBOOK_DIR)/hardware +KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR ?= keyboardio/avr/build-tools/makefiles/ + +include $(BOARD_HARDWARE_PATH)/$(KALEIDOSCOPE_PLUGIN_MAKEFILE_DIR)/rules.mk diff --git a/src/Kaleidoscope-FlashHelper.h b/src/Kaleidoscope-FlashHelper.h new file mode 100644 index 00000000..f2a3faa8 --- /dev/null +++ b/src/Kaleidoscope-FlashHelper.h @@ -0,0 +1,20 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FlashHelper -- Firmware-assisted flashing + * Copyright (C) 2020 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 . + */ + +#pragma once + +#include diff --git a/src/kaleidoscope/device/ATmega32U4Keyboard.h b/src/kaleidoscope/device/ATmega32U4Keyboard.h index c769cf32..c6cb33c5 100644 --- a/src/kaleidoscope/device/ATmega32U4Keyboard.h +++ b/src/kaleidoscope/device/ATmega32U4Keyboard.h @@ -27,17 +27,29 @@ #include "kaleidoscope/driver/storage/ATmega32U4EEPROMProps.h" #include "kaleidoscope/driver/storage/AVREEPROM.h" -#define ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_) \ - struct BOARD_##Props : kaleidoscope::device::ATmega32U4KeyboardProps { \ - struct KeyScannerProps \ - : public kaleidoscope::driver::keyscanner::ATmegaProps \ - { \ - ATMEGA_KEYSCANNER_PROPS(ROW_PIN_LIST(ROW_PINS_), \ - COL_PIN_LIST(COL_PINS_)); \ - }; \ - typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; \ - typedef kaleidoscope::driver::bootloader::avr::BOOTLOADER_ BootLoader; \ - static constexpr const char *short_name = NAME_; \ +//#define PROG_KEY(...) __VA_ARGS__ +//#define NO_PROG_KEY PROG_KEY(KeyScannerProps::KeyAddr::invalid_state) + +#define PROG_KEY(...) \ + static constexpr uint8_t prog_key_addresses[] = { \ + KeyScannerProps::KeyAddr(__VA_ARGS__).toInt() \ + } + +#define NO_PROG_KEY \ + static constexpr uint8_t prog_key_addresses[] = {} + +#define ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_, PROG_KEY_) \ + struct BOARD_##Props : kaleidoscope::device::ATmega32U4KeyboardProps { \ + struct KeyScannerProps \ + : public kaleidoscope::driver::keyscanner::ATmegaProps \ + { \ + ATMEGA_KEYSCANNER_PROPS(ROW_PIN_LIST(ROW_PINS_), \ + COL_PIN_LIST(COL_PINS_)); \ + }; \ + typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; \ + typedef kaleidoscope::driver::bootloader::avr::BOOTLOADER_ BootLoader; \ + static constexpr const char *short_name = NAME_; \ + PROG_KEY_; \ }; #define ATMEGA32U4_DEVICE(BOARD_) \ @@ -47,21 +59,21 @@ #ifndef KALEIDOSCOPE_VIRTUAL_BUILD -#define ATMEGA32U4_KEYBOARD(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_) \ - ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, \ - FORWARD(ROW_PINS_), FORWARD(COL_PINS_)) \ +#define ATMEGA32U4_KEYBOARD(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_, PROG_KEY_) \ + ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, \ + FORWARD(ROW_PINS_), FORWARD(COL_PINS_), FORWARD(PROG_KEY_)) \ ATMEGA32U4_DEVICE(BOARD_) #else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD -#define ATMEGA32U4_KEYBOARD(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_) \ - ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, \ - FORWARD(ROW_PINS_), FORWARD(COL_PINS_)) \ - /* Device definition omitted for virtual device builds. \ - * We need to forward declare the device name, though, as there are \ - * some legacy extern references to boards whose definition \ - * depends on this. \ - */ \ +#define ATMEGA32U4_KEYBOARD(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_, PROG_KEY_) \ + ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, \ + FORWARD(ROW_PINS_), FORWARD(COL_PINS_), FORWARD(PROG_KEY_)) \ + /* Device definition omitted for virtual device builds. \ + * We need to forward declare the device name, though, as there are \ + * some legacy extern references to boards whose definition \ + * depends on this. \ + */ \ class BOARD_; #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/Base.h b/src/kaleidoscope/device/Base.h index d9ac0652..095d8978 100644 --- a/src/kaleidoscope/device/Base.h +++ b/src/kaleidoscope/device/Base.h @@ -64,6 +64,7 @@ struct BaseProps { typedef kaleidoscope::driver::storage::BaseProps StorageProps; typedef kaleidoscope::driver::storage::None Storage; static constexpr const char *short_name = USB_PRODUCT; + static constexpr const uint8_t prog_key_addresses[] = {}; }; template @@ -107,6 +108,13 @@ class Base { return matrix_columns * matrix_rows; } + static constexpr auto progKeyAddresses() { + return Props::prog_key_addresses; + } + static constexpr uint8_t numProgKeys() { + return sizeof(Props::prog_key_addresses) / sizeof(uint8_t); + } + /** * Returns the HID driver used by the keyboard. */ diff --git a/src/kaleidoscope/device/dygma/Raise.h b/src/kaleidoscope/device/dygma/Raise.h index 921da20e..0ddc7963 100644 --- a/src/kaleidoscope/device/dygma/Raise.h +++ b/src/kaleidoscope/device/dygma/Raise.h @@ -172,6 +172,9 @@ struct RaiseProps : kaleidoscope::device::BaseProps { typedef RaiseSideFlasherProps SideFlasherProps; typedef kaleidoscope::util::flasher::KeyboardioI2CBootloader SideFlasher; static constexpr const char *short_name = "raise"; + static constexpr uint8_t prog_key_addresses[] = { + KeyScannerProps::KeyAddr(0, 0).toInt() + }; }; class Raise: public kaleidoscope::device::Base { diff --git a/src/kaleidoscope/device/keyboardio/Model01.h b/src/kaleidoscope/device/keyboardio/Model01.h index ab267273..fa2950a3 100644 --- a/src/kaleidoscope/device/keyboardio/Model01.h +++ b/src/kaleidoscope/device/keyboardio/Model01.h @@ -122,6 +122,9 @@ struct Model01Props : public kaleidoscope::device::ATmega32U4KeyboardProps { typedef Model01KeyScanner KeyScanner; typedef kaleidoscope::driver::bootloader::avr::Caterina BootLoader; static constexpr const char *short_name = "kbio01"; + static constexpr uint8_t prog_key_addresses[] = { + KeyScannerProps::KeyAddr(0, 0).toInt() + }; }; #ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/olkb/Planck.h b/src/kaleidoscope/device/olkb/Planck.h index 497276ef..6d4c6ea8 100644 --- a/src/kaleidoscope/device/olkb/Planck.h +++ b/src/kaleidoscope/device/olkb/Planck.h @@ -31,7 +31,8 @@ namespace olkb { ATMEGA32U4_KEYBOARD( Planck, HalfKay, "planck", ROW_PIN_LIST({ PIN_D0, PIN_D5, PIN_B5, PIN_B6 }), - COL_PIN_LIST({ PIN_F1, PIN_F0, PIN_B0, PIN_C7, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_D4, PIN_D6, PIN_B4, PIN_D7 }) + COL_PIN_LIST({ PIN_F1, PIN_F0, PIN_B0, PIN_C7, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_D4, PIN_D6, PIN_B4, PIN_D7 }), + NO_PROG_KEY ); #define PER_KEY_DATA(dflt, \ diff --git a/src/kaleidoscope/device/technomancy/Atreus.h b/src/kaleidoscope/device/technomancy/Atreus.h index a25855a1..e6981c4c 100644 --- a/src/kaleidoscope/device/technomancy/Atreus.h +++ b/src/kaleidoscope/device/technomancy/Atreus.h @@ -39,16 +39,17 @@ ATMEGA32U4_KEYBOARD( Atreus, HalfKay, "atreus", #ifdef KALEIDOSCOPE_HARDWARE_ATREUS_PINOUT_ASTAR ROW_PIN_LIST({PIN_D0, PIN_D1, PIN_D3, PIN_D2}), - COL_PIN_LIST({PIN_D7, PIN_C6, PIN_B5, PIN_B4, PIN_E6, PIN_D4, PIN_B6, PIN_F6, PIN_F7, PIN_D6, PIN_B7}) + COL_PIN_LIST({PIN_D7, PIN_C6, PIN_B5, PIN_B4, PIN_E6, PIN_D4, PIN_B6, PIN_F6, PIN_F7, PIN_D6, PIN_B7}), #endif #ifdef KALEIDOSCOPE_HARDWARE_ATREUS_PINOUT_ASTAR_DOWN ROW_PIN_LIST({PIN_D0, PIN_D1, PIN_D3, PIN_D2}), - COL_PIN_LIST({PIN_B7, PIN_D6, PIN_F7, PIN_F6, PIN_B6, PIN_D4, PIN_E6, PIN_B4, PIN_B5, PIN_C6, PIN_D7}) + COL_PIN_LIST({PIN_B7, PIN_D6, PIN_F7, PIN_F6, PIN_B6, PIN_D4, PIN_E6, PIN_B4, PIN_B5, PIN_C6, PIN_D7}), #endif #ifdef KALEIDOSCOPE_HARDWARE_ATREUS_PINOUT_LEGACY_TEENSY2 ROW_PIN_LIST({PIN_D0, PIN_D1, PIN_D2, PIN_D3}), - COL_PIN_LIST({PIN_F6, PIN_F5, PIN_F4, PIN_B7, PIN_B6, PIN_B5, PIN_B4, PIN_B3, PIN_B2, PIN_B1, PIN_B0}) + COL_PIN_LIST({PIN_F6, PIN_F5, PIN_F4, PIN_B7, PIN_B6, PIN_B5, PIN_B4, PIN_B3, PIN_B2, PIN_B1, PIN_B0}), #endif + NO_PROG_KEY ); #define PER_KEY_DATA(dflt, \ diff --git a/src/kaleidoscope/device/technomancy/Atreus2.h b/src/kaleidoscope/device/technomancy/Atreus2.h index 2cc0a222..a36b0299 100644 --- a/src/kaleidoscope/device/technomancy/Atreus2.h +++ b/src/kaleidoscope/device/technomancy/Atreus2.h @@ -32,7 +32,8 @@ namespace technomancy { ATMEGA32U4_KEYBOARD( Atreus2, Caterina, "atreus", ROW_PIN_LIST({PIN_F6, PIN_F5, PIN_F4, PIN_F1}), - COL_PIN_LIST({PIN_F7, PIN_E2, PIN_C7, PIN_C6, PIN_B6, PIN_B5, PIN_D7, PIN_D6, PIN_D4, PIN_D5, PIN_D3, PIN_D2}) + COL_PIN_LIST({PIN_F7, PIN_E2, PIN_C7, PIN_C6, PIN_B6, PIN_B5, PIN_D7, PIN_D6, PIN_D4, PIN_D5, PIN_D3, PIN_D2}), + PROG_KEY(3, 0) ); #define PER_KEY_DATA(dflt, \ diff --git a/src/kaleidoscope/plugin/FlashHelper.cpp b/src/kaleidoscope/plugin/FlashHelper.cpp new file mode 100644 index 00000000..682992b8 --- /dev/null +++ b/src/kaleidoscope/plugin/FlashHelper.cpp @@ -0,0 +1,82 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FlashHelper -- Firmware-assisted flashing + * Copyright (C) 2020 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 . + */ + +#include +#include + +#include "kaleidoscope/key_events.h" + +namespace kaleidoscope { +namespace plugin { + +uint8_t FlashHelper::timeout_ = 10; +uint32_t FlashHelper::start_time_; +bool FlashHelper::is_active_; + +EventHandlerResult FlashHelper::onFocusEvent(const char *command) { + if (::Focus.handleHelp(command, PSTR("flash.prepare\nflash.resume"))) + return EventHandlerResult::OK; + + if (strncmp_P(command, PSTR("flash."), 6) != 0) + return EventHandlerResult::OK; + + if (strcmp_P(command + 6, PSTR("prepare")) == 0) { + activate(); + return EventHandlerResult::EVENT_CONSUMED; + } + if (strcmp_P(command + 6, PSTR("resume")) == 0) { + deactivate(); + return EventHandlerResult::EVENT_CONSUMED; + } + + return EventHandlerResult::OK; + +} + +EventHandlerResult FlashHelper::beforeEachCycle() { + if (!isActive()) + goto end; + + if (!Runtime.hasTimeExpired(start_time_, (uint16_t)(timeout_ * 1000))) + goto end; + + deactivate(); + +end: + return EventHandlerResult::OK; +} + +EventHandlerResult FlashHelper::onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state) { + if (!isActive()) + return EventHandlerResult::OK; + + const auto progKeys = Runtime.device().progKeyAddresses(); + const uint8_t progKeyNum = Runtime.device().numProgKeys(); + + for (int8_t i = 0; i < progKeyNum; i++) { + if (key_addr.toInt() == progKeys[i]) { + return EventHandlerResult::EVENT_CONSUMED; + } + } + + return EventHandlerResult::OK; +} + +} +} + +kaleidoscope::plugin::FlashHelper FlashHelper; diff --git a/src/kaleidoscope/plugin/FlashHelper.h b/src/kaleidoscope/plugin/FlashHelper.h new file mode 100644 index 00000000..9602b872 --- /dev/null +++ b/src/kaleidoscope/plugin/FlashHelper.h @@ -0,0 +1,60 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-FlashHelper -- Firmware-assisted flashing + * Copyright (C) 2020 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 . + */ + +#pragma once + +#include "kaleidoscope/Runtime.h" + +namespace kaleidoscope { +namespace plugin { + +class FlashHelper: public kaleidoscope::Plugin { + public: + FlashHelper() {} + + static void setTimeout(uint8_t timeout) { + timeout_ = timeout; + } + static uint8_t getTimeout() { + return timeout_; + } + static void activate() { + is_active_ = true; + start_time_ = Runtime.millisAtCycleStart(); + } + static void deactivate() { + is_active_ = false; + } + static bool isActive() { + return is_active_; + } + + EventHandlerResult onFocusEvent(const char *command); + EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t key_state); + EventHandlerResult beforeEachCycle(); + + private: + static bool is_active_; + static uint8_t timeout_; + + static uint32_t start_time_; +}; + +} +} + +extern kaleidoscope::plugin::FlashHelper FlashHelper;