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
  • Hi Johannes, 

    Are you sure the 15uA extra current comes from GPIO configuration?

    Would you be able to make a small sample only using gpio-keys to compare the power difference?

    You can share me the sample if the difference still exists. 

    In addition, I share a discussion about System off mode (+) nRF9160 - SYSTEM OFF Mode Current - Nordic Q&A - Nordic DevZone - Nordic DevZone (nordicsemi.com) just in case you are also interested.

    Best regards,

    Charlie

  • 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)

Reply
  • 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)

Children
  • 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

  • Hi Charlie,

    sorry for replying so late.

    I can confirm that after applying your change to input_gpio_keys.c, the floor current is at the level I expected (3.4 μA on my custom board).

    However, when in addition I set CONFIG_PM_DEVICE=y *and* CONFIG_PM_DEVICE_RUNTIME=y, the floor current is increased again.
    Initially I suspected this would be caused by the pm action in input_gpio_keys.c; but when I removed that, the power consumption is still increased.

    For our product, I need to set CONFIG_PM_DEVICE=y (and would prefer to enable CONFIG_PM_DEVICE_RUNTIME as well), to reduce the power consumption of some external peripherals.

    I'd be glad if we can resolve this.

  • Hi Johannes,

    According to previous discussion about PM: devzone.nordicsemi.com/.../472615

    Power management is automatically handled by the hardware on our chips. Therefore, the support for PM on Nordic ICs was removed since SDK v2.5.0: https://github.com/nrfconnect/sdk-zephyr/commit/96b38273138f05dd06cf7a58fa361f401e773e5e

    The PM running may need some extra peripherals like timer, so you are expected to see current increase. nRF chips manage PM on hardware level so we dropped support for Zephyr PM.

    Best regards,

    Charlie

  • Hi Charlie,

    I understand that Nordic MCUs do not need (and do not support) CONFIG_PM. And I just confirmed that we still achieve the same power consumption when CONFIG_PM_DEVICE is not set. However, I think that is only because we were lucky and the drivers for the external chips we have do not require or use CONFIG_PM.

    Nevertheless, my problem has been resolved by this. Thanks!

Related