| /* |
| * Copyright (c) 2023 Jeroen van Dooren |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include "test_uart.h" |
| |
| K_SEM_DEFINE(tx_wide_done, 0, 1); |
| K_SEM_DEFINE(tx_wide_aborted, 0, 1); |
| K_SEM_DEFINE(rx_wide_rdy, 0, 1); |
| K_SEM_DEFINE(rx_wide_buf_released, 0, 1); |
| K_SEM_DEFINE(rx_wide_disabled, 0, 1); |
| |
| static ZTEST_BMEM const struct device *const uart_dev = |
| DEVICE_DT_GET(UART_NODE); |
| |
| static void init_test(void) |
| { |
| __ASSERT_NO_MSG(device_is_ready(uart_dev)); |
| uart_rx_disable(uart_dev); |
| uart_tx_abort(uart_dev); |
| k_sem_reset(&tx_wide_done); |
| k_sem_reset(&tx_wide_aborted); |
| k_sem_reset(&rx_wide_rdy); |
| k_sem_reset(&rx_wide_buf_released); |
| k_sem_reset(&rx_wide_disabled); |
| } |
| |
| #ifdef CONFIG_USERSPACE |
| static void set_permissions(void) |
| { |
| k_thread_access_grant(k_current_get(), &tx_wide_done, &tx_wide_aborted, |
| &rx_wide_rdy, &rx_wide_buf_released, &rx_wide_disabled, |
| uart_dev); |
| } |
| #endif |
| |
| static void uart_async_test_init(void) |
| { |
| init_test(); |
| |
| #ifdef CONFIG_USERSPACE |
| set_permissions(); |
| #endif |
| } |
| |
| static void test_single_read_callback(const struct device *dev, |
| struct uart_event *evt, void *user_data) |
| { |
| ARG_UNUSED(dev); |
| |
| switch (evt->type) { |
| case UART_TX_DONE: |
| k_sem_give(&tx_wide_done); |
| break; |
| case UART_TX_ABORTED: |
| (*(uint32_t *)user_data)++; |
| break; |
| case UART_RX_RDY: |
| k_sem_give(&rx_wide_rdy); |
| break; |
| case UART_RX_BUF_RELEASED: |
| k_sem_give(&rx_wide_buf_released); |
| break; |
| case UART_RX_DISABLED: |
| k_sem_give(&rx_wide_disabled); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| ZTEST_BMEM volatile uint32_t tx_wide_aborted_count; |
| |
| static void *single_read_setup_wide(void) |
| { |
| uart_async_test_init(); |
| |
| uart_callback_set(uart_dev, |
| test_single_read_callback, |
| (void *) &tx_wide_aborted_count); |
| |
| return NULL; |
| } |
| |
| ZTEST_USER(uart_async_single_read_wide, test_single_read_wide) |
| { |
| uint16_t rx_buf[10] = {0}; |
| |
| /* Check also if sending from read only memory (e.g. flash) works. */ |
| static const uint16_t tx_buf[5] = {0x74, 0x65, 0x73, 0x74, 0x0D}; |
| |
| zassert_not_equal(memcmp(tx_buf, rx_buf, 5), 0, |
| "Initial buffer check failed"); |
| |
| uart_rx_enable_u16(uart_dev, rx_buf, 10, 50 * USEC_PER_MSEC); |
| zassert_equal(k_sem_take(&rx_wide_rdy, K_MSEC(100)), -EAGAIN, |
| "RX_RDY not expected at this point"); |
| |
| uart_tx_u16(uart_dev, tx_buf, sizeof(tx_buf)/sizeof(uint16_t), 100 * USEC_PER_MSEC); |
| zassert_equal(k_sem_take(&tx_wide_done, K_MSEC(100)), 0, "TX_DONE timeout"); |
| zassert_equal(k_sem_take(&rx_wide_rdy, K_MSEC(100)), 0, "RX_RDY timeout"); |
| zassert_equal(k_sem_take(&rx_wide_rdy, K_MSEC(100)), -EAGAIN, |
| "Extra RX_RDY received"); |
| |
| zassert_equal(memcmp(tx_buf, rx_buf, 5), 0, "Buffers not equal"); |
| zassert_not_equal(memcmp(tx_buf, rx_buf+5, 5), 0, "Buffers not equal"); |
| |
| uart_tx_u16(uart_dev, tx_buf, sizeof(tx_buf)/sizeof(uint16_t), 100 * USEC_PER_MSEC); |
| zassert_equal(k_sem_take(&tx_wide_done, K_MSEC(100)), 0, "TX_DONE timeout"); |
| zassert_equal(k_sem_take(&rx_wide_rdy, K_MSEC(100)), 0, "RX_RDY timeout"); |
| zassert_equal(k_sem_take(&rx_wide_buf_released, K_MSEC(100)), |
| 0, |
| "RX_BUF_RELEASED timeout"); |
| zassert_equal(k_sem_take(&rx_wide_disabled, K_MSEC(1000)), 0, |
| "RX_DISABLED timeout"); |
| zassert_equal(k_sem_take(&rx_wide_rdy, K_MSEC(100)), -EAGAIN, |
| "Extra RX_RDY received"); |
| |
| zassert_equal(memcmp(tx_buf, rx_buf+5, 5), 0, "Buffers not equal"); |
| zassert_equal(tx_wide_aborted_count, 0, "TX aborted triggered"); |
| } |
| |
| ZTEST_SUITE(uart_async_single_read_wide, NULL, single_read_setup_wide, |
| NULL, NULL, NULL); |