41
41
//| self,
42
42
//| *,
43
43
//| clock: microcontroller.Pin,
44
- //| data: microcontroller.Pin,
44
+ //| data: Union[ microcontroller.Pin, Sequence[microcontroller.Pin]] ,
45
45
//| latch: microcontroller.Pin,
46
46
//| value_to_latch: bool = True,
47
- //| key_count: int,
47
+ //| key_count: Union[ int, Sequence[int]] ,
48
48
//| value_when_pressed: bool,
49
49
//| interval: float = 0.020,
50
50
//| max_events: int = 64
53
53
//| Create a `Keys` object that will scan keys attached to a parallel-in serial-out shift register
54
54
//| like the 74HC165 or CD4021.
55
55
//| 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.
56
57
//|
57
58
//| Key number 0 is the first (or more properly, the zero-th) bit read. In the
58
59
//| 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.
59
61
//|
60
62
//| An `EventQueue` is created when this object is created and is available in the `events` attribute.
61
63
//|
62
64
//| :param microcontroller.Pin clock: The shift register clock pin.
63
65
//| 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)
65
67
//| :param microcontroller.Pin latch:
66
68
//| Pin used to latch parallel data going into the shift register.
67
69
//| :param bool value_to_latch: Pin state to latch data being read.
68
70
//| ``True`` if the data is latched when ``latch`` goes high
69
71
//| ``False`` if the data is latched when ``latch`` goes low.
70
72
//| The default is ``True``, which is how the 74HC165 operates. The CD4021 latch is the opposite.
71
73
//| 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)
73
75
//| :param bool value_when_pressed: ``True`` if the pin reads high when the key is pressed.
74
76
//| ``False`` if the pin reads low (is grounded) when the key is pressed.
75
77
//| :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
91
93
{ MP_QSTR_data , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
92
94
{ MP_QSTR_latch , MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
93
95
{ 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 },
95
97
{ MP_QSTR_value_when_pressed , MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_BOOL },
96
98
{ MP_QSTR_interval , MP_ARG_KW_ONLY | MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
97
99
{ MP_QSTR_max_events , MP_ARG_KW_ONLY | MP_ARG_INT , {.u_int = 64 } },
98
100
};
99
101
mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
100
102
mp_arg_parse_all_kw_array (n_args , n_kw , all_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
101
103
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
+
102
148
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 );
104
149
const mcu_pin_obj_t * latch = validate_obj_is_free_pin (args [ARG_latch ].u_obj , MP_QSTR_latch );
105
150
const bool value_to_latch = args [ARG_value_to_latch ].u_bool ;
106
151
107
- const size_t key_count = (size_t )mp_arg_validate_int_min (args [ARG_key_count ].u_int , 1 , MP_QSTR_key_count );
108
152
const bool value_when_pressed = args [ARG_value_when_pressed ].u_bool ;
109
153
const mp_float_t interval =
110
154
mp_arg_validate_obj_float_non_negative (args [ARG_interval ].u_obj , 0.020f , MP_QSTR_interval );
111
155
const size_t max_events = (size_t )mp_arg_validate_int_min (args [ARG_max_events ].u_int , 1 , MP_QSTR_max_events );
112
156
113
157
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 );
115
159
116
160
return MP_OBJ_FROM_PTR (self );
161
+
117
162
#else
118
163
mp_raise_NotImplementedError_varg (translate ("%q" ), MP_QSTR_ShiftRegisterKeys );
119
164
#endif
@@ -155,7 +200,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_shiftregisterkeys___exit___obj
155
200
//| ...
156
201
157
202
//| 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)
159
204
//| """
160
205
161
206
//| events: EventQueue
0 commit comments