Syntax in dts file for defining a GPIO output based on nxp,kinetis-gpio.yaml #defines


Bo.Kragelund@...
 

Hello developers!

I have difficulties finding any documentation/examples of how to define a simple GPIO as an e.g. output in the frdm_k64f.dts file for the frdm_k64f board.

As long as we talk about defining the outputs for LEDS on the board, this is done very nice based on the gpio-keys.yaml specific for this purpose.
As seen below, which is copied from the frdm_k64f.dts file, you simply define the port, pin number, and flags in one line like this: gpios = <&gpiob 22 0>, which means port b, pin 22, and no flags.
leds {
compatible = "gpio-leds";
red_led: led_0 {
gpios = <&gpiob 22 0>;
label = "User LD1";
};
};
 
But in general, I believe the idea is to define GPIO in the dts file based on the nxp,kinetis-gpio.yaml file created for this purpose, instead of the gpio-keys.yaml file.
But this file has a completely different way/syntax for defining a GPIO compared to the gpio-keys.yaml file.
It doesn't have the gpios property, but reg and interrupt instead. It also includes the below lines, which I guess I should use in some way:

"#cells":
  - pin
  - flags
 
Since I am rather new in dts and yaml syntax, I hope someone can help me with the syntax for setting port b, pin 22, and no flags, based on the nxp,kinetis-gpio.yaml file...

As written before, I haven't been able to find any examples so far in either the zephyr repository or zephyr documentation.

Thank you for your help.

Best regards,
Bo Kragelund

I hope someone can help me,


Andrei Gansari
 

Hello Bo,

 

 

We have a general help page for Device Tree: https://docs.zephyrproject.org/latest/guides/dts/index.html

 

In your particular case, you need to set port b pin 22 as output.

 

Device Tree:

The purpose of DT is to describe the HW of the board (boot time @ Linux, compile time @ Zephyr).

K64F’s DT file is found in: boards/arm/frdm_k64f/frdm_k64f.dts I expect this is what you are looking at. It also includes file dts/arm/nxp/nxp_k6x.dtsi where port b is set using nxp,kinetis-gpio.yaml. Dtsi file is a generic dts include file that describes the SoC (we may have another board with the same SoC on it).

Add the following to frdm_k64f.dts to use gpiob from nxp_k6x.dtsi:

&gpiob {

    status = "ok";

};

You can comment out/remove the following to remove he led configuration on the same pin:

        red_led: led_0 {

            gpios = <&gpiob 22 0>;

            label = "User LD1";

        };

 

Code:

You can’t configure a pin as in/out, using DT, we have board’s pinmux.c (in boards/arm/frdm_k64f) to do that. This is because GPIO should be dynamic during the application.

pinmux_pin_set(portb, 22, PORT_PCR_MUX(kPORT_MuxAsGpio));

The code above sets pin as GPIO (for the led in the case above). Then set pin to output and send a signal:

#include <gpio.h>

 

    pinmux_pin_set(portb, 22, PORT_PCR_MUX(kPORT_MuxAsGpio));

 

    struct device *gpiob =

           device_get_binding(DT_NXP_KINETIS_GPIO_GPIO_B_LABEL);

 

    gpio_pin_configure(gpiob, 22, GPIO_DIR_OUT);

    gpio_pin_write(gpiob, 22, 0);

 

DT_NXP_KINETIS_GPIO_GPIO_B_LABEL can be found in files zephyr/include/generated/generated_dts_board*** (relative to build folder) this is the effect of setting portb in dts.

 

 

Regards,

Andrei Gânsari

 

From: devel@... <devel@...> On Behalf Of Bo.Kragelund via Lists.Zephyrproject.Org
Sent: Thursday, March 28, 2019 12:57 PM
To: devel@...
Cc: devel@...
Subject: [Zephyr-devel] Syntax in dts file for defining a GPIO output based on nxp,kinetis-gpio.yaml #defines

 

Hello developers!

I have difficulties finding any documentation/examples of how to define a simple GPIO as an e.g. output in the frdm_k64f.dts file for the frdm_k64f board.

As long as we talk about defining the outputs for LEDS on the board, this is done very nice based on the gpio-keys.yaml specific for this purpose.
As seen below, which is copied from the frdm_k64f.dts file, you simply define the port, pin number, and flags in one line like this: gpios = <&gpiob 22 0>, which means port b, pin 22, and no flags.

leds {

compatible = "gpio-leds";

red_led: led_0 {

gpios = <&gpiob 22 0>;

label = "User LD1";

};

};

 

But in general, I believe the idea is to define GPIO in the dts file based on the nxp,kinetis-gpio.yaml file created for this purpose, instead of the gpio-keys.yaml file.
But this file has a completely different way/syntax for defining a GPIO compared to the gpio-keys.yaml file.
It doesn't have the gpios property, but reg and interrupt instead. It also includes the below lines, which I guess I should use in some way:

"#cells":

  - pin

  - flags

 

Since I am rather new in dts and yaml syntax, I hope someone can help me with the syntax for setting port b, pin 22, and no flags, based on the nxp,kinetis-gpio.yaml file...

As written before, I haven't been able to find any examples so far in either the zephyr repository or zephyr documentation.

Thank you for your help.

Best regards,
Bo Kragelund

I hope someone can help me,


Bo.Kragelund@...
 

Hello Andrei,

And thank you very much for your quick answer.
I really appriciate the quick link to where I can find the documentation and also the example you have provided.

I am also aware of, that it will be in the code, that you configure the pin to be input or output.

But what is not so great is, that we would very much like to define the port and pin number at the dts level for the specific boards, that we support.
We want the code to be generic and not be changed, if a new board will use another pin for the same function.

This is what zephyr has achieved by making the gpio-leds.yaml and then setup the leds in the board specific dts files.
By doing this, along with using alias, you simply refer to the define LED0_GPIO_PIN in your code across all boards without knowing what pin it is and what port in the code, which we like.

We have actually made our own gpio-xxx.yaml, which looks similar to gpio-leds.yaml and placed it in the same location as gpio-leds.yaml.
Then we put the following lines in the dts file for the given board:

_test {
compatible = "gpio-xxx";
test_pin {
gpios = <&gpiob 22 0>;
label = "My test pin";
};
};

This will create the following in the auto generated header file:

/* test_pin */
#define DT_GPIO_OUT_TEST_PIN_GPIO_CONTROLLER "GPIO_1"
#define DT_GPIO_OUT_TEST_PIN_GPIO_FLAGS 0
#define DT_GPIO_OUT_TEST_PIN_GPIO_PIN 22
#define DT_GPIO_OUT_TEST_PIN_LABEL "My test pin"
 
We don't use alias because we want to see in the code, that the defines comes from dts.
The code will then have lines like this:

wdt_device = device_get_binding(DT_GPIO_OUT_TEST_PIN_GPIO_CONTROLLER);
gpio_pin_configure(wdt_device, DT_GPIO_OUT_TEST_PIN_GPIO_PIN, GPIO_DIR_OUT | DT_GPIO_OUT_TEST_PIN_GPIO_FLAGS);
gpio_pin_write(wdt_device, DT_GPIO_OUT_TEST_PIN_GPIO_PIN, 1);
 
I guess this is a way to do it, if you want to keep your code independant of pin numbers etc.
Of course you have to write the dts lines with the exact same names in all dts files supporting this function.

Best regards,
Bo


Andrei Gansari
 

Hello,

 

Yes, my example was hardcoded in regard to port and pin number. Your example makes them configurable via dts, while code remains the same.

 

I only have to point another thing: the generated macros name will remain the same in other dts configurations if you keep the same name across dts (in the example:  _test {} ).

 

 

Regards,

Andrei

 

 

From: devel@... <devel@...> On Behalf Of Bo.Kragelund via Lists.Zephyrproject.Org
Sent: Thursday, March 28, 2019 5:06 PM
To: devel@...
Cc: devel@...
Subject: Re: [Zephyr-devel] Syntax in dts file for defining a GPIO output based on nxp,kinetis-gpio.yaml #defines

 

Hello Andrei,

And thank you very much for your quick answer.
I really appriciate the quick link to where I can find the documentation and also the example you have provided.

I am also aware of, that it will be in the code, that you configure the pin to be input or output.

But what is not so great is, that we would very much like to define the port and pin number at the dts level for the specific boards, that we support.
We want the code to be generic and not be changed, if a new board will use another pin for the same function.

This is what zephyr has achieved by making the gpio-leds.yaml and then setup the leds in the board specific dts files.
By doing this, along with using alias, you simply refer to the define LED0_GPIO_PIN in your code across all boards without knowing what pin it is and what port in the code, which we like.

We have actually made our own gpio-xxx.yaml, which looks similar to gpio-leds.yaml and placed it in the same location as gpio-leds.yaml.
Then we put the following lines in the dts file for the given board:

_test {

compatible = "gpio-xxx";

test_pin {

gpios = <&gpiob 22 0>;

label = "My test pin";

};

};


This will create the following in the auto generated header file:

/* test_pin */

#define DT_GPIO_OUT_TEST_PIN_GPIO_CONTROLLER "GPIO_1"

#define DT_GPIO_OUT_TEST_PIN_GPIO_FLAGS 0

#define DT_GPIO_OUT_TEST_PIN_GPIO_PIN 22

#define DT_GPIO_OUT_TEST_PIN_LABEL "My test pin"

 

We don't use alias because we want to see in the code, that the defines comes from dts.
The code will then have lines like this:


wdt_device = device_get_binding(DT_GPIO_OUT_TEST_PIN_GPIO_CONTROLLER);

gpio_pin_configure(wdt_device, DT_GPIO_OUT_TEST_PIN_GPIO_PIN, GPIO_DIR_OUT | DT_GPIO_OUT_TEST_PIN_GPIO_FLAGS);

gpio_pin_write(wdt_device, DT_GPIO_OUT_TEST_PIN_GPIO_PIN, 1);

 

I guess this is a way to do it, if you want to keep your code independant of pin numbers etc.
Of course you have to write the dts lines with the exact same names in all dts files supporting this function.

Best regards,
Bo


Bo.Kragelund@...
 

Thank you for your quick assistance yesterday Andrei.

Maybe I misunderstood your last point, but as I see it, it is the name "test_pin" in my example, which needs to remain the same across dts files for other boards to keep the same generated macro name in the dts configurations.
It is also the name "test_pin" that is added as a header comment in the auto generated file generated_dts_board.h as /* test_pin */
I think the name "_test" is just a name for the dts node itself and not used anywhere.

Bonus info:
Using a "_" in the begining of the dts node name "_test" actually puts the generated macro names in the top of the auto generated file generated_dts_board.h, which might be a help to distinguish between your own definitions and the definitions made in zephyr already. Probably because the dts nodes are generated in alphabetic order.

Best regards,
Bo