I have three Nordic Semiconductor prototyping boards that expose the nRF51422, nRF52832, and nRF52840 microcontrollers for firmware development.

They look like this:

PCA10028, PCA10040, PCA10059 development kits

Now, I could write a piece of embedded firmware to do what I need for just one of the boards, and call it a day. But I want to try something a bit different.

Rather than write one firmware for each board, I want to write one firmware that runs on all of the boards. At runtime, the firmware will determine what kind of chip it is running on, then adapt itself to maximally use the available peripherals.

The program will use modern C++ to achieve as much programmer efficiency as possible, and will actively avoid using the Nordic Semiconductor nRF5 SDK (which I think uses really, really ugly and preprocessor magic-heavy C code) with way too much global scope.

This write-up captures the steps in taking the idea from the concept stage through to development, starting with baseline functionality, and discusses a bunch of the Gotchas encountered along the way.

The Goal

The ultimate user-facing goal is a simple app that plots data roughly as follows:

noisefloor app window wireframe 1a

The firmware will use the RADIO peripheral on each chip to sample the Received Signal Strength Indicator value on a single frequency band (within the 2400 - 2485 MHz range), to do this as quickly as possible for a regularly-repeated 2 millisecond-long Time Division Multiple Access timeslot, and to plot this information on a generic laptop computer.

We’ll have to make a few calculations and measurements to get a sense of the sampling rate and resolution possible for each chip.

I can’t say what specifically I’m using this for (top secret), but it’s the missing piece of a puzzle I need for visibility into another piece of firmware I’m writing. The measured RSSI values aren’t important here, only the precise timing offsets within the timeslot.

Buying a pricy spectrum analyzer is out of the question, and would only happen if this plan doesn’t work.

I remember reading somewhere once that part of the final exam of apprentice craftspeople was that they were required to create their own tools to use when building their final training product. The idea being, that anyone worthy of being considered a master craftsperson might need to start utterly from scratch.

We’re not going all the way down to the atomic level here (I’d need a RISC-V design for that, maybe someday). I will be using the GNU Compiler Collection and LLVM Clang compilers respectively as baselines and I will document the full list of tools used in a separate section.

Ready to get going? Let’s take a look at the Boundary Conditions and Peripheral Interfaces.

Updated 2020-04-22 22:18:35 +0200, proudly made with Asciidoctor.