Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
ringbuf tested
  • Loading branch information
dhalbert committed Apr 22, 2020
commit fbc8719fadbffd9b3e4ba1ceb42182c4370d0621
11 changes: 5 additions & 6 deletions ports/mimxrt10xx/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,17 +198,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
claim_pin(self->tx_pin->pin);

if (self->rx_pin != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
// The LPUART ring buffer wastes one byte to distinguish between full and empty.
self->ringbuf = gc_alloc(receiver_buffer_size + 1, false, true /*long-lived*/);

if (!self->rbuf.buf) {
if (!self->ringbuf) {
LPUART_Deinit(self->uart);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}

LPUART_TransferCreateHandle(self->uart, &self->handle, LPUART_UserCallback, self);
// Pass actual allocated size; the LPUART routines are cognizant that
// the capacity is one less than the size.
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->rbuf.buf, self->rbuf.size);
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->ringbuf, receiver_buffer_size + 1);

claim_pin(self->rx_pin->pin);
}
Expand All @@ -225,9 +226,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {

LPUART_Deinit(self->uart);

gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
gc_free(self->ringbuf);

// reset_pin_number(self->rx_pin);
// reset_pin_number(self->tx_pin);
Expand Down
2 changes: 1 addition & 1 deletion ports/mimxrt10xx/common-hal/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ typedef struct {
mp_obj_base_t base;
LPUART_Type *uart;
lpuart_handle_t handle;
ringbuf_t rbuf;
uint8_t* ringbuf;
bool rx_ongoing;
uint32_t baudrate;
uint8_t character_bits;
Expand Down
4 changes: 2 additions & 2 deletions ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer
uint64_t start_ticks = supervisor_ticks_ms64();

// Wait for all bytes received or timeout
while ( (ringbuf_avail(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
Expand All @@ -125,7 +125,7 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
uint16_t count = ringbuf_avail(&self->ringbuf);
uint16_t count = ringbuf_num_filled(&self->ringbuf);
sd_nvic_critical_region_exit(is_nested_critical_region);
return count;
}
Expand Down
43 changes: 20 additions & 23 deletions ports/nrf/common-hal/_bleio/PacketBuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
// Make room for the new value by dropping the oldest packets first.
while (ringbuf_capacity(&self->ringbuf) - ringbuf_avail(&self->ringbuf) < len + sizeof(uint16_t)) {
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
for (uint16_t i = 0; i < packet_length; i++) {
Expand Down Expand Up @@ -202,10 +202,7 @@ void common_hal_bleio_packet_buffer_construct(
}

if (incoming) {
// This is a macro.
ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false);

if (self->ringbuf.buf == NULL) {
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
}
}
Expand Down Expand Up @@ -250,7 +247,7 @@ void common_hal_bleio_packet_buffer_construct(
}

int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
if (ringbuf_avail(&self->ringbuf) < 2) {
if (ringbuf_num_filled(&self->ringbuf) < 2) {
return 0;
}

Expand Down Expand Up @@ -315,25 +312,25 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
}

uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) {
uint16_t mtu;
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return 0;
}
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
connection = &bleio_connections[i];
if (connection->conn_handle == self->conn_handle) {
break;
// First, assume default MTU size.
uint16_t mtu = BLE_GATT_ATT_MTU_DEFAULT;

// If there's a connection, get its actual MTU.
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
connection = &bleio_connections[i];
if (connection->conn_handle == self->conn_handle) {
if (connection->mtu != 0) {
mtu = connection->mtu;
}
break;
}
}
}
if (connection->mtu == 0) {
mtu = BLE_GATT_ATT_MTU_DEFAULT;
}
if (self->characteristic->max_length > mtu) {
mtu = self->characteristic->max_length;
}
uint16_t att_overhead = 3;
return mtu - att_overhead;

// 3 is bytes of ATT overhead.
return MIN(mtu - 3, self->characteristic->max_length);
}

bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
Expand Down
21 changes: 8 additions & 13 deletions ports/nrf/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)

switch ( event->type ) {
case NRFX_UARTE_EVT_RX_DONE:
ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);

// keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
Expand All @@ -113,7 +113,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
// Possible Error source is Overrun, Parity, Framing, Break
// uint32_t errsrc = event->data.error.error_mask;

ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
ringbuf_put_n(&self->ringbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);

// Keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
Expand Down Expand Up @@ -191,9 +191,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// pointers like this are NOT moved, allocating the buffer
// in the long-lived pool is not strictly necessary)
// (This is a macro.)
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);

if ( !self->rbuf.buf ) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
nrfx_uarte_uninit(self->uarte);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
Expand Down Expand Up @@ -227,10 +225,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx_pin_number);
self->tx_pin_number = NO_PIN;
self->rx_pin_number = NO_PIN;

gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
ringbuf_free(&self->ringbuf);
}
}

Expand All @@ -243,7 +238,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
uint64_t start_ticks = supervisor_ticks_ms64();

// Wait for all bytes received or timeout
while ( (ringbuf_avail(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
Expand All @@ -255,7 +250,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));

// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->rbuf, data, len);
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);

NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));

Expand Down Expand Up @@ -312,13 +307,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}

uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_avail(&self->rbuf);
return ringbuf_num_filled(&self->ringbuf);
}

void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
ringbuf_clear(&self->rbuf);
ringbuf_clear(&self->ringbuf);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
}

Expand Down
2 changes: 1 addition & 1 deletion ports/nrf/common-hal/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ typedef struct {
uint32_t baudrate;
uint32_t timeout_ms;

ringbuf_t rbuf;
ringbuf_t ringbuf;
uint8_t rx_char; // EasyDMA buf

uint8_t tx_pin_number;
Expand Down
18 changes: 7 additions & 11 deletions ports/stm/common-hal/busio/UART.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,

// Init buffer for rx and claim pins
if (self->rx != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
if (!self->rbuf.buf) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
mp_raise_ValueError(translate("UART Buffer allocation error"));
}
claim_pin(rx);
Expand Down Expand Up @@ -248,21 +247,18 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
self->tx = NULL;
self->rx = NULL;
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
ringbuf_free(&self->ringbuf);
}

size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
if (self->rx == NULL) {
mp_raise_ValueError(translate("No RX pin"));
}

size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();

// Wait for all bytes received or timeout, same as nrf
while ( (ringbuf_avail(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
//restart if it failed in the callback
if (errflag != HAL_OK) {
Expand All @@ -277,7 +273,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->rbuf, data, len);
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
HAL_NVIC_EnableIRQ(self->irq);

if (rx_bytes == 0) {
Expand Down Expand Up @@ -317,7 +313,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
if ((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
return;
}
ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
ringbuf_put_n(&context->ringbuf, &context->rx_char, 1);
errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);

return;
Expand Down Expand Up @@ -376,13 +372,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}

uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_avail(&self->rbuf);
return ringbuf_num_filled(&self->ringbuf);
}

void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
ringbuf_clear(&self->rbuf);
ringbuf_clear(&self->ringbuf);
HAL_NVIC_EnableIRQ(self->irq);
}

Expand Down
2 changes: 1 addition & 1 deletion ports/stm/common-hal/busio/UART.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typedef struct {
const mcu_periph_obj_t *tx;
const mcu_periph_obj_t *rx;

ringbuf_t rbuf;
ringbuf_t ringbuf;
uint8_t rx_char;

uint32_t baudrate;
Expand Down
10 changes: 8 additions & 2 deletions py/ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived) {
return r->buf != NULL;
}

void ringbuf_free(ringbuf_t *r) {
gc_free(r->buf);
r->size = 0;
ringbuf_clear(r);
}

size_t ringbuf_capacity(ringbuf_t *r) {
return r->size - 1;
}
Expand Down Expand Up @@ -72,12 +78,12 @@ void ringbuf_clear(ringbuf_t *r) {
}

// Number of free slots that can be written.
size_t ringbuf_free(ringbuf_t *r) {
size_t ringbuf_num_empty(ringbuf_t *r) {
return (r->size + r->iget - r->iput - 1) % r->size;
}

// Number of bytes available to read.
size_t ringbuf_avail(ringbuf_t *r) {
size_t ringbuf_num_filled(ringbuf_t *r) {
return (r->size + r->iput - r->iget) % r->size;
}

Expand Down
5 changes: 3 additions & 2 deletions py/ringbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ typedef struct _ringbuf_t {
// ringbuf_t buf = {buf_array, sizeof(buf_array)};

bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived);
void ringbuf_free(ringbuf_t *r);
size_t ringbuf_capacity(ringbuf_t *r);
int ringbuf_get(ringbuf_t *r);
int ringbuf_put(ringbuf_t *r, uint8_t v);
void ringbuf_clear(ringbuf_t *r);
size_t ringbuf_free(ringbuf_t *r);
size_t ringbuf_avail(ringbuf_t *r);
size_t ringbuf_num_empty(ringbuf_t *r);
size_t ringbuf_num_filled(ringbuf_t *r);
size_t ringbuf_put_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
size_t ringbuf_get_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);

Expand Down
6 changes: 3 additions & 3 deletions shared-module/_bleio/ScanResults.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size,
}

mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) {
while (ringbuf_avail(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
while (ringbuf_num_filled(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
if (ringbuf_avail(&self->buf) == 0 || mp_hal_is_interrupted()) {
if (ringbuf_num_filled(&self->buf) == 0 || mp_hal_is_interrupted()) {
return mp_const_none;
}

Expand Down Expand Up @@ -97,7 +97,7 @@ void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
uint16_t len) {
int32_t packet_size = sizeof(uint8_t) + sizeof(ticks_ms) + sizeof(rssi) + NUM_BLEIO_ADDRESS_BYTES +
sizeof(addr_type) + sizeof(len) + len;
int32_t empty_space = self->buf.size - ringbuf_avail(&self->buf);
int32_t empty_space = self->buf.size - ringbuf_num_filled(&self->buf);
if (packet_size >= empty_space) {
// We can't fit the packet so skip it.
return;
Expand Down