33
44#include "py/mpconfig.h"
55
6- #if PYBRICKS_PY_EV3DEVDEVICES
6+ #if PYBRICKS_PY_EV3DEVICES
77
88#include <pybricks/common.h>
99#include <pybricks/ev3devices.h>
1717// pybricks.ev3devices.InfraredSensor class object
1818typedef struct _ev3devices_InfraredSensor_obj_t {
1919 pb_type_device_obj_base_t device_base ;
20+ /** Channel id, cached while awaiting read operation. */
21+ uint8_t current_channel ;
2022} ev3devices_InfraredSensor_obj_t ;
2123
2224// pybricks.ev3devices.InfraredSensor.__init__
@@ -26,32 +28,26 @@ static mp_obj_t ev3devices_InfraredSensor_make_new(const mp_obj_type_t *type, si
2628
2729 ev3devices_InfraredSensor_obj_t * self = mp_obj_malloc (ev3devices_InfraredSensor_obj_t , type );
2830 pb_type_device_init_class (& self -> device_base , port_in , LEGO_DEVICE_TYPE_ID_EV3_IR_SENSOR );
31+ self -> current_channel = 1 ;
2932 return MP_OBJ_FROM_PTR (self );
3033}
3134
3235// pybricks.ev3devices.InfraredSensor.distance
3336static mp_obj_t ev3devices_InfraredSensor_distance (mp_obj_t self_in ) {
34- int8_t * distance = pb_type_device_get_data_blocking (self_in , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__PROX );
37+ int8_t * distance = pb_type_device_get_data (self_in , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__PROX );
3538 return mp_obj_new_int (distance [0 ]);
3639}
37- static MP_DEFINE_CONST_FUN_OBJ_1 (ev3devices_InfraredSensor_distance_obj , ev3devices_InfraredSensor_distance ) ;
40+ static PB_DEFINE_CONST_TYPE_DEVICE_METHOD_OBJ (ev3devices_InfraredSensor_distance_obj , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__PROX , ev3devices_InfraredSensor_distance ) ;
3841
3942// pybricks.ev3devices.InfraredSensor.beacon
40- static mp_obj_t ev3devices_InfraredSensor_beacon ( size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
43+ static mp_obj_t ev3devices_InfraredSensor_beacon_map ( mp_obj_t self_in ) {
4144
42- PB_PARSE_ARGS_METHOD (n_args , pos_args , kw_args ,
43- ev3devices_InfraredSensor_obj_t , self ,
44- PB_ARG_REQUIRED (channel ));
45+ int8_t * beacon_data = pb_type_device_get_data (self_in , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__SEEK );
4546
46- mp_int_t channel = pb_obj_get_int (channel_in );
47- if (channel < 1 || channel > 4 ) {
48- pb_assert (PBIO_ERROR_INVALID_ARG );
49- }
47+ ev3devices_InfraredSensor_obj_t * self = MP_OBJ_TO_PTR (self_in );
5048
51- int8_t * beacon_data = pb_type_device_get_data_blocking (MP_OBJ_FROM_PTR (self ), LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__SEEK );
52-
53- mp_int_t heading = beacon_data [channel * 2 - 2 ] * 3 ;
54- mp_int_t distance = beacon_data [channel * 2 - 1 ];
49+ mp_int_t heading = beacon_data [self -> current_channel * 2 - 2 ] * 3 ;
50+ mp_int_t distance = beacon_data [self -> current_channel * 2 - 1 ];
5551
5652 mp_obj_t ret [2 ];
5753
@@ -65,23 +61,29 @@ static mp_obj_t ev3devices_InfraredSensor_beacon(size_t n_args, const mp_obj_t *
6561
6662 return mp_obj_new_tuple (2 , ret );
6763}
68- static MP_DEFINE_CONST_FUN_OBJ_KW (ev3devices_InfraredSensor_beacon_obj , 1 , ev3devices_InfraredSensor_beacon ) ;
69-
70- // pybricks.ev3devices.InfraredSensor.buttons
71- static mp_obj_t ev3devices_InfraredSensor_buttons (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
64+ static PB_DEFINE_CONST_TYPE_DEVICE_METHOD_OBJ (ev3devices_InfraredSensor_beacon_mapped_obj , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__SEEK , ev3devices_InfraredSensor_beacon_map ) ;
7265
66+ static mp_obj_t ev3devices_InfraredSensor_beacon (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
7367 PB_PARSE_ARGS_METHOD (n_args , pos_args , kw_args ,
7468 ev3devices_InfraredSensor_obj_t , self ,
7569 PB_ARG_REQUIRED (channel ));
76-
7770 mp_int_t channel = pb_obj_get_int (channel_in );
7871 if (channel < 1 || channel > 4 ) {
7972 pb_assert (PBIO_ERROR_INVALID_ARG );
8073 }
74+ self -> current_channel = channel ;
75+ return pb_type_device_method_call (MP_OBJ_FROM_PTR (& ev3devices_InfraredSensor_beacon_mapped_obj ), 1 , 0 , pos_args );
76+ }
77+ static MP_DEFINE_CONST_FUN_OBJ_KW (ev3devices_InfraredSensor_beacon_obj , 1 , ev3devices_InfraredSensor_beacon ) ;
78+
79+ // pybricks.ev3devices.InfraredSensor.buttons
80+ static mp_obj_t ev3devices_InfraredSensor_buttons_map (mp_obj_t self_in ) {
8181
82- int8_t * buttons_data = pb_type_device_get_data_blocking ( MP_OBJ_FROM_PTR ( self ), LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__REMOTE );
82+ ev3devices_InfraredSensor_obj_t * self = MP_OBJ_TO_PTR ( self_in );
8383
84- mp_int_t encoded = buttons_data [channel - 1 ];
84+ int8_t * buttons_data = pb_type_device_get_data (MP_OBJ_FROM_PTR (self ), LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__REMOTE );
85+
86+ mp_int_t encoded = buttons_data [self -> current_channel - 1 ];
8587 mp_obj_t pressed [2 ];
8688 uint8_t len = 0 ;
8789
@@ -134,12 +136,25 @@ static mp_obj_t ev3devices_InfraredSensor_buttons(size_t n_args, const mp_obj_t
134136
135137 return mp_obj_new_list (len , pressed );
136138}
139+ static PB_DEFINE_CONST_TYPE_DEVICE_METHOD_OBJ (ev3devices_InfraredSensor_buttons_mapped_obj , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__REMOTE , ev3devices_InfraredSensor_buttons_map ) ;
140+
141+ static mp_obj_t ev3devices_InfraredSensor_buttons (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
142+ PB_PARSE_ARGS_METHOD (n_args , pos_args , kw_args ,
143+ ev3devices_InfraredSensor_obj_t , self ,
144+ PB_ARG_REQUIRED (channel ));
145+ mp_int_t channel = pb_obj_get_int (channel_in );
146+ if (channel < 1 || channel > 4 ) {
147+ pb_assert (PBIO_ERROR_INVALID_ARG );
148+ }
149+ self -> current_channel = channel ;
150+ return pb_type_device_method_call (MP_OBJ_FROM_PTR (& ev3devices_InfraredSensor_buttons_mapped_obj ), 1 , 0 , pos_args );
151+ }
137152static MP_DEFINE_CONST_FUN_OBJ_KW (ev3devices_InfraredSensor_buttons_obj , 1 , ev3devices_InfraredSensor_buttons ) ;
138153
139154// pybricks.ev3devices.InfraredSensor.keypad
140155static mp_obj_t ev3devices_InfraredSensor_keypad (mp_obj_t self_in ) {
141156
142- int16_t keypad_data = * (int16_t * )pb_type_device_get_data_blocking (self_in , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__REM_A );
157+ int16_t keypad_data = * (int16_t * )pb_type_device_get_data (self_in , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__REM_A );
143158
144159 if (keypad_data == 384 ) {
145160 return mp_obj_new_list (0 , NULL );
@@ -163,7 +178,7 @@ static mp_obj_t ev3devices_InfraredSensor_keypad(mp_obj_t self_in) {
163178
164179 return mp_obj_new_list (len , pressed );
165180}
166- static MP_DEFINE_CONST_FUN_OBJ_1 (ev3devices_InfraredSensor_keypad_obj , ev3devices_InfraredSensor_keypad ) ;
181+ static PB_DEFINE_CONST_TYPE_DEVICE_METHOD_OBJ (ev3devices_InfraredSensor_keypad_obj , LEGO_DEVICE_MODE_EV3_INFRARED_SENSOR__REM_A , ev3devices_InfraredSensor_keypad ) ;
167182
168183// dir(pybricks.ev3devices.InfraredSensor)
169184static const mp_rom_map_elem_t ev3devices_InfraredSensor_locals_dict_table [] = {
@@ -181,4 +196,4 @@ MP_DEFINE_CONST_OBJ_TYPE(pb_type_ev3devices_InfraredSensor,
181196 make_new , ev3devices_InfraredSensor_make_new ,
182197 locals_dict , & ev3devices_InfraredSensor_locals_dict );
183198
184- #endif // PYBRICKS_PY_EV3DEVDEVICES
199+ #endif // PYBRICKS_PY_EV3DEVICES
0 commit comments