Add state integration based debouncing to the keypad module
This commit is contained in:
parent
50c504dfdf
commit
3e184e994c
14 changed files with 83 additions and 61 deletions
|
|
@ -59,6 +59,7 @@
|
|||
//| columns_to_anodes: bool = True,
|
||||
//| interval: float = 0.020,
|
||||
//| max_events: int = 64,
|
||||
//| debounce_threshold: int = 1,
|
||||
//| ) -> None:
|
||||
//| """
|
||||
//| Create a `Keys` object that will scan the key matrix attached to the given row and column pins.
|
||||
|
|
@ -82,19 +83,24 @@
|
|||
//| maximum number of key transition events that are saved.
|
||||
//| Must be >= 1.
|
||||
//| If a new event arrives when the queue is full, the oldest event is discarded.
|
||||
//| :param int debounce_threshold: Emit events for state changes only after a key has been
|
||||
//| in the respective state for ``debounce_threshold`` times on average.
|
||||
//| Successive measurements are spaced apart by ``interval`` seconds.
|
||||
//| The default is 1, which resolves immediately. The maximum is 127.
|
||||
//| """
|
||||
//| ...
|
||||
|
||||
STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
#if CIRCUITPY_KEYPAD_KEYMATRIX
|
||||
keypad_keymatrix_obj_t *self = mp_obj_malloc(keypad_keymatrix_obj_t, &keypad_keymatrix_type);
|
||||
enum { ARG_row_pins, ARG_column_pins, ARG_columns_to_anodes, ARG_interval, ARG_max_events };
|
||||
enum { ARG_row_pins, ARG_column_pins, ARG_columns_to_anodes, ARG_interval, ARG_max_events, ARG_debounce_threshold };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_row_pins, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_column_pins, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_columns_to_anodes, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
|
||||
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_max_events, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
|
||||
{ MP_QSTR_debounce_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
|
@ -109,6 +115,7 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar
|
|||
const mp_float_t interval =
|
||||
mp_arg_validate_obj_float_non_negative(args[ARG_interval].u_obj, 0.020f, MP_QSTR_interval);
|
||||
const size_t max_events = (size_t)mp_arg_validate_int_min(args[ARG_max_events].u_int, 1, MP_QSTR_max_events);
|
||||
const uint8_t debounce_threshold = (uint8_t)mp_arg_validate_int_range(args[ARG_debounce_threshold].u_int, 1, 127, MP_QSTR_debounce_threshold);
|
||||
|
||||
const mcu_pin_obj_t *row_pins_array[num_row_pins];
|
||||
const mcu_pin_obj_t *column_pins_array[num_column_pins];
|
||||
|
|
@ -127,7 +134,7 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar
|
|||
column_pins_array[column] = pin;
|
||||
}
|
||||
|
||||
common_hal_keypad_keymatrix_construct(self, num_row_pins, row_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, interval, max_events);
|
||||
common_hal_keypad_keymatrix_construct(self, num_row_pins, row_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, interval, max_events, debounce_threshold);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
#else
|
||||
mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_KeyMatrix);
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
extern const mp_obj_type_t keypad_keymatrix_type;
|
||||
|
||||
void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint_t num_row_pins, const mcu_pin_obj_t *row_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, mp_float_t interval, size_t max_events);
|
||||
void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint_t num_row_pins, const mcu_pin_obj_t *row_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, mp_float_t interval, size_t max_events, uint8_t debounce_threshold);
|
||||
|
||||
void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@
|
|||
//| value_when_pressed: bool,
|
||||
//| pull: bool = True,
|
||||
//| interval: float = 0.020,
|
||||
//| max_events: int = 64
|
||||
//| max_events: int = 64,
|
||||
//| debounce_threshold: int = 1,
|
||||
//| ) -> None:
|
||||
//| """
|
||||
//| Create a `Keys` object that will scan keys attached to the given sequence of pins.
|
||||
|
|
@ -84,19 +85,24 @@
|
|||
//| maximum number of key transition events that are saved.
|
||||
//| Must be >= 1.
|
||||
//| If a new event arrives when the queue is full, the oldest event is discarded.
|
||||
//| :param int debounce_threshold: Emit events for state changes only after a key has been
|
||||
//| in the respective state for ``debounce_threshold`` times on average.
|
||||
//| Successive measurements are spaced apart by ``interval`` seconds.
|
||||
//| The default is 1, which resolves immediately. The maximum is 127.
|
||||
//| """
|
||||
//| ...
|
||||
|
||||
STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
#if CIRCUITPY_KEYPAD_KEYS
|
||||
keypad_keys_obj_t *self = mp_obj_malloc(keypad_keys_obj_t, &keypad_keys_type);
|
||||
enum { ARG_pins, ARG_value_when_pressed, ARG_pull, ARG_interval, ARG_max_events };
|
||||
enum { ARG_pins, ARG_value_when_pressed, ARG_pull, ARG_interval, ARG_max_events, ARG_debounce_threshold };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_pins, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_value_when_pressed, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_BOOL },
|
||||
{ MP_QSTR_pull, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
|
||||
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL } },
|
||||
{ MP_QSTR_max_events, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
|
||||
{ MP_QSTR_debounce_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
|
@ -110,6 +116,7 @@ STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, s
|
|||
const mp_float_t interval =
|
||||
mp_arg_validate_obj_float_non_negative(args[ARG_interval].u_obj, 0.020f, MP_QSTR_interval);
|
||||
const size_t max_events = (size_t)mp_arg_validate_int_min(args[ARG_max_events].u_int, 1, MP_QSTR_max_events);
|
||||
const uint8_t debounce_threshold = (uint8_t)mp_arg_validate_int_range(args[ARG_debounce_threshold].u_int, 1, 127, MP_QSTR_debounce_threshold);
|
||||
|
||||
const mcu_pin_obj_t *pins_array[num_pins];
|
||||
|
||||
|
|
@ -118,7 +125,7 @@ STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, s
|
|||
validate_obj_is_free_pin(mp_obj_subscr(pins, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL), MP_QSTR_pin);
|
||||
}
|
||||
|
||||
common_hal_keypad_keys_construct(self, num_pins, pins_array, value_when_pressed, args[ARG_pull].u_bool, interval, max_events);
|
||||
common_hal_keypad_keys_construct(self, num_pins, pins_array, value_when_pressed, args[ARG_pull].u_bool, interval, max_events, debounce_threshold);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
extern const mp_obj_type_t keypad_keys_type;
|
||||
|
||||
void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pins, const mcu_pin_obj_t *pins[], bool value_when_pressed, bool pull, mp_float_t interval, size_t max_events);
|
||||
void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pins, const mcu_pin_obj_t *pins[], bool value_when_pressed, bool pull, mp_float_t interval, size_t max_events, uint8_t debounce_threshold);
|
||||
|
||||
void common_hal_keypad_keys_deinit(keypad_keys_obj_t *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,8 @@
|
|||
//| key_count: Union[int, Sequence[int]],
|
||||
//| value_when_pressed: bool,
|
||||
//| interval: float = 0.020,
|
||||
//| max_events: int = 64
|
||||
//| max_events: int = 64,
|
||||
//| debounce_threshold: int = 1,
|
||||
//| ) -> None:
|
||||
//| """
|
||||
//| Create a `Keys` object that will scan keys attached to a parallel-in serial-out shift register
|
||||
|
|
@ -95,6 +96,10 @@
|
|||
//| maximum number of key transition events that are saved.
|
||||
//| Must be >= 1.
|
||||
//| If a new event arrives when the queue is full, the oldest event is discarded.
|
||||
//| :param int debounce_threshold: Emit events for state changes only after a key has been
|
||||
//| in the respective state for ``debounce_threshold`` times on average.
|
||||
//| Successive measurements are spaced apart by ``interval`` seconds.
|
||||
//| The default is 1, which resolves immediately. The maximum is 127.
|
||||
//| """
|
||||
//| ...
|
||||
|
||||
|
|
@ -102,7 +107,7 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz
|
|||
#if CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS
|
||||
keypad_shiftregisterkeys_obj_t *self =
|
||||
mp_obj_malloc(keypad_shiftregisterkeys_obj_t, &keypad_shiftregisterkeys_type);
|
||||
enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_key_count, ARG_value_when_pressed, ARG_interval, ARG_max_events };
|
||||
enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_key_count, ARG_value_when_pressed, ARG_interval, ARG_max_events, ARG_debounce_threshold };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_clock, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
|
|
@ -112,6 +117,7 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz
|
|||
{ MP_QSTR_value_when_pressed, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_BOOL },
|
||||
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_max_events, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
|
||||
{ MP_QSTR_debounce_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
|
@ -168,9 +174,10 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz
|
|||
const mp_float_t interval =
|
||||
mp_arg_validate_obj_float_non_negative(args[ARG_interval].u_obj, 0.020f, MP_QSTR_interval);
|
||||
const size_t max_events = (size_t)mp_arg_validate_int_min(args[ARG_max_events].u_int, 1, MP_QSTR_max_events);
|
||||
const uint8_t debounce_threshold = (uint8_t)mp_arg_validate_int_range(args[ARG_debounce_threshold].u_int, 1, 127, MP_QSTR_debounce_threshold);
|
||||
|
||||
common_hal_keypad_shiftregisterkeys_construct(
|
||||
self, clock, num_data_pins, data_pins_array, latch, value_to_latch, num_key_counts, key_count_array, value_when_pressed, interval, max_events);
|
||||
self, clock, num_data_pins, data_pins_array, latch, value_to_latch, num_key_counts, key_count_array, value_when_pressed, interval, max_events, debounce_threshold);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
extern const mp_obj_type_t keypad_shiftregisterkeys_type;
|
||||
|
||||
void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, const mcu_pin_obj_t *clock_pin, mp_uint_t num_data_pins, const mcu_pin_obj_t *data_pins[], const mcu_pin_obj_t *latch_pin, bool value_to_latch, size_t num_key_count, size_t key_counts[], bool value_when_pressed, mp_float_t interval, size_t max_events);
|
||||
void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, const mcu_pin_obj_t *clock_pin, mp_uint_t num_data_pins, const mcu_pin_obj_t *data_pins[], const mcu_pin_obj_t *latch_pin, bool value_to_latch, size_t num_key_count, size_t key_counts[], bool value_when_pressed, mp_float_t interval, size_t max_events, uint8_t debounce_threshold);
|
||||
|
||||
void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
//| column_pins: Sequence[microcontroller.Pin],
|
||||
//| interval: float = 0.020,
|
||||
//| max_events: int = 64,
|
||||
//| debounce_threshold: int = 1,
|
||||
//| ) -> None:
|
||||
//| """
|
||||
//| Create a `keypad.Keys` object that will scan the key matrix attached to the given row and column pins.
|
||||
|
|
@ -77,17 +78,22 @@
|
|||
//| maximum number of key transition events that are saved.
|
||||
//| Must be >= 1.
|
||||
//| If a new event arrives when the queue is full, the oldest event is discarded.
|
||||
//| :param int debounce_threshold: Emit events for state changes only after a key has been
|
||||
//| in the respective state for ``debounce_threshold`` times on average.
|
||||
//| Successive measurements are spaced apart by ``interval`` seconds.
|
||||
//| The default is 1, which resolves immediately. The maximum is 127.
|
||||
//| """
|
||||
//| ...
|
||||
|
||||
STATIC mp_obj_t keypad_demux_demuxkeymatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
keypad_demux_demuxkeymatrix_obj_t *self = mp_obj_malloc(keypad_demux_demuxkeymatrix_obj_t, &keypad_demux_demuxkeymatrix_type);
|
||||
enum { ARG_row_addr_pins, ARG_column_pins, ARG_interval, ARG_max_events };
|
||||
enum { ARG_row_addr_pins, ARG_column_pins, ARG_interval, ARG_max_events, ARG_debounce_threshold };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_row_addr_pins, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_column_pins, MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_max_events, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} },
|
||||
{ MP_QSTR_debounce_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
|
@ -102,6 +108,7 @@ STATIC mp_obj_t keypad_demux_demuxkeymatrix_make_new(const mp_obj_type_t *type,
|
|||
const mp_float_t interval =
|
||||
mp_arg_validate_obj_float_non_negative(args[ARG_interval].u_obj, 0.020f, MP_QSTR_interval);
|
||||
const size_t max_events = (size_t)mp_arg_validate_int_min(args[ARG_max_events].u_int, 1, MP_QSTR_max_events);
|
||||
const uint8_t debounce_threshold = (uint8_t)mp_arg_validate_int_range(args[ARG_debounce_threshold].u_int, 1, 127, MP_QSTR_debounce_threshold);
|
||||
|
||||
const mcu_pin_obj_t *row_addr_pins_array[num_row_addr_pins];
|
||||
const mcu_pin_obj_t *column_pins_array[num_column_pins];
|
||||
|
|
@ -120,7 +127,7 @@ STATIC mp_obj_t keypad_demux_demuxkeymatrix_make_new(const mp_obj_type_t *type,
|
|||
column_pins_array[column] = pin;
|
||||
}
|
||||
|
||||
common_hal_keypad_demux_demuxkeymatrix_construct(self, num_row_addr_pins, row_addr_pins_array, num_column_pins, column_pins_array, interval, max_events);
|
||||
common_hal_keypad_demux_demuxkeymatrix_construct(self, num_row_addr_pins, row_addr_pins_array, num_column_pins, column_pins_array, interval, max_events, debounce_threshold);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
extern const mp_obj_type_t keypad_demux_demuxkeymatrix_type;
|
||||
|
||||
void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], mp_float_t interval, size_t max_events);
|
||||
void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], mp_float_t interval, size_t max_events, uint8_t debounce_threshold);
|
||||
|
||||
void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_obj_t *self);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ static mp_uint_t row_column_to_key_number(keypad_keymatrix_obj_t *self, mp_uint_
|
|||
return row * self->column_digitalinouts->len + column;
|
||||
}
|
||||
|
||||
void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint_t num_row_pins, const mcu_pin_obj_t *row_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, mp_float_t interval, size_t max_events) {
|
||||
void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint_t num_row_pins, const mcu_pin_obj_t *row_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) {
|
||||
|
||||
mp_obj_t row_dios[num_row_pins];
|
||||
for (size_t row = 0; row < num_row_pins; row++) {
|
||||
|
|
@ -72,13 +72,10 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint
|
|||
}
|
||||
self->column_digitalinouts = mp_obj_new_tuple(num_column_pins, column_dios);
|
||||
|
||||
self->currently_pressed = (bool *)m_malloc(sizeof(bool) * num_row_pins * num_column_pins);
|
||||
self->previously_pressed = (bool *)m_malloc(sizeof(bool) * num_row_pins * num_column_pins);
|
||||
|
||||
self->columns_to_anodes = columns_to_anodes;
|
||||
self->funcs = &keymatrix_funcs;
|
||||
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events);
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold);
|
||||
}
|
||||
|
||||
void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self) {
|
||||
|
|
@ -138,8 +135,6 @@ static void keymatrix_scan_now(void *self_in, mp_obj_t timestamp) {
|
|||
|
||||
for (size_t column = 0; column < common_hal_keypad_keymatrix_get_column_count(self); column++) {
|
||||
mp_uint_t key_number = row_column_to_key_number(self, row, column);
|
||||
const bool previous = self->currently_pressed[key_number];
|
||||
self->previously_pressed[key_number] = previous;
|
||||
|
||||
// Get the current state, by reading whether the column got pulled to the row value or not.
|
||||
// If low and columns_to_anodes is true, the key is pressed.
|
||||
|
|
@ -147,10 +142,9 @@ static void keymatrix_scan_now(void *self_in, mp_obj_t timestamp) {
|
|||
const bool current =
|
||||
common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]) !=
|
||||
self->columns_to_anodes;
|
||||
self->currently_pressed[key_number] = current;
|
||||
|
||||
// Record any transitions.
|
||||
if (previous != current) {
|
||||
if (keypad_debounce((keypad_scanner_obj_t *)self, key_number, current)) {
|
||||
keypad_eventqueue_record(self->events, key_number, current, timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static keypad_scanner_funcs_t keys_funcs = {
|
|||
.get_key_count = keys_get_key_count,
|
||||
};
|
||||
|
||||
void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pins, const mcu_pin_obj_t *pins[], bool value_when_pressed, bool pull, mp_float_t interval, size_t max_events) {
|
||||
void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pins, const mcu_pin_obj_t *pins[], bool value_when_pressed, bool pull, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) {
|
||||
mp_obj_t dios[num_pins];
|
||||
|
||||
for (size_t i = 0; i < num_pins; i++) {
|
||||
|
|
@ -58,12 +58,10 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin
|
|||
}
|
||||
|
||||
self->digitalinouts = mp_obj_new_tuple(num_pins, dios);
|
||||
self->currently_pressed = (bool *)m_malloc(sizeof(bool) * num_pins);
|
||||
self->previously_pressed = (bool *)m_malloc(sizeof(bool) * num_pins);
|
||||
self->value_when_pressed = value_when_pressed;
|
||||
self->funcs = &keys_funcs;
|
||||
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events);
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -93,18 +91,13 @@ static void keypad_keys_scan_now(void *self_in, mp_obj_t timestamp) {
|
|||
size_t key_count = keys_get_key_count(self);
|
||||
|
||||
for (mp_uint_t key_number = 0; key_number < key_count; key_number++) {
|
||||
// Remember the previous up/down state.
|
||||
const bool previous = self->currently_pressed[key_number];
|
||||
self->previously_pressed[key_number] = previous;
|
||||
|
||||
// Get the current state.
|
||||
const bool current =
|
||||
common_hal_digitalio_digitalinout_get_value(self->digitalinouts->items[key_number]) ==
|
||||
self->value_when_pressed;
|
||||
self->currently_pressed[key_number] = current;
|
||||
|
||||
// Record any transitions.
|
||||
if (previous != current) {
|
||||
if (keypad_debounce((keypad_scanner_obj_t *)self, key_number, current)) {
|
||||
keypad_eventqueue_record(self->events, key_number, current, timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ static keypad_scanner_funcs_t shiftregisterkeys_funcs = {
|
|||
.get_key_count = shiftregisterkeys_get_key_count,
|
||||
};
|
||||
|
||||
void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, const mcu_pin_obj_t *clock_pin, mp_uint_t num_data_pins, const mcu_pin_obj_t *data_pins[], const mcu_pin_obj_t *latch_pin, bool value_to_latch, mp_uint_t num_key_counts, size_t key_counts[], bool value_when_pressed, mp_float_t interval, size_t max_events) {
|
||||
void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, const mcu_pin_obj_t *clock_pin, mp_uint_t num_data_pins, const mcu_pin_obj_t *data_pins[], const mcu_pin_obj_t *latch_pin, bool value_to_latch, mp_uint_t num_key_counts, size_t key_counts[], bool value_when_pressed, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) {
|
||||
|
||||
digitalio_digitalinout_obj_t *clock =
|
||||
mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type);
|
||||
|
|
@ -94,7 +94,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_
|
|||
self->value_when_pressed = value_when_pressed;
|
||||
self->funcs = &shiftregisterkeys_funcs;
|
||||
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events);
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold);
|
||||
}
|
||||
|
||||
void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self) {
|
||||
|
|
@ -143,7 +143,7 @@ static void shiftregisterkeys_scan_now(void *self_in, mp_obj_t timestamp) {
|
|||
for (mp_uint_t scan_number = 0; scan_number < self->max_key_count; scan_number++) {
|
||||
common_hal_digitalio_digitalinout_set_value(self->clock, false);
|
||||
|
||||
// Zero-th data appears on on the data pin immediately, without shifting.
|
||||
// Zero-th data appears on the data pin immediately, without shifting.
|
||||
|
||||
// Loop through all the data pins that share the latch
|
||||
mp_uint_t index = 0;
|
||||
|
|
@ -157,17 +157,13 @@ static void shiftregisterkeys_scan_now(void *self_in, mp_obj_t timestamp) {
|
|||
|
||||
mp_uint_t key_number = scan_number + index;
|
||||
|
||||
// Remember the previous up/down state.
|
||||
const bool previous = self->currently_pressed[key_number];
|
||||
self->previously_pressed[key_number] = previous;
|
||||
|
||||
// Get the current state.
|
||||
// Get the current state.
|
||||
const bool current =
|
||||
common_hal_digitalio_digitalinout_get_value(self->data_pins->items[i]) == self->value_when_pressed;
|
||||
self->currently_pressed[key_number] = current;
|
||||
|
||||
// Record any transitions.
|
||||
if (previous != current) {
|
||||
if (keypad_debounce((keypad_scanner_obj_t *)self, key_number, current)) {
|
||||
keypad_eventqueue_record(self->events, key_number, current, timestamp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,10 +99,9 @@ void keypad_deregister_scanner(keypad_scanner_obj_t *scanner) {
|
|||
supervisor_release_lock(&keypad_scanners_linked_list_lock);
|
||||
}
|
||||
|
||||
void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events) {
|
||||
void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) {
|
||||
size_t key_count = common_hal_keypad_generic_get_key_count(self);
|
||||
self->currently_pressed = (bool *)m_malloc(sizeof(bool) * key_count);
|
||||
self->previously_pressed = (bool *)m_malloc(sizeof(bool) * key_count);
|
||||
self->debounce_counter = (int8_t *)m_malloc(sizeof(int8_t) * key_count);
|
||||
|
||||
self->interval_ticks = (mp_uint_t)(interval * 1024); // interval * 1000 * (1024/1000)
|
||||
|
||||
|
|
@ -110,6 +109,8 @@ void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, si
|
|||
common_hal_keypad_eventqueue_construct(events, max_events);
|
||||
self->events = events;
|
||||
|
||||
self->debounce_threshold = debounce_threshold;
|
||||
|
||||
// Add self to the list of active keypad scanners.
|
||||
keypad_register_scanner(self);
|
||||
keypad_scan_now(self, port_get_raw_ticks(NULL));
|
||||
|
|
@ -127,11 +128,27 @@ static void keypad_scan_maybe(keypad_scanner_obj_t *self, uint64_t now) {
|
|||
keypad_scan_now(self, now);
|
||||
}
|
||||
|
||||
bool keypad_debounce(keypad_scanner_obj_t *self, mp_uint_t key_number, bool current) {
|
||||
if (current) {
|
||||
if ((self->debounce_counter[key_number] < self->debounce_threshold) &&
|
||||
(++self->debounce_counter[key_number] == 0)) {
|
||||
self->debounce_counter[key_number] = self->debounce_threshold;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ((self->debounce_counter[key_number] > -self->debounce_threshold) &&
|
||||
(--self->debounce_counter[key_number] == 0)) {
|
||||
self->debounce_counter[key_number] = -self->debounce_threshold;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void common_hal_keypad_generic_reset(void *self_in) {
|
||||
keypad_scanner_obj_t *self = self_in;
|
||||
size_t key_count = common_hal_keypad_generic_get_key_count(self);
|
||||
memset(self->previously_pressed, false, key_count);
|
||||
memset(self->currently_pressed, false, key_count);
|
||||
memset(self->debounce_counter, self->debounce_threshold, key_count);
|
||||
keypad_scan_now(self, port_get_raw_ticks(NULL));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ typedef struct _keypad_scanner_funcs_t {
|
|||
struct _keypad_scanner_obj_t *next; \
|
||||
keypad_scanner_funcs_t *funcs; \
|
||||
uint64_t next_scan_ticks; \
|
||||
bool *previously_pressed; \
|
||||
bool *currently_pressed; \
|
||||
int8_t *debounce_counter; \
|
||||
struct _keypad_eventqueue_obj_t *events; \
|
||||
mp_uint_t interval_ticks
|
||||
mp_uint_t interval_ticks; \
|
||||
uint8_t debounce_threshold
|
||||
|
||||
typedef struct _keypad_scanner_obj_t {
|
||||
KEYPAD_SCANNER_COMMON_FIELDS;
|
||||
|
|
@ -59,7 +59,8 @@ void keypad_reset(void);
|
|||
|
||||
void keypad_register_scanner(keypad_scanner_obj_t *scanner);
|
||||
void keypad_deregister_scanner(keypad_scanner_obj_t *scanner);
|
||||
void keypad_construct_common(keypad_scanner_obj_t *scanner, mp_float_t interval, size_t max_events);
|
||||
void keypad_construct_common(keypad_scanner_obj_t *scanner, mp_float_t interval, size_t max_events, uint8_t debounce_cycles);
|
||||
bool keypad_debounce(keypad_scanner_obj_t *self, mp_uint_t key_number, bool current);
|
||||
|
||||
size_t common_hal_keypad_generic_get_key_count(void *scanner);
|
||||
void common_hal_keypad_deinit_core(void *scanner);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ static mp_uint_t row_column_to_key_number(keypad_demux_demuxkeymatrix_obj_t *sel
|
|||
return row * self->column_digitalinouts->len + column;
|
||||
}
|
||||
|
||||
void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], mp_float_t interval, size_t max_events) {
|
||||
void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], mp_float_t interval, size_t max_events, uint8_t debounce_threshold) {
|
||||
|
||||
mp_obj_t row_addr_dios[num_row_addr_pins];
|
||||
for (size_t row = 0; row < num_row_addr_pins; row++) {
|
||||
|
|
@ -72,13 +72,9 @@ void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatri
|
|||
}
|
||||
self->column_digitalinouts = mp_obj_new_tuple(num_column_pins, column_dios);
|
||||
|
||||
size_t num_rows = 1 << num_row_addr_pins;
|
||||
self->currently_pressed = (bool *)m_malloc(sizeof(bool) * num_rows * num_column_pins);
|
||||
self->previously_pressed = (bool *)m_malloc(sizeof(bool) * num_rows * num_column_pins);
|
||||
|
||||
self->funcs = &keymatrix_funcs;
|
||||
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events);
|
||||
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold);
|
||||
}
|
||||
|
||||
void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_obj_t *self) {
|
||||
|
|
@ -138,16 +134,13 @@ static void demuxkeymatrix_scan_now(void *self_in, mp_obj_t timestamp) {
|
|||
|
||||
for (size_t column = 0; column < common_hal_keypad_demux_demuxkeymatrix_get_column_count(self); column++) {
|
||||
mp_uint_t key_number = row_column_to_key_number(self, row, column);
|
||||
const bool previous = self->currently_pressed[key_number];
|
||||
self->previously_pressed[key_number] = previous;
|
||||
|
||||
// Get the current state, by reading whether the column got pulled to the row value or not.
|
||||
// If low, the key is pressed.
|
||||
const bool current = !common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]);
|
||||
self->currently_pressed[key_number] = current;
|
||||
|
||||
// Record any transitions.
|
||||
if (previous != current) {
|
||||
if (keypad_debounce((keypad_scanner_obj_t *)self, key_number, current)) {
|
||||
keypad_eventqueue_record(self->events, key_number, current, timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue