This new plugin will allow MouseKeys to be configured via Focus, and store and
retrieve its config parameters from EEPROM, enabling Chrysalis to control it.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
This is a major rewrite of the MouseKeys plugin, primarily focused on mouse
cursor movement keys. There is no change to the keys themselves, and the
behaviour is fairly similar, but there are now better configuration parameters
and defaults. The new parameters are a minimum speed, a maximum speed, and the
length of time it takes to reach that maximum speed, without needing to worry
about the report update interval.
Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
Remove the effectively unused `initial_suspend_` variable. It wasn't
doing anything useful, because it was set to false on the first round
through the event loop. Also remove the unused reference to the internal
AVR USB core variable `_usbSuspendState`.
Saves 18 bytes of flash on AVR, and 32 on GD32.
Signed-off-by: Taylor Yu <tlyu@mit.edu>
Fix a race condition in `sketch.mk` that tends to pop up when doing
`make -j smoke-sketches`. Ignore failures from `install -d`, because
they seem to only occur due to a TOCTOU condition in `install`.
Signed-off-by: Taylor Yu <tlyu@mit.edu>
The difference between the AVR and the GD32 implementation was the way we
checked if the device is suspended, otherwise the logic was exactly the same,
duplicated.
To remove the need for duplicating the same code for every architecture we
support, lift out the suspension check instead. This way the core logic becomes
shared between all of them.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
detecting the device port at evaluation time rather than execution time.
This meant that we were doing the "where is the board" check for any
compilation target, even if we'd never flash.
Arduino's board probing is somewhat heavyweight and can take a couple of
seconds.
We move that logic into a shell expression executed at runtime.
On my laptop, this shaves 10 seconds off make -j 9 simulator tests,
which is pretty nice since that used to take about 30 seconds.
But on a plain `make simulator-tests`, it shaved a full minute from the
2 minute and 30 second runtime.
When flushing the on-tap action, we need to use `handleKeyEvent`, because our
address may not be valid, and `handleKeyswitchEvent` will not perform the action
if the address is invalid.
This addresses keyboardio/Chrysalis#1055.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This reverts commit 1d8eb6d2e2.
Rainbow effects on the Model 100 had some harsh transitions,
especially from red/orange to yellow.
@obra reported that the gamma implementation was disabled on the
Model 100 earlier because it broke the firmware so badly that
the keyboard was unusable for typing. This no longer seems to be
the case, possibly due to changes in the Arduino core and/or
<pgmspace.h> compatibility.
Signed-off-by: Taylor Yu <tlyu@mit.edu>
Updates for the FocusSerial documentation, showing the new patterns, and
documenting the new methods.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
With the new patterns, `Focus.inputMatchesCommand(command, cmd)` felt wrong, so
this patch renames the `command` argument of `onFocusEvent()` to `input`, to
better match what it really is.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
In the past, we were using `Focus.handleHelp()` to see if we're handling a
`help` command, and print the commands supported by the handler. We also used
`strcmp_P` directly to compare (parts of) our input against command supported by
the handler. This approach works, but had multiple major disadvantages: it
duplicated strings between `handleHelp` and the `strcmp_P` calls, and it relied
on fragile substring pointers to save space.
To replace all that, this patch implements a different approach. Help handling
is split between a check (`Focus.inputMatchesHelp()`) and a
reply (`Focus.printHelp()`), the latter of which takes a list of `PSTR()`
strings, rather than one single string. This allows us to reuse the same
strings for comparing against the handler's input.
The new approach no longer uses the fragile substring pointers, nor does it use
`strcmp_P` directly, but goes through a wrapper (`Focus.inputMatchesCommand()`)
instead.
These changes lead to a more readable pattern. While we do use longer strings as
a result, there is less duplication, and the new patterns also require less
code, so we end up with saving space, at least on AVR devices.
The old methods are still available and usable, but they're deprecated.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
`Serial.read()` is unbuffered, and will return `-1` (which we cast to an
unsigned char, so 255) immediately if there is no data in the incoming buffer.
This is unlike every other kind of read we do, which use `parseInt()`, and are
thus buffered reads with a timeout.
The problem with returning `-1` immediately is that Chrysalis sends data in
chunks, so if we end up trying to read a char at a chunk boundary, we'll end up
reading -1s, which we treat as valid data, and cast it to an unsigned char,
completely throwing off the protocol in the process.
By using `readBytes()`, we have a one second window during which more data can
arrive, and as such, is consistent with the rest of our reads.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The new plugin enables configuring some aspects of SpaceCadet through Focus: the
current mode, and the global timeout. This is makes it possible to ship firmware
with SpaceCadet included, disabled by default, but still allow one to enable it
without having to map and tap the enable key.
The settings are also persisted into storage.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The example in the documentation was referring to a function that does not
exist. Correct it to use the one that does.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Fall back to `dash` on macOS, because `bash` randomly drops serial
input, causing the tool to hang.
Flush the command buffer before sending the requested command. A
failed upload session can cause characters to remain in the command
buffer.
Redirect stdin instead of using a separate file descriptor. Also do
this before running `stty`. This allows the `stty` settings to
actually take effect on macOS, which seems to reset the termios
state of serial devices upon the last close of the device.
Tested on macOS 10.15 and Ubuntu 20.04.
Signed-off-by: Taylor Yu <tlyu@mit.edu>
Previously, a newline that wasn't read with the rest of the command in
a single event would get appended to the command buffer instead of
remaining in the "peek" buffer, so the command dispatch would never
fire.
Stash a space delimiter instead of storing it in the buffer, only to
overwrite it later.
Fix an off-by-one error that could cause a buffered command to not be
null-terminated. This probably didn't cause a problem in practice,
because Focus plugins mostly did a `strcmp` against a fixed string that
is smaller than the command buffer size.
Signed-off-by: Taylor Yu <tlyu@mit.edu>
The new plugin provides a Focus-based interface for setting custom layer names.
The layer names aren't used internally, they're purely for use by host-side
applications.
This addresses the Kaleidoscope-side of keyboardio/Chrysalis#3.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
It was always intended to be public - it is even documented as such! -, but was
mistakenly left private.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
Instead of simply echoing "device.reset" into the device port, call
`bin/focus-send`, which sets the `raw` setting on the port, before writing into
it. Without that, the command is not recognised by the firmware.
We could do the stty call in the makefile directly, but to support macOS, we'd
need to treat that specially, and at that point, it's easier to just call
`bin/focus-send`. The sketch relies on having the Kaleidoscope repo available
anyway, so we can safely rely on `bin/focus-send` being there, too.
Because we're now using the tool in the makefiles, `focus-test` was renamed to
`focus-send`.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
A number of devices declared the bootloader in their device properties as
`BootLoader`, while the base class, and anything using it, was looking for
`Bootloader`. This resulted in these devices using the default, dummy
bootloader, rather than the one we intended to set.
This patch corrects that, and everything's using `Bootloader` now, including the
documentation.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This simple plugin does nothing more than provide a `version` focus command,
which will print the firmware version configured at build-time (defaulting to
"0.0.0").
This is a header-only plugin, so that Arduino compiles it in the same
compilation unit as the main sketch, allowing us to set the version from the
sketch, if so desired.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
The Model100 has a lot more space available compared to the Model01, so we can
have more layers in EEPROM. While we could have more than 8, 8 is the limit that
OneShot and dual-use keys support via Chrysalis, so to avoid potential
confusion, lets have 8 layers only.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
This enables the IdleLEDs, Qukeys, OneShot, Escape-OneShot and DynamicMacros
plugins for the Model100 sketch. None of these - apart from IdleLEDs - cause any
change in behavior unless first configured so.
Signed-off-by: Gergely Nagy <algernon@keyboard.io>
2 years ago
100 changed files with 2513 additions and 941 deletions
@ -5,7 +5,7 @@ Flexible firmware for Arduino-powered keyboards.
This package contains the "core" of Kaleidoscope and a number of [example firmware "Sketches"](https://github.com/keyboardio/Kaleidoscope/tree/master/examples).
If you're just getting started with the Keyboardio Model 01, the [introductory docs are here](https://github.com/keyboardio/Kaleidoscope/wiki/Keyboardio-Model-01-Introduction) and the source for the basic firmware package is here: https://github.com/keyboardio/Model01-Firmware. It's probably a good idea to start there, learn how to modify your keymap and maybe turn some modules on or off, and then come back to the full repository when you have more complex changes in mind.
If you're just getting started with the Keyboardio Model 01, the [introductory docs are here](https://github.com/keyboardio/Kaleidoscope/wiki/Keyboardio-Model-01-Introduction) and the source for the basic firmware package is here: https://github.com/keyboardio/Model01-Firmware. It's probably a good idea to start there, learn how to modify your keymap and maybe turn some modules on or off, and then come back to the full repository when you have more complex changes in mind. (The firmware for all other devices is inside examples/Devices in this Kaleidoscope repo.)
We replaced it with a new Makefile based build system that uses `arduino-cli` instead of of the full Arduino IDE. This means that you can now check out development copies of Kaliedoscope into any directory, using the `KALEIDOSCOPE_DIR` environment variable to point to your installation.
We replaced it with a new Makefile based build system that uses `arduino-cli` instead of of the full Arduino IDE. This means that you can now check out development copies of Kaliedoscope into any directory, using the `KALEIDOSCOPE_DIR` environment variable to point to your installation.
::Focus.send(F("Congratulations, the test command works!"));
@ -47,6 +52,18 @@ void setup () {
The plugin provides the `Focus` object, with a couple of helper methods aimed at developers. Terminating the response with a dot on its own line is handled implicitly by `FocusSerial`, one does not need to do that explicitly.
### `.inputMatchesHelp(input)`
Returns `true` if the given `input` matches the `help` command. To be used at the top of `onFocusEvent()`, followed by `.printHelp(...)`.
### `.printHelp(...)`
Given a series of strings (stored in `PROGMEM`, via `PSTR()`), prints them one per line. Assumes it is run as part of handling the `help` command. Returns `EventHandlerResult::OK`.
### `.inputMatchesCommand(input, command)`
Returns `true` if the `input` matches the expected `command`, false otherwise. A convenience function over `strcmp_P()`.