High Baud Rate UART Configuration

Hello,

I am attempting to run /dev/ttyTHS2 at 8 Mbit/s, in order to stream data from a microcontroller to the Jetson TX2. I’m using Ubuntu 16.04 LTS, Python 3.5, and PySerial on the TX2. I have configured the UART on the MCU and TX2 to use two stop bits. I have found that communication works well for small transfers at 4 Mbit/s. However, when I try to use a baud rate of 8 Mbit/s, the TX2 UART transmits at the wrong baud rate – using an oscilloscope, I can see that the true baud rate used by the TX2’s UART is as high as 8.8%. When trying to use a baud rate of 12.5 MB/s on the TX2, I found an even higher baud rate error of ~16%.

Presumably the issue is that a clock frequency is being used for which there is no integer divisor that produces the desired baud rate. Unfortunately the API I am using (PySerial) doesn’t give me much visibility into how the UART is actually being configured…

Can anyone recommend either

  • A serial API in Python, C or C++ which is known to work with baud rates over 4 Mbit/s on the TX2, or
  • Some other way of modifying -- or even just viewing -- UART register configuration, without having to write my own serial driver

Thanks!

hello oliver30sgx,

according to TX2 TRM, the maximum baud rate is 12.5Mbps.
please also access Tegra X2 (Parker Series SoC) Technical Reference Manual, and check the [UNIVERSAL ASYNCHRONOUS RECEIVER/TRANSMITTER (UART)] chapter.

please also refer to Jetson TX2 Series Software Features for the uart speeds.

you could also refer to UART registers in the Technical Reference Manual
thanks

Hi JerryChang,

Thanks for your reply, but I think you misunderstood my post. I have looked at the UART chapter in the TRM and I’m aware that 12.5 Mbps is the maximum UART speed. I am trying to configure the UART for 8 Mbps, but this has not worked because of incorrect clock configuration.

The question is: is there any existing software which will correctly configure the UART for such speeds? Or do I need to modify / rewrite the tegra serial driver in order to use the UART at this speed?

I don’t know about that particular speed, but also know that once you achieve that speed you’ll need two stop bits (one stop a bit past 115200 becomes unreliable, and much above 115200 one stop bit will fail).

Hi linuxdev,

Thanks for your reply. Like I said, I have configured the UART to use two stop bits.

For what it’s worth, I found that one stop bit worked quite reliably at 1 Mbit/s. Once I increased the baud rate to 2 Mbit/s, the second stop bit did become necessary.

Dear Nvidia,

My company is developing a product which uses your Jetson TX2. Our current design requires that UARTC functions at 8 Mbit/s or higher. We are having trouble configuring the UART to work properly at this speed. We require your support.

The problem we are having is an incorrect baud rate. You can see the result of trying to configure the UART for 8 Mbit/s in this psuedo eye diagram: https://ibb.co/WB1Zskc. The actual baud rate which the UART achieves is ~7.3 Mbit/s.

The UART is being configured in python as follows:

import serial
s = serial.Serial('/dev/ttyTHS2', 8000000, stopbits=serial.STOPBITS_TWO)

Presumably Nvidia has tested the UARTs on the TX2 at baud rates above 4 Mbit/s. Can you tell me what software was used to do that? Are configuration changes required in order for the UART to work properly at 8 Mbit/s? Do I need to use a different API than PySerial?

Hi,

Linux kernel has limit till 4Mbps as maximum baud rate defined is 4Mbps
#define B4000000 0010017
./include/uapi/asm-generic/termbits.h
Question:

  1. Any changes you have done in kernel side to achieve 8/12.5Mbps
  2. Can you share the clock tree dump “cat /sys/kernel/debug/bpmp/debug/clk/clk_tree”

thanks
Bibek

It seems if you provide, BOTHER flag in your application you can achieve higher rates.
We will set this up on jetson and provide results early next week.
We suspect, parent clock needs to be changes to attain 8Mbit/s

Hi bbasu,

Thanks for your reply.

  1. We haven’t made any changes to the kernel to achieve higher baud rates.
  2. I have attached the output of clk_tree both before and after I have tried configuring UARTC (using the python code in my previous post).

UARTC clock rate as reported clk_tree is:

// clk_tree output *BEFORE* configuring /dev/ttyTHS2
pllp_aon			enabled: 1	refcounts: 5,0,	rate: 408000000
	uartc			enabled: 1	refcounts: 0,1,	rate: 16000000

// clk_tree output *AFTER* trying to configure /dev/ttyTHS2 for 8 Mbit/s
pllp_aon			enabled: 1	refcounts: 5,0,	rate: 408000000
	uartc			enabled: 1	refcounts: 0,1,	rate: 116571429

I appreciate you looking into this, thanks.

Hi oliver,
Can you please change try to change parent clk of uartc:
Please try below change in kernel dt:
diff:
uartc: serial@c280000 {
dmas = <&gpcdma 3>, <&gpcdma 3>;
dma-names = “rx”, “tx”;
clocks = <&tegra_car TEGRA186_CLK_UARTC>,

  •   <&tegra_car TEGRA186_CLK_PLLP_OUT0>;          // remove this line
    
  •  <[b]&tegra_car TEGRA186_CLK_PLLC4_OUT2>[/b];   // add this line
    

clock-names = “serial”, “parent”;
resets = <&tegra_car TEGRA186_RESET_UARTC>;
}

Let us know if this works.

Thanks,
Shubhi

Hi Shubhi,

Thanks for your reply. Can you tell me what the hex value of TEGRA186_CLK_PLLC4_OUT2 is, and where to find such information for future reference? When I decompile the .dtb file using ‘dtc -I fs -O dts -o extracted.dts /proc/device-tree’, I found that most of the properties are hex values instead of enumerations:

serial@c280000 {
		reg = <0x0 0xc280000 0x0 0x40>;
		dmas = <0x19 0x3 0x19 0x3>;
		interrupts = <0x0 0x72 0x4>;
		reg-shift = <0x2>;
		compatible = "nvidia,tegra186-hsuart";
		clock-names = "serial", "parent";
		reset-names = "serial";
		nvidia,adjust-baud-rates = <0x1c200 0x1c200 0x64>;
		clocks = <0xd 0xd7 0xd 0x10d>;
		resets = <0xd 0x31>;
		nvidia,memory-clients = <0xe>;
		status = "okay";
		phandle = <0x75>;
		#stream-id-cells = <0x1>;
		dma-names = "rx", "tx";
		linux,phandle = <0x75>;
	};

Hi,

It is defined in kernel source code header file:
…/dt-bindings/clock/tegra186-clock.h
#define TEGRA186_CLK_PLLC4_OUT2 278
So hex value is 116

Please try changing clocks :
clocks = <0xd 0xd7 0xd 0x116>;

Thanks,
Shubhi

Hello Shubhi,

I was able to modify the device tree. I used ‘xxd /proc/device-tree/serial@c280000/clocks’ to verify the settings of ‘<0xd 0xd7 0xd 0x116>’ which you recommended.

After doing this, the baud rate error is worse. When I try to configure the UART for 8 Mbit/s, in the same way described above, the bit period is 26 microseconds, rather than the expected 125 nanoseconds. From looking at clk_tree I can see that the UART clock rate is

// clk_tree output *BEFORE* configuring /dev/ttyTHS2
aon_apb     enabled: 1  refcounts: 3,0, rate: 38400000
  uartc   enabled: 1  refcounts: 0,1, rate: 153600

// clk_tree output *AFTER* trying to configure /dev/ttyTHS2 for 8 Mbit/s
aon_apb     enabled: 1  refcounts: 3,0, rate: 38400000
  uartc   enabled: 1  refcounts: 0,1, rate: 614400

Thanks

Hello oliver30sgx,

Based on your earlier comment of achieving ~7.3 Mbits/S on UARTC (J17) when setting to 8Mbits/s.
Yes its correct. TX2 uartc hardware limits this based on supported tolerance range, clock parent and divisor.

PLLC4_MUXED clock can be used to achieve exactly 8Mbits/s. But UARTC has no support of this clock source.

To achieve exactly 8Mbits/s baud rate on TX2, you need to change to another uart port which has PLLC4_MUXED as possible clock source and set the clock source accordingly.

Thanks & Regards,
Sandipan

Hi Sandipan,

Thanks for your reply; I understand the problem now. We may try to use a different UART in the future if we are not able to get other solutions working, but for now I think switching to Ethernet or USB is going to be a better path for us.

Thanks,
Oliver