From 27dfdd737eb03b410781af20592fa6c3bec13dfd Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Thu, 2 Nov 2023 17:31:05 +0100 Subject: [PATCH] drivers: serial: emul: Make UART FIFO size realistic Real UARTs usually write 1 to a few bytes at a time through a latch buffer. Add latch buffer property to binding for uart_emul and limit fifo_read and fifo_fill to not exceed the latch buffer. Signed-off-by: Bjarki Arge Andreasen --- drivers/serial/uart_emul.c | 20 ++++++++++---------- dts/bindings/serial/zephyr,uart-emul.yaml | 6 ++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/serial/uart_emul.c b/drivers/serial/uart_emul.c index 6bfe3cf8a85..645c888e539 100644 --- a/drivers/serial/uart_emul.c +++ b/drivers/serial/uart_emul.c @@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(uart_emul, CONFIG_UART_LOG_LEVEL); struct uart_emul_config { bool loopback; + size_t latch_buffer_size; }; struct uart_emul_work { @@ -147,13 +148,14 @@ static int uart_emul_fifo_fill(const struct device *dev, const uint8_t *tx_data, int ret; struct uart_emul_data *data = dev->data; const struct uart_emul_config *config = dev->config; + uint32_t put_size = MIN(config->latch_buffer_size, size); K_SPINLOCK(&data->tx_lock) { - ret = ring_buf_put(data->tx_rb, tx_data, size); + ret = ring_buf_put(data->tx_rb, tx_data, put_size); } if (config->loopback) { - uart_emul_put_rx_data(dev, (uint8_t *)tx_data, ret); + uart_emul_put_rx_data(dev, (uint8_t *)tx_data, put_size); } if (data->tx_data_ready_cb) { data->tx_data_ready_cb(dev, ring_buf_size_get(data->tx_rb), data->user_data); @@ -164,19 +166,16 @@ static int uart_emul_fifo_fill(const struct device *dev, const uint8_t *tx_data, static int uart_emul_fifo_read(const struct device *dev, uint8_t *rx_data, int size) { - int ret; struct uart_emul_data *data = dev->data; + const struct uart_emul_config *config = dev->config; + uint32_t bytes_to_read; K_SPINLOCK(&data->rx_lock) { - ret = MIN(size, ring_buf_size_get(data->rx_rb)); - size = ret; - - for (int n = 0; size > 0; size -= n, rx_data += n) { - n = ring_buf_get(data->rx_rb, rx_data, size); - } + bytes_to_read = MIN(config->latch_buffer_size, ring_buf_size_get(data->rx_rb)); + ring_buf_get(data->rx_rb, rx_data, bytes_to_read); } - return ret; + return bytes_to_read; } static int uart_emul_irq_tx_ready(const struct device *dev) @@ -450,6 +449,7 @@ void uart_emul_set_errors(const struct device *dev, int errors) \ static struct uart_emul_config uart_emul_cfg_##inst = { \ .loopback = DT_INST_PROP(inst, loopback), \ + .latch_buffer_size = DT_INST_PROP(inst, latch_buffer_size), \ }; \ static struct uart_emul_data uart_emul_data_##inst = { \ .rx_rb = &uart_emul_##inst##_rx_rb, \ diff --git a/dts/bindings/serial/zephyr,uart-emul.yaml b/dts/bindings/serial/zephyr,uart-emul.yaml index d3d50dc9e93..119aa49df6a 100644 --- a/dts/bindings/serial/zephyr,uart-emul.yaml +++ b/dts/bindings/serial/zephyr,uart-emul.yaml @@ -25,3 +25,9 @@ properties: description: | Connects TX to RX internally creating a loop back connection. Useful for testing. + + latch-buffer-size: + type: int + default: 1 + description: | + Size of the virtual UART latch buffer.