Hi,
I'm trying to setup a "proper" configuration of IRQ from external GPIOs on nRF52832, using the Zephyr GPIO API. Ambition is to keep the SoC in "System ON" mode consuming a few uAs, but I'm not able to find any good examples of this configurations. Below is a modified version of the "Blinky" sample showing my current understanding how to use the API for this task, this works but results in high current consumption of the SoC.
After a lot of trial and error I've concluded that the missing piece seems to be a "sense-edge-mask" property on the gpio0 node in the DT, running the sample code below on the nRF52 DK just shows a difference of ~10uA when adding this property but on the real target hardware with a more complex setup in the DT the difference is huge (hundreds of uA). The IRQs I'm trying to configure should be edge sensitive, it seems that using level sensitive IRQs does not require this "sense-edge-mask" property?
I find documentation lacking in this area, how is "sense-edge-mask" related with gpio and gpiote and what is the expected setup in this case? Some DTs seems to enable the gpiote peripheral as well, but it is not clear when and why this should be done?
Maybe related question, on this nRF52832 SoC it doesn't seem possible to enable PM via "CONFIG_PM=y" since the SoC does not set the "HAS_PM" flag. Is PM and/or PM_DEVICE supported on the nRF SoCs, can drivers add hooks here for additional power savings?
#include <zephyr/kernel.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) /* * 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 led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); static struct gpio_callback irq_cb; static void irqHandler(const struct device *port, struct gpio_callback *cb, gpio_port_pins_t pins) { // Do something } int main(void) { int ret; if (!gpio_is_ready_dt(&led)) { return 0; } ret = gpio_pin_configure_dt(&led, (GPIO_INPUT | GPIO_PULL_UP)); if (ret < 0) { return 0; } gpio_init_callback(&irq_cb, irqHandler, BIT(led.pin)); ret = gpio_add_callback_dt(&led, &irq_cb); if (ret < 0) { return 0; } ret = gpio_pin_interrupt_configure_dt(&led, GPIO_INT_EDGE_FALLING); if (ret < 0) { return 0; } while (1) { k_msleep(SLEEP_TIME_MS); } return 0; }