Skip to content

Commit

Permalink
Merge pull request #4454 from trunneml/improveddebounce
Browse files Browse the repository at this point in the history
Adaptive debounce logic
  • Loading branch information
ezuk authored Nov 22, 2018
2 parents b7dd415 + ad91454 commit 48262bd
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
17 changes: 10 additions & 7 deletions keyboards/ergodox_ez/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

#define RGBW 1

/* "debounce" is measured in keyboard scans. Some users reported
* needing values as high as 15, which was at the time around 50ms.
/*
* The debounce filtering reports a key/switch change directly,
* without any extra delay. After that the debounce logic will filter
* all further changes, until the key/switch reports the same state for
* the given count of scans.
* So a perfect switch will get a short debounce period and
* a bad key will get a much longer debounce period.
* The result is an adaptive debouncing period for each switch.
*
* If you don't define it here, the matrix code will default to
* 5, which is now closer to 10ms, but still plenty according to
* manufacturer specs.
*
* Default is quite high, because of reports with some production
* runs seeming to need it. This may change when configuration for
* this is more directly exposed.
*/
#define DEBOUNCE 15
#define DEBOUNCE 10

#define USB_MAX_POWER_CONSUMPTION 500

Expand Down
49 changes: 28 additions & 21 deletions keyboards/ergodox_ez/matrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.

/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
/*
* matrix state(1:on, 0:off)
* contains the raw values without debounce filtering of the last read cycle.
*/
static matrix_row_t raw_matrix[MATRIX_ROWS];

// Debouncing: store for each key the number of scans until it's eligible to
// change. When scanning the matrix, ignore any changes in keys that have
Expand Down Expand Up @@ -118,6 +123,7 @@ void matrix_init(void)
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
raw_matrix[i] = 0;
for (uint8_t j=0; j < MATRIX_COLS; ++j) {
debounce_matrix[i * MATRIX_COLS + j] = 0;
}
Expand Down Expand Up @@ -151,26 +157,30 @@ void matrix_power_up(void) {

// Returns a matrix_row_t whose bits are set if the corresponding key should be
// eligible to change in this scan.
matrix_row_t debounce_mask(uint8_t row) {
matrix_row_t debounce_mask(matrix_row_t rawcols, uint8_t row) {
matrix_row_t result = 0;
for (uint8_t j=0; j < MATRIX_COLS; ++j) {
if (debounce_matrix[row * MATRIX_COLS + j]) {
--debounce_matrix[row * MATRIX_COLS + j];
matrix_row_t change = rawcols ^ raw_matrix[row];
raw_matrix[row] = rawcols;
for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
if (debounce_matrix[row * MATRIX_COLS + i]) {
--debounce_matrix[row * MATRIX_COLS + i];
} else {
result |= (1 << j);
result |= (1 << i);
}
}
return result;
}

// Report changed keys in the given row. Resets the debounce countdowns
// corresponding to each set bit in 'change' to DEBOUNCE.
void debounce_report(matrix_row_t change, uint8_t row) {
for (uint8_t i = 0; i < MATRIX_COLS; ++i) {
if (change & (1 << i)) {
debounce_matrix[row * MATRIX_COLS + i] = DEBOUNCE;
}
}
return result;
}

matrix_row_t debounce_read_cols(uint8_t row) {
// Read the row without debouncing filtering and store it for later usage.
matrix_row_t cols = read_cols(row);
// Get the Debounce mask.
matrix_row_t mask = debounce_mask(cols, row);
// debounce the row and return the result.
return (cols & mask) | (matrix[row] & ~mask);;
}

uint8_t matrix_scan(void)
Expand Down Expand Up @@ -214,15 +224,12 @@ uint8_t matrix_scan(void)
select_row(i + MATRIX_ROWS_PER_SIDE);
// we don't need a 30us delay anymore, because selecting a
// left-hand row requires more than 30us for i2c.
matrix_row_t mask = debounce_mask(i);
matrix_row_t cols = (read_cols(i) & mask) | (matrix[i] & ~mask);
debounce_report(cols ^ matrix[i], i);
matrix[i] = cols;

// grab cols from left hand
matrix[i] = debounce_read_cols(i);
// grab cols from right hand
mask = debounce_mask(i + MATRIX_ROWS_PER_SIDE);
cols = (read_cols(i + MATRIX_ROWS_PER_SIDE) & mask) | (matrix[i + MATRIX_ROWS_PER_SIDE] & ~mask);
debounce_report(cols ^ matrix[i + MATRIX_ROWS_PER_SIDE], i + MATRIX_ROWS_PER_SIDE);
matrix[i + MATRIX_ROWS_PER_SIDE] = cols;
matrix[i + MATRIX_ROWS_PER_SIDE] = debounce_read_cols(i + MATRIX_ROWS_PER_SIDE);

unselect_rows();
}

Expand Down

0 comments on commit 48262bd

Please sign in to comment.