Unable to get GPIO controller handle from gpio node using DT_GPIO_CTLR


Jason Bens <jason.bens@...>
 

Hi,

 

I’m sure this is a very stupid question, but I haven’t been able to get to get this working.  I’ve got the following device tree fragment:

 

     gpio0: gpio@842500 {

           compatible = "nordic,nrf-gpio";

           gpio-controller;

           reg = < 0x842500 0x300 >;

           #gpio-cells = < 0x2 >;

           label = "GPIO_0";

           status = "okay";

           port = < 0x0 >;

          phandle = < 0x2 >;

     };

 

(and elsewhere…)

 

     buttons {

           compatible = "gpio-keys";

           button_sel_role: button_1 {

                gpios = < &gpio0 0x2 0x11 >;

                label = "Push button 1";

           };

     };

 

Button_sel_role is on different GPIO controllers on some of the devices I’m developing on.  I’d like to get the GPIO controller handle, and figured I could do it with something like the following:

     static const struct device *gpio_dev = DT_GPIO_CTLR(DT_NODELABEL(button_sel_role), gpios);

 

Unfortunately, this gives me a long chain of macro expansions, eventually terminating in

<build_dir>/zephyr/include/generated/devicetree_unfixed.h:656:52: error: 'DT_N_S_soc_S_peripheral_50000000_S_gpio_842500' undeclared (first use in this function); did you mean 'DT_N_S_soc_S_peripheral_50000000_S_gpio_842500_ORD'?

[build]   656 | #define DT_N_S_buttons_S_button_1_P_gpios_IDX_0_PH DT_N_S_soc_S_peripheral_50000000_S_gpio_842500

 

Using DT_PROP, I can access the label, so I don’t think the expansion of DT_NODELABEL is wrong.  I’m not really sure how to continue troubleshooting this.  Any advice?

 

Thanks,

 

  • Jason


Jason Bens <jason.bens@...>
 

Solved, and yes, it was a stupid question.  Given a closer read of the DT_GPIO_CTLR documentation, I noticed that it returns a node identifier, and not, as I expected a device handle.  The correct statement:

static const struct device *gpio_dev = DEVICE_DT_GET(DT_GPIO_CTLR(DT_NODELABEL(button_sel_role), gpios));

 

Thank you for everyone’s help,

 

  • Jason

 

From: users@... <users@...> On Behalf Of Jason Bens
Sent: March 16, 2022 7:27 PM
To: users@...
Subject: [Zephyr-users] Unable to get GPIO controller handle from gpio node using DT_GPIO_CTLR

 

External Email:

Hi,

 

I’m sure this is a very stupid question, but I haven’t been able to get to get this working.  I’ve got the following device tree fragment:

 

     gpio0: gpio@842500 {

           compatible = "nordic,nrf-gpio";

           gpio-controller;

           reg = < 0x842500 0x300 >;

           #gpio-cells = < 0x2 >;

           label = "GPIO_0";

           status = "okay";

           port = < 0x0 >;

          phandle = < 0x2 >;

     };

 

(and elsewhere…)

 

     buttons {

           compatible = "gpio-keys";

           button_sel_role: button_1 {

                gpios = < &gpio0 0x2 0x11 >;

                label = "Push button 1";

           };

     };

 

Button_sel_role is on different GPIO controllers on some of the devices I’m developing on.  I’d like to get the GPIO controller handle, and figured I could do it with something like the following:

     static const struct device *gpio_dev = DT_GPIO_CTLR(DT_NODELABEL(button_sel_role), gpios);

 

Unfortunately, this gives me a long chain of macro expansions, eventually terminating in

<build_dir>/zephyr/include/generated/devicetree_unfixed.h:656:52: error: 'DT_N_S_soc_S_peripheral_50000000_S_gpio_842500' undeclared (first use in this function); did you mean 'DT_N_S_soc_S_peripheral_50000000_S_gpio_842500_ORD'?

[build]   656 | #define DT_N_S_buttons_S_button_1_P_gpios_IDX_0_PH DT_N_S_soc_S_peripheral_50000000_S_gpio_842500

 

Using DT_PROP, I can access the label, so I don’t think the expansion of DT_NODELABEL is wrong.  I’m not really sure how to continue troubleshooting this.  Any advice?

 

Thanks,

 

  • Jason


Bolivar, Marti
 

Hi Jason,

On Wed, Mar 16 2022, Jason Bens via lists zephyrproject org wrote:
I'd like to get the GPIO controller handle, and figured I could do it with something like the following:
static const struct device *gpio_dev =
DT_GPIO_CTLR(DT_NODELABEL(button_sel_role), gpios);
DT_GPIO_CTLR returns a node identifier:

https://docs.zephyrproject.org/latest/reference/devicetree/api.html#c.DT_GPIO_CTLR

And node identifiers are not values:

https://docs.zephyrproject.org/latest/guides/dts/api-usage.html#node-identifiers-are-not-values

You can't do anything useful with a node identifier at runtime -- the
devicetree has "vanished" at that point (see
https://www.youtube.com/watch?v=sWaxQyIgEBY for what I mean by
"vanished").

You need to convert the node identifier to a device pointer with
DEVICE_DT_GET:

static const struct device *gpio_dev =
DEVICE_DT_GET(DT_GPIO_CTLR(DT_NODELABEL(button_sel_role), gpios));

Hope this helps,
Martí