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;
}

Related