Skip to content

Commit f052dc4

Browse files
committed
ShiftRegisterKeys: allow specifying sense of latch
1 parent 8c74b4a commit f052dc4

File tree

4 files changed

+18
-11
lines changed

4 files changed

+18
-11
lines changed

shared-bindings/keypad/ShiftRegisterKeys.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
//| class ShiftRegisterKeys:
3737
//| """Manage a set of keys attached to an incoming shift register."""
3838
//|
39-
//| def __init__(self, clock: microcontroller.Pin, data: microcontroller.Pin, latch: microcontroller.Pin, value_when_pressed: bool, interval: float = 0.020, max_events: int = 64) -> None:
39+
//| 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:
4040
//| """
4141
//| Create a `Keys` object that will scan keys attached to a parallel-in serial-out shift register
42-
//| like the 74HC165 or equivalent.
42+
//| like the 74HC165 or CD4021.
4343
//| Note that you may chain shift registers to load in as many values as you need.
4444
//|
4545
//| Key number 0 is the first (or more properly, the zero-th) bit read. In the
@@ -53,8 +53,12 @@
5353
//| The shift register should clock on a low-to-high transition.
5454
//| :param microcontroller.Pin data: the incoming shift register data pin
5555
//| :param microcontroller.Pin latch:
56-
//| Pin used to trigger loading parallel data pins into the shift register.
57-
//| Active low: pull low to load the data.
56+
//| Pin used to latch parallel data going into the shift register.
57+
//| :param bool value_to_latch: Pin state to latch data being read.
58+
//| ``True`` if the data is latched when ``latch`` goes high
59+
//| ``False`` if the data is latched when ``latch goes low.
60+
//| The default is ``True``, which is how the 74HC165 operates. The CD4021 latch is the opposite.
61+
//| Once the data is latched, it will be shifted out by toggling the clock pin.
5862
//| :param int num_keys: number of data lines to clock in
5963
//| :param bool value_when_pressed: ``True`` if the pin reads high when the key is pressed.
6064
//| ``False`` if the pin reads low (is grounded) when the key is pressed.
@@ -70,11 +74,12 @@
7074
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) {
7175
keypad_shiftregisterkeys_obj_t *self = m_new_obj(keypad_shiftregisterkeys_obj_t);
7276
self->base.type = &keypad_shiftregisterkeys_type;
73-
enum { ARG_clock, ARG_data, ARG_latch, ARG_num_keys, ARG_value_when_pressed, ARG_interval, ARG_max_events };
77+
enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_num_keys, ARG_value_when_pressed, ARG_interval, ARG_max_events };
7478
static const mp_arg_t allowed_args[] = {
7579
{ MP_QSTR_clock, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
7680
{ MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
7781
{ MP_QSTR_latch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
82+
{ MP_QSTR_value_to_latch, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
7883
{ MP_QSTR_num_keys, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
7984
{ MP_QSTR_value_when_pressed, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_BOOL },
8085
{ MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
@@ -86,6 +91,7 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz
8691
mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj);
8792
mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj);
8893
mcu_pin_obj_t *latch = validate_obj_is_free_pin(args[ARG_latch].u_obj);
94+
const bool value_to_latch = args[ARG_value_to_latch].u_bool;
8995

9096
const size_t num_keys = (size_t)mp_arg_validate_int_min(args[ARG_num_keys].u_int, 1, MP_QSTR_num_keys);
9197
const bool value_when_pressed = args[ARG_value_when_pressed].u_bool;
@@ -94,7 +100,7 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz
94100
const size_t max_events = (size_t)mp_arg_validate_int_min(args[ARG_max_events].u_int, 1, MP_QSTR_max_events);
95101

96102
common_hal_keypad_shiftregisterkeys_construct(
97-
self, clock, data, latch, num_keys, value_when_pressed, interval, max_events);
103+
self, clock, data, latch, value_to_latch, num_keys, value_when_pressed, interval, max_events);
98104

99105
return MP_OBJ_FROM_PTR(self);
100106
}

shared-bindings/keypad/ShiftRegisterKeys.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
extern const mp_obj_type_t keypad_shiftregisterkeys_type;
3434

35-
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, size_t num_keys, bool value_when_pressed, mp_float_t interval, size_t max_events);
35+
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);
3636

3737
void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self);
3838
bool common_hal_keypad_shiftregisterkeys_deinited(keypad_shiftregisterkeys_obj_t *self);

shared-module/keypad/ShiftRegisterKeys.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#include "supervisor/port.h"
3636
#include "supervisor/shared/tick.h"
3737

38-
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, size_t num_keys, bool value_when_pressed, mp_float_t interval, size_t max_events) {
38+
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) {
3939

4040
digitalio_digitalinout_obj_t *clock = m_new_obj(digitalio_digitalinout_obj_t);
4141
clock->base.type = &digitalio_digitalinout_type;
@@ -54,6 +54,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_
5454
common_hal_digitalio_digitalinout_construct(latch, latch_pin);
5555
common_hal_digitalio_digitalinout_switch_to_output(latch, true, DRIVE_MODE_PUSH_PULL);
5656
self->latch = latch;
57+
self->value_to_latch = value_to_latch;
5758

5859
self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * num_keys, false, false);
5960
self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * num_keys, false, false);
@@ -126,7 +127,7 @@ void keypad_shiftregisterkeys_scan(keypad_shiftregisterkeys_obj_t *self) {
126127
self->last_scan_ticks = now;
127128

128129
// Latch (freeze) the current state of the input pins.
129-
common_hal_digitalio_digitalinout_set_value(self->latch, true);
130+
common_hal_digitalio_digitalinout_set_value(self->latch, self->value_to_latch);
130131

131132
for (mp_uint_t key_num = 0; key_num < common_hal_keypad_shiftregisterkeys_get_num_keys(self); key_num++) {
132133
// Zero-th data appears on on the data pin immediately, without shifting.
@@ -151,6 +152,5 @@ void keypad_shiftregisterkeys_scan(keypad_shiftregisterkeys_obj_t *self) {
151152
}
152153

153154
// Start reading the input pins again.
154-
common_hal_digitalio_digitalinout_set_value(self->latch, false);
155-
155+
common_hal_digitalio_digitalinout_set_value(self->latch, !self->value_to_latch);
156156
}

shared-module/keypad/ShiftRegisterKeys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef struct {
4848
bool *currently_pressed;
4949
keypad_eventqueue_obj_t *events;
5050
bool value_when_pressed;
51+
bool value_to_latch;
5152
} keypad_shiftregisterkeys_obj_t;
5253

5354
void keypad_shiftregisterkeys_scan(keypad_shiftregisterkeys_obj_t *self);

0 commit comments

Comments
 (0)