@@ -93,13 +93,17 @@ typedef struct {
9393 */
9494 uint8_t noti_num ;
9595 /**
96- * Index to read (the oldest data)
96+ * Index to read (the oldest data).
9797 */
9898 uint8_t noti_idx_read ;
9999 /**
100- * Index to write (next free slot)
100+ * Index to write (next free slot).
101101 */
102102 uint8_t noti_idx_write ;
103+ /**
104+ * The buffer is full, next write will override oldest data.
105+ */
106+ bool noti_data_full ;
103107 #endif // PYBRICKS_PY_IODEVICES
104108 uint8_t left [3 ];
105109 uint8_t right [3 ];
@@ -500,8 +504,18 @@ static pbio_pybricks_error_t handle_lwp3_generic_notification(pbdrv_bluetooth_co
500504 return PBIO_PYBRICKS_ERROR_OK ;
501505 }
502506
507+ // Buffer is full, so drop oldest sample by advancing read index.
508+ if (self -> noti_data_full ) {
509+ self -> noti_idx_read = (self -> noti_idx_read + 1 ) % self -> noti_num ;
510+ }
511+
503512 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 );
504513 self -> noti_idx_write = (self -> noti_idx_write + 1 ) % self -> noti_num ;
514+
515+ // After writing it is full if the _next_ write will override the
516+ // to-be-read data. If it was already full when we started writing, both
517+ // indexes have now advanced so it is still full now.
518+ self -> noti_data_full = self -> noti_idx_read == self -> noti_idx_write ;
505519 return PBIO_PYBRICKS_ERROR_OK ;
506520}
507521
@@ -520,7 +534,7 @@ static mp_obj_t pb_type_iodevices_LWP3Device_make_new(const mp_obj_type_t *type,
520534 bool pair = mp_obj_is_true (pair_in );
521535
522536 self -> noti_num = mp_obj_get_int (num_notifications_in );
523- self -> noti_num = self -> noti_num ? self -> noti_num : 1 ;
537+ self -> noti_num = self -> noti_num > 0 ? self -> noti_num : 1 ;
524538
525539 if (MP_STATE_PORT (notification_buffer )) {
526540 mp_raise_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("Can use only one LWP3Device" ));
@@ -529,6 +543,7 @@ static mp_obj_t pb_type_iodevices_LWP3Device_make_new(const mp_obj_type_t *type,
529543 MP_STATE_PORT (notification_buffer ) = m_malloc0 (LWP3_MAX_MESSAGE_SIZE * self -> noti_num );
530544 self -> noti_idx_read = 0 ;
531545 self -> noti_idx_write = 0 ;
546+ self -> noti_data_full = false;
532547
533548 pb_lwp3device_connect (name_in , timeout_in , hub_kind , handle_lwp3_generic_notification , pair );
534549
@@ -569,12 +584,17 @@ static mp_obj_t lwp3device_read(mp_obj_t self_in) {
569584
570585 pb_lwp3device_assert_connected ();
571586
572- if (self -> noti_idx_read == self -> noti_idx_write || !self -> noti_num || !MP_STATE_PORT (notification_buffer )) {
587+ if (!self -> noti_num || !MP_STATE_PORT (notification_buffer )) {
588+ pb_assert (PBIO_ERROR_FAILED );
589+ }
590+
591+ if (!self -> noti_data_full && self -> noti_idx_write == self -> noti_idx_read ) {
573592 return mp_const_none ;
574593 }
575594
576595 // Update index before returning, else bad values would not be cleared.
577596 uint8_t index = self -> noti_idx_read ;
597+ self -> noti_data_full = false;
578598 self -> noti_idx_read = (self -> noti_idx_read + 1 ) % self -> noti_num ;
579599
580600 // First byte is the size.
0 commit comments