Steps when setting up GPIO

I'm trying to get my head around the steps involved in doing something as simple as accessing a GPIO pin.

I'm running VSCode as my IDE, with the nRF Connect extension (V1.7.0).  I've been playing around with the blinky example contained in ..\v1.7.0\zephyr\samples, and I'm using the nRF52-DK with the nRF52832 chipset.

What I need is someone to just step me through the process of how to set up my code so I can access the relevant GPIO on my hardware, and then change its state.  The blinky example does this, and I can play around with that and add some additional GPIO pins, etc, but I'm not fully understanding all the stuff involving nodes and devices and flags, etc, etc.  I want to get that clear in my head before I try and go too much further.

As I understand it:

1.  In the Devicetree, a GPIO pin will be defined along the lines:

       gpio_pin_name: pin_name {
            gpios = <&gpio0 PIN_NUMBER GPIO_ACTIVE_LOW>;
            label = "GPIO PIN";
        };
In this example, pin_name is the sub-node name in Devicetree, but that's not something I can reference in my code - correct?  If I wanted to reference this pin, I'd need to be using the sub-node label, in this case "gpio_pin_name - correct?
2.  Next step is to create an alias to the gpio_pin_name instance.  Not sure if this is strictly necessary, but I guess is good practise as it looks like it ensures my code is then easily compatible with different hardware.  So, in my example, I might do something like:
#define PIN_1_NODE  DT_ALIAS(gpio_pin_name)
#if DT_NODE_HAS_STATUS(PIN_1_NODE  DT_ALIAS, okay)
#define PIN_1         DT_GPIO_LABEL(PIN_1_NODE, gpios)
#define PIN_1_PIN     DT_GPIO_PIN(PIN_1_NODE, gpios)
#define PIN_1_FLAGS   DT_GPIO_FLAGS(PIN_1_NODE, gpios)
So, now PIN_1_NODE is set up to reference all the node info in the Devicetree for gpio_pin_name (I think!)
Could I skip this step, and instead just use gpio_pin_name in place of PIN_1_NODE whenever I need to access the Devicetree info?  I guess this would mean if I try and interface to a board that doesn't use "gpio_pin_name", then I have to go through my code and change all those references, rather than just change the #define statement above, correct?
3.  In my code, the next step I need to complete is creating a device, of type  "struct device" that will store all the information from the Devicetree for the GPIO pin I am interested in using. 
So, I could do:
struct device *gpio_pin_1;
The pointer gpio_pin_1 then needs to be associated with the Devicetree entry for gpio_pin_name.  If I understand things correctly, that is done using the device_get_binding API, viz:
gpio_pin_1 = device_get_binding(gpio_pin_name);
or
gpio_pin_1 = device_get_binding(PIN_1_NODE);
Correct?
4.  OK, assuming I'm still on the right path, I can now start manipulating the GPIO pin using the various gpio_ API's.  e.g.
gpio_pin_configure(gpio_pin_1, PIN_1_PIN, GPIO_OUTPUT_ACTIVE | PIN_1_FLAGS);
gpio_pin_set(gpio_pin_1, PIN_1_PIN, 0);
I know this probably all seems second nature to most of you, but as a beginner is this development environment, that is used to a completely different approach, I'm wanting to get all this clear in my head now, so I don't get caught out later.
If I've missed any critical steps above, or added some that aren't strictly needed, I'd appreciate your comments.
Cheers,
Mike
Related