Power consumption too high with zephyr

Hello,

I'm experiencing high current consumption with Zephyr OS. I'm using SDK 3.1.0 and the device still draws about 900 µA, and I don't know why.
Although I have a custom board for the main development, for the power consumption tests I'm using an nRF52840 DK board.

I have enabled the power management feature in prj.conf with: CONFIG_PM_DEVICE

Here is my prj.conf : 

CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y
CONFIG_TICKLESS_KERNEL=y
CONFIG_GPIO=y
CONFIG_CRC=y
CONFIG_POWEROFF=y
CONFIG_HWINFO=y

CONFIG_NCS_SAMPLES_DEFAULTS=y
#CONFIG_DK_LIBRARY=y
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_UART_CONSOLE=n

CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="FREEDOM"
CONFIG_BT_MAX_CONN=2
CONFIG_BT_SMP=y
CONFIG_BT_MAX_PAIRED=8

CONFIG_BT_GATT_AUTO_SEC_REQ=y
CONFIG_BT_FIXED_PASSKEY=y

CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y

# Enable bonding
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y
CONFIG_SETTINGS_RUNTIME=y
CONFIG_SETTINGS_NVS=y

CONFIG_BT_DIS=y
CONFIG_BT_DIS_SETTINGS=y
CONFIG_BT_DIS_STR_MAX=32
CONFIG_BT_DIS_PNP=n
CONFIG_BT_DIS_MODEL=""
CONFIG_BT_DIS_MANUF=""
CONFIG_BT_DIS_SERIAL_NUMBER=y
CONFIG_BT_DIS_FW_REV=y
CONFIG_BT_DIS_HW_REV=y
CONFIG_BT_DIS_SW_REV=y
CONFIG_BT_DIS_SERIAL_NUMBER_STR="123456789abcdef"
CONFIG_BT_DIS_FW_REV_STR="0.0.0"
CONFIG_BT_DIS_HW_REV_STR="0.0.0"
CONFIG_BT_DIS_SW_REV_STR="0.0.0"

# Enable MCUboot bootloader build in the application
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="priv.pem"
# Include MCUMGR and its dependencies in the build
CONFIG_NCS_SAMPLE_MCUMGR_BT_OTA_DFU=y
#CONFIG_MCUMGR_TRANSPORT_BT_AUTHEN=y

CONFIG_BT_EXT_ADV=y
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
CONFIG_BT_DEVICE_NAME_DYNAMIC=n
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=100

# CONFIG_BT_GATT_AUTO_UPDATE_MTU=y
CONFIG_BT_L2CAP_TX_MTU=247
#CONFIG_BT_CTLR_PHY_2M=y
#CONFIG_BT_USER_PHY_UPDATE=y


CONFIG_MODBUS=y
#CONFIG_MODBUS_RAW_ADU=y
#CONFIG_MODBUS_ROLE_CLIENT=y

CONFIG_PARTITION_MANAGER_ENABLED=y

CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FS_LITTLEFS_BLK_DEV=y
#CONFIG_FS_LITTLEFS_FMP_DEV=n
CONFIG_FS_LITTLEFS_FC_HEAP_SIZE=8192
CONFIG_FS_LITTLEFS_CACHE_SIZE=512
#CONFIG_FS_LITTLEFS_LOOKAHEAD_SIZE=2048

CONFIG_DISK_ACCESS=y
CONFIG_DISK_DRIVERS=y
CONFIG_DISK_DRIVER_RAM=y

CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC=y
CONFIG_CLOCK_CONTROL_NRF_K32SRC_XTAL=n
CONFIG_MULTITHREADING=y

CONFIG_HEAP_MEM_POOL_SIZE=30000

# Enable binary descriptors
#CONFIG_BINDESC=y

# Enable definition of binary descriptors
#CONFIG_BINDESC_DEFINE=y

# Enable default build time binary descriptors
#CONFIG_BINDESC_DEFINE_BUILD_TIME=y
#CONFIG_BINDESC_BUILD_DATE_TIME_STRING=y

# Enable file system commands
CONFIG_MCUMGR_GRP_FS=y
CONFIG_MCUMGR_GRP_FS_DL_CHUNK_SIZE_LIMIT=y
CONFIG_MCUMGR_GRP_FS_DL_CHUNK_SIZE=200

# Enable the storage erase command.
CONFIG_MCUMGR_GRP_ZBASIC=y
CONFIG_MCUMGR_GRP_ZBASIC_STORAGE_ERASE=y
# Optionally force the file system to be recreated
#CONFIG_APP_WIPE_STORAGE=y
# fs_dirent structures are big.
CONFIG_MAIN_STACK_SIZE=2500
CONFIG_BT_RX_STACK_SIZE=2500
CONFIG_BT_HCI_TX_STACK_SIZE=4096
CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE=6000

# Let __ASSERT do its job
CONFIG_DEBUG=y

CONFIG_INIT_STACKS=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_MPU_STACK_GUARD=n
CONFIG_STACK_SENTINEL=y
CONFIG_THREAD_MONITOR=y
CONFIG_THREAD_NAME=y

# CONFIG_PM_SINGLE_IMAGE=y  # or CONFIG_PM_MULTI_IMAGE if you use MCUboot
CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y

#CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
#CONFIG_PM_PARTITION_REGION_SETTINGS_STORAGE_EXTERNAL=y
#CONFIG_PM_PARTITION_REGION_NVS_STORAGE_EXTERNAL=y

CONFIG_SPI=n                # We don’t use Zephyr’s abstraction
#CONFIG_SPI_NOR=y
#CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
#CONFIG_NORDIC_QSPI_NOR=y
#CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
#CONFIG_NRFX_SPIM=y         # Enables global use of SPIM (base for SPIM2)
#CONFIG_NRFX_SPIM1=y        # We want SPIM2 in low-level (NRFX)
CONFIG_NRFX_SPIM2=y         # We want SPIM2 in low-level (NRFX)
#CONFIG_NRFX_GPIOTE=y

CONFIG_GPIO=y
CONFIG_NFCT_PINS_AS_GPIOS=y
#CONFIG_LOG_DEFAULT_LEVEL=4
#CONFIG_WATCHDOG=n

CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_UART_INTERRUPT_DRIVEN=n

CONFIG_SYS_HEAP_RUNTIME_STATS=y      # required to get heap stats

CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_CONN_RSSI=y
CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y

CONFIG_RESET_ON_FATAL_ERROR=y
#CONFIG_FAULT_DUMP=2         # Print more info on exceptions
#CONFIG_EXCEPTION_DEBUG=y   # More verbose debug (useful in dev)

CONFIG_TINYCRYPT=y
CONFIG_TINYCRYPT_AES=y
CONFIG_TINYCRYPT_AES_CTR=y

CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y
CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK=y

CONFIG_GPIO_AS_PINRESET=y

my   .dtsi : 

&pinctrl {

	uart1_default: uart1_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 17)>;
		};
		group2 {
			psels = <NRF_PSEL(UART_RX, 0, 14)>;
			bias-pull-up;
		};
	};

	uart1_sleep: uart1_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 17)>,
				<NRF_PSEL(UART_RX, 0, 14)>;
			low-power-enable;
		};
	};
/*
	spi2_default: spi2_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 11)>,
				<NRF_PSEL(SPIM_MOSI, 0, 8)>,
				<NRF_PSEL(SPIM_MISO, 0, 7)>;
		};
	};

	spi2_sleep: spi2_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 11)>,
				<NRF_PSEL(SPIM_MOSI, 0, 8)>,
				<NRF_PSEL(SPIM_MISO, 0, 7)>;
			low-power-enable;
		};
	};
*/
};

my    .dts : 

/dts-v1/;
#include <nordic/nrf52840_qfaa.dtsi>
#include "ngtble-pinctrl.dtsi"

/ {
	model = "Nordic NGT BLE NRF52840";
	compatible = "teledyne,ngtble";

	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,ieee802154 = &ieee802154;
	};

	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
	};
};

&gpiote {
	status = "okay";
};

&gpio0 {
	status = "okay";
};

&gpio1 {
	status = "okay";
};

&uart1 {
	compatible = "nordic,nrf-uarte";
	status = "okay";
	current-speed = <9600>;
	pinctrl-0 = <&uart1_default>;
	pinctrl-1 = <&uart1_sleep>;
	pinctrl-names = "default", "sleep";
};

&flash0 {

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

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 DT_SIZE_K(48)>;
		};
		
		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0x0000c000 DT_SIZE_K(432)>;
		};

		slot1_partition: partition@78000 {
			label = "image-1";
			reg = <0x00078000 DT_SIZE_K(432)>;
		};

		lfs2_partition: partition@E4000 {
            label = "lfs2";
            reg = <0x000E4000 DT_SIZE_K(104)>;
        };

		storage_partition: partition@fe000 {
			label = "storage";
			reg = <0x000fe000 DT_SIZE_K(2)>;
		};
	};
};

my app.overlay : 

 / {
     chosen {
         /*nordic,pm-ext-flash = &mx25r16;*/
     };
     
    fstab {
        compatible = "zephyr,fstab";
        
        lfs3: lfs3 {
            compatible = "zephyr,fstab,littlefs";
            mount-point = "/int1";
            partition = <&int_storage_1>;
            //automount;
            read-size = <16>;
            prog-size = <16>;
            cache-size = <64>;
            lookahead-size = <32>;
            block-cycles = <512>;
        };
    };

    ramdisk0: ramdisk  {
        compatible = "zephyr,ram-disk";
        status = "okay";
        disk-name = "RAM";
        sector-size = <512>;
        sector-count = <160>;
    };
 };

&flash0 {

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

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x00000000 DT_SIZE_K(48)>;
		};

		slot0_partition: partition@c000 {
			label = "image-0";
			reg = <0x0000c000 DT_SIZE_K(432)>;
		};

		slot1_partition: partition@78000 {
			label = "image-1";
			reg = <0x00078000 DT_SIZE_K(432)>;
		};

		int_storage_1: partition@E4000 {
            label = "int_part_1";
            reg = <0x000E4000 DT_SIZE_K(104)>;
        };

		storage_partition: partition@fe000 {
			label = "storage";
			reg = <0x000fe000 DT_SIZE_K(2)>;
		};
	};
};

&uart1 {
	status = "okay";
	current-speed = <9600>;
	pinctrl-0 = <&uart1_default>;
	pinctrl-1 = <&uart1_sleep>;
	pinctrl-names = "default", "sleep";
    
    modbus0 {
		compatible = "zephyr,modbus-serial";
		status = "okay";
	};
};

&spi2 {
    status = "disabled";
};

my main.c file : 

int main(void)
{


	for (;;) {		

		}

		k_sleep(K_MSEC(1000));
	}
}

When I load a project with the old SDK 17.1.0, I’m able to reach a power consumption of around 1 µA, so I’m pretty sure this is not a hardware issue.

I check in debug that the WFI instruction was called.

If you have any suggestions, please feel free to share.

Regards,

Aurélien

Related