From 2e21af99b9cf1e51c26b844f65f6d03500159fc7 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 18 Dec 2018 09:41:11 +0100 Subject: [PATCH 1/3] Implement a Hardware base class This is basically the old Kaleidoscope-Hardware plugin pulled in, and made into a base class. The purpose is documentation (#167) mostly. The base class has default implementations for all methods (most do nothing), and can be overridden by derived classes. Since the hardware object is always going to be called through `KeyboardHardware`, which has the exact type of the hardware, we do not need to use virtual functions. The derived class will just shadow the default implementations. All hardware plugins were updated to use this (directly or indirectly). The resulting compiled binary is the same, but we were able to remove a few boilerplate lines from here and there. Signed-off-by: Gergely Nagy --- src/kaleidoscope/Hardware.h | 268 ++++++++++++++++++ src/kaleidoscope/hardware/ATMegaKeyboard.h | 14 +- src/kaleidoscope/hardware/ez/ErgoDox.h | 14 +- .../hardware/keyboardio/Model01.h | 4 +- 4 files changed, 277 insertions(+), 23 deletions(-) create mode 100644 src/kaleidoscope/Hardware.h diff --git a/src/kaleidoscope/Hardware.h b/src/kaleidoscope/Hardware.h new file mode 100644 index 00000000..805730aa --- /dev/null +++ b/src/kaleidoscope/Hardware.h @@ -0,0 +1,268 @@ +/* -*- mode: c++ -*- + * Kaleidoscope-Hardware -- Kaleidoscope Hardware Base class + * Copyright (C) 2017, 2018 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 . + */ + +/** @file kaleidoscope/Hardware.h + * Base class for Kaleidoscope hardware libraries. + */ + +#pragma once + +#ifndef CRGB +#error cRGB and CRGB *must* be defined before including this header! +#endif + +/* All hardware libraries must define the following macros: + * HARDWARE_IMPLEMENTATION - the name of your public object conforming to + * the 'class Hardware' interface below. + * CRGB(r,g,b) - explained below + */ + +/** + * Forward declaration of the cRGB structure. + * + * The base class does not define the cRGB structure, that is left up to the + * individual Hardware libraries. We do a forward declaration here, because the + * base hardware has methods that depend on a cRGB structure. + * + * The structure will need to have at least three members: r, g, and b - + * compilation will fail otherwise. + * + * Despite its name, the members do not need to be in the order r g b -- most + * likely they will be in an order that is convenient for the hardware. So + * initializing a cRGB with a struct literal will give surprising results for any + * colors where r, g, and b do not have the same value. Each Hardware library + * defines a CRGB(r,g,b) macro which returns a literal cRGB with the given values. + */ +typedef struct cRGB cRGB; + +namespace kaleidoscope { +/** Kaleidoscope Hardware base class. + * Essential methods all hardware libraries must implement. + */ +class Hardware { + public: + /** + * @defgroup kaleidoscope_hardware_leds Kaleidoscope::Hardware/LEDs + * @{ + */ + /** + * Sync the LEDs with the underlying hardware. This should make sure that + * changes made before this call are reflected on the device. + */ + void syncLeds(void) {} + /** + * Set the color of a per-key LED at a given row and column. + * + * Setting the color does not need to take effect immediately, it can be + * delayed until @ref syncLeds is called. + * + * @param row is the logical row position of the key. + * @param col is the logical column position of the key. + * @param color is the color to set the LED to. + */ + void setCrgbAt(byte row, byte col, cRGB color) {} + /** + * Set the color of a per-key LED at a given LED index. + * + * Setting the color does not need to take effect immediately, it can be + * delayed until @ref syncLeds is called. + * + * @param i is the LED index to change the color of. + * @param color is the color to set it to. + */ + void setCrgbAt(uint8_t i, cRGB color) {} + /** + * Returns the color of the LED at a given index. + * + * @param i is the index of the LED to return the color of. + * + * @returns The color at the given position. + */ + cRGB getCrgbAt(uint8_t i) { + cRGB c = { + 0, 0, 0 + }; + return c; + } + /** + * Returns the index of the LED at a given row & column. + * + * @param row is the logical row position of the key. + * @param col is the logical column position of the key. + * + * @returns The index of the LED at the given position, or -1 if there are no + * LEDs there. + */ + int8_t getLedIndex(uint8_t row, byte col) { + return -1; + } + /** @} */ + + /** @defgroup kaleidoscope_hardware_matrix Kaleidoscope::Hardware/Matrix + * @{ + */ + /** + * Scan the keyboard matrix, and act on it. + */ + void scanMatrix(void) {} + /** + * Read the state of the keyboard matrix. + * + * Do whatever is necessary to read the current keyboard state - but without + * acting on it. + * + * This is primarily used by @ref scanMatrix, but may have other uses too. + */ + void readMatrix(void) {} + /** + * Act on the scanned keyboard matrix. + * + * Iterate through the scanned state (@see readMatrix), and act on any events. + */ + void actOnMatrixScan(void) {} + /** @} */ + + /** @defgroup kaleidoscope_hardware_masking Kaleidoscope::Hardware/Key masking + * + * Sometimes there are situations when one wants to ignore key events for a + * while, to mask them out. Masked keys will be ignored until they are + * released. + * + * This is implemented in the Hardware library because that knows best how + * to mask efficiently, as this requires a deeper knowledge of the hardware, + * which is all but hidden from the rest of the plugins. + * @{ + */ + /** + * Mask out a key. + * + * Masking a key out means that any other event than a release will be + * ignored until said release. + * + * @param row is the row the key is located at in the matrix. + * @param col is the column the key is located at in the matrix. + */ + void maskKey(byte row, byte col) {} + /** + * Unmask a key. + * + * Remove the mask - if any - for a given key. To be used when the mask + * needs to be removed without the key being released. + * + * @param row is the row the key is located at in the matrix. + * @param col is the column the key is located at in the matrix. + */ + void unMaskKey(byte row, byte col) {} + /** + * Check whether a key is masked or not. + * + * @param row is the row the key is located at in the matrix. + * @param col is the column the key is located at in the matrix. + * + * @returns true if the key is masked, false otherwise. + */ + bool isKeyMasked(byte row, byte col) { + return false; + } + /** @} */ + + /** @defgroup kaleidoscope_hardware_reattach Kaleidoscope::Hardware/Attach & Detach + * + * In situations where one wants to re-initialize the devices, perhaps to + * change settings inbetween, detaching from and then attaching back to the + * host is a desirable feature to have. Especially if this does not cut power, + * nor reboot the device. + * + * Because different hardware has different ways to accomplish this, the + * hardware plugin must provide these functions. Kaleidoscope will wrap them, + * so user code does not have to deal with KeyboardHardware. + * @{ + */ + /** + * Detach the device from the host. + * + * Must detach the device, without rebooting or cutting power. Only the end + * points should get detached, the device must remain powered on. + */ + void detachFromHost() {} + /** + * Attack the device to the host. + * + * Must restore the link detachFromHost severed. + */ + void attachToHost() {} + + /** @} */ + + /** + * @defgroup kaleidoscope_hardware_keyswitch_state Kaleidoscope::Hardware/Key-switch state + * + * These methods offer a way to peek at the key switch states, for those cases + * where we need to deal with the state closest to the hardware. Some methods + * offer a way to check if a key is pressed, others return the number of + * pressed keys. + * + * @{ + */ + /** + * Check if a key is pressed at a given position. + * + * @param row is the row the key is located at in the matrix. + * @param col is the column the key is located at in the matrix. + * + * @returns true if the key is pressed, false otherwise. + */ + bool isKeyswitchPressed(byte row, byte col) { + return false; + } + /** + * Check if a key is pressed at a given position. + * + * @param keyIndex is the key index, as calculated by `keyIndex`. + * + * @note Key indexes start at 1, not 0! + * + * @returns true if the key is pressed, false otherwise. + */ + bool isKeyswitchPressed(uint8_t keyIndex) { + return false; + } + /** + * Check the number of key switches currently pressed. + * + * @returns the number of keys pressed. + */ + uint8_t pressedKeyswitchCount() { + return 0; + } + + /** @} */ + + /** + * @defgroup kaleidoscope_hardware_misc Kaleidoscope::Hardware/Miscellaneous methods + * @{ + */ + /** + * Method to do any hardware-specific initialization. + * + * Called once when the device boots, this should initialize the device, and + * bring it up into a useful state. + */ + void setup() {} + /** @} */ +}; +} diff --git a/src/kaleidoscope/hardware/ATMegaKeyboard.h b/src/kaleidoscope/hardware/ATMegaKeyboard.h index ca73a12f..f44fafe7 100644 --- a/src/kaleidoscope/hardware/ATMegaKeyboard.h +++ b/src/kaleidoscope/hardware/ATMegaKeyboard.h @@ -39,6 +39,8 @@ struct cRGB { #endif +#include "kaleidoscope/Hardware.h" + #define ROW_PIN_LIST(...) __VA_ARGS__ #define COL_PIN_LIST(...) __VA_ARGS__ @@ -69,23 +71,13 @@ struct cRGB { namespace kaleidoscope { namespace hardware { -class ATMegaKeyboard { +class ATMegaKeyboard : public kaleidoscope::Hardware { public: ATMegaKeyboard(void) {} // these will be overridden by the subclass static uint8_t debounce; - void syncLeds(void) {} - void setCrgbAt(uint8_t row, byte col, cRGB color) {} - void setCrgbAt(int8_t i, cRGB crgb) {} - cRGB getCrgbAt(int8_t i) { - return CRGB(0, 0, 0); - } - int8_t getLedIndex(uint8_t row, byte col) { - return -1; - } - void setup(void); /** Detaching from / attaching to the host. diff --git a/src/kaleidoscope/hardware/ez/ErgoDox.h b/src/kaleidoscope/hardware/ez/ErgoDox.h index c7672ca7..000d537d 100644 --- a/src/kaleidoscope/hardware/ez/ErgoDox.h +++ b/src/kaleidoscope/hardware/ez/ErgoDox.h @@ -42,11 +42,13 @@ struct cRGB { #define CRGB(r,g,b) (cRGB){b, g, r} +#include "kaleidoscope/Hardware.h" + namespace kaleidoscope { namespace hardware { namespace ez { -class ErgoDox { +class ErgoDox : public kaleidoscope::Hardware { public: ErgoDox(void) {} @@ -54,16 +56,6 @@ class ErgoDox { static constexpr byte matrix_rows = 14; static constexpr int8_t led_count = 0; - void syncLeds(void) {} - void setCrgbAt(byte row, byte col, cRGB color) {} - void setCrgbAt(int8_t i, cRGB crgb) {} - cRGB getCrgbAt(int8_t i) { - return CRGB(0, 0, 0); - } - int8_t getLedIndex(byte row, byte col) { - return -1; - } - void scanMatrix(void); void readMatrix(void); void actOnMatrixScan(void); diff --git a/src/kaleidoscope/hardware/keyboardio/Model01.h b/src/kaleidoscope/hardware/keyboardio/Model01.h index c0fc0a6e..33dde527 100644 --- a/src/kaleidoscope/hardware/keyboardio/Model01.h +++ b/src/kaleidoscope/hardware/keyboardio/Model01.h @@ -29,11 +29,13 @@ #define CRGB(r,g,b) (cRGB){b, g, r} +#include "kaleidoscope/Hardware.h" + namespace kaleidoscope { namespace hardware { namespace keyboardio { -class Model01 { +class Model01 : public kaleidoscope::Hardware { public: Model01(void); From d7df39dffdc343b8e3a488a5437221f00842ae7a Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 18 Dec 2018 09:55:34 +0100 Subject: [PATCH 2/3] Hardware: Move detachFromHost/attachToHost to the base class Since all implementations of detachFromHost/attachToHost are the same for all our current keyboards, move it to the base class as a default. Signed-off-by: Gergely Nagy --- src/kaleidoscope/Hardware.h | 9 ++++++--- src/kaleidoscope/hardware/ATMegaKeyboard.cpp | 8 -------- src/kaleidoscope/hardware/ATMegaKeyboard.h | 11 ----------- src/kaleidoscope/hardware/ez/ErgoDox.cpp | 8 -------- src/kaleidoscope/hardware/ez/ErgoDox.h | 11 ----------- src/kaleidoscope/hardware/keyboardio/Model01.cpp | 8 -------- src/kaleidoscope/hardware/keyboardio/Model01.h | 11 ----------- 7 files changed, 6 insertions(+), 60 deletions(-) diff --git a/src/kaleidoscope/Hardware.h b/src/kaleidoscope/Hardware.h index 805730aa..35a303a4 100644 --- a/src/kaleidoscope/Hardware.h +++ b/src/kaleidoscope/Hardware.h @@ -198,14 +198,17 @@ class Hardware { * Must detach the device, without rebooting or cutting power. Only the end * points should get detached, the device must remain powered on. */ - void detachFromHost() {} + void detachFromHost() { + UDCON |= _BV(DETACH); + } /** * Attack the device to the host. * * Must restore the link detachFromHost severed. */ - void attachToHost() {} - + void attachToHost() { + UDCON &= ~_BV(DETACH); + } /** @} */ /** diff --git a/src/kaleidoscope/hardware/ATMegaKeyboard.cpp b/src/kaleidoscope/hardware/ATMegaKeyboard.cpp index 230eb3de..59f17401 100644 --- a/src/kaleidoscope/hardware/ATMegaKeyboard.cpp +++ b/src/kaleidoscope/hardware/ATMegaKeyboard.cpp @@ -51,14 +51,6 @@ void ATMegaKeyboard::setup(void) { TIMSK1 = _BV(TOIE1); } -void ATMegaKeyboard::detachFromHost() { - UDCON |= _BV(DETACH); -} - -void ATMegaKeyboard::attachToHost() { - UDCON &= ~_BV(DETACH); -} - void __attribute__((optimize(3))) ATMegaKeyboard::readMatrix(void) { for (uint8_t current_row = 0; current_row < KeyboardHardware.matrix_rows; current_row++) { uint16_t mask, cols; diff --git a/src/kaleidoscope/hardware/ATMegaKeyboard.h b/src/kaleidoscope/hardware/ATMegaKeyboard.h index f44fafe7..13d56483 100644 --- a/src/kaleidoscope/hardware/ATMegaKeyboard.h +++ b/src/kaleidoscope/hardware/ATMegaKeyboard.h @@ -80,17 +80,6 @@ class ATMegaKeyboard : public kaleidoscope::Hardware { void setup(void); - /** Detaching from / attaching to the host. - * - * These two functions should detach the device from (or attach it to) the - * host, preferably without rebooting the device. Their purpose is to allow - * one to do some configuration inbetween, so the re-attach happens with - * different properties. The device remains powered between these operations, - * only the connection to the host gets severed. - */ - void detachFromHost(); - void attachToHost(); - void readMatrix(void); /** diff --git a/src/kaleidoscope/hardware/ez/ErgoDox.cpp b/src/kaleidoscope/hardware/ez/ErgoDox.cpp index 46f1fdd6..b5228780 100644 --- a/src/kaleidoscope/hardware/ez/ErgoDox.cpp +++ b/src/kaleidoscope/hardware/ez/ErgoDox.cpp @@ -223,14 +223,6 @@ void ErgoDox::debounceRow(uint8_t change, uint8_t row) { } } -void ErgoDox::detachFromHost() { - UDCON |= (1 << DETACH); -} - -void ErgoDox::attachToHost() { - UDCON &= ~(1 << DETACH); -} - bool ErgoDox::isKeyswitchPressed(byte row, byte col) { return (bitRead(keyState_[row], col) != 0); } diff --git a/src/kaleidoscope/hardware/ez/ErgoDox.h b/src/kaleidoscope/hardware/ez/ErgoDox.h index 000d537d..ff765d37 100644 --- a/src/kaleidoscope/hardware/ez/ErgoDox.h +++ b/src/kaleidoscope/hardware/ez/ErgoDox.h @@ -61,17 +61,6 @@ class ErgoDox : public kaleidoscope::Hardware { void actOnMatrixScan(void); void setup(); - /** Detaching from / attaching to the host. - * - * These two functions should detach the device from (or attach it to) the - * host, preferably without rebooting the device. Their purpose is to allow - * one to do some configuration inbetween, so the re-attach happens with - * different properties. The device remains powered between these operations, - * only the connection to the host gets severed. - */ - void detachFromHost(); - void attachToHost(); - /* Key masking * ----------- * diff --git a/src/kaleidoscope/hardware/keyboardio/Model01.cpp b/src/kaleidoscope/hardware/keyboardio/Model01.cpp index f0f67980..0db65458 100644 --- a/src/kaleidoscope/hardware/keyboardio/Model01.cpp +++ b/src/kaleidoscope/hardware/keyboardio/Model01.cpp @@ -292,14 +292,6 @@ void Model01::setKeyscanInterval(uint8_t interval) { rightHand.setKeyscanInterval(interval); } -void Model01::detachFromHost() { - UDCON |= (1 << DETACH); -} - -void Model01::attachToHost() { - UDCON &= ~(1 << DETACH); -} - bool Model01::isKeyswitchPressed(byte row, byte col) { if (col <= 7) { return (bitRead(leftHandState.rows[row], 7 - col) != 0); diff --git a/src/kaleidoscope/hardware/keyboardio/Model01.h b/src/kaleidoscope/hardware/keyboardio/Model01.h index 33dde527..0360e8cc 100644 --- a/src/kaleidoscope/hardware/keyboardio/Model01.h +++ b/src/kaleidoscope/hardware/keyboardio/Model01.h @@ -55,17 +55,6 @@ class Model01 : public kaleidoscope::Hardware { void setup(); void rebootBootloader(); - /** Detaching from / attaching to the host. - * - * These two functions should detach the device from (or attach it to) the - * host, preferably without rebooting the device. Their purpose is to allow - * one to do some configuration inbetween, so the re-attach happens with - * different properties. The device remains powered between these operations, - * only the connection to the host gets severed. - */ - void detachFromHost(); - void attachToHost(); - /* These public functions are things supported by the Model 01, but * aren't necessarily part of the Kaleidoscope API */ From e95646efd0259e89ed640a593eeb7d05b6a50946 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Tue, 18 Dec 2018 09:58:42 +0100 Subject: [PATCH 3/3] Hardware: Remove duplicated documentation Methods that originate from the `kaleidoscope::Hardware` base class need not be documented every time they're being overridden. That leads to duplication, and higher chance of documentation going stale. As such, remove such cases, and rely on the base class having plenty of documentation instead. Signed-off-by: Gergely Nagy --- src/kaleidoscope/hardware/ATMegaKeyboard.h | 47 +------------------ src/kaleidoscope/hardware/ez/ErgoDox.h | 38 --------------- .../hardware/keyboardio/Model01.h | 38 --------------- 3 files changed, 2 insertions(+), 121 deletions(-) diff --git a/src/kaleidoscope/hardware/ATMegaKeyboard.h b/src/kaleidoscope/hardware/ATMegaKeyboard.h index 13d56483..88320fe4 100644 --- a/src/kaleidoscope/hardware/ATMegaKeyboard.h +++ b/src/kaleidoscope/hardware/ATMegaKeyboard.h @@ -75,60 +75,17 @@ class ATMegaKeyboard : public kaleidoscope::Hardware { public: ATMegaKeyboard(void) {} - // these will be overridden by the subclass static uint8_t debounce; void setup(void); - void readMatrix(void); + void actOnMatrixScan(); + void scanMatrix(); - /** - * Check the number of key switches currently pressed. - * - * @returns the number of keys pressed. - */ uint8_t pressedKeyswitchCount(); - - /** Key switch states - * - * These methods offer a way to peek at the key switch states, for those cases - * where we need to deal with the state closest to the hardware. Some methods - * offer a way to check if a key is pressed, others return the number of - * pressed keys. - */ - /** - * Check if a key is pressed at a given position. - * - * @param row is the row the key is located at in the matrix. - * @param col is the column the key is located at in the matrix. - * - * @returns true if the key is pressed, false otherwise. - */ bool isKeyswitchPressed(uint8_t row, byte col); - - /** - * Check if a key is pressed at a given position. - * - * @param keyIndex is the key index, as calculated by `keyIndex`. - * - * @note Key indexes start at 1, not 0! - * - * @returns true if the key is pressed, false otherwise. - */ bool isKeyswitchPressed(uint8_t keyIndex); - void actOnMatrixScan(); - void scanMatrix(); - - /* Key masking - * ----------- - * - * There are situations when one wants to ignore key events for a while, and - * mask them out. These functions help do that. In isolation, they do nothing, - * plugins and the core firmware is expected to make use of these. - * - * See `handleKeyswitchEvent` in the Kaleidoscope sources for a use-case. - */ void maskKey(byte row, byte col); void unMaskKey(byte row, byte col); bool isKeyMasked(byte row, byte col); diff --git a/src/kaleidoscope/hardware/ez/ErgoDox.h b/src/kaleidoscope/hardware/ez/ErgoDox.h index ff765d37..87249560 100644 --- a/src/kaleidoscope/hardware/ez/ErgoDox.h +++ b/src/kaleidoscope/hardware/ez/ErgoDox.h @@ -61,50 +61,12 @@ class ErgoDox : public kaleidoscope::Hardware { void actOnMatrixScan(void); void setup(); - /* Key masking - * ----------- - * - * There are situations when one wants to ignore key events for a while, and - * mask them out. These functions help do that. In isolation, they do nothing, - * plugins and the core firmware is expected to make use of these. - * - * See `handleKeyswitchEvent` in the Kaleidoscope sources for a use-case. - */ void maskKey(byte row, byte col); void unMaskKey(byte row, byte col); bool isKeyMasked(byte row, byte col); - /** Key switch states - * - * These methods offer a way to peek at the key switch states, for those cases - * where we need to deal with the state closest to the hardware. Some methods - * offer a way to check if a key is pressed, others return the number of - * pressed keys. - */ - /** - * Check if a key is pressed at a given position. - * - * @param row is the row the key is located at in the matrix. - * @param col is the column the key is located at in the matrix. - * - * @returns true if the key is pressed, false otherwise. - */ bool isKeyswitchPressed(byte row, byte col); - /** - * Check if a key is pressed at a given position. - * - * @param keyIndex is the key index, as calculated by `keyIndex`. - * - * @note Key indexes start at 1, not 0! - * - * @returns true if the key is pressed, false otherwise. - */ bool isKeyswitchPressed(uint8_t keyIndex); - /** - * Check the number of key switches currently pressed. - * - * @returns the number of keys pressed. - */ uint8_t pressedKeyswitchCount(); // ErgoDox-specific stuff diff --git a/src/kaleidoscope/hardware/keyboardio/Model01.h b/src/kaleidoscope/hardware/keyboardio/Model01.h index 0360e8cc..5457f87b 100644 --- a/src/kaleidoscope/hardware/keyboardio/Model01.h +++ b/src/kaleidoscope/hardware/keyboardio/Model01.h @@ -63,51 +63,13 @@ class Model01 : public kaleidoscope::Hardware { void setKeyscanInterval(uint8_t interval); boolean ledPowerFault(void); - /* Key masking - * ----------- - * - * There are situations when one wants to ignore key events for a while, and - * mask them out. These functions help do that. In isolation, they do nothing, - * plugins and the core firmware is expected to make use of these. - * - * See `handleKeyswitchEvent` in the Kaleidoscope sources for a use-case. - */ void maskKey(byte row, byte col); void unMaskKey(byte row, byte col); bool isKeyMasked(byte row, byte col); void maskHeldKeys(void); - /** Key switch states - * - * These methods offer a way to peek at the key switch states, for those cases - * where we need to deal with the state closest to the hardware. Some methods - * offer a way to check if a key is pressed, others return the number of - * pressed keys. - */ - /** - * Check if a key is pressed at a given position. - * - * @param row is the row the key is located at in the matrix. - * @param col is the column the key is located at in the matrix. - * - * @returns true if the key is pressed, false otherwise. - */ bool isKeyswitchPressed(byte row, byte col); - /** - * Check if a key is pressed at a given position. - * - * @param keyIndex is the key index, as calculated by `keyIndex`. - * - * @note Key indexes start at 1, not 0! - * - * @returns true if the key is pressed, false otherwise. - */ bool isKeyswitchPressed(uint8_t keyIndex); - /** - * Check the number of key switches currently pressed. - * - * @returns the number of keys pressed. - */ uint8_t pressedKeyswitchCount(); keydata_t leftHandState;