@@ -107,25 +107,13 @@ typedef struct {
107107 */
108108 mp_obj_t light ;
109109 /**
110- * Powered Up Remote Left button states , populated by notifications.
110+ * Application specific data, like cached button state , populated by notifications.
111111 */
112- uint8_t left [3 ];
113- /**
114- * Powered Up Remote Right button states, populated by notifications.
115- */
116- uint8_t right [3 ];
117- /**
118- * Powered Up Remote Center button state, populated by notifications.
119- */
120- uint8_t center ;
112+ uint8_t data [8 ];
121113 /**
122114 * Routine to run after establishing a connection (e.g. subscribing to ports).
123115 */
124116 pbio_os_process_func_t post_connect_setup_func ;
125- /**
126- * Routine to before (re-)establishing a connection (e.g. clearing stale data.)
127- */
128- mp_fun_1_t pre_connect_func ;
129117 // Null-terminated name used to filter advertisements and responses.
130118 // Also used as the name of the device when setting the name, since this
131119 // is not updated in the driver until the next time it connects.
@@ -313,10 +301,14 @@ static void pb_type_lwp3device_intialize_connection(mp_obj_t self_in, mp_obj_t c
313301
314302 bool want_connection = mp_obj_is_true (connect_in );
315303
316- // Reinitialize or clear data before connecting.
317- if (self -> pre_connect_func ) {
318- self -> pre_connect_func (self_in );
319- }
304+ // Clear data before reconnecting.
305+ memset (self -> data , 0 , sizeof (self -> data ));
306+
307+ // Clear past notifications (for generic LWP3 class).
308+ memset (self -> notification_buffer , 0 , LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
309+ self -> noti_idx_read = 0 ;
310+ self -> noti_idx_write = 0 ;
311+ self -> noti_data_full = false;
320312
321313 // Attempt to re-use existing connection.
322314 pbio_error_t err = pbdrv_bluetooth_peripheral_get_connected (& self -> peripheral , self , & self -> scan_config );
@@ -394,13 +386,13 @@ static void pb_type_remote_handle_notification(void *user, const uint8_t *value,
394386 }
395387 if (value [0 ] == 5 && value [2 ] == LWP3_MSG_TYPE_HW_NET_CMDS && value [3 ] == LWP3_HW_NET_CMD_CONNECTION_REQ ) {
396388 // This message is meant for something else, but contains the center button state
397- self -> center = value [4 ];
389+ self -> data [ 6 ] = value [4 ];
398390 } else if (value [0 ] == 7 && value [2 ] == LWP3_MSG_TYPE_PORT_VALUE ) {
399391 // This assumes that the handset button ports have already been set to mode KEYSD
400392 if (value [3 ] == REMOTE_PORT_LEFT_BUTTONS ) {
401- memcpy (self -> left , & value [4 ], 3 );
393+ memcpy (& self -> data [ 0 ] , & value [4 ], 3 );
402394 } else if (value [3 ] == REMOTE_PORT_RIGHT_BUTTONS ) {
403- memcpy (self -> right , & value [4 ], 3 );
395+ memcpy (& self -> data [ 3 ] , & value [4 ], 3 );
404396 }
405397 }
406398}
@@ -415,25 +407,25 @@ mp_obj_t pb_type_remote_button_pressed(mp_obj_t self_in) {
415407 mp_obj_t pressed [7 ];
416408 size_t num = 0 ;
417409
418- if (self -> left [0 ]) {
410+ if (self -> data [0 ]) {
419411 pressed [num ++ ] = pb_type_button_new (MP_QSTR_LEFT_PLUS );
420412 }
421- if (self -> left [1 ]) {
413+ if (self -> data [1 ]) {
422414 pressed [num ++ ] = pb_type_button_new (MP_QSTR_LEFT );
423415 }
424- if (self -> left [2 ]) {
416+ if (self -> data [2 ]) {
425417 pressed [num ++ ] = pb_type_button_new (MP_QSTR_LEFT_MINUS );
426418 }
427- if (self -> right [ 0 ]) {
419+ if (self -> data [ 3 ]) {
428420 pressed [num ++ ] = pb_type_button_new (MP_QSTR_RIGHT_PLUS );
429421 }
430- if (self -> right [ 1 ]) {
422+ if (self -> data [ 4 ]) {
431423 pressed [num ++ ] = pb_type_button_new (MP_QSTR_RIGHT );
432424 }
433- if (self -> right [ 2 ]) {
425+ if (self -> data [ 5 ]) {
434426 pressed [num ++ ] = pb_type_button_new (MP_QSTR_RIGHT_MINUS );
435427 }
436- if (self -> center ) {
428+ if (self -> data [ 6 ] ) {
437429 pressed [num ++ ] = pb_type_button_new (MP_QSTR_CENTER );
438430 }
439431
@@ -564,15 +556,6 @@ static pbio_error_t pb_type_remote_post_connect(pbio_os_state_t *state, mp_obj_t
564556 PBIO_OS_ASYNC_END (PBIO_SUCCESS );
565557}
566558
567- static mp_obj_t pb_type_remote_clear (mp_obj_t self_in ) {
568- pb_type_lwp3device_obj_t * self = MP_OBJ_TO_PTR (self_in );
569- // Ensure that no buttons are "pressed" after reconnecting
570- memset (& self -> left , 0 , sizeof (self -> left ));
571- memset (& self -> right , 0 , sizeof (self -> right ));
572- self -> center = 0 ;
573- return mp_const_none ;
574- }
575-
576559static mp_obj_t pb_type_remote_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
577560 PB_PARSE_ARGS_CLASS (n_args , n_kw , args ,
578561 PB_ARG_DEFAULT_NONE (name ),
@@ -589,7 +572,6 @@ static mp_obj_t pb_type_remote_make_new(const mp_obj_type_t *type, size_t n_args
589572 self -> hub_kind = LWP3_HUB_KIND_HANDSET ;
590573
591574 self -> post_connect_setup_func = pb_type_remote_post_connect ;
592- self -> pre_connect_func = pb_type_remote_clear ;
593575
594576 self -> scan_config = (pbdrv_bluetooth_peripheral_connect_config_t ) {
595577 .match_adv = pb_type_lwp3device_advertisement_matches ,
@@ -645,37 +627,49 @@ static void pb_type_technic_move_hub_handle_notification(void *user, const uint8
645627 // Not processing any notifications. We could monitor the hub's internal sensors.
646628}
647629
630+ /**
631+ * Stored format for the common data field in the lwp3 object.
632+ */
633+ typedef struct {
634+ uint8_t speed_now ;
635+ uint8_t steering_now ;
636+ uint8_t speed_last ;
637+ uint8_t steering_last ;
638+ } pb_type_lwp3device_technic_movehub_data_t ;
639+
648640static pbio_error_t pb_type_technic_move_hub_write_command (mp_obj_t self_in ) {
649641 pb_type_lwp3device_obj_t * self = MP_OBJ_TO_PTR (self_in );
650642
651643 // Don't repeat again if already sent idential values this many
652644 // times in this interval.
653645 const uint8_t max_repeat = 2 ;
654646 const uint32_t max_repeat_timeout = 500 ;
655-
647+
648+ pb_type_lwp3device_technic_movehub_data_t * data = (void * )self -> data ;
649+
656650 // Reusing the remote button buffer to store drive state.
657- bool identical = self -> right [ 0 ] == self -> left [ 0 ] && self -> right [ 1 ] == self -> left [ 1 ] ;
651+ bool identical = data -> speed_last == data -> speed_now && data -> steering_last == data -> steering_now ;
658652
659653 // Count identical messages sent in short time span, using center for counter.
660654 if (!identical || pbio_os_timer_is_expired (& self -> timer )) {
661- self -> center = 0 ;
655+ self -> data [ 4 ] = 0 ;
662656 }
663657
664658 // If we sent the same thing several times within timeout, it probably arrived.
665- if (self -> center == max_repeat ) {
659+ if (self -> data [ 4 ] == max_repeat ) {
666660 return PBIO_SUCCESS ;
667661 }
668662
669663 // Send command and keep track of the time.
670664 uint8_t light_mode = 0 ;
671- self -> right [ 0 ] = self -> left [ 0 ] ;
672- self -> right [ 1 ] = self -> left [ 1 ] ;
665+ data -> speed_last = data -> speed_now ;
666+ data -> steering_last = data -> steering_now ;
673667
674- self -> center = pbio_int_math_min (self -> center + 1 , max_repeat );
668+ self -> data [ 4 ] = pbio_int_math_min (self -> data [ 4 ] + 1 , max_repeat );
675669 pbio_os_timer_set (& self -> timer , max_repeat_timeout );
676-
670+
677671 const uint8_t cmd [] = {
678- 0x0d , 0x00 , 0x81 , 0x36 , 0x11 , 0x51 , 0x00 , 0x03 , 0x00 , self -> left [ 0 ], self -> left [ 1 ] , light_mode , 0 ,
672+ 0x0d , 0x00 , 0x81 , 0x36 , 0x11 , 0x51 , 0x00 , 0x03 , 0x00 , data -> speed_now , data -> steering_now , light_mode , 0 ,
679673 };
680674 return pbdrv_bluetooth_peripheral_write_characteristic (self -> peripheral , self -> lwp3_char_handle , cmd , sizeof (cmd ));
681675}
@@ -728,9 +722,10 @@ static mp_obj_t pb_type_technic_move_hub_drive_power(size_t n_args, const mp_obj
728722 PB_PARSE_ARGS_METHOD (n_args , pos_args , kw_args ,
729723 pb_type_lwp3device_obj_t , self ,
730724 PB_ARG_REQUIRED (power ));
731-
725+
732726 mp_obj_t self_in = MP_OBJ_FROM_PTR (self );
733- self -> left [0 ] = pbio_int_math_clamp (pb_obj_get_int (power_in ), 100 );
727+ pb_type_lwp3device_technic_movehub_data_t * data = (void * )self -> data ;
728+ data -> speed_now = pbio_int_math_clamp (pb_obj_get_int (power_in ), 100 );
734729 pb_assert (pb_type_technic_move_hub_write_command (self_in ));
735730 return wait_or_await_operation (self_in );
736731}
@@ -744,7 +739,8 @@ static mp_obj_t pb_type_technic_move_hub_steer(size_t n_args, const mp_obj_t *po
744739
745740 // Steering is a percentage of the calibrated angle. Go just under maximum
746741 // to avoid pushing against the mechanical constraint.
747- self -> left [1 ] = pbio_int_math_clamp (pb_obj_get_int (percentage_in ), 97 );
742+ pb_type_lwp3device_technic_movehub_data_t * data = (void * )self -> data ;
743+ data -> steering_now = pbio_int_math_clamp (pb_obj_get_int (percentage_in ), 97 );
748744 pb_assert (pb_type_technic_move_hub_write_command (self_in ));
749745 return wait_or_await_operation (self_in );
750746}
@@ -766,9 +762,6 @@ static mp_obj_t pb_type_technic_move_hub_make_new(const mp_obj_type_t *type, siz
766762 self -> hub_kind = LWP3_HUB_KIND_TECHNIC_MOVE ;
767763 self -> post_connect_setup_func = pb_type_technic_move_hub_post_connect ;
768764
769- // Re-using the unused remote left buffer to store drive state.
770- self -> pre_connect_func = pb_type_remote_clear ;
771-
772765 self -> scan_config = (pbdrv_bluetooth_peripheral_connect_config_t ) {
773766 .match_adv = pb_type_lwp3device_advertisement_matches ,
774767 .match_adv_rsp = pb_type_lwp3device_advertisement_response_matches ,
@@ -822,17 +815,6 @@ static void pb_type_lwp3device_handle_notification_generic(void *user, const uin
822815 self -> noti_data_full = self -> noti_idx_read == self -> noti_idx_write ;
823816}
824817
825-
826- static mp_obj_t pb_type_iodevices_lwp3device_clear (mp_obj_t self_in ) {
827- pb_type_lwp3device_obj_t * self = MP_OBJ_TO_PTR (self_in );
828- // Clear past notifications.
829- memset (self -> notification_buffer , 0 , LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
830- self -> noti_idx_read = 0 ;
831- self -> noti_idx_write = 0 ;
832- self -> noti_data_full = false;
833- return mp_const_none ;
834- }
835-
836818static mp_obj_t pb_type_lwp3device_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
837819 PB_PARSE_ARGS_CLASS (n_args , n_kw , args ,
838820 PB_ARG_REQUIRED (hub_kind ),
@@ -859,7 +841,6 @@ static mp_obj_t pb_type_lwp3device_make_new(const mp_obj_type_t *type, size_t n_
859841 .notification_handler = pb_type_lwp3device_handle_notification_generic ,
860842 .options = mp_obj_is_true (pair_in ) ? PBDRV_BLUETOOTH_PERIPHERAL_OPTIONS_PAIR : PBDRV_BLUETOOTH_PERIPHERAL_OPTIONS_NONE ,
861843 };
862- self -> pre_connect_func = pb_type_iodevices_lwp3device_clear ;
863844 self -> post_connect_setup_func = NULL ;
864845 pb_type_lwp3device_set_name_filter_and_timeout (self , name_in , timeout_in );
865846
0 commit comments