Power Profiler Kit II with nRF52833

OS: Windows 10

NCS: 2.0.0

nRF Connect for Desktop: v3.12.0

Power Profiler: v3.5.3

We are starting work on battery optimization on our product.  I setup the PPK2 with my nRF52833 DK to learn the PPK2 and implementing nRF52 low power modes in the Zephyr world. 

I am running the Zephyr "System Off" demo on the DK.  https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.0.0/zephyr/samples/boards/nrf/system_off/README.html

I setup the PPK2 with the DK and ran the demo, but I am seeing really odd results.  As you can see, while the demo is going through it's stages, the PPK2 data logger looks correct.

However, approximately three seconds after then nRF52833 goes into "system off" mode, the PPK2 data logger displays the below, until a button 1 or reset button press.

Since I am new to nRF52 low power modes in Zephyr (long history with the old SDK) and this is the first time using the PPK2, I am unclear what I am seeing.  I have attached main.c from the  "system off" project for reference.  Does anyone have an explanation for what I am seeing?  Thanks in advance.

.

/*
 * Copyright (c) 2019 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <zephyr.h>
#include <device.h>
#include <init.h>
#include <pm/pm.h>
#include <pm/device.h>
#include <pm/policy.h>
#include <soc.h>
#include "retained.h"
#include <hal/nrf_gpio.h>

#define CONSOLE_LABEL DT_LABEL(DT_CHOSEN(zephyr_console))

#define BUSY_WAIT_S 2U
#define SLEEP_S 2U

/* Prevent deep sleep (system off) from being entered on long timeouts
 * or `K_FOREVER` due to the default residency policy.
 *
 * This has to be done before anything tries to sleep, which means
 * before the threading system starts up between PRE_KERNEL_2 and
 * POST_KERNEL.  Do it at the start of PRE_KERNEL_2.
 */
static int disable_ds_1(const struct device *dev)
{
	ARG_UNUSED(dev);

	pm_policy_state_lock_get(PM_STATE_SOFT_OFF);
	return 0;
} 

SYS_INIT(disable_ds_1, PRE_KERNEL_2, 0);

void main(void)
{
	int rc;
	const struct device *cons = device_get_binding(CONSOLE_LABEL);

	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 */
	}
}

Parents Reply
  • Hello, sorry for the late reply. Had to test this myself and discuss with a colleague. 

    The spikes that you see are refresh mode spikes which are completely fine. The average current consumption is what you want to look at. 3,35µA is a little high, you should see more down to 0,6-0,8µA. Can you try to switch SW6 to nRF Only?

    I tested this here aswell:

      

    The signal is "noisy" but this can be due to the USB connection. If you have an external power source to connect External Supply (P21) it should give less noise. 

    Kind regards,
    Øyvind

Children
No Data
Related