GPIO overlays

I've been looking through this forum for advice on GPIO overlays and there seems to be a lot of confusion.

So I looked at the button and blinky examples and put together the following overlay for my board:

/{
	custom_leds {
 	   compatible = "gpio-leds";
	   led0: led_0 {
		  gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
		  label = "My custom LED";
	   };
	};
	aliases {
		mycustomled = &led0;
	};
 };
 

This repurposes GPIO 15 to be an LED instead of a button as it was in the original dts file.

The first problem with this approach is that I get the following warning:

Pin 15 of &gpio0 already assigned to &button2
bl652_dvk.dts(44, 12): Overlapping assignment

I suspect I'm not doing the overlay correctly to remap a GPIO from a button in the dts to an LED in the overlay. But it does build.

The next thing I do is to try and get a device in the runtime code with the following line:

const struct device * dev_custom_led = DEVICE_DT_GET(DT_NODELABEL(mycustomled));

This does not build, even though it's the same mechanism that I use to get the device for other things like the ADC or the SPI bus. So I suspect the warning in the device tree overlay is actually an error.

How should I do this? How do I use an overlay to repurpose a GPIO?

  • The first problem with this approach is that I get the following warning:

    As indicated by the warning, you currently have the GPIO assigned as both a button and an LED. To get rid of the warning, you can delete the button node and its alias in your overlay, as shown below.

    /delete-node/ &button2;
    
    
    /{
        custom_leds {
            compatible = "gpio-leds";
            led0: led_0 {
                gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
                label = "My custom LED";
            };
        };
        aliases {
            mycustomled = &ledx;
            /delete-property/ sw2;
        };
    
    };

    The next thing I do is to try and get a device in the runtime code with the following line:

    If you want to use the Zephyr GPIO API to control the pin, then you need to initialize the gpio_dt_spec struct for the child node (led0). You can see how it is done in the Blinky example here: https://github.com/nrfconnect/sdk-zephyr/blob/b37ce40878ec52295afe6350d17712d60eb6639a/samples/basic/blinky/src/main.c#L20C75-L20C75  

    E.g.,

    #define LED0_NODE DT_ALIAS(mycustomled)
    
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

    Best regards,

    Vidar

  • I added the delete-property as you suggested. In my case, GPIO 15 was connected to button2 and aliased to sw1 in my boards dts file. Here's fragment from the board's dts:

    	buttons {
    		compatible = "gpio-keys";
    		button1: button_1 {
    			gpios = <&gpio0 11 GPIO_PULL_UP>;
    			label = "Push button switch 1";
    		};
    		button2: button_2 {
    			gpios = <&gpio0 15 GPIO_PULL_UP>;
    			label = "Push button switch 2";
    		};
    	};
    
    	/* These aliases are provided for compatibility with samples */
    	aliases {
    		led0 = &led1;
    		led1 = &led2;
    		sw0 = &button1;
    		sw1 = &button2;
    		mcuboot-button0 = &button1;
    		mcuboot-led0 = &led1;
    		watchdog0 = &wdt0;
    	};
    	

    So my overlay deletes sw1 and looks like this:

    /{
    	custom_leds {
     	   compatible = "gpio-leds";
    	   led0: led_0 {
    		  gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>;
    		  label = "My custom LED";
    	   };
    	};
    	aliases {
    		mycustomled = &led0;
    		/delete-property/ sw1;
    	};
     };
     

    I'm still getting the same warning:

    Pin 15 of &gpio0 already assigned to &button2
    bl652_dvk.dts(44, 12): Overlapping assignment
    

    I pasted in the runtime code as you suggested and the build still fails, probably because I'm still not correctly deleting the button and replacing with the led.

    Can you see what I still have wrong?

  • It looks like you only deleted the alias, but not the button node. I had this line at the beginning of my overlay: 

    /delete-node/ &button2;

    Bret Foreman said:
    I pasted in the runtime code as you suggested and the build still fails

    Can you please post the build log? You should be able to compile despite the warning about overlapping pin assignments.

  • Adding only

    /delete-node/ &button2;
    

    In my overlay file causes this line in the dts file to fail:

    		sw1 = &button2;
    

    The message is "Unknown reference to &button2" as you might expect.

    Adding this line to my overlay:

    		/delete-property/ sw1;
    

    Does not fix it.

    I've zipped up and attached the entire project so you can see the build failure first hand.cm_fw_core.zip

  • Thanks for sharing your project. Yes, it is necessary to remove the alias as well if you delete the button node, just as I did in the overlay I posted earlier.

    While building your project, I got an "implicit declaration" warning for the GPIO_DT_SPEC_GET() macro and an "incomplete type" error for the gpio_dt_spec struct. This was because you were missing the <zephyr/drivers/gpio.h> include.

    Build log

    Code with required "include"

    #include <zephyr/drivers/gpio.h>
    
    #define LED0_NODE DT_ALIAS(mycustomled)
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);

Related