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

Problem using nRF Connect SDK devicetree GPIO definitions in code

Hi,

I am just starting out creating a project to run on an nRF9160 on custom hardware. I have set up a development environment (v1.9.0) through nRF Connect for Desktop app. I have created a custom board configuration based on the thingy91_nrf9160 board files, and successfully built an example project (cloud_client) for this board configuration.

Now I want to add some GPIO of my own to setup connections to the rest of my system, but since I am new to device trees I am not sure that I am doing things correctly.

Starting out with a testpad on the pcb, I added a GPIO pin to the dts file as follows:

/ {
    /* model and compatible parameter defined here...  */

	tp: testpin {
		gpios = <&gpio0 22 0>;
	};
	
	/* reserved memory defined here... */
};

/* some peripherals defined here... */

&gpio0 {
	status = "okay";
};

/* some more peripherals defined here... */

And I try to use the pin through a sourcefile that I have added to the src folder, using the nrf52840_reset.c code as an example:

#include <drivers/gpio.h>
#include <device.h>
#include <devicetree.h>

#define TP_NODE         DT_NODELABEL(tp)
#define TP_GPIO_CTRL    DT_GPIO_CTLR(TP_NODE, gpios)
#define TP_GPIO_PIN     DT_GPIO_PIN(TP_NODE, gpios)
#define TP_GPIO_FLAGS   DT_GPIO_FLAGS(TP_NODE, gpios)

static struct device *port = NULL;

void TestpinInit(void)
{
    port = DEVICE_DT_GET(TP_GPIO_CTRL);
    gpio_pin_configure(port, TP_GPIO_PIN, TP_GPIO_FLAGS | GPIO_OUTPUT_INACTIVE);
}

void TestpinToggle(void)
{
    if (NULL != port)
    {
        gpio_pin_toggle(port, TP_GPIO_PIN);
    }
}

Unfortunately this code creates quite some build errors; all similar. For example:

In file included from C:\_tools\v1.9.0\zephyr\include\toolchain\gcc.h:72,
                 from C:\_tools\v1.9.0\zephyr\include\toolchain.h:50,
                 from C:\_tools\v1.9.0\zephyr\include\sys\printk.h:11,
                 from C:\_tools\v1.9.0\zephyr\include\sys\__assert.h:11,
                 from C:\_tools\v1.9.0\zephyr\include\drivers\gpio.h:18,
                 from c:\_repo\project\nrf9160\cloud_client\src\testpin.c:32:
../src/testpin.c: In function 'TestpinInit':
C:\_tools\v1.9.0\zephyr\include\device.h:96:39: error: '__device_dts_ord_DT_N_S_testpin_P_gpios_IDX_0_PH_ORD' undeclared (first use in this function)
   96 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
      |                                       ^~~~~~~~~
C:\_tools\v1.9.0\zephyr\include\toolchain\common.h:132:26: note: in definition of macro '_DO_CONCAT'
  132 | #define _DO_CONCAT(x, y) x ## y
      |                          ^
C:\_tools\v1.9.0\zephyr\include\device.h:96:31: note: in expansion of macro '_CONCAT'
   96 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
      |                               ^~~~~~~
C:\_tools\v1.9.0\zephyr\include\device.h:291:37: note: in expansion of macro 'DEVICE_NAME_GET'
  291 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_NAME(node_id))
      |                                     ^~~~~~~~~~~~~~~
C:\_tools\v1.9.0\zephyr\include\device.h:311:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
  311 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
      |                                  ^~~~~~~~~~~~~~~~~~
c:\_repo\project\nrf9160\cloud_client\src\testpin.c:72:12: note: in expansion of macro 'DEVICE_DT_GET'
   72 |     port = DEVICE_DT_GET(TP_GPIO_CTRL);
      |            ^~~~~~~~~~~~~
C:\_tools\v1.9.0\zephyr\include\device.h:96:39: note: each undeclared identifier is reported only once for each function it appears in
   96 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
      |                                       ^~~~~~~~~
C:\_tools\v1.9.0\zephyr\include\toolchain\common.h:132:26: note: in definition of macro '_DO_CONCAT'
  132 | #define _DO_CONCAT(x, y) x ## y
      |                          ^
C:\_tools\v1.9.0\zephyr\include\device.h:96:31: note: in expansion of macro '_CONCAT'
   96 | #define DEVICE_NAME_GET(name) _CONCAT(__device_, name)
      |                               ^~~~~~~
C:\_tools\v1.9.0\zephyr\include\device.h:291:37: note: in expansion of macro 'DEVICE_NAME_GET'
  291 | #define DEVICE_DT_NAME_GET(node_id) DEVICE_NAME_GET(Z_DEVICE_DT_DEV_NAME(node_id))
      |                                     ^~~~~~~~~~~~~~~
C:\_tools\v1.9.0\zephyr\include\device.h:311:34: note: in expansion of macro 'DEVICE_DT_NAME_GET'
  311 | #define DEVICE_DT_GET(node_id) (&DEVICE_DT_NAME_GET(node_id))
      |                                  ^~~~~~~~~~~~~~~~~~
c:\_repo\project\nrf9160\cloud_client\src\testpin.c:72:12: note: in expansion of macro 'DEVICE_DT_GET'
   72 |     port = DEVICE_DT_GET(TP_GPIO_CTRL);
      |            ^~~~~~~~~~~~~

I am not sure how to interpret these errors. To me it appears that the compiler creates a node name through the macros used, and it does not match the node name given in the dts file. I am having trouble getting out of this what name the compiler actually expects; where exactly have I made my error and what should I do to fix it.

Can anyone here point me in the right direction?

Parents
  • Hello, 

    Looks like the DTS configuration you have attached is missing the whole configuration, and you have only part of the configuration. E.g. look at nrf\boards\arm\thingy91_nrf9160\thingy91_nrf9160_common.dts

    From here you can see how they have configured the button connected to the nRF9160:

    buttons {
    	compatible = "gpio-keys";
    
    	button0: button_0 {
    		gpios = <&gpio0 26 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    		label = "Button 1";
    	};
    };
    
    &gpio0 {
    	status = "okay";
    };

    Edit: You should also have a look at the basic button sample in Zephyr (zephyr\samples\basic\button\src\main.c)

    Kind regards,
    Øyvind

Reply
  • Hello, 

    Looks like the DTS configuration you have attached is missing the whole configuration, and you have only part of the configuration. E.g. look at nrf\boards\arm\thingy91_nrf9160\thingy91_nrf9160_common.dts

    From here you can see how they have configured the button connected to the nRF9160:

    buttons {
    	compatible = "gpio-keys";
    
    	button0: button_0 {
    		gpios = <&gpio0 26 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    		label = "Button 1";
    	};
    };
    
    &gpio0 {
    	status = "okay";
    };

    Edit: You should also have a look at the basic button sample in Zephyr (zephyr\samples\basic\button\src\main.c)

    Kind regards,
    Øyvind

Children
  • Hi Øyvind,


    Thank you for your answer. I have seen the button examples, but the trouble is I am not trying to implement a button here. I am implementing a GPIO pin.


    Looking at the Zephyr device tree documentation they make it seem like you can just create a node (which I named tp) and include a "gpios" parameter to it to define a gpio. All of the examples look like this, roughly..


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


    Looking at the nRF Connect view in Visual Studio Code under the devicetree tab the pin is also recognised as a GPIO node with the name tp, so sómething is happening..

    I have tried adding my own source file to the dts configuration, but that made no difference.

    testpins {
    	compatible = "testpin";
    
    	tp: tspn {
    		gpios = <&gpio0 22 0>;
    		label = "TP42";
    	};
    };

    How do I configure just a regular old GPIO in the devicetree (not tied button or led drivers) to use in my own code?

Related