Skip to content

Commit addd23f

Browse files
committed
pybricks.iodevices.LWP3Device: Use flag to track buffer full.
This was we don't need N+1 buffer size for N samples. We weren't doing the +1 before, so it wouldn't work when choosing N = 1 before. This is fixed now.
1 parent c8cc9b4 commit addd23f

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

pybricks/iodevices/pb_type_iodevices_lwp3device.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)