Coap Client SED low power

I am using:

nRF52840
NRF Connect SDK 1.9.1
Custom hardware

My project is based on the Coap Client example with mtd overlay added  and is running in SED mode. I am using ot_coap_client_utils.c, so that I may send confirmable messages. 

Using the PPK2, I am measuring a baseline current over 2 mA.  I tried it also on the DK and got similar results. On the DK I used the PPK2 in Source mode and connected it to the Battery input.  With my custom hardware I use it in Ampere mode, with a lab power supply.

This will be a battery operated product.  How do I find what is drawing this current?

The small blip is a blinking LED, and the tall spike is a data request (every 3 seconds).

The external hardware is all very low current and are not accessed most of the time.  The main() function initializes everything then calls k_sleep(K_FOREVER).  I think I have disabled everything I'm not using.  So why is there still 2 mA all the time?

dts file:

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

/dts-v1/;
#include <nordic/nrf52840_qiaa.dtsi>

/ {
	model = "My_Sensor";
	compatible = "mycompany,my-sensor";

	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,entropy = &rng;
		/* From: https://github.com/simon-iversen/sdk-zephyr/blob/serial_dfu_ext_flash_hello_world/samples/hello_world/boards/nrf52840dk_nrf52840.overlay
         *  for using external flash for DFU */
         nordic,pm-ext-flash = &mx25r64;
	};

	leds {
		compatible = "gpio-leds";
		led0: led_0 {
			gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
			label = "Red LED 0";
		};
		ledbootloader0: bootloader_led0 {
			gpios = <&gpio0 31 GPIO_ACTIVE_LOW>;
			label = "Bootloader LED 0";
		};

		led1: led_1 {
			gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;
			label = "Green LED 1";
		};
		led2: led_2 {
			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
			label = "Blue LED 2";
		};
	};

	buttons {
		compatible = "gpio-keys";
		button0: button_0 {
			gpios = <&gpio0 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "Push button switch 0";
		};

		button1: button_1 {
			gpios = <&gpio1 11 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "EXTERNALn";
		};

	}; 

	gpioout {
		compatible = "gpio-leds";
		speaker: gpioout_0 {
			gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
			label = "SPEAKER";
		};
	};

	gpioin {
		compatible = "gpio-keys";

		hdcint0: hdcint_0 {
			gpios = <&gpio1 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
			label = "INT0";  
		};
		lisint1: lisint_1 {
			gpios = <&gpio1 15 (GPIO_ACTIVE_LOW)>;		
			label = "INT1";  
		};
		lisint2: lisint_2 {
			gpios = <&gpio1 14 (GPIO_ACTIVE_LOW)>;		
			label = "INT2";  
		};

		cfg0: cfg_0 {
			gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>;
			label = "CFG0";
		};
		cfg1: cfg_1 {
			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
			label = "CFG1";
		};
		cfg2: cfg_2 {
			gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>;
			label = "CFG2";
		};
		cfg3: cfg_3 {
			gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
			label = "CFG3";
		};
		cfg4: cfg_4 {
			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
			label = "CFG4";
		};
		cfg5: cfg_5 {
			gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>;
			label = "CFG5";
		};
		cfg6: cfg_6 {
			gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
			label = "CFG6";
		};
	};

    pwmleds {
        compatible = "pwm-leds";
        pwm_speaker0: pwm_speaker_0 {
            pwms = <&pwm0 44>;
			status = "okay";
        };
	};	

	/* These aliases are provided for compatibility with samples */
	aliases {
		led0 = &led0;
		led1 = &led1;
		led2 = &led2;
		sw0 = &button0;
		sw1 = &button1;
		lis-int1 = &lisint1;
		lis-int2 = &lisint2;
		bootloader-led0 = &led0;
		pwm-speaker0 = &pwm_speaker0;
	};
};

&pwm0 {
	status = "okay";
	ch0-pin = <44>;
	//ch0-inverted;			// Don't invert, 0% duty cycle will be low
};

&adc {
	status = "okay";
};

/ {
	vbatt {
		compatible = "voltage-divider";
		io-channels = <&adc 0>;
		output-ohms = <1000000>;
		full-ohms = <(2000000 + 1000000)>;
	};
};

&gpiote {
	status = "disabled";
};

&gpio0 {
	status = "okay";
};

&gpio1 {
	status = "okay";
};

&uart0 {
	compatible = "nordic,nrf-uarte";
	//status = "okay";
	status = "disabled";
	current-speed = <115200>;
	tx-pin = <34>;		/* pins are swapped on schematic Rev 6 */
	rx-pin = <40>;
	rx-pull-up;
/*    rts-pin = <5>; */
/*    cts-pin = <7>; */

	cts-pull-up;
};

&uart1 {
	status = "disabled";
};


&i2c0 {
	compatible = "nordic,nrf-twim";
	status = "okay";
	sda-pin = <26>;
	scl-pin = <27>;
	clock-frequency = < I2C_BITRATE_FAST >;
};


&i2c1 {
	/* Cannot be used together with spi1. */	
   status = "disabled";
};

 &spi0 {
	status = "disabled";
 };

 &spi1 {
	status = "disabled";
 };

 &spi2 {
	status = "disabled";
 };

 &spi3 {
	status = "disabled";
 };

 &timer0 {
	status = "disabled";
 };
 &timer1 {
	status = "disabled";
 };
 &timer2 {
	status = "disabled";
 };
 &timer3 {
	status = "disabled";
 };
 &timer4 {
	status = "disabled";
 };
 &temp {
	status = "disabled";
 };
 

 &qspi {
	status = "okay";
	sck-pin = <16>;
	io-pins = <24>, <22>, <23>, <21>;
	csn-pins = <15>;
	mx25r64: mx25r6435f@0 {
		compatible = "nordic,qspi-nor";
		reg = <0>;
		/* MX25R64 supports only pp and pp4io */
		writeoc = "pp4io";
		/* MX25R64 supports all readoc options */
		readoc = "read4io";
		sck-frequency = <8000000>;
		label = "MX25R64";
		jedec-id = [c2 28 17];
		sfdp-bfp = [
			e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 68 44
			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
		];
		size = <67108864>;
		has-dpd;
		t-enter-dpd = <10000>;
		t-exit-dpd = <35000>;
	};
};
 

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

		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x0 0x10000>;
		};
		slot0_partition: partition@10000 {
			label = "image-0";
			reg = <0x10000 0xE8000>;
		};
		// slot1_partition: partition@7e000 {
		// 	label = "image-1";
		// 	reg = <0x7e000 0x72000>;
		// };
		// scratch_partition: partition@f0000 {
		// 	label = "image-scratch";
		// 	reg = <0xf0000 0xa000>;
		// };

		//cert_partition: partition@F5000 {
        //    label = "dev-certs";
        //    reg = <0x000F5000 0x00003000>;
        //};

		storage_partition: partition@f8000 {
			label = "storage";
			reg = <0xf8000 0x8000>;
		};
	};
};

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

        slot1_partition: partition@0 {
            label = "image-1";
            reg = <0x00000000 0x0000E8000>;
        };
        scratch_partition: partition@e8000 {
            label = "image-scratch";
            reg = <0x0000E8000 0x0000E8000>;
        };
		download_partition: partition@1d0000 {
			label = "image-download";
			reg = <0x001D0000 0x00010000>;
		};
    };
};

prj.conf

#
# Copyright (c) 2020 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# nRF board library
CONFIG_DK_LIBRARY=y

# Enable CoAP utils and CoAP protocol
#CONFIG_COAP_UTILS=y
# Enable OpenThread CoAP support API
CONFIG_OPENTHREAD_COAP=y
CONFIG_OPENTHREAD_COAP_OBSERVE=y


# Configure sample logging setting
#CONFIG_LOG=y
#CONFIG_COAP_CLIENT_LOG_LEVEL_DBG=y
#CONFIG_COAP_CLIENT_UTILS_LOG_LEVEL_DBG=y
#CONFIG_COAP_UTILS_LOG_LEVEL_DBG=y
#CONFIG_OPENTHREAD_LOG_LEVEL_NOTE=y
#CONFIG_OPENTHREAD_DEBUG=y

# Adjust log strdup settings
CONFIG_LOG_STRDUP_MAX_STRING=128

# Generic networking options
CONFIG_NETWORKING=y

# L2 OpenThread enabling
CONFIG_NET_L2_OPENTHREAD=y

# Network shell
#CONFIG_SHELL=y
#CONFIG_OPENTHREAD_SHELL=y
#CONFIG_SHELL_ARGC_MAX=26
#CONFIG_SHELL_CMD_BUFF_SIZE=416

# Enable OpenThread features set
CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER=y

# Network sockets
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_SOCKETS_POLL_MAX=4

# Thread Joiner
CONFIG_OPENTHREAD_JOINER=y
CONFIG_OPENTHREAD_JOINER_AUTOSTART=y
CONFIG_OPENTHREAD_JOINER_PSKD="M00N6BANANA"
CONFIG_OPENTHREAD_MANUAL_START=n

# Same network Master Key for client and server
#CONFIG_OPENTHREAD_NETWORKKEY="00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"

CONFIG_ASSERT=y
CONFIG_ASSERT_NO_COND_INFO=y
CONFIG_MBEDTLS_SHA1_C=n
CONFIG_FPU=y

# QSPI Flash
CONFIG_SPI=y
CONFIG_NORDIC_QSPI_NOR=y
CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096
CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16
CONFIG_FLASH=y

CONFIG_MAIN_STACK_SIZE=8192

# PWM for speaker
CONFIG_PWM=y
CONFIG_PWM_LOG_LEVEL_DBG=n

# Sensors
CONFIG_I2C=y
CONFIG_GPIO=y
#CONFIG_SENSOR=y
#CONFIG_TI_HDC=y
CONFIG_ADC=y

overlay_mtd.conf

#
# Copyright (c) 2020 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable MTD Sleepy End Device
CONFIG_OPENTHREAD_MTD=y
CONFIG_OPENTHREAD_MTD_SED=y
CONFIG_OPENTHREAD_POLL_PERIOD=3000
CONFIG_RAM_POWER_DOWN_LIBRARY=y
CONFIG_PM_DEVICE=y

# This variant requires increased system workqueue stack size
#CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=1536
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=3072

# Low Power, turn off uarts
CONFIG_SERIAL=n
CONFIG_LOG=n
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_RTT_CONSOLE=n
CONFIG_USE_SEGGER_RTT=n
CONFIG_PRINTK=n

I checked .config and confirmed that CONFIG_SERIAL is not set, nor is CONFIG_LOG.

Any help is appreciated.

Mary

  • Hi,

    Could you post the .config file and the zephyr.dts file that is generated in the build folder when you build the sample?

  • I think most of the current is from the flash device, MX25R6435.  From other posts, I saw that the CSn must be configured as gpio output and set high, but it doesn't come up that way.  I will eventually be using MCUBOOT, with externa flash as slot1.

    I created a "HelloWorld" but with this added to the prj.conf

    CONFIG_SERIAL=n
    CONFIG_PM=y
    CONFIG_PM_DEVICE=y

    I set the CSn as gpio output, and set it high.  I am now down to 121 uA, which is still too high, but there are some other devices I need to look into.

    About the QSPI flash...

    I tried adding this code to configure the CSn line.  Stepping into, then out of this function led to a odd place, where the call stack wasn't as expected.  I ended up in nf_qspi_nor.c, in functions that I did not call.  I noticed that there is support for "Anomaly 122" there.  So, what is the proper way, using ncs, to put the flash in deep power down, then reawaken it when I need to use it?  I will only use it for OTA updates.

    void flash_low_power()
    {
    	struct device *dev;
    	// eratum 122
    	// https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_122.html
    	*(volatile uint32_t *)0x40029010ul = 1ul;
        *(volatile uint32_t *)0x40029054ul = 1ul;
        nrfx_qspi_uninit();
    
    	dev = device_get_binding(QSPI_CS_DEVICE);
    	if (dev == NULL) {
    		printk("Cannot bind gpio device\r\n");
    		//return -ENODEV;
    		return;
    	}
    
    	
    	int err = gpio_pin_configure(dev, QSPI_CS_PIN, GPIO_OUTPUT);
    	gpio_pin_set(dev, QSPI_CS_PIN, 1);
    
    }

    Here are the requested files.

    my.config6320.zephyr.dts

    Mary

  • Found it.

    This code puts the flash device in deep power down, then sets the CSn output high.  

    #if (CONFIG_SPI_NOR - 0) ||				\
    	DT_NODE_HAS_STATUS(DT_INST(0, jedec_spi_nor), okay)
    #define FLASH_DEVICE DT_LABEL(DT_INST(0, jedec_spi_nor))
    #define FLASH_NAME "JEDEC SPI-NOR"
    #elif (CONFIG_NORDIC_QSPI_NOR - 0) || \
    	DT_NODE_HAS_STATUS(DT_INST(0, nordic_qspi_nor), okay)
    #define FLASH_DEVICE DT_LABEL(DT_INST(0, nordic_qspi_nor))
    #define FLASH_NAME "JEDEC QSPI-NOR"
    #elif DT_NODE_HAS_STATUS(DT_INST(0, st_stm32_qspi_nor), okay)
    #define FLASH_DEVICE DT_LABEL(DT_INST(0, st_stm32_qspi_nor))
    #define FLASH_NAME "JEDEC QSPI-NOR"
    #else
    #error Unsupported flash driver
    #endif
    
    #define QSPI_CS_DEVICE		DT_GPIO_LABEL(DT_NODELABEL(qspics), gpios)		
    #define QSPI_CS_PIN			DT_GPIO_PIN(DT_NODELABEL(qspics), gpios)
    
    
    void flash_low_power()
    {
    	const struct device *flash_dev;
    	const struct device *cs_dev;
    
    	flash_dev = device_get_binding(FLASH_DEVICE);
    
    	pm_device_action_run(flash_dev, PM_DEVICE_ACTION_SUSPEND);
    
    	cs_dev = device_get_binding(QSPI_CS_DEVICE);
    	if (cs_dev == NULL) {
    		printk("Cannot bind gpio device\r\n");
    		//return -ENODEV;
    		return;
    	}
    	
    	int err = gpio_pin_configure(cs_dev, QSPI_CS_PIN, GPIO_OUTPUT);
    	gpio_pin_set(cs_dev, QSPI_CS_PIN, 1);
    
    }
    

    Mary

Related