Help Reducing Sleep Current While Keeping RTC Active

I’m working on a device using a Nordic chip and the following setup:

  • nRF Connect SDK: v2.5.2
  • Toolchains: v2.7.0

We need to minimize current consumption during sleep while keeping the RTC active so it can wake the device at the appropriate time. Currently, we’re measuring around 446 µA in sleep mode, which is significantly higher than expected.

Here are some key points regarding our setup and what we’ve tried so far:

  1. We disable all peripherals (UART, SPI, sensor, etc.) before entering sleep.
  2. We only need the RTC to remain powered to wake the device.
  3. We do not need to retain anything in RAM during sleep.

Despite these measures, the sleep current remains higher than our target. Could you please advise on how to further reduce the sleep current? Are there additional configurations or hardware considerations we should address to achieve lower power consumption levels, ideally closer to typical values for this chip?

Thank you very much for your assistance.

Best regards,


void deep_sleep_state()
{
	LOG_INF("Deep Sleep State");

	uint64_t seconds_to_deep_sleep = 600;

	LOG_INF("Fail count: %u", fail_count);
	LOG_INF("Sleeping for: %llu seconds", seconds_to_deep_sleep);

	// Check if necessary
	//k_sleep(K_MSEC(3000));

	bluetooth_disable();

	if( set_rtc_alarm(seconds_to_deep_sleep) != 0 ) {
		// TODO: Handle nap error
	}

	int rc;
	const struct device *const console_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
	const struct device *const uart1_dev = DEVICE_DT_GET(DT_NODELABEL(uart1));
	const struct device *const sensor_dev = DEVICE_DT_GET_ANY(st_lis2dh);
	const struct device *const spi3_dev = DEVICE_DT_GET(DT_NODELABEL(spi3));

	rc = pm_device_action_run(console_dev, PM_DEVICE_ACTION_SUSPEND);
	rc = pm_device_action_run(uart1_dev, PM_DEVICE_ACTION_SUSPEND);
	rc = pm_device_action_run(sensor_dev, PM_DEVICE_ACTION_SUSPEND);
	flash_suspend();
	rc = pm_device_action_run(spi3_dev, PM_DEVICE_ACTION_SUSPEND);

	// disable pins
	const struct device* gpio0_dev = device_get_binding("gpio@50000000"); // gpio 0

	gpio_pin_configure(gpio0_dev, 12, (GPIO_INPUT | GPIO_PULL_DOWN)); // gpio 0.12 - DS18EXT
	gpio_pin_configure(gpio0_dev, 13, (GPIO_INPUT | GPIO_PULL_DOWN)); // gpio 0.13 - LED
	gpio_pin_configure(gpio0_dev, 26, (GPIO_INPUT | GPIO_PULL_DOWN)); // gpio 0.26 - DS18INT
	gpio_pin_configure(gpio0_dev, 28, (GPIO_INPUT | GPIO_PULL_DOWN)); // gpio 0.28 - CS sensor
	gpio_pin_configure(gpio0_dev, 29, (GPIO_INPUT | GPIO_PULL_DOWN)); // gpio 0.29 - Miso sensor

	k_sem_reset(&rtc_alarm_sem);
	k_sem_take(&rtc_alarm_sem, K_FOREVER);

	rc = pm_device_action_run(console_dev, PM_DEVICE_ACTION_RESUME);

	LOG_WRN("Wokend up - Rebooting");

	// Check if necessary
	//k_sleep(K_MSEC(5000));

	sys_reboot(SYS_REBOOT_COLD);
}

Edit:
Additionally, we want to mention that we are using a custom board with our own hardware design. For your reference, we have attached the relevant .dts and .dtsi files below. If you spot any issues or necessary changes in the device tree configuration that could help lower power consumption, please let us know.

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

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>
#include "imachine_nrf52840-pinctrl.dtsi"
#include <zephyr/dt-bindings/input/input-event-codes.h>

/ {
	model = "IMACHINE_NRF52840";
	compatible = "nordic,imachine-nrf52840";

	chosen {
		zephyr,console = &uart0;
		zephyr,shell-uart = &uart0;
		zephyr,uart-mcumgr = &uart0;
		zephyr,bt-mon-uart = &uart0;
		zephyr,bt-c2h-uart = &uart0;
		zephyr,sram = &sram0;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
		zephyr,settings-partition = &settings_partition;
	};

	buttons {
		compatible = "gpio-keys";
		hall_effect_sensor: hall_effect_sensor {
			gpios = <&gpio0 3 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Sensor hall";
			zephyr,code = <INPUT_KEY_0>;
		};
		// TODO: a ser validado com o Andre -sugestao do Mauro P0.18
		reset_button: reset_button {
			gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Reset";
			zephyr,code = <INPUT_KEY_1>;
		};
	};

	leds {
		compatible = "gpio-leds";
		reg_control_gpio: reg_control_gpio {
			gpios =
				<&gpio0 27 (GPIO_ACTIVE_LOW | GPIO_PULL_DOWN)>;
		};

		led: led {
			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
		};

	};

	aliases {
		hallsensor = &hall_effect_sensor;
		resetbutton = &reset_button;
		regcontrolgpio = &reg_control_gpio;
		watchdog0 = &wdt;
		led = &led;
	};

	w1: w1 {
		compatible = "zephyr,w1-gpio";
		gpios = <&gpio0 26 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN | GPIO_PULL_UP)>;
	};
};

&flash0 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x0 0xc000>;
		};
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0xc000 0x71000>;
		};
		slot1_partition: partition@7d000 {
			label = "image-1";
			reg = <0x7d000 0x71000>;
		};

		/* Partition used to store Bluetooth config data- 8kB */
		settings_partition: partition@ee000 {
			label = "settings";
			reg = <0xee000 0x2000>;
		};
		scratch_partition: partition@f0000 {
			label = "image-scratch";
			reg = <0xf0000 0xa000>;
		};

		/* Partition used to store accelerometer data - 24kB */
		storage_partition: partition@fa000 {
			label = "storage";
			reg = <0xfa000 0x6000>;
		};
	};
};

&gpio0 {
	status = "okay";
};

&gpio1 {
	status = "okay";
};

&gpiote {
	status = "okay";
};

&uart0 {
	compatible = "nordic,nrf-uarte";
	status = "okay";
	current-speed = <115200>;
	pinctrl-0 = <&uart0_default>;
	pinctrl-1 = <&uart0_sleep>;
	pinctrl-names = "default", "sleep";
};

&spi3 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi3_default>;
	pinctrl-1 = <&spi3_sleep>;
	pinctrl-names = "default","sleep";
	cs-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;

	lis2dh12_imachine@0 {
		status = "okay";
		compatible = "lis2_imachine";
		reg = <0x0>;
		spi-max-frequency = <10000000>;
		// INT1 = P0.31, INT2 = P0.05
		irq-gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>, <&gpio0 5 GPIO_ACTIVE_HIGH>;
	};
};

&uart1 {
	status = "okay";
	current-speed = <115200>;
	pinctrl-0 = <&uart1_default>;
	pinctrl-1 = <&uart1_sleep>;
	pinctrl-names = "default", "sleep";
};

&i2c0 {
	status = "disabled";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default","sleep";
};

&rtc2 {
	status = "okay";
	prescaler = <256>;
};

&wdt {
	status = "okay";
};

&timer1 {
	status = "okay";
};


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

 &pinctrl {
	// Console UART
	uart0_default: uart0_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 6)>; // Originally P0.8 - changed to use UART instead of RTT
		};
		group2 {
			psels = <NRF_PSEL(UART_RX, 0, 8)>; // Originally P0.11 - changed to use UART instead of RTT
			bias-pull-up;
		};
	};

	uart0_sleep: uart0_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 6)>, // Originally P0.8 - changed to use UART instead of RTT
				<NRF_PSEL(UART_RX, 0, 8)>; // Originally P0.11 - changed to use UART instead of RTT
			low-power-enable;
		};
	};

	uart1_default: uart1_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 1, 7)>;
		};
		group2 {
			psels = <NRF_PSEL(UART_RX, 1, 6)>;
		};
	};

	uart1_sleep: uart1_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 1, 7)>,
				<NRF_PSEL(UART_RX, 1, 6)>;
			low-power-enable;
		};
	};

	// LIS2DH12
	// SD0 - MISO
	// SDA - MOSI

	spi3_default: spi3_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
				<NRF_PSEL(SPIM_MOSI, 0, 30)>,
				<NRF_PSEL(SPIM_MISO, 0, 29)>;
		};
	};

	spi3_sleep: spi3_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 2)>,
				<NRF_PSEL(SPIM_MOSI, 0, 30)>,
				<NRF_PSEL(SPIM_MISO, 0, 29)>;
			low-power-enable;
		};
	};

	i2c0_default: i2c0_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 4)>,
					<NRF_PSEL(TWIM_SCL, 0, 7)>; // Originally P0.6 - changed to use UART instead of RTT
		};
	};

	i2c0_sleep: i2c0_sleep {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 4)>,
					<NRF_PSEL(TWIM_SCL, 0, 7)>; // Originally P0.6 - changed to use UART instead of RTT
			low-power-enable;
		};
	};

};
Related