Level-triggered GPIO interrupt with NCS 2.7 on nRF9160

Hi,

after upgrading to NCS v2.7.0, I have some trouble with an increased sleep power consumption of our device when I use Zephyr's gpio-keys for the button input.

I was using NCS v2.5.2 before. Initially after upgrading, the button would not work any more at all, when I would compile with `CONFIG_PM_DEVICE` and `CONFIG_PM_DEVICE_RUNTIME`. That could be resolved by calling `pm_device_runtime_get()` on the gpio-keys device during initialization. Now the button would work, but the sleep power consumption would increase by around 15 μA.

With NCS v2.5.2, I also had an increase of the power consumption by about 15 μA when I added the button with gpio-keys to my software and enabled CONFIG_INPUT.
According to this (old) thread on devzone, the nRF9160 would require the use of level-, not edge-triggered GPIO interrupts, for low power consumption.

I then applied a small fix to the Zephyr gpio-keys driver, to use level-triggered instead of edge-triggered interrupts (see https://github.com/senseing-gmbh/sdk-zephyr/commit/7cab2bf5b45c6edf39632d5d0886781a05aaf50d). With this fix, the sleep power consumption would be good again.

Now, with NCS v2.7.0, simply replacing `GPIO_INT_EDGE_BOTH` in `zephr/drivers/input/input_gpio_keys.c` by `GPIO_INT_LEVELS_LOGICAL` again did not do the trick, though. I also tried `GPIO_INT_LEVEL_ACTIVE`, but then the sleep power consumption is still increased and the button would not work any more.

Is my approach to use `pm_device_runtime_get()` right, and how can I reduce the power consumption again with gpio-keys?

Parents Reply Children
  • Hi Charlie,

    thanks for your reply!

    I couldn't find out how to attach source files to this thread, but it's easily reproduceable e.g. with a slight modification of the Zephyr input_dump sample (e.g. from NCS v2.7.0, zephyr/samples/subsys/input/input_dump).

    Just add code for initializing the modem to the main function (to work around NCSDK-10106), so it looks as follows:

    #include <stdio.h>
    #include <modem/nrf_modem_lib.h>
    
    int main(void)
    {
        int ret = nrf_modem_lib_init();
        if (ret) {
            printf("ERROR: Modem library initialization failed (%d)", ret);
            return ret;
        }
    
        printf("Input sample started\n");
        return 0;
    }
    

    Then, compile the the sample as follows:

    west build -b nrf9160dk/nrf9160/ns (read) -- -DCONFIG_NRF_MODEM_LIB=y -DCONFIG_SERIAL=n

    On my board, this results in a sleep current of ~18 μA:

    Whereas, when the same sample is build with an additional `-DCONFIG_INPUT_GPIO_KEYS=n`, on my board the sleep current would be around 3 μA:

    (I am using a custom board, but it simply consists of an nRF9160, an LDO and a SIM card slot, so I am still using the nrf9160dk/nrf9160/ns target)

  • Hi Johannes,

    I tried the solution you mentioned before, and the following change will make a nRF9160DK consume around 2.3uA floor current.

    C:\NCS\v2.7.0\zephyr\samples\subsys\input\input_dump> git diff
    diff --git a/drivers/input/input_gpio_keys.c b/drivers/input/input_gpio_keys.c
    index fa27ca5bd64..d666e9c18de 100644
    --- a/drivers/input/input_gpio_keys.c
    +++ b/drivers/input/input_gpio_keys.c
    @@ -149,7 +149,7 @@ static int gpio_keys_interrupt_configure(const struct gpio_dt_spec *gpio_spec,
    
            LOG_DBG("port=%s, pin=%d", gpio_spec->port->name, gpio_spec->pin);
    
    -       ret = gpio_pin_interrupt_configure_dt(gpio_spec, GPIO_INT_EDGE_BOTH);
    +       ret = gpio_pin_interrupt_configure_dt(gpio_spec, GPIO_INT_LEVELS_LOGICAL & ~GPIO_INT_MODE_DISABLED);
            if (ret < 0) {
                    LOG_ERR("interrupt configuration failed: %d", ret);
                    return ret;
    diff --git a/samples/subsys/input/input_dump/prj.conf b/samples/subsys/input/input_dump/prj.conf
    index e4c7fb97d5d..e8137283778 100644
    --- a/samples/subsys/input/input_dump/prj.conf
    +++ b/samples/subsys/input/input_dump/prj.conf
    @@ -3,3 +3,4 @@ CONFIG_LOG_MODE_MINIMAL=y
     
     CONFIG_INPUT=y
     CONFIG_INPUT_EVENT_DUMP=y
    +CONFIG_SERIAL=n
    \ No newline at end of file

    Change CONFIG_SERIAL to y and verified that the buttons still work.

    *** Booting nRF Connect SDK v2.7.0-5cb85570ca43 ***
    *** Using Zephyr OS v3.6.99-100befc70c74 ***
    Input sample started
    I: input event: dev=buttons          SYN type= 1 code= 11 value=1
    I: input event: dev=buttons          SYN type= 1 code= 11 value=0
    I: input event: dev=buttons          SYN type= 1 code=  2 value=1
    I: input event: dev=buttons          SYN type= 1 code=  2 value=0
    I: input event: dev=buttons          SYN type= 1 code= 11 value=1
    I: input event: dev=buttons          SYN type= 1 code= 11 value=0
    I: input event: dev=buttons          SYN type= 1 code=  2 value=1
    I: input event: dev=buttons          SYN type= 1 code=  2 value=0

    Do you have a chance to test with an nRF9160DK? 

    Best regards,

    Charlie

Related