@@ -396,12 +396,6 @@ static mp_obj_t pb_lwp3device_connect(mp_obj_t self_in, mp_obj_t name_in, mp_obj
396396 return pb_type_async_wait_or_await (& config , & lwp3device -> iter , true);
397397}
398398
399- void pb_type_lwp3device_start_cleanup (void ) {
400-
401- #if PYBRICKS_PY_IODEVICES
402- MP_STATE_PORT (notification_buffer ) = NULL ;
403- #endif
404- }
405399
406400mp_obj_t pb_type_remote_button_pressed (void ) {
407401 pb_lwp3device_t * remote = & pb_lwp3device_singleton ;
@@ -530,10 +524,13 @@ MP_DEFINE_CONST_OBJ_TYPE(pb_type_pupdevices_Remote,
530524
531525#if PYBRICKS_PY_IODEVICES
532526
527+ // pointer to dynamically allocated memory - needed for driver callback
528+ static uint8_t * notification_buffer ;
529+
533530static pbio_pybricks_error_t handle_lwp3_generic_notification (const uint8_t * value , uint32_t size ) {
534531 pb_lwp3device_t * self = & pb_lwp3device_singleton ;
535532
536- if (!MP_STATE_PORT ( notification_buffer ) || !self -> noti_num ) {
533+ if (!notification_buffer || !self -> noti_num ) {
537534 // Allocated data not ready, but no error.
538535 return PBIO_PYBRICKS_ERROR_OK ;
539536 }
@@ -543,7 +540,7 @@ static pbio_pybricks_error_t handle_lwp3_generic_notification(const uint8_t *val
543540 self -> noti_idx_read = (self -> noti_idx_read + 1 ) % self -> noti_num ;
544541 }
545542
546- 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 );
543+ memcpy (& notification_buffer [self -> noti_idx_write * LWP3_MAX_MESSAGE_SIZE ], & value [0 ], (size < LWP3_MAX_MESSAGE_SIZE ) ? size : LWP3_MAX_MESSAGE_SIZE );
547544 self -> noti_idx_write = (self -> noti_idx_write + 1 ) % self -> noti_num ;
548545
549546 // After writing it is full if the _next_ write will override the
@@ -553,6 +550,11 @@ static pbio_pybricks_error_t handle_lwp3_generic_notification(const uint8_t *val
553550 return PBIO_PYBRICKS_ERROR_OK ;
554551}
555552
553+ typedef struct {
554+ mp_obj_base_t base ;
555+ uint8_t notification_buffer [];
556+ } lwp3_device_obj_t ;
557+
556558static mp_obj_t pb_type_iodevices_LWP3Device_make_new (const mp_obj_type_t * type , size_t n_args , size_t n_kw , const mp_obj_t * args ) {
557559 PB_PARSE_ARGS_CLASS (n_args , n_kw , args ,
558560 PB_ARG_REQUIRED (hub_kind ),
@@ -561,7 +563,7 @@ static mp_obj_t pb_type_iodevices_LWP3Device_make_new(const mp_obj_type_t *type,
561563 PB_ARG_DEFAULT_FALSE (pair ),
562564 PB_ARG_DEFAULT_INT (num_notifications , 8 ));
563565
564- mp_obj_base_t * obj = mp_obj_malloc ( mp_obj_base_t , type );
566+
565567 pb_lwp3device_t * self = & pb_lwp3device_singleton ;
566568
567569 uint8_t hub_kind = pb_obj_get_positive_int (hub_kind_in );
@@ -570,11 +572,13 @@ static mp_obj_t pb_type_iodevices_LWP3Device_make_new(const mp_obj_type_t *type,
570572 self -> noti_num = mp_obj_get_int (num_notifications_in );
571573 self -> noti_num = self -> noti_num > 0 ? self -> noti_num : 1 ;
572574
573- if (MP_STATE_PORT ( notification_buffer ) ) {
575+ if (notification_buffer ) {
574576 mp_raise_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("Can use only one LWP3Device" ));
575577 }
576578
577- MP_STATE_PORT (notification_buffer ) = m_malloc0 (LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
579+ lwp3_device_obj_t * obj = mp_obj_malloc_var_with_finaliser (lwp3_device_obj_t , uint8_t , LWP3_MAX_MESSAGE_SIZE * self -> noti_num , type );
580+ notification_buffer = obj -> notification_buffer ;
581+ memset (notification_buffer , 0 , LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
578582 self -> noti_idx_read = 0 ;
579583 self -> noti_idx_write = 0 ;
580584 self -> noti_data_full = false;
@@ -608,7 +612,7 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
608612
609613 pb_lwp3device_assert_connected ();
610614
611- if (!self -> noti_num || !MP_STATE_PORT ( notification_buffer ) ) {
615+ if (!self -> noti_num || !notification_buffer ) {
612616 pb_assert (PBIO_ERROR_FAILED );
613617 }
614618
@@ -622,7 +626,7 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
622626 self -> noti_idx_read = (self -> noti_idx_read + 1 ) % self -> noti_num ;
623627
624628 // First byte is the size.
625- uint8_t len = MP_STATE_PORT ( notification_buffer ) [index * LWP3_MAX_MESSAGE_SIZE ];
629+ uint8_t len = notification_buffer [index * LWP3_MAX_MESSAGE_SIZE ];
626630 if (len < LWP3_HEADER_SIZE || len > LWP3_MAX_MESSAGE_SIZE ) {
627631 // This is rare but it can happen sometimes. It is better to just
628632 // ignore it rather than raise and crash the user application.
@@ -632,11 +636,17 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
632636 // Allocation of the return object may drive the runloop and process
633637 // new incoming messages, so copy data atomically before that happens.
634638 uint8_t message [LWP3_MAX_MESSAGE_SIZE ];
635- memcpy (message , & MP_STATE_PORT ( notification_buffer ) [index * LWP3_MAX_MESSAGE_SIZE ], len );
639+ memcpy (message , & notification_buffer [index * LWP3_MAX_MESSAGE_SIZE ], len );
636640 return mp_obj_new_bytes (message , len );
637641}
638642static MP_DEFINE_CONST_FUN_OBJ_1 (lwp3device_read_obj , lwp3device_read ) ;
639643
644+ mp_obj_t lwp3device_data_close (mp_obj_t self_in ) {
645+ notification_buffer = NULL ;
646+ return mp_const_none ;
647+ }
648+ MP_DEFINE_CONST_FUN_OBJ_1 (lwp3device_data_close_obj , lwp3device_data_close );
649+
640650static const mp_rom_map_elem_t pb_type_iodevices_LWP3Device_locals_dict_table [] = {
641651 { MP_ROM_QSTR (MP_QSTR_disconnect ), MP_ROM_PTR (& pb_lwp3device_disconnect_obj ) },
642652 { MP_ROM_QSTR (MP_QSTR_name ), MP_ROM_PTR (& pb_lwp3device_name_obj ) },
0 commit comments