many renamings; add overflowed flag to EventQuque

This commit is contained in:
Dan Halbert 2021-06-23 09:18:40 -04:00
parent f052dc4d8b
commit acf90fbb43
19 changed files with 346 additions and 246 deletions

View File

@ -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, "<Event: keynum %d %s>",
common_hal_keypad_event_get_key_num(self),
mp_printf(print, "<Event: key_number %d %s>",
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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;