tests/periph_uart_mode: Add uart_mode test for single UART MCU

The existing periph_uart test depends on having more than one UART.
This test allows for manual testing with the use of a probe

on-behalf-of: @sparkmeter <ben.postman@sparkmeter.io>
This commit is contained in:
Ben Postman 2019-06-03 14:47:12 -04:00
parent 9a000cf4e6
commit 567fa8e32d
3 changed files with 216 additions and 0 deletions

View File

@ -0,0 +1,14 @@
include ../Makefile.tests_common
BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-leonardo arduino-nano\
arduino-uno nucleo-f031k6
FEATURES_REQUIRED += periph_uart
FEATURES_REQUIRED += periph_uart_modecfg
USEMODULE += xtimer
# Set this to prevent welcome message from printing and confusing output
CFLAGS+=-DLOG_LEVEL=LOG_NONE
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,22 @@
Expected result
===============
Use a probe to examine the output from the UART. It tests all
permutations of data-bits, parity, and stop-bits. For each mode, the mode
configuration will be printed to STDOUT as:
<data-bits><parity-bits><stop-bits>
For example: 7 data-bits, even parity, and 2 stop-bits would be: 7E2
Only supported mode strings will be printed out. At the end of the
test, the default mode will be restored, and a list indicating which
modes were supported and unsupported by the device. The scope still
needs to be used to validate that the settings were applied properly.
If a different BAUD rate than 115200 is desired, compile with:
`CFLAGS+=-DSTDIO_UART_BAUDRATE=<BAUD>`
Background
==========
This test was created because the existing periph_uart test relies on the
presence of multiple UARTs, so that one can be used for the shell, and another
for testing. This test requires no shell hookup, and automatically runs through
the test procedure, relying on a probe to examine the results.

View File

@ -0,0 +1,180 @@
/*
* Copyright (C) 2018 Sparkmeter
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Manual test application for UART mode on CPUs with only one UART
*
* @author Ben Postman <ben.l.postman@gmail.com>
*
* @}
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "periph/uart.h"
#include "stdio_uart.h"
#include "xtimer.h"
/* Number of different options for each mode parameter */
#define DATA_BIT_OPTIONS (4)
#define PARITY_OPTIONS (5)
#define STOP_BIT_OPTIONS (2)
#define TOTAL_OPTIONS (DATA_BIT_OPTIONS * PARITY_OPTIONS * STOP_BIT_OPTIONS)
/* Character positions in the mode string */
#define DATA_BIT_POS (0)
#define PARITY_POS (1)
#define STOP_BIT_POS (2)
/* Length of the printable mode string, includes null terminator */
#define MODE_STR_LEN (4)
/* UART_DEV is always 0 since this test is for device with 1 UART */
#define _UART_DEV (UART_DEV(0))
/* Delay between each mode, makes parsing results easier */
#ifndef DELAY_US
#define DELAY_US 50000
#endif
/* Stores each mode string for printing at the end of the test */
static char mode_strings[TOTAL_OPTIONS][MODE_STR_LEN];
static void _get_mode(const uart_data_bits_t data_bits,
const uart_parity_t parity, const uart_stop_bits_t stop_bits, char* mode_str) {
switch (data_bits) {
case UART_DATA_BITS_5:
mode_str[DATA_BIT_POS] = '5';
break;
case UART_DATA_BITS_6:
mode_str[DATA_BIT_POS] = '6';
break;
case UART_DATA_BITS_7:
mode_str[DATA_BIT_POS] = '7';
break;
case UART_DATA_BITS_8:
mode_str[DATA_BIT_POS] = '8';
break;
default:
break;
}
switch (parity) {
case UART_PARITY_NONE:
mode_str[PARITY_POS] = 'N';
break;
case UART_PARITY_EVEN:
mode_str[PARITY_POS] = 'E';
break;
case UART_PARITY_ODD:
mode_str[PARITY_POS] = 'O';
break;
case UART_PARITY_MARK:
mode_str[PARITY_POS] = 'M';
break;
case UART_PARITY_SPACE:
mode_str[PARITY_POS] = 'S';
break;
default:
break;
}
switch (stop_bits) {
case UART_STOP_BITS_1:
mode_str[STOP_BIT_POS] = '1';
break;
case UART_STOP_BITS_2:
mode_str[STOP_BIT_POS] = '2';
break;
default:
break;
}
mode_str[MODE_STR_LEN - 1] = '\0';
}
int main(void)
{
int8_t status;
/* Stores the result for each mode */
bool results[TOTAL_OPTIONS];
/* Results index that is used to associate mode_strings and results */
uint8_t ridx = 0;
/* Use arrays so that each option can be easily iterated over */
const uart_data_bits_t data_bits[DATA_BIT_OPTIONS] = {
UART_DATA_BITS_5,
UART_DATA_BITS_6,
UART_DATA_BITS_7,
UART_DATA_BITS_8
};
const uart_parity_t parity[PARITY_OPTIONS] = {
UART_PARITY_NONE,
UART_PARITY_EVEN,
UART_PARITY_ODD,
UART_PARITY_MARK,
UART_PARITY_SPACE
};
const uart_stop_bits_t stop_bits[STOP_BIT_OPTIONS] = {
UART_STOP_BITS_1,
UART_STOP_BITS_2
};
/* Test each permutation */
for (int didx = 0; didx < 4; ++didx) {
for (int pidx = 0; pidx < 5; ++pidx) {
for (int sidx = 0; sidx < 2; ++sidx) {
/* Initialize stdio to get printf */
stdio_init();
status = uart_mode(_UART_DEV, data_bits[didx],
parity[pidx], stop_bits[sidx]);
_get_mode(data_bits[didx], parity[pidx],
stop_bits[sidx], mode_strings[ridx]);
if (status == UART_OK) {
results[ridx] = true;
printf("%s\n", mode_strings[ridx]);
xtimer_usleep(DELAY_US);
}
else {
results[ridx] = false;
}
ridx++;
}
}
}
/* Reset mode and print results */
stdio_init();
uart_mode(_UART_DEV, UART_DATA_BITS_8, UART_PARITY_NONE, UART_STOP_BITS_1);
for (int i = 0; i < TOTAL_OPTIONS; ++i) {
if (results[i] == true) {
printf("%s: Supported\n", mode_strings[i]);
}
else {
printf("%s: Unsupported\n", mode_strings[i]);
}
}
return 0;
}