I needed to learn how to do interrupt handling on the Nordic.  The simplest thing seemed to be to setup the RTC to generate regular interrupts.  It was a useful process because I learned quite a bit about the hardware in the process.

(My test program is called: RTC_C_nRF51822)
There are two clocks: a low-frequency clock, and a high-frequency clock.  The LFCLK runs at 32KHz.  It generates the basic system tick which is a sub-multiple of the 32768Hz.  The PRESCALAR which essentially divides the clock is only 12 bits wide, so the slowest clock-tick is 32768/(0xFFF + 1) = 8Hz.

#define RTC_FREQUENCY_HZ  (10UL) 
#define COUNTER_PRESCALER ((LFCLK_FREQUENCY / RTC_FREQUENCY_HZ) – 1)

The name of the interrupt routine is hard-wired : void RTC0_IRQHandler()  It gets called at RTC_FREQUENCY_HZ.

There is another times called the “compare” timer that can be set to cause an timer interrupt at any multiple of RTC_FREQUENCY_HZ.

Whereas the basic tick interrupt repeats automatically, the compare timer is a one-shot and has to be restarted.

So the basic process involves setting up the timer frequencies, and the interrupt events and masks, and then going to sleep until a tick, or “compare” interrupt occurs.

The sleep loop is a little subtle.  It is important to make sure that all pending interrupts are processed before sleeping, for which this opaque/confusing sequence is recommended.

// Enter System ON sleep mode __WFE(); // Make sure any pending events are cleared __SEV(); __WFE();

Incidentally I learned that the basic printf procedure is interrupts driven, so it get’s a bit confusing.

So here’s an example that toggles one LED every ten system ticks, and the other at 3Hz.

I noticed that in sleep mode the board is still consuming about 1.5mA with the LEDs off.

Leave a Reply