Implement debouncing

This adds a very simple debouncing algorithm for debouncing. It works by making
sure a key is not changing state more than a configurable amount of cycles.
Defaults to five cycles for now.

Fixes #1.

Signed-off-by: Gergely Nagy <algernon@keyboard.io>
pull/427/head^2
Gergely Nagy 7 years ago
parent 12ed823c2d
commit 596d3cf12e

@ -28,6 +28,8 @@ ErgoDoxScanner ErgoDox::scanner_;
uint8_t ErgoDox::previousKeyState_[ROWS]; uint8_t ErgoDox::previousKeyState_[ROWS];
uint8_t ErgoDox::keyState_[ROWS]; uint8_t ErgoDox::keyState_[ROWS];
uint8_t ErgoDox::masks_[ROWS]; uint8_t ErgoDox::masks_[ROWS];
uint8_t ErgoDox::debounce_matrix_[ROWS][COLS];
uint8_t ErgoDox::debounce = 5;
void ErgoDox::setup(void) { void ErgoDox::setup(void) {
wdt_disable(); wdt_disable();
@ -53,20 +55,23 @@ void ErgoDox::setup(void) {
setStatusLEDBrightness(3, 15); setStatusLEDBrightness(3, 15);
} }
void ErgoDox::readMatrix() { void ErgoDox::readMatrixRow(uint8_t row) {
for (uint8_t i = 0; i < ROWS / 2; i++) { uint8_t mask, cols;
scanner_.selectRow(i);
scanner_.selectRow(i + ROWS / 2);
// TODO(algernon): debouncing previousKeyState_[row] = keyState_[row];
mask = debounceMaskForRow(row);
cols = (scanner_.readCols(row) & mask) | (keyState_[row] & ~mask);
debounceRow(cols ^ keyState_[row], row);
keyState_[row] = cols;
}
// left side void ErgoDox::readMatrix() {
previousKeyState_[i] = keyState_[i]; for (uint8_t row = 0; row < ROWS / 2; row++) {
keyState_[i] = scanner_.readCols(i); scanner_.selectRow(row);
scanner_.selectRow(row + ROWS / 2);
// right side readMatrixRow(row);
previousKeyState_[i + ROWS / 2] = keyState_[i + ROWS / 2]; readMatrixRow(row + ROWS / 2);
keyState_[i + ROWS / 2] = scanner_.readCols(i + ROWS / 2);
scanner_.unselectRows(); scanner_.unselectRows();
} }
@ -159,6 +164,28 @@ void ErgoDox::resetDevice() {
asm volatile("jmp 0x7E00"); asm volatile("jmp 0x7E00");
} }
uint8_t ErgoDox::debounceMaskForRow(uint8_t row) {
uint8_t result = 0;
for (uint8_t c = 0; c < COLS; ++c) {
if (debounce_matrix_[row][c]) {
--debounce_matrix_[row][c];
} else {
result |= (1 << c);
}
}
return result;
}
void ErgoDox::debounceRow(uint8_t change, uint8_t row) {
for (uint8_t i = 0; i < COLS; ++i) {
if (change & (1 << i)) {
debounce_matrix_[row][i] = debounce;
}
}
}
} }
} }

@ -75,11 +75,18 @@ class ErgoDox {
void resetDevice(); void resetDevice();
static uint8_t debounce;
private: private:
static ErgoDoxScanner scanner_; static ErgoDoxScanner scanner_;
static uint8_t previousKeyState_[ROWS]; static uint8_t previousKeyState_[ROWS];
static uint8_t keyState_[ROWS]; static uint8_t keyState_[ROWS];
static uint8_t masks_[ROWS]; static uint8_t masks_[ROWS];
static uint8_t debounce_matrix_[ROWS][COLS];
static uint8_t debounceMaskForRow(uint8_t row);
static void debounceRow(uint8_t change, uint8_t row);
static void readMatrixRow(uint8_t row);
}; };
#define KEYMAP_STACKED( \ #define KEYMAP_STACKED( \

Loading…
Cancel
Save