This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
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

Power use with GPIOTE is too high?

I have just begun tests with the nRF51822 DK.

I have written a test program which uses the RTC and PPI to generate an event every 125 ms, and use a task to toggle a GPIO pin. I try to put the processor to sleep with __WFI().

I was expecting a very low current consumption, since my impression was that the CPU would not be used for the PPI event/task system. However, I measure 123 mV on K2 on the DK PCB with the SMA antenna. I interpret this to mean that the device is drawing about 1.2 mA. I was expecting something on the order of "2.3μA@3V ON mode, all blocks IDLE" [Datasheet] + some uA for the RTC.

The GPIO pin which I toggle has been disconnected and should not be drawing any current.

See below my source code. I'd be grateful for hints to reduce power use as much as possible.

// processor family; required by nrf.h
#define NRF51

#include "nrf.h"
#include "nrf_gpiote.h"
#include "nrf_gpio.h"

/*
 * constants
 */
#define GPIOTE_CHANNEL_NUMBER 0
#define outPin 25

/*
 * static function prototypes
 */
 
/** @brief Function starting the internal LFCLK XTAL oscillator.
 */
static void lfclk_config(void);
static void rtc_config(void);

int main( int argc, char **argv )
{
	// Disable DC/DC converter to save power
	// enable low power mode
	NRF_POWER->DCDCEN = 0;
	NRF_POWER->TASKS_LOWPWR = 1;
	
	// setup GPIO
	nrf_gpio_cfg_output(outPin);

	// setup task to toggle pin.
	// Configure GPIOTE_CHANNEL_NUMBER to toggle the GPIO pin state with input.
  // @note Only one GPIOTE task can be coupled to an output pin.
  nrf_gpiote_task_config( GPIOTE_CHANNEL_NUMBER, outPin /* GPIO_OUTPUT_PIN_NUMBER */, \
                           NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
	
	// setup RTC to generate event on tick every second
	// Use crystal as Low frequency clock source
	lfclk_config();
	rtc_config();
	
	// setup PPI to automatically toggle GPIO pin on tick event

	// Configure PPI channel 0 to stop Timer 0 counter at TIMER1 COMPARE[0] match, which is every even number of seconds.
  NRF_PPI->CH[0].EEP = (uint32_t)(&NRF_RTC0->EVENTS_TICK);
  NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[GPIOTE_CHANNEL_NUMBER];

  // Enable PPI channel 0
  NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);

	// sleep
	while( 1 )
		__WFI();
}

/** @brief Function starting the internal LFCLK XTAL oscillator.
 */
static void lfclk_config(void)
{
    NRF_CLOCK->LFCLKSRC             = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
    NRF_CLOCK->EVENTS_LFCLKSTARTED  = 0;
    NRF_CLOCK->TASKS_LFCLKSTART     = 1;
    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
    {
        //Do nothing.
    }
    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
}

/** @brief Function for configuring the RTC with TICK to 100Hz and COMPARE0 to 10 sec.
 */
static void rtc_config(void)
{
	// prescaler max is 4095 = 125 ms.
	// do compare thing to get 1 Hz
	// can't tick at slower than 125 ms = 8 Hz. 
	NRF_RTC0->PRESCALER     = 4095;                    // Set prescaler to a TICK of RTC_FREQUENCY.

    // Enable TICK event and TICK interrupt:
    NRF_RTC0->EVTENSET      = RTC_INTENSET_TICK_Msk; 

		NRF_RTC0->TASKS_START = 1;
}

  • I just found the discussion: "Why does my nrf51822 consume 1 ma in sleep"

    I powercycled the circuit to disable the debug interface. This reduced the consumption from 1240 to 950 uA. Then I made sure the HF cystal was enabled, which reduced the power consumption ot 870 uA. Still a factor 100 too high, I think.

    As you see in the code, I have not explicitly enabled any other peripheral modules. But it does seem like something is using the 16 MHz crystal. Could it be the GPIOTE? If so, how can I make it release the 16 MHz crystal?

  • I added code to power down peripherals as below, but I am still measuring 87 mV (=870 uA).

    
    	// Disable unused peripherals
    	// Radio:
    	NRF_RADIO->TASKS_DISABLE = 1;
    	NRF_RADIO->POWER = 0;
    		
    	NRF_POWER->POFCON = 0; // Disable Power Fail Comparator
    	NRF_GPIOTE->INTENSET = 0; // Disable all GPIO interrupts
    	NRF_TIMER0->TASKS_STOP = 1;
    	NRF_TIMER0->POWER = 0;
    	NRF_TIMER1->TASKS_STOP = 1;
    	NRF_TIMER1->POWER = 0;
    	NRF_TIMER2->POWER = 0;
    	// NRF_WDT->CONFIG = 0;
    	NRF_WDT->POWER = 0;
    	NRF_RNG->POWER = 0;
    	NRF_TEMP->POWER = 0;
    	NRF_ECB->POWER = 0;
    	NRF_CCM->POWER = 0;
    	NRF_AAR->POWER = 0;
    	NRF_SPI0->POWER = 0;
    	NRF_SPI1->POWER = 0;
    	NRF_SPIS1->POWER = 0;
    	NRF_TWI0->POWER = 0;
    	NRF_TWI1->POWER = 0;
    	NRF_UART0->POWER = 0;
    	NRF_QDEC->POWER = 0;
    	NRF_ADC->POWER = 0;
    	NRF_LPCOMP->POWER = 0;
    
    
  • Ok, I tracked this down further. I minimized the program, and the following line causes the program to draw about 950 uA:

    
    	NRF_GPIOTE->CONFIG[GPIOTE_CHANNEL_NUMBER] = 
    (GPIOTE_CONFIG_MODE_Task *shiftleft* GPIOTE_CONFIG_MODE_Pos)     |
                                             ((uint32_t)outPin *shiftleft* GPIOTE_CONFIG_PSEL_Pos)     |
                                             ((uint32_t)NRF_GPIOTE_POLARITY_TOGGLE *shiftleft* GPIOTE_CONFIG_POLARITY_Pos) |
                                             ((uint32_t)NRF_GPIOTE_INITIAL_VALUE_HIGH *shiftleft* GPIOTE_CONFIG_OUTINIT_Pos);
    
    

    (There's apparently a bug in the forum, so I replaced two 'less than' with shiftleft above)

    In the product specification, section 8.10 says the GPIOTE should only draw 0.1 uA "in Output mode". As far as I can understand, the above uses the GPIOTE in output mode (defines a task which toggles an output pin).

    Please help me understand why the above line causes the GPIOTE to draw more than 0.1 uA!

  • FYI, I'm seeing similar behavior with GPIOTE causing about 1.2 mA current draw. In my application I can relatively easily enable/disable the GPIOTE when needed by setting the GPIO config mode to DISABLE when not in use.

  • Have you read the PAN?

    1. GPIOTE: 1V2 + HFCLK are requested always when the GPIOTE task is configured.

    Symptoms: Excess current consumption in system ON mode when CPU is sleeping.

    Conditions: One or more GPIOTE channels are configured in task mode.

    Consequences: Battery life time is degraded.

    Workaround: None.

Related