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