From 1cacb11a261928e4552934791b3cff0139c76fbc Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Mon, 31 May 2021 16:35:50 +0200 Subject: [PATCH] tests/periph_uart: add automated test --- tests/periph_uart/Kconfig | 1 + tests/periph_uart/Makefile | 1 + tests/periph_uart/main.c | 94 +++++++++++++++++++++++++++++++++++++- 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/tests/periph_uart/Kconfig b/tests/periph_uart/Kconfig index e43f5f8de8..394cc6b398 100644 --- a/tests/periph_uart/Kconfig +++ b/tests/periph_uart/Kconfig @@ -10,4 +10,5 @@ config APPLICATION default y imply MODULE_PERIPH_UART_MODECFG imply MODULE_PERIPH_LPUART + imply MODULE_PERIPH_UART_RXSTART_IRQ depends on TEST_KCONFIG diff --git a/tests/periph_uart/Makefile b/tests/periph_uart/Makefile index c7fa83da21..20dd17f59a 100644 --- a/tests/periph_uart/Makefile +++ b/tests/periph_uart/Makefile @@ -3,6 +3,7 @@ include ../Makefile.tests_common FEATURES_REQUIRED += periph_uart FEATURES_OPTIONAL += periph_lpuart # STM32 L0 and L4 provides lpuart support FEATURES_OPTIONAL += periph_uart_modecfg +FEATURES_OPTIONAL += periph_uart_rxstart_irq USEMODULE += shell USEMODULE += xtimer diff --git a/tests/periph_uart/main.c b/tests/periph_uart/main.c index 90afb22167..0a58ae7d09 100644 --- a/tests/periph_uart/main.c +++ b/tests/periph_uart/main.c @@ -50,6 +50,10 @@ #define STDIO_UART_DEV (UART_UNDEF) #endif +#ifndef STX +#define STX 0x2 +#endif + typedef struct { char rx_mem[UART_BUFSIZE]; ringbuffer_t rx_buf; @@ -60,6 +64,8 @@ static uart_ctx_t ctx[UART_NUMOF]; static kernel_pid_t printer_pid; static char printer_stack[THREAD_STACKSIZE_MAIN]; +static bool test_mode; + #ifdef MODULE_PERIPH_UART_MODECFG static uart_data_bits_t data_bits_lut[] = { UART_DATA_BITS_5, UART_DATA_BITS_6, UART_DATA_BITS_7, UART_DATA_BITS_8 }; @@ -83,18 +89,73 @@ static int parse_dev(char *arg) return dev; } +#ifdef MODULE_PERIPH_UART_RXSTART_IRQ +static void rxs_cb(void *arg) +{ + ringbuffer_add_one(arg, STX); +} +#endif + static void rx_cb(void *arg, uint8_t data) { uart_t dev = (uart_t)arg; - ringbuffer_add_one(&(ctx[dev].rx_buf), data); - if (data == '\n') { + ringbuffer_add_one(&ctx[dev].rx_buf, data); + + if (!test_mode && data == '\n') { msg_t msg; msg.content.value = (uint32_t)dev; msg_send(&msg, printer_pid); } } +static int _self_test(uart_t dev, unsigned baud) +{ + const char test_string[] = "Hello UART!"; + + if (uart_init(UART_DEV(dev), baud, rx_cb, (void *)dev)) { + printf("error configuring %u baud\n", baud); + return -1; + } + + test_mode = true; + + uart_write(dev, (uint8_t*)test_string, sizeof(test_string)); + for (unsigned i = 0; i < sizeof(test_string); ++i) { + int c = ringbuffer_get_one(&ctx[dev].rx_buf); + if (c != test_string[i]) { + printf("mismatch at index %u: %x != %x\n", i, c, test_string[i]); + return -1; + } + } + +#ifdef MODULE_PERIPH_UART_RXSTART_IRQ + /* test RX Start detection if available */ + uart_rxstart_irq_configure(dev, rxs_cb, &ctx[dev].rx_buf); + uart_rxstart_irq_enable(dev); + + uart_write(dev, (uint8_t*)test_string, sizeof(test_string)); + for (unsigned i = 0; i < sizeof(test_string); ++i) { + int c = ringbuffer_get_one(&ctx[dev].rx_buf); + if (c != STX) { + printf("expected start condition, got %x\n", c); + return -1; + } + + c = ringbuffer_get_one(&ctx[dev].rx_buf); + if (c != test_string[i]) { + printf("mismatch at index %u: %x != %x, start condition reported\n", + i, c, test_string[i]); + return -1; + } + } + uart_rxstart_irq_disable(dev); +#endif + + test_mode = false; + return 0; +} + static void *printer(void *arg) { (void)arg; @@ -259,12 +320,41 @@ static int cmd_send(int argc, char **argv) return 0; } +static int cmd_test(int argc, char **argv) +{ + int dev; + + if (argc < 2) { + printf("usage: %s \n", argv[0]); + return 1; + } + /* parse parameters */ + dev = parse_dev(argv[1]); + if (dev < 0) { + return 1; + } + + puts("[START]"); + + /* run self test with different baud rates */ + for (unsigned i = 1; i <= 12; ++i) { + if (_self_test(dev, 9600 * i)) { + puts("[FAILURE]"); + return -1; + } + } + + puts("[SUCCESS]"); + return 0; +} + static const shell_command_t shell_commands[] = { { "init", "Initialize a UART device with a given baudrate", cmd_init }, #ifdef MODULE_PERIPH_UART_MODECFG { "mode", "Setup data bits, stop bits and parity for a given UART device", cmd_mode }, #endif { "send", "Send a string through given UART device", cmd_send }, + { "test", "Run an automated test on a UART with RX and TX connected", cmd_test }, { NULL, NULL, NULL } };