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>
This commit is contained in:
robert-hh
2025-03-09 11:39:12 +01:00
committed by Damien George
parent 2b2a431878
commit 6db7b47ab9

View File

@@ -88,8 +88,10 @@ typedef struct _machine_uart_obj_t {
uint16_t timeout; // timeout waiting for first char (in ms)
uint16_t timeout_char; // timeout waiting between chars (in ms)
bool new;
uint16_t rxbuf_len;
ringbuf_t read_buffer;
#if MICROPY_HW_UART_TXBUF
uint16_t txbuf_len;
ringbuf_t write_buffer;
#endif
#if MICROPY_PY_MACHINE_UART_IRQ
@@ -287,16 +289,6 @@ void machine_uart_set_baudrate(mp_obj_t self_in, uint32_t baudrate) {
static void mp_machine_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
size_t rxbuf_len = self->read_buffer.size - 1;
#if MICROPY_HW_UART_TXBUF
size_t txbuf_len = self->write_buffer.size - 1;
#endif
if (self->bits > 8) {
rxbuf_len /= 2;
#if MICROPY_HW_UART_TXBUF
txbuf_len /= 2;
#endif
}
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, "
"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_
")",
self->id, self->baudrate, self->bits, _parity_name[self->parity],
self->stop + 1, pin_find_by_id(self->tx)->name, pin_find_by_id(self->rx)->name,
self->timeout, self->timeout_char, rxbuf_len
self->timeout, self->timeout_char, self->rxbuf_len
#if MICROPY_HW_UART_TXBUF
, txbuf_len
, self->txbuf_len
#endif
#if MICROPY_HW_UART_RTSCTS
, 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,
// Set bits if configured.
if (args[ARG_bits].u_int > 0) {
self->bits = args[ARG_bits].u_int;
// Invalidate the buffers since the size may have to be changed
self->read_buffer.buf = NULL;
#if MICROPY_HW_UART_TXBUF
self->write_buffer.buf = NULL;
#endif
}
// Set parity if configured.
@@ -414,7 +411,7 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
}
// Set the RX buffer size if configured.
size_t rxbuf_len = DEFAULT_BUFFER_SIZE;
size_t rxbuf_len = self->rxbuf_len;
if (args[ARG_rxbuf].u_int > 0) {
rxbuf_len = args[ARG_rxbuf].u_int;
if (rxbuf_len < MIN_BUFFER_SIZE) {
@@ -422,11 +419,16 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
} else if (rxbuf_len > MAX_BUFFER_SIZE) {
mp_raise_ValueError(MP_ERROR_TEXT("rxbuf too large"));
}
// Force re-allocting of the buffer if the size changed
if (rxbuf_len != self->rxbuf_len) {
self->read_buffer.buf = NULL;
self->rxbuf_len = rxbuf_len;
}
}
#if MICROPY_HW_UART_TXBUF
// Set the TX buffer size if configured.
size_t txbuf_len = DEFAULT_BUFFER_SIZE;
size_t txbuf_len = self->txbuf_len;
if (args[ARG_txbuf].u_int > 0) {
txbuf_len = args[ARG_txbuf].u_int;
if (txbuf_len < MIN_BUFFER_SIZE) {
@@ -434,6 +436,11 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
} else if (txbuf_len > MAX_BUFFER_SIZE) {
mp_raise_ValueError(MP_ERROR_TEXT("txbuf too large"));
}
// Force re-allocting of the buffer if the size changed
if (txbuf_len != self->txbuf_len) {
self->write_buffer.buf = NULL;
self->txbuf_len = txbuf_len;
}
}
#endif
@@ -462,10 +469,14 @@ static void mp_machine_uart_init_helper(machine_uart_obj_t *self, size_t n_args,
}
// Allocate the RX/TX buffers.
if (self->read_buffer.buf == NULL) {
ringbuf_alloc(&(self->read_buffer), rxbuf_len + 1);
}
#if MICROPY_HW_UART_TXBUF
if (self->write_buffer.buf == NULL) {
ringbuf_alloc(&(self->write_buffer), txbuf_len + 1);
}
#endif
// 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
self->stop = 0;
self->timeout = 1;
self->timeout_char = 1;
self->rxbuf_len = DEFAULT_BUFFER_SIZE;
self->read_buffer.buf = NULL;
#if MICROPY_HW_UART_TXBUF
self->txbuf_len = DEFAULT_BUFFER_SIZE;
self->write_buffer.buf = NULL;
#endif
#if defined(pin_TX) && defined(pin_RX)
// Initialize with the default pins
self->tx = mp_hal_get_pin_obj((mp_obj_t)pin_TX);