NRF52832 low power mode / sleep mode [ZephyrsOS]

Hi guys,

I'm working on this project which was basically a migration from STM32 to the nordic NRF52832 in order to enable the BLE beaconing mode.

It has been a challenge to make all of the project to run on ZephyrsOS. However, the code is now at a state where all the previous functions are validated and working. I'm now missing the low power consumption mode. This is a battery powered project so the target consumption in idle state should be around 100uA.

Hardware details:

 - Custom PCB

 - LIS3DHTR accelerometer always powered

 - EG915 Quectel with Mosfet for turning it off

 - TDC1000 with Mosfet for turning it off

 - MCP9700Ax-E/TO temperature sensor with Mosfet for turning it off

Requirements:

 - Every 24H run the TDC1000 and MCP9700 and get a sample. Publish the sample using the EG915 and go back to sleep.

 - Use LIS3DHTR to force a sample if high motion detected (interrupt pin), but this can wait.

I've read this article that explains the difference between system_off and system_on and for the NRF52832 I think I don't have other option than going with the system_on. System_off requires external pins to wake up (no timer based option) so it will not work for the 24H requirement. However, as a comparison I've tested the example system_off with my device_tree overlay:

nrf52dk_nrf52832.overlay

// To get started, press Ctrl+Space (or Option+Esc) to bring up the completion menu and view the available nodes.

// You can also use the buttons in the sidebar to perform actions on nodes.
// Actions currently available include:

// * Enabling / disabling the node
// * Adding the bus to a bus
// * Removing the node
// * Connecting ADC channels

// For more help, browse the DeviceTree documentation at https: //docs.zephyrproject.org/latest/guides/dts/index.html
// You can also visit the nRF DeviceTree extension documentation at https: //docs.nordicsemi.com/bundle/nrf-connect-vscode/page/guides/ncs_configure_app.html#devicetree-support-in-the-extension


/ {
	aliases {
		modem-uart = &uart0;
		modem = &modem;
		gasket-temp-sensor = &gasket_temp_sensor;
		ambient-temp-sensor = &ambient_temp_sensor;
		enable-level-sense = &enable_level_sense;
		enable-modem-power = &enable_modem_power;
		modem-pwr-key = &modem_pwr_key;
		modem-rst-key = &modem_rst_key;
		dbg-rx = &dbg_rx;
		dbg-tx = &dbg_tx;
		tdc1000-en = &tdc1000_en_pin;
		tdc1000-rst = &tdc1000_rst_pin;
		tdc1000-trigger = &tdc1000_trigger_pin;
		tdc1000-chsel = &tdc1000_chsel_pin;
		tdc1000-start = &tdc1000_start_pin;
		tdc1000-stop = &tdc1000_stop_pin;
		tdc1000-errb = &tdc1000_errb_pin;
	};

	gasket_temp_sensor: gasket_temp_sensor {
		compatible = "microchip,mcp970x";
		status = "okay";
		family = "MCP9700/9700A";
		io-channels = <&adc 0>;
		friendly-name = "Gasket Temperature";
	};

	ambient_temp_sensor: ambient_temp_sensor {
		compatible = "microchip,mcp970x";
		status = "okay";
		family = "MCP9700/9700A";
		io-channels = <&adc 1>;
		friendly-name = "Ambient Temperature";
	};

	zephyr,user {
		io-channels = <&adc 2>;
		io-channel-names = "battery_voltage";
	};

	enable_level_sense: enable_level_sense {
		compatible = "power-switch";
		gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
	};

	enable_modem_power: enable_modem_power {
		compatible = "power-switch";
		gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
	};

	modem_pwr_key: modem_pwr_key {
		compatible = "power-switch";
		gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
	};

	modem_rst_key: modem_rst_key {
		compatible = "power-switch";
		gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_en_pin: tdc1000_en_pin {
		compatible = "power-switch";
		gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_rst_pin: tdc1000_rst_pin {
		compatible = "power-switch";
		gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_trigger_pin: tdc1000_trigger_pin {
		compatible = "power-switch";
		gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_chsel_pin: tdc1000_chsel_pin {
		compatible = "power-switch";
		gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_start_pin: tdc1000_start_pin {
		compatible = "input-switch";
		gpios = <&gpio0 29 (GPIO_PULL_DOWN)>;
	};

	tdc1000_stop_pin: tdc1000_stop_pin {
		compatible = "input-switch";
		gpios = <&gpio0 28 (GPIO_PULL_DOWN)>;
	};

	tdc1000_errb_pin: tdc1000_errb_pin {
		compatible = "input-switch";
		gpios = <&gpio0 30 0>;
	};

	leds {
		compatible = "gpio-leds";

		dbg_rx: dbg_rx {
			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
		};

		dbg_tx: dbg_tx {
			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
		};
	};
};

&gpio0 {
	status = "okay";
};

&adc {
	status = "okay";
	#address-cells = <1>;
	#size-cells = <0>;

	channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1_3";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS,10)>;
		zephyr,input-positive = <NRF_SAADC_AIN0>;
		zephyr,resolution = <12>; /* 0.055C per ADC step */
		zephyr,oversampling = <2>; /* x4 */
	};

	channel@1 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1_3";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS,10)>;
		zephyr,input-positive = <NRF_SAADC_AIN1>;
		zephyr,resolution = <12>; /* 0.055C per ADC step */
		zephyr,oversampling = <2>; /* x4 */
	};

	channel@2 {
		reg = <2>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_VDD_1_4";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,input-positive = <NRF_SAADC_AIN2>;
		zephyr,resolution = <12>;
		zephyr,oversampling = <2>; /* x4 */
		zephyr,vref-mv = <825>;
	};
};

&i2c0 {
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default", "sleep";
	lis3dh@19 {
		compatible = "st,lis2dh";
		reg = <0x19>;
		irq-gpios = <&gpio0 5 GPIO_INT_WAKEUP>;
		disconnect-sdo-sa0-pull-up;
	};
};

&spi1 {
	status = "okay";
	cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
	pinctrl-0 = <&spi1_default>;
	pinctrl-1 = <&spi1_sleep>;
	pinctrl-names = "default", "sleep";
	gendev: gendev@0 {
		status = "okay";
		compatible = "vnd,spi-device";
		reg = <0>;
		spi-max-frequency = <1600000>;
		label = "GenDev";
	};
};

&uart0 {
	status = "okay";
	pinctrl-0 = <&uart0_default>;
	pinctrl-1 = <&uart0_sleep>;
	pinctrl-names = "default", "sleep";

	modem: modem {
		status = "disabled";
		compatible = "quectel,bg9x";
		mdm-power-gpios = <&gpio0 23 0>;
		mdm-reset-gpios = <&gpio0 19 0>;
	};
};

&rtc0 {
	status = "okay";
};

&pwm0 {
	status = "okay";
	pinctrl-0 = <&pwm0_default>;
	pinctrl-1 = <&pwm0_sleep>;
	pinctrl-names = "default", "sleep";

	tdc_clk_in: tdc_clk_in {
		status = "okay";
		compatible = "pwm-clock";
		#clock-cells = <1>;
		pwms = <&pwm0 0 PWM_HZ(4000000) PWM_POLARITY_NORMAL>;
	};
};

&pinctrl {
	i2c0_default: i2c0_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 0, 13)>, <NRF_PSEL(TWIM_SDA, 0, 12)>;
		};
	};

	i2c0_sleep: i2c0_sleep {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 0, 13)>, <NRF_PSEL(TWIM_SDA, 0, 12)>;
			low-power-enable;
		};
	};

	spi1_default: spi1_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 22)>,
			        <NRF_PSEL(SPIM_MOSI, 0, 20)>,
			        <NRF_PSEL(SPIM_MISO, 0, 17)>;
		};
	};

	spi1_sleep: spi1_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 22)>,
			        <NRF_PSEL(SPIM_MOSI, 0, 20)>,
			        <NRF_PSEL(SPIM_MISO, 0, 17)>;
			low-power-enable;
		};
	};

	pwm0_default: pwm0_default {
		group1 {
			psels = <NRF_PSEL(PWM_OUT0, 0, 27)>; // TDC_CLK_8MHZ
		};
	};

	pwm0_sleep: pwm0_sleep {
		group1 {
			psels = <NRF_PSEL(PWM_OUT0, 0, 27)>; // TDC_CLK_8MHZ
			low-power-enable;
		};
	};

	uart0_default: uart0_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 16)>, <NRF_PSEL(UART_RX, 0, 15)>;
		};
	};

	uart0_sleep: uart0_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 16)>, <NRF_PSEL(UART_RX, 0, 15)>;
			low-power-enable;
		};
	};
};

&reg {
	regulator-initial-mode = <NRF5X_REG_MODE_LDO>;
};

// &gpiote0 {
//     interrupts = <6 1>;
// };


and I got a average consumption of around 40uA.

When I try the system_off in my project it doesn't work and the consumption is around 6mA.

nrf52kbd_nrf52832.overlay

// To get started, press Ctrl+Space (or Option+Esc) to bring up the completion menu and view the available nodes.

// You can also use the buttons in the sidebar to perform actions on nodes.
// Actions currently available include:

// * Enabling / disabling the node
// * Adding the bus to a bus
// * Removing the node
// * Connecting ADC channels

// For more help, browse the DeviceTree documentation at https: //docs.zephyrproject.org/latest/guides/dts/index.html
// You can also visit the nRF DeviceTree extension documentation at https: //docs.nordicsemi.com/bundle/nrf-connect-vscode/page/guides/ncs_configure_app.html#devicetree-support-in-the-extension


/ {
	aliases {
		modem-uart = &uart0;
		modem = &modem;
		gasket-temp-sensor = &gasket_temp_sensor;
		ambient-temp-sensor = &ambient_temp_sensor;
		enable-level-sense = &enable_level_sense;
		enable-modem-power = &enable_modem_power;
		modem-pwr-key = &modem_pwr_key;
		modem-rst-key = &modem_rst_key;
		dbg-rx = &dbg_rx;
		dbg-tx = &dbg_tx;
		tdc1000-en = &tdc1000_en_pin;
		tdc1000-rst = &tdc1000_rst_pin;
		tdc1000-trigger = &tdc1000_trigger_pin;
		tdc1000-chsel = &tdc1000_chsel_pin;
		tdc1000-start = &tdc1000_start_pin;
		tdc1000-stop = &tdc1000_stop_pin;
		tdc1000-errb = &tdc1000_errb_pin;
	};

	gasket_temp_sensor: gasket_temp_sensor {
		compatible = "microchip,mcp970x";
		status = "okay";
		family = "MCP9700/9700A";
		io-channels = <&adc 0>;
		friendly-name = "Gasket Temperature";
	};

	ambient_temp_sensor: ambient_temp_sensor {
		compatible = "microchip,mcp970x";
		status = "okay";
		family = "MCP9700/9700A";
		io-channels = <&adc 1>;
		friendly-name = "Ambient Temperature";
	};

	zephyr,user {
		io-channels = <&adc 2>;
		io-channel-names = "battery_voltage";
	};

	enable_level_sense: enable_level_sense {
		compatible = "power-switch";
		gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
	};

	enable_modem_power: enable_modem_power {
		compatible = "power-switch";
		gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>;
	};

	modem_pwr_key: modem_pwr_key {
		compatible = "power-switch";
		gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>;
	};

	modem_rst_key: modem_rst_key {
		compatible = "power-switch";
		gpios = <&gpio0 19 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_en_pin: tdc1000_en_pin {
		compatible = "power-switch";
		gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_rst_pin: tdc1000_rst_pin {
		compatible = "power-switch";
		gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_trigger_pin: tdc1000_trigger_pin {
		compatible = "power-switch";
		gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_chsel_pin: tdc1000_chsel_pin {
		compatible = "power-switch";
		gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
	};

	tdc1000_start_pin: tdc1000_start_pin {
		compatible = "input-switch";
		gpios = <&gpio0 29 (GPIO_PULL_DOWN)>;
	};

	tdc1000_stop_pin: tdc1000_stop_pin {
		compatible = "input-switch";
		gpios = <&gpio0 28 (GPIO_PULL_DOWN)>;
	};

	tdc1000_errb_pin: tdc1000_errb_pin {
		compatible = "input-switch";
		gpios = <&gpio0 30 0>;
	};

	leds {
		compatible = "gpio-leds";

		dbg_rx: dbg_rx {
			gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
		};

		dbg_tx: dbg_tx {
			gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
		};
	};
};

&gpio0 {
	status = "okay";
};

&adc {
	status = "okay";
	#address-cells = <1>;
	#size-cells = <0>;

	channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1_3";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS,10)>;
		zephyr,input-positive = <NRF_SAADC_AIN0>;
		zephyr,resolution = <12>; /* 0.055C per ADC step */
		zephyr,oversampling = <2>; /* x4 */
	};

	channel@1 {
		reg = <1>;
		zephyr,gain = "ADC_GAIN_1_3";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS,10)>;
		zephyr,input-positive = <NRF_SAADC_AIN1>;
		zephyr,resolution = <12>; /* 0.055C per ADC step */
		zephyr,oversampling = <2>; /* x4 */
	};

	channel@2 {
		reg = <2>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_VDD_1_4";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,input-positive = <NRF_SAADC_AIN2>;
		zephyr,resolution = <12>;
		zephyr,oversampling = <2>; /* x4 */
		zephyr,vref-mv = <825>;
	};
};

&i2c0 {
	status = "okay";
	pinctrl-0 = <&i2c0_default>;
	pinctrl-1 = <&i2c0_sleep>;
	pinctrl-names = "default", "sleep";
	lis3dh@19 {
		compatible = "st,lis2dh";
		reg = <0x19>;
		irq-gpios = <&gpio0 5 GPIO_INT_WAKEUP>;
		disconnect-sdo-sa0-pull-up;
	};
};

&spi1 {
	status = "okay";
	cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
	pinctrl-0 = <&spi1_default>;
	pinctrl-1 = <&spi1_sleep>;
	pinctrl-names = "default", "sleep";
	gendev: gendev@0 {
		status = "okay";
		compatible = "vnd,spi-device";
		reg = <0>;
		spi-max-frequency = <1600000>;
		label = "GenDev";
	};
};

&uart0 {
	status = "okay";
	pinctrl-0 = <&uart0_default>;
	pinctrl-1 = <&uart0_sleep>;
	pinctrl-names = "default", "sleep";

	modem: modem {
		status = "disabled";
		compatible = "quectel,bg9x";
		mdm-power-gpios = <&gpio0 23 0>;
		mdm-reset-gpios = <&gpio0 19 0>;
	};
};

&rtc0 {
	status = "okay";
};

&pwm0 {
	status = "okay";
	pinctrl-0 = <&pwm0_default>;
	pinctrl-1 = <&pwm0_sleep>;
	pinctrl-names = "default", "sleep";

	tdc_clk_in: tdc_clk_in {
		status = "okay";
		compatible = "pwm-clock";
		#clock-cells = <1>;
		pwms = <&pwm0 0 PWM_HZ(4000000) PWM_POLARITY_NORMAL>;
	};
};

&pinctrl {
	i2c0_default: i2c0_default {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 0, 13)>, <NRF_PSEL(TWIM_SDA, 0, 12)>;
		};
	};

	i2c0_sleep: i2c0_sleep {
		group1 {
			psels = <NRF_PSEL(TWIM_SCL, 0, 13)>, <NRF_PSEL(TWIM_SDA, 0, 12)>;
			low-power-enable;
		};
	};

	spi1_default: spi1_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 22)>,
			        <NRF_PSEL(SPIM_MOSI, 0, 20)>,
			        <NRF_PSEL(SPIM_MISO, 0, 17)>;
		};
	};

	spi1_sleep: spi1_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 22)>,
			        <NRF_PSEL(SPIM_MOSI, 0, 20)>,
			        <NRF_PSEL(SPIM_MISO, 0, 17)>;
			low-power-enable;
		};
	};

	pwm0_default: pwm0_default {
		group1 {
			psels = <NRF_PSEL(PWM_OUT0, 0, 27)>; // TDC_CLK_8MHZ
		};
	};

	pwm0_sleep: pwm0_sleep {
		group1 {
			psels = <NRF_PSEL(PWM_OUT0, 0, 27)>; // TDC_CLK_8MHZ
			low-power-enable;
		};
	};

	uart0_default: uart0_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 16)>, <NRF_PSEL(UART_RX, 0, 15)>;
		};
	};

	uart0_sleep: uart0_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 16)>, <NRF_PSEL(UART_RX, 0, 15)>;
			low-power-enable;
		};
	};
};

&reg {
	regulator-initial-mode = <NRF5X_REG_MODE_LDO>;
};

// &gpiote0 {
//     interrupts = <6 1>;
// };

prj.conf

CONFIG_SENSOR=y
CONFIG_LIS2DH=y
CONFIG_I2C=y
CONFIG_GPIO=y

CONFIG_LOG=n
CONFIG_USE_SEGGER_RTT=n
CONFIG_CONSOLE=n
CONFIG_RTT_CONSOLE=n
CONFIG_UART_CONSOLE=n

CONFIG_SERIAL=y
CONFIG_UART_INTERRUPT_DRIVEN=y

CONFIG_ADC=y
CONFIG_MCP970X=y

CONFIG_BT=y
CONFIG_PWM=y
CONFIG_CLOCK_CONTROL=y
CONFIG_SPI=y

CONFIG_WDT_LOG_LEVEL_INF=n
CONFIG_WATCHDOG=n
CONFIG_WDT_DISABLE_AT_BOOT=n

CONFIG_REQUIRES_FLOAT_PRINTF=y
CONFIG_BT_DEVICE_NAME="Beacon"

CONFIG_MAIN_THREAD_PRIORITY=10

CONFIG_LIS2DH_TRIGGER_GLOBAL_THREAD=y
CONFIG_LIS2DH_ACCEL_RANGE_2G=y
CONFIG_LIS2DH_OPER_MODE_LOW_POWER=y
CONFIG_LIS2DH_ODR_1=y
CONFIG_LIS2DH_ODR_RUNTIME=y

CONFIG_NRFX_TIMER0=y
CONFIG_NRFX_PPI=y

CONFIG_PM_DEVICE=y
CONFIG_POWEROFF=y

main.c

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/usb/usbd.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/logging/log.h>
// #include <zephyr/drivers/watchdog.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/poweroff.h>
#include <zephyr/sys/util.h>

#include "accel_reader.h"
#include "tank_reader.h"
#include "cellular_handler.h"
#include "ble_handler.h"

/****************************************************** Asserts *******************************************************/

/****************************************************** Defines *******************************************************/
#define SLEEP_TIME_FOR_FLUSHING_MS 5000
// #define WDT_OPT 0
/****************************************************** Typedefs ******************************************************/

/***************************************************** Constants ******************************************************/
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
const struct device *const sensor = DEVICE_DT_GET_ANY(st_lis2dh);

/***************************************************** Variables ******************************************************/

/*********************************************** Internal Declarations ************************************************/

/***************************************************** Functions ******************************************************/

int main(void)
{
    while (1)
    {
        int err;
        /* Power down the ACCEL reader device */
        err = pm_device_action_run(sensor, PM_DEVICE_ACTION_SUSPEND);
        if (err) {
            LOG_ERR("pm_device_action_run() failed (%d)\n", err);
        }

        sys_poweroff();
    }

    return 0;
}

/************************************************* Internal Functions *************************************************/

What could be the issue here? The only difference are the proj.conf files and the fact that in my project I'm using the nrf52kbd_nrf52832.overlay instead of the nrf52dk_nrf52832.overlay. Btw, I'm using the PPK2 to do the measurements. 

Also, any suggestions/advices on how can I achieve the best low power performance?

Thank you for the ongoing support,

Best regards,

Fernando Fontes

Parents
  • Hi

    How do you verify that you're in an idle mode on your end here. How do you measure current consumption, and can you confirm that a debugger isn't attached and running or that debug mode isn't enabled, as that would cause pin P0.18 to be active. 

    Have you checked the signal on P0.18 when seeing this high current consumption to see what's happening on that pin. Try setting the P0.18 to an idle level and see if that affects the current consumption.

    Can you upload the zephyr.dts file of these two builds here so we can see what the differences are. Please also upload the memory map for reference.

    Best regards,

    Simon

Reply
  • Hi

    How do you verify that you're in an idle mode on your end here. How do you measure current consumption, and can you confirm that a debugger isn't attached and running or that debug mode isn't enabled, as that would cause pin P0.18 to be active. 

    Have you checked the signal on P0.18 when seeing this high current consumption to see what's happening on that pin. Try setting the P0.18 to an idle level and see if that affects the current consumption.

    Can you upload the zephyr.dts file of these two builds here so we can see what the differences are. Please also upload the memory map for reference.

    Best regards,

    Simon

Children
  • Hi Simon,

    Thank you for the ongoing support.

    The example prints a message every time it goes into sleep mode. I was trusting that. Then I moved to my original setup and I’ve disabled the logs in the conf.proj file. 

    I’m using the power profiler kit 2 in voltage mode to measure the power consumption. The programmer is not connected. I’ve this difference from 50uA to 6mA when the SPI is enabled with the CS pin on the P0.18 port.

    Tomorrow I will be on the lab and I will measure the pin to try to get more insights on what is happening when it goes to sleep mode. 

    I will also try to upload the files later today or tomorrow. 

    So, there is nothing obvious regarding the P0.18 that could be causing this?

    Best regards, 

    Fernando Fontes

  • Ok, so I've been playing around with the gpio configuration by calling the gpio_pin_configure_dt() and this was what I got:

    gpio_pin_configure_dt(&cs_gpio, GPIO_INPUT):

    gpio_pin_configure_dt(&cs_gpio,GPIO_OUTPUT_INACTIVE):

    I've measured with the multimeter and oscilloscope and when the P0.18 is configured as GPIO_OUTPUT_INACTIVE the voltage is around 2V and with GPIO_INPUT is 0V. It doesn't make sense for GPIO_OUTPUT_INACTIVE to make the voltage around 2V right?

    CS line is only connecting the MCU and the TDC1000. Nothing else connected on that line.

    I also don't have any clue from where does this 1mA pulses are coming from. At the beginning I thought it was the LIS3D accelerometer, but that are the 400uA. Disabling the accel by setting ODR to 0 gives me this:

     Is the CPU waking up?

    With the following code, I can fix the 6mA issue, since I force the pin to go to input mode before sleeping.

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <inttypes.h>
    #include <stdio.h>
    
    #include <zephyr/device.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/sensor.h>
    #include <zephyr/kernel.h>
    #include <zephyr/pm/device.h>
    #include <zephyr/sys/poweroff.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/pm/device.h>
    
    #define SPI_NODE DT_NODELABEL(spi1)
    
    static const struct device *spi_dev = DEVICE_DT_GET(SPI_NODE);
    static const struct gpio_dt_spec cs_gpio = GPIO_DT_SPEC_GET_BY_IDX(SPI_NODE, cs_gpios, 0);
    const struct device *const sensor = DEVICE_DT_GET_ANY(st_lis2dh);
    
    int main(void)
    {
    	struct sensor_trigger trig;
        int rc;
    
        trig.type = SENSOR_TRIG_DATA_READY;
        trig.chan = SENSOR_CHAN_ACCEL_XYZ;
    
    	// turn off
        struct sensor_value odr = {
            .val1 = 0,
        };
    
        rc = sensor_attr_set(sensor, trig.chan,
                             SENSOR_ATTR_SAMPLING_FREQUENCY,
                             &odr);
    
    	pm_device_action_run(spi_dev, PM_DEVICE_ACTION_SUSPEND);
    
    	gpio_pin_configure_dt(&cs_gpio, GPIO_INPUT);
    
    	sys_poweroff();
    
    	return 0;
    }
    

    I'm also attaching the zephyr.dts and zephyr.map of this build.

    7725.zephyr.map1057.zephyr.dts

    Best regards,

    Fernando Fontes

Related