From acf90fbb43f399970c66a34d2a0258b56bb306ef Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 23 Jun 2021 09:18:40 -0400 Subject: [PATCH] many renamings; add overflowed flag to EventQuque --- shared-bindings/keypad/Event.c | 49 ++++---- shared-bindings/keypad/Event.h | 5 +- shared-bindings/keypad/EventQueue.c | 53 ++++++-- shared-bindings/keypad/EventQueue.h | 7 +- shared-bindings/keypad/KeyMatrix.c | 135 +++++++++++++-------- shared-bindings/keypad/KeyMatrix.h | 15 +-- shared-bindings/keypad/Keys.c | 46 ++++--- shared-bindings/keypad/Keys.h | 6 +- shared-bindings/keypad/ShiftRegisterKeys.c | 60 +++++---- shared-bindings/keypad/ShiftRegisterKeys.h | 8 +- shared-module/keypad/Event.c | 8 +- shared-module/keypad/Event.h | 2 +- shared-module/keypad/EventQueue.c | 40 +++--- shared-module/keypad/EventQueue.h | 3 +- shared-module/keypad/KeyMatrix.c | 81 +++++++------ shared-module/keypad/KeyMatrix.h | 2 +- shared-module/keypad/Keys.c | 32 +++-- shared-module/keypad/ShiftRegisterKeys.c | 38 +++--- shared-module/keypad/ShiftRegisterKeys.h | 2 +- 19 files changed, 346 insertions(+), 246 deletions(-) diff --git a/shared-bindings/keypad/Event.c b/shared-bindings/keypad/Event.c index ff1323eac0..11cd0c120c 100644 --- a/shared-bindings/keypad/Event.c +++ b/shared-bindings/keypad/Event.c @@ -32,44 +32,44 @@ //| class Event: //| """A key transition event.""" -//| def __init__(self, key_num: int=0, pressed: bool=True) -> None: +//| def __init__(self, key_number: int=0, pressed: bool=True) -> None: //| """Create a key transition event, which reports a key-pressed or key-released transition. //| -//| :param int key_num: the key number +//| :param int key_number: the key number //| :param bool pressed: ``True`` if the key was pressed; ``False`` if it was released. //| """ //| ... //| - STATIC mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { keypad_event_obj_t *self = m_new_obj(keypad_event_obj_t); self->base.type = &keypad_event_type; - enum { ARG_key_num, ARG_pressed }; + enum { ARG_key_number, ARG_pressed }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_key_num, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_key_number, MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_pressed, MP_ARG_BOOL, {.u_bool = true} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mp_uint_t key_num = (mp_uint_t)mp_arg_validate_int_min(args[ARG_key_num].u_int, 0, MP_QSTR_key_num); + const mp_uint_t key_number = + (mp_uint_t)mp_arg_validate_int_min(args[ARG_key_number].u_int, 0, MP_QSTR_key_number); - common_hal_keypad_event_construct(self, key_num, args[ARG_pressed].u_bool); + common_hal_keypad_event_construct(self, key_number, args[ARG_pressed].u_bool); return MP_OBJ_FROM_PTR(self); } -//| key_num: int +//| key_number: int //| """The key number.""" //| -STATIC mp_obj_t keypad_event_get_key_num(mp_obj_t self_in) { +STATIC mp_obj_t keypad_event_get_key_number(mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_event_get_key_num(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_event_get_key_number(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(keypad_event_get_key_num_obj, keypad_event_get_key_num); +MP_DEFINE_CONST_FUN_OBJ_1(keypad_event_get_key_number_obj, keypad_event_get_key_number); -const mp_obj_property_t keypad_event_key_num_obj = { +const mp_obj_property_t keypad_event_key_number_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&keypad_event_get_key_num_obj, + .proxy = {(mp_obj_t)&keypad_event_get_key_number_obj, MP_ROM_NONE, MP_ROM_NONE}, }; @@ -111,7 +111,7 @@ const mp_obj_property_t keypad_event_released_obj = { }; //| def __eq__(self, other: object) -> bool: -//| """Two `Event` objects are equal if their `key_num` +//| """Two `Event` objects are equal if their `key_number` //| and `pressed`/`released` values are equal. //| """ //| ... @@ -123,10 +123,11 @@ STATIC mp_obj_t keypad_event_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_ob keypad_event_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in); keypad_event_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in); return mp_obj_new_bool( - (common_hal_keypad_event_get_key_num(lhs) == - common_hal_keypad_event_get_key_num(rhs)) && + (common_hal_keypad_event_get_key_number(lhs) == + common_hal_keypad_event_get_key_number(rhs)) && (common_hal_keypad_event_get_pressed(lhs) == - common_hal_keypad_event_get_pressed(rhs))); + common_hal_keypad_event_get_pressed(rhs)) + ); } else { return mp_const_false; } @@ -144,9 +145,9 @@ STATIC mp_obj_t keypad_event_unary_op(mp_unary_op_t op, mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self); switch (op) { case MP_UNARY_OP_HASH: { - const mp_int_t key_num = common_hal_keypad_event_get_key_num(self); + const mp_int_t key_number = common_hal_keypad_event_get_key_number(self); const bool pressed = common_hal_keypad_event_get_pressed(self); - return MP_OBJ_NEW_SMALL_INT((pressed << 15) + key_num); + return MP_OBJ_NEW_SMALL_INT((pressed << 15) + key_number); } default: return MP_OBJ_NULL; // op not supported @@ -155,16 +156,16 @@ STATIC mp_obj_t keypad_event_unary_op(mp_unary_op_t op, mp_obj_t self_in) { STATIC void keypad_event_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "", - common_hal_keypad_event_get_key_num(self), + mp_printf(print, "", + common_hal_keypad_event_get_key_number(self), common_hal_keypad_event_get_pressed(self) ? "pressed" : "released"); } STATIC const mp_rom_map_elem_t keypad_event_locals_dict_table[] = { // Properties - { MP_ROM_QSTR(MP_QSTR_key_num), MP_ROM_PTR(&keypad_event_key_num_obj) }, - { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&keypad_event_pressed_obj) }, - { MP_ROM_QSTR(MP_QSTR_released), MP_ROM_PTR(&keypad_event_released_obj) }, + { MP_ROM_QSTR(MP_QSTR_key_number), MP_ROM_PTR(&keypad_event_key_number_obj) }, + { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&keypad_event_pressed_obj) }, + { MP_ROM_QSTR(MP_QSTR_released), MP_ROM_PTR(&keypad_event_released_obj) }, }; STATIC MP_DEFINE_CONST_DICT(keypad_event_locals_dict, keypad_event_locals_dict_table); diff --git a/shared-bindings/keypad/Event.h b/shared-bindings/keypad/Event.h index 23017f1dc5..35cfdcdc64 100644 --- a/shared-bindings/keypad/Event.h +++ b/shared-bindings/keypad/Event.h @@ -32,10 +32,9 @@ extern const mp_obj_type_t keypad_event_type; -void common_hal_keypad_event_construct(keypad_event_obj_t *self, mp_uint_t key_num, bool pressed); -mp_int_t common_hal_keypad_event_get_key_num(keypad_event_obj_t *self); +void common_hal_keypad_event_construct(keypad_event_obj_t *self, mp_uint_t key_number, bool pressed); +mp_int_t common_hal_keypad_event_get_key_number(keypad_event_obj_t *self); bool common_hal_keypad_event_get_pressed(keypad_event_obj_t *self); bool common_hal_keypad_event_get_released(keypad_event_obj_t *self); - #endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENT__H diff --git a/shared-bindings/keypad/EventQueue.c b/shared-bindings/keypad/EventQueue.c index ae544a6665..72bbd06452 100644 --- a/shared-bindings/keypad/EventQueue.c +++ b/shared-bindings/keypad/EventQueue.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/keypad/Event.h" #include "shared-bindings/keypad/EventQueue.h" @@ -36,50 +37,50 @@ //| """ //| ... -//| def next(self) -> Optional[Event]: +//| def get(self) -> Optional[Event]: //| """Return the next key transition event. Return ``None`` if no events are pending. //| //| Note that the queue size is limited; see ``max_events`` in the constructor of //| a scanner such as `Keys` or `KeyMatrix`. -//| If a new event arrives when the queue is full, the oldest event is discarded. +//| If a new event arrives when the queue is full, the queue is cleared, and +//| `overflowed` is set to ``True``. //| //| :return: the next queued key transition `Event` //| :rtype: Optional[Event] //| """ //| ... //| -STATIC mp_obj_t keypad_eventqueue_next(mp_obj_t self_in) { +STATIC mp_obj_t keypad_eventqueue_get(mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); - return common_hal_keypad_eventqueue_next(self); + return common_hal_keypad_eventqueue_get(self); } -MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_next_obj, keypad_eventqueue_next); +MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_obj, keypad_eventqueue_get); -//| def store_next(self, event: Event) -> bool: +//| def get_into(self, event: Event) -> bool: //| """Store the next key transition event in the supplied event, if available, //| and return ``True``. //| If there are no queued events, do not touch ``event`` and return ``False``. //| -//| The advantage of this method over ``next()`` is that it does not allocate storage. +//| The advantage of this method over ``get()`` is that it does not allocate storage. //| Instead you can reuse an existing ``Event`` object. //| //| Note that the queue size is limited; see ``max_events`` in the constructor of //| a scanner such as `Keys` or `KeyMatrix`. -//| If a new event arrives when the queue is full, the oldest event is discarded. //| //| :return ``True`` if an event was available and stored, ``False`` if not. //| :rtype: bool //| """ //| ... //| -STATIC mp_obj_t keypad_eventqueue_store_next(mp_obj_t self_in, mp_obj_t event_in) { +STATIC mp_obj_t keypad_eventqueue_get_into(mp_obj_t self_in, mp_obj_t event_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); keypad_event_obj_t *event = MP_OBJ_TO_PTR(mp_arg_validate_type(event_in, &keypad_event_type, MP_QSTR_event)); - return mp_obj_new_bool(common_hal_keypad_eventqueue_store_next(self, event)); + return mp_obj_new_bool(common_hal_keypad_eventqueue_get_into(self, event)); } -MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_store_next_obj, keypad_eventqueue_store_next); +MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_get_into_obj, keypad_eventqueue_get_into); //| def clear(self) -> None: //| """Clear any queued key transition events. @@ -117,10 +118,36 @@ STATIC mp_obj_t keypad_eventqueue_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } } +//| overflowed: bool +//| """``True`` if an event could not be added to the event queue because it was full. +//| When this happens, the event queue is cleared. +//| The `overflowed` flag is persistent. Reset it by setting it to ``False``. +//| """ +//| +STATIC mp_obj_t keypad_eventqueue_get_overflowed(mp_obj_t self_in) { + keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_keypad_eventqueue_get_overflowed(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_overflowed_obj, keypad_eventqueue_get_overflowed); + +STATIC mp_obj_t keypad_eventqueue_set_overflowed(mp_obj_t self_in, mp_obj_t overflowed_in) { + keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_keypad_eventqueue_set_overflowed(self, mp_obj_is_true(overflowed_in)); + return MP_ROM_NONE; +} +MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_set_overflowed_obj, keypad_eventqueue_set_overflowed); + +const mp_obj_property_t keypad_eventqueue_overflowed_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&keypad_eventqueue_get_overflowed_obj, + (mp_obj_t)&keypad_eventqueue_set_overflowed_obj, + MP_ROM_NONE}, +}; + STATIC const mp_rom_map_elem_t keypad_eventqueue_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&keypad_eventqueue_clear_obj) }, - { MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&keypad_eventqueue_next_obj) }, - { MP_ROM_QSTR(MP_QSTR_store_next), MP_ROM_PTR(&keypad_eventqueue_store_next_obj) }, + { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&keypad_eventqueue_get_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_into), MP_ROM_PTR(&keypad_eventqueue_get_into_obj) }, }; STATIC MP_DEFINE_CONST_DICT(keypad_eventqueue_locals_dict, keypad_eventqueue_locals_dict_table); diff --git a/shared-bindings/keypad/EventQueue.h b/shared-bindings/keypad/EventQueue.h index 6faa2971fd..fbbd9df0cb 100644 --- a/shared-bindings/keypad/EventQueue.h +++ b/shared-bindings/keypad/EventQueue.h @@ -36,7 +36,10 @@ void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_ void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self); size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self); -mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self); -bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event); +mp_obj_t common_hal_keypad_eventqueue_get(keypad_eventqueue_obj_t *self); +bool common_hal_keypad_eventqueue_get_into(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event); + +bool common_hal_keypad_eventqueue_get_overflowed(keypad_eventqueue_obj_t *self); +void common_hal_keypad_eventqueue_set_overflowed(keypad_eventqueue_obj_t *self, bool overflowed); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_EVENTQUEUE_H diff --git a/shared-bindings/keypad/KeyMatrix.c b/shared-bindings/keypad/KeyMatrix.c index f2c80b42e5..fc29f67e33 100644 --- a/shared-bindings/keypad/KeyMatrix.c +++ b/shared-bindings/keypad/KeyMatrix.c @@ -36,26 +36,25 @@ //| class KeyMatrix: //| """Manage a 2D matrix of keys with row and column pins.""" //| -//| def __init__(self, row_pins: Sequence[microcontroller.Pin], col_pins: Sequence[microcontroller.Pin], columns_to_anodes: bool = True, interval: float = 0.020, max_events: int = 64) -> None: +//| def __init__(self, row_pins: Sequence[microcontroller.Pin], column_pins: Sequence[microcontroller.Pin], columns_to_anodes: bool = True, interval: float = 0.020, max_events: int = 64) -> None: //| """ //| Create a `Keys` object that will scan the key matrix attached to the given row and column pins. -//| There should not be any pull-ups or pull-downs on the matrix. +//| There should not be any external pull-ups or pull-downs on the matrix: +//| ``KeyMatrix`` enables internal pull-ups or pull-downs on the pins as necessary. //| //| The keys are numbered sequentially from zero. A key number can be computed -//| by ``row * len(col_pins) + col``. +//| by ``row * len(column_pins) + column``. //| //| An `EventQueue` is created when this object is created and is available in the `events` attribute. //| -//| The keys are debounced by waiting about 20 msecs before reporting a transition. -//| //| :param Sequence[microcontroller.Pin] row_pins: The pins attached to the rows. -//| :param Sequence[microcontroller.Pin] col_pins: The pins attached to the colums. +//| :param Sequence[microcontroller.Pin] column_pins: The pins attached to the colums. //| :param bool columns_to_anodes: Default ``True``. //| If the matrix uses diodes, the diode anodes are typically connected to the column pins, //| and the cathodes should be connected to the row pins. If your diodes are reversed, //| set ``columns_to_anodes`` to ``False``. -//| :param float interval: Scan keys no more often -//| to allow for debouncing. Given in seconds. +//| :param float interval: Scan keys no more often than ``interval`` to allow for debouncing. +//| ``interval`` is in float seconds. The default is 0.020 (20 msecs). //| :param int max_events: maximum size of `events` `EventQueue`: //| maximum number of key transition events that are saved. //| Must be >= 1. @@ -66,10 +65,10 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { keypad_keymatrix_obj_t *self = m_new_obj(keypad_keymatrix_obj_t); self->base.type = &keypad_keymatrix_type; - enum { ARG_row_pins, ARG_col_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 }; static const mp_arg_t allowed_args[] = { { MP_QSTR_row_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_col_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} }, @@ -81,15 +80,15 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar // mp_obj_len() will be >= 0. const size_t num_row_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(row_pins)); - mp_obj_t col_pins = args[ARG_col_pins].u_obj; - const size_t num_col_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(col_pins)); + mp_obj_t column_pins = args[ARG_column_pins].u_obj; + const size_t num_column_pins = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(column_pins)); 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); mcu_pin_obj_t *row_pins_array[num_row_pins]; - mcu_pin_obj_t *col_pins_array[num_col_pins]; + mcu_pin_obj_t *column_pins_array[num_column_pins]; for (size_t row = 0; row < num_row_pins; row++) { mcu_pin_obj_t *pin = @@ -97,13 +96,13 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar row_pins_array[row] = pin; } - for (size_t col = 0; col < num_col_pins; col++) { + for (size_t column = 0; column < num_column_pins; column++) { mcu_pin_obj_t *pin = - validate_obj_is_free_pin(mp_obj_subscr(col_pins, MP_OBJ_NEW_SMALL_INT(col), MP_OBJ_SENTINEL)); - col_pins_array[col] = pin; + validate_obj_is_free_pin(mp_obj_subscr(column_pins, MP_OBJ_NEW_SMALL_INT(column), MP_OBJ_SENTINEL)); + column_pins_array[column] = pin; } - common_hal_keypad_keymatrix_construct(self, num_row_pins, row_pins_array, num_col_pins, col_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); return MP_OBJ_FROM_PTR(self); } @@ -142,71 +141,102 @@ STATIC void check_for_deinit(keypad_keymatrix_obj_t *self) { } } -//| num_keys: int +//| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ //| -STATIC mp_obj_t keypad_keymatrix_get_num_keys(mp_obj_t self_in) { +STATIC mp_obj_t keypad_keymatrix_get_key_count(mp_obj_t self_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_keymatrix_get_num_keys(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_keymatrix_get_key_count(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(keypad_keymatrix_get_num_keys_obj, keypad_keymatrix_get_num_keys); +MP_DEFINE_CONST_FUN_OBJ_1(keypad_keymatrix_get_key_count_obj, keypad_keymatrix_get_key_count); -const mp_obj_property_t keypad_keymatrix_num_keys_obj = { +const mp_obj_property_t keypad_keymatrix_key_count_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&keypad_keymatrix_get_num_keys_obj, + .proxy = {(mp_obj_t)&keypad_keymatrix_get_key_count_obj, MP_ROM_NONE, MP_ROM_NONE}, }; -//| def key_num(self, row: int, col: int) -> int: -//| """Return the key number for a given row and column. -//| The key number is calculated by ``row * len(col_pins) + col``. +//| def key_number_to_row_column(self, row: int, column: int) -> Tuple[int]: +//| """Return the row and column for the given key number. +//| The row is ``key_number // len(column_pins)``. +//| The column is ``key_number % len(column_pins)``. +//| +//| :return: ``(row, column)`` +//| :rtype: Tuple[int] //| """ //| ... //| -STATIC mp_obj_t keypad_keymatrix_key_num(mp_obj_t self_in, mp_obj_t row_in, mp_obj_t col_in) { +STATIC mp_obj_t keypad_keymatrix_key_number_to_row_column(mp_obj_t self_in, mp_obj_t key_number_in) { + keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + const mp_uint_t key_number = (mp_uint_t)mp_arg_validate_int_range( + mp_obj_get_int(key_number_in), + 0, (mp_int_t)common_hal_keypad_keymatrix_get_key_count(self), + MP_QSTR_key_number); + + mp_uint_t row; + mp_uint_t column; + common_hal_keypad_keymatrix_key_number_to_row_column(self, key_number, &row, &column); + + mp_obj_t row_column[2]; + row_column[0] = MP_OBJ_NEW_SMALL_INT(row); + row_column[1] = MP_OBJ_NEW_SMALL_INT(column); + + return mp_obj_new_tuple(2, row_column); +} +MP_DEFINE_CONST_FUN_OBJ_2(keypad_keymatrix_key_number_to_row_column_obj, keypad_keymatrix_key_number_to_row_column); + +//| def row_column_to_key_number(self, row: int, column: int) -> int: +//| """Return the key number for a given row and column. +//| The key number is ``row * len(column_pins) + column``. +//| """ +//| ... +//| +STATIC mp_obj_t keypad_keymatrix_row_column_to_key_number(mp_obj_t self_in, mp_obj_t row_in, mp_obj_t column_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); const mp_uint_t row = (mp_uint_t)mp_arg_validate_int_range( - mp_obj_get_int(row_in), 0, (mp_int_t)common_hal_keypad_keymatrix_get_num_rows(self), MP_QSTR_row); + mp_obj_get_int(row_in), 0, (mp_int_t)common_hal_keypad_keymatrix_get_row_count(self), MP_QSTR_row); - const mp_int_t col = (mp_uint_t)mp_arg_validate_int_range( - mp_obj_get_int(col_in), 0, (mp_int_t)common_hal_keypad_keymatrix_get_num_cols(self), MP_QSTR_col); + const mp_int_t column = (mp_uint_t)mp_arg_validate_int_range( + mp_obj_get_int(column_in), 0, (mp_int_t)common_hal_keypad_keymatrix_get_column_count(self), MP_QSTR_column); return MP_OBJ_NEW_SMALL_INT( - (mp_int_t)common_hal_keypad_keymatrix_key_num(self, row, col)); + (mp_int_t)common_hal_keypad_keymatrix_row_column_to_key_number(self, row, column)); } -MP_DEFINE_CONST_FUN_OBJ_3(keypad_keymatrix_key_num_obj, keypad_keymatrix_key_num); +MP_DEFINE_CONST_FUN_OBJ_3(keypad_keymatrix_row_column_to_key_number_obj, keypad_keymatrix_row_column_to_key_number); -//| def pressed(self, key_num: int) -> None: +//| def pressed(self, key_number: int) -> None: //| """Return ``True`` if the given key is pressed. This is a debounced read //| of the key state which bypasses the `events` `EventQueue`. //| """ //| ... //| -STATIC mp_obj_t keypad_keymatrix_pressed(mp_obj_t self_in, mp_obj_t key_num_in) { +STATIC mp_obj_t keypad_keymatrix_pressed(mp_obj_t self_in, mp_obj_t key_number_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - mp_uint_t key_num = mp_arg_validate_int_range( - mp_obj_get_int(key_num_in), 0, (mp_int_t)common_hal_keypad_keymatrix_get_num_keys(self), MP_QSTR_key_num); + mp_uint_t key_number = mp_arg_validate_int_range( + mp_obj_get_int(key_number_in), 0, (mp_int_t)common_hal_keypad_keymatrix_get_key_count(self), MP_QSTR_key_number); - return mp_obj_new_bool(common_hal_keypad_keymatrix_pressed(self, (mp_uint_t)key_num)); + return mp_obj_new_bool(common_hal_keypad_keymatrix_pressed(self, (mp_uint_t)key_number)); } MP_DEFINE_CONST_FUN_OBJ_2(keypad_keymatrix_pressed_obj, keypad_keymatrix_pressed); -//| def store_states(self, states: _typing.WriteableBuffer) -> None: +//| def get_states_into(self, states: _typing.WriteableBuffer) -> None: //| """Write the state of all the keys into ``states``. //| Write a ``1`` if pressed, and ``0`` if released. -//| The ``length`` of ``states`` must be `num_keys`. +//| The ``length`` of ``states`` must be `key_count`. //| This is a debounced read of the state of all the keys, and bypasses the `events` `EventQueue`. //| The read is done atomically. //| """ //| ... //| -STATIC mp_obj_t keypad_keymatrix_store_states(mp_obj_t self_in, mp_obj_t pressed) { +STATIC mp_obj_t keypad_keymatrix_get_states_into(mp_obj_t self_in, mp_obj_t pressed) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -216,13 +246,13 @@ STATIC mp_obj_t keypad_keymatrix_store_states(mp_obj_t self_in, mp_obj_t pressed mp_raise_ValueError_varg(translate("%q must store bytes"), MP_QSTR_states); } - (void)mp_arg_validate_length_with_name(bufinfo.len, common_hal_keypad_keymatrix_get_num_keys(self), - MP_QSTR_states, MP_QSTR_num_keys); + (void)mp_arg_validate_length_with_name(bufinfo.len, common_hal_keypad_keymatrix_get_key_count(self), + MP_QSTR_states, MP_QSTR_key_count); - common_hal_keypad_keymatrix_store_states(self, (uint8_t *)bufinfo.buf); + common_hal_keypad_keymatrix_get_states_into(self, (uint8_t *)bufinfo.buf); return MP_ROM_NONE; } -MP_DEFINE_CONST_FUN_OBJ_2(keypad_keymatrix_store_states_obj, keypad_keymatrix_store_states); +MP_DEFINE_CONST_FUN_OBJ_2(keypad_keymatrix_get_states_into_obj, keypad_keymatrix_get_states_into); //| events: EventQueue //| """The `EventQueue` associated with this `Keys` object. (read-only) @@ -242,15 +272,16 @@ const mp_obj_property_t keypad_keymatrix_events_obj = { }; STATIC const mp_rom_map_elem_t keypad_keymatrix_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&keypad_keymatrix_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_keymatrix___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&keypad_keymatrix_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_keymatrix___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_keymatrix_events_obj) }, - { MP_ROM_QSTR(MP_QSTR_key_num), MP_ROM_PTR(&keypad_keymatrix_key_num_obj) }, - { MP_ROM_QSTR(MP_QSTR_num_keys), MP_ROM_PTR(&keypad_keymatrix_num_keys_obj) }, - { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&keypad_keymatrix_pressed_obj) }, - { MP_ROM_QSTR(MP_QSTR_store_states), MP_ROM_PTR(&keypad_keymatrix_store_states_obj) }, + { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_keymatrix_events_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_states_into), MP_ROM_PTR(&keypad_keymatrix_get_states_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_key_number_to_row_column), MP_ROM_PTR(&keypad_keymatrix_key_number_to_row_column_obj) }, + { MP_ROM_QSTR(MP_QSTR_row_column_to_key_number), MP_ROM_PTR(&keypad_keymatrix_row_column_to_key_number_obj) }, + { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_keymatrix_key_count_obj) }, + { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&keypad_keymatrix_pressed_obj) }, }; STATIC MP_DEFINE_CONST_DICT(keypad_keymatrix_locals_dict, keypad_keymatrix_locals_dict_table); diff --git a/shared-bindings/keypad/KeyMatrix.h b/shared-bindings/keypad/KeyMatrix.h index 72e1847c44..98152f759a 100644 --- a/shared-bindings/keypad/KeyMatrix.h +++ b/shared-bindings/keypad/KeyMatrix.h @@ -32,19 +32,20 @@ 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, mcu_pin_obj_t *row_pins[], mp_uint_t num_col_pins, mcu_pin_obj_t *col_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, mcu_pin_obj_t *row_pins[], mp_uint_t num_column_pins, mcu_pin_obj_t *column_pins[], bool columns_to_anodes, mp_float_t interval, size_t max_events); void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self); bool common_hal_keypad_keymatrix_deinited(keypad_keymatrix_obj_t *self); -mp_uint_t common_hal_keypad_keymatrix_key_num(keypad_keymatrix_obj_t *self, mp_uint_t row, mp_uint_t col); +void common_hal_keypad_keymatrix_key_number_to_row_column(keypad_keymatrix_obj_t *self, mp_uint_t key_number, mp_uint_t *row, mp_uint_t *column); +mp_uint_t common_hal_keypad_keymatrix_row_column_to_key_number(keypad_keymatrix_obj_t *self, mp_uint_t row, mp_uint_t column); -mp_uint_t common_hal_keypad_keymatrix_get_num_keys(keypad_keymatrix_obj_t *self); -mp_uint_t common_hal_keypad_keymatrix_get_num_cols(keypad_keymatrix_obj_t *self); -mp_uint_t common_hal_keypad_keymatrix_get_num_rows(keypad_keymatrix_obj_t *self); +mp_uint_t common_hal_keypad_keymatrix_get_key_count(keypad_keymatrix_obj_t *self); +mp_uint_t common_hal_keypad_keymatrix_get_column_count(keypad_keymatrix_obj_t *self); +mp_uint_t common_hal_keypad_keymatrix_get_row_count(keypad_keymatrix_obj_t *self); mp_obj_t common_hal_keypad_keymatrix_get_events(keypad_keymatrix_obj_t *self); -bool common_hal_keypad_keymatrix_pressed(keypad_keymatrix_obj_t *self, mp_uint_t key_num); -void common_hal_keypad_keymatrix_store_states(keypad_keymatrix_obj_t *self, uint8_t *states); +bool common_hal_keypad_keymatrix_pressed(keypad_keymatrix_obj_t *self, mp_uint_t key_number); +void common_hal_keypad_keymatrix_get_states_into(keypad_keymatrix_obj_t *self, uint8_t *states); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_KEYMATRIX_H diff --git a/shared-bindings/keypad/Keys.c b/shared-bindings/keypad/Keys.c index 5f1d0ecc7d..95e68e9bd1 100644 --- a/shared-bindings/keypad/Keys.c +++ b/shared-bindings/keypad/Keys.c @@ -43,8 +43,6 @@ //| //| An `EventQueue` is created when this object is created and is available in the `events` attribute. //| -//| The keys are debounced by waiting about 20 msecs before reporting a transition. -//| //| :param Sequence[microcontroller.Pin] pins: The pins attached to the keys. //| The key numbers correspond to indices into this sequence. //| :param bool value_when_pressed: ``True`` if the pin reads high when the key is pressed. @@ -56,8 +54,8 @@ //| If an external pull is already provided for all the pins, you can set ``pull`` to ``False``. //| However, enabling an internal pull when an external one is already present is not a problem; //| it simply uses slightly more current. -//| :param float interval: Scan keys no more often -//| to allow for debouncing. Given in seconds. +//| :param float interval: Scan keys no more often than ``interval`` to allow for debouncing. +//| ``interval`` is in float seconds. The default is 0.020 (20 msecs). //| :param int max_events: maximum size of `events` `EventQueue`: //| maximum number of key transition events that are saved. //| Must be >= 1. @@ -137,50 +135,50 @@ STATIC void check_for_deinit(keypad_keys_obj_t *self) { } } -//| num_keys: int +//| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ //| -STATIC mp_obj_t keypad_keys_get_num_keys(mp_obj_t self_in) { +STATIC mp_obj_t keypad_keys_get_key_count(mp_obj_t self_in) { keypad_keys_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_keys_get_num_keys(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_keys_get_key_count(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(keypad_keys_get_num_keys_obj, keypad_keys_get_num_keys); +MP_DEFINE_CONST_FUN_OBJ_1(keypad_keys_get_key_count_obj, keypad_keys_get_key_count); -const mp_obj_property_t keypad_keys_num_keys_obj = { +const mp_obj_property_t keypad_keys_key_count_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&keypad_keys_get_num_keys_obj, + .proxy = {(mp_obj_t)&keypad_keys_get_key_count_obj, MP_ROM_NONE, MP_ROM_NONE}, }; -//| def pressed(self, key_num: int) -> None: +//| def pressed(self, key_number: int) -> None: //| """Return ``True`` if the given key is pressed. // This is a debounced read of the key state which bypasses the `events` `EventQueue`. //| """ //| ... //| -STATIC mp_obj_t keypad_keys_pressed(mp_obj_t self_in, mp_obj_t key_num_in) { +STATIC mp_obj_t keypad_keys_pressed(mp_obj_t self_in, mp_obj_t key_number_in) { keypad_keys_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - const mp_int_t key_num = mp_obj_get_int(key_num_in); - (void)mp_arg_validate_int_range(key_num, 0, common_hal_keypad_keys_get_num_keys(self), MP_QSTR_key_num); + const mp_int_t key_number = mp_obj_get_int(key_number_in); + (void)mp_arg_validate_int_range(key_number, 0, common_hal_keypad_keys_get_key_count(self), MP_QSTR_key_number); - return mp_obj_new_bool(common_hal_keypad_keys_pressed(self, (mp_uint_t)key_num)); + return mp_obj_new_bool(common_hal_keypad_keys_pressed(self, (mp_uint_t)key_number)); } MP_DEFINE_CONST_FUN_OBJ_2(keypad_keys_pressed_obj, keypad_keys_pressed); -//| def store_states(self, states: _typing.WriteableBuffer) -> None: +//| def get_states_into(self, states: _typing.WriteableBuffer) -> None: //| """Write the states of all the keys into ``states``. //| Write a ``1`` if pressed, and ``0`` if released. -//| The ``length`` of ``states`` must be `num_keys`. +//| The ``length`` of ``states`` must be `key_count`. //| This is a debounced read of the state of all the keys, and bypasses the `events` `EventQueue`. //| The read is done atomically. //| """ //| ... //| -STATIC mp_obj_t keypad_keys_store_states(mp_obj_t self_in, mp_obj_t pressed) { +STATIC mp_obj_t keypad_keys_get_states_into(mp_obj_t self_in, mp_obj_t pressed) { keypad_keys_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -189,13 +187,13 @@ STATIC mp_obj_t keypad_keys_store_states(mp_obj_t self_in, mp_obj_t pressed) { if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { mp_raise_ValueError_varg(translate("%q must store bytes"), MP_QSTR_pressed); } - (void)mp_arg_validate_length_with_name(bufinfo.len,common_hal_keypad_keys_get_num_keys(self), - MP_QSTR_pressed, MP_QSTR_num_keys); + (void)mp_arg_validate_length_with_name(bufinfo.len,common_hal_keypad_keys_get_key_count(self), + MP_QSTR_pressed, MP_QSTR_key_count); - common_hal_keypad_keys_store_states(self, (uint8_t *)bufinfo.buf); + common_hal_keypad_keys_get_states_into(self, (uint8_t *)bufinfo.buf); return MP_ROM_NONE; } -MP_DEFINE_CONST_FUN_OBJ_2(keypad_keys_store_states_obj, keypad_keys_store_states); +MP_DEFINE_CONST_FUN_OBJ_2(keypad_keys_get_states_into_obj, keypad_keys_get_states_into); //| events: EventQueue //| """The `EventQueue` associated with this `Keys` object. (read-only) @@ -220,9 +218,9 @@ STATIC const mp_rom_map_elem_t keypad_keys_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_keys___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_keys_events_obj) }, - { MP_ROM_QSTR(MP_QSTR_num_keys), MP_ROM_PTR(&keypad_keys_num_keys_obj) }, + { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_keys_key_count_obj) }, { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&keypad_keys_pressed_obj) }, - { MP_ROM_QSTR(MP_QSTR_store_states), MP_ROM_PTR(&keypad_keys_store_states_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_states_into), MP_ROM_PTR(&keypad_keys_get_states_into_obj) }, }; STATIC MP_DEFINE_CONST_DICT(keypad_keys_locals_dict, keypad_keys_locals_dict_table); diff --git a/shared-bindings/keypad/Keys.h b/shared-bindings/keypad/Keys.h index 6160b8b959..3ac3dd43b2 100644 --- a/shared-bindings/keypad/Keys.h +++ b/shared-bindings/keypad/Keys.h @@ -38,8 +38,8 @@ void common_hal_keypad_keys_deinit(keypad_keys_obj_t *self); bool common_hal_keypad_keys_deinited(keypad_keys_obj_t *self); mp_obj_t common_hal_keypad_keys_get_events(keypad_keys_obj_t *self); -mp_uint_t common_hal_keypad_keys_get_num_keys(keypad_keys_obj_t *self); -bool common_hal_keypad_keys_pressed(keypad_keys_obj_t *self, mp_uint_t key_num); -void common_hal_keypad_keys_store_states(keypad_keys_obj_t *self, uint8_t *states); +mp_uint_t common_hal_keypad_keys_get_key_count(keypad_keys_obj_t *self); +bool common_hal_keypad_keys_pressed(keypad_keys_obj_t *self, mp_uint_t key_number); +void common_hal_keypad_keys_get_states_into(keypad_keys_obj_t *self, uint8_t *states); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_KEYS_H diff --git a/shared-bindings/keypad/ShiftRegisterKeys.c b/shared-bindings/keypad/ShiftRegisterKeys.c index 2946ba3f98..e5d959348c 100644 --- a/shared-bindings/keypad/ShiftRegisterKeys.c +++ b/shared-bindings/keypad/ShiftRegisterKeys.c @@ -36,7 +36,7 @@ //| class ShiftRegisterKeys: //| """Manage a set of keys attached to an incoming shift register.""" //| -//| def __init__(self, *, clock: microcontroller.Pin, data: microcontroller.Pin, latch: microcontroller.Pin, value_to_latch: bool = True, num_keys: int, value_when_pressed: bool, interval: float = 0.020, max_events: int = 64) -> None: +//| def __init__(self, *, clock: microcontroller.Pin, data: microcontroller.Pin, latch: microcontroller.Pin, value_to_latch: bool = True, key_count: int, value_when_pressed: bool, interval: float = 0.020, max_events: int = 64) -> None: //| """ //| Create a `Keys` object that will scan keys attached to a parallel-in serial-out shift register //| like the 74HC165 or CD4021. @@ -47,8 +47,6 @@ //| //| An `EventQueue` is created when this object is created and is available in the `events` attribute. //| -//| The keys are debounced by waiting about 20 msecs before reporting a transition. -//| //| :param microcontroller.Pin clock: The shift register clock pin. //| The shift register should clock on a low-to-high transition. //| :param microcontroller.Pin data: the incoming shift register data pin @@ -59,11 +57,11 @@ //| ``False`` if the data is latched when ``latch goes low. //| The default is ``True``, which is how the 74HC165 operates. The CD4021 latch is the opposite. //| Once the data is latched, it will be shifted out by toggling the clock pin. -//| :param int num_keys: number of data lines to clock in +//| :param int key_count: number of data lines to clock in //| :param bool value_when_pressed: ``True`` if the pin reads high when the key is pressed. //| ``False`` if the pin reads low (is grounded) when the key is pressed. -//| :param float interval: Scan keys no more often -//| to allow for debouncing. Given in seconds. +//| :param float interval: Scan keys no more often than ``interval`` to allow for debouncing. +//| ``interval`` is in float seconds. The default is 0.020 (20 msecs). //| :param int max_events: maximum size of `events` `EventQueue`: //| maximum number of key transition events that are saved. //| Must be >= 1. @@ -74,13 +72,13 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { keypad_shiftregisterkeys_obj_t *self = m_new_obj(keypad_shiftregisterkeys_obj_t); self->base.type = &keypad_shiftregisterkeys_type; - enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_num_keys, 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 }; 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 }, { MP_QSTR_latch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_value_to_latch, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, - { MP_QSTR_num_keys, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_key_count, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, { 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} }, @@ -93,14 +91,14 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz mcu_pin_obj_t *latch = validate_obj_is_free_pin(args[ARG_latch].u_obj); const bool value_to_latch = args[ARG_value_to_latch].u_bool; - const size_t num_keys = (size_t)mp_arg_validate_int_min(args[ARG_num_keys].u_int, 1, MP_QSTR_num_keys); + const size_t key_count = (size_t)mp_arg_validate_int_min(args[ARG_key_count].u_int, 1, MP_QSTR_key_count); const bool value_when_pressed = args[ARG_value_when_pressed].u_bool; 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); common_hal_keypad_shiftregisterkeys_construct( - self, clock, data, latch, value_to_latch, num_keys, value_when_pressed, interval, max_events); + self, clock, data, latch, value_to_latch, key_count, value_when_pressed, interval, max_events); return MP_OBJ_FROM_PTR(self); } @@ -141,51 +139,51 @@ STATIC void check_for_deinit(keypad_shiftregisterkeys_obj_t *self) { } } -//| num_keys: int +//| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ //| -STATIC mp_obj_t keypad_shiftregisterkeys_get_num_keys(mp_obj_t self_in) { +STATIC mp_obj_t keypad_shiftregisterkeys_get_key_count(mp_obj_t self_in) { keypad_shiftregisterkeys_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_shiftregisterkeys_get_num_keys(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_keypad_shiftregisterkeys_get_key_count(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(keypad_shiftregisterkeys_get_num_keys_obj, keypad_shiftregisterkeys_get_num_keys); +MP_DEFINE_CONST_FUN_OBJ_1(keypad_shiftregisterkeys_get_key_count_obj, keypad_shiftregisterkeys_get_key_count); -const mp_obj_property_t keypad_shiftregisterkeys_num_keys_obj = { +const mp_obj_property_t keypad_shiftregisterkeys_key_count_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&keypad_shiftregisterkeys_get_num_keys_obj, + .proxy = {(mp_obj_t)&keypad_shiftregisterkeys_get_key_count_obj, MP_ROM_NONE, MP_ROM_NONE}, }; -//| def pressed(self, key_num: int) -> None: +//| def pressed(self, key_number: int) -> None: //| """Return ``True`` if the given key is pressed. // This is a debounced read of the key state which bypasses the `events` `EventQueue`. //| """ //| ... //| -STATIC mp_obj_t keypad_shiftregisterkeys_pressed(mp_obj_t self_in, mp_obj_t key_num_in) { +STATIC mp_obj_t keypad_shiftregisterkeys_pressed(mp_obj_t self_in, mp_obj_t key_number_in) { keypad_shiftregisterkeys_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - mp_uint_t key_num = mp_arg_validate_int_range( - mp_obj_get_int(key_num_in), 0, (mp_int_t)common_hal_keypad_shiftregisterkeys_get_num_keys(self), - MP_QSTR_key_num); + mp_uint_t key_number = mp_arg_validate_int_range( + mp_obj_get_int(key_number_in), 0, (mp_int_t)common_hal_keypad_shiftregisterkeys_get_key_count(self), + MP_QSTR_key_number); - return mp_obj_new_bool(common_hal_keypad_shiftregisterkeys_pressed(self, key_num)); + return mp_obj_new_bool(common_hal_keypad_shiftregisterkeys_pressed(self, key_number)); } MP_DEFINE_CONST_FUN_OBJ_2(keypad_shiftregisterkeys_pressed_obj, keypad_shiftregisterkeys_pressed); -//| def store_states(self, states: _typing.WriteableBuffer) -> None: +//| def get_states_into(self, states: _typing.WriteableBuffer) -> None: //| """Write the states of all the keys into ``states``. //| Write a ``1`` if pressed, and ``0`` if released. -//| The ``length`` of ``states`` must be `num_keys`. +//| The ``length`` of ``states`` must be `key_count`. //| This is a debounced read of the state of all the keys, and bypasses the `events` `EventQueue`. //| The read is done atomically. //| """ //| ... //| -STATIC mp_obj_t keypad_shiftregisterkeys_store_states(mp_obj_t self_in, mp_obj_t pressed) { +STATIC mp_obj_t keypad_shiftregisterkeys_get_states_into(mp_obj_t self_in, mp_obj_t pressed) { keypad_shiftregisterkeys_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -194,13 +192,13 @@ STATIC mp_obj_t keypad_shiftregisterkeys_store_states(mp_obj_t self_in, mp_obj_t if (bufinfo.typecode != 'b' && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { mp_raise_ValueError_varg(translate("%q must store bytes"), MP_QSTR_pressed); } - (void)mp_arg_validate_length_with_name(bufinfo.len, common_hal_keypad_shiftregisterkeys_get_num_keys(self), - MP_QSTR_states, MP_QSTR_num_keys); + (void)mp_arg_validate_length_with_name(bufinfo.len, common_hal_keypad_shiftregisterkeys_get_key_count(self), + MP_QSTR_states, MP_QSTR_key_count); - common_hal_keypad_shiftregisterkeys_store_states(self, (uint8_t *)bufinfo.buf); + common_hal_keypad_shiftregisterkeys_get_states_into(self, (uint8_t *)bufinfo.buf); return MP_ROM_NONE; } -MP_DEFINE_CONST_FUN_OBJ_2(keypad_shiftregisterkeys_store_states_obj, keypad_shiftregisterkeys_store_states); +MP_DEFINE_CONST_FUN_OBJ_2(keypad_shiftregisterkeys_get_states_into_obj, keypad_shiftregisterkeys_get_states_into); //| events: EventQueue //| """The `EventQueue` associated with this `Keys` object. (read-only) @@ -225,9 +223,9 @@ STATIC const mp_rom_map_elem_t keypad_shiftregisterkeys_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_shiftregisterkeys___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_shiftregisterkeys_events_obj) }, - { MP_ROM_QSTR(MP_QSTR_num_keys), MP_ROM_PTR(&keypad_shiftregisterkeys_num_keys_obj) }, + { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_shiftregisterkeys_key_count_obj) }, { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&keypad_shiftregisterkeys_pressed_obj) }, - { MP_ROM_QSTR(MP_QSTR_store_states), MP_ROM_PTR(&keypad_shiftregisterkeys_store_states_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_states_into), MP_ROM_PTR(&keypad_shiftregisterkeys_get_states_into_obj) }, }; STATIC MP_DEFINE_CONST_DICT(keypad_shiftregisterkeys_locals_dict, keypad_shiftregisterkeys_locals_dict_table); diff --git a/shared-bindings/keypad/ShiftRegisterKeys.h b/shared-bindings/keypad/ShiftRegisterKeys.h index 6a27d3cc73..9aced14466 100644 --- a/shared-bindings/keypad/ShiftRegisterKeys.h +++ b/shared-bindings/keypad/ShiftRegisterKeys.h @@ -32,14 +32,14 @@ extern const mp_obj_type_t keypad_shiftregisterkeys_type; -void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, mcu_pin_obj_t *clock_pin, mcu_pin_obj_t *data_pin, mcu_pin_obj_t *latch_pin, bool value_to_latch, size_t num_keys, bool value_when_pressed, mp_float_t interval, size_t max_events); +void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, mcu_pin_obj_t *clock_pin, mcu_pin_obj_t *data_pin, mcu_pin_obj_t *latch_pin, bool value_to_latch, size_t key_count, bool value_when_pressed, mp_float_t interval, size_t max_events); void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self); bool common_hal_keypad_shiftregisterkeys_deinited(keypad_shiftregisterkeys_obj_t *self); mp_obj_t common_hal_keypad_shiftregisterkeys_get_events(keypad_shiftregisterkeys_obj_t *self); -mp_uint_t common_hal_keypad_shiftregisterkeys_get_num_keys(keypad_shiftregisterkeys_obj_t *self); -bool common_hal_keypad_shiftregisterkeys_pressed(keypad_shiftregisterkeys_obj_t *self, mp_uint_t key_num); -void common_hal_keypad_shiftregisterkeys_store_states(keypad_shiftregisterkeys_obj_t *self, uint8_t *states); +mp_uint_t common_hal_keypad_shiftregisterkeys_get_key_count(keypad_shiftregisterkeys_obj_t *self); +bool common_hal_keypad_shiftregisterkeys_pressed(keypad_shiftregisterkeys_obj_t *self, mp_uint_t key_number); +void common_hal_keypad_shiftregisterkeys_get_states_into(keypad_shiftregisterkeys_obj_t *self, uint8_t *states); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_KEYPAD_SHIFTREGISTERKEYS_H diff --git a/shared-module/keypad/Event.c b/shared-module/keypad/Event.c index 21b4ad18d3..d938002cc5 100644 --- a/shared-module/keypad/Event.c +++ b/shared-module/keypad/Event.c @@ -26,13 +26,13 @@ #include "shared-module/keypad/Event.h" -void common_hal_keypad_event_construct(keypad_event_obj_t *self, mp_uint_t key_num, bool pressed) { - self->key_num = key_num; +void common_hal_keypad_event_construct(keypad_event_obj_t *self, mp_int_t key_number, bool pressed) { + self->key_number = key_number; self->pressed = pressed; } -mp_int_t common_hal_keypad_event_get_key_num(keypad_event_obj_t *self) { - return self->key_num; +mp_int_t common_hal_keypad_event_get_key_number(keypad_event_obj_t *self) { + return self->key_number; } bool common_hal_keypad_event_get_pressed(keypad_event_obj_t *self) { diff --git a/shared-module/keypad/Event.h b/shared-module/keypad/Event.h index 4780df0aa2..3c47b0e636 100644 --- a/shared-module/keypad/Event.h +++ b/shared-module/keypad/Event.h @@ -31,7 +31,7 @@ typedef struct { mp_obj_base_t base; - uint16_t key_num; + uint16_t key_number; bool pressed; } keypad_event_obj_t; diff --git a/shared-module/keypad/EventQueue.c b/shared-module/keypad/EventQueue.c index 556e425e4b..204c5d21dc 100644 --- a/shared-module/keypad/EventQueue.c +++ b/shared-module/keypad/EventQueue.c @@ -27,17 +27,17 @@ #include "shared-bindings/keypad/Event.h" #include "shared-module/keypad/EventQueue.h" -// Top bit of 16-bit event indicates pressed or released. Rest is key_num. +// Key number is lower 15 bits of a 16-bit value. #define EVENT_PRESSED (1 << 15) -#define EVENT_RELEASED (0) -#define EVENT_KEY_NUM_MASK (~EVENT_PRESSED) +#define EVENT_KEY_NUM_MASK ((1 << 15) - 1) void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events) { // Event queue is 16-bit values. ringbuf_alloc(&self->encoded_events, max_events * 2, false); + self->overflowed = false; } -mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self) { +mp_obj_t common_hal_keypad_eventqueue_get(keypad_eventqueue_obj_t *self) { int encoded_event = ringbuf_get16(&self->encoded_events); if (encoded_event == -1) { return MP_ROM_NONE; @@ -49,7 +49,7 @@ mp_obj_t common_hal_keypad_eventqueue_next(keypad_eventqueue_obj_t *self) { return MP_OBJ_FROM_PTR(event); } -bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event) { +bool common_hal_keypad_eventqueue_get_into(keypad_eventqueue_obj_t *self, keypad_event_obj_t *event) { int encoded_event = ringbuf_get16(&self->encoded_events); if (encoded_event == -1) { return false; @@ -60,9 +60,6 @@ bool common_hal_keypad_eventqueue_store_next(keypad_eventqueue_obj_t *self, keyp return true; } - - - void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self) { ringbuf_clear(&self->encoded_events); } @@ -71,10 +68,25 @@ size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self) { return ringbuf_num_filled(&self->encoded_events); } -void keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_num, bool pressed) { - if (ringbuf_num_empty(&self->encoded_events) == 0) { - // Discard oldest if full. - ringbuf_get16(&self->encoded_events); - } - ringbuf_put16(&self->encoded_events, key_num | (pressed ? EVENT_PRESSED : EVENT_RELEASED)); +bool common_hal_keypad_eventqueue_get_overflowed(keypad_eventqueue_obj_t *self) { + return self->overflowed; +} + +void common_hal_keypad_eventqueue_set_overflowed(keypad_eventqueue_obj_t *self, bool overflowed) { + self->overflowed = overflowed; +} + +bool keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_number, bool pressed) { + if (ringbuf_num_empty(&self->encoded_events) == 0) { + // Queue is full. The caller will decide what to do, including whether to set the overflowed flag. + return false; + } + + uint16_t encoded_event = key_number & EVENT_KEY_NUM_MASK; + if (pressed) { + encoded_event |= EVENT_PRESSED; + } + ringbuf_put16(&self->encoded_events, encoded_event); + + return true; } diff --git a/shared-module/keypad/EventQueue.h b/shared-module/keypad/EventQueue.h index 88e585b23b..ce5e55ef3b 100644 --- a/shared-module/keypad/EventQueue.h +++ b/shared-module/keypad/EventQueue.h @@ -33,8 +33,9 @@ typedef struct { mp_obj_base_t base; ringbuf_t encoded_events; + bool overflowed; } keypad_eventqueue_obj_t; -void keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_num, bool pressed); +bool keypad_eventqueue_record(keypad_eventqueue_obj_t *self, mp_uint_t key_number, bool pressed); #endif // MICROPY_INCLUDED_SHARED_MODULE_KEYPAD_EVENTQUEUE_H diff --git a/shared-module/keypad/KeyMatrix.c b/shared-module/keypad/KeyMatrix.c index 8ac3abe837..3cf7c89a91 100644 --- a/shared-module/keypad/KeyMatrix.c +++ b/shared-module/keypad/KeyMatrix.c @@ -36,11 +36,11 @@ #include "supervisor/port.h" #include "supervisor/shared/tick.h" -static mp_uint_t row_col_to_key_num(keypad_keymatrix_obj_t *self, mp_uint_t row, mp_uint_t col) { - return row * self->col_digitalinouts->len + col; +static mp_uint_t row_column_to_key_number(keypad_keymatrix_obj_t *self, mp_uint_t row, mp_uint_t column) { + return row * self->column_digitalinouts->len + column; } -void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint_t num_row_pins, mcu_pin_obj_t *row_pins[], mp_uint_t num_col_pins, mcu_pin_obj_t *col_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, mcu_pin_obj_t *row_pins[], mp_uint_t num_column_pins, mcu_pin_obj_t *column_pins[], bool columns_to_anodes, mp_float_t interval, size_t max_events) { mp_obj_t row_dios[num_row_pins]; for (size_t row = 0; row < num_row_pins; row++) { @@ -52,18 +52,18 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint } self->row_digitalinouts = mp_obj_new_tuple(num_row_pins, row_dios); - mp_obj_t col_dios[num_col_pins]; - for (size_t col = 0; col < num_col_pins; col++) { + mp_obj_t column_dios[num_column_pins]; + for (size_t column = 0; column < num_column_pins; column++) { digitalio_digitalinout_obj_t *dio = m_new_obj(digitalio_digitalinout_obj_t); dio->base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(dio, col_pins[col]); + common_hal_digitalio_digitalinout_construct(dio, column_pins[column]); common_hal_digitalio_digitalinout_switch_to_input(dio, columns_to_anodes ? PULL_UP : PULL_DOWN); - col_dios[col] = dio; + column_dios[column] = dio; } - self->col_digitalinouts = mp_obj_new_tuple(num_col_pins, col_dios); + self->column_digitalinouts = mp_obj_new_tuple(num_column_pins, column_dios); - self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * num_row_pins * num_col_pins, false, false); - self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * num_row_pins * num_col_pins, false, false); + self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * num_row_pins * num_column_pins, false, false); + self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * num_row_pins * num_column_pins, false, false); self->columns_to_anodes = columns_to_anodes; @@ -89,47 +89,53 @@ void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self) { // Remove self from the list of active keypad scanners first. keypad_deregister_scanner((keypad_scanner_obj_t *)self); - for (size_t row = 0; row < common_hal_keypad_keymatrix_get_num_rows(self); row++) { + for (size_t row = 0; row < common_hal_keypad_keymatrix_get_row_count(self); row++) { common_hal_digitalio_digitalinout_deinit(self->row_digitalinouts->items[row]); } self->row_digitalinouts = MP_ROM_NONE; - for (size_t col = 0; col < common_hal_keypad_keymatrix_get_num_cols(self); col++) { - common_hal_digitalio_digitalinout_deinit(self->col_digitalinouts->items[col]); + for (size_t column = 0; column < common_hal_keypad_keymatrix_get_column_count(self); column++) { + common_hal_digitalio_digitalinout_deinit(self->column_digitalinouts->items[column]); } - self->col_digitalinouts = MP_ROM_NONE; + self->column_digitalinouts = MP_ROM_NONE; } bool common_hal_keypad_keymatrix_deinited(keypad_keymatrix_obj_t *self) { return self->row_digitalinouts == MP_ROM_NONE; } -size_t common_hal_keypad_keymatrix_get_num_keys(keypad_keymatrix_obj_t *self) { - return common_hal_keypad_keymatrix_get_num_rows(self) * common_hal_keypad_keymatrix_get_num_cols(self); +size_t common_hal_keypad_keymatrix_get_key_count(keypad_keymatrix_obj_t *self) { + return common_hal_keypad_keymatrix_get_row_count(self) * common_hal_keypad_keymatrix_get_column_count(self); } -size_t common_hal_keypad_keymatrix_get_num_rows(keypad_keymatrix_obj_t *self) { +size_t common_hal_keypad_keymatrix_get_row_count(keypad_keymatrix_obj_t *self) { return self->row_digitalinouts->len; } -size_t common_hal_keypad_keymatrix_get_num_cols(keypad_keymatrix_obj_t *self) { - return self->col_digitalinouts->len; +size_t common_hal_keypad_keymatrix_get_column_count(keypad_keymatrix_obj_t *self) { + return self->column_digitalinouts->len; } -bool common_hal_keypad_keymatrix_pressed(keypad_keymatrix_obj_t *self, mp_uint_t key_num) { - return self->currently_pressed[key_num]; +bool common_hal_keypad_keymatrix_pressed(keypad_keymatrix_obj_t *self, mp_uint_t key_number) { + return self->currently_pressed[key_number]; } // The length of states has already been validated. -void common_hal_keypad_keymatrix_store_states(keypad_keymatrix_obj_t *self, uint8_t *states) { +void common_hal_keypad_keymatrix_get_states_into(keypad_keymatrix_obj_t *self, uint8_t *states) { // Read the state atomically. supervisor_acquire_lock(&keypad_scanners_linked_list_lock); - memcpy(states, self->currently_pressed, common_hal_keypad_keymatrix_get_num_keys(self)); + memcpy(states, self->currently_pressed, common_hal_keypad_keymatrix_get_key_count(self)); supervisor_release_lock(&keypad_scanners_linked_list_lock); } -mp_uint_t common_hal_keypad_keymatrix_key_num(keypad_keymatrix_obj_t *self, mp_uint_t row, mp_uint_t col) { - return row_col_to_key_num(self, row, col); +mp_uint_t common_hal_keypad_keymatrix_row_column_to_key_number(keypad_keymatrix_obj_t *self, mp_uint_t row, mp_uint_t column) { + return row_column_to_key_number(self, row, column); +} + +void common_hal_keypad_keymatrix_key_number_to_row_column(keypad_keymatrix_obj_t *self, mp_uint_t key_number, mp_uint_t *row, mp_uint_t *column) { + const size_t num_columns = common_hal_keypad_keymatrix_get_column_count(self); + *row = key_number / num_columns; + *column = key_number % num_columns; } mp_obj_t common_hal_keypad_keymatrix_get_events(keypad_keymatrix_obj_t *self) { @@ -147,28 +153,35 @@ void keypad_keymatrix_scan(keypad_keymatrix_obj_t *self) { // On entry, all pins are set to inputs with a pull-up or pull-down, // depending on the diode orientation. - for (size_t row = 0; row < common_hal_keypad_keymatrix_get_num_rows(self); row++) { + for (size_t row = 0; row < common_hal_keypad_keymatrix_get_row_count(self); row++) { // Switch this row to an output and set level appropriately // Set low if columns_to_anodes is true, else set high. common_hal_digitalio_digitalinout_switch_to_output( self->row_digitalinouts->items[row], !self->columns_to_anodes, DRIVE_MODE_PUSH_PULL); - for (size_t col = 0; col < common_hal_keypad_keymatrix_get_num_cols(self); col++) { - mp_uint_t key_num = row_col_to_key_num(self, row, col); - const bool previous = self->currently_pressed[key_num]; - self->previously_pressed[key_num] = previous; + 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 col got pulled to the row value or not. + // 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. // If high and columns_to_anodes is false, the key is pressed. const bool current = - common_hal_digitalio_digitalinout_get_value(self->col_digitalinouts->items[col]) != + common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]) != self->columns_to_anodes; - self->currently_pressed[key_num] = current; + self->currently_pressed[key_number] = current; // Record any transitions. if (previous != current) { - keypad_eventqueue_record(self->events, key_num, current); + if (!keypad_eventqueue_record(self->events, key_number, current)) { + // The event queue is full. Reset all states to initial values and set the overflowed flag. + const size_t key_count = common_hal_keypad_keymatrix_get_key_count(self); + memset(self->previously_pressed, false, key_count); + memset(self->currently_pressed, false, key_count); + + common_hal_keypad_eventqueue_set_overflowed(self->events, true); + } } } diff --git a/shared-module/keypad/KeyMatrix.h b/shared-module/keypad/KeyMatrix.h index 4f789aa382..bd7e2d23e2 100644 --- a/shared-module/keypad/KeyMatrix.h +++ b/shared-module/keypad/KeyMatrix.h @@ -39,7 +39,7 @@ typedef struct { // All scanners have a next field here, to keep a linked list of active scanners. keypad_scanner_obj_t *next; mp_obj_tuple_t *row_digitalinouts; - mp_obj_tuple_t *col_digitalinouts; + mp_obj_tuple_t *column_digitalinouts; mp_uint_t interval_ticks; uint64_t last_scan_ticks; bool *previously_pressed; diff --git a/shared-module/keypad/Keys.c b/shared-module/keypad/Keys.c index 5f5d2f3880..9443da85b6 100644 --- a/shared-module/keypad/Keys.c +++ b/shared-module/keypad/Keys.c @@ -75,7 +75,7 @@ void common_hal_keypad_keys_deinit(keypad_keys_obj_t *self) { // Remove self from the list of active keypad scanners first. keypad_deregister_scanner((keypad_scanner_obj_t *)self); - for (size_t key = 0; key < common_hal_keypad_keys_get_num_keys(self); key++) { + for (size_t key = 0; key < common_hal_keypad_keys_get_key_count(self); key++) { common_hal_digitalio_digitalinout_deinit(self->digitalinouts->items[key]); } self->digitalinouts = MP_ROM_NONE; @@ -86,18 +86,18 @@ bool common_hal_keypad_keys_deinited(keypad_keys_obj_t *self) { return self->digitalinouts == MP_ROM_NONE; } -size_t common_hal_keypad_keys_get_num_keys(keypad_keys_obj_t *self) { +size_t common_hal_keypad_keys_get_key_count(keypad_keys_obj_t *self) { return self->digitalinouts->len; } -bool common_hal_keypad_keys_pressed(keypad_keys_obj_t *self, mp_uint_t key_num) { - return self->currently_pressed[key_num]; +bool common_hal_keypad_keys_pressed(keypad_keys_obj_t *self, mp_uint_t key_number) { + return self->currently_pressed[key_number]; } // The length of states has already been validated. -void common_hal_keypad_keys_store_states(keypad_keys_obj_t *self, uint8_t *states) { +void common_hal_keypad_keys_get_states_into(keypad_keys_obj_t *self, uint8_t *states) { // Read the state atomically. supervisor_acquire_lock(&keypad_scanners_linked_list_lock); - memcpy(states, self->currently_pressed, common_hal_keypad_keys_get_num_keys(self)); + memcpy(states, self->currently_pressed, common_hal_keypad_keys_get_key_count(self)); supervisor_release_lock(&keypad_scanners_linked_list_lock); } @@ -114,20 +114,28 @@ void keypad_keys_scan(keypad_keys_obj_t *self) { self->last_scan_ticks = now; - for (mp_uint_t key_num = 0; key_num < common_hal_keypad_keys_get_num_keys(self); key_num++) { + const size_t key_count = common_hal_keypad_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_num]; - self->previously_pressed[key_num] = previous; + 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_num]) == + common_hal_digitalio_digitalinout_get_value(self->digitalinouts->items[key_number]) == self->value_when_pressed; - self->currently_pressed[key_num] = current; + self->currently_pressed[key_number] = current; // Record any transitions. if (previous != current) { - keypad_eventqueue_record(self->events, key_num, current); + if (!keypad_eventqueue_record(self->events, key_number, current)) { + // The event queue is full. Reset all states to initial values and set the overflowed flag. + memset(self->previously_pressed, false, key_count); + memset(self->currently_pressed, false, key_count); + + common_hal_keypad_eventqueue_set_overflowed(self->events, true); + } } } } diff --git a/shared-module/keypad/ShiftRegisterKeys.c b/shared-module/keypad/ShiftRegisterKeys.c index 5d7d956632..21bf103642 100644 --- a/shared-module/keypad/ShiftRegisterKeys.c +++ b/shared-module/keypad/ShiftRegisterKeys.c @@ -35,7 +35,7 @@ #include "supervisor/port.h" #include "supervisor/shared/tick.h" -void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, mcu_pin_obj_t *clock_pin, mcu_pin_obj_t *data_pin, mcu_pin_obj_t *latch_pin, bool value_to_latch, size_t num_keys, bool value_when_pressed, mp_float_t interval, size_t max_events) { +void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, mcu_pin_obj_t *clock_pin, mcu_pin_obj_t *data_pin, mcu_pin_obj_t *latch_pin, bool value_to_latch, size_t key_count, bool value_when_pressed, mp_float_t interval, size_t max_events) { digitalio_digitalinout_obj_t *clock = m_new_obj(digitalio_digitalinout_obj_t); clock->base.type = &digitalio_digitalinout_type; @@ -56,10 +56,10 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ self->latch = latch; self->value_to_latch = value_to_latch; - self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * num_keys, false, false); - self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * num_keys, false, false); + self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * key_count, false, false); + self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * key_count, false, false); self->value_when_pressed = value_when_pressed; - self->num_keys = num_keys; + self->key_count = key_count; self->interval_ticks = (mp_uint_t)(interval * 1024); // interval * 1000 * (1024/1000) self->last_scan_ticks = port_get_raw_ticks(NULL); @@ -98,18 +98,18 @@ bool common_hal_keypad_shiftregisterkeys_deinited(keypad_shiftregisterkeys_obj_t return self->clock == MP_ROM_NONE; } -size_t common_hal_keypad_shiftregisterkeys_get_num_keys(keypad_shiftregisterkeys_obj_t *self) { - return self->num_keys; +size_t common_hal_keypad_shiftregisterkeys_get_key_count(keypad_shiftregisterkeys_obj_t *self) { + return self->key_count; } -bool common_hal_keypad_shiftregisterkeys_pressed(keypad_shiftregisterkeys_obj_t *self, mp_uint_t key_num) { - return self->currently_pressed[key_num]; +bool common_hal_keypad_shiftregisterkeys_pressed(keypad_shiftregisterkeys_obj_t *self, mp_uint_t key_number) { + return self->currently_pressed[key_number]; } // The length of states has already been validated. -void common_hal_keypad_shiftregisterkeys_store_states(keypad_shiftregisterkeys_obj_t *self, uint8_t *states) { +void common_hal_keypad_shiftregisterkeys_get_states_into(keypad_shiftregisterkeys_obj_t *self, uint8_t *states) { // Read the state atomically. supervisor_acquire_lock(&keypad_scanners_linked_list_lock); - memcpy(states, self->currently_pressed, common_hal_keypad_shiftregisterkeys_get_num_keys(self)); + memcpy(states, self->currently_pressed, common_hal_keypad_shiftregisterkeys_get_key_count(self)); supervisor_release_lock(&keypad_scanners_linked_list_lock); } @@ -129,25 +129,33 @@ void keypad_shiftregisterkeys_scan(keypad_shiftregisterkeys_obj_t *self) { // Latch (freeze) the current state of the input pins. common_hal_digitalio_digitalinout_set_value(self->latch, self->value_to_latch); - for (mp_uint_t key_num = 0; key_num < common_hal_keypad_shiftregisterkeys_get_num_keys(self); key_num++) { + const size_t key_count = common_hal_keypad_shiftregisterkeys_get_key_count(self); + + for (mp_uint_t key_number = 0; key_number < key_count; key_number++) { // Zero-th data appears on on the data pin immediately, without shifting. common_hal_digitalio_digitalinout_set_value(self->clock, false); // Remember the previous up/down state. - const bool previous = self->currently_pressed[key_num]; - self->previously_pressed[key_num] = previous; + 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->data) == self->value_when_pressed; - self->currently_pressed[key_num] = current; + self->currently_pressed[key_number] = current; // Trigger a shift to get the next bit. common_hal_digitalio_digitalinout_set_value(self->clock, true); // Record any transitions. if (previous != current) { - keypad_eventqueue_record(self->events, key_num, current); + if (!keypad_eventqueue_record(self->events, key_number, current)) { + // The event queue is full. Reset all states to initial values and set the overflowed flag. + memset(self->previously_pressed, false, key_count); + memset(self->currently_pressed, false, key_count); + + common_hal_keypad_eventqueue_set_overflowed(self->events, true); + } } } diff --git a/shared-module/keypad/ShiftRegisterKeys.h b/shared-module/keypad/ShiftRegisterKeys.h index c685a7141c..b04c622679 100644 --- a/shared-module/keypad/ShiftRegisterKeys.h +++ b/shared-module/keypad/ShiftRegisterKeys.h @@ -41,7 +41,7 @@ typedef struct { digitalio_digitalinout_obj_t *clock; digitalio_digitalinout_obj_t *data; digitalio_digitalinout_obj_t *latch; - size_t num_keys; + size_t key_count; mp_uint_t interval_ticks; uint64_t last_scan_ticks; bool *previously_pressed;