This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

NCS v2.4.0: low power by example

Dear Support team,

I'm involved in the activity to migrate to NCS a project already developed & successfuly tested with using nRF52 SDK v17.1.0, over the custom board initially designed.

That custom board is based on nRF52832_xxAA, battery powered, equipped with an inertial sensor from STM (MEMS) over SPI0, and a 8Mbit flash memory over SPI1, plus some LEDs and one button. The original .dts file is contained in the folder "<ncs_path>\v2.4.0\zephyr\boards\arm\nrf52dk_nrf52832" successfully overlayed for what concerns the custom I/O mapping. Indeed, everything is working fine without MCUBOOT (I'll add it as a final step when everything will be fixed), until I decided to check the power absorbment from the battery that reported around 150 microAmps in "idle" mode (advertising active and the whole system waiting for events).

As I expect an absorbment from 10 to 20 microAmp, I decided to start from the beginning: the "empty" main as reported below:

int main(void)
{
   while(1)
      NRF_POWER->SYSTEMOFF = 1;

   return 0;
}

This "empty" main reports 30.0 microAmps (NCS) against the 0.30 microAmps reported by the same "empty" main in the APP built with SDK v17.1.0, anyone could tell me whats's possibly wrong ?


PS: "CONFIG_SERIAL=n" has been applied already as many posts seeemed to be resolutive, also in the overlay "&uart0" is stated as "disabled".

PS #2: already included and built some examples from zephyr/samples/bluetooth (only advertising just to remain basic) and I never saw an absorbment less than 100 microAmps, therefore I can't exclude the extension nRF Connect for VSCode, as it's common to all test made so far

  • Hi,

     

    Could you try setting the /CSN pins for these sensors to the inactive? 

    If the SPI Flash is enabled, could you try setting it to a suspended state before entering systemoff?

    dev = DEVICE_DT_GET(DT_NODELABEL(my_device));
    pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);

     

    Kind regards,

    Håkon

  • Dear Hakon,

    thank you for your prompt reply.

    You got the point, indeed, even if no modules were compiled other than "main.c", there was CONFIG_SPI=y in prj.conf still enabled therefore your doubt about SPI initialized before main() was correct. Now the absorbment is back to 0.3 microAmps as reported from my multimeter (see picture attached).

    Let me take advantage of your availability to ask you a working example of pm_device_action_run() so that I can understand the correct approach to save power when no resource are needed.

    thank you so much for now

    regards, Paolo

  • Dear Paolo,

     

    I'm glad to hear that you got it working as intended.

    pzuck said:
    Let me take advantage of your availability to ask you a working example of pm_device_action_run() so that I can understand the correct approach to save power when no resource are needed.

    I would recommend that you check out other threads on this forum, by searching around for that specific API (or CONFIG_PM_DEVICE):

     NRF5340 power management 

     Un-Initializing I2C/TWI at runtime on nrf5340 with NCS SDK 1.9.1 

     

    The documentation can also be very helpful here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/pm/device_runtime.html

     

    Kind regards,

    Håkon

  • Dear Hakon,

    I'm struggling with the understanding of low power mode in Zephyr, once completed my APP that uses SPI the absorbment doesn't vary altough many attempts to introduce what reported here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/pm/device_runtime.html

    Therefore I decided to build a very basic sample "blinky" and measuring the current absorption with PPK2 starting with the original version (wave 1) and after adding "CONFIG_SPI=y" in prj.conf (wave2).

    Regarding wave1: why I see many spikes with 20 ms interval only when the LED is on ?

    Regarding wave 2: why the spikes are present also when LED is OFF taking more than 30 microAmps even if SPI is not used ?

    thank you

    regards, Paolo

    blinky/src/main.c

    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/spi.h>
    
    /* 1000 msec = 1 sec */
    #define SLEEP_TIME_MS   1000
    
    /* The devicetree node identifier for the "led0" alias. */
    #define LED0_NODE DT_NODELABEL(led_red)
    
    /*
     * A build error on this line means your board is unsupported.
     * See the sample documentation for information on how to fix this.
     */
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    
    int main(void)
    {
    	if (!gpio_is_ready_dt(&led))
    	{
    		return 0;
    	}
    
    	int ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
    	if (ret < 0)
    		return 0;
    
    	while (1) 
    	{
    		ret = gpio_pin_toggle_dt(&led);
    		if (ret < 0)
    			return 0;
    		
    		k_msleep(SLEEP_TIME_MS);
    	}
    	
    	return 0;
    }
    

    wave1:

    wave2:

    overlay file:

    &pinctrl {
    	spi0_default: spi0_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 17)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 16)>,
    				<NRF_PSEL(SPIM_MISO, 0, 15)>;
    		};
    	};
    
    	spi0_sleep: spi0_sleep {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 17)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 16)>,
    				<NRF_PSEL(SPIM_MISO, 0, 15)>;
    			low-power-enable;
    		};
    	};
    
    	spi1_default: spi1_default {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 7)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 6)>,
    				<NRF_PSEL(SPIM_MISO, 0, 3)>;
    		};
    	};
    
    	spi1_sleep: spi1_sleep {
    		group1 {
    			psels = <NRF_PSEL(SPIM_SCK, 0, 7)>,
    				<NRF_PSEL(SPIM_MOSI, 0, 6)>,
    				<NRF_PSEL(SPIM_MISO, 0, 3)>;
    			low-power-enable;
    		};
    	};
    };
    
    &spi0 {
    	//compatible = "nordic,nrf-spi";
    	status = "okay";
    	cs-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
    	spi0_cs: spi0_cs@0 {
    		reg = <0>;
    	};
    };
    
    &spi1 {
    	//compatible = "nordic,nrf-spi";
    	cs-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
    	spi1_cs: spi1_cs@0 {
    		reg = <0>;
    	};
    };
    
    

  • Hi,

     

    In both scenarios, you are sourcing the external LED, which will cause current to flow through the nRF itself.

    If you instead just set a GPIO (no load on it), it will not give you these spikes.

     

    The spikes is due to a specific "regulator refresh mode", where the nRF will sample the voltage and if it dips beneath a minimum voltage, it will charge up an external capacitor on your design, causing the 2-3 mA in-rush that you're seeing.

     

    When you set CONFIG_SPI=y, could you check the state of CONFIG_SPI_NOR at this time?

     

    Kind regards,

    Håkon

Related