tests/periph_uart: add automated test

This commit is contained in:
Benjamin Valentin 2021-05-31 16:35:50 +02:00
parent d48f673597
commit 1cacb11a26
3 changed files with 94 additions and 2 deletions

View File

@ -10,4 +10,5 @@ config APPLICATION
default y default y
imply MODULE_PERIPH_UART_MODECFG imply MODULE_PERIPH_UART_MODECFG
imply MODULE_PERIPH_LPUART imply MODULE_PERIPH_LPUART
imply MODULE_PERIPH_UART_RXSTART_IRQ
depends on TEST_KCONFIG depends on TEST_KCONFIG

View File

@ -3,6 +3,7 @@ include ../Makefile.tests_common
FEATURES_REQUIRED += periph_uart FEATURES_REQUIRED += periph_uart
FEATURES_OPTIONAL += periph_lpuart # STM32 L0 and L4 provides lpuart support FEATURES_OPTIONAL += periph_lpuart # STM32 L0 and L4 provides lpuart support
FEATURES_OPTIONAL += periph_uart_modecfg FEATURES_OPTIONAL += periph_uart_modecfg
FEATURES_OPTIONAL += periph_uart_rxstart_irq
USEMODULE += shell USEMODULE += shell
USEMODULE += xtimer USEMODULE += xtimer

View File

@ -50,6 +50,10 @@
#define STDIO_UART_DEV (UART_UNDEF) #define STDIO_UART_DEV (UART_UNDEF)
#endif #endif
#ifndef STX
#define STX 0x2
#endif
typedef struct { typedef struct {
char rx_mem[UART_BUFSIZE]; char rx_mem[UART_BUFSIZE];
ringbuffer_t rx_buf; ringbuffer_t rx_buf;
@ -60,6 +64,8 @@ static uart_ctx_t ctx[UART_NUMOF];
static kernel_pid_t printer_pid; static kernel_pid_t printer_pid;
static char printer_stack[THREAD_STACKSIZE_MAIN]; static char printer_stack[THREAD_STACKSIZE_MAIN];
static bool test_mode;
#ifdef MODULE_PERIPH_UART_MODECFG #ifdef MODULE_PERIPH_UART_MODECFG
static uart_data_bits_t data_bits_lut[] = { UART_DATA_BITS_5, UART_DATA_BITS_6, static uart_data_bits_t data_bits_lut[] = { UART_DATA_BITS_5, UART_DATA_BITS_6,
UART_DATA_BITS_7, UART_DATA_BITS_8 }; UART_DATA_BITS_7, UART_DATA_BITS_8 };
@ -83,18 +89,73 @@ static int parse_dev(char *arg)
return dev; 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) static void rx_cb(void *arg, uint8_t data)
{ {
uart_t dev = (uart_t)arg; uart_t dev = (uart_t)arg;
ringbuffer_add_one(&(ctx[dev].rx_buf), data); ringbuffer_add_one(&ctx[dev].rx_buf, data);
if (data == '\n') {
if (!test_mode && data == '\n') {
msg_t msg; msg_t msg;
msg.content.value = (uint32_t)dev; msg.content.value = (uint32_t)dev;
msg_send(&msg, printer_pid); 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) static void *printer(void *arg)
{ {
(void)arg; (void)arg;
@ -259,12 +320,41 @@ static int cmd_send(int argc, char **argv)
return 0; return 0;
} }
static int cmd_test(int argc, char **argv)
{
int dev;
if (argc < 2) {
printf("usage: %s <dev>\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[] = { static const shell_command_t shell_commands[] = {
{ "init", "Initialize a UART device with a given baudrate", cmd_init }, { "init", "Initialize a UART device with a given baudrate", cmd_init },
#ifdef MODULE_PERIPH_UART_MODECFG #ifdef MODULE_PERIPH_UART_MODECFG
{ "mode", "Setup data bits, stop bits and parity for a given UART device", cmd_mode }, { "mode", "Setup data bits, stop bits and parity for a given UART device", cmd_mode },
#endif #endif
{ "send", "Send a string through given UART device", cmd_send }, { "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 } { NULL, NULL, NULL }
}; };