Skip to content







Hardware counters are elementary components in digital design and can be used for a multitude of applications. They are also at the core of every computing platform. Counters are used in conjunction with a clock source, RC oscillator, crystal, PLL etc, in order to alert the processor when a certain number of clock cycles have been generated.

In some cases a counter can be used to generate control signals to a sequential circuit.

But these counters can also be used to simply count the number of events that have occurred. If there is a signal that transitions from one state to another, in such a way that it could be used as a clock signal, one could count the number of events that have occurred since the counter has been reset.


This document describes the HardwareCounter abstraction. The purpose of a HardwareCounter is to count the number of clock cycles, pulses, or transitions of a signal connected to a clock source pin. This particular ability is useful for various L2 applications.

Some examples would be: 1. Utilizing 2x HardwareCounters can be used to create a quadrature encoder library. 2. Utilizing a HardwareCounter and Uptime() can be used with a digital tachometer, to measure the radial velocity of a motor, where the tachometer's output is a square wave, and the frequency of the wave corresponds to the speed of the device. 3. Utilizing a HardwareCounter to measure the number of pulses generated by the LTC4150 coulomb counter. A pulse is generated by the coulomb counter after a set amount of charge has flowed through a shunt resistor. The count of coulombs can directly indicate the amount of charge left in a battery. Using it with Uptime(), it can be used to determine the average current.

A HardwareCounter can be implemented in three ways:

  1. Gpio with interrupt support.
  2. With the gpio interrupt setup with the appropriate trigger condition (fall, rise, both), on every interrupt, increment an integer by 1. That integer is your count.
  3. This implementation is an economic one, in that most micro-controllers will have GPIO with interrupt capabilities.
  4. Has a limitation of clock frequency. The faster the frequency, the more interrupts occur, the less time your processor has to do actual work.
  5. Timer hardware with external clock input support and interrupts disabled.
  6. This is the most processor efficient option as it requires processing power input from the CPU. The counter hardware can increment itself based on the clock input signal, leaving the processor the time to do other work.
  7. Gpio with CPU polling
  8. Continuously check a pin to determine if it has transitioned.
  9. Can operate at high frequencies.
  10. Has a massive limitation in that, the CPU has to spend most of its time Checking the pin, otherwise, it may miss a transition. Only recommended for systems that have no other option.

Detailed Design


class HardwareCounter
  enum class Direction : int8_t
    kDown = -1,
    kUp   = 1,

  virtual void Initialize() = 0;
  virtual void Set(uint32_t new_count_value) = 0;
  virtual void SetDirection(Direction direction) = 0;
  virtual void Enable() = 0;
  virtual void Disable() = 0;
  virtual uint32_t GetCount() = 0;

void Initialize()

When called, this initializes the peripheral hardware. You must ensure that the counter is set to zero after this call. NOTE: This must not enable the counter. In order to start counting based on an external input, an explicit invocation of Enable() must occur.

void Set(uint32_t new_count_value)

Set counter to a specific value. There is no guarantee that counts will not be missed during the invocation of this call.

void SetDirection(Direction direction)

Set the counting direction to either up or down.

void Enable()

Starts counting from clock input. Must be called after Initialize() to begin counting.

void Disable()

Stops counting from clock input. Current count is retained.

uint32_t GetCount()

Get the current count from hardware timer.

Future Advancements


Testing Plan

Unit Testing Scheme

This interface does not come with utility methods, thus there is no code to test.

Demonstration Project