|
7 | 7 | #include <string.h>
|
8 | 8 |
|
9 | 9 | #include "py/gc.h"
|
| 10 | +#include "py/mphal.h" |
10 | 11 | #include "py/runtime.h"
|
11 | 12 | #include "shared-bindings/digitalio/DigitalInOut.h"
|
12 | 13 | #include "shared-bindings/keypad/EventQueue.h"
|
@@ -104,19 +105,31 @@ static void demuxkeymatrix_scan_now(void *self_in, mp_obj_t timestamp) {
|
104 | 105 | keypad_demux_demuxkeymatrix_obj_t *self = self_in;
|
105 | 106 |
|
106 | 107 | 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. |
108 | 113 | size_t mask = 0b00000001;
|
109 | 114 | for (size_t row_addr_pin = 0; row_addr_pin < self->row_addr_digitalinouts->len; row_addr_pin++) {
|
110 | 115 | digitalio_digitalinout_obj_t *dio = self->row_addr_digitalinouts->items[row_addr_pin];
|
111 | 116 | common_hal_digitalio_digitalinout_set_value(dio, (mask & row) != 0);
|
112 | 117 | mask = mask << 1;
|
113 | 118 | }
|
114 | 119 |
|
| 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 | + |
115 | 128 | for (size_t column = 0; column < common_hal_keypad_demux_demuxkeymatrix_get_column_count(self); column++) {
|
116 | 129 | mp_uint_t key_number = row_column_to_key_number(self, row, column);
|
117 | 130 |
|
118 | 131 | // 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) |
120 | 133 | const bool current = !common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]);
|
121 | 134 |
|
122 | 135 | // Record any transitions.
|
|
0 commit comments