Trigger GPIO interrupt on high pin level

Hi,

I'm modifying the Nodric Developer Academy example for GPIO (https://github.com/NordicDeveloperAcademy/ncs-fund/blob/main/v2.x.x/lesson2/fund_less2_exer2_solution/src/main.c), using the nRF52840DK.

I'm trying to trigger an interrupt based on high pin level, using the following code:

/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   1000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE 		DT_ALIAS(led0)
#define BUTTON0_NODE	DT_NODELABEL(button0)
#define BUTTON1_NODE	DT_NODELABEL(button1)
#define BUTTON2_NODE	DT_NODELABEL(button2)

//#define BUTTON_PORT DEVICE_DT_GET(DT_GPIO_CTLR(DT_NODELABEL(button0), gpios))

/*
 * A build error on this line means your board is unsupported.
 * See the sample documentation for information on how to fix this.
 */
static const struct gpio_dt_spec led0_spec = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static const struct gpio_dt_spec button0_spec = GPIO_DT_SPEC_GET(BUTTON0_NODE, gpios);
static const struct gpio_dt_spec button1_spec = GPIO_DT_SPEC_GET(BUTTON1_NODE, gpios);
static const struct gpio_dt_spec button2_spec = GPIO_DT_SPEC_GET(BUTTON2_NODE, gpios);

//Structure for GPIO callback when we define an interrupt
static struct gpio_callback button2_cb;

void button_pressed_callback(const struct device *gpiob, struct gpio_callback *cb, gpio_port_pins_t pins)
{
	gpio_pin_toggle_dt(&led0_spec);
	gpio_pin_set_dt(&button1_spec, 1);
}

void main(void)
{

	gpio_pin_configure_dt(&led0_spec, GPIO_OUTPUT);
	gpio_pin_configure_dt(&button0_spec, GPIO_INPUT | GPIO_ACTIVE_HIGH);
	gpio_pin_configure_dt(&button1_spec, GPIO_OUTPUT);
	gpio_pin_configure_dt(&button2_spec, GPIO_INPUT | GPIO_ACTIVE_HIGH);


	gpio_pin_interrupt_configure_dt(&button2_spec, GPIO_ACTIVE_HIGH);
	gpio_init_callback(&button2_cb, button_pressed_callback, BIT(button2_spec.pin));
	gpio_add_callback(button2_spec.port, &button2_cb);

	while (1) {
		
		k_msleep(SLEEP_TIME_MS);
	}
}

But button 2 (and the interrupt callback) will only work with a low level (triggered when connected to ground). How can I change this to active high (triggers when connected to VDD)?

Thanks in advance.

  • Hi,

    In the devicetree, or rather an overlay to a device tree, you can configure the pin to be active high. 

    1. Build your current project (or something that compiles) for the nRF52840dk
    2. Create a new overlay for the file
    3. Use the Devicetree helper located at the actions tab in VS Code extension
    4. Open the buttons-node
    5. Select the button you want to configure
    6. Set it to active high instead of active low

    You can now see that in the dts you generated in step 2 that the buttons has changed. Every other button than button 2 is active low, while button 2 is active high.

     

    Recompiling and running your firmware should result in a build where button two is now active high, while the rest is active low.

    Do note, that the Devicetree helper tool might give the wrong output in some cases, so I recommend that you also consult with the documentation regarding configuring devicetree and overlay here https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/index.html. It is however a tremendously good tool to familiarize yourself with what you can do with nodes and how to change things.

    Let me know if this resolves your issue

    Kind regards,
    Andreas

  • Hi Andreas, thank you for the detailed response. Just one question, once I follow the 6 steps, the changes are reflected in the devicetree file itself, not the overlay. Am I doing something wrong here?

  • Yeah, you're right. I was a bit too quick there and assumed that the changes would be added to the overlay directly

    What you can do to not make this change permanent to every future build with that board file to do is to copy said output, i.e the changes that is added to the board file to the overlay file that resides in your project folder. This will ensure that whatever is in the overlay file overwrites the board file configuration for only the projects that uses this overlay file

    Let me know if you're able to resolve it by doing that and if not I'll look more into it! :) 

    Kind regards,
    Andreas

Related