Hello,
I'am searching for hours to find a solution, but could not find one.
I use a Linux based OS built by buildroot.
According to the "i.MX 6SoloX Applications Processor Reference Manual" chapter "1.4 Features", all UART interfaces supports up to 4 Mbps.
"Six UARTs operating up to 4.0 Mbps each, …"
My problem is that I can not set the baud rate to 1000000 bit per second (1 Mbps).
# stty -F /dev/ttymxc4 1000000
stty: invalid argument '1000000'
I also toggled the hardware flow of the interface:
# stty -F /dev/ttymxc4 -crtscts
# stty -F /dev/ttymxc4 1000000
stty: invalid argument '1000000'
A C-program to set the baud rate to 1 Mbps runs without any errors but the baud rate goes to '0':
…
char *portname = "/dev/ttymxc4"
…
set_interface(fd, B1000000);
Result:
# stty -F /dev/ttymxc4
speed 0 baud; line = 0;
I also checked the UART clock speed:
# cat /sys/class/tty/ttymxc4/uartcl
80000000
What do I need to do to increase the serial baud rate to 1 Mbps?
已解决! 转到解答。
The source of the UART baud rate problem was the stty command of the used busybox- tools (v1.24.2).
A work a round to fix the problem was to install the coreutils including stty that smoothly did the job.
buildroot:
-> Target packages
-> Show packages that are also provided by busybox
-> coreutils
Furthermore, I initiated a bug report @ [1] to get the busybox tools fixed.
[1]:
The source of the UART baud rate problem was the stty command of the used busybox- tools (v1.24.2).
A work a round to fix the problem was to install the coreutils including stty that smoothly did the job.
buildroot:
-> Target packages
-> Show packages that are also provided by busybox
-> coreutils
Furthermore, I initiated a bug report @ [1] to get the busybox tools fixed.
[1]:
I also checked termios2 from this thread [How do I change the IMX6 UART clock speed] with the C-example from this thread [How to set 250000 baud rate in pyserial ? - comp.lang.python]:
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <linux/termios.h>int ioctl(int d, int request, ...);
int main(int argc, char *argv[]) {
struct termios2 t;
int fd,baud;if (argc != 3) {
fprintf(stderr,"usage: %s <device> <baud>\n", argv[0]);
return 1;
}fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
fprintf(stderr, "error opening %s: %s", argv[1], strerror(errno));
return 2;
}baud = atoi(argv[2]);
if (ioctl(fd, TCGETS2, &t)) {
perror("TCGETS2");
return 3;
}t.c_cflag &= ~CBAUD;
t.c_cflag |= BOTHER;
t.c_ispeed = baud;
t.c_ospeed = baud;if (ioctl(fd, TCSETS2, &t)) {
perror("TCSETS2");
return 4;
}if (ioctl(fd, TCGETS2, &t)) {
perror("TCGETS2");
return 5;
}printf("actual speed reported %d\n", t.c_ospeed);
return 0;}
The example is working on a USB serial adapter but not on the UART of the iMX6SX:
# stty -F /dev/ttymxc4
NUM: 0x29
DENOM: 0xC34speed 9600 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-brkint -imaxbel
# ./test_arm /dev/ttymxc4 115200NUM: 0x29
DENOM: 0xC34
NUM: 0x1F7
DENOM: 0xC34actual speed reported 115200
# stty -F /dev/ttymxc4NUM: 0x1F7
DENOM: 0xC34speed 115200 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-brkint -imaxbel
# ./test_arm /dev/ttymxc4 1000000NUM: 0x1F7
DENOM: 0xC34
NUM: 0x00
DENOM: 0x00actual speed reported 1000000
# stty -F /dev/ttymxc4NUM: 0x00
DENOM: 0x00speed 0 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-brkint -imaxbel
one can debug it using attached Linux Manual
Chapter 45 Universal Asynchronous Receiver/Transmitter
(UART) Driver and AN4553 Using Open Source Debugging Tools for Linux on i.MX Processors
http://www.nxp.com/assets/documents/data/en/application-notes/AN4553.pdf
Best regards
igor
I checked the sources [ http://www.nxp.com/docs/en/reference-manual/IMX6SXRM.pdf ] and will present my findings:
The UART circuit is clocked by "UART_CLK_ROOT". The PLL number 3 (PLL3) in the MCU is running with 480 MHz and after a static divider of 6 in the hardware "UART_CLK_ROOT" results with a frequency of 80 MHz.
According to [ https://community.nxp.com/thread/312518#comment-351167 ] the UART circuit should be able to generate the required frequency.
But why does the iMX6 not support the baud rate of 1 Mbps?
I am not sure where the problem is. Is it the hardware or the software?
But what is the relation between "UART_CLK_ROOT" and the corresponding baud rate?
I also checked the supported baud rates in my setting up to 4 Mbps:
$ for i in $(seq 1 1 4000000); do stty -F /dev/ttymxc4 $i 2> /dev/null; if [ "$?" -eq "0" ]; then echo $i; fi; done
50
75
110
134
150
200
300
600
1200
1800
2400
4800
9600
19200
38400
57600
115200
230400
460800
921600
please check with jtag (or printf) ccm and uart dividers (check uart chapter of RM)
using Figure 19-2. Clock Tree i.MX6SX Reference Manual
http://www.nxp.com/docs/en/reference-manual/IMX6SXRM.pdf
Best regards
igor
please check baudrate registers UARTx_UBMR, UARTx_UBRC,
sect.65.4.2.2 Maximum Baud Rate i.MX6SX Reference Manual
http://www.nxp.com/docs/en/reference-manual/IMX6SXRM.pdf
Best regards
igor
In now checked the registers and macros:
Marco BOTHER is defined:
BOTHER: 0x1000drivers/tty/serial/imx.c:
imx_set_termios() {
…
////////// debug @ line 1441
printk("\nNUM: 0x%02X\n", num);
printk("DENOM: 0x%02X\n\n", denom);writel(num, sport->port.membase + UBIR);
writel(denom, sport->port.membase + UBMR);
…command line:
# stty -F /dev/ttymxc4NUM: 0x1F7
DENOM: 0xC34speed 115200 baud; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-brkint -imaxbel
# stty -F /dev/ttymxc4 9600NUM: 0x1F7
DENOM: 0xC34
NUM: 0x29
DENOM: 0xC34# stty -F /dev/ttymxc4 9600
NUM: 0x29
DENOM: 0xC34# stty -F /dev/ttymxc4 115200
NUM: 0x29
DENOM: 0xC34
NUM: 0x1F7
DENOM: 0xC34# stty -F /dev/ttymxc4 921600
NUM: 0x1F7
DENOM: 0xC34
NUM: 0x23F
DENOM: 0x270# stty -F /dev/ttymxc4 1000000
stty: invalid argument '1000000'
It seems that the registers UBIR and UBMR will not be calculated and set. So where is the error in this case? Is it the Freescale driver itself?
Hi Maik
reason may be that root frequency does not allow for such configuration,
one can check parent pll and try to reprogram it (note, it may be also used by
other peripherals) and uart ccm dividers using Figure 19-2. Clock Tree i.MX6SX Reference Manual
http://www.nxp.com/docs/en/reference-manual/IMX6SXRM.pdf
Best regards
igor
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------