This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

~500 uA current consumed in __WFI()

Hello,

I just started 4 days ago. My project consists of two parts. The first module that I am working on should communicate with. a I2C sensor, go to sleep for 30 seconds and repeat. Current consumption is critical, as a 2200 mA 3.6V battery should last for > 1 year. I am replacing a PIC processor that only uses in the nA range in Deep Sleep. The processor is replaces, because in the Second part of this project, I will also need to communicate using BLE with another unit. 

I based my project on the TWI Sensor example, that I understand does not use a SoftDevice (SD).

I got TWI (I2C) com up and running, and I am using nrf_drv_timer_init() timer to fire an Event every 30 seconds.

Problem is that current consumption in __WFI()  is ~500 uA: Need it as low as possible (<= 10 uA). Searched for days on the forum: Nothing I have tested helps!

Program structure is roughly as follows:

You can get a copy of the whole Segger project if you need, it's no secret and is not very large, but a bit messy at this experimental stage.

main() {

// Various statements found on this forum to shut down peripherals:

   NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos);

   NRF_SAADC->ENABLE = SAADC_ENABLE_ENABLE_Disabled;

   twi_init();

   nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; // Probably not necessary: Done in sdk_config.h

   nrf_drv_timer_init(&TIMER_LED, &timer_cfg, timer_led_event_handler);

   time_ticks = nrf_drv_timer_ms_to_ticks(&TIMER_LED, time_ms);

   nrf_drv_timer_extended_compare(
     &TIMER_LED, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);

   nrf_drv_timer_enable(&TIMER_LED);

    while (true)
    {

        // Rapid blink of LED 1 twice to see that things are running (500 ms)

        nrf_drv_twi_enable(&m_twi);

        float temperature = Read_Temperature_Sensor_Temperature(writeBuffer, dataBuffer, TEMP_SENSOR_ADDR);   

        nrf_drv_twi_disable(&m_twi); // Does not seem to reduce power...       

        // // http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.Rev2.errata%2Fdita%2Ferrata%2FnRF52832%2FRev2%2Flatest%2Fanomaly_832_87.html&cp=2_1_1_0_1_24


        NRF_LOG_INFO("Temperature: " NRF_LOG_FLOAT_MARKER " C \r\n", NRF_LOG_FLOAT(temperature));
        NRF_LOG_FLUSH();

        #if (__FPU_USED == 1)
        __set_FPSCR(__get_FPSCR() & ~(0x0000009F)); // Errata had missing underscores for this call
       (void) __get_FPSCR();
       NVIC_ClearPendingIRQ(FPU_IRQn);
       
        __WFI();       

       NRF_LOG_INFO("\r\n************  After After __WFI(); ***************"); 

    } // end while 

} // end main()

Questions

1) Can you please help tip me how to reduce the current consumption

2) The project I based my example on does not use a Softdevice. I see that many examples on how to reduce current does not compile when I do not have a SoftDevice
    a) Is there a way to include SoftDevice 132 (I will use nRF52832) in an existing project?
       
     b) I have seen the guide on how to prepare the Board with a Softdevice, but I do not understand how that works:
         If I flash a SoftDevice to the Board, won't that be overwritten when I debug my program on the board, or download a hex file?

3) Using an example as a starting point gets complicated with respect to sdk_config.h once one needs to base the project on two different projects.
    Is there any tool that can Merge several sdk_config.h files? I have so far done it manually, but it takes time...


Wish

It would be nice to have a Guide that shows how to Enable / Disable every peripheral, as this seems to be a recurring question on the forum.

Parents
  • Hi,

    A current consumption of about 500 μA indicate that the high frequency clock is running, probably because a peripheral is requesting it. Therefore, you should always make sure to disable any peripherals that use the high frequency clock (which is most peripherals, except RTC, LPCOMP and a few others).

    1) You should disable peripherals (typically all except the RTC in a typical application) before going to sleep. This includes that you need to disable UART logging. For a typical SDK example all you need for it to be low power is to build the release version (in SES there is a drop-down where you select between Release and Debug) and disable logging in the projects sdk_config.h. (You should also activate the DC/DC by calling sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE) after initializing the SoftDevice but is has less of an impact).

    2a) The SoftDevice "protects" a number of system resources, so that they can only be accessed via SoftDevice APIs when the SoftDevice is enabled. Therefor you typically cannot use the same code with and without a SoftDevice. However, the legacy driver layer (SDK 15) handles this for you, so you should be able to use mostly the same code with and without a SoftDevice as long as you access HW peripherals via the SDK drivers.

    2b) The SoftDevice must be programmed to the beginning of the flash (starting with the MBR ad address 0), so you must adjust your application to start at a higher flash address when using a SoftDevice. The start address depends on the SoftDevice version and can be found in the SoftDevice release notes. You must also adjust the memory size and start address, as the SoftDevice will use some memory. This depends on the configuration. There are a number of things to remember here, so I suggest you start with the Getting Started section in the SDK documentation. You should probably also refer to this section of the SoftDevice specification in order to understand how the application communicates with the SoftDevice. Lastly I recommend you to look at the BLE examples in the SDK to see practical examples of how to use the SoftDevice. There you can also see memory layout and other project settings when using a SoftDevice.

    3) We do not have any tool for merging sdk_config.h files. You have to do it manually, copying/editing as needed.

    Regarding your wish, you typically only need to use the driver API to disable a peripheral. Most peripherals have functions called *_uninit() and *_disable().

  • Hello Einar,

    Thanks for a fast reply. However, you are talking a bit over my head at this stage (beginner)

    << Therefore, you should always make sure to disable any peripherals that use the high frequency clock (which is most peripherals, except RTC, LPCOMP and a few others).>>

    As I stated in the question: I do not know the commands to do this. I have read the docs and forums, but still do not understand what the commands are...

    Q1

    I only use TWI (I2C) and the Timer at this stage. Can you please give me the commands to disable the other peripherals?

    Q2

    You say that the SoftDevice needs to be flashed before it can be used;
    But what about the example Segger projects that use a SoftDevice: They compile and run without flashing the SoftDevice separately: I guess the SoftDevice is a part of these projects?

    How can I make a SoftDevice a part of my Project that currently does not use a SoftDevice?

Reply
  • Hello Einar,

    Thanks for a fast reply. However, you are talking a bit over my head at this stage (beginner)

    << Therefore, you should always make sure to disable any peripherals that use the high frequency clock (which is most peripherals, except RTC, LPCOMP and a few others).>>

    As I stated in the question: I do not know the commands to do this. I have read the docs and forums, but still do not understand what the commands are...

    Q1

    I only use TWI (I2C) and the Timer at this stage. Can you please give me the commands to disable the other peripherals?

    Q2

    You say that the SoftDevice needs to be flashed before it can be used;
    But what about the example Segger projects that use a SoftDevice: They compile and run without flashing the SoftDevice separately: I guess the SoftDevice is a part of these projects?

    How can I make a SoftDevice a part of my Project that currently does not use a SoftDevice?

Children
  • Hi,

    Q1. You can find information about this by referring to the documentation for the relevant drivers. For the TWIM driver: "The instance can be disabled using nrf_drv_twi_disable and uninitialized using nrf_drv_twi_uninit." For the timer driver, you have to refer to the API documentation, where you can see the following functions: nrf_drv_timer_uninit() and nrf_drv_timer_disable().

    Q2. The example SES projects are configured to automatically flash the SoftDevice for projects that use it, so you do not need to do it manually there. If you start off with an example what does not use a SoftDevice then  you either need to update the example to flash the SoftDevice for you , or you should flash it manually. See Running examples that use a SoftDevice. The easiest is to just start off with a SES project that use a SoftDevice from the SDK, as that would give you the other project configuration for free as well (memory layout configuration, required defines depending on SoftDevice etc.).

Related