Skip to content

Commit 111040f

Browse files
committed
fix: Add delay to DemuxKeyMatrix
1 parent 53f76c5 commit 111040f

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

shared-module/keypad_demux/DemuxKeyMatrix.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <string.h>
88

99
#include "py/gc.h"
10+
#include "py/mphal.h"
1011
#include "py/runtime.h"
1112
#include "shared-bindings/digitalio/DigitalInOut.h"
1213
#include "shared-bindings/keypad/EventQueue.h"
@@ -104,19 +105,31 @@ static void demuxkeymatrix_scan_now(void *self_in, mp_obj_t timestamp) {
104105
keypad_demux_demuxkeymatrix_obj_t *self = self_in;
105106

106107
for (size_t row = 0; row < common_hal_keypad_demux_demuxkeymatrix_get_row_count(self); row++) {
107-
// Set the row address on demultiplexer
108+
// Set the row address on the demultiplexer. This currently assumes an inverting
109+
// demux like the 74hc138 which outputs low on the selected line and high on non-selected ones.
110+
// This class should probably support a columns_to_anodes parameter where this case would
111+
// be True (the row gets pulled low), and a non-inverting demux like 74hc238 would
112+
// set columns_to_anodes=False.
108113
size_t mask = 0b00000001;
109114
for (size_t row_addr_pin = 0; row_addr_pin < self->row_addr_digitalinouts->len; row_addr_pin++) {
110115
digitalio_digitalinout_obj_t *dio = self->row_addr_digitalinouts->items[row_addr_pin];
111116
common_hal_digitalio_digitalinout_set_value(dio, (mask & row) != 0);
112117
mask = mask << 1;
113118
}
114119

120+
// Wait a moment to let the columns settle.
121+
// The normal KeyMatrix uses a 1us delay but that still gave echoes on my
122+
// nullbitsco nibble 65% (16 x 5 matrix). For example when key (row, col) is pressed
123+
// both (row, col) and (row+1, col) (and sometimes row+2) are registered,
124+
// especially when row+1 is a power of 2 (all mux bits change) and col is 0.
125+
// The QMK implementation for this keyboard uses a 5us delay which works here too
126+
mp_hal_delay_us(5);
127+
115128
for (size_t column = 0; column < common_hal_keypad_demux_demuxkeymatrix_get_column_count(self); column++) {
116129
mp_uint_t key_number = row_column_to_key_number(self, row, column);
117130

118131
// Get the current state, by reading whether the column got pulled to the row value or not.
119-
// If low, the key is pressed.
132+
// (with a columns_to_anodes parameter this could mimic the KeyMatrix code)
120133
const bool current = !common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]);
121134

122135
// Record any transitions.

0 commit comments

Comments
 (0)