Skip to content

Commit 6db7b47

Browse files
robert-hhdpgeorge
authored andcommitted
samd/machine_uart: Fix unintended UART buffer allocation on init().
The buffer was be reset on every call to uart.init(). If no sizes were given, the buffer was set to the default size 256. That made problems e.g. with PPP. This commit fixes it, keeping the buffer size if not deliberately changed and allocating new buffers only if the size was changed. Cater for changes of the bits value, which requires a change to the buffer size. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent 2b2a431 commit 6db7b47

1 file changed

Lines changed: 33 additions & 16 deletions

File tree

ports/samd/machine_uart.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ typedef struct _machine_uart_obj_t {
8888
uint16_t timeout; // timeout waiting for first char (in ms)
8989
uint16_t timeout_char; // timeout waiting between chars (in ms)
9090
bool new;
91+
uint16_t rxbuf_len;
9192
ringbuf_t read_buffer;
9293
#if MICROPY_HW_UART_TXBUF
94+
uint16_t txbuf_len;
9395
ringbuf_t write_buffer;
9496
#endif
9597
#if MICROPY_PY_MACHINE_UART_IRQ
@@ -287,16 +289,6 @@ void machine_uart_set_baudrate(mp_obj_t self_in, uint32_t baudrate) {
287289

288290
static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
289291
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
290-
size_t rxbuf_len = self->read_buffer.size - 1;
291-
#if MICROPY_HW_UART_TXBUF
292-
size_t txbuf_len = self->write_buffer.size - 1;
293-
#endif
294-
if (self->bits > 8) {
295-
rxbuf_len /= 2;
296-
#if MICROPY_HW_UART_TXBUF
297-
txbuf_len /= 2;
298-
#endif
299-
}
300292

301293
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, "
302294
"tx=\"%q\", rx=\"%q\", timeout=%u, timeout_char=%u, rxbuf=%d"
@@ -312,9 +304,9 @@ static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_
312304
")",
313305
self->id, self->baudrate, self->bits, _parity_name[self->parity],
314306
self->stop + 1, pin_find_by_id(self->tx)->name, pin_find_by_id(self->rx)->name,
315-
self->timeout, self->timeout_char, rxbuf_len
307+
self->timeout, self->timeout_char, self->rxbuf_len
316308
#if MICROPY_HW_UART_TXBUF
317-
, txbuf_len
309+
, self->txbuf_len
318310
#endif
319311
#if MICROPY_HW_UART_RTSCTS
320312
, self->rts != 0xff ? pin_find_by_id(self->rts)->name : MP_QSTR_None
@@ -358,6 +350,11 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
358350
// Set bits if configured.
359351
if (args[ARG_bits].u_int > 0) {
360352
self->bits = args[ARG_bits].u_int;
353+
// Invalidate the buffers since the size may have to be changed
354+
self->read_buffer.buf = NULL;
355+
#if MICROPY_HW_UART_TXBUF
356+
self->write_buffer.buf = NULL;
357+
#endif
361358
}
362359

363360
// Set parity if configured.
@@ -414,26 +411,36 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
414411
}
415412

416413
// Set the RX buffer size if configured.
417-
size_t rxbuf_len = DEFAULT_BUFFER_SIZE;
414+
size_t rxbuf_len = self->rxbuf_len;
418415
if (args[ARG_rxbuf].u_int > 0) {
419416
rxbuf_len = args[ARG_rxbuf].u_int;
420417
if (rxbuf_len < MIN_BUFFER_SIZE) {
421418
rxbuf_len = MIN_BUFFER_SIZE;
422419
} else if (rxbuf_len > MAX_BUFFER_SIZE) {
423420
mp_raise_ValueError(MP_ERROR_TEXT("rxbuf too large"));
424421
}
422+
// Force re-allocting of the buffer if the size changed
423+
if (rxbuf_len != self->rxbuf_len) {
424+
self->read_buffer.buf = NULL;
425+
self->rxbuf_len = rxbuf_len;
426+
}
425427
}
426428

427429
#if MICROPY_HW_UART_TXBUF
428430
// Set the TX buffer size if configured.
429-
size_t txbuf_len = DEFAULT_BUFFER_SIZE;
431+
size_t txbuf_len = self->txbuf_len;
430432
if (args[ARG_txbuf].u_int > 0) {
431433
txbuf_len = args[ARG_txbuf].u_int;
432434
if (txbuf_len < MIN_BUFFER_SIZE) {
433435
txbuf_len = MIN_BUFFER_SIZE;
434436
} else if (txbuf_len > MAX_BUFFER_SIZE) {
435437
mp_raise_ValueError(MP_ERROR_TEXT("txbuf too large"));
436438
}
439+
// Force re-allocting of the buffer if the size changed
440+
if (txbuf_len != self->txbuf_len) {
441+
self->write_buffer.buf = NULL;
442+
self->txbuf_len = txbuf_len;
443+
}
437444
}
438445
#endif
439446

@@ -462,10 +469,14 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
462469
}
463470

464471
// Allocate the RX/TX buffers.
465-
ringbuf_alloc(&(self->read_buffer), rxbuf_len + 1);
472+
if (self->read_buffer.buf == NULL) {
473+
ringbuf_alloc(&(self->read_buffer), rxbuf_len + 1);
474+
}
466475

467476
#if MICROPY_HW_UART_TXBUF
468-
ringbuf_alloc(&(self->write_buffer), txbuf_len + 1);
477+
if (self->write_buffer.buf == NULL) {
478+
ringbuf_alloc(&(self->write_buffer), txbuf_len + 1);
479+
}
469480
#endif
470481

471482
// Step 1: Configure the Pin mux.
@@ -503,6 +514,12 @@ static mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_arg
503514
self->stop = 0;
504515
self->timeout = 1;
505516
self->timeout_char = 1;
517+
self->rxbuf_len = DEFAULT_BUFFER_SIZE;
518+
self->read_buffer.buf = NULL;
519+
#if MICROPY_HW_UART_TXBUF
520+
self->txbuf_len = DEFAULT_BUFFER_SIZE;
521+
self->write_buffer.buf = NULL;
522+
#endif
506523
#if defined(pin_TX) && defined(pin_RX)
507524
// Initialize with the default pins
508525
self->tx = mp_hal_get_pin_obj((mp_obj_t)pin_TX);

0 commit comments

Comments
 (0)