Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/drivers/uart/uart_baudrate_test/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ source "Kconfig.zephyr"

config TEST_ALLOWED_DEVIATION
int "Allowed deviation (%) for UART timing checks"
default 25
default 5
range 0 100
help
Maximum allowed deviation (%) from the programmed values for the test to be
Expand Down
115 changes: 57 additions & 58 deletions tests/drivers/uart/uart_baudrate_test/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#include <zephyr/drivers/gpio.h>
#include <hal/nrf_gpio.h>
#include <stdlib.h>
#include <math.h>


static NRF_GPIO_Type *gpio_port =
((NRF_GPIO_Type *)DT_REG_ADDR(DT_GPIO_CTLR(DT_PATH(zephyr_user), gpios)));
static uint32_t pin_mask = BIT(DT_GPIO_PIN(DT_PATH(zephyr_user), gpios));
static const struct gpio_dt_spec gpio_spec =
GPIO_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), gpios, 0);
static const struct device *const uart_dev = DEVICE_DT_GET(DT_NODELABEL(dut));

static const uint8_t tx_buf[1] = {0x00};
static const uint8_t tx_buf[] = {0x00, 0x00};

#define PIN_STATE_SIZE 16384
static int pin_state[PIN_STATE_SIZE] = {};
#define PIN_STATE_SIZE 32768
static uint8_t pin_state[PIN_STATE_SIZE] = {};

#define REPEAT_NUMBER 10
#define REPEAT_NUMBER 3

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void uart_fifo_callback(const struct device *dev, void *user_data)
Expand All @@ -43,7 +48,7 @@ static void uart_fifo_callback(const struct device *dev, void *user_data)
}
#endif

static void check_timing(const struct gpio_dt_spec *gpio_dt, uint32_t baudrate)
static void check_timing(uint32_t baudrate)
{
uint64_t cycles_s_sys;
struct uart_config test_uart_config;
Expand All @@ -53,16 +58,18 @@ static void check_timing(const struct gpio_dt_spec *gpio_dt, uint32_t baudrate)
double gpio_read_time_us_mean;
int32_t start_index;
int32_t stop_index;
int32_t idle_found;
int32_t start_index_count_zero;
double bit_diviation_mean;
double symbol_diviation_mean;
bool once = true;
int key;

ret = uart_config_get(uart_dev, &test_uart_config);
zassert_equal(ret, 0, "uart_config_get: %d\n", ret);

test_uart_config.parity = UART_CFG_PARITY_EVEN;
test_uart_config.stop_bits = UART_CFG_STOP_BITS_2;
test_uart_config.stop_bits = UART_CFG_STOP_BITS_1;
test_uart_config.flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
test_uart_config.baudrate = baudrate;
ret = uart_configure(uart_dev, &test_uart_config);
Expand All @@ -75,37 +82,11 @@ static void check_timing(const struct gpio_dt_spec *gpio_dt, uint32_t baudrate)
cycles_s_sys = (uint64_t)sys_clock_hw_cycles_per_sec();
TC_PRINT("Cycles: %llu cycles\n", cycles_s_sys);

/*
* Measure time needed to read gpios
*/
gpio_read_time_us_mean = 0;
key = irq_lock();
for (uint32_t t = 0; t < REPEAT_NUMBER; ++t) {
cycle_start_time = k_cycle_get_32();
for (uint32_t i = 0; i < PIN_STATE_SIZE; ++i) {
pin_state[i] = gpio_pin_get_dt(&gpio_spec);
}
cycle_stop_time = k_cycle_get_32();
double gpio_read_time_us =
((cycle_stop_time - cycle_start_time) / (double)PIN_STATE_SIZE) *
(1e6 / cycles_s_sys);
gpio_read_time_us_mean += gpio_read_time_us;
}
irq_unlock(key);
gpio_read_time_us_mean /= (double)REPEAT_NUMBER;
TC_PRINT("GPIO get takes: %.2f us\n", gpio_read_time_us_mean);

double expected_bit_period_us = 1e6 / (double)baudrate;
double number_of_bits = 8;

number_of_bits += 1;
if (test_uart_config.stop_bits == UART_CFG_STOP_BITS_1) {
number_of_bits += 1;
} else if (test_uart_config.stop_bits == UART_CFG_STOP_BITS_2) {
number_of_bits += 2;
} else {
zassert_true(false, "Unsupported stop_bits: %d", test_uart_config.stop_bits);
}
/* Stop bit is 1 so it is not counted. */
if (test_uart_config.parity != UART_CFG_PARITY_NONE) {
number_of_bits += 1;
}
Expand All @@ -114,11 +95,6 @@ static void check_timing(const struct gpio_dt_spec *gpio_dt, uint32_t baudrate)
TC_PRINT("[%d] Expected symbol time: %.2f us, expected bit time: %.2f us\n", baudrate,
expected_symbol_period_us, expected_bit_period_us);

if (expected_bit_period_us < gpio_read_time_us_mean) {
TC_PRINT("[%d] Not supported - gpio measurement is too slow.\n", baudrate);
ztest_test_skip();
}

start_index_count_zero = 0;
bit_diviation_mean = 0;
symbol_diviation_mean = 0;
Expand All @@ -136,26 +112,49 @@ static void check_timing(const struct gpio_dt_spec *gpio_dt, uint32_t baudrate)
/*
* Check gpio
*/

key = irq_lock();
cycle_start_time = k_cycle_get_32();
for (uint32_t i = 0; i < PIN_STATE_SIZE; ++i) {
pin_state[i] = gpio_pin_get_dt(&gpio_spec);
pin_state[i] = nrf_gpio_port_in_read(gpio_port) & pin_mask ? 1 : 0;
}
cycle_stop_time = k_cycle_get_32();
irq_unlock(key);

if (once) {
/* Calculate only for the first iteration. */
uint32_t t_us = k_cyc_to_us_ceil32(cycle_stop_time - cycle_start_time);

gpio_read_time_us_mean = (double)t_us / PIN_STATE_SIZE;
once = false;
TC_PRINT("GPIO get takes: %.2f us\n", gpio_read_time_us_mean);
}

if (expected_bit_period_us < gpio_read_time_us_mean) {
TC_PRINT("[%d] Not supported - gpio measurement is too slow.\n", baudrate);
ztest_test_skip();
}

/*
* Find start of start bit and end of stop bit
* Find start of start bit and end of stop bit. For higher baudrates it is
* possible that first byte is already being transferred. In search for
* byte start and end, start from searching for idle state between byte 0 and 1.
*/
start_index = -1;
stop_index = -1;
idle_found = -1;
for (uint32_t i = 0; i < PIN_STATE_SIZE; ++i) {
if (-1 == start_index) {
if (0 == pin_state[i]) {
if (1 == pin_state[i]) {
idle_found = 0;
} else if ((idle_found == 0) && (0 == pin_state[i])) {
start_index = i;
}
} else {
if (-1 == stop_index) {
if (1 == pin_state[i]) {
stop_index = i;
break;
}
} else {
zassert_true(1 == pin_state[i], "Unexpected low at %d\n",
Expand Down Expand Up @@ -209,86 +208,86 @@ static void check_timing(const struct gpio_dt_spec *gpio_dt, uint32_t baudrate)

ZTEST(uart_baudrate_test, test_08_2400)
{
check_timing(&gpio_spec, 2400);
check_timing(2400);
}

ZTEST(uart_baudrate_test, test_09_4800)
{
check_timing(&gpio_spec, 4800);
check_timing(4800);
}

ZTEST(uart_baudrate_test, test_10_9600)
{
check_timing(&gpio_spec, 9600);
check_timing(9600);
}

ZTEST(uart_baudrate_test, test_11_14400)
{
check_timing(&gpio_spec, 14400);
check_timing(14400);
}
ZTEST(uart_baudrate_test, test_12_19200)
{
check_timing(&gpio_spec, 19200);
check_timing(19200);
}

ZTEST(uart_baudrate_test, test_13_38400)
{
check_timing(&gpio_spec, 38400);
check_timing(38400);
}

ZTEST(uart_baudrate_test, test_14_57600)
{
check_timing(&gpio_spec, 57600);
check_timing(57600);
}

ZTEST(uart_baudrate_test, test_15_115200)
{
check_timing(&gpio_spec, 115200);
check_timing(115200);
}

ZTEST(uart_baudrate_test, test_16_230400)
{
check_timing(&gpio_spec, 230400);
check_timing(230400);
}

ZTEST(uart_baudrate_test, test_17_460800)
{
check_timing(&gpio_spec, 460800);
check_timing(460800);
}

ZTEST(uart_baudrate_test, test_18_576000)
{
check_timing(&gpio_spec, 576000);
check_timing(576000);
}

ZTEST(uart_baudrate_test, test_19_921600)
{
check_timing(&gpio_spec, 921600);
check_timing(921600);
}

ZTEST(uart_baudrate_test, test_20_1000000)
{
check_timing(&gpio_spec, 1000000);
check_timing(1000000);
}

ZTEST(uart_baudrate_test, test_21_2000000)
{
check_timing(&gpio_spec, 2000000);
check_timing(2000000);
}

ZTEST(uart_baudrate_test, test_22_3000000)
{
check_timing(&gpio_spec, 3000000);
check_timing(3000000);
}

ZTEST(uart_baudrate_test, test_23_4000000)
{
check_timing(&gpio_spec, 4000000);
check_timing(4000000);
}

ZTEST(uart_baudrate_test, test_24_8000000)
{
check_timing(&gpio_spec, 8000000);
check_timing(8000000);
}

static void *uart_baudrate_test_setup(void)
Expand Down
Loading