Unions are a C-reminiscense that are better avoided in modern C++.
They cause specific problems due to their nature of representing
independent types. The way they are used in Kaleidoscope, they
can easily be replaced by a class.
This enables it to properly work with Key objects in constexpr context
where with the old union-based implementation the compiler reported
errors when one Key was constructed based on a key_code/flags pair and
another one through raw-data. In such a case, the compiler assumes that
both Key instances represent something entirely different. This is
because unions were never meant for type conversions and the C++
standard considers their use for that purpose as undefined behavior.
The new class provides accessor methods for raw-data access and for
key_code/flags-data access.
This is a breaking change as it is is not possible to replace direct
member access patterns like
key.raw = 0xFFFF;
based on the raw-accessors.
For the .keyCode and .flags members, proxy objects are used
to enable the generation of suitable deprecations warnings.
All direct access via .raw, .keyCode and .flags have been replaced
throughout Kaleidoscope.
Information on how to upgrade is provided in UPGRADING.md
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This implements a new plugin, `PersistentLEDMode`, whose single purpose is to
store the current LED mode to storage, whenever it changes. Since we can't hook
into led mode change events yet, we abuse the `afterEachCycle()` hook to compare
the current led mode to what we think it is, and store it if it changes.
This is obviously not very elegant, but the best we can do right now.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Having to recompile and re-flash firmware to set the idle timeout of the plugin
isn't a fun or desired experience. It's fine when one already figured out the
timeout they want, and have no desire to change it. For everyone else, being
able to configure it at run-time via Focus, and have it persist to EEPROM is a
much nicer experience.
This change adds an alternative version of the plugin, `PersistentIdleLEDs`, a
subclass of the original one. This one provides the focus command and
persistence. It's a child class, because that results in a smaller footprint
than a separate plugin that calls the `IdleLEDs` object.
The code borrows from - but is not wire-compatible with - Dygma's implementation
by @mattvenn.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
While not complete yet, this is a stab at documenting the new device APIs. There
are parts still missing, but pointers are there to the headers which show the
API.
`UPGRADING.md` and `NEWS.md` have also been updated to mention these.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The new device APIs were built on top of composition (instead of inheritance,
like the former one). At the highest level, we have `kaleidoscope::device::Base`
and `kaleidoscope::device::BaseProps`. The latter is a set of overrideable
properties, components that make up the device: the key scanner, LEDs, MCU, and
so on.
Many components - like the key scanner and LEDs - also come in a similar setup:
the base class and properties, because this allows us to make them fairly
efficient templates.
All of the existing devices have been ported to the new APIs. While the old
`Hardware` base class remains - for now, and deprecated - it is not guaranteed
to work.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of using `Kaleidoscope.serialPort()` in every example, introduce a
helper variable in some cases, to make the coder nicer to read.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Deprecate Model01-TestMode, in favour of the newer HardwareTestMode plugin. We
also turn it into a no-op, so that we don't need to update it for API changes
coming in the near future.
The Model01 example has been updated to use the newer HardwareTestMode instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of having to define `HARDWARE_IMPLEMENTATION` to the class name of the
device, and define `KeyboardHardware` from within the plugin, let all devices
set `kaleidoscope::Device` to their own class via a typedef. Furthermore,
instead of `KeyboardHardware`, use `Kaleidoscope.device()` instead. This makes
device plugins a little bit simpler, and our naming more consistent.
Because some parts of the firmware need to access the device object before the
`Kaleidoscope` object is available, we can't make it a member of that. For this
reason, the device object is `kaleidoscope_internal::device`, and
`Kaleidoscope.device()` wraps it. In general, the wrapper should be used. But if
access to the device is required before `Kaleidoscope` is available, then that's
also available.
The `Kaleidoscope` object grew a few more wrappers: `storage()` and
`serialPort()`, so that one doesn't need to use `Kaleidoscope.device()`
directly, but can use the wrappers, which are noticably shorter to write.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Some boards used to provide the device object under an alias named after the
device itself. For the sake of consistency, we do not want to provide these
aliases in the future. As such, deprecate them, and update all users to use
`KeyboardHardware` instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of having to include `device/key_indexes.h` from every single hardware
plugin, include it from `Kaleidoscope.h` instead. This also allows us to get rid
of the redundant `KeyAddr` typedef, by including `kaleidoscope/KeyAddr.h` from
`key_indexes.h` instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Move all the hardware plugins from the `kaleidoscope::hardware` namespace to
`kaleidoscope::device`, in perparation for deeper changes to come later.
This is merely a restructuring, there are no functional changes. The one
breaking change is that `ATMegaKeyboard` moved too, and we do not provide any
backward compatibility there.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
While we made attempts at forcing Arduino to use the current copy (that's what
all the `current-libraries` stuff are), it apparently doesn't work anymore. As a
quick workaround, delete the bundled Kaleidoscope's `library.properties`, so
Arduino won't find it, and will use the current one instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
While we technically only support AVR for now, most of the code is
arch-agnostic, and we'll soon have ARM boards too. This is a preparation step to
unlock that architecture.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When deciding how much data to work with, store the number of LEDs on the board,
not the number of keys. Boards may have less or more LEDs than keys, and since
the plugin is supposed to support theming the LEDs, that number is the one we want.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
In preparation for making Serial access configurable on a per-board basis,
introduce `KeyboardHardware.serialPort()`, which - for the time being - returns
the Serial object.
All users of Serial have been updated to use the new API.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of directly accessing the EEPROM, do so through
`KeyboardHardware.storage()`, which - for the time being - is a function that
simply returns the `EEPROM` object.
All plugins that were using EEPROM directly were updated, and so was the
EEPROM-Settings documentation.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We want to keep `key_hue` below 255, without clipping it there, otherwise the
effect will come out glitchy. To achieve that, we simply substract 255 until
we're above the cap. This results in the rainbow being laid out in a kind of
wave.
Previously, we didn't do this in a loop, which only worked when the device had
less than 128 LEDs. For devices with more, we need to do this in a loop, until
we get below the cap.
Based on #664 by @mattvenn.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
To make it easier to test hardware plugin changes, and compile only their
example firmware, add a Makefile for the ErgoDox EZ and the Keyboardio Model01.
All the other devices already have one, these two should have one too.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Moved all of the Devices into vendor subdirectories, and named the board
directories after the board itself.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This implements a new plugin for Dynamic (EEPROM-stored) macros. Unlike the
Macros plugin, these macros are stored in EEPROM, and can't run custom code,
only the steps outlined in the Macros documentation.
The plugin provides two Focus commands (`macros.map` and `macros.trigger`) to
get or set the dynamic macros, and to trigger one without having to place them
on the keymap.
Fixes#370.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>