This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Configuring multiple UARTs on nRF5340DK (plus other serial interfaces)

I'm using the nRF5340 (currently nRF5340DK with custom hardware following shortly) and NCS 1.6.0. I'm working on a project that needs at least two UARTs and one SPI master interface, but I haven't been able to find an example to base this on and I can't seem to find the right combination of settings. It looks like there may also be considerations like shared resources between UART/SPI/TWI that must be configured correctly. I've also noticed the comment in v1.6.0/nrf/samples/CMakeLists.txt that says we can’t use UART1 because it’s used by the TF-M secure application. We can move debug logging from UART0 to RTT if needed to free up the UART0 resource. Is there an example that I've overlooked that clearly shows how to configure this? Or can someone explain what needs to be done? Configuring serial interfaces should be relatively straightforward but we just can't seem to get it right and I'm having a hard time tracking down what exactly is misconfigured.

If it matters, we may also need a separate configuration with one UART, one SPI master, and one TWI master. I'm hoping/assuming that will be straightforward once we see how to implement 2xUART and 1xSPI master but if there are any other tricky settings to know about if we need to replace one UART with a TWI master, I'd be interested in hearing about those settings.

Thanks.

Parents
  • Hello, Sydney!

    It's regrettable to hear about your experiences with our SDK. I definitely agree that the documentation and samples on using peripherals is lackluster and I can assure you that work is being done to improved this. That will likely take some time, however, so I will give you a brief overview of how you can enable and use peripherals in NCS:


    1. Enable the peripheral drivers in the project configuration. To ensure that the drivers for UART and SPI are enabled you can add the following KConfig options to the prj.conf:

    #Enable UART driver
    CONFIG_UART=y
    
    #Enable SPIM driver
    CONFIG_SPI=y
    CONFIG_NRX_SPIM0=y 

    Notes:
    - I'm using SPIM0 here, but you can of course enable any of the other SPIM instances. Make sure to account for that in the steps below as well. 

    2. Configure the hardware peripherals. This is done by using a device tree overlay for your given board. In your case you should add a file to your project called "nrf5340dk_nrf5340_cpuapp.overlay", which should contain some something like this:

    &spi0 {
      status = "okay";
      label = "SPI_0"; 
    };
    
    &uart0 {
        status = "disabled";
    };
    
    &uart1 {
        compatible = "nordic,nrf-uarte";
        status = "okay";
        label = "UART_1";
        current-speed = < 115200 >;
        tx-pin = < 14 >;
        rx-pin = < 16 >;
        rts-pin = < 13 >;
        cts-pin = < 15 >;
    };
    
    &uart2 {
        compatible = "nordic,nrf-uarte";
        status = "okay";
        label = "UART_1";
        current-speed = < 115200 >;
        tx-pin = < 9 >;
        rx-pin = < 10 >;
        rts-pin = < 11 >;
        cts-pin = < 12 >;
    };
    

    Notes:
    - The different configuration options for the peripherals can be found in the DTS Bindings documentation. In your case nordic,nrf-spi and nordic,nrf-uarte are the relevant bindings.
    - Notice that UART0 is explicitly disabled here to ensure that SPI0 can be used. The same method applies for other instances of hardware peripherals as well.
    - The configuration above uses arbitrary pins. You can choose pins on the DK freely as long as they are available. Information on this can be found in the nRF5340 DK documentation.

    3. Bind and use the peripherals in the application. This is done using the Devicetree API and the respective peripheral's driver. For your reference that's SPI and UART. The binding operation would look something like this:

    const struct device *spi_dev;
    const struct device *uart1_dev;
    const struct device *uart2_dev;
    int error;
    
    spi_dev = device_get_binding("SPI_0");
    if (!spi_dev) {
        printk("Binding failed.");
        return;
    }
    
    uart1_dev = device_get_binding("UART_1");
    if (!uart1_dev) {
        printk("Binding failed.");
        return;
    }
    
    uart2_dev = device_get_binding("UART_2");
    if (!uart2_dev) {
        printk("Binding failed.");
        return;
    }

    Notes: 
    - There are several examples demonstrating the binding process and usage of peripherals. I suggest having a look at our LPUART sample and some of the driver samples in Zephyr.

    I hope this gives you some clarity on how to enable and use peripherals in NCS. As you suggested yourself using RTT for logging will free up one of the UARTs to do this add the following options to the project configuration:

    # Config logger
    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=n


    Please reach out if you face any issues.

    Best regards,
    Carl Richard

Reply
  • Hello, Sydney!

    It's regrettable to hear about your experiences with our SDK. I definitely agree that the documentation and samples on using peripherals is lackluster and I can assure you that work is being done to improved this. That will likely take some time, however, so I will give you a brief overview of how you can enable and use peripherals in NCS:


    1. Enable the peripheral drivers in the project configuration. To ensure that the drivers for UART and SPI are enabled you can add the following KConfig options to the prj.conf:

    #Enable UART driver
    CONFIG_UART=y
    
    #Enable SPIM driver
    CONFIG_SPI=y
    CONFIG_NRX_SPIM0=y 

    Notes:
    - I'm using SPIM0 here, but you can of course enable any of the other SPIM instances. Make sure to account for that in the steps below as well. 

    2. Configure the hardware peripherals. This is done by using a device tree overlay for your given board. In your case you should add a file to your project called "nrf5340dk_nrf5340_cpuapp.overlay", which should contain some something like this:

    &spi0 {
      status = "okay";
      label = "SPI_0"; 
    };
    
    &uart0 {
        status = "disabled";
    };
    
    &uart1 {
        compatible = "nordic,nrf-uarte";
        status = "okay";
        label = "UART_1";
        current-speed = < 115200 >;
        tx-pin = < 14 >;
        rx-pin = < 16 >;
        rts-pin = < 13 >;
        cts-pin = < 15 >;
    };
    
    &uart2 {
        compatible = "nordic,nrf-uarte";
        status = "okay";
        label = "UART_1";
        current-speed = < 115200 >;
        tx-pin = < 9 >;
        rx-pin = < 10 >;
        rts-pin = < 11 >;
        cts-pin = < 12 >;
    };
    

    Notes:
    - The different configuration options for the peripherals can be found in the DTS Bindings documentation. In your case nordic,nrf-spi and nordic,nrf-uarte are the relevant bindings.
    - Notice that UART0 is explicitly disabled here to ensure that SPI0 can be used. The same method applies for other instances of hardware peripherals as well.
    - The configuration above uses arbitrary pins. You can choose pins on the DK freely as long as they are available. Information on this can be found in the nRF5340 DK documentation.

    3. Bind and use the peripherals in the application. This is done using the Devicetree API and the respective peripheral's driver. For your reference that's SPI and UART. The binding operation would look something like this:

    const struct device *spi_dev;
    const struct device *uart1_dev;
    const struct device *uart2_dev;
    int error;
    
    spi_dev = device_get_binding("SPI_0");
    if (!spi_dev) {
        printk("Binding failed.");
        return;
    }
    
    uart1_dev = device_get_binding("UART_1");
    if (!uart1_dev) {
        printk("Binding failed.");
        return;
    }
    
    uart2_dev = device_get_binding("UART_2");
    if (!uart2_dev) {
        printk("Binding failed.");
        return;
    }

    Notes: 
    - There are several examples demonstrating the binding process and usage of peripherals. I suggest having a look at our LPUART sample and some of the driver samples in Zephyr.

    I hope this gives you some clarity on how to enable and use peripherals in NCS. As you suggested yourself using RTT for logging will free up one of the UARTs to do this add the following options to the project configuration:

    # Config logger
    CONFIG_LOG=y
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_LOG_BACKEND_UART=n


    Please reach out if you face any issues.

    Best regards,
    Carl Richard

Children
No Data
Related