Zephyr GPIO Interrupt

I am porting my code from Nordic SDK16 to Zephyr and NRF Connect SDK 2.0. I am working on putting a chip into sleep mode and set up a wake up on a press of the button. Everything seems to be working ok on the first run but after the chip wakes up, the gpio call back gets called twice and I have no idea why. I tried removing a call back with gpio_remove_callback(button.port, &button_cb_data) but its not helping. Thanks for any help.

#define SW0_NODE	DT_ALIAS(sw0)
#if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
#error "Unsupported board: sw0 devicetree alias is not defined"
#endif
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
static struct gpio_callback button_cb_data;

static int disable_ds_1(const struct device *dev)
{
	ARG_UNUSED(dev);
	pm_policy_state_lock_get(PM_STATE_SOFT_OFF);
	return 0;
}

SYS_INIT(disable_ds_1, PRE_KERNEL_2, 0);

static void power_down() {
    printk("Power down\r\n");
    pm_state_force(0u, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0});
    k_sleep(K_SECONDS(2U));
}

static void prepare_wake_up() {
    printk("Preparing wake up\r\n");
    nrf_gpio_cfg_input(NRF_DT_GPIOS_TO_PSEL(DT_ALIAS(sw0), gpios), NRF_GPIO_PIN_PULLUP);
	nrf_gpio_cfg_sense_set(NRF_DT_GPIOS_TO_PSEL(DT_ALIAS(sw0), gpios), NRF_GPIO_PIN_SENSE_LOW);
}

static void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    if (gpio_pin_get(button.port, button.pin)) {
        printk("Button pressed...\r\n");
    } else {
        printk("Button released...\r\n");
        prepare_wake_up();
        power_down();
    }
}

int main() {
    if (!device_is_ready(button.port)) {
		printk("Error: button device %s is not ready\n",
		       button.port->name);
		return;
	}

	gpio_pin_configure_dt(&button, GPIO_INPUT));

	gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_BOTH);

	gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
	gpio_add_callback(button.port, &button_cb_data);
}

On the first run it will be:

Button pressed...

Button released...

Prepare wake up...

Power down...

Then after system wakes up with the press of the button, this happens:

Button pressed...

Button pressed...

Button released...

Prepare wake up...

Power down...

Button released...

Prepare wake up...

Power down...

Related