By means of this macro, headers can check if they are compiled
in the sketch compilation unit or in any other compilation unit.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
The new plugin exposes some layer control functions over Focus, to be able to
control layers from the host side.
Fixes#780.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When setting the idle timeout to zero, stop checking for idleness, and never
turn the LEDs off. Setting the timeout to a higher value again will resume the
plugin's functionality.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Even though the HID facade is deprecated in favour of the HID driver, to
maintain backwards compatibility, we should include `kaleidoscope/hid.h` by
default.
Fixes#793.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
When handling the `led.brightness` command, we forgot to break out of the switch
statement, thus executing the `setall` branch too. This resulted in very slow
operations, because we had to wait for a read to timeout.
Adding a break fixes all that.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This changes the IdleLEDs plugin to only re-enable LEDs if they were disabled
due to idleness. If they were turned off any other way, the plugin will not
re-enable them. This makes it play better with the `Key_LEDToggle` key.
Fixes#790.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The new `.setBrightness()` and `.getBrightness()` methods control the brightness
of the LEDs, by dispatching them to the LED drivers. We dispatch to the drivers
so that nothing else needs to be aware of brightness control. Plugins will
always set the unadjusted colors, and anything and anyone who reads colors, will
also get the unadjusted values.
Pushing the adjustment down to the driver level makes everything smooth, and
since we do gamma correction there anyway, it makes sense to do brightness
adjustment at the same place, too.
Fixes#775.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The (internal) `::dygma::raise::Hand` class had two methods that weren't used by
Kaleidoscope at all: `.setAllLEDsTo` and `.setOneLEDTo`. Since they're unused,
remove them.
We weren't going to use them anyway, because they immediately sync to the LED
driver, while we want to do that in `syncLeds()`, and in there only.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This adds `LEDControl.disable()` and `LEDControl.enable()` which disable and
enable LED operations, respectively. These are meant to replace the current
`LEDControl.paused` property (which is getting deprecated with this change), and
do some additional work on top of just disabling or re-enabling future updates
and sync. Namely, `disable()` will also turn LEDs off, while `enable()` will
refresh them all, too.
We also add a dedicated `Key_LEDToggle` key to disable/enable LEDs. This is
useful when one wants to turn LEDs off, without changing active LED mode to
`LEDOff`.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The USB-Quirks plugin was relying on the old HIDAdaptor APIs, including
the (undocumented) defines that enable/disable the boot keyboard. Since we no
longer have those defines, the plugin was effectively a no-op.
This updates the plugin to work with the new APIs, without the need for ifdefs.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
`RaiseKeyScanner::pressedKeyswitchCount` and `::previousPressedKeyswitchCount()`
used `__builtin_popcountl` to count the bits set in the left and right hand
states, but that only looks at 32 bits out of the 64 we have in each half. We
should be using `__builtin_popcountll` instead.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
To make it easier to configure which HID implementation - and which parts of it
- a particular board uses, we turn our current HID facade (`kaleidoscope::hid`)
into a proper, Props-supported driver. This also allows us to get rid of the
`Kaleidoscope-HIDAdaptor-KeyboardioHID` library.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Make the Model01's `setup()` method non-static, so that we can call the parents
`setup()` method too. We want to do that so if new drivers are added, we
automatically pick those up.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
- Rewrite decay code to fade brightness smoothly with an x^4
relationship
- Fade hue linearly from orange to red rather than for a subset of
time from red to orange
Signed-off-by: Bart Nagel <bart@tremby.net>
With this change, each device can specify a short name in their device
properties, which will be used to override the HID shortname. Due to link order,
we need to do the override in the user sketch, so we hook into the `KEYMAPS`
macro, to call `_INIT_HID_GETSHORTNAME`, which will set the override up for us.
The short name defaults to "kaleidoscope".
Together with keyboardio/KeyboardioHID#61, fixeskeyboardio/KeyboardioHID#54.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The build now fails if the avr-gcc version is too old.
A verbose error message reports Arduino upgrade information.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
The two files kaleidoscope_internal/sketch_preprocessing/sketch_header.h
and kaleidoscope_internal/sketch_preprocessing/sketch_footer.h
are automatically pasted at the top and bottom of the
preprocessed sketch.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Sketch exploration choked on the rare case that an empty keymap
was supplied with `KEYMAP()`.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
To be able to compile a firmware for the Raise, we need to include the HID
facade, and the base keyscanner implementation from the Raise device plugin.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This was done to enable separate inclusion of the central runtime
class without having to include the central header
kaleidoscope/Kaleidoscope.h which used to pull in a lot of stuff that is
not required in many compilation units.
The new class `Runtime_` lives in namespace kaleidoscope its singleton
instance is `kaleidoscope::Runtime`. It is now only available internally
in library Kaleidoscope but not from the sketch.
The original class name `Kaleidoscope_` in global scope has been deprecated.
The original instance name `Kaleidoscope` in global scope has been
preserved to be used by end users in their sketches.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This implements an extension to the `TapDance` plugin, allowing us to store
`tapDanceActionKeys()`-esque lists in Storage. The core idea here is very
similar to that of `DynamicMacros`: we dump/restore the full list via Focus,
build a cached index on setup and any updates, and play back the selected key
when need be.
Unlike `DynamicMacros`,this plugin is built on top of `TapDance` and cannot
function without it.
Fixes#730.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The virtual hid was recently included in the core firmware repo.
Due to missing `#ifdef KALEIDOSCOPE_VIRTUAL_BUILD` in some
files, two versions of the hid library, one for the virtual and one for
the physical device were build. The linker perferred the one that it
encountered first. That caused a link order dependency that possibly
renders some firmware builds without HID reports being send to the host.
This change adds thse missing `#ifdef KALEIDOSCOPE_VIRTUAL_BUILD`
clauses.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This static member did not have an instance under
certain circumstances. A typical workaround for such
a situation is to make it a local static of an accessor
function. By this means the one definition rule is
not violated and the object always instanciated. It is still optimized
away by the compiler in case device::Base<...>::LEDs() is not called.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
`RaiseKeyScanner::actOnMatrixScan()` erroneously looped through all the columns
in the matrix, while we only wanted to loop through the left half, since we read
the right half at the same time, not separately. This resulted in half the keys
producing two events, due to overflow. We also calculated the key number
incorrectly.
Both of these issues are fixed with this patch.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The submember is a bitfield that needs its own braced list.
Gcc silently tolerates this clang warns about it.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Clang seems to have problem with recognizing that those
functions are actually static members. This change
makes it more obvious to the compiler, which functions we actually refer
to.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This feature unfortunately relies on a non-standard feature
that is supported by gcc as an extension but triggers
errors when build with clang.
The fix is to disable the feature until we find a better solution
to allow virtual builds with clang.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
While older GCC versions accept using an unnamed struct, gcc 7+ does not. Use a
named one instead, to make both gcc versions happy.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This implements a new device plugin, to drive the Dygma Raise. A few helpers are
also introduces, which are used by the Raise only for now, but are generic
enough so that eventually, other boards may use them too.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This commit adds a new template hook exploreSketch() that allows plugins to efficiently
obtain compile-time known information about the sketch.
The hook is called before setup and is passed a _Sketch
template parameter that wraps two more types Plugins and StaticKeymap, whose static constexpr methods can be used
to explore the registered plugins and the static keymap.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Hook methods can now be templated.
A template parameter type list, a list of template parameters and
a list of dummy template arguments have been added to the
macro arguments used in _FOR_EACH_EVENT_HANDLER.
Non-template hooks pass empty parenthesis for the three newly
introduced macro arguments.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This enables compile time exploration of the keymap
from all code that is part of the sketch's compilation unit.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
The Model01.h required some reordering of header includes
and some forward defines of certain types that are
used in property classes.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This method is now implemented in the LED driver
base class based on the LED driver properties.Removed method
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Kaleidoscope's device API defines two types to be exported
as kaleidoscope::Device and kaleidoscope::DeviceProps.
The newly introduced macro EXPORT_DEVICE can be used
to export those two type names conveniently.
The macro also serves the purpose to only export a type named
kaleidoscope::Device in non-virtual device builds. In virtual
builds, a homonymous type is exported by the virtual device header
Virtual.h.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
This is a primitive implementation of a `FlashAsStorage` (or rather,
`FlashAsEEPROM`)-based storage component. It's based on `FlashAsEEPROM`, because
I couldn't find a sane way to push the storage data variable within our template
class.
At some point, this needs to be reworked, to pull the size from Props, and not
use the EEPROM API wrappers.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
We'd like to be able to run custom code whenever the led mode changes, reliably,
without having to resort to checking the mode every cycle. For this purpose, we
introduce the `onLEDModeChange()` handler plugins can hook into. It will be
called every time `LEDControl.set_mode()` is called, even if that just sets the
mode to the currently active one.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
LED driver properties now can re-define an array
for their individual mapping from key offsets to LED indices.
This array is both constexpr (can be used at compiletime) and
stored in PROGMEM. The latter is used by the LED driver base
class to map key offsets to LED ids at runtime.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Using call by reference in FocusSerial::send(...) and
FocusSerial::sendRaw(...) causes linker errors due to
undefined symbols if constexpr constants are passed to the
methods.
This is because if a constexpr value is bound to a reference
this is the same as taking the address of the value. Thus,
the compiler has to generate an instance. Some constants
like e.g. FocusSerial::NEWLINE do not come with an
instance.
This seems not to cause problems with avr-gcc up to now
but generates linker errors during virtual compiles with later gcc
versions (e.g. gcc 8.3.0).
This change does not incur any additional overhead as
all version of FocusSerial's send methods are already inlined,
and the templated versions root to the non-template versions of the send
methods that only accept call-by-value anyway.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Up to now, the device header was included by several files
via the command
This commit introduces a build type selection header
kaleidoscope/device/device.h that enables to
either directly include the device header or
to first include the 'physical' device header
and then the 'virtual' device header.
This is meant for the virtual device to be able
to be defined depending on the properties of the
physical device.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
Plugin Kaleidoscope-HardwareVirtual is now obsolete.
Everything device related has been incorporated in the
core repo as a virtual device in kaleidoscope/devices/virtual.
Signed-off-by: Florian Fleissner <florian.fleissner@inpartik.de>
The MCU family is called `ATmega`. not `ATMega`, so correct all occurrences of
it, while we still can. Also renamed `kaleidoscope::driver::keyscanner::AVR` to
`kaleidoscope::driver::keyscanner::ATmega`.
As a side-effect, this fixes compilation under the Arduino IDE, which defines
`AVR` as a symbol.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
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>
We have a few AVR-specific things which do not have a guard yet, and cause
issues on other architectures. This adds those missing guards to the following
places:
- The `kaleidoscope::Hardware` base class, which is deprecated, but still
exists. As such, it needs to be restricted to AVR devices only (since that's all
it supported, non-AVR devices should use the new APIs).
- `device/keyboardio/twi` are only used by the Imago at the moment, and is
AVR-specific, so guard that too.
- Removed an unneeded include from `driver::bootloader::None`, because it
doesn't need `<avr/wdt.h>`.
- `plugin::FirmwareDump` is now restricted to AVR, because that's the only
architecture we support dumping the firmware on.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The `AVREEPROM` storage is AVR-specific, and it depends on features and headers
that may not make sense elsewhere. As such, guard it with an `#ifdef`, to only
compile it for AVR-based devices.
Fixes#718.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
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>
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>