|
35 | 35 | #include "supervisor/shared/translate.h" |
36 | 36 | #include "GamePad.h" |
37 | 37 |
|
| 38 | +digitalio_digitalinout_obj_t *validate_pin(mp_obj_t obj) { |
| 39 | + if (!MP_OBJ_IS_TYPE(obj, &digitalio_digitalinout_type)) { |
| 40 | + mp_raise_TypeError(translate("expected a DigitalInOut")); |
| 41 | + } |
| 42 | + digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(obj); |
| 43 | + raise_error_if_deinited( |
| 44 | + common_hal_digitalio_digitalinout_deinited(pin)); |
| 45 | + return pin; |
| 46 | +} |
38 | 47 |
|
39 | 48 | //| .. currentmodule:: gamepad |
40 | 49 | //| |
@@ -100,19 +109,52 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args, |
100 | 109 | mp_raise_TypeError(translate("too many arguments")); |
101 | 110 | } |
102 | 111 | for (size_t i = 0; i < n_args; ++i) { |
103 | | - if (!MP_OBJ_IS_TYPE(args[i], &digitalio_digitalinout_type)) { |
104 | | - mp_raise_TypeError(translate("expected a DigitalInOut")); |
105 | | - } |
106 | | - digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(args[i]); |
107 | | - raise_error_if_deinited( |
108 | | - common_hal_digitalio_digitalinout_deinited(pin)); |
| 112 | + validate_pin(args[i]); |
| 113 | + } |
| 114 | + if (!MP_STATE_VM(gamepad_singleton)) { |
| 115 | + gamepad_obj_t* gamepad_singleton = m_new_obj(gamepad_obj_t); |
| 116 | + gamepad_singleton->base.type = &gamepad_type; |
| 117 | + MP_STATE_VM(gamepad_singleton) = gc_make_long_lived(gamepad_singleton); |
109 | 118 | } |
| 119 | + gamepad_init_pins(n_args, args); |
| 120 | + return MP_OBJ_FROM_PTR(MP_STATE_VM(gamepad_singleton)); |
| 121 | +} |
| 122 | + |
| 123 | + |
| 124 | +//| .. class:: GamePadShift(data, clock, latch) |
| 125 | +//| |
| 126 | +//| Initializes button scanning routines. |
| 127 | +//| |
| 128 | +//| The ``data``, ``clock`` and ``latch`` parameters are ``DigitalInOut`` |
| 129 | +//| objects connected to the shift register controlling the buttons. |
| 130 | +//| |
| 131 | +//| They button presses are accumulated, until the ``get_pressed`` method |
| 132 | +//| is called, at which point the button state is cleared, and the new |
| 133 | +//| button presses start to be recorded. |
| 134 | +//| |
| 135 | +STATIC mp_obj_t gamepadshift_make_new(const mp_obj_type_t *type, size_t n_args, |
| 136 | + const mp_obj_t *pos_args, mp_map_t *kw_args) { |
| 137 | + |
| 138 | + enum { ARG_data, ARG_clock, ARG_latch }; |
| 139 | + static const mp_arg_t allowed_args[] = { |
| 140 | + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, |
| 141 | + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ}, |
| 142 | + { MP_QSTR_latch, MP_ARG_REQUIRED | MP_ARG_OBJ}, |
| 143 | + }; |
| 144 | + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; |
| 145 | + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), |
| 146 | + allowed_args, args); |
| 147 | + |
| 148 | + digitalio_digitalinout_obj_t *data_pin = validate_pin(args[ARG_data].u_obj); |
| 149 | + digitalio_digitalinout_obj_t *clock_pin = validate_pin(args[ARG_clock].u_obj); |
| 150 | + digitalio_digitalinout_obj_t *latch_pin = validate_pin(args[ARG_latch].u_obj); |
| 151 | + |
110 | 152 | if (!MP_STATE_VM(gamepad_singleton)) { |
111 | 153 | gamepad_obj_t* gamepad_singleton = m_new_obj(gamepad_obj_t); |
112 | 154 | gamepad_singleton->base.type = &gamepad_type; |
113 | 155 | MP_STATE_VM(gamepad_singleton) = gc_make_long_lived(gamepad_singleton); |
114 | 156 | } |
115 | | - gamepad_init(n_args, args); |
| 157 | + gamepad_init_shift(data_pin, clock_pin, latch_pin); |
116 | 158 | return MP_OBJ_FROM_PTR(MP_STATE_VM(gamepad_singleton)); |
117 | 159 | } |
118 | 160 |
|
@@ -158,3 +200,15 @@ const mp_obj_type_t gamepad_type = { |
158 | 200 | .make_new = gamepad_make_new, |
159 | 201 | .locals_dict = (mp_obj_dict_t*)&gamepad_locals_dict, |
160 | 202 | }; |
| 203 | + |
| 204 | +STATIC const mp_rom_map_elem_t gamepadshift_locals_dict_table[] = { |
| 205 | + { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&gamepad_get_pressed_obj)}, |
| 206 | + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gamepad_deinit_obj)}, |
| 207 | +}; |
| 208 | +STATIC MP_DEFINE_CONST_DICT(gamepadshift_locals_dict, gamepadshift_locals_dict_table); |
| 209 | +const mp_obj_type_t gamepadshift_type = { |
| 210 | + { &mp_type_type }, |
| 211 | + .name = MP_QSTR_GamePadShift, |
| 212 | + .make_new = gamepadshift_make_new, |
| 213 | + .locals_dict = (mp_obj_dict_t*)&gamepadshift_locals_dict, |
| 214 | +}; |
0 commit comments