4141//| self,
4242//| *,
4343//| clock: microcontroller.Pin,
44- //| data: microcontroller.Pin,
44+ //| data: Union[ microcontroller.Pin, Sequence[microcontroller.Pin]] ,
4545//| latch: microcontroller.Pin,
4646//| value_to_latch: bool = True,
47- //| key_count: int,
47+ //| key_count: Union[ int, Sequence[int]] ,
4848//| value_when_pressed: bool,
4949//| interval: float = 0.020,
5050//| max_events: int = 64
5353//| Create a `Keys` object that will scan keys attached to a parallel-in serial-out shift register
5454//| like the 74HC165 or CD4021.
5555//| Note that you may chain shift registers to load in as many values as you need.
56+ //| Furthermore, you can put multiple shift registers in parallel and share clock and latch.
5657//|
5758//| Key number 0 is the first (or more properly, the zero-th) bit read. In the
5859//| 74HC165, this bit is labeled ``Q7``. Key number 1 will be the value of ``Q6``, etc.
60+ //| With multiple data pins, key numbers of the next pin are sequentially to the current pin.
5961//|
6062//| An `EventQueue` is created when this object is created and is available in the `events` attribute.
6163//|
6264//| :param microcontroller.Pin clock: The shift register clock pin.
6365//| The shift register should clock on a low-to-high transition.
64- //| :param microcontroller.Pin data: the incoming shift register data pin
66+ //| :param Union[ microcontroller.Pin, Sequence[microcontroller.Pin]] data: the incoming shift register data pin(s)
6567//| :param microcontroller.Pin latch:
6668//| Pin used to latch parallel data going into the shift register.
6769//| :param bool value_to_latch: Pin state to latch data being read.
6870//| ``True`` if the data is latched when ``latch`` goes high
6971//| ``False`` if the data is latched when ``latch`` goes low.
7072//| The default is ``True``, which is how the 74HC165 operates. The CD4021 latch is the opposite.
7173//| Once the data is latched, it will be shifted out by toggling the clock pin.
72- //| :param int key_count: number of data lines to clock in
74+ //| :param Union[ int, Sequence[int]] key_count: number of data lines to clock in (per data pin)
7375//| :param bool value_when_pressed: ``True`` if the pin reads high when the key is pressed.
7476//| ``False`` if the pin reads low (is grounded) when the key is pressed.
7577//| :param float interval: Scan keys no more often than ``interval`` to allow for debouncing.
@@ -91,29 +93,72 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz
9193 { MP_QSTR_data , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
9294 { MP_QSTR_latch , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
9395 { MP_QSTR_value_to_latch , MP_ARG_KW_ONLY | MP_ARG_BOOL , {.u_bool = true} },
94- { MP_QSTR_key_count , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
96+ { MP_QSTR_key_count , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
9597 { MP_QSTR_value_when_pressed , MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_BOOL },
9698 { MP_QSTR_interval , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
9799 { MP_QSTR_max_events , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 64 } },
98100 };
99101 mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
100102 mp_arg_parse_all_kw_array (n_args , n_kw , all_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
101103
104+ size_t num_data_pins ;
105+
106+ if (mp_obj_is_type (args [ARG_data ].u_obj , & mcu_pin_type )) {
107+ num_data_pins = 1 ;
108+ } else {
109+ num_data_pins = (size_t )MP_OBJ_SMALL_INT_VALUE (mp_obj_len (args [ARG_data ].u_obj ));
110+ }
111+
112+ const mcu_pin_obj_t * data_pins_array [num_data_pins ];
113+
114+ if (mp_obj_is_type (args [ARG_data ].u_obj , & mcu_pin_type )) {
115+ const mcu_pin_obj_t * datapin = validate_obj_is_free_pin (args [ARG_data ].u_obj , MP_QSTR_data );
116+ data_pins_array [0 ] = datapin ;
117+ } else {
118+ for (size_t pin = 0 ; pin < num_data_pins ; pin ++ ) {
119+ const mcu_pin_obj_t * datapin =
120+ validate_obj_is_free_pin (mp_obj_subscr (args [ARG_data ].u_obj , MP_OBJ_NEW_SMALL_INT (pin ), MP_OBJ_SENTINEL ), MP_QSTR_data );
121+ data_pins_array [pin ] = datapin ;
122+ }
123+ }
124+
125+ size_t num_key_counts ;
126+
127+ if (mp_obj_is_int (args [ARG_key_count ].u_obj )) {
128+ num_key_counts = 1 ;
129+ } else {
130+ num_key_counts = (size_t )MP_OBJ_SMALL_INT_VALUE (mp_obj_len (args [ARG_key_count ].u_obj ));
131+ }
132+
133+ mp_arg_validate_length (num_key_counts , num_data_pins , MP_QSTR_key_count );
134+
135+ size_t key_count_array [num_key_counts ];
136+
137+ if (mp_obj_is_int (args [ARG_key_count ].u_obj )) {
138+ const size_t key_count = (size_t )mp_arg_validate_int_min (args [ARG_key_count ].u_int , 1 , MP_QSTR_key_count );
139+ key_count_array [0 ] = key_count ;
140+ } else {
141+ for (size_t kc = 0 ; kc < num_key_counts ; kc ++ ) {
142+ mp_int_t mpint = mp_obj_get_int (mp_obj_subscr (args [ARG_key_count ].u_obj , MP_OBJ_NEW_SMALL_INT (kc ), MP_OBJ_SENTINEL ));
143+ const size_t key_count = (size_t )mp_arg_validate_int_min (mpint , 1 , MP_QSTR_key_count );
144+ key_count_array [kc ] = key_count ;
145+ }
146+ }
147+
102148 const mcu_pin_obj_t * clock = validate_obj_is_free_pin (args [ARG_clock ].u_obj , MP_QSTR_clock );
103- const mcu_pin_obj_t * data = validate_obj_is_free_pin (args [ARG_data ].u_obj , MP_QSTR_data );
104149 const mcu_pin_obj_t * latch = validate_obj_is_free_pin (args [ARG_latch ].u_obj , MP_QSTR_latch );
105150 const bool value_to_latch = args [ARG_value_to_latch ].u_bool ;
106151
107- const size_t key_count = (size_t )mp_arg_validate_int_min (args [ARG_key_count ].u_int , 1 , MP_QSTR_key_count );
108152 const bool value_when_pressed = args [ARG_value_when_pressed ].u_bool ;
109153 const mp_float_t interval =
110154 mp_arg_validate_obj_float_non_negative (args [ARG_interval ].u_obj , 0.020f , MP_QSTR_interval );
111155 const size_t max_events = (size_t )mp_arg_validate_int_min (args [ARG_max_events ].u_int , 1 , MP_QSTR_max_events );
112156
113157 common_hal_keypad_shiftregisterkeys_construct (
114- self , clock , data , latch , value_to_latch , key_count , value_when_pressed , interval , max_events );
158+ self , clock , num_data_pins , data_pins_array , latch , value_to_latch , num_key_counts , key_count_array , value_when_pressed , interval , max_events );
115159
116160 return MP_OBJ_FROM_PTR (self );
161+
117162 #else
118163 mp_raise_NotImplementedError_varg (translate ("%q" ), MP_QSTR_ShiftRegisterKeys );
119164 #endif
@@ -155,7 +200,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_shiftregisterkeys___exit___obj
155200//| ...
156201
157202//| key_count: int
158- //| """The number of keys that are being scanned. (read-only)
203+ //| """The total number of keys that are being scanned. (read-only)
159204//| """
160205
161206//| events: EventQueue
0 commit comments