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

Minimising power consumption when running RTC with HFXO and LFXO enabled

Hello,

Following on from this question, I've been trying to identify the source of unexpectedly high power consumption when using the RTC. In order to test this, I am using the nRF52DK board and have create a bare-bones C project using SEGGER Embedded Studio. The C project was created using the SEGGER New Project wizard and choosing "A C/C++ Executable for a Cortex-M processor", selecting the nRF52832_xxAA device and then simply adding the modules/nrfx/mdk and components/toolchain/cmsis/include paths from the nRF52 SDK to the preprocessor include paths - this allows me to #include the nrf52.h file. I then created the following program:

#include <stdio.h>
#include <stdlib.h>
#include "nrf52.h"

void main(void) {
  NRF_POWER->DCDCEN = 1;

  NRF_CLOCK->TASKS_HFCLKSTART = 1;  // Start the HFXO
  while(NRF_CLOCK->HFCLKSTAT != 0x010001);  // Wait for it to start running

  NRF_CLOCK->LFCLKSRC = 1; // Enable the 32khz crystal
  NRF_CLOCK->TASKS_LFCLKSTART = 1; // Start the 32khz crystal
  // Wait for the LF osc to be running
  while(NRF_CLOCK->LFCLKSTAT != 0x010001);

  // Initialise the RTC peripheral
  #define RTC_FREQ_HZ 10
  NRF_RTC0->PRESCALER = 32768 / (RTC_FREQ_HZ) - 1; 
  NRF_RTC0->CC[0] = RTC_FREQ_HZ;  // Should trigger every 1s
  NRF_RTC0->EVTEN = 0x010000;     // Enable CC[0] event
  NRF_RTC0->INTENSET = 0x010000;  // Enable the CC[0] interrupt
  NVIC_EnableIRQ(RTC0_IRQn);
  NRF_RTC0->TASKS_START = 1;

  while(1) {
    __WFI();
    printf("Compare event!\n");
  }
}

// RTC0 ISR
void ExternalISR11(void) 
{
  volatile uint32_t i;
  NRF_RTC0->EVENTS_COMPARE[0] = 0;
  i = NRF_RTC0->EVENTS_COMPARE[0];
  NRF_RTC0->TASKS_CLEAR = 1;
}

As you can see, the code first enables the HFXO and LFXO, after which RTC is initialised with a frequency of 10Hz and configured to generate an interrupt via the COMPARE feature every 1s. In the main loop, the WFI instruction is used to enter SYSTEM_ON sleep mode. After 1s, the CPU wakes up and the debug printf command is executed successfully. I've tested the code in the debugger and it appears to work fine, with the printf message being printed every second.

Via jumper P22 on the nRF52DK, I've measured the current consumption of the CPU and it's 450uA, which is quite high. What I'm expecting is that when the WFI instruction is called, the CPU enters sleep mode and the power manager disables the HFCLK so that only the LFCLK is running and powering the RTC. However, it seems that the HFCLK is not being turned off in sleep. What is being done wrong here?

Related