@@ -88,10 +88,6 @@ static pbdrv_bluetooth_peripheral_char_t pb_lwp3device_char = {
8888typedef struct {
8989 pbio_task_t task ;
9090 #if PYBRICKS_PY_IODEVICES
91- /**
92- * Buffer of incoming notifications.
93- */
94- uint8_t * noti_data ;
9591 /**
9692 * Maximum number of stored notifications.
9793 */
@@ -116,8 +112,6 @@ typedef struct {
116112} pb_lwp3device_t ;
117113
118114static pb_lwp3device_t pb_lwp3device_singleton ;
119- void * pb_lwp3device_root_pointer = & pb_lwp3device_singleton ;
120- MP_REGISTER_ROOT_POINTER (void * pb_lwp3device_root_pointer );
121115
122116// Handles LEGO Wireless protocol messages from the Powered Up Remote.
123117static pbio_pybricks_error_t handle_remote_notification (pbdrv_bluetooth_connection_t connection , const uint8_t * value , uint32_t size ) {
@@ -337,6 +331,11 @@ static void pb_lwp3device_configure_remote(void) {
337331}
338332
339333void pb_type_lwp3device_start_cleanup (void ) {
334+
335+ #if PYBRICKS_PY_IODEVICES
336+ MP_STATE_PORT (notification_buffer ) = NULL ;
337+ #endif
338+
340339 static pbio_task_t disconnect_task ;
341340 pbdrv_bluetooth_peripheral_disconnect (& disconnect_task );
342341 // Task awaited in pybricks de-init.
@@ -487,12 +486,12 @@ MP_DEFINE_CONST_OBJ_TYPE(pb_type_pupdevices_Remote,
487486static pbio_pybricks_error_t handle_lwp3_generic_notification (pbdrv_bluetooth_connection_t connection , const uint8_t * value , uint32_t size ) {
488487 pb_lwp3device_t * self = & pb_lwp3device_singleton ;
489488
490- if (!self -> noti_data || !self -> noti_num ) {
489+ if (!MP_STATE_PORT ( notification_buffer ) || !self -> noti_num ) {
491490 // Allocated data not ready, but no error.
492491 return PBIO_PYBRICKS_ERROR_OK ;
493492 }
494493
495- memcpy (& self -> noti_data [self -> noti_idx_write * LWP3_MAX_MESSAGE_SIZE ], & value [0 ], (size < LWP3_MAX_MESSAGE_SIZE ) ? size : LWP3_MAX_MESSAGE_SIZE );
494+ memcpy (& MP_STATE_PORT ( notification_buffer ) [self -> noti_idx_write * LWP3_MAX_MESSAGE_SIZE ], & value [0 ], (size < LWP3_MAX_MESSAGE_SIZE ) ? size : LWP3_MAX_MESSAGE_SIZE );
496495 self -> noti_idx_write = (self -> noti_idx_write + 1 ) % self -> noti_num ;
497496 return PBIO_PYBRICKS_ERROR_OK ;
498497}
@@ -515,7 +514,12 @@ static mp_obj_t pb_type_iodevices_LWP3Device_make_new(const mp_obj_type_t *type,
515514
516515 self -> noti_num = mp_obj_get_int (num_notifications_in );
517516 self -> noti_num = self -> noti_num ? self -> noti_num : 1 ;
518- self -> noti_data = m_malloc0 (LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
517+
518+ if (MP_STATE_PORT (notification_buffer )) {
519+ mp_raise_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("Can use only one LWP3Device" ));
520+ }
521+
522+ MP_STATE_PORT (notification_buffer ) = m_malloc0 (LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
519523 self -> noti_idx_read = 0 ;
520524 self -> noti_idx_write = 0 ;
521525
@@ -558,7 +562,7 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
558562
559563 pb_lwp3device_assert_connected ();
560564
561- if (self -> noti_idx_read == self -> noti_idx_write || !self -> noti_num || !self -> noti_data ) {
565+ if (self -> noti_idx_read == self -> noti_idx_write || !self -> noti_num || !MP_STATE_PORT ( notification_buffer ) ) {
562566 return mp_const_none ;
563567 }
564568
@@ -567,7 +571,7 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
567571 self -> noti_idx_read = (self -> noti_idx_read + 1 ) % self -> noti_num ;
568572
569573 // First byte is the size.
570- uint8_t len = self -> noti_data [index * LWP3_MAX_MESSAGE_SIZE ];
574+ uint8_t len = MP_STATE_PORT ( notification_buffer ) [index * LWP3_MAX_MESSAGE_SIZE ];
571575 if (len < LWP3_HEADER_SIZE || len > LWP3_MAX_MESSAGE_SIZE ) {
572576 // This is rare but it can happen sometimes. It is better to just
573577 // ignore it rather than raise and crash the user application.
@@ -577,7 +581,7 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
577581 // Allocation of the return object may drive the runloop and process
578582 // new incoming messages, so copy data atomically before that happens.
579583 uint8_t message [LWP3_MAX_MESSAGE_SIZE ];
580- memcpy (message , & self -> noti_data [index * LWP3_MAX_MESSAGE_SIZE ], len );
584+ memcpy (message , & MP_STATE_PORT ( notification_buffer ) [index * LWP3_MAX_MESSAGE_SIZE ], len );
581585 return mp_obj_new_bytes (message , len );
582586}
583587static MP_DEFINE_CONST_FUN_OBJ_1 (lwp3device_read_obj , lwp3device_read ) ;
@@ -596,6 +600,8 @@ MP_DEFINE_CONST_OBJ_TYPE(pb_type_iodevices_LWP3Device,
596600 make_new , pb_type_iodevices_LWP3Device_make_new ,
597601 locals_dict , & pb_type_iodevices_LWP3Device_locals_dict );
598602
603+ MP_REGISTER_ROOT_POINTER (uint8_t * notification_buffer );
604+
599605#endif // PYBRICKS_PY_IODEVICES
600606
601607#endif // PYBRICKS_PY_PUPDEVICES_REMOTE
0 commit comments