← Christopher Yarbro

nrf_pcnt

A hardware pulse counter for the nRF52, built from parts on the chip. It counts without CPU intervention.

C · nrfx 2.x and 3.xApache 2.0Source

Why

Moire's soil-moisture probe reports moisture as a frequency, so measuring it means counting pulses over a fixed window. The ESP32 has a pulse-counter peripheral for this; the nRF52 doesn't. Counting in an interrupt handler would wake the CPU on every pulse, which defeats the point of a node that is supposed to spend most of its life asleep.

How it works

The nRF52's Programmable Peripheral Interconnect (PPI) wires one peripheral's event directly to another peripheral's task, with no CPU in between. Two PPI channels and two timers make a gated counter:

Pulse pin ──► GPIOTE IN event ──PPI──► TIMER2 COUNT task      (counter, 32-bit)
TIMER3 COMPARE[1] event ──────PPI──► TIMER2 CAPTURE[0] task   (gate, 1 MHz)
  1. GPIOTE raises an event on each falling edge of the pulse pin.
  2. PPI routes that event to TIMER2's COUNT task. TIMER2 runs in counter mode, so each pulse increments it in hardware.
  3. TIMER3 runs at 1 MHz with a compare value equal to the measurement window.
  4. When the window ends, a second PPI channel fires TIMER2's CAPTURE task, latching the count into a register.

After setup the CPU does nothing. Reading the result is one register read whenever the application next wakes up.

API

nrfx_err_t pcntInit(int pin, uint16_t measureTimeMs);
void       pcntClearCounter(void);   // reset the count
void       pcntClearTimer(void);     // restart the window
uint32_t   pcntGetCount(void);       // count latched at end of window

Notes