NRF9160 power off and wake up

Hello, this is a follow up on this ticket: https://devzone.nordicsemi.com/f/nordic-q-a/84834/protecting-the-battery-via-sleep-mode

Our goal is to switch off the device (based on nrf9160) when battery voltage is under a threshold and wake it up (reboot) upon external power connection.

Our setup is a board with battery input. We have connected the USB line to GPIO 14 to be able to detect power input (this is working as explained below).

We were told (see ticket linked above) to mimic this example: https://github.com/nrfconnect/sdk-zephyr/tree/main/samples/boards/nrf/system_off

Our very simple POC:

void main(void)
{
    printk("Power off POC started\n");

    nrf_gpio_cfg_input(DT_GPIO_PIN(DT_NODELABEL(external_power_detection), gpios), NRF_GPIO_PIN_NOPULL);
    nrf_gpio_cfg_sense_set(DT_GPIO_PIN(DT_NODELABEL(external_power_detection), gpios), NRF_GPIO_PIN_SENSE_HIGH);
    // k_sleep(K_SECONDS(1));
    // pm_power_state_force(0u, (struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0});

    int v;
    int acc = 0;
    int seconds = 0;

    while (1) {
        v = nrf_gpio_pin_read(DT_GPIO_PIN(DT_NODELABEL(external_power_detection), gpios));
        printk("Input value: %d\n", v);
        acc += v;
        seconds++;
        printk("Input high %d times, seconds passed: %d\n", acc, seconds);
        k_sleep(K_SECONDS(1));
    }
    
    
    
}

Running this example, we read the USB connected PIN every second, we keep track of the seconds. While USB is connected the accumulator and the number of seconds keep in sync, disconnecting the USB for a few seconds, the application keeps running because of the battery. Then we connect the USB again to get access to the console and we can verify that the accumulator has remained unchanged while the seconds passed have continued to increase. Example of output:

*** Booting Zephyr OS build v2.7.99-ncs1-1  ***
Power off POC started
Input value: 1
Input high 1 times, seconds passed: 1
Input value: 1
Input high 2 times, seconds passed: 2
Input value: 1
Input high 3 times, seconds passed: 3
Input value: 1
Input high 4 times, seconds passed: 4
Input value: 1
Input high 5 times, seconds passed: 5
Input value: 1
Input high 6 times, seconds passed: 6
Input value: 1
Input high 7 times, seconds passed: 7
[Disconnected]
[Connected]
Input value: 1
Input high 9 times, seconds passed: 15
Input value: 1
Input high 10 times, seconds passed: 16
Input value: 1
Input high 11 times, seconds passed: 17

This verifies that power detection is working. Now for the switch off/wake up part. In the example we were given, we find nowhere how to link the input event to a "wake up callback", nevertheless, if we uncomment  these lines from the POC example:

    // k_sleep(K_SECONDS(1));
    // pm_power_state_force(0u, (struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0});

And run it , the unit does switch off, but when disconnecting and connecting power again, it keeps being off (remember that power is maintained through all the process thanks to the battery)

Our question is, how to instruct the device to wake up or reboot upon input activation?

Thank you.

Xavier

  • Hello Xavier,

    I will have to get back to you next week, due to the upcoming holiday.

    Regards,

    Elfving

  • Hello again Xavier,

    Nice testing!

    In the example we were given, we find nowhere how to link the input event to a "wake up callback"

    Right, when using the lowest power state "PM_STATE_SOFT_OFF" there is no need for it. The contents of system(CPU and memory) will not be preserved, so the system will be restarted as if from an initial power-up and kernel boot either way. 

    If you'd want a wake-up callback you could always go for another power state, but I got the impression that you wanted to do a reboot either way? The documentation on the sample offers some more info on eg. RAM retention, in case that is relevant for you.

    Our question is, how to instruct the device to wake up or reboot upon input activation?

    I will have to get back to you on this, as I have some concerns here.

    Btw, what NCS version are you using?

    Regards,

    Elfving

  • Hello again, 

    When it comes to checking the voltage in order to enter sleep mode, the best way to proceed depends on if you are using a regulator or not. If you aren't, you can measure the voltage using the %XVBAT command. If you are using a regulator, you would have to create a voltage divider and measure that lower voltage using the ADC. (Its common to then use a mosfet along with the voltage divider, to stop too much current being wasted). 

    The wake-up is a bit harder, as you need to notice the increased voltage in order to reboot. For this you would have to create an additional external circuit that can create a jump to a logical one, and feed that to the GPIO.

    Regards,

    Elfving

  • I see.

    We have been testing a bit from our side, it seems like the shutdown left the system in an inconsistent state because sometimes, after shutdown, it woke up upon cable connection but sometimes didn't.

    In the end what worked for us is to shut down the modem before and to give it some time to shutdown, these is the shutdown sequence that we are using right now and seems to be working fine:

                nrf_gpio_cfg_input(POWER_DETECTION_GPIO_PIN, NRF_GPIO_PIN_NOPULL);
                nrf_gpio_cfg_sense_set(POWER_DETECTION_GPIO_PIN, NRF_GPIO_PIN_SENSE_HIGH);
                LOG_INF("Batterylow, about to sleep");
                LOG_INF("Power off modem");
                lte_lc_offline();
                lte_lc_power_off();
                k_sleep(K_SECONDS(5)); //We need to give the modem time to shut down
                LOG_INF("Power off DEVICE");
                pm_power_state_force(0u, (struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0});
                k_sleep(K_SECONDS(5)); //Trigger the shutdown by sleeping

    With this sequence we do get a system shutdown and a reliable wake up upon usb cable connection (which is connected to a GPIO).

  • XavierN said:

    We have been testing a bit from our side, it seems like the shutdown left the system in an inconsistent state because sometimes, after shutdown, it woke up upon cable connection but sometimes didn't.

    Yeah that might be correct. When turning off the modem, it will start off by disconnecting from the network. This might take some time, potentially 5 seconds if that is what you've arrived at. During this time it won't be able to go into system OFF - and won't be able to wake up either. So I don't think it is in an inconsistent state per se, just not in PM_STATE_SOFT_OFF. I believe the modem can give a callback when it completed, but I am not sure about this.

    Btw, is the USB power connected to the GPIO, or VDD line which is additionally connected to USB power? Ie., does the GPIO pin you use for wake-up jump from 3V to 5V when you connect USB?

    Regards,

    Elfving

Related