Power consumption is too high

I am using the PCA10028 to connect to my board and use Segger embedded studio. I am unable to bring my power consumption below 1 mA.

To exclude my hardware from the equation, I decided to connect the EEPROM I´m using (24LC16) and one key to the PCA10028 board and use the nRF current measurement feature. I soldered a 22 Ohm resistor on R6 and loaded my program into it. 

The program is very simple: if key is ON I have BLE advertising and all runs.

If key is OFF, then I stop BLE advertising and only keep my app_timer running on RTC1. I tried also stopping the timer and the result is the same. I get 1 mA consumption.

I tried performing NRF_POWER->SYSTEMOFF = 1; instruction but the controller doesn't stop (I made an endless loop with this instruction and toggle of a LED) and the code just ignores the command and continues running, even if I don't connect the board to the PC (use then a battery for supply).

I tried also NRF_POWER->TASKS_LOWPWR = 1; but it also doesn't work.

I tried __WFE(); __SEV(); and even __WFI(); but none seams to work. 

What am I doing wrong?

  • For information, here is my main loop:

    //-------------------------------------
    /**@brief Application main function.
     */
    //-------------------------------------
    int main(void)
    {
        uint32_t err_code;
    
    // ---- Initialize ckock timer ----
        
        APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
        err_code = app_timer_create(&real_time_clock_id, APP_TIMER_MODE_REPEATED, rtc_handler);
        app_timer_start(real_time_clock_id, 32767, false);
        
    // ---- Initialize kernel timer ----
        err_code = app_timer_create(&kernel_clock_id, APP_TIMER_MODE_REPEATED, kernel_handler);
    // ----
    #ifdef USE_BLE
        ble_stack_init();
        gap_params_init();
        services_init();
        advertising_init();
        conn_params_init();
    #endif
    //    configure_ram_retention();
    #ifdef DEBUG_PRINT
        printf("\r\nUART Start after RESET!\r\n");
        printf("BT Disconnected");
        printf("\r\n");
    #endif
        InitIo();
        CheckWarmCold();      // chek if EEPROM was initialized
        ClearRxString();      // clear BLE receive buffer
        f_key_was_on = 0;
        f_power_is_on = 0;    
        InitIo();             // configure ports
        for (;;)
          {
          power_manage();
          if (f_power_is_on)
            {
            if (f_data_rx)
              {
              f_data_rx = 0;
    #ifdef DEBUG_PRINT
              printf("RX: ");
              printf(rx_string);
              printf("\r\n");
    #endif
              if (ParseMessage())           // parse command to rx_data[]
                {
                ClearRxString();            // clear rx_buffer for next communication
                ExecuteMessage();
                }
              else
                ClearRxString();            // message invalid: clear rx_buffer for next communication
              }
            if (f_data_tx)
              {
              f_data_tx = 0;
    #ifdef DEBUG_PRINT
              printf("TX: ");
              printf(tx_string);
              printf("\r\n");
    #endif
              ble_nus_string_send(&m_nus, tx_string, tx_string_len);
              }
            }
          CheckPowerKey();                // check power key
          if (f_power_is_on)
            {
            CheckScheduling();
            UpdatePumpOperation();
            Timers();
            UpdateLed();
            }
          }
    }
    

  • and the Check Power Key routine:

    //-------------------------------------
    void CheckPowerKey(void)
    {
      if (f_key_was_on)
        {
    #ifdef DEMO_BOARD
        if (nrf_gpio_pin_read(K_PWR) || !nrf_gpio_pin_read(PDN))
    #else
        if (!nrf_gpio_pin_read(K_PWR) || !nrf_gpio_pin_read(PDN))
    #endif
          {
          f_key_was_on = 0;   // key changed ON -> OFF
          }
        else // Key is On and not PDN: => switch on if was off
          {
          if (!f_power_is_on)
            {
            f_power_is_on = 1;
            PowerOffToOn();
            first_minute = 60;
            StartBLE();       // start BLE and kernel_int
            RebuildActionSequence();
    //        ReloadOnPeriod();
    //        ReloadOffPeriod();
            if (!po_on_period)
              po_on_period = TEST_ON_PERIOD;
            }
          }
        }
      else // f_key_was_on = 0
        {
    #ifdef DEMO_BOARD
        if (!nrf_gpio_pin_read(K_PWR) && nrf_gpio_pin_read(PDN))
    #else
        if (nrf_gpio_pin_read(K_PWR) && nrf_gpio_pin_read(PDN))
    #endif
          {
          f_key_was_on = 1;       // key changed OFF -> ON
          }
        else // Power key is OFF: => switch off if it was on
          {
          if (f_power_is_on)
            {
            StopBLE();       // stop BLE and kernel_int
            f_power_is_on = 0;
            first_minute = 0;
            PowerOnToOff();
            }
          }
        }
    }
    

  • Here is the rest:

    //-------------------------------------
    void StopBLE(void)
    {
    #ifdef USE_BLE
      if (f_bt_connected)
        bsp_event_handler(BSP_EVENT_DISCONNECT);
      advertising_stop();
    #endif
      app_timer_stop(kernel_clock_id);
      InitIo();                       // set IO to minimum consumption
    }
    //-------------------------------------
    //
    //-------------------------------------
    void StartBLE(void)
    {
    #ifdef USE_BLE
      ble_advertising_start(BLE_ADV_MODE_FAST);
    #endif
      app_timer_start(kernel_clock_id, 327, false);
      InitIo();                       // set IO to minimum consumption
    }
    //-------------------------------------
    //
    //-------------------------------------
    void PowerOnToOff(void)
    {
      nrf_gpio_pin_set(LED);
      nrf_gpio_pin_set(P_ON);
      i2c_init();
      app_timer_stop(real_time_clock_id);       // stop RTC1 - also clears COUNTER
    }
    //-------------------------------------
    //
    //-------------------------------------
    void PowerOffToOn(void)
    {
      lword seconds_elapsed;
      
      seconds_elapsed = NRF_RTC1->COUNTER;
      app_timer_start(real_time_clock_id, 32767, false);
    }
    

  • Another thing: if I hold the controller in RESET (on the PCA10028) I have 1 mA consumption!

  • I forgot to mention: I am using soft_device 12 and I can say that it is the BLE soft_device that is consuming this power. So I think the answer to my problem could be quite simple:
    How can I switch off the complete BLE before going into low power consumption?

Related