Device tree : how to get uart characteristics from DTS?

I'm struggling with SDKConnect and the device tree stuff... and finding it hard to get good examples or docs TBH

So, I have the sample dts files for the nRF5340DK, which defines the config for the 'uart0' node:

&uart0 {
    status = "okay";
    current-speed = <115200>;
    pinctrl-0 = <&uart0_default>;
    pinctrl-1 = <&uart0_sleep>;
    pinctrl-names = "default", "sleep";
};
and the pinctrl mappings:
uart0_default: uart0_default {
        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 20)>,
                <NRF_PSEL(UART_RTS, 0, 19)>;
        };
        group2 {
            psels = <NRF_PSEL(UART_RX, 0, 22)>,
                <NRF_PSEL(UART_CTS, 0, 21)>;
            bias-pull-up;
        };
    };

    uart0_sleep: uart0_sleep {
        group1 {
            psels = <NRF_PSEL(UART_TX, 0, 20)>,
                <NRF_PSEL(UART_RX, 0, 22)>,
                <NRF_PSEL(UART_RTS, 0, 19)>,
                <NRF_PSEL(UART_CTS, 0, 21)>;
            low-power-enable;
        };
    };
aliases {
    console = &uart0;
}
Given this, how to I get the port/pins for my console in my C code? and switch between 'default' and 'sleep' cases easily - given they are in 2 groups for one case and 1 group for the other?
I want to use the nrfx uarte driver, not the zephyr driver, so getting the struct device (via get_device_info()) doesn't help?
I was hoping to be able to do something like:
uint8_t rxd_pin = NRFX_PSEL_UART_RX_PORT(DT_PROP(DT_PROP(DT_ALIAS(console), group1)),psel) << 4 | NRFX_PSEL_UART_RX_PIN(DT_PROP(DT_PROP(DT_ALIAS(console), group1)),
(since I saw similar code to get the pins for an I2C node... NRFX_PSEL_SDA_PORT/PIN macros)
but no such macro seems to exist for uart? I can get the 'current-speed' property ok...
Any pointers on using the pinctrl macros to get NRF_PSEL components? I will confess to being a newbie on the whole device tree config stuff...
Maybe I'm looking in the wrong place - but honestly there are SO many files to keep in mind for the dts stuff....
thanks!
  • Hi BrianW,

    I empathize with your difficulties in getting starts with Devicetree. We do offer an online course to help with the early stages, but what you are trying to do is unfortunately more advanced than what the course covers.

    You will first want to look into the concept of phandle, then you can find the pin control API here: https://docs.nordicsemi.com/bundle/ncs-2.6.1/page/zephyr/build/dts/api/api.html#pinctrl-pin-control.

    Devicetree API is makes it more straightforward when using the Zephyr API to access peripheral. As you want to use nrfx drives, it becomes a little more complex.
    The benefit of using the API above is that your hardware description is still concentrated in the Devicetree, allowing the project to support multiple hardware with just the Devicetree board files change. You can just disable the nodes in Devicetree, and use pin number directly in code, at the cost of this benefit.

    Hieu

  • Devicetree API is makes it more straightforward when using the Zephyr API to access peripheral. As you want to use nrfx drives, it becomes a little more complex.

    Yes, it does. And I was kind of hoping for a reply with more specific help about how to do it, the documentation is VERY basic.

    Specific questions then:

    I want to get the uart config to populate an nrfx uarte config structure, 

    nrfx_uarte_config_t uarte_comm_params;
    Specifically .rxd_pin, .txd_pin, .rts_pin, .cts_pin, .baudrate, .config.parity,, .config.paritytype, .config.stop.
    I use an alias 'console' to reference the uart: 
    / {
        aliases {
            console = &uart0;
    };
    and then uart0 and its pinctrl as as previously.
    My C code wants to do:
    init_uart("console");
    but I'll accept 
    init_uart(DT_PATH(DT_ALIAS(console)))
    to get the string path that I can then use to find the node...
    Q1 : how to go from a runtime string "console" to a DT node to be able look up properties? Are there callable methods that do the same jobs as the macros to interrogate the DTS at runtime?
    Q2 : how to get the pinctrl property for the specific pin use? (eg the pin for rxd in 'default' pinctrl?)
    Q3 : how to get the gpio pin reference for the txd, rxd etc pins from the pinctrl (given the use of the PSEL() macro to merge pin use, port, gpio into a single 32 bit value)? Where are the macros to unpack NRF_PSEL?
    A code sample would be very helpful.
    thanks
  • by the way, I tried doing

    char* nodepath = DT_PATH(DT_ALIAS(console));

    and this fails to compile:

    C:/work/dev/nordic_connect/zephyr/include/zephyr/devicetree.h:90:17: error: 'DT_N_S_DT_N_S_soc_S_peripheral_40000000_S_uart_8000' undeclared (first use in this function); did you mean 'DT_N_S_soc_S_peripheral_40000000_S_uart_8000_ORD'?

    The duplicated "DT_N_S_" part makes me think that the DT_PATH and DT_ALIAS macros don't play well together, despite what I understand the parameter to DT_PATH to be? (a node id).

    any pointers on this?

Related