zephyr: stm32: serial: Data is not read properly at a certain baud rate

Describe the bug UART data is not read properly at a certain baud rate.

To Reproduce Board: stm32f4_disco Barcode module: EM1399
image

I was conducting a test with EM1399 to read the barcode. EM1399 is connected to UART1.

west init zephyrproject -m https://github.com/KwonTae-young/zephyr/ --mr code
cd zephyrproject/zephyr
source zephyr-env.sh
mkdir samples/barcode/build
cd samples/barcode/build/
cmake -DBOARD=stm32f4_disco ..
make -j8 flash

Expected behavior I expected the scanned barcode information to be output.

Impact At certain baud rate, barcode data is not read properly through UART.

Screenshots or console output I have tested on a total of two boards.(stm32f4_disco, nrf52840_pca10056) stm32f4_disco does not read the data properly. nrf52840_pca10056 reads the data correctly.

  1. UART setup of EM1399
EM1399
baud rate 9600
stop bit 1
data bit 8
parity none
flow control none
  1. stm32f4_disco image
  • pin connection
EM1399 stm32f4_disco
VDD(2) 3V
GND(3) GND
TX(5) PB7(UART1_RX)
nTrig(12) custom button
  • console
***** Booting Zephyr OS zephyr-v1.13.0-5106-g5d6c36b85f *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=9600
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 32 (1 bytes)
uart_isr: 37 (1 bytes)
uart_isr: 31 (1 bytes)
uart_isr: 36 (1 bytes)
uart_isr: 0a (1 bytes)
  1. nrf52840_pca10056 image
  • pin connection
EM1399 nrf52840_pca10056
VDD(2) 3V
GND(3) GND
TX(5) P0.27(UART1_RX)
nTrig(12) custom button
  • console
***** Booting Zephyr OS zephyr-v1.13.0-5105-g7352d2b0c1 *****
Sample app running on: nrf52840_pca10056
uart_init() done
uart_config.baudrate=9600
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 32 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 37 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 31 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 36 (1 bytes)
uart_isr: 0d (1 bytes)

Environment (please complete the following information):

  • OS: Linux(Ubuntu 18.04)
  • Toolchain: Zephyr SDK 0.9.5
  • Commit SHA or Version used: 7352d2b0c1b912c4e95ef0977cc310f9f427d6ed.

Additional context nrf52840_pca10056 is normal and only stm32f4_disco is read strangely. So I think it is a bug. The barcode data tested is shown below. image

/*
 * Copyright (c) 2015 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <stdio.h>
#include <zephyr/types.h>
#include <string.h>
#include <uart.h>
#include <misc/byteorder.h>

#define BUF_MAXSIZE	256
#define SLEEP_TIME	500

static struct device *uart_dev;
static u8_t rx_buf[BUF_MAXSIZE];

static void msg_dump(const char *s, u8_t *data, unsigned len)
{
	unsigned i;

	printf("%s: ", s);
	for (i = 0U; i < len; i++) {
		printf("%02x ", data[i]);
	}
	printf("(%u bytes)\n", len);
}

static void uart_isr(struct device *x)
{
	int len = uart_fifo_read(uart_dev, rx_buf, BUF_MAXSIZE);

	ARG_UNUSED(x);
	msg_dump(__func__, rx_buf, len);
}

static void uart_init(void)
{
	uart_dev = device_get_binding("UART_1");

	uart_irq_callback_set(uart_dev, uart_isr);
	uart_irq_rx_enable(uart_dev);

	printf("%s() done\n", __func__);
}

void main(void)
{
	struct uart_config uart_cfg;
	int ret;

	printf("Sample app running on: %s\n", CONFIG_BOARD);

	uart_init();

	ret = uart_config_get(uart_dev, &uart_cfg);
	if (ret == 0) {
		printf("uart_config.baudrate=%d\n", uart_cfg.baudrate);
		printf("uart_config.parity=%d\n", uart_cfg.parity);
		printf("uart_config.stop_bits=%d\n", uart_cfg.stop_bits);
		printf("uart_config.data_bits=%d\n", uart_cfg.data_bits);
		printf("uart_config.flow_ctrl=%d\n", uart_cfg.flow_ctrl);
	} else {
		printf("uart_config_get() error\n");
	}

	while (1) {
		k_sleep(SLEEP_TIME);
	}
}
  • baud rate I tested it by changing the baud rate. The baud rate of EM1399 and stm32f4_disco are set equal. The test results show that the data was read correctly only on 2400 and 4800. Below is the log by the baud rate I tested in stm32f4_disco.
  1. baud rate: 1200
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=1200
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
uart_isr: 00 (1 bytes)
  1. baud date: 2400
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=2400
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 32 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 37 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 31 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 36 (1 bytes)
uart_isr: 0d (1 bytes)
uart_isr: 0a (1 bytes)
  1. baud rate: 4800
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=4800
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 32 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 37 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 31 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 36 (1 bytes)
uart_isr: 0d (1 bytes)
uart_isr: 0a (1 bytes)
  1. baud rate: 9600
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=9600
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 32 (1 bytes)
uart_isr: 37 (1 bytes)
uart_isr: 31 (1 bytes)
uart_isr: 36 (1 bytes)
uart_isr: 0a (1 bytes)
  1. baud rate: 14400
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=14400
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 39 (1 bytes)
uart_isr: 32 (1 bytes)
uart_isr: 34 (1 bytes)
uart_isr: 36 (1 bytes)
  1. baud rate: 19200
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=19200
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 30 (1 bytes)
uart_isr: 37 (1 bytes)
uart_isr: 36 (1 bytes)
  1. baud rate: 38400
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=38400
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 37 (1 bytes)
  1. baud rate: 57600
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=57600
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)
uart_isr: 34 (1 bytes)
  1. baud rate: 115200
***** Booting Zephyr OS zephyr-v1.13.0-5106-g34550e11e9 *****
Sample app running on: stm32f4_disco
uart_init() done
uart_config.baudrate=115200
uart_config.parity=0
uart_config.stop_bits=1
uart_config.data_bits=3
uart_config.flow_ctrl=0
uart_isr: 38 (1 bytes)
uart_isr: 38 (1 bytes)

I’m sorry I do not have enough English. Thank you.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Txs @pfalcon for help on this. @KwonTae-young, please close the issue when you think it is ok.

@KwonTae-young:

It is read well using the tty API.

Glad to hear!

I created a program that reads the barcode using the tty API. The source has been uploaded to the tty_api_test branch.

/*
 * Copyright (c) 2015 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <stdio.h>
#include <uart.h>
#include <device.h>
#include <console.h>
#include <tty.h>
#include <string.h>

#define BARCODE_UART_PORT	"UART_1"

static struct device *uart_dev;
static struct tty_serial console_serial;

static u8_t console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE];
static u8_t barcode_buf[64];
static u8_t length = 0;

int barcode_init()
{
	struct uart_config uart_cfg;
	int ret;

	uart_dev = device_get_binding(BARCODE_UART_PORT);
	if (uart_dev == NULL) {
		printf("Failed to get %s\n", BARCODE_UART_PORT);
		return -1;
	}

	ret = uart_config_get(uart_dev, &uart_cfg);
	if (!ret) {
		printf("\n======== [%s] ========\n", BARCODE_UART_PORT);
		printf("[%s] uart_config.baudrate=%d\n", BARCODE_UART_PORT, uart_cfg.baudrate);
		printf("[%s] uart_config.parity=%d\n", BARCODE_UART_PORT, uart_cfg.parity);
		printf("[%s] uart_config.stop_bits=%d\n", BARCODE_UART_PORT, uart_cfg.stop_bits);
		printf("[%s] uart_config.data_bits=%d\n", BARCODE_UART_PORT, uart_cfg.data_bits);
		printf("[%s] uart_config.flow_ctrl=%d\n", BARCODE_UART_PORT, uart_cfg.flow_ctrl);
	} else {
		printf("uart_config_get() error\n");
		return -1;
	}

	tty_init(&console_serial, uart_dev);
	tty_set_rx_buf(&console_serial, console_rxbuf, sizeof(console_rxbuf));

	return 0;
}


int get_barcode()
{
	int size = 0;

	size = tty_read(&console_serial, console_rxbuf, 1);
	if (size > 0) {
		barcode_buf[length++] = console_rxbuf[0];
		if (console_rxbuf[0] == 0x0a) {
			return 0;
		}
	}

	return -1;
}

void main(void)
{
	int i, ret;

	printf("tty API sample app running on(for barcode): %s\n", CONFIG_BOARD);

	ret = barcode_init();
	if (ret) {
		printf("barcode_init() error\n");
		return;
	}

	while (1) {
		if (!get_barcode()) {
			printf("barcode data: ");
			for (i = 0; i < length; i++) {
				printf("%02x ", barcode_buf[i]);
			}
			printf("\n");

			length = 0;
			memset(console_rxbuf, 0x00, sizeof(console_rxbuf));
			memset(barcode_buf, 0x00, sizeof(barcode_buf));
		}
	}

	return;
}

I created two barcodes for testing. It is read well using the tty API. image image

***** Booting Zephyr OS zephyr-v1.13.0-5108-gd6e60d5cb0 *****
tty API sample app running on(for barcode): stm32f4_disco

======== [UART_1] ========
[UART_1] uart_config.baudrate=9600
[UART_1] uart_config.parity=0
[UART_1] uart_config.stop_bits=1
[UART_1] uart_config.data_bits=3
[UART_1] uart_config.flow_ctrl=0
barcode data: 31 32 33 34 35 36 37 38 39 30 0d 0a
barcode data: 31 32 33 34 35 36 37 38 39 30 0d 0a
barcode data: 31 32 33 34 35 36 37 38 39 30 0d 0a
barcode data: 5a 65 70 68 79 72 0d 0a
barcode data: 5a 65 70 68 79 72 0d 0a
barcode data: 5a 65 70 68 79 72 0d 0a