This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

nRF9160 DK - UART big picture

Dear Nordic-Support Team,

Introduction

I have read through some sources (tickets and documentation) but I am still struggling to see the big picture of UART configuration in context of the nRF9160 DK. I noticed that even the terminology changes across different sources.

For example: in the tickets https://devzone.nordicsemi.com/f/nordic-q-a/47652/nrf9160-dk-uart-configuration and https://devzone.nordicsemi.com/f/nordic-q-a/68810/how-to-configue-an-external-uart-from-nrf9160-dk UART0 and UART1 are mentioned as primary and secondary UARTs which are forwarded through the virtual comports VCOM0 and VCOM2 respectively. However, Nordic's documentation (https://infocenter.nordicsemi.com/index.jsp?topic=%2Fug_nrf91_dk%2FUG%2Fnrf91_DK%2Fboard_controller.html&anchor=board_controller and https://infocenter.nordicsemi.com/index.jsp?topic=%2Fug_nrf91_dk%2FUG%2Fnrf91_DK%2Fhw_switches_uart_if.html) states, that UART1 and UART2 are forwarded though the virtual comports VCOM0 and VCOM2.

Thus, it would be great if you could help me to understand the big picture about how the different UARTs are set up per default and how they can be configured.

Device tree files

Because of the different terminology in the sources I have read, I had a look at the device tree files of the nRF9160, the nRF52840, and the nRF9160 DK in the Nordic Connect SDK.

The device tree file of the nRF9160 suggests that the nRF9160 chip has four UART interfaces. Is that correct? To get the terminology straight, I will call them UART_9160_[0,1,2,3] in the following.

# ncs\v1.9.1\zephyr\dts\arm\nordic\nrf9160_common.dtsi

# [...]

uart0: uart@8000 {
	compatible = "nordic,nrf-uarte";
	reg = <0x8000 0x1000>;
	interrupts = <8 NRF_DEFAULT_IRQ_PRIORITY>;
	status = "disabled";
	label = "UART_0";
};

uart1: uart@9000 {
	compatible = "nordic,nrf-uarte";
	reg = <0x9000 0x1000>;
	interrupts = <9 NRF_DEFAULT_IRQ_PRIORITY>;
	status = "disabled";
	label = "UART_1";
};

uart2: uart@a000 {
	compatible = "nordic,nrf-uarte";
	reg = <0xa000 0x1000>;
	interrupts = <10 NRF_DEFAULT_IRQ_PRIORITY>;
	status = "disabled";
	label = "UART_2";
};

uart3: uart@b000 {
	compatible = "nordic,nrf-uarte";
	reg = <0xb000 0x1000>;
	interrupts = <11 NRF_DEFAULT_IRQ_PRIORITY>;
	status = "disabled";
	label = "UART_3";
};

# [...]

The device tree file of the nRF52840 suggests that the nRF52840 chip has two UART interfaces. Is that correct? To get the terminology straight, I will call them UART_52840_[0,1] in the following.

# ncs\v1.9.1\zephyr\dts\arm\nordic\nrf52840.dtsi

# [...]

uart0: uart@40002000 {
	/* uart can be either UART or UARTE, for the user to pick */
	/* compatible = "nordic,nrf-uarte" or "nordic,nrf-uart"; */
	compatible = "nordic,nrf-uarte";
	reg = <0x40002000 0x1000>;
	interrupts = <2 NRF_DEFAULT_IRQ_PRIORITY>;
	status = "disabled";
	label = "UART_0";
};

# [...]

uart1: uart@40028000 {
	compatible = "nordic,nrf-uarte";
	reg = <0x40028000 0x1000>;
	interrupts = <40 NRF_DEFAULT_IRQ_PRIORITY>;
	status = "disabled";
	label = "UART_1";
};

# [...]

The device tree file of the nRF9160 DK suggests that the nRF9160 DK exposes three UART interfaces to the user via the board's pins and/or via the virtual comports of the J-Link debug probe. Is that correct? To get the terminology straight, I will call them UART_DK_[0,1,2] in the following.

# ncs\v1.9.1\zephyr\boards\arm\nrf9160dk_nrf9160\nrf9160dk_nrf9160_common.dts

# [...]

&uart0 {
	status = "okay";
	current-speed = <115200>;
	tx-pin = <29>;
	rx-pin = <28>;
	rx-pull-up;
	rts-pin = <27>;
	cts-pin = <26>;
	cts-pull-up;
};

arduino_serial: &uart1 {
	status = "okay";
	current-speed = <115200>;
	tx-pin = <1>;
	rx-pin = <0>;
	rx-pull-up;
	rts-pin = <14>;
	cts-pin = <15>;
	cts-pull-up;
};

&uart2 {
	tx-pin = <24>;
	rx-pin = <23>;
};

# [...]

General Questions

Assuming my assumptions about the device tree files are correct. Can you please answer the following questions?

  1. How do the different UART entities UART_9160_[0,1,2,3], UART_52840_[0,1], and UART_DK_[0,1,2] relate to each other?
  2. Why does the nRF9160 DK only expose three UART entities while the nRF9160 has four?
  3. How can I configure which UART entity is exposed through which pins of the nRF9160 DK
  4. Which UART entities are forwarded per default through the virtual comports?
  5. How can I configure which UART entities are forwarded through the virtual comports?
  6. How can I stop an UART entity from being forwarded  through the virtual comports?
  7. Assuming that UART_DK_0 is the "primary" UART used for console and AT data traffic, would it mess with the nRF9160 DK if UART_DK_0 would additionally be used to communicate to other external devices?

Use case specific questions

I would like to use the UARTs of the nRF9160 DK in the following way:

  1. Attach sensors which communicate, with a certain serial protocol, to one UART via the pins of the nRF9160 DK. This UART should not be exposed via the virtual comports
  2. Attach a second class of sensors, which communicate with another serial protocol, to a second UART via the pins of the nRF9160 DK. This UART should not be exposed via the virtual comports
  3. Communicate (e. g. send commands to my user application on the nrf9160 from a PC) with the nRF9160 DK over a third UART which is only exposed via a virtual comport but not via the pins of the nRF9160 DK

Can you please provide some configuration suggestions for e. g. an overlay-file and/or prj.conf-file-settings for that use case of mine and mention caveats if there are any?

Final remarks

I am aware that answering this ticket might take some effort but I really like to get this topic straight. Thus, thank you allot for your help!

  • Hi,

    How do the different UART entities UART_9160_[0,1,2,3], UART_52840_[0,1], and UART_DK_[0,1,2] relate to each other?

     As you say, the nRF9160 can have 4 UARTs (UART_NRF9160_[0,1,2,3]), while the nRF52840 can have 2 UARTs (UART_NRF52840_[0,1]). We use the same HW peripheral for all serial busses: UART, SPI and I2C. The peripheral can only be one of those at a time. So, depending on your configuration, you might not have 4 UARTs available, but e.g. 2 UARTs, 1 I2C and 1 SPI. For simplicity going forward, let's assume we always have the maximum possible amount of UARTs, unless explicitly stated otherwise.

    Which pins are assigned to which peripheral is configurable at runtime. In NCS and Zephyr, that configuration is done by the device tree files. So the pins you see in the SoC .dts files are simply the "default" pins used by the SDK, but they can be changed by boards and applications.

    When you look at ncs\v1.9.1\zephyr\boards\arm\nrf9160dk_nrf9160\nrf9160dk_nrf9160_common.dts, you see the configuration of the nRF9160 on the nRF9160 DK. Note that in the SoC board files, all the UARTs are disabled. In the DK board files, two of them are enabled, and the pins of the third are modified.

    In other words, UART_DK_[0,1,2] = UART_NRF9160_[0,1,2]. UART_NRF9160_3 are not mentioned in the DK board files. I.e. it uses the same pins as in the SoC files, and is still disabled.

    Again, I want to repeat that the both the board and SoC configurations can be overwritten by the application.

    The story for the nRF52840 is similar. In the SoC device tree files both UARTs are disabled, while in the board files (zephyr/boards/arm/nrf9160dk_nrf52840.dts) UART_NRF52840_0 is enabled, and the pinout is changed.

    In either case, these .dts files only tell you which UARTs has been routed to which pins of the SoCs. Not where those pins are routed on the actual DK.

    Why does the nRF9160 DK only expose three UART entities while the nRF9160 has four?

    If you are talking about UART_DK_[0,1,2], that is not the correct interpretation. See above.

    However, you are correct that the nRF9160 DK only converts 3 UARTs to virtual serial ports that you can see on your computer. This is because the on-board debugger only can convert  3 UARTs to USB veirtula serial ports (VCOMs). Of these three UARTs, two are used by the nRF9160 (UART_NRF9160_0 and UART_NRF9160_1 by default), and one by the nRF52840 (UART_NRF52840_0 by default).

    How can I configure which UART entity is exposed through which pins of the nRF9160 DK

    To better understand how to use the device tree, I recommend you our nRF Connect SDK Fundamentals course on our Nordic Developer Academy: https://academy.nordicsemi.com/courses/nrf-connect-sdk-fundamentals/

    Which UART entities are forwarded per default through the virtual comports?

    See my answer above, as well as the schematics and documentation for the DK.

    How can I configure which UART entities are forwarded through the virtual comports?

    As previously mentioned, you can change the pinout so that the UART entity you want use the pins connected to the on-board debugger.

    How can I stop an UART entity from being forwarded  through the virtual comports?

    You can either not use the pins connected to the on-board debugger, or you can change the routing on the DK so those pins are routed to the pin headers instead. For more information, see the board controller FW documentation: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/zephyr/boards/arm/nrf9160dk_nrf52840/doc/index.html#board-controller-firmware

    Assuming that UART_DK_0 is the "primary" UART used for console and AT data traffic, would it mess with the nRF9160 DK if UART_DK_0 would additionally be used to communicate to other external devices?

    UART is only designed to be used between two nodes. Adding a third device is not really supported. However, you can use other UARTs for console and/or AT commands, or you can not use the console/AT commands at all.

    I would like to use the UARTs of the nRF9160 DK in the following way:

    This should be easily enough with a device tree overlay file. I recommend staying with UART_NRF9160_0 for communicating over a VCOM, as well as having UART_NRF9160_1 for modem tracing. Modem traces are really an invaluable tool for debugging network and connection issues.

    The two UARTs for sensor communication can be UART_NRF9160_[2,3]. Just remember to disable I2C 2 and 3 and SPI 2 and 3.

    All that, as well as choosing which pins are used can be done in a device tree overlay file. As for which pins to use, you should look at the DK schematics.

    Best regards,

    Didrik

  • Hi Didrik,

    thank you allot for you comprehensive answer. It clarified allot of things. I'll make sure to have a look at the course you suggested.

    We use the same HW peripheral for all serial busses: UART, SPI and I2C. The peripheral can only be one of those at a time.

    If I interpret your statement and the device tree files correct, I have four and only four HW peripherals at my disposal when working with the nRF9160 DK. That means for example if I would use three of them as UARTs and one of them as SPI interface, I would be in trouble if I would need an additional I2C interface. Is that correct?

  • Correct. The nRF9160 only has 4 serial peripherals.

    However, it is possible to re-configure them at runtime. So, e.g. assuming you don't need the SPI and the I2C at the same time, you can use the same peripheral for both (with different pins, or some switching mechanism).

  • Hi Didrik,

    thank you for your Reply.

    However, it is possible to re-configure them at runtime.

    That sounds like a good solution to me. Can you please provide a link to the documentation of this feature or tell me in which header the corresponding functions are declared?

    Thank you!

Related