Merge pull request #595 from keyboardio/f/GenericTestMode

A more widely usable version of the Model01 test mode
pull/618/head
Jesse Vincent 6 years ago committed by GitHub
commit bd05be4974
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,19 @@
/* Kaleidoscope-Hardware-TestMode - A factory test mode for the Model 01.
* Copyright (C) 2017-2019 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "kaleidoscope/plugin/HardwareTestMode.h"

@ -253,6 +253,40 @@ class Hardware {
return 0; return 0;
} }
/**
* Check if a key was pressed at a given position on the previous scan
*
* @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 was pressed, false otherwise.
*/
bool wasKeyswitchPressed(byte row, byte col) {
return false;
}
/**
* Check if a key was pressed at a given position on the previous scan.
*
* @param keyIndex is the key index, as calculated by `keyIndex`.
*
* @note Key indexes start at 1, not 0!
*
* @returns true if the key was pressed, false otherwise.
*/
bool wasKeyswitchPressed(uint8_t keyIndex) {
return false;
}
/**
* Check the number of key switches pressed in the previous scan.
*
* @returns the number of keys pressed.
*/
uint8_t previousPressedKeyswitchCount() {
return 0;
}
/** @} */ /** @} */
/** /**
@ -266,6 +300,16 @@ class Hardware {
* bring it up into a useful state. * bring it up into a useful state.
*/ */
void setup() {} void setup() {}
/**
* Method to configure the device for a hardware test mode
*
* Called by the Kaleidoscope Hardware test plugin, this method should
* do any device-specific initialization needed for factory hardware testing
*
*/
void enableHardwareTestMode() {}
/** @} */ /** @} */
}; };
} }

@ -85,6 +85,28 @@ bool ATMegaKeyboard::isKeyswitchPressed(uint8_t keyIndex) {
keyIndex % KeyboardHardware.matrix_columns); keyIndex % KeyboardHardware.matrix_columns);
} }
uint8_t ATMegaKeyboard::previousPressedKeyswitchCount() {
uint8_t count = 0;
for (int8_t r = 0; r < KeyboardHardware.matrix_rows; r++) {
count += __builtin_popcount(KeyboardHardware.previousKeyState_[r]);
}
return count;
}
bool ATMegaKeyboard::wasKeyswitchPressed(uint8_t row, byte col) {
return (bitRead(KeyboardHardware.previousKeyState_[row], col) != 0);
}
bool ATMegaKeyboard::wasKeyswitchPressed(uint8_t keyIndex) {
keyIndex--;
return wasKeyswitchPressed(keyIndex / KeyboardHardware.matrix_columns,
keyIndex % KeyboardHardware.matrix_columns);
}
void __attribute__((optimize(3))) ATMegaKeyboard::actOnMatrixScan() { void __attribute__((optimize(3))) ATMegaKeyboard::actOnMatrixScan() {
for (byte row = 0; row < KeyboardHardware.matrix_rows; row++) { for (byte row = 0; row < KeyboardHardware.matrix_rows; row++) {
for (byte col = 0; col < KeyboardHardware.matrix_columns; col++) { for (byte col = 0; col < KeyboardHardware.matrix_columns; col++) {

@ -87,6 +87,10 @@ class ATMegaKeyboard : public kaleidoscope::Hardware {
bool isKeyswitchPressed(uint8_t row, byte col); bool isKeyswitchPressed(uint8_t row, byte col);
bool isKeyswitchPressed(uint8_t keyIndex); bool isKeyswitchPressed(uint8_t keyIndex);
uint8_t previousPressedKeyswitchCount();
bool wasKeyswitchPressed(uint8_t row, byte col);
bool wasKeyswitchPressed(uint8_t keyIndex);
void maskKey(byte row, byte col); void maskKey(byte row, byte col);
void unMaskKey(byte row, byte col); void unMaskKey(byte row, byte col);
bool isKeyMasked(byte row, byte col); bool isKeyMasked(byte row, byte col);

@ -232,6 +232,24 @@ bool ErgoDox::isKeyswitchPressed(uint8_t keyIndex) {
return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS);
} }
bool ErgoDox::wasKeyswitchPressed(byte row, byte col) {
return (bitRead(previousKeyState_[row], col) != 0);
}
bool ErgoDox::wasKeyswitchPressed(uint8_t keyIndex) {
keyIndex--;
return wasKeyswitchPressed(keyIndex / COLS, keyIndex % COLS);
}
uint8_t ErgoDox::previousPressedKeyswitchCount() {
uint8_t count = 0;
for (uint8_t r = 0; r < ROWS; r++) {
count += __builtin_popcount(previousKeyState_[r]);
}
return count;
}
uint8_t ErgoDox::pressedKeyswitchCount() { uint8_t ErgoDox::pressedKeyswitchCount() {
uint8_t count = 0; uint8_t count = 0;

@ -69,6 +69,10 @@ class ErgoDox : public kaleidoscope::Hardware {
bool isKeyswitchPressed(uint8_t keyIndex); bool isKeyswitchPressed(uint8_t keyIndex);
uint8_t pressedKeyswitchCount(); uint8_t pressedKeyswitchCount();
bool wasKeyswitchPressed(byte row, byte col);
bool wasKeyswitchPressed(uint8_t keyIndex);
uint8_t previousPressedKeyswitchCount();
// ErgoDox-specific stuff // ErgoDox-specific stuff
void setStatusLED(uint8_t led, bool state = true); void setStatusLED(uint8_t led, bool state = true);
void setStatusLEDBrightness(uint8_t led, uint8_t brightness); void setStatusLEDBrightness(uint8_t led, uint8_t brightness);

@ -85,6 +85,17 @@ void Model01::setup(void) {
TWBR = 12; // This is 400mhz, which is the fastest we can drive the ATTiny TWBR = 12; // This is 400mhz, which is the fastest we can drive the ATTiny
} }
void Model01::enableHardwareTestMode() {
// Toggle the programming LEDS on
PORTD |= (1 << 5);
PORTB |= (1 << 0);
// Disable the debouncer on the ATTinys
KeyboardHardware.setKeyscanInterval(2);
}
void Model01::setCrgbAt(int8_t i, cRGB crgb) { void Model01::setCrgbAt(int8_t i, cRGB crgb) {
if (i < 0) { if (i < 0) {
@ -305,10 +316,28 @@ bool Model01::isKeyswitchPressed(uint8_t keyIndex) {
return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS); return isKeyswitchPressed(keyIndex / COLS, keyIndex % COLS);
} }
bool Model01::wasKeyswitchPressed(byte row, byte col) {
if (col <= 7) {
return (bitRead(previousLeftHandState.rows[row], 7 - col) != 0);
} else {
return (bitRead(previousRightHandState.rows[row], 7 - (col - 8)) != 0);
}
}
bool Model01::wasKeyswitchPressed(uint8_t keyIndex) {
keyIndex--;
return wasKeyswitchPressed(keyIndex / COLS, keyIndex % COLS);
}
uint8_t Model01::pressedKeyswitchCount() { uint8_t Model01::pressedKeyswitchCount() {
return __builtin_popcountl(leftHandState.all) + __builtin_popcountl(rightHandState.all); return __builtin_popcountl(leftHandState.all) + __builtin_popcountl(rightHandState.all);
} }
uint8_t Model01::previousPressedKeyswitchCount() {
return __builtin_popcountl(previousLeftHandState.all) + __builtin_popcountl(previousRightHandState.all);
}
} }
} }
} }

@ -72,6 +72,12 @@ class Model01 : public kaleidoscope::Hardware {
bool isKeyswitchPressed(uint8_t keyIndex); bool isKeyswitchPressed(uint8_t keyIndex);
uint8_t pressedKeyswitchCount(); uint8_t pressedKeyswitchCount();
bool wasKeyswitchPressed(byte row, byte col);
bool wasKeyswitchPressed(uint8_t keyIndex);
uint8_t previousPressedKeyswitchCount();
void enableHardwareTestMode();
keydata_t leftHandState; keydata_t leftHandState;
keydata_t rightHandState; keydata_t rightHandState;
keydata_t previousLeftHandState; keydata_t previousLeftHandState;

@ -0,0 +1,129 @@
/* Kaleidoscope-HardwareTestMode - A factory test mode for the Model 01.
* Copyright (C) 2017-2019 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 <http://www.gnu.org/licenses/>.
*/
#include "Kaleidoscope.h"
#include "Kaleidoscope-HardwareTestMode.h"
#include "Kaleidoscope-LEDEffect-Rainbow.h"
namespace kaleidoscope {
namespace plugin {
constexpr uint8_t CHATTER_CYCLE_LIMIT = 30;
uint8_t HardwareTestMode::actionKey;
void HardwareTestMode::setActionKey(uint8_t key) {
actionKey = key;
}
void HardwareTestMode::waitForKeypress() {
while (1) {
KeyboardHardware.readMatrix();
if (KeyboardHardware.isKeyswitchPressed(actionKey) &&
! KeyboardHardware.wasKeyswitchPressed(actionKey)) {
break;
}
}
}
void HardwareTestMode::setLeds(cRGB color) {
::LEDControl.set_all_leds_to(color);
::LEDControl.syncLeds();
waitForKeypress();
}
void HardwareTestMode::testLeds(void) {
constexpr cRGB red = CRGB(201, 0, 0);
constexpr cRGB blue = CRGB(0, 0, 201);
constexpr cRGB green = CRGB(0, 201, 0);
constexpr cRGB brightWhite = CRGB(160, 160, 160);
setLeds(brightWhite);
setLeds(blue);
setLeds(green);
setLeds(red);
// rainbow for 10 seconds
::LEDRainbowEffect.update_delay(5);
for (auto i = 0; i < 300; i++) {
::LEDRainbowEffect.update();
::LEDControl.syncLeds();
}
}
void HardwareTestMode::testMatrix() {
// Reset bad keys from previous tests.
chatter_data state[KeyboardHardware.matrix_columns * KeyboardHardware.matrix_rows] = {0, 0, 0};
constexpr cRGB red = CRGB(201, 0, 0);
constexpr cRGB blue = CRGB(0, 0, 201);
constexpr cRGB green = CRGB(0, 201, 0);
constexpr cRGB yellow = CRGB(201, 100, 0);
while (1) {
KeyboardHardware.readMatrix();
for (byte row = 0; row < KeyboardHardware.matrix_rows; row++) {
for (byte col = 0; col < KeyboardHardware.matrix_columns; col++) {
uint8_t keynum = (row * KeyboardHardware.matrix_columns) + (col);
// If the key is toggled on
if (KeyboardHardware.isKeyswitchPressed(row, col) && ! KeyboardHardware.wasKeyswitchPressed(row, col)) {
// And it's too soon (in terms of cycles between changes)
state[keynum].tested = 1;
if (state[keynum].cyclesSinceStateChange < CHATTER_CYCLE_LIMIT) {
state[keynum].bad = 1;
}
state[keynum].cyclesSinceStateChange = 0;
} else if (state[keynum].cyclesSinceStateChange < CHATTER_CYCLE_LIMIT) {
state[keynum].cyclesSinceStateChange++;
}
// If the key is held down
if (KeyboardHardware.isKeyswitchPressed(row, col) && KeyboardHardware.wasKeyswitchPressed(row, col)) {
KeyboardHardware.setCrgbAt(row, col, green);
}
// If we triggered chatter detection ever on this key
else if (state[keynum].bad == 1) {
KeyboardHardware.setCrgbAt(row, col, red);
} else if (state[keynum].tested == 0) {
KeyboardHardware.setCrgbAt(row, col, yellow);
}
// If the key is not currently pressed and was not just released and is not marked bad
else if (! KeyboardHardware.isKeyswitchPressed(row, col)) {
KeyboardHardware.setCrgbAt(row, col, blue);
}
}
}
::LEDControl.syncLeds();
}
}
void HardwareTestMode::runTests() {
// When we start test mode, we -may- have some keys held, so empty it
// out and send a new report
kaleidoscope::hid::releaseAllKeys();
kaleidoscope::hid::sendKeyboardReport();
KeyboardHardware.enableHardwareTestMode();
testLeds();
testMatrix();
}
}
}
kaleidoscope::plugin::HardwareTestMode HardwareTestMode;

@ -0,0 +1,49 @@
/* Kaleidoscope-HardwareTestMode - A factory test mode for the Model 01.
* Copyright (C) 2017-2019 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Arduino.h>
#include "Kaleidoscope.h"
namespace kaleidoscope {
namespace plugin {
class HardwareTestMode : public kaleidoscope::Plugin {
public:
typedef struct {
uint8_t bad : 1,
tested : 1,
cyclesSinceStateChange: 6;
} chatter_data;
static uint8_t actionKey;
HardwareTestMode(void) {}
static void runTests();
static void setActionKey(uint8_t key);
private:
static void testLeds();
static void testMatrix();
static void toggleProgrammingLedsOn();
static void waitForKeypress();
static void setLeds(cRGB color);
};
}
}
extern kaleidoscope::plugin::HardwareTestMode HardwareTestMode;
Loading…
Cancel
Save