High Power Consumption - System On

Hi,
We are currently migrating our nrf5 SDK code to NCS (2.2.0 currently) on a custom nrf52833 board.

While in system off we have been able to achieve our expected sub-uA average consumption (between 0.5 and 0.8), we have been unable to reach our system on value of 3.3 uA, and are stuck on around 5.8 uA average.

Our overlay fragment is below:

&uart0 {
	status = "disabled";
};


&pinctrl {

    // acc
    status = "okay";
    spi1_default: spi1_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 4)>,
                <NRF_PSEL(SPIM_MOSI, 0, 11)>,
                <NRF_PSEL(SPIM_MISO, 1, 9)>;
        };
    };

    spi1_sleep: spi1_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 4)>,
                <NRF_PSEL(SPIM_MOSI, 0, 11)>,
                <NRF_PSEL(SPIM_MISO, 1, 9)>;
                
            low-power-enable;
        };
    };
};


&spi1 {
    compatible = "nordic,nrf-spi";
    status = "okay";
    clock-frequency = <0x4000000>;
    overrun-character = < 255 >;
    cs-gpios = < &gpio0 5 GPIO_ACTIVE_LOW >, < &gpio0 15 GPIO_ACTIVE_LOW >;
};

&spi0 {
    status = "disabled";
};

&adc {
	status="okay";
	compatible = "nordic,nrf-saadc";
	#io-channel-cells = <1>;
};

prj.conf:

CONFIG_GPIO=y
CONFIG_BT=y
CONFIG_BT_DEBUG_LOG=n
CONFIG_BT_SMP=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DIS=y
CONFIG_BT_LIM_ADV_TIMEOUT=60
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_CTLR_CRYPTO=y
CONFIG_BT_HOST_CCM=n
CONFIG_BT_MAX_PAIRED=5

CONFIG_BOOTLOADER_MCUBOOT=y

CONFIG_BT_CTLR_PHY_2M=n
CONFIG_BT_CTLR_PHY_CODED=n

CONFIG_BT_USER_DATA_LEN_UPDATE=n
CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251

CONFIG_BT_AUTO_DATA_LEN_UPDATE=y
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=y

CONFIG_BT_HCI=y 
CONFIG_BT_CTLR_LE_ENC=n
CONFIG_BT_SMP_SC_ONLY=n

CONFIG_BT_BONDABLE=y
CONFIG_BT_SMP_ENFORCE_MITM=n
CONFIG_BT_SMP_APP_PAIRING_ACCEPT=n

CONFIG_BT_DEBUG_SMP=n

CONFIG_NRFX_RTC2=y

CONFIG_SPI=y
CONFIG_SPI_NRFX=y

CONFIG_NFCT_PINS_AS_GPIOS=y


## in prod - set all below to false
CONFIG_LOG=y
CONFIG_UART_CONSOLE=n
CONFIG_LOG_BACKEND_UART=n
CONFIG_PRINTK=y
CONFIG_LOG_PRINTK=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_RTT_CONSOLE=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y


CONFIG_BT_DIS_FW_REV=y
CONFIG_BT_DIS_FW_REV_STR=""
CONFIG_BT_DIS_HW_REV=y
CONFIG_BT_DIS_HW_REV_STR=""
CONFIG_BT_DIS_MANUF=""
CONFIG_BT_DIS_MODEL="RTOS"
CONFIG_BT_DIS_SERIAL_NUMBER=y
CONFIG_BT_DIS_SERIAL_NUMBER_STR=""
CONFIG_BT_DIS_SETTINGS=y

CONFIG_SETTINGS_RUNTIME=y
CONFIG_SETTINGS_CUSTOM=y
CONFIG_SETTINGS=y
CONFIG_BT_SETTINGS=y

CONFIG_HARDWARE_DEVICE_CS_GENERATOR=y

CONFIG_BT_DIS_PNP=n
CONFIG_BT_BAS=y
CONFIG_BT_HRS=n
CONFIG_BT_ATT_PREPARE_COUNT=40
CONFIG_BT_DEVICE_NAME=""
CONFIG_BT_DEVICE_APPEARANCE=833

CONFIG_ADC=y
CONFIG_ADC_NRFX_SAADC=y
CONFIG_NRFX_SAADC=y
CONFIG_BOARD_ENABLE_DCDC=y

CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_NVS=y
CONFIG_SETTINGS_NVS=y
CONFIG_FLASH_MAP=y
CONFIG_FCB=n

CONFIG_TEMP_NRF5=n
CONFIG_TEMP_NRF5_MPSL=n
CONFIG_UART_NRFX=n
CONFIG_BOOT_BANNER=n

A few things we have tried:

  • Turning off logs - no change.
  • Turning off all unused peripherals from the original nrf52833dk.dts file in the overlay - no change.
  • Setting states of the CPU using PM - all states besides SOFT_OFF yield no change to power consump.

What are we missing?

Thanks!
Roi

Parents
  • What is the main application doing? Since you achieved lower currents in nRF5SDK, it most likely is a configuration issue rather than any hw/sw issue.

    But it is hard for me to narrow down the problem with the information given. Can you please provide me the whole application project so that I can try to debug that here?

    Also there might be little more overhead in kernel tick handling which might consume little more power than the bate metal examples. I have not benchmarked how much more but should be that big difference like you are observing.

  • Hi,
    I cannot upload the code itself, but I can outline what is running when I measure these levels:

    • Within main loop:
      • Checking boolean flags - in 99% of the cases the work portion does not happen:
        			if(flag1 || flag2 || flag3){
        				//work
        			}
      • k_msleep(100);
    • Async during main loop:
      • Two buttons awaiting interrupts - awaiting on GPIO_INT_LEVEL_ACTIVE
      • Single shot timer is running, and is restarted every minute:
        //definition
        K_TIMER_DEFINE(sleep_timer, sleep_timer_elapsed, sleep_timer_stopped);
        
        // start logic
        k_timer_start(&sleep_timer, K_MINUTES(1), K_NO_WAIT);
      • RTC2 is running with 511 prescaler:
        const nrfx_rtc_t rtc = NRFX_RTC_INSTANCE(2);
        
            int ret;
            nrfx_rtc_config_t config = {.prescaler = SYS_TIME_PRESCALER, .reliable = false, .tick_latency = 1,
                                        .interrupt_priority = NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY};
        
        
            ret = nrfx_rtc_init(&rtc, &config, rtc_handler);
            	if (ret < 0) {
        		return;
        	}
        	nrfx_rtc_tick_enable(&rtc, true);
            nrfx_rtc_overflow_enable(&rtc, true);
            nrfx_rtc_tick_disable(&rtc);
            nrfx_rtc_enable(&rtc);

    Thanks!

    Roi

  • Hi,
    I have attempted to turn off everything in overlay that was not turned off in build/zephyr/zephyr.dts:

    &nvic {
        status = "disabled";
    };
    
    &i2c0 {
        status = "disabled";
    };
    
    &temp {
        status = "disabled";
    };
    
    &gpiote {
        status = "disabled";
    };
    
    &timer0 {
        status = "disabled";
    };
    
    &timer1 {
        status = "disabled";
    };
    
    &timer2 {
        status = "disabled";
    };
    
    &timer3 {
        status = "disabled";
    };
    
    &timer4 {
        status = "disabled";
    };
    
    &rtc0 {
        status = "disabled";
    };
    
    &rtc1 {
        status = "disabled";
    };
    
    &ecb {
        status = "disabled";
    };
    
    &ccm {
        status = "disabled";
    };
    
    &egu0 {
        status = "disabled";
    };
    
    &egu1 {
        status = "disabled";
    };
    
    &egu2 {
        status = "disabled";
    };
    
    &egu3 {
        status = "disabled";
    };
    
    &egu4 {
        status = "disabled";
    };
    
    &egu5 {
        status = "disabled";
    };
    
    &pwm0 {
        status = "disabled";
    };
    
    &acl {
        status = "disabled";
    };
    
    &ppi {
        status = "disabled";
    };
    
    &mwu {
        status = "disabled";
    };
    
    &usbd {
        status = "disabled";
    };
    
    &uart1 {
        status = "disabled";
    };
    
    &spi3 {
        status = "disabled";
    };
    
    &wdt0 {
        status = "disabled";
    };
    
    &rng_hci {
        status = "disabled";
    };
    &ieee802154{
        status = "disabled";
    };

    The only things not disabled are:

    • FICR
    • UICR
    • Clock
    • Power
    • Radio
    • SPI1 - since we are using this for 2 peripherals
    • ADC - we use this to measure battery every X hours
    • RNG
    • RTC2 - see above
    • GPIO0
    • GPIO1
    • pinctrl

    The average power consumption remains 5.8 uA

    Thanks!

    Roi

  • For reference I have tried NCS 2.4.0 and the power consump even goes up a bit (5.9 uA average)

  • Hi,
    I thought it best to update that I also tried with a custom_board (as opposed to an overlay on nrf52833dk_nrf52833, and got the same measurements.

  • I am sorry for late reply, That power consumption does not make sense.Either you have to test this on nRF52833 DK or help me reproduce it at my desk. I do not know any ERRATA that has about 4.5uA of increased current consumption in system off mode on nRF52833.

  • Hi,

    As said above, the higher consumption is in system on only.

    System off is even slightlu better on our board on zephyr (~0.5 uA ) than on nrf5 sdk (~0.8 uA).

    Also as said - the measured 5.8 average is with a peripheral device that uses about 1.5 uA avg, but this overhead exists on our 3.3 uA measurement as well. With the peripheral device off, we acheive 1.8 uA on nrf5 sdk, but 4.3 uA on zephyr.

    Thanks!

    Roi

Reply
  • Hi,

    As said above, the higher consumption is in system on only.

    System off is even slightlu better on our board on zephyr (~0.5 uA ) than on nrf5 sdk (~0.8 uA).

    Also as said - the measured 5.8 average is with a peripheral device that uses about 1.5 uA avg, but this overhead exists on our 3.3 uA measurement as well. With the peripheral device off, we acheive 1.8 uA on nrf5 sdk, but 4.3 uA on zephyr.

    Thanks!

    Roi

Children
  • Hi,
    We have managed to get down to around 3.8 uA average by changing our sleep logic to:

    • Sleep X=70 MS every main loop
    • In addition, if there is no work to do, sleep an additional Y=600 MS every main loop.

    This seems like a high amount of sleep to us to acheive this - is this what is to be expected on zephyr?

    Thanks!

    Roi

  • In zephyr, the sleep is automatically done in the idle thread. So I am not really sure how you are forcing the sleep? 

    Making the device go to sleep in main might not be a best way to do it. It is better to use k_mssleep (if you are not using it already).'

    Also 3.8uA of current in system on sleep is not bad. How much is your goal to achieve with the RTOS and application running?

  • We are using k_msleep as you say Slight smile

    3.8 uA is great for us, but to achieve this we need to add an IDLE state sleep of 600 ms, which is what I was asking if this is standard

  • sorry for the late reply, was away for few days.

    Roiger said:
    3.8 uA is great for us, but to achieve this we need to add an IDLE state sleep of 600 ms, which is what I was asking if this is standard

    Ideally in Zephyr RTOS, if you have all threads behaving (yielding) properly, then you should not need to add additional sleep at all. You should make sure that the idle thread in the Zephyr RTOS is able to run most of the time when there is nothing else to do on your application. The only way the idle thread runs is when all the other threads in your application have yielded properly (by k_yield, k_sleep, waiting for semaphore/mutex etc).

    The fact that you need to add additional sleep outside the idle thread means that atleast one of your application thread is not yielding. I would try to plug your application to Segger SystemView and see if there are any threads that are running longer than it should without your additional sleep of 600ms.

Related