Getting from GPIO1 in device tree for NRFX based code in 2.4.1

Hello,

I am updating code from 2.0.0 to 2.4.1 and see that there are large changes to the gpio interface on the zephyr side and most and the DT_GPIO macros seem to all be deprecated and I can no longer get the node label for gpio as before, DT_GPIO_LABEL.  I see in the NRFX code example in git that you are still using DT_GPIO_PIN macro and this works fine if the pin is on gpio0.  My issue is I have several devices that need to get the offset for gpio1 and i used to compare the label using DT_GPIO_LABEL which no longer works.  Any help would be appreciated as the current device tree based gpio drivers reference the device and nrfx code uses the absolute address.  Also if there is a better way to continue to use the PPI and DPPI that would be informative as well.

#define CLACKER_NODE              DT_ALIAS(spoon)
#define CLACKER_DT_LABEL          DT_GPIO_LABEL(CLACKER_NODE, gpios)    <- this macro is now broken
#define CLACKER_DT_PIN            DT_GPIO_PIN(CLACKER_NODE, gpios)
Thanks,
Ed
  • Hello Edward,

    Thank you for contacting DevZone at NordicSemi.

    As per the Zephyr 3.4.99 Devicetree API, section for the GPIO (zephr DT API)

    DT_GPIO_LABEL_BY_IDX(node_idgpio_phaidx) gets a label property from GPIO Phandle by given index

    However, this is deprecated. The recommended macro is:

    DEVICE_DT_GET(DT_GPIO_CTLR_BY_IDX(node, gpio_pha, idx))

    Example: given below devicetree fragment:

    gpio1: gpio@... {
            label = "GPIO_1";
    };
    
    gpio2: gpio@... {
            label = "GPIO_2";
    };
    
    n: node {
            gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
                    <&gpio2 30 GPIO_ACTIVE_HIGH>;
    };

    The use of macro will be:

    DT_GPIO_LABEL_BY_IDX(DT_NODELABEL(n), gpios, 1)

    that would provide the label of gpio2, that is "GPIO_2"

    BR,

    Naeem

  • Naeem

    That also seems to be deprecated as labels seem to be getting eliminated. This is the current device tree base.

    gpio0: gpio@50000000 {
                compatible = "nordic,nrf-gpio";
                gpio-controller;
                reg = <0x50000000 0x200
                       0x50000500 0x300>;
                #gpio-cells = <2>;
                status = "disabled";
                port = <0>;
            };

            gpio1: gpio@50000300 {
                compatible = "nordic,nrf-gpio";
                gpio-controller;
                reg = <0x50000300 0x200
                       0x50000800 0x300>;
                #gpio-cells = <2>;
                ngpios = <10>;
                status = "disabled";
                port = <1>;
            };
  • Hello Edward,

    You can use DT_PROP or DT_PROP_BY_IDX macro as well as per your needs.

    Below is sample snippet from Zephyr documents

  • so use dt prop to get the port from gpio.  That makes sense.  In the mean time i made a function that compared the address of the gpio device which should be relatively future proof given how often zephyr changes device tree stuff.

    uint32_t drv_common_get_gpio_dt(struct gpio_dt_spec * spec)
    {
        uint32_t val = 0;
        // int result;

        const struct device * gpio0port = device_get_binding("GPIO_0");
        val = spec->pin;

        if(gpio0port != spec->port )
        {
            val += 32;
        }

        return val;
    }
  • Just for anyone else who needs this i came up with this macro

    #define GPIO_NODE_NRFX_PIN(node_id) \
            ((DT_PROP_BY_PHANDLE(node_id, gpios, port)*32) + DT_GPIO_PIN(node_id,gpios))
Related