Is it possible to invert the UART's polarity in software?


I am trying to communicate over UART with another embedded device.
When sending the letter ‘a’ twice, this is what I get:

As you can see the binary ASCII value is inverted and sent in reverse order, ie (when ommiting the start and stop bit): 0111 1001 in stead of 0110 0001.

Besides this the start condition is a logical 1 instead of being a logical 0, like the other device would expect. Is there any way to work around this via software?

On a sidenote, I am pretty sure some competent people here will be able to give me some advice on this related beginner’s question: when doing $ls /dev/ I get a lot of devices but don’t know at all which one corresponds to which one of my uarts. Is there a way to know this instead of trying them all one after the other?


I suspect there is just a mismatched setting between the two devices. The basic settings are for speed (which you probably already have correct since this sort of works), bits (default is 8…maybe this is already correct since the first byte comes out ok), stop bits (this is probably wrong), and parity (odd or even or none…this too is probably correct but might look like the equivalent of wrong stop bits). The short abbreviation for speed 115200, 8 bits, no stop bits, 1 parity is:

115200 8N1

An interesting character is capital ‘O’ because it is bit pattern “0000 1111”. If you send ‘O’ four times in a row what do you get? Does it shift by 1 bit each time? Which direction does it shift?

UARTs themselves are not something you can query. When you use a program to find out what the UART is set to you are really asking what the driver is set to do. Whether or not the UART can actually achieve those settings is another story. So when researching I usually say to start in loopback mode because a UART will always agree with itself. Two UARTs talking to each other can have incorrect non-matching setup. An example would be that one side is expecting one stop bit, the other is expecting two stop bits…depending on direction of transmit there might be an extra bit or missing bit on the receiving side.

On any UART if you jumper the TX and RX pins you have loopback (you can’t use hardware flow control though…that’s another example where if one side requires flow control and the other doesn’t, then communications may work in one direction only). If you also jumper CTS and RTS pins, then you have loopback of hardware flow control as well. Having CTS/RTS jumpered in no way prevents normal communications when CTS/RTS is not enabled in software.

If a loopback port has a text terminal application connected for keyboard chat, then typing anything in will result in that same text being echoed back. I like gtkterm for this (e.g., to install “sudo apt-get install gtkterm”) since some older popular programs also complicate things by wanting to send modem init commands (e.g., minicom). If I have a UART in loopback then the following would test speed 115200 8N1 for the “/dev/ttyS1” port:

gtkterm -b 8 -t 1 -s 115200 -p /dev/ttyS1
# Or, optionally, the same device using the HS driver:
gtkterm -b 8 -t 1 -s 115200 -p /dev/ttyTHS1

If that works, then you know that particular port really does work at those settings. What settings does the device you talk to use? You will probably need to look closely at the documents for the device you are working with and determine what settings that device is supposed to use prior to knowing what to set to make it work. Loopback gtkterm can answer if the TK1 side is functioning correct at those settings.

About device naming: On Jetson platforms there are two possible drivers for the integrated UARTs. One is a standard driver such as what any basic hardware would use. When this driver is used the name will be something like “ttyS0” or “ttyS1”. There is a second driver which might also be used, this is for the “High Speed” (“HS”) driver. This driver differs because internally it uses DMA and might be able to achieve higher throughput with lower overhead. The naming convention would be something like “ttyTHS0” or “ttyTHS1”. Note that “ttyS0” and “ttyTHS0” are the same hardware, but different drivers. “ttyS1” and “ttyTHS1” are the same hardware, but different drivers. You should use only one driver at a time, don’t mix even though the devices exist.

Serial console is “ttyS0”. Most applications would have chosen “ttyTHS0”. However, U-Boot does not have the DMA-capable HS driver, and so if you want serial console to work from U-Boot through Linux without a stop to reset, then you have to stick to “ttyS0”. Which UART are you using? If “ttyS0” or “ttyTHS0”, then you are probably getting unexpected interactions with the serial console.

Any file in “/dev” is not normally a real file these days. Those are an interface directly to a driver generated by the driver itself. In cases where “mknod” is used to create such a file the file is blank and whatever interaction works is only after a driver attaches to the device. Mostly such files (pseudo files) will come to exist or go away depending on whether the driver is installed or removed. Possibly hardware might need to be detected during a driver install before the device will exist (hot plug USB devices are a great example…various “/dev/video#” will show up or go away dynamically depending on how many standard class USB cameras exist).

Mostly the naming of such devices is determined by the driver itself. Certain drivers have a standardized naming convention, either from tradition or because of a POSIX standard. There is an automated system known as “udev” which can be used to rename devices as well. An example might be that a particular serial UART from some custom device might rename itself after the manufacturer’s name.

NOTE: Speeds above 115200 will require two stop bits.