From 7df2d5468583bc2d5c0d3525a2609f428cab31dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Chru=C5=9Bci=C5=84ski?= Date: Fri, 19 Apr 2024 09:50:52 +0200 Subject: [PATCH] tests: drivers: uart: Add test for line errors handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add test which validates behavior of the UART driver when there are errors on the receiver line. Signed-off-by: Krzysztof Chruściński --- tests/drivers/uart/uart_errors/CMakeLists.txt | 10 + tests/drivers/uart/uart_errors/Kconfig | 11 + tests/drivers/uart/uart_errors/README.txt | 4 + .../boards/nrf5340dk_nrf5340_cpuapp.conf | 2 + .../boards/nrf5340dk_nrf5340_cpuapp.overlay | 55 +++ .../boards/nrf54h20dk_nrf54h20_common.dtsi | 62 +++ .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 11 + .../nrf54l15pdk_nrf54l15_cpuapp.overlay | 54 +++ tests/drivers/uart/uart_errors/prj.conf | 6 + tests/drivers/uart/uart_errors/src/main.c | 435 ++++++++++++++++++ tests/drivers/uart/uart_errors/testcase.yaml | 23 + 11 files changed, 673 insertions(+) create mode 100644 tests/drivers/uart/uart_errors/CMakeLists.txt create mode 100644 tests/drivers/uart/uart_errors/Kconfig create mode 100644 tests/drivers/uart/uart_errors/README.txt create mode 100644 tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.conf create mode 100644 tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay create mode 100644 tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_common.dtsi create mode 100644 tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_cpuapp.overlay create mode 100644 tests/drivers/uart/uart_errors/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay create mode 100644 tests/drivers/uart/uart_errors/prj.conf create mode 100644 tests/drivers/uart/uart_errors/src/main.c create mode 100644 tests/drivers/uart/uart_errors/testcase.yaml diff --git a/tests/drivers/uart/uart_errors/CMakeLists.txt b/tests/drivers/uart/uart_errors/CMakeLists.txt new file mode 100644 index 00000000000..01ab729f848 --- /dev/null +++ b/tests/drivers/uart/uart_errors/CMakeLists.txt @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(uart_errors) + +target_sources(app PRIVATE + src/main.c + ) diff --git a/tests/drivers/uart/uart_errors/Kconfig b/tests/drivers/uart/uart_errors/Kconfig new file mode 100644 index 00000000000..aed523c5832 --- /dev/null +++ b/tests/drivers/uart/uart_errors/Kconfig @@ -0,0 +1,11 @@ +# UART test configuration options +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config DUAL_UART_TEST + bool "Enable dual UART test" + +config SETUP_MISMATCH_TEST + bool "Enable mismatched configuration in dual UART test" + +source "Kconfig.zephyr" diff --git a/tests/drivers/uart/uart_errors/README.txt b/tests/drivers/uart/uart_errors/README.txt new file mode 100644 index 00000000000..c2b5de24031 --- /dev/null +++ b/tests/drivers/uart/uart_errors/README.txt @@ -0,0 +1,4 @@ +The purpose of this test is to validate UART receiver when error occurs on +the line. Error is generated by the second UART driver instance which sends +certain bytes with parity enabled when receiver is configured without parity. +Additional bit triggers framing error. diff --git a/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.conf b/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..025b9236147 --- /dev/null +++ b/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,2 @@ +CONFIG_UART_1_NRF_HW_ASYNC=y +CONFIG_UART_1_NRF_HW_ASYNC_TIMER=1 diff --git a/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay b/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000..9be4328f7d1 --- /dev/null +++ b/tests/drivers/uart/uart_errors/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +&pinctrl { + uart1_default_alt: uart1_default_alt { + group1 { + psels = , + ; + }; + }; + + uart1_sleep_alt: uart1_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart2_default_alt: uart2_default_alt { + group1 { + psels = ; + }; + group2 { + psels = ; + bias-pull-up; + }; + }; + + uart2_sleep_alt: uart2_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +dut: &uart1 { + current-speed = <115200>; + compatible = "nordic,nrf-uarte"; + status = "okay"; + pinctrl-0 = <&uart1_default_alt>; + pinctrl-1 = <&uart1_sleep_alt>; + pinctrl-names = "default", "sleep"; +}; + +dut_aux: &uart2 { + current-speed = <115200>; + compatible = "nordic,nrf-uarte"; + status = "okay"; + pinctrl-0 = <&uart2_default_alt>; + pinctrl-1 = <&uart2_sleep_alt>; + pinctrl-names = "default", "sleep"; + disable-rx; +}; diff --git a/tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_common.dtsi b/tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_common.dtsi new file mode 100644 index 00000000000..cff282c8b41 --- /dev/null +++ b/tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_common.dtsi @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +&pinctrl { + uart135_default_alt: uart135_default_alt { + group1 { + psels = , + ; + }; + }; + + uart135_sleep_alt: uart135_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&pinctrl { + uart137_default_alt: uart137_default_alt { + group1 { + psels = ; + }; + group2 { + psels = + ; + bias-pull-up; + }; + }; + + uart137_sleep_alt: uart137_sleep_alt { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +dut: &uart135 { + status = "okay"; + memory-regions = <&cpuapp_dma_region>; + pinctrl-0 = <&uart135_default_alt>; + pinctrl-1 = <&uart135_sleep_alt>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; +}; + +dut_aux: &uart137 { + status = "okay"; + memory-regions = <&cpuapp_dma_region>; + pinctrl-0 = <&uart137_default_alt>; + pinctrl-1 = <&uart137_sleep_alt>; + pinctrl-names = "default", "sleep"; + current-speed = <115200>; + disable-rx; +}; diff --git a/tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000..eccd7057656 --- /dev/null +++ b/tests/drivers/uart/uart_errors/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include "nrf54h20dk_nrf54h20_common.dtsi" + +&dut_aux { + memory-regions = <&cpuapp_dma_region>; +}; + +&dut { + memory-regions = <&cpuapp_dma_region>; +}; diff --git a/tests/drivers/uart/uart_errors/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay b/tests/drivers/uart/uart_errors/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..babbc740133 --- /dev/null +++ b/tests/drivers/uart/uart_errors/boards/nrf54l15pdk_nrf54l15_cpuapp.overlay @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +&pinctrl { + uart21_default: uart21_default { + group1 { + psels = , + ; + }; + }; + + uart21_sleep: uart21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; + + uart22_default: uart22_default { + group1 { + psels = + ; + bias-pull-up; + }; + group2 { + psels = ; + }; + }; + + uart22_sleep: uart22_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +dut: &uart21 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart21_default>; + pinctrl-1 = <&uart21_sleep>; + pinctrl-names = "default", "sleep"; +}; + +dut_aux: &uart22 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart22_default>; + pinctrl-1 = <&uart22_sleep>; + pinctrl-names = "default", "sleep"; + disable-rx; +}; diff --git a/tests/drivers/uart/uart_errors/prj.conf b/tests/drivers/uart/uart_errors/prj.conf new file mode 100644 index 00000000000..5d44ebeccd2 --- /dev/null +++ b/tests/drivers/uart/uart_errors/prj.conf @@ -0,0 +1,6 @@ +CONFIG_SERIAL=y +CONFIG_ZTEST=y +CONFIG_TEST_USERSPACE=y +CONFIG_UART_USE_RUNTIME_CONFIGURE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_PM_DEVICE=y diff --git a/tests/drivers/uart/uart_errors/src/main.c b/tests/drivers/uart/uart_errors/src/main.c new file mode 100644 index 00000000000..657275448d1 --- /dev/null +++ b/tests/drivers/uart/uart_errors/src/main.c @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @addtogroup t_driver_uart + * @{ + * @defgroup t_uart_errors test_uart_errors + * @} + */ + +#include +#include +#include +#include +LOG_MODULE_REGISTER(test, LOG_LEVEL_NONE); + +#if DT_NODE_EXISTS(DT_NODELABEL(dut)) +#define UART_NODE DT_NODELABEL(dut) +#else +#error "No dut device in the test" +#endif + +#if DT_NODE_EXISTS(DT_NODELABEL(dut_aux)) +#define UART_NODE_AUX DT_NODELABEL(dut_aux) +#else +#error "No dut_aux device in the test" +#endif + +static const struct device *const uart_dev = DEVICE_DT_GET(UART_NODE); +static const struct device *const uart_dev_aux = DEVICE_DT_GET(UART_NODE_AUX); + +#define RX_CHUNK_CNT 2 +#define RX_CHUNK_LEN 16 +#define RX_TIMEOUT (1 * USEC_PER_MSEC) + +static uint8_t rx_chunks[RX_CHUNK_CNT][16]; +static uint32_t rx_chunks_mask = BIT_MASK(RX_CHUNK_CNT); +static uint8_t rx_buffer[256]; +static uint32_t rx_buffer_cnt; +static volatile uint32_t rx_stopped_cnt; +static volatile bool rx_active; + +struct aux_dut_data { + const uint8_t *buf; + size_t len; + size_t curr; + int err_byte; + struct k_sem *sem; + bool cfg_ok; +}; + +/* Simple buffer allocator. If allocation fails then test fails inside that function. */ +static uint8_t *alloc_rx_chunk(void) +{ + uint32_t idx; + + zassert_true(rx_chunks_mask > 0); + + idx = __builtin_ctz(rx_chunks_mask); + rx_chunks_mask &= ~BIT(idx); + + return rx_chunks[idx]; +} + +static void free_rx_chunk(uint8_t *buf) +{ + memset(buf, 0, RX_CHUNK_LEN); + for (size_t i = 0; i < ARRAY_SIZE(rx_chunks); i++) { + if (rx_chunks[i] == buf) { + rx_chunks_mask |= BIT(i); + break; + } + } +} + +static void dut_async_callback(const struct device *dev, struct uart_event *evt, void *user_data) +{ + switch (evt->type) { + case UART_TX_DONE: + zassert_true(false); + break; + case UART_RX_RDY: + LOG_INF("RX:%p len:%d off:%d", + (void *)evt->data.rx.buf, evt->data.rx.len, evt->data.rx.offset); + /* Aggregate all received data into a single buffer. */ + memcpy(&rx_buffer[rx_buffer_cnt], &evt->data.rx.buf[evt->data.rx.offset], + evt->data.rx.len); + rx_buffer_cnt += evt->data.rx.len; + break; + case UART_RX_BUF_REQUEST: + { + uint8_t *buf = alloc_rx_chunk(); + + LOG_INF("buf request: %p", (void *)buf); + zassert_equal(uart_rx_buf_rsp(dev, buf, RX_CHUNK_LEN), 0); + break; + } + case UART_RX_BUF_RELEASED: + LOG_INF("buf release: %p", (void *)evt->data.rx_buf.buf); + free_rx_chunk(evt->data.rx_buf.buf); + break; + case UART_RX_DISABLED: + zassert_true(rx_chunks_mask == BIT_MASK(RX_CHUNK_CNT)); + /* If test continues re-enable the receiver. Disabling may happen + * during the test after error is detected. + */ + if (rx_active) { + uint8_t *buf = alloc_rx_chunk(); + int err; + + LOG_INF("RX disabled, re-enabling:%p", (void *)buf); + err = uart_rx_enable(dev, buf, RX_CHUNK_LEN, RX_TIMEOUT); + zassert_equal(err, 0); + } else { + LOG_WRN("RX disabled"); + } + break; + case UART_RX_STOPPED: + LOG_WRN("RX error"); + rx_stopped_cnt++; + break; + default: + zassert_true(false); + break; + } + +} + +static void dut_int_callback(const struct device *dev, void *user_data) +{ + while (uart_irq_update(dev) && uart_irq_is_pending(dev)) { + zassert_false(uart_irq_tx_ready(dev)); + if (uart_err_check(dev) != 0) { + rx_stopped_cnt++; + } + if (uart_irq_rx_ready(dev)) { + size_t rem = sizeof(rx_buffer) - rx_buffer_cnt; + int len = uart_fifo_read(dev, &rx_buffer[rx_buffer_cnt], rem); + + zassert_true(len >= 0); + rx_buffer_cnt += len; + } + } +} + +static void aux_async_callback(const struct device *dev, struct uart_event *evt, void *user_data) +{ + struct k_sem *sem = user_data; + + switch (evt->type) { + case UART_TX_DONE: + k_sem_give(sem); + break; + default: + zassert_true(false); + break; + } +} + +/* Callback is handling injection of one corrupted byte. In order to corrupt that byte + * uart must be reconfigured so when it is time to reconfigure interrupt is disabled + * and semaphore is posted to reconfigure the uart in the thread context. + */ +static void aux_int_callback(const struct device *dev, void *user_data) +{ + struct aux_dut_data *data = user_data; + size_t req_len; + size_t tx_len; + bool completed = data->curr == data->len; + bool inject_err = data->err_byte >= 0; + bool pre_err = inject_err && (data->curr == data->err_byte); + bool post_err = inject_err && ((data->curr + 1) == data->err_byte); + bool trig_reconfig = ((pre_err && data->cfg_ok) || (post_err && !data->cfg_ok)); + + while (uart_irq_tx_ready(dev)) { + if (completed || trig_reconfig) { + /* Transmission completed or not configured correctly. */ + uart_irq_tx_disable(dev); + k_sem_give(data->sem); + } else { + if (pre_err) { + req_len = 1; + } else if (inject_err && (data->curr < data->err_byte)) { + req_len = data->err_byte - data->curr; + } else { + req_len = data->len - data->curr; + } + + tx_len = uart_fifo_fill(dev, &data->buf[data->curr], req_len); + data->curr += tx_len; + } + } +} + +static void reconfigure(const struct device *dev, bool cfg_ok, bool *hwfc) +{ + struct uart_config config; + + zassert_equal(uart_config_get(uart_dev, &config), 0); + + if (hwfc) { + if (IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN)) { + /* Reconfiguration may happen on disabled device. In the + * interrupt driven mode receiver is always on so we need + * to suspend the device to disable the receiver and + * reconfigure it. + */ + pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND); + } + config.flow_ctrl = *hwfc ? UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE; + } + + config.parity = cfg_ok ? UART_CFG_PARITY_NONE : UART_CFG_PARITY_EVEN; + + zassert_equal(uart_configure(dev, &config), 0); + + if (hwfc) { + if (IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN)) { + pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME); + } + } +} + +/** @brief Transmit a buffer with optional one byte corrupted. + * + * Function supports asynchronous and interrupt driven APIs. + * + * @param dev Device. + * @param buf Buffer. + * @param len Buffer length. + * @param err_byte Index of byte which is sent with parity enabled. -1 to send without error. + */ +static void aux_tx(const struct device *dev, const uint8_t *buf, size_t len, int err_byte) +{ + int err; + struct k_sem sem; + + k_sem_init(&sem, 0, 1); + + if (IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN)) { + struct aux_dut_data data = { + .buf = buf, + .len = len, + .err_byte = err_byte, + .cfg_ok = true, + .sem = &sem + }; + + err = uart_irq_callback_user_data_set(dev, aux_int_callback, &data); + zassert_equal(err, 0); + + uart_irq_tx_enable(dev); + + if (err_byte >= 0) { + /* Reconfigure to unaligned configuration. */ + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); + data.cfg_ok = false; + reconfigure(dev, false, NULL); + uart_irq_tx_enable(dev); + + /* Reconfigure back to correct configuration. */ + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); + data.cfg_ok = true; + reconfigure(dev, true, NULL); + uart_irq_tx_enable(dev); + } + + /* Wait for completion. */ + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); + return; + } + + err = uart_callback_set(dev, aux_async_callback, &sem); + zassert_equal(err, 0); + + if (err_byte < 0) { + err = uart_tx(dev, buf, len, 100 * USEC_PER_MSEC); + zassert_equal(err, 0); + + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); + return; + } else if (err_byte > 0) { + err = uart_tx(dev, buf, err_byte, 100 * USEC_PER_MSEC); + zassert_equal(err, 0); + + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); + } + /* Reconfigure to unaligned configuration that will lead to error. */ + reconfigure(dev, false, NULL); + + err = uart_tx(dev, &buf[err_byte], 1, 100 * USEC_PER_MSEC); + zassert_equal(err, 0); + + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); + /* Reconfigure back to the correct configuration. */ + reconfigure(dev, true, NULL); + + err = uart_tx(dev, &buf[err_byte + 1], len - err_byte - 1, 100 * USEC_PER_MSEC); + zassert_equal(err, 0); + + err = k_sem_take(&sem, K_MSEC(100)); + zassert_equal(err, 0); +} + +/** @brief Test function. + * + * Test starts by sending 10 bytes without error then 10 bytes with an error on + * @p err_byte and then again 10 bytes without error. It is expected that driver + * will receive correctly first 10 bytes then detect error and recover to + * receive correctly last 10 bytes. + * + * @param hwfc Use hardware flow control. + * @param err_byte Index of corrupted byte in the second 10 byte sequence. + */ +static void test_detect_error(bool hwfc, int err_byte) +{ + uint8_t buf[10]; + int err; + + reconfigure(uart_dev, true, &hwfc); + reconfigure(uart_dev_aux, true, &hwfc); + + for (size_t i = 0; i < sizeof(buf); i++) { + buf[i] = i; + } + + if (IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN)) { + uart_irq_err_enable(uart_dev); + uart_irq_rx_enable(uart_dev); + } else { + uint8_t *b = alloc_rx_chunk(); + + LOG_INF("dut rx enable buf:%p", (void *)b); + err = uart_rx_enable(uart_dev, b, RX_CHUNK_LEN, RX_TIMEOUT); + zassert_equal(err, 0); + } + + /* Send TX without error */ + aux_tx(uart_dev_aux, buf, sizeof(buf), -1); + /* Send TX without error */ + + k_msleep(10); + zassert_equal(sizeof(buf), rx_buffer_cnt, "Expected %d got %d", sizeof(buf), rx_buffer_cnt); + zassert_equal(memcmp(buf, rx_buffer, rx_buffer_cnt), 0); + + /* Send TX with error on nth byte. */ + aux_tx(uart_dev_aux, buf, sizeof(buf), err_byte); + + /* At this point when error is detected receiver will be restarted and it may + * be started when there is a transmission on the line if HWFC is disabled + * which will trigger next error so until there is a gap on the line there + * might be multiple errors detected. However, when HWFC is enabled then there + * should be only one error. + */ + k_msleep(100); + zassert_true(rx_stopped_cnt > 0); + + /* Send TX without error. Receiver is settled so it should be correctly received. */ + aux_tx(uart_dev_aux, buf, sizeof(buf), -1); + + k_msleep(100); + TC_PRINT("RX bytes:%d/%d err_cnt:%d\n", rx_buffer_cnt, 3 * sizeof(buf), rx_stopped_cnt); + + LOG_HEXDUMP_INF(rx_buffer, rx_buffer_cnt, "Received data:"); + + /* Last received chunk should be correct. */ + zassert_equal(memcmp(buf, &rx_buffer[rx_buffer_cnt - sizeof(buf)], sizeof(buf)), 0); + + if (IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN)) { + uart_irq_err_disable(uart_dev); + uart_irq_rx_disable(uart_dev); + } else { + rx_active = false; + err = uart_rx_disable(uart_dev); + zassert_true((err == 0) || (err == -EFAULT)); + + k_msleep(10); + } +} + +ZTEST(uart_errors, test_detect_error_first_byte) +{ + test_detect_error(false, 0); +} + +ZTEST(uart_errors, test_detect_error_in_the_middle) +{ + test_detect_error(false, 5); +} + +ZTEST(uart_errors, test_detect_error_first_byte_hwfc) +{ + test_detect_error(true, 0); +} + +ZTEST(uart_errors, test_detect_error_in_the_middle_hwfc) +{ + test_detect_error(true, 5); +} + +/* + * Test setup + */ +static void *test_setup(void) +{ + zassert_true(device_is_ready(uart_dev), "DUT UART device is not ready"); + zassert_true(device_is_ready(uart_dev_aux), "DUT_AUX UART device is not ready"); + + if (IS_ENABLED(CONFIG_UART_INTERRUPT_DRIVEN)) { + zassert_equal(uart_irq_callback_set(uart_dev, dut_int_callback), 0); + } else { + zassert_equal(uart_callback_set(uart_dev, dut_async_callback, NULL), 0); + } + + return NULL; +} + +static void before(void *unused) +{ + ARG_UNUSED(unused); + rx_buffer_cnt = 0; + rx_stopped_cnt = 0; + rx_active = true; +} + +ZTEST_SUITE(uart_errors, NULL, test_setup, before, NULL, NULL); diff --git a/tests/drivers/uart/uart_errors/testcase.yaml b/tests/drivers/uart/uart_errors/testcase.yaml new file mode 100644 index 00000000000..9ce1e989c67 --- /dev/null +++ b/tests/drivers/uart/uart_errors/testcase.yaml @@ -0,0 +1,23 @@ +common: + tags: drivers uart + depends_on: gpio + harness: ztest + harness_config: + fixture: gpio_loopback +tests: + drivers.uart.uart_errors.int_driven: + filter: CONFIG_SERIAL_SUPPORT_INTERRUPT + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp + - nrf5340dk/nrf5340/cpuapp + drivers.uart.uart_errors.async: + filter: CONFIG_SERIAL_SUPPORT_ASYNC + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15pdk/nrf54l15/cpuapp + - nrf5340dk/nrf5340/cpuapp + extra_configs: + - CONFIG_UART_ASYNC_API=y + - CONFIG_UART_INTERRUPT_DRIVEN=n + - CONFIG_PM_DEVICE=n