Performing surgery to fix Jetson Xavier NX --> DJI Type-C Development board UART communication

Hey everyone!

If you’re searching for a solution to this problem, you’re probably just as fed up and tired as I was the few nights before RMNA 2022. For you, there’s a TLDR at the bottom. For everyone else, read on.

The Goal:
Our goal was to communicate between our DJI Type-C Development board and our Jetson Xavier NX over the UART line (not through USB). This isn’t new to us, we used the Type-A board the previous year in a near-identical manner to pass our vision data from the same Xavier NXs to our Dev Board, and that worked flawlessly. We run at 115200 baud, and pass 14 bytes per message.

The only changes between the previous year and the current year were that we were now using the Type-C board instead of the Type-A board, and that our UART line was longer and passing through the slipring of our robots as well.

The Problem:
When we sent bytes over from our Xavier NX to our Type-C board, our receive task would report that it was receiving bytes, but these bytes seemed to always read high, reading as mostly 0xFF, and sometimes 0xFD, 0xEF, etc.

Interestingly, sometimes when we moved around the Dev-Board and the Xavier, we’d get brief periods of communication (with high packet loss), but it wasn’t reproducible and happened only very briefly.

The Clues:
During our testing process, we tried sending information from our Jetson to an Arduino, and to another Jetson. Both the Arduino and Jetson were able to perfectly decipher the messages sent by the first Jetson. We also tried sending messages from an Arduino to our Type-C board, and that worked flawlessly as well, with no misinterpreted bytes. We knew that both our Jetson and our Dev-Board were working fine in isolation, but why wouldn’t they work together?

After comparing the board schematics for both the Type-A and C, @kaelinl and I realized that the Type-C implementation of UART uses a 4.7kΩ pull-up resistor that the Type-A omits. Why? Only DJI knows. The STM32 chip used by the Type-C already has support for software-configurable pull-up/down on the UART TX and RX pins, meaning as far as we know, there isn’t really any use for a discrete pull-up resistor as featured on the Type-C.

Type-A No Pull-up

Additionally, @kaelinl noted that the Jetsons tend to have very weak current sources. Investigating the Jetson Nano Developer Kit 40-Pin Expansion Header GPIO Usage Considerations reveals that the level shifters used for the GPIO pins on Jetsons have output buffers with a series 4kΩ resistor (page 3). At 3.3V, this means that the maximum current that can be provided by the Jetson is 3.3V / 4kΩ = 0.825mA. The document also notes that values of external pull-up/down resistors should be greater than 50kΩ, and that using a resistor that is too small could lead to “unreliable operation” (page 4). With the 4.7kΩ pull-up resistor used by DJI, the pull-up current would be 3.3V / 4.7kΩ = 0.7mA.

It seems that the pull-up current is so close in magnitude to the output current of the Jetson’s pin that the Jetson has little authority over the logic level of the pin, which explains why any bytes we read from the board would always read high or close to high; the output level of the UART pin was nearly always pinned at 3.3V.

The Solution:
The problem is clear: there’s a resistor on the Type-C board that is messing with our communication. Our (crude) solution was to locate the resistor on the Type-C board and remove it. There are definitely better ways to resolve this problem, like using an external transistor/buffer on the pin to provide more current, but we didn’t have enough time to properly solve this problem before RMUL so :confused: this is what we went with.


Here it is ^

And this is where it used to be ^ (forgive me dji)

Here’s an tutorial video we made covering the removal process of the offending resistor:

The Result:
It works! Removing the resistor resulted brought our UART communications to exactly what we were expecting, and we were able to send and receive messages over UART at 1kHz, which was the fastest we tried. This is what we ran with at RMUL 2022, and while our vision pipeline had other issues, our Jetson - Dev-Board communication pipeline worked flawlessly.

Let us know if this post was helpful, and we’ll see y’all at RMUL 2023!

TLDR; There’s a resistor on the Type-C board that makes it hard for the Jetson to talk to it, remove the resistor and you should be golden. Here’s a tutorial video that we made for you.

1 Like