You may be interested in the technical reference manual. Go here, click on “Jetson TX1” (you may need to register, but it’s free). From there, type “technical” in the filter. The link for “Tegra X1 (SoC) Technical Reference Manual”, provides detailed information on the Tegra X1 module. Chapter 36 gives information on the UARTs. Note that the UART controllers have more than one mode, and not all settings apply to all modes. The 16450 is older, the 16550 should be what you use. Although the UART defaults to 16450 I think L4T puts it into 16550 mode.
According to the TRM speeds up to 12.5 Mbps are supported (I don’t know the exact speeds). You would have a harder time with higher speeds if not using hardware flow control. Additionally, there was a patch for the driver of the ttyTHS* devices (the “ttyTHS*” names, versus “ttyS*” names, is an indicator of using DMA for theoretically lower latency); without that higher speeds would be problematic. With hardware flow control (CTS/DTS versus 3-wire software flow control) you’ll find it easier to reach higher speeds. In the case of 3-wire software flow control your cable lengths and quality will need to be better and/or shorter lengths even if you have that patch in.
The patches I mentioned were created for R24.1, current release is R24.2.1, so it may be these are no longer needed (I haven’t checked). I’d advise upgrading the L4T version anyway if you’re not running the current version. Here’s the serial port patches (use “git clone https://bitbucket.org/tealdrones/nvidia_tx1_patches/src”):
https://bitbucket.org/tealdrones/nvidia_tx1_patches/src
Some serial port related commands you may be interested in checking out:
- setserial
- statserial
- stty
- ser2net
Note that at least in the case of setserial (and probably some other commands) that a query usually asks the driver what its settings are. This is not the same as what the actual hardware is using unless the setting is compatible. UARTs are not plug-n-play devices, so sometimes a command for a driver tries blindly to use a setting and does not necessarily know if the hardware actually accepted the setting.
Additionally, I find many serial console programs antiquated such that they only accept devices named by “ttyS#” format, at least in the GUI. When you go to change a setting within the GUI, even if you only go to change speed, you may find the port has reverted to ttyS0 and is no longer what you wanted…you may need to type this in each time you change any setting via GUI. Command line options to gtkterm for port (e.g., “-p /dev/ttyUSB0” or “-p /dev/ttyTHS2”) are the most reliable way to change port. You can also specify speed on command line to gtkterm via the "-s " option…but once again you may find serial port programs (and other serial software) are idiots and sometimes won’t accept a setting because they were hard wired to believe 115200 is the speed cap.
An example:
sudo -s
stty -F /dev/ttyTHS2 115200
stty -F /dev/ttyUSB0 115200
gtkterm -p /dev/ttyTHS2 -s 115200 &
gtkterm -p /dev/ttyUSB0 -s 115200 &
# ...type stuff...
# ...exit the gtkterm programs...
stty -F /dev/ttyTHS2 9600
stty -F /dev/ttyUSB0 9600
gtkterm -p /dev/ttyTHS2 -s 9600 &
gtkterm -p /dev/ttyUSB0 -s 9600 &
# ...type stuff...
# ...exit the gtkterm programs...
# Do other things with serial ports...
# observe settings:
stty -a -F /dev/ttyTHS2
speed 115200 baud; rows 0; columns 0; 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; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
# OR SHORT FORM:
stty -F /dev/ttyTHS2 115200
stty -F /dev/ttyTHS2
speed 115200 baud; line = 0;
-brkint -imaxbel
stty -F /dev/ttyTHS2 230400
stty -F /dev/ttyTHS2
speed 230400 baud; line = 0;
-brkint -imaxbel
stty -F /dev/ttyTHS2 460800
stty -F /dev/ttyTHS2
speed 460800 baud; line = 0;
-brkint -imaxbel
stty -F /dev/ttyTHS2 921600
stty -F /dev/ttyTHS2
speed 921600 baud; line = 0;
-brkint -imaxbel
# There are probably faster settings which will work...
exit
The trouble with all of this is basically an extension to what the serial console programs do…many serial communications programs have a given set of values they believe can work, and reject others. Just because the port hardware can handle the rate it doesn’t mean general software will allow it. Generally it seems stty can set speeds gtkterm won’t allow. Just because a terminal program won’t succeed at a speed stty allows it doesn’t mean your custom program wouldn’t work at that speed (give it a try).
“setserial” is interesting because it may tell you something was accepted, but in reality hardware wasn’t really set…this is the case of a driver not necessarily telling you what the hardware is doing, it’s only telling you what the driver is trying to do. setserial talks only to a driver, whether the hardware listens to the driver is an unknown. Example of how hardware and software may not be aware of reality:
sudo -s
stty -F /dev/ttyUSB0 115200
setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 26
closing_wait: infinite
Flags: spd_cust low_latency
stty -F /dev/ttyUSB0 921600
setserial -a /dev/ttyUSB0
/dev/ttyUSB0, Line 0, UART: unknown, Port: 0x0000, IRQ: 0
Baud_base: 24000000, close_delay: 0, divisor: 26
closing_wait: infinite
Flags: spd_cust low_latency
setserial -G /dev/ttyUSB0
/dev/ttyUSB0 uart unknown port 0x0000 irq 0 baud_base 24000000 spd_cust low_latency
setserial -G /dev/ttyTHS2
/dev/ttyTHS2 uart undefined port 0x0000 irq 78 baud_base 0 spd_normal
exit
Notice how setserial sees no difference before and after stty has changed port speeds. Notice how setserial tries to find out which UART type is found, but does not know…this is one reason why serial port programs have problems…drivers do not always report what the hardware device is (that knowledge could be hard coded, or custom to specific hardware, but serial UART chips are not plug-n-play and can’t be queried).
You can type “setserial --help” and get some information. If it turns out one of those settings is possible by the hardware it should work for hardware setup…finding out if it really did work might mean testing your custom program code.