Hi there,
I'm trying to achieve the system OFF current consumption on the nRF52-DK which is stated in the datasheet as 0.3uA with no RAM retention.
I'm running the nRF5x system off demo, using the nRF Connect SDK v2.4.2, measuring current using the PPK2.
I've attached the main function which is part of the sample, as well as a PPK2 screenshot when the device is in it's off state (according to the sample code). The baseline current consumption appears to be sitting around 1-2uA, with regular spikes up to ~20uA every ~260ms.
Do you why these spikes are occurring, how to eliminate them, and reduce the current consumption during the off state to ~0.3uA?
int main(void)
{
int rc;
const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
if (!device_is_ready(cons)) {
printk("%s: device not ready.\n", cons->name);
return 0;
}
printk("\n%s system off demo\n", CONFIG_BOARD);
if (IS_ENABLED(CONFIG_APP_RETENTION)) {
bool retained_ok = retained_validate();
/* Increment for this boot attempt and update. */
retained.boots += 1;
retained_update();
printk("Retained data: %s\n", retained_ok ? "valid" : "INVALID");
printk("Boot count: %u\n", retained.boots);
printk("Off count: %u\n", retained.off_count);
printk("Active Ticks: %" PRIu64 "\n", retained.uptime_sum);
} else {
printk("Retained data not supported\n");
}
/* Configure to generate PORT event (wakeup) on button 1 press. */
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);
printk("Busy-wait %u s\n", BUSY_WAIT_S);
k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC);
printk("Busy-wait %u s with UART off\n", BUSY_WAIT_S);
rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);
k_busy_wait(BUSY_WAIT_S * USEC_PER_SEC);
rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME);
printk("Sleep %u s\n", SLEEP_S);
k_sleep(K_SECONDS(SLEEP_S));
printk("Sleep %u s with UART off\n", SLEEP_S);
rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);
k_sleep(K_SECONDS(SLEEP_S));
rc = pm_device_action_run(cons, PM_DEVICE_ACTION_RESUME);
printk("Entering system off; press BUTTON1 to restart\n");
if (IS_ENABLED(CONFIG_APP_RETENTION)) {
/* Update the retained state */
retained.off_count += 1;
retained_update();
}
/* Above we disabled entry to deep sleep based on duration of
* controlled delay. Here we need to override that, then
* force entry to deep sleep on any delay.
*/
pm_state_force(0u, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0});
/* Now we need to go sleep. This will let the idle thread runs and
* the pm subsystem will use the forced state. To confirm that the
* forced state is used, lets set the same timeout used previously.
*/
k_sleep(K_SECONDS(SLEEP_S));
printk("ERROR: System off failed\n");
while (true) {
/* spin to avoid fall-off behavior */
}
return 0;
}
